Subject: Disklabels arrive for 2.11BSD (#257 part 8 of 18) Index: sys,bin,usr.lib,(many more)/ 2.11BSD Description: The moving the partitions tables out of the disk drivers and to a disklabel residing on the media has been on the wish list for many many years. Disklabels have finally arrived for 2.11BSD! Repeat-By: Observation. Also a reading of the setup and installation documentation for previous 2BSD releases (2.9, 2.10, 2.11) all have a paragraph similar to this present: "It is possible to change the partitions by changing the code for the table in the disk driver. Since it's desirable to do this, these tables really should be read off each pack...." Fix: This is part 8 of 18. Gather all parts before doing anything except reading the instructions which are in #250 (part 1). Updated by this part are: /usr/src/lib/libc/gen/disklabel.c /usr/src/lib/libc/gen/Makefile /usr/src/lib/libc/pdp/gen/disktab.c /usr/src/lib/libc/pdp/gen/Makefile 'disklabel.c' is new and added to the system by unpacking the included shar archive. 'disktab.c' is removed from the system. It has been replaced by the 'disklabel.c' module. NOTE: The /etc/disktab format has changed. There will be a reminder of this in the part which replaces the disktab file. Cut where indicated and save to a file (/tmp/257). Then: cd /tmp sh 257 sh lib.shar sh lib.sh patch -p0 < lib.patch rm lib.shar lib.sh lib.patch -------------------------cut here----------------------- #! /bin/sh # This is a shell archive, meaning: # 1. Remove everything above the #! /bin/sh line. # 2. Save the resulting text in a file. # 3. Execute the file with /bin/sh (not csh) to create: # lib.sh # lib.patch # lib.shar # This archive created: Tue Jun 27 22:20:38 1995 export PATH; PATH=/bin:/usr/bin:$PATH if test -f 'lib.sh' then echo shar: "will not over-write existing file 'lib.sh'" else sed 's/^Y//' << \SHAR_EOF > 'lib.sh' Y#!/bin/sh Ymv /usr/src/lib/libc/pdp/gen/disktab.c /usr/src/lib/libc/pdp/gen/disktab.c~ SHAR_EOF fi if test -f 'lib.patch' then echo shar: "will not over-write existing file 'lib.patch'" else sed 's/^Y//' << \SHAR_EOF > 'lib.patch' Y*** /usr/src/lib/libc/gen/Makefile.old Sat Apr 1 23:16:43 1995 Y--- /usr/src/lib/libc/gen/Makefile Thu Apr 13 22:08:34 1995 Y*************** Y*** 3,9 **** Y # All rights reserved. The Berkeley software License Agreement Y # specifies the terms and conditions for redistribution. Y # Y! # @(#)Makefile 5.7.3 (2.11BSD) 1995/04/01 Y # Y # Several routines have been rewritten in assembly language for the VAX and Y # the PDP. If you are not running on a VAX or PDP, you should use the Y--- 3,9 ---- Y # All rights reserved. The Berkeley software License Agreement Y # specifies the terms and conditions for redistribution. Y # Y! # @(#)Makefile 5.7.4 (2.11BSD) 1995/04/13 Y # Y # Several routines have been rewritten in assembly language for the VAX and Y # the PDP. If you are not running on a VAX or PDP, you should use the Y*************** Y*** 14,20 **** Y Y CFLAGS= -O ${DEFS} Y STDSRC= abort.c alarm.c atoi.c atol.c calloc.c closedir.c crypt.c \ Y! ctime.c ctype_.c daemon.c devname.c err.c errlst.c execvp.c fakcu.c \ Y fstab.c gcvt.c getenv.c getgrent.c getgrgid.c getgrnam.c getlogin.c \ Y getpass.c getpwent.c getloadavg.c \ Y getttyent.c getttynam.c getusershell.c getwd.c \ Y--- 14,21 ---- Y Y CFLAGS= -O ${DEFS} Y STDSRC= abort.c alarm.c atoi.c atol.c calloc.c closedir.c crypt.c \ Y! ctime.c ctype_.c daemon.c devname.c disklabel.c err.c errlst.c \ Y! execvp.c fakcu.c \ Y fstab.c gcvt.c getenv.c getgrent.c getgrgid.c getgrnam.c getlogin.c \ Y getpass.c getpwent.c getloadavg.c \ Y getttyent.c getttynam.c getusershell.c getwd.c \ Y*************** Y*** 26,32 **** Y telldir.c time.c timezone.c ttyname.c ttyslot.c ualarm.c usleep.c \ Y valloc.c strdup.c strsep.c uname.c wait.c wait3.c waitpid.c Y STDOBJ= abort.o alarm.o atoi.o atol.o calloc.o closedir.o crypt.o \ Y! ctime.o ctype_.o daemon.o devname.o err.o errlst.o execvp.o fakcu.o \ Y fstab.o gcvt.o getenv.o getgrent.o getgrgid.o getgrnam.o getlogin.o \ Y getpass.o getpwent.o getloadavg.o \ Y getttyent.o getttynam.o getusershell.o getwd.o \ Y--- 27,34 ---- Y telldir.c time.c timezone.c ttyname.c ttyslot.c ualarm.c usleep.c \ Y valloc.c strdup.c strsep.c uname.c wait.c wait3.c waitpid.c Y STDOBJ= abort.o alarm.o atoi.o atol.o calloc.o closedir.o crypt.o \ Y! ctime.o ctype_.o daemon.o devname.o disklabel.o err.o errlst.o \ Y! execvp.o fakcu.o \ Y fstab.o gcvt.o getenv.o getgrent.o getgrgid.o getgrnam.o getlogin.o \ Y getpass.o getpwent.o getloadavg.o \ Y getttyent.o getttynam.o getusershell.o getwd.o \ Y*** /usr/src/lib/libc/pdp/gen/Makefile.old Sat Apr 9 00:56:31 1994 Y--- /usr/src/lib/libc/pdp/gen/Makefile Thu Apr 13 22:10:18 1995 Y*************** Y*** 3,15 **** Y # All rights reserved. The Berkeley software License Agreement Y # specifies the terms and conditions for redistribution. Y # Y! # @(#)Makefile 5.6.2 (2.11BSD GTE) 4/9/94 Y # Y! SRCS= _setjmp.s abs.s alloca.s atof.c bcmp.s bcopy.s bzero.s disktab.c \ Y ecvt.c fabs.s ffs.s frexp.s index.s insque.s ldexp.s ldfps.s \ Y modf.s nsym.c remque.s rindex.s rollback.s setjmp.s setjmperr.c \ Y strcat.s strcmp.s strcpy.s strlen.s strncat.s strncmp.s strncpy.s Y! OBJS= _setjmp.o abs.o alloca.o atof.o bcmp.o bcopy.o bzero.o disktab.o \ Y ecvt.o fabs.o ffs.o frexp.o index.o insque.o ldexp.o ldfps.o \ Y modf.o nsym.o remque.o rindex.o rollback.o setjmp.o setjmperr.o \ Y strcat.o strcmp.o strcpy.o strlen.o strncat.o strncmp.o strncpy.o Y--- 3,15 ---- Y # All rights reserved. The Berkeley software License Agreement Y # specifies the terms and conditions for redistribution. Y # Y! # @(#)Makefile 5.6.3 (2.11BSD GTE) 1995/04/13 Y # Y! SRCS= _setjmp.s abs.s alloca.s atof.c bcmp.s bcopy.s bzero.s \ Y ecvt.c fabs.s ffs.s frexp.s index.s insque.s ldexp.s ldfps.s \ Y modf.s nsym.c remque.s rindex.s rollback.s setjmp.s setjmperr.c \ Y strcat.s strcmp.s strcpy.s strlen.s strncat.s strncmp.s strncpy.s Y! OBJS= _setjmp.o abs.o alloca.o atof.o bcmp.o bcopy.o bzero.o \ Y ecvt.o fabs.o ffs.o frexp.o index.o insque.o ldexp.o ldfps.o \ Y modf.o nsym.o remque.o rindex.o rollback.o setjmp.o setjmperr.o \ Y strcat.o strcmp.o strcpy.o strlen.o strncat.o strncmp.o strncpy.o Y*************** Y*** 41,47 **** Y Y tags: Y cwd=`pwd`; \ Y! for i in atof.c disktab.c ecvt.c; do \ Y ctags -a -f ${TAGSFILE} $$cwd/$$i; \ Y done Y Y--- 41,47 ---- Y Y tags: Y cwd=`pwd`; \ Y! for i in atof.c ecvt.c; do \ Y ctags -a -f ${TAGSFILE} $$cwd/$$i; \ Y done Y Y*************** Y*** 75,82 **** Y bcmp.o: bcmp.s ./DEFS.h Y bcopy.o: bcopy.s ./DEFS.h Y bzero.o: bzero.s ./DEFS.h Y- disktab.o: disktab.c /usr/include/disktab.h /usr/include/stdio.h Y- disktab.o: /usr/include/ctype.h Y ecvt.o: ecvt.c Y fabs.o: fabs.s ./DEFS.h Y ffs.o: ffs.s ./DEFS.h Y--- 75,80 ---- SHAR_EOF fi if test -f 'lib.shar' then echo shar: "will not over-write existing file 'lib.shar'" else sed 's/^Y//' << \SHAR_EOF > 'lib.shar' Y#! /bin/sh Y# This is a shell archive, meaning: Y# 1. Remove everything above the #! /bin/sh line. Y# 2. Save the resulting text in a file. Y# 3. Execute the file with /bin/sh (not csh) to create: Y# /usr/src/lib/libc/gen/disklabel.c Y# This archive created: Mon Jun 19 20:23:34 1995 Yexport PATH; PATH=/bin:/usr/bin:$PATH Yif test -f '/usr/src/lib/libc/gen/disklabel.c' Ythen Y echo shar: "will not over-write existing file '/usr/src/lib/libc/gen/disklabel.c'" Yelse Ysed 's/^X//' << \SHAR_EOF > '/usr/src/lib/libc/gen/disklabel.c' YX/* YX * Copyright (c) 1983, 1987 Regents of the University of California. YX * All rights reserved. YX * YX * Redistribution and use in source and binary forms, with or without YX * modification, are permitted provided that the following conditions YX * are met: YX * 1. Redistributions of source code must retain the above copyright YX * notice, this list of conditions and the following disclaimer. YX * 2. Redistributions in binary form must reproduce the above copyright YX * notice, this list of conditions and the following disclaimer in the YX * documentation and/or other materials provided with the distribution. YX * 3. All advertising materials mentioning features or use of this software YX * must display the following acknowledgement: YX * This product includes software developed by the University of YX * California, Berkeley and its contributors. YX * 4. Neither the name of the University nor the names of its contributors YX * may be used to endorse or promote products derived from this software YX * without specific prior written permission. YX * YX * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND YX * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE YX * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE YX * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE YX * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL YX * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS YX * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) YX * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT YX * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY YX * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF YX * SUCH DAMAGE. YX */ YX YX#if defined(LIBC_SCCS) && !defined(lint) YXstatic char sccsid[] = "@(#)disklabel.c 5.17.1 (2.11BSD) 4/10/95"; YX#endif /* LIBC_SCCS and not lint */ YX YX#include YX#include YX#include YX#include YX#include YX YX#define DKTYPENAMES YX#include YX#include YX#include YX YXextern int errno; YX YXstatic char *dgetstr(); YXstatic dgetent(); YXstatic dnamatch(); YXstatic long dgetnum(), _gtnumdflt(); YXstatic dgetflag(); YXstatic gettype(); YXstatic error(); YX YX#define getnumdflt(field, dname, dflt) field=_gtnumdflt(dname,(long)dflt) YX YXstruct disklabel * YXgetdiskbyname(name) YX char *name; YX{ YX static struct disklabel disk; YX static char boot[MAXPATHLEN]; YX char localbuf[256]; /* BUFSIZ reduced to save stack space */ YX char buf[BUFSIZ]; YX char *cp, *cq; /* can't be register */ YX register struct disklabel *dp = &disk; YX register struct partition *pp; YX char p, max, psize[3], pbsize[3], YX pfsize[3], poffset[3], ptype[3]; YX u_long *dx; YX YX if (dgetent(buf, name) <= 0) YX return ((struct disklabel *)0); YX bzero((char *)&disk, sizeof(disk)); YX /* YX * typename YX */ YX cq = dp->d_typename; YX cp = buf; YX while (cq < dp->d_typename + sizeof(dp->d_typename) - 1 && YX (*cq = *cp) && *cq != '|' && *cq != ':') YX cq++, cp++; YX *cq = '\0'; YX /* YX * boot name (optional) xxboot YX */ YX cp = boot; YX dp->d_boot0 = dgetstr("b0", &cp); YX cp = localbuf; YX cq = dgetstr("ty", &cp); YX if (cq && strcmp(cq, "removable") == 0) YX dp->d_flags |= D_REMOVABLE; YX else if (cq && strcmp(cq, "simulated") == 0) YX dp->d_flags |= D_RAMDISK; YX if (dgetflag("sf")) YX dp->d_flags |= D_BADSECT; YX YX/* YX * Have to do this because anything except 512 will cause chaos in YX * disklabel(8). disklabel(8) tries to protect itself against this YX * but the safest thing is to fix the sector size here. The only thing YX * which ever used a value other than 512 was the RL02 and RL01 YX * disktab entries and they have been fixed. YX*/ YX YX#ifdef corrupt_filesystems YX getnumdflt(dp->d_secsize, "se", 512); YX#endif YX dp->d_secsize = 512; YX YX dp->d_ntracks = dgetnum("nt"); YX dp->d_nsectors = dgetnum("ns"); YX dp->d_ncylinders = dgetnum("nc"); YX cq = dgetstr("dt", &cp); YX if (cq) YX dp->d_type = gettype(cq, dktypenames); YX else YX getnumdflt(dp->d_type, "dt", 0); YX getnumdflt(dp->d_secpercyl, "sc", dp->d_nsectors * dp->d_ntracks); YX getnumdflt(dp->d_secperunit, "su", dp->d_secpercyl * dp->d_ncylinders); YX getnumdflt(dp->d_sparespertrack, "rt", 0); YX getnumdflt(dp->d_sparespercyl, "rc", 0); YX getnumdflt(dp->d_acylinders, "ac", 0); YX getnumdflt(dp->d_rpm, "rm", 3600); YX getnumdflt(dp->d_interleave, "il", 1); YX getnumdflt(dp->d_trackskew, "sk", 0); YX getnumdflt(dp->d_cylskew, "cs", 0); YX getnumdflt(dp->d_headswitch, "hs", 0); YX getnumdflt(dp->d_trkseek, "ts", 0); YX YX/* YX * See the comments in src/bin/disklabel.c for a more detailed explaination YX * which the 'bbsize' is set to 512. The simple explanation is that the YX * designers of disklabeling confused 'sectors' and 'filesystem blocks'. YX * BBSIZE is set to 1024 even though the real boot area (what the boot roms YX * will read) is 512. YX*/ YX#ifdef boot_area_really_is_1k YX getnumdflt(dp->d_bbsize, "bs", BBSIZE); YX#endif YX dp->d_bbsize = 512; YX YX getnumdflt(dp->d_sbsize, "sb", SBSIZE); YX strcpy(psize, "px"); YX strcpy(pbsize, "bx"); YX strcpy(pfsize, "fx"); YX strcpy(poffset, "ox"); YX strcpy(ptype, "tx"); YX max = 'a' - 1; YX pp = &dp->d_partitions[0]; YX for (p = 'a'; p < 'a' + MAXPARTITIONS; p++, pp++) { YX psize[1] = pbsize[1] = pfsize[1] = poffset[1] = ptype[1] = p; YX pp->p_size = dgetnum(psize); YX if (pp->p_size == -1L) YX pp->p_size = 0L; YX else { YX pp->p_offset = dgetnum(poffset); YX getnumdflt(pp->p_fsize, pfsize, 0); YX if (pp->p_fsize) YX pp->p_frag = dgetnum(pbsize) / pp->p_fsize; YX getnumdflt(pp->p_fstype, ptype, 0); YX if (pp->p_fstype == 0 && (cq = dgetstr(ptype, &cp))) YX pp->p_fstype = gettype(cq, fstypenames); YX max = p; YX } YX } YX dp->d_npartitions = max + 1 - 'a'; YX (void)strcpy(psize, "dx"); YX dx = dp->d_drivedata; YX for (p = '0'; p < '0' + NDDATA; p++, dx++) { YX psize[1] = p; YX getnumdflt(*dx, psize, 0); YX } YX dp->d_magic = DISKMAGIC; YX dp->d_magic2 = DISKMAGIC; YX return (dp); YX} YX YX#include YX YXstatic char *tbuf; YXstatic char *dskip(); YXstatic char *ddecode(); YX YX/* YX * Get an entry for disk name in buffer bp, YX * from the diskcap file. Parse is very rudimentary; YX * we just notice escaped newlines. YX */ YXstatic YXdgetent(bp, name) YX char *bp, *name; YX{ YX register char *cp; YX register int c; YX register int i = 0, cnt = 0; YX char ibuf[512]; /* BUFSIZE - reduced to conserve stack space */ YX int tf; YX YX tbuf = bp; YX tf = open(_PATH_DISKTAB, 0); YX if (tf < 0) { YX error(errno); YX return (-1); YX } YX for (;;) { YX cp = bp; YX for (;;) { YX if (i == cnt) { YX cnt = read(tf, ibuf, sizeof (ibuf)); YX if (cnt <= 0) { YX error(errno); YX close(tf); YX return (0); YX } YX i = 0; YX } YX c = ibuf[i++]; YX if (c == '\n') { YX if (cp > bp && cp[-1] == '\\'){ YX cp--; YX continue; YX } YX break; YX } YX if (cp >= bp+BUFSIZ) { YX error(EFTYPE); YX break; YX } else YX *cp++ = c; YX } YX *cp = 0; YX YX /* YX * The real work for the match. YX */ YX if (dnamatch(name)) { YX close(tf); YX return (1); YX } YX } YX} YX YX/* YX * Dnamatch deals with name matching. The first field of the disktab YX * entry is a sequence of names separated by |'s, so we compare YX * against each such name. The normal : terminator after the last YX * name (before the first field) stops us. YX */ YXstatic YXdnamatch(np) YX char *np; YX{ YX register char *Np, *Bp; YX YX Bp = tbuf; YX if (*Bp == '#') YX return (0); YX for (;;) { YX for (Np = np; *Np && *Bp == *Np; Bp++, Np++) YX continue; YX if (*Np == 0 && (*Bp == '|' || *Bp == ':' || *Bp == 0)) YX return (1); YX while (*Bp && *Bp != ':' && *Bp != '|') YX Bp++; YX if (*Bp == 0 || *Bp == ':') YX return (0); YX Bp++; YX } YX} YX YX/* YX * Skip to the next field. Notice that this is very dumb, not YX * knowing about \: escapes or any such. If necessary, :'s can be put YX * into the diskcap file in octal. YX */ YXstatic char * YXdskip(bp) YX register char *bp; YX{ YX YX while (*bp && *bp != ':') YX bp++; YX while (*bp == ':') YX bp++; YX return (bp); YX} YX YX/* YX * Return the (numeric) option id. YX * Numeric options look like YX * li#80 YX * i.e. the option string is separated from the numeric value by YX * a # character. If the option is not found we return -1. YX * Note that we handle octal numbers beginning with 0. YX */ YXstatic long YXdgetnum(id) YX char *id; YX{ YX register int base; YX long i; YX register char *bp = tbuf; YX YX for (;;) { YX bp = dskip(bp); YX if (*bp == 0) YX return (-1); YX if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) YX continue; YX if (*bp == '@') YX return (-1); YX if (*bp != '#') YX continue; YX bp++; YX base = 10; YX if (*bp == '0') YX base = 8; YX i = 0; YX while (isdigit(*bp)) YX i *= base, i += *bp++ - '0'; YX return (i); YX } YX} YX YX/* YX * Handle a flag option. YX * Flag options are given "naked", i.e. followed by a : or the end YX * of the buffer. Return 1 if we find the option, or 0 if it is YX * not given. YX */ YXstatic YXdgetflag(id) YX char *id; YX{ YX register char *bp = tbuf; YX YX for (;;) { YX bp = dskip(bp); YX if (!*bp) YX return (0); YX if (*bp++ == id[0] && *bp != 0 && *bp++ == id[1]) { YX if (!*bp || *bp == ':') YX return (1); YX else if (*bp == '@') YX return (0); YX } YX } YX} YX YX/* YX * Get a string valued option. YX * These are given as YX * cl=^Z YX * Much decoding is done on the strings, and the strings are YX * placed in area, which is a ref parameter which is updated. YX * No checking on area overflow. YX */ YXstatic char * YXdgetstr(id, area) YX char *id, **area; YX{ YX register char *bp = tbuf; YX YX for (;;) { YX bp = dskip(bp); YX if (!*bp) YX return (0); YX if (*bp++ != id[0] || *bp == 0 || *bp++ != id[1]) YX continue; YX if (*bp == '@') YX return (0); YX if (*bp != '=') YX continue; YX bp++; YX return (ddecode(bp, area)); YX } YX} YX YX/* YX * Tdecode does the grung work to decode the YX * string capability escapes. YX */ YXstatic char * YXddecode(str, area) YX register char *str; YX char **area; YX{ YX register char *cp; YX register int c; YX register char *dp; YX int i; YX YX cp = *area; YX while ((c = *str++) && c != ':') { YX switch (c) { YX YX case '^': YX c = *str++ & 037; YX break; YX YX case '\\': YX dp = "E\033^^\\\\::n\nr\rt\tb\bf\f"; YX c = *str++; YXnextc: YX if (*dp++ == c) { YX c = *dp++; YX break; YX } YX dp++; YX if (*dp) YX goto nextc; YX if (isdigit(c)) { YX c -= '0', i = 2; YX do YX c <<= 3, c |= *str++ - '0'; YX while (--i && isdigit(*str)); YX } YX break; YX } YX *cp++ = c; YX } YX *cp++ = 0; YX str = *area; YX *area = cp; YX return (str); YX} YX YXstatic YXgettype(t, names) YX char *t; YX char **names; YX{ YX register char **nm; YX YX for (nm = names; *nm; nm++) YX if (strcasecmp(t, *nm) == 0) YX return (nm - names); YX if (isdigit(*t)) YX return (atoi(t)); YX return (0); YX} YX YXstatic YXerror(err) YX int err; YX{ YX struct iovec iov[4]; YX YX iov[0].iov_base = "disktab: "; YX iov[0].iov_len = 9; YX iov[1].iov_base = _PATH_DISKTAB; YX iov[1].iov_len = sizeof (_PATH_DISKTAB) - 1; YX iov[2].iov_base = strerror(err); YX iov[2].iov_len = strlen(iov[2].iov_base); YX iov[3].iov_base = "\n"; YX iov[3].iov_len = 1; YX (void)writev(fileno(stderr), &iov, 4); YX} YX YXstatic long YX_gtnumdflt(dname, dflt) YX char *dname; YX long dflt; YX { YX long f; YX YX f = dgetnum(dname); YX if (f == -1L) YX f = dflt; YX return(f); YX } YSHAR_EOF Yfi Yexit 0 Y# End of shell archive SHAR_EOF fi exit 0 # End of shell archive