diff options
author | joerg <joerg@FreeBSD.org> | 2001-07-13 16:48:56 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 2001-07-13 16:48:56 +0000 |
commit | 43c5cead2a08c914b399e0c5e0fdc5c2b9249f37 (patch) | |
tree | 48a6bee3e1dabae938db37f7587c91e40f133b2c /sbin/fdisk/fdisk.c | |
parent | ef89f431f1881652b00827f6313e66beceab856b (diff) | |
download | FreeBSD-src-43c5cead2a08c914b399e0c5e0fdc5c2b9249f37.zip FreeBSD-src-43c5cead2a08c914b399e0c5e0fdc5c2b9249f37.tar.gz |
After some (long-standing ;-) critics from Bruce, throw away the old
device search code i introduce nearly six years ago in rev 1.8. Bruce
suggested to rather use the device name of the root filesystem instead
which is certainly the most sensible default. Since there are many
possible cases for a root filesystem name (device with and without
slices, consider /dev/vinum/root even though it currently could not
work as such), there's some heuristic using a RE in order to find out
the canonical device name from the mounted name. This probably won't
quite fit for a NFS root (can't test that right now), but then,
there's hard to find a good default for those machines anyway. ;-)
This unbreaks the functionality of rev 1.2 i once broke in 1.8. :)
Diffstat (limited to 'sbin/fdisk/fdisk.c')
-rw-r--r-- | sbin/fdisk/fdisk.c | 90 |
1 files changed, 60 insertions, 30 deletions
diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index 1cb2ec3..2f47567 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -30,11 +30,15 @@ static const char rcsid[] = #endif /* not lint */ #include <sys/disklabel.h> +#include <sys/param.h> #include <sys/stat.h> +#include <sys/mount.h> #include <ctype.h> #include <fcntl.h> #include <err.h> #include <errno.h> +#include <paths.h> +#include <regex.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -66,11 +70,7 @@ static char lbuf[LBUF]; #define MIN_SEC_SIZE 512 /* the sector size to start sensing at */ int secsize = 0; /* the sensed sector size */ -const char *disk; -const char *disks[] = -{ - "/dev/ad0", "/dev/da0", 0 -}; +char *disk; struct disklabel disklabel; /* disk parameters */ @@ -197,6 +197,7 @@ static void print_params(); static void change_active(int which); static void change_code(); static void get_params_to_use(); +static char *get_rootdisk(void); static void dos(int sec, int size, unsigned char *c, unsigned char *s, unsigned char *h); static int open_disk(int u_flag); @@ -221,6 +222,7 @@ static int string(char *str, char **ans); int main(int argc, char *argv[]) { + struct stat sb; int c, i; while ((c = getopt(argc, argv, "BIab:f:istuv1234")) != -1) @@ -271,34 +273,26 @@ main(int argc, char *argv[]) argc -= optind; argv += optind; - if (argc > 0) - { - static char realname[12]; - - if(strncmp(argv[0], "/dev", 4) == 0) + if (argc == 0) { + disk = get_rootdisk(); + } else { + if (stat(argv[0], &sb) == 0) { + /* OK, full pathname given */ + disk = argv[0]; + } else if (errno == ENOENT) { + /* Try prepending "/dev" */ + if ((disk = malloc(strlen(argv[0]) + strlen(_PATH_DEV) + + 1)) == NULL) + errx(1, "out of memory"); + strcpy(disk, _PATH_DEV); + strcat(disk, argv[0]); + } else { + /* other stat error, let it fail below */ disk = argv[0]; - else - { - snprintf(realname, 12, "/dev/%s", argv[0]); - disk = realname; - } - - if (open_disk(u_flag) < 0) - err(1, "cannot open disk %s", disk); - } - else - { - int rv = 0; - - for(i = 0; disks[i]; i++) - { - disk = disks[i]; - rv = open_disk(u_flag); - if(rv != -2) break; } - if(rv < 0) - err(1, "cannot open any disk"); } + if (open_disk(u_flag) < 0) + err(1, "cannot open disk %s", disk); /* (abu)use mboot.bootinst to probe for the sector size */ if ((mboot.bootinst = malloc(MAX_SEC_SIZE)) == NULL) @@ -1453,3 +1447,39 @@ sanitize_partition(partp) return (1); } + +/* + * Try figuring out the root device's canonical disk name. + * The following choices are considered: + * /dev/ad0s1a => /dev/ad0 + * /dev/da0a => /dev/da0 + * /dev/vinum/root => /dev/vinum/root + */ +static char * +get_rootdisk(void) +{ + struct statfs rootfs; + regex_t re; +#define NMATCHES 2 + regmatch_t rm[NMATCHES]; + char *s; + int rv; + + if (statfs("/", &rootfs) == -1) + err(1, "statfs(\"/\")"); + + if ((rv = regcomp(&re, "^(/dev/.*)(\\d+(s\\d+)?[a-h])?$", + REG_EXTENDED)) != 0) + errx(1, "regcomp() failed (%d)", rv); + if ((rv = regexec(&re, rootfs.f_mntfromname, NMATCHES, rm, 0)) != 0) + errx(1, +"mounted root fs resource doesn't match expectations (regexec returned %d)", + rv); + if ((s = malloc(rm[1].rm_eo - rm[1].rm_so + 1)) == NULL) + errx(1, "out of memory"); + memcpy(s, rootfs.f_mntfromname + rm[1].rm_so, + rm[1].rm_eo - rm[1].rm_so); + s[rm[1].rm_eo - rm[1].rm_so] = 0; + + return s; +} |