From 68c67469aabe112cc0ef90bd87700370d96a4085 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 3 Nov 2009 05:51:20 +0100 Subject: mkswap: add -L LABEL option. closes bug 689. Signed-off-by: Denys Vlasenko --- include/usage.h | 14 +++----- util-linux/mkswap.c | 92 ++++++++++++++++++++++++++--------------------------- 2 files changed, 50 insertions(+), 56 deletions(-) diff --git a/include/usage.h b/include/usage.h index f703e32..0d01577 100644 --- a/include/usage.h +++ b/include/usage.h @@ -2815,17 +2815,11 @@ "$ mknod -m 644 /tmp/pipe p\n" #define mkswap_trivial_usage \ - "DEVICE" + "[OPTIONS] BLOCKDEV" /* [SIZE_IN_KB] */ #define mkswap_full_usage "\n\n" \ - "Prepare block device to be used as swap partition" -#if 0 - "[-c] [-v0|-v1] DEVICE [BLOCKS]" - "\nOptions:" - "\n -c Check for readability" - "\n -v0 Make swap version 0 (max 128M)" - "\n -v1 Make swap version 1 (default for kernels > 2.1.117)" - "\n BLOCKS Number of blocks to use (default is entire partition)" -#endif + "Prepare BLOCKDEV to be used as swap partition\n" \ + "\nOptions:" \ + "\n -L LBL Label" \ #define mktemp_trivial_usage \ "[-dt] [-p DIR] [TEMPLATE]" diff --git a/util-linux/mkswap.c b/util-linux/mkswap.c index 2f7827d..289692d 100644 --- a/util-linux/mkswap.c +++ b/util-linux/mkswap.c @@ -50,72 +50,70 @@ static void mkswap_selinux_setcontext(int fd, const char *path) # define mkswap_selinux_setcontext(fd, path) ((void)0) #endif -#if 0 /* from Linux 2.6.23 */ +/* from Linux 2.6.23 */ /* - * Magic header for a swap area. The first part of the union is - * what the swap magic looks like for the old (limited to 128MB) - * swap area format, the second part of the union adds - in the - * old reserved area - some extra information. Note that the first - * kilobyte is reserved for boot loader or disk label stuff... + * Magic header for a swap area. ... Note that the first + * kilobyte is reserved for boot loader or disk label stuff. */ -union swap_header { - struct { - char reserved[PAGE_SIZE - 10]; - char magic[10]; /* SWAP-SPACE or SWAPSPACE2 */ - } magic; - struct { - char bootbits[1024]; /* Space for disklabel etc. */ - __u32 version; /* second kbyte, word 0 */ - __u32 last_page; /* 1 */ - __u32 nr_badpages; /* 2 */ - unsigned char sws_uuid[16]; /* 3,4,5,6 */ - unsigned char sws_volume[16]; /* 7,8,9,10 */ - __u32 padding[117]; /* 11..127 */ - __u32 badpages[1]; /* 128, total 129 32-bit words */ - } info; +struct swap_header_v1 { +/* char bootbits[1024]; Space for disklabel etc. */ + uint32_t version; /* second kbyte, word 0 */ + uint32_t last_page; /* 1 */ + uint32_t nr_badpages; /* 2 */ + char sws_uuid[16]; /* 3,4,5,6 */ + char sws_volume[16]; /* 7,8,9,10 */ + uint32_t padding[117]; /* 11..127 */ + uint32_t badpages[1]; /* 128 */ + /* total 129 32-bit words in 2nd kilobyte */ }; -#endif #define NWORDS 129 -#define hdr ((uint32_t*)(&bb_common_bufsiz1)) +#define hdr ((struct swap_header_v1*)bb_common_bufsiz1) -struct BUG_bufsiz1_is_too_small { - char BUG_bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1]; +struct BUG_sizes { + char swap_header_v1_wrong[sizeof(*hdr) != (NWORDS * 4) ? -1 : 1]; + char bufsiz1_is_too_small[COMMON_BUFSIZE < (NWORDS * 4) ? -1 : 1]; }; /* Stored without terminating NUL */ static const char SWAPSPACE2[sizeof("SWAPSPACE2")-1] ALIGN1 = "SWAPSPACE2"; int mkswap_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int mkswap_main(int argc, char **argv) +int mkswap_main(int argc UNUSED_PARAM, char **argv) { - int fd, pagesize; + int fd; + unsigned pagesize; off_t len; + const char *label = ""; - // No options supported. - - if (argc != 2) bb_show_usage(); + opt_complementary = "=1"; + /* TODO: -p PAGESZ, -U UUID, + * optional SIZE_IN_KB 2nd param + */ + getopt32(argv, "L:", &label); + argv += optind; - // Figure out how big the device is and announce our intentions. + fd = xopen(argv[0], O_WRONLY); - fd = xopen(argv[1], O_RDWR); + /* Figure out how big the device is and announce our intentions */ /* fdlength was reported to be unreliable - use seek */ len = xlseek(fd, 0, SEEK_END); -#if ENABLE_SELINUX - xlseek(fd, 0, SEEK_SET); -#endif + if (ENABLE_SELINUX) + xlseek(fd, 0, SEEK_SET); + pagesize = getpagesize(); - printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", - len - pagesize); - mkswap_selinux_setcontext(fd, argv[1]); + len -= pagesize; + printf("Setting up swapspace version 1, size = %"OFF_FMT"u bytes\n", len); + mkswap_selinux_setcontext(fd, argv[0]); + + /* Make a header. hdr is zero-filled so far... */ + hdr->version = 1; + hdr->last_page = (uoff_t)len / pagesize; - // Make a header. hdr is zero-filled so far... - hdr[0] = 1; - hdr[1] = (len / pagesize) - 1; if (ENABLE_FEATURE_MKSWAP_UUID) { char uuid_string[32]; - generate_uuid((void*) &hdr[3]); - bin2hex(uuid_string, (void*) &hdr[3], 16); + generate_uuid((void*)hdr->sws_uuid); + bin2hex(uuid_string, hdr->sws_uuid, 16); /* f.e. UUID=dfd9c173-be52-4d27-99a5-c34c6c2ff55f */ printf("UUID=%.8s" "-%.4s-%.4s-%.4s-%.12s\n", uuid_string, @@ -125,16 +123,18 @@ int mkswap_main(int argc, char **argv) uuid_string+8+4+4+4 ); } + safe_strncpy(hdr->sws_volume, label, 16); - // Write the header. Sync to disk because some kernel versions check - // signature on disk (not in cache) during swapon. + /* Write the header. Sync to disk because some kernel versions check + * signature on disk (not in cache) during swapon. */ xlseek(fd, 1024, SEEK_SET); xwrite(fd, hdr, NWORDS * 4); xlseek(fd, pagesize - 10, SEEK_SET); xwrite(fd, SWAPSPACE2, 10); fsync(fd); - if (ENABLE_FEATURE_CLEAN_UP) close(fd); + if (ENABLE_FEATURE_CLEAN_UP) + close(fd); return 0; } -- cgit v1.1