📄 disklabel.c
字号:
/* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * Symmetric Computer Systems. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifndef lintstatic char copyright[] ="@(#) Copyright (c) 1987, 1993\n\ The Regents of the University of California. All rights reserved.\n";#endif /* not lint */#ifndef lintstatic char sccsid[] = "@(#)disklabel.c 8.2 (Berkeley) 1/7/94";/* from static char sccsid[] = "@(#)disklabel.c 1.2 (Symmetric) 11/28/85"; */#endif /* not lint */#include <sys/param.h>#include <sys/signal.h>#include <sys/errno.h>#include <sys/file.h>#include <sys/ioctl.h>#include <sys/stat.h>#define DKTYPENAMES#include <sys/disklabel.h>#include <ufs/ffs/fs.h>#include <unistd.h>#include <string.h>#include <stdio.h>#include <ctype.h>#include "pathnames.h"/* * Disklabel: read and write disklabels. * The label is usually placed on one of the first sectors of the disk. * Many machines also place a bootstrap in the same area, * in which case the label is embedded in the bootstrap. * The bootstrap source must leave space at the proper offset * for the label on such machines. */#ifdef tahoe#define RAWPARTITION 'a'#else#define RAWPARTITION 'c'#endif#ifndef BBSIZE#define BBSIZE 8192 /* size of boot area, with label */#endif#ifdef tahoe#define NUMBOOT 0#else#if defined(hp300) || defined(hp800)#define NUMBOOT 1#else#define NUMBOOT 2#endif#endif#define DEFEDITOR _PATH_VI#define streq(a,b) (strcmp(a,b) == 0)char *dkname;char *specname;char tmpfil[] = _PATH_TMP;extern int errno;char namebuf[BBSIZE], *np = namebuf;struct disklabel lab;struct disklabel *readlabel(), *makebootarea();char bootarea[BBSIZE];#if NUMBOOT > 0int installboot; /* non-zero if we should install a boot program */char *bootbuf; /* pointer to buffer with remainder of boot prog */int bootsize; /* size of remaining boot program */char *xxboot; /* primary boot */char *bootxx; /* secondary boot */char boot0[MAXPATHLEN];char boot1[MAXPATHLEN];#endifenum { UNSPEC, EDIT, NOWRITE, READ, RESTORE, WRITE, WRITEABLE, WRITEBOOT} op = UNSPEC;int rflag;#ifdef DEBUGint debug;#define OPTIONS "BNRWb:ders:w"#else#define OPTIONS "BNRWb:ers:w"#endifmain(argc, argv) int argc; char *argv[];{ extern char *optarg; extern int optind; register struct disklabel *lp; FILE *t; int ch, f, flag, error = 0; char *name = 0; while ((ch = getopt(argc, argv, OPTIONS)) != EOF) switch (ch) {#if NUMBOOT > 0 case 'B': ++installboot; break; case 'b': xxboot = optarg; break;#if NUMBOOT > 1 case 's': bootxx = optarg; break;#endif#endif case 'N': if (op != UNSPEC) usage(); op = NOWRITE; break; case 'R': if (op != UNSPEC) usage(); op = RESTORE; break; case 'W': if (op != UNSPEC) usage(); op = WRITEABLE; break; case 'e': if (op != UNSPEC) usage(); op = EDIT; break; case 'r': ++rflag; break; case 'w': if (op != UNSPEC) usage(); op = WRITE; break;#ifdef DEBUG case 'd': debug++; break;#endif case '?': default: usage(); } argc -= optind; argv += optind;#if NUMBOOT > 0 if (installboot) { rflag++; if (op == UNSPEC) op = WRITEBOOT; } else { if (op == UNSPEC) op = READ; xxboot = bootxx = 0; }#else if (op == UNSPEC) op = READ;#endif if (argc < 1) usage(); dkname = argv[0]; if (dkname[0] != '/') { (void)sprintf(np, "%sr%s%c", _PATH_DEV, dkname, RAWPARTITION); specname = np; np += strlen(specname) + 1; } else specname = dkname; f = open(specname, op == READ ? O_RDONLY : O_RDWR); if (f < 0 && errno == ENOENT && dkname[0] != '/') { (void)sprintf(specname, "%sr%s", _PATH_DEV, dkname); np = namebuf + strlen(specname) + 1; f = open(specname, op == READ ? O_RDONLY : O_RDWR); } if (f < 0) Perror(specname); switch(op) { case EDIT: if (argc != 1) usage(); lp = readlabel(f); error = edit(lp, f); break; case NOWRITE: flag = 0; if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) Perror("ioctl DIOCWLABEL"); break; case READ: if (argc != 1) usage(); lp = readlabel(f); display(stdout, lp); error = checklabel(lp); break; case RESTORE:#if NUMBOOT > 0 if (installboot && argc == 3) { makelabel(argv[2], 0, &lab); argc--; }#endif if (argc != 2) usage(); lp = makebootarea(bootarea, &lab, f); if (!(t = fopen(argv[1], "r"))) Perror(argv[1]); if (getasciilabel(t, lp)) error = writelabel(f, bootarea, lp); break; case WRITE: if (argc == 3) { name = argv[2]; argc--; } if (argc != 2) usage(); makelabel(argv[1], name, &lab); lp = makebootarea(bootarea, &lab, f); *lp = lab; if (checklabel(lp) == 0) error = writelabel(f, bootarea, lp); break; case WRITEABLE: flag = 1; if (ioctl(f, DIOCWLABEL, (char *)&flag) < 0) Perror("ioctl DIOCWLABEL"); break;#if NUMBOOT > 0 case WRITEBOOT: { struct disklabel tlab; lp = readlabel(f); tlab = *lp; if (argc == 2) makelabel(argv[1], 0, &lab); lp = makebootarea(bootarea, &lab, f); *lp = tlab; if (checklabel(lp) == 0) error = writelabel(f, bootarea, lp); break; }#endif } exit(error);}/* * Construct a prototype disklabel from /etc/disktab. As a side * effect, set the names of the primary and secondary boot files * if specified. */makelabel(type, name, lp) char *type, *name; register struct disklabel *lp;{ register struct disklabel *dp; char *strcpy(); dp = getdiskbyname(type); if (dp == NULL) { fprintf(stderr, "%s: unknown disk type\n", type); exit(1); } *lp = *dp;#if NUMBOOT > 0 /* * Set bootstrap name(s). * 1. If set from command line, use those, * 2. otherwise, check if disktab specifies them (b0 or b1), * 3. otherwise, makebootarea() will choose ones based on the name * of the disk special file. E.g. /dev/ra0 -> raboot, bootra */ if (!xxboot && lp->d_boot0) { if (*lp->d_boot0 != '/') (void)sprintf(boot0, "%s/%s", _PATH_BOOTDIR, lp->d_boot0); else (void)strcpy(boot0, lp->d_boot0); xxboot = boot0; }#if NUMBOOT > 1 if (!bootxx && lp->d_boot1) { if (*lp->d_boot1 != '/') (void)sprintf(boot1, "%s/%s", _PATH_BOOTDIR, lp->d_boot1); else (void)strcpy(boot1, lp->d_boot1); bootxx = boot1; }#endif#endif /* d_packname is union d_boot[01], so zero */ bzero(lp->d_packname, sizeof(lp->d_packname)); if (name) (void)strncpy(lp->d_packname, name, sizeof(lp->d_packname));}writelabel(f, boot, lp) int f; char *boot; register struct disklabel *lp;{ register int i; int flag; setbootflag(lp); lp->d_magic = DISKMAGIC; lp->d_magic2 = DISKMAGIC; lp->d_checksum = 0; lp->d_checksum = dkcksum(lp); if (rflag) { /* * First set the kernel disk label, * then write a label to the raw disk. * If the SDINFO ioctl fails because it is unimplemented, * keep going; otherwise, the kernel consistency checks * may prevent us from changing the current (in-core) * label. */ if (ioctl(f, DIOCSDINFO, lp) < 0 && errno != ENODEV && errno != ENOTTY) { l_perror("ioctl DIOCSDINFO"); return (1); } (void)lseek(f, (off_t)0, SEEK_SET); /* * write enable label sector before write (if necessary), * disable after writing. */ flag = 1; if (ioctl(f, DIOCWLABEL, &flag) < 0) perror("ioctl DIOCWLABEL"); if (write(f, boot, lp->d_bbsize) != lp->d_bbsize) { perror("write"); return (1); }#if NUMBOOT > 0 /* * Output the remainder of the disklabel */ if (bootbuf && write(f, bootbuf, bootsize) != bootsize) { perror("write"); return(1); }#endif flag = 0; (void) ioctl(f, DIOCWLABEL, &flag); } else if (ioctl(f, DIOCWDINFO, lp) < 0) { l_perror("ioctl DIOCWDINFO"); return (1); }#ifdef vax if (lp->d_type == DTYPE_SMD && lp->d_flags & D_BADSECT) { daddr_t alt; alt = lp->d_ncylinders * lp->d_secpercyl - lp->d_nsectors; for (i = 1; i < 11 && i < lp->d_nsectors; i += 2) { (void)lseek(f, (off_t)((alt + i) * lp->d_secsize), SEEK_SET); if (write(f, boot, lp->d_secsize) < lp->d_secsize) { int oerrno = errno; fprintf(stderr, "alternate label %d ", i/2); errno = oerrno; perror("write"); } } }#endif return (0);}l_perror(s) char *s;{ int saverrno = errno; fprintf(stderr, "disklabel: %s: ", s); switch (saverrno) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -