Home | History | Annotate | Line # | Download | only in newdisk
newdisk.c revision 1.8
      1  1.8    isaki /*	$NetBSD: newdisk.c,v 1.8 2011/04/29 06:00:33 isaki Exp $	*/
      2  1.6    isaki 
      3  1.1  minoura /*-
      4  1.1  minoura  * Copyright (c) 1999 Minoura Makoto
      5  1.1  minoura  * All rights reserved.
      6  1.1  minoura  *
      7  1.1  minoura  * Redistribution and use in source and binary forms, with or without
      8  1.1  minoura  * modification, are permitted provided that the following conditions
      9  1.1  minoura  * are met:
     10  1.1  minoura  * 1. Redistributions of source code must retain the above copyright
     11  1.1  minoura  *    notice, this list of conditions and the following disclaimer.
     12  1.1  minoura  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.1  minoura  *    notice, this list of conditions and the following disclaimer in the
     14  1.1  minoura  *    documentation and/or other materials provided with the distribution.
     15  1.1  minoura  * 3. All advertising materials mentioning features or use of this software
     16  1.1  minoura  *    must display the following acknowledgement:
     17  1.1  minoura  *	This product includes software developed by Minoura Makoto.
     18  1.1  minoura  * 4. The name of the author may not be used to endorse or promote products
     19  1.1  minoura  *    derived from this software without specific prior written permission.
     20  1.1  minoura  *
     21  1.1  minoura  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22  1.1  minoura  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23  1.1  minoura  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24  1.1  minoura  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25  1.1  minoura  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26  1.1  minoura  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27  1.1  minoura  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28  1.1  minoura  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29  1.1  minoura  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30  1.1  minoura  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31  1.1  minoura  */
     32  1.1  minoura 
     33  1.1  minoura /*
     34  1.1  minoura  * Create the disk mark for x68k SCSI IPL.
     35  1.1  minoura  * It used to be a shell/awk script, but is rewritten in order to be fit with
     36  1.1  minoura  * the install kernel.
     37  1.1  minoura  *
     38  1.1  minoura  * Usage: /usr/mdec/newdisk [-vnfc] [-m /usr/mdec/mboot] /dev/rsd?c
     39  1.1  minoura  */
     40  1.1  minoura 
     41  1.1  minoura #include <stdio.h>
     42  1.1  minoura #include <stdlib.h>
     43  1.1  minoura #include <string.h>
     44  1.1  minoura #include <fcntl.h>
     45  1.1  minoura #include <unistd.h>
     46  1.1  minoura #include <util.h>
     47  1.1  minoura #include <sys/param.h>
     48  1.1  minoura #include <sys/disklabel.h>
     49  1.1  minoura #include <sys/dkio.h>
     50  1.1  minoura 
     51  1.1  minoura char *mboot = MBOOT;
     52  1.1  minoura char dev[MAXPATHLEN];
     53  1.1  minoura char buf[4096 + 1];
     54  1.1  minoura 
     55  1.2  minoura const char copyright[] = "NetBSD/x68k SCSI Primary Boot. ";
     56  1.1  minoura 
     57  1.2  minoura int verbose = 0, dry_run = 0, force = 0, check_only = 0, mark_only = 0;
     58  1.1  minoura 
     59  1.4      dsl void usage(void) __attribute__((__noreturn__));
     60  1.4      dsl int main(int, char *[]);
     61  1.1  minoura 
     62  1.3   mhitch void
     63  1.1  minoura usage(void)
     64  1.1  minoura {
     65  1.6    isaki 	fprintf(stderr,
     66  1.6    isaki 		"Usage: %s [-v] [-n] [-f] [-c] [-m /usr/mdec/mboot] "
     67  1.7    isaki 		"/dev/rsdXc\n", getprogname());
     68  1.6    isaki 	exit(1);
     69  1.6    isaki 	/* NOTREACHED */
     70  1.1  minoura }
     71  1.1  minoura 
     72  1.1  minoura int
     73  1.5      dsl main(int argc, char *argv[])
     74  1.1  minoura {
     75  1.6    isaki 	int ch;
     76  1.6    isaki 	int fd;
     77  1.6    isaki 	struct disklabel label;
     78  1.6    isaki 
     79  1.6    isaki 	while ((ch = getopt(argc, argv, "vnfcm:p")) != -1) {
     80  1.6    isaki 		switch (ch) {
     81  1.6    isaki 		case 'v':
     82  1.6    isaki 			verbose = 1;
     83  1.6    isaki 			break;
     84  1.6    isaki 		case 'n':
     85  1.6    isaki 			dry_run = 1;
     86  1.6    isaki 			break;
     87  1.6    isaki 		case 'f':
     88  1.6    isaki 			force = 1;
     89  1.6    isaki 			break;
     90  1.6    isaki 		case 'c':
     91  1.6    isaki 			check_only = 1;
     92  1.6    isaki 			break;
     93  1.6    isaki 		case 'm':
     94  1.6    isaki 			mboot = optarg;
     95  1.6    isaki 			break;
     96  1.6    isaki 		case 'p':
     97  1.6    isaki 			mark_only = 1;
     98  1.6    isaki 			break;
     99  1.6    isaki 		default:
    100  1.6    isaki 			usage();
    101  1.6    isaki 		}
    102  1.1  minoura 	}
    103  1.6    isaki 	argc -= optind;
    104  1.6    isaki 	argv += optind;
    105  1.6    isaki 
    106  1.6    isaki 	if (argc != 1)
    107  1.6    isaki 		usage();
    108  1.6    isaki 
    109  1.6    isaki 	fd = opendisk(argv[0], O_RDONLY, dev, MAXPATHLEN, 0);
    110  1.6    isaki 	if (fd < 0)
    111  1.6    isaki 		err(1, "opening %s", dev);
    112  1.6    isaki 	if (access(mboot, R_OK) < 0)
    113  1.6    isaki 		err(1, "checking %s", mboot);
    114  1.6    isaki 
    115  1.6    isaki 	if (read(fd, buf, 512) < 0)
    116  1.6    isaki 		err(1, "reading %s", dev);
    117  1.6    isaki 	if (strncmp(buf, "X68SCSI1", 8) == 0 && !force)
    118  1.6    isaki 		errx(1, "%s is already marked.  "
    119  1.8    isaki 		        "Use -f to overwrite the existing mark.", dev);
    120  1.6    isaki 	if (check_only)
    121  1.6    isaki 		return 0;
    122  1.1  minoura 
    123  1.6    isaki 	if (verbose)
    124  1.6    isaki 		fprintf(stderr, "Inspecting %s... ", dev);
    125  1.1  minoura 
    126  1.6    isaki 	if (ioctl(fd, DIOCGDINFO, &label) < 0)
    127  1.6    isaki 		err(1, "inspecting %s", dev);
    128  1.6    isaki 	close(fd);
    129  1.6    isaki 	if (label.d_secsize != 512)
    130  1.6    isaki 		errx(1, "This type of disk is not supported by NetBSD.");
    131  1.1  minoura 
    132  1.6    isaki 	if (verbose)
    133  1.6    isaki 		fprintf(stderr, "total number of sector is %d.\n",
    134  1.6    isaki 			label.d_secperunit);
    135  1.1  minoura 
    136  1.2  minoura 	if (verbose)
    137  1.6    isaki 		fprintf(stderr, "Building disk mark... ");
    138  1.6    isaki 	memset(buf, 0, 3072);
    139  1.6    isaki #define n label.d_secperunit
    140  1.6    isaki 	sprintf(buf, "X68SCSI1%c%c%c%c%c%c%c%c%s",
    141  1.6    isaki 		2, 0,
    142  1.6    isaki 		(n/16777216)%256, (n/65536)%256, (n/256)%256, n%256,
    143  1.6    isaki 		1, 0, copyright);
    144  1.1  minoura #undef n
    145  1.2  minoura 	if (verbose)
    146  1.6    isaki 		fprintf(stderr, "done.\n");
    147  1.1  minoura 
    148  1.6    isaki 	if (verbose)
    149  1.6    isaki 		fprintf(stderr, "Merging %s... ", mboot);
    150  1.6    isaki 	fd = open(mboot, O_RDONLY);
    151  1.1  minoura 	if (fd < 0)
    152  1.6    isaki 		err(1, "opening %s", mboot);
    153  1.6    isaki 	if (read(fd, buf+1024, 1024) < 0)
    154  1.6    isaki 		err(1, "reading %s", mboot);
    155  1.1  minoura 	close(fd);
    156  1.6    isaki 	if (verbose)
    157  1.6    isaki 		fprintf(stderr, "done.\n");
    158  1.6    isaki 
    159  1.6    isaki 	if (!mark_only) {
    160  1.6    isaki 		if (verbose)
    161  1.6    isaki 			fprintf(stderr,
    162  1.6    isaki 				"Creating an empty partition table... ");
    163  1.6    isaki #define n (label.d_secperunit/2)
    164  1.6    isaki 		sprintf(buf+2048,
    165  1.6    isaki 			"X68K%c%c%c%c%c%c%c%c%c%c%c%c",
    166  1.6    isaki 			0, 0, 0, 32,
    167  1.6    isaki 			(n/16777215)%256, (n/65536)%256, (n/256)%256, n%256,
    168  1.6    isaki 			(n/16777215)%256, (n/65536)%256, (n/256)%256, n%256);
    169  1.6    isaki #undef n
    170  1.6    isaki 		if (verbose)
    171  1.6    isaki 			fprintf(stderr, "done.\n");
    172  1.6    isaki 	}
    173  1.1  minoura 
    174  1.6    isaki 	if (dry_run) {
    175  1.6    isaki 		char filename[MAXPATHLEN] = "/tmp/diskmarkXXXXX";
    176  1.6    isaki 		fd = mkstemp(filename);
    177  1.6    isaki 		if (fd < 0)
    178  1.6    isaki 			err(1, "opening %s", filename);
    179  1.6    isaki 		if (write(fd, buf, 4096) < 0)
    180  1.6    isaki 			err(1, "writing %s", filename);
    181  1.6    isaki 		close(fd);
    182  1.6    isaki 		fprintf(stderr, "Disk mark is kept in %s.\n", filename);
    183  1.6    isaki 	} else {
    184  1.6    isaki 		int mode = 1;
    185  1.6    isaki 
    186  1.6    isaki 		if (verbose)
    187  1.6    isaki 			fprintf(stderr, "Writing... ");
    188  1.6    isaki 		fd = open(dev, O_WRONLY);
    189  1.6    isaki 		if (fd < 0)
    190  1.6    isaki 			err(1, "opening %s", dev);
    191  1.6    isaki 		if (ioctl(fd, DIOCWLABEL, (char *)&mode) < 0)
    192  1.6    isaki 			err(1, "DIOCWLABEL %s", dev);
    193  1.6    isaki 		if (write(fd, buf, 4096) != 4096) {
    194  1.6    isaki 			mode = 0;
    195  1.6    isaki 			ioctl(fd, DIOCWLABEL, (char *)&mode);
    196  1.6    isaki 			err(1, "DIOCWLABEL %s", dev);
    197  1.6    isaki 		}
    198  1.6    isaki 		ioctl(fd, DIOCWLABEL, (char *)&mode);
    199  1.6    isaki 		if (verbose)
    200  1.6    isaki 			fprintf(stderr, "done.\n");
    201  1.6    isaki 		close(fd);
    202  1.1  minoura 	}
    203  1.1  minoura 
    204  1.6    isaki 	return 0;
    205  1.1  minoura }
    206