mkswap: add -L LABEL option. closes bug 689.
authorDenys Vlasenko <vda.linux@googlemail.com>
Tue, 3 Nov 2009 04:51:20 +0000 (05:51 +0100)
committerDenys Vlasenko <vda.linux@googlemail.com>
Tue, 3 Nov 2009 04:51:20 +0000 (05:51 +0100)
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
include/usage.h
util-linux/mkswap.c

index f703e32500c9380161203a4e51defe04ff855294..0d01577c7058ba9f86668d0d41a6e1f638594409 100644 (file)
        "$ 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]"
index 2f7827d6fa6d53b0f0f62b9a117cfed2dd1d4481..289692da3f245900e8689a92c3ea572c12ee4165 100644 (file)
@@ -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;
 }