--- util-linux-2.11a/disk-utils/mkswap.c.~1~ Thu Mar 8 20:57:26 2001 +++ util-linux-2.11a/disk-utils/mkswap.c Thu Mar 15 22:01:54 2001 @@ -8,11 +8,12 @@ /* * 20.12.91 - time began. Got VM working yesterday by doing this by hand. * - * Usage: mkswap [-c] [-vN] [-f] device [size-in-blocks] + * Usage: mkswap [-c] [-vN] [-f] [-L label] device [size-in-blocks] * * -c for readability checking. (Use it unless you are SURE!) * -vN for swap areas version N. (Only N=0,1 known today.) * -f for forcing swap creation even if it would smash partition table. + * -L for setting the volume label. (Disallows -v0.) * * The device may be a block device or an image of one, but this isn't * enforced (but it's not much fun on a character device :-). @@ -29,6 +30,8 @@ * 1999-02-22 Arkadiusz Mi¶kiewicz * - added Native Language Support * + * 2001-03-15 Mikael Pettersson + * - added volume label support */ #include @@ -160,7 +163,8 @@ unsigned int version; unsigned int last_page; unsigned int nr_badpages; - unsigned int padding[125]; + char volume_label[16]; + char padding[125*sizeof(int)-16]; unsigned int badpages[1]; } *p; @@ -313,7 +317,7 @@ static void usage(void) { fprintf(stderr, - _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] /dev/name [blocks]\n"), + _("Usage: %s [-c] [-v0|-v1] [-pPAGESZ] [-L label] /dev/name [blocks]\n"), program_name); exit(1); } @@ -438,6 +442,7 @@ int force = 0; char *block_count = 0; char *pp; + char *label = 0; program_name = (argc && *argv) ? argv[0] : "fsck.minix"; if ((pp = strrchr(program_name, '/')) != NULL) @@ -462,6 +467,11 @@ case 'f': force=1; break; + case 'L': + label = argv[i]+2; + if (!*label && i+1 < argc) + label = argv[++i]; + break; case 'p': pp = argv[i]+2; if (!*pp && i+1 < argc) @@ -525,6 +535,12 @@ else version = 1; } + if (label && version == 0) { + fprintf(stderr, + _("%s: error: version 0 cannot use volume label\n"), + program_name); + usage(); + } if (version != 0 && version != 1) { fprintf(stderr, _("%s: error: unknown version %d\n"), program_name, version); @@ -598,6 +614,8 @@ p->version = version; p->last_page = PAGES-1; p->nr_badpages = badpages; + if (label) + strncpy(p->volume_label, label, sizeof(p->volume_label)); } goodpages = PAGES - badpages - 1; --- util-linux-2.11a/mount/swapon.c.~1~ Fri Jul 9 04:56:40 1999 +++ util-linux-2.11a/mount/swapon.c Thu Mar 15 22:01:09 2001 @@ -7,9 +7,13 @@ * - added Native Language Support * Sun Mar 21 1999 - Arnaldo Carvalho de Melo * - fixed strerr(errno) in gettext calls - * + * 2001-03-15 Mikael Pettersson + * - added volume label support (adapted from mount_by_label.c) */ +#include +#include +#include #include #include #include @@ -38,6 +42,7 @@ { { "all", 0, 0, 'a' }, { "help", 0, 0, 'h' }, + { "label", required_argument, 0, 'L' }, { "priority", required_argument, 0, 'p' }, { "summary", 0, 0, 's' }, { "verbose", 0, 0, 'v' }, @@ -51,8 +56,9 @@ fprintf (fp, _("usage: %s [-hV]\n" " %s -a [-v]\n" " %s [-v] [-p priority] special ...\n" + " %s [-v] [-p priority] -L label\n" " %s [-s]\n"), - program_name, program_name, program_name, program_name); + program_name, program_name, program_name, program_name, program_name); exit (n); } @@ -78,6 +84,180 @@ #include #endif +/* Try to get PAGE_SIZE from libc or kernel includes */ +#ifdef HAVE_sys_user_h + /* Note: says: for gdb only */ +#include /* for PAGE_SIZE and PAGE_SHIFT */ +#else +#ifdef HAVE_asm_page_h +#include /* for PAGE_SIZE and PAGE_SHIFT */ + /* we also get PAGE_SIZE via getpagesize() */ +#endif +#endif + +static unsigned int pagesize; + +static void init_pagesize(void) +{ + pagesize = getpagesize(); +#ifdef PAGE_SIZE + if (PAGE_SIZE != pagesize) + fprintf(stderr, _("%s: Assuming page size %u, not %lu\n"), + program_name, pagesize, PAGE_SIZE); +#endif +} + +struct swap_header_v1 { + char bootbits[1024]; /* Space for disklabel etc. */ + unsigned int version; + unsigned int last_page; + unsigned int nr_badpages; + char volume_label[16]; + char padding[125*sizeof(int)-16]; + unsigned int badpages[1]; +}; + +#define PROC_PARTITIONS "/proc/partitions" +#define DEVLABELDIR "/dev" + +struct partition_list { + struct partition_list *next; + const char *device; + const char *label; +}; +static struct partition_list *partition_list_head; +static struct partition_list **partition_list_tailp = &partition_list_head; + +static char *get_label(const char *device) +{ + int fd; + char magic[10]; + char label[16+1]; /* +1 for '\0' */ + char *p = NULL; + + fd = open(device, O_RDONLY); + if (fd < 0) + return NULL; + if (lseek(fd, pagesize-10, SEEK_SET) != pagesize-10) + goto out; + if (read(fd, magic, sizeof(magic)) != sizeof(magic)) + goto out; + if (strncmp(magic, "SWAPSPACE2", sizeof(magic)) != 0) + goto out; + if (lseek(fd, offsetof(struct swap_header_v1, volume_label), SEEK_SET) + != offsetof(struct swap_header_v1, volume_label)) + goto out; + if (read(fd, label, sizeof(label)-1) != sizeof(label)-1) + goto out; + label[sizeof(label)-1] = '\0'; + p = strdup(label); + out: + close(fd); + return p; +} + +static void partition_list_append(const char *device, const char *label) +{ + struct partition_list *p; + + p = malloc(sizeof(*p)); + if (!p) { + fprintf(stderr, _("%s: Out of memory\n"), program_name); + exit(1); + } + p->next = NULL; + p->device = device; + p->label = label; + *partition_list_tailp = p; + partition_list_tailp = &p->next; +} + +static void partition_list_init(void) +{ + char line[100]; + char *s; + int ma, mi, sz; + static char ptname[100]; + FILE *procpt; + char *label; + char device[110]; + int firstPass; + int handleOnFirst; + + if (partition_list_head) + return; + + procpt = fopen(PROC_PARTITIONS, "r"); + if (!procpt) { + static int warn = 0; + if (warn == 0) + fprintf(stderr, _("%s: unable to open %s\n"), + program_name, PROC_PARTITIONS); + warn = 1; + return; + } + + init_pagesize(); + + for (firstPass = 1; firstPass >= 0; firstPass--) { + fseek(procpt, 0, SEEK_SET); + + while (fgets(line, sizeof(line), procpt)) { + if (sscanf (line, " %d %d %d %[^\n ]", + &ma, &mi, &sz, ptname) != 4) + continue; + + /* skip extended partitions (heuristic: size 1) */ + if (sz == 1) + continue; + + /* look only at md devices on first pass */ + handleOnFirst = !strncmp(ptname, "md", 2); + if (firstPass != handleOnFirst) + continue; + + /* skip entire disk (minor 0, 64, ... on ide; + 0, 16, ... on sd) */ + /* heuristic: partition name ends in a digit */ + + for(s = ptname; *s; s++) + ; + if (isdigit(s[-1])) { + /* + * Note: this is a heuristic only - there is no reason + * why these devices should live in /dev. + * Perhaps this directory should be specifiable by option. + * One might for example have /devlabel with links to /dev + * for the devices that may be accessed in this way. + * (This is useful, if the cdrom on /dev/hdc must not + * be accessed.) + */ + sprintf(device, "%s/%s", DEVLABELDIR, ptname); + label = get_label(device); + if (label) + partition_list_append(strdup(device), label); + } + } + } + + fclose(procpt); +} + +static const char *find_special_by_label(const char *label) +{ + struct partition_list *partition; + + partition_list_init(); + + partition = partition_list_head; + while (partition) { + if (strcmp(partition->label, label) == 0) + return partition->device; + partition = partition->next; + } + return NULL; +} + static int swap (const char *special, int prio) { @@ -87,6 +267,19 @@ if (verbose) printf(_("%s on %s\n"), program_name, special); + if (strncmp(special, "LABEL=", 6) == 0) { + const char *p = find_special_by_label(special+6); + if (!p) { + fprintf(stderr, _("%s: unable to resolve %s\n"), + program_name, special); + return -1; + } + if (verbose) + printf(_("%s: resolved %s to %s\n"), + program_name, special, p); + special = p; + } + if (streq (program_name, "swapon")) { if (stat(special, &st) < 0) { int errsv = errno; @@ -164,6 +357,7 @@ int status; int all = 0; int c; + char *label = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -174,7 +368,7 @@ else program_name = argv[0]; - while ((c = getopt_long (argc, argv, "ahp:svV", longopts, NULL)) != EOF) + while ((c = getopt_long (argc, argv, "ahL:p:svV", longopts, NULL)) != EOF) switch (c) { case 'a': /* all */ @@ -183,6 +377,9 @@ case 'h': /* help */ usage (stdout, 0); break; + case 'L': /* label */ + label = optarg; + break; case 'p': /* priority */ priority = atoi(optarg); break; @@ -226,6 +423,11 @@ status |= swap (fstab->mnt_fsname, priority); } } + } else if (label) { /* pretend we read LABEL=