Re: [PATCH]swapinfo: Print or change the label / UUID of a swap partition

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 23, 2010 at 06:32:14PM -0600, Jason Borden wrote:
> Patch file is attached.
> From ac3964c4de87580e06cf10090e8f7c3af9c1aec9 Mon Sep 17 00:00:00 2001
> From: Jason Borden <jborden@xxxxxxxxxxxx>
> Date: Tue, 23 Mar 2010 18:17:07 -0600
> Subject: [PATCH] add swapinfo utility
>  swapinfo is a utility that replaces the previously submitted, but
>  uncommitted, "swaplabel" patch and now includes support for swap
>  partition uuids as well as labels. It has also been updated to use
>  libblkid for partition probing as well as improved error handling.
> 
> Signed-off-by: Jason Borden <jborden@xxxxxxxxxxxx>
> ---
>  disk-utils/Makefile.am |   14 +++-
>  disk-utils/swapinfo.8  |   62 +++++++++++++++++
>  disk-utils/swapinfo.c  |  170 ++++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 243 insertions(+), 3 deletions(-)
>  create mode 100644 disk-utils/swapinfo.8
>  create mode 100644 disk-utils/swapinfo.c

 Applied with some changes, see the patch below. 
 
 I have also renamed the utility from swapinfo to swaplabel. I think the
 original name 'swaplabel' was better (the functionality is similar to
 e2label or so).

 Thanks,

    Karel

>From 4dddc2d4aa37367432f719b7c84cb8084bd7a109 Mon Sep 17 00:00:00 2001
From: Jason Borden <jborden@xxxxxxxxxxxx>
Date: Fri, 2 Apr 2010 15:52:45 +0200
Subject: [PATCH] swaplabel: new command

Print or change the label / UUID of a swap area.

[kzak@xxxxxxxxxx: - code refactoring
                  - add long options
                  - clean up Makefile.am]

Signed-off-by: Jason Borden <jborden@xxxxxxxxxxxx>
Signed-off-by: Karel Zak <kzak@xxxxxxxxxx>
---
 AUTHORS                |    2 +
 disk-utils/.gitignore  |    1 +
 disk-utils/Makefile.am |   36 +++++---
 disk-utils/swaplabel.8 |   66 ++++++++++++++
 disk-utils/swaplabel.c |  226 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/swapheader.h   |    8 ++-
 6 files changed, 325 insertions(+), 14 deletions(-)
 create mode 100644 disk-utils/swaplabel.8
 create mode 100644 disk-utils/swaplabel.c

diff --git a/AUTHORS b/AUTHORS
index 803a76d..b4fbee6 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -35,6 +35,8 @@ AUTHORS (merged projects & commands):
                        Jeremy Katz <katzj@xxxxxxxxxx>
       unshare:         Mikhail Gusarov <dottedmag@xxxxxxxxxxxxx>
       wipefs:          Karel Zak <kzak@xxxxxxxxxx>
+      swaplabel:       Jason Borden <jborden@xxxxxxxxxxxx>
+                       Karel Zak <kzak@xxxxxxxxxx>
 
 
 CONTRIBUTORS:
diff --git a/disk-utils/.gitignore b/disk-utils/.gitignore
index 726008f..c97b342 100644
--- a/disk-utils/.gitignore
+++ b/disk-utils/.gitignore
@@ -10,3 +10,4 @@ mkswap
 mkfs.cramfs
 elvtune
 raw
+swaplabel
diff --git a/disk-utils/Makefile.am b/disk-utils/Makefile.am
index ed0a6e4..67aeae4 100644
--- a/disk-utils/Makefile.am
+++ b/disk-utils/Makefile.am
@@ -5,17 +5,32 @@ if LINUX
 utils_common += ../lib/linux_version.c
 endif
 
+if HAVE_UUID
+if BUILD_LIBUUID
+uuid_cflags = -I$(ul_libuuid_srcdir)
+uuid_ldadd = $(ul_libuuid_la)
+else
+uuid_cflags = $(UUID_CFLAGS)
+uuid_ldadd = $(UUID_LIBS)
+endif
+endif
+
 dist_man_MANS = isosize.8 mkfs.8 mkswap.8 \
            fsck.minix.8 mkfs.minix.8 mkfs.bfs.8
 
 sbin_PROGRAMS = mkfs mkswap fsck.minix mkfs.minix mkfs.bfs
+
 fsck_minix_SOURCES = fsck.minix.c minix.h
 mkfs_minix_SOURCES = mkfs.minix.c minix.h $(utils_common)
 mkfs_bfs_SOURCES = mkfs.bfs.c $(utils_common)
 
+swaplabel_SOURCES = swaplabel.c $(utils_common)
+swaplabel_LDADD = $(uuid_ldadd)
+swaplabel_CFLAGS = $(AM_CFLAGS) $(uuid_cflags)
+
 mkswap_SOURCES = mkswap.c $(utils_common) ../lib/wholedisk.c
-mkswap_LDADD =
-mkswap_CFLAGS = $(AM_CFLAGS)
+mkswap_LDADD = $(uuid_ldadd)
+mkswap_CFLAGS = $(AM_CFLAGS) $(uuid_cflags)
 
 usrbin_exec_PROGRAMS = isosize
 usrsbin_exec_PROGRAMS =
@@ -27,6 +42,13 @@ usrsbin_exec_PROGRAMS += fdformat
 blockdev_SOURCES = blockdev.c $(utils_common)
 endif
 
+if BUILD_LIBBLKID
+sbin_PROGRAMS += swaplabel
+dist_man_MANS += swaplabel.8
+swaplabel_LDADD += $(ul_libblkid_la)
+swaplabel_CFLAGS += -I$(ul_libblkid_incdir)
+endif
+
 if BUILD_ELVTUNE
 sbin_PROGRAMS += elvtune
 dist_man_MANS += elvtune.8
@@ -49,16 +71,6 @@ fsck_cramfs_LDADD = -lz
 mkfs_cramfs_LDADD = -lz
 endif
 
-if HAVE_UUID
-if BUILD_LIBUUID
-mkswap_LDADD += $(ul_libuuid_la)
-mkswap_CFLAGS += -I$(ul_libuuid_srcdir)
-else
-mkswap_LDADD += $(UUID_LIBS)
-mkswap_CFLAGS += $(UUID_CFLAGS)
-endif
-endif
-
 if BUILD_LIBBLKID
 # only in-tree libblkid has partitions parsing support
 mkswap_LDADD += $(ul_libblkid_la)
diff --git a/disk-utils/swaplabel.8 b/disk-utils/swaplabel.8
new file mode 100644
index 0000000..aade3ca
--- /dev/null
+++ b/disk-utils/swaplabel.8
@@ -0,0 +1,66 @@
+.\" Copyright 2010 Jason Borden <jborden@xxxxxxxxxxxx>
+.\"
+.\" This file may be copied under the terms of the GNU Public License.
+.\"
+.TH SWAPLABEL 8 "2 April 2010" "Linux" "Linux Programmer's Manual"
+.SH NAME
+swaplabel \- Print or change the label / UUID of a swap area
+.SH SYNOPSIS
+.B swaplabel
+.RB [ \-L
+.IR label ]
+.RB [ \-U
+.IR UUID ]
+.I device
+.SH DESCRIPTION
+.B swaplabel
+will display or change the label / UUID of a swap partition located on
+.IR device 
+(or regular file).
+.PP
+If the optional arguments
+.B \-L 
+and
+.B \-U 
+are not present,
+.B swaplabel
+will simply display the awap area label and UUID of
+.IR device .
+.PP
+If an optional argument is present, then
+.B swaplabel
+will change the appropriate value of
+.IR device .
+These values can also be set during swap creation using
+.BR mkswap (8).
+The
+.B swaplabel
+utility allows to change the label or UUID on actively used swap device.
+.SH OPTIONS
+.IP "\fB\-h, \-\-help\fP"
+Print help and exit.
+.IP "\fB\-L, \-\-label\fP \fIlabel\fP"
+Specify a new label for
+.IR device .
+Swap partition labels can be at most 16 characters long.  If
+.IR label
+is longer than 16 characters,
+.B swapinfo
+will truncate it and print a warning message.
+.IP "\fB\-U, \-\-uuid\fP \fIuuid\fP"
+Specify a new UUID for
+.IR device .
+.IR UUID
+must be in the standard 8-4-4-4-12 character format, such as is ouput by
+.BR uuidgen (1) .
+.PP
+.SH AUTHOR
+.B swaplabel
+was written by Jason Borden <jborden@xxxxxxxxxxxx> and Karel Zak <kzak@xxxxxxxxxx>.
+.SH AVAILABILITY
+.B swaplabel
+is part of the util-linux-ng package and is available from ftp://ftp.kernel.org/pub/linux/utils/util-linux-ng/.
+.SH SEE ALSO
+.BR mkswap (8),
+.BR swapon (8),
+.BR uuidgen (1)
diff --git a/disk-utils/swaplabel.c b/disk-utils/swaplabel.c
new file mode 100644
index 0000000..6341972
--- /dev/null
+++ b/disk-utils/swaplabel.c
@@ -0,0 +1,226 @@
+/*
+ * swaplabel.c - Print or change the label / UUID of a swap partition
+ *
+ * Copyright (C) 2010 Jason Borden <jborden@xxxxxxxxxxxx>
+ * Copyright (C) 2010 Karel Zak <kzak@xxxxxxxxxx>
+ *
+ * Usage: swaplabel [-L label] [-U UUID] device
+ *
+ * This file may be redistributed under the terms of the GNU Public License
+ * version 2 or later.
+ *
+ */
+#include <stdio.h>
+#include <stddef.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <err.h>
+#include <blkid.h>
+#include <getopt.h>
+
+#ifdef HAVE_LIBUUID
+# ifdef HAVE_UUID_UUID_H
+#  include <uuid/uuid.h>
+# else
+#  include <uuid.h>
+# endif
+#endif
+
+#include "c.h"
+#include "writeall.h"
+#include "swapheader.h"
+#include "xstrncpy.h"
+#include "nls.h"
+
+#define SWAP_UUID_OFFSET	(offsetof(struct swap_header_v1_2, uuid))
+#define SWAP_LABEL_OFFSET	(offsetof(struct swap_header_v1_2, volume_name))
+
+/*
+ * Returns new libblkid prober. This function call exit() on error.
+ */
+static blkid_probe get_swap_prober(const char *devname)
+{
+	blkid_probe pr;
+	int rc;
+	const char *version = NULL;
+	char *swap_filter[] = { "swap", NULL };
+
+	pr = blkid_new_probe_from_filename(devname);
+	if (!pr) {
+		warn(_("%s: unable to probe device"), devname);
+		return NULL;
+	}
+
+	blkid_probe_enable_superblocks(pr, TRUE);
+	blkid_probe_set_superblocks_flags(pr,
+			BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
+			BLKID_SUBLKS_VERSION);
+
+	blkid_probe_filter_superblocks_type(pr, BLKID_FLTR_ONLYIN, swap_filter);
+
+	rc = blkid_do_safeprobe(pr);
+	if (rc == -1)
+		warn(_("%s: unable to probe device"), devname);
+	else if (rc == -2)
+		warnx(_("%s: ambivalent probing result, use wipefs(8)"), devname);
+	else if (rc == 1)
+		warnx(_("%s: not a valid swap partition"), devname);
+
+	if (rc == 0) {
+		/* supported is SWAPSPACE2 only */
+		blkid_probe_lookup_value(pr, "VERSION", &version, NULL);
+		if (strcmp(version, "2"))
+			warnx(_("%s: unsupported swap version '%s'"),
+						devname, version);
+		else
+			return pr;
+	}
+
+	blkid_free_probe(pr);
+	return NULL;
+}
+
+/* Print the swap partition information */
+static int print_info(blkid_probe pr, const char *devname)
+{
+	const char *data;
+
+	if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
+		printf("LABEL: %s\n", data);
+
+	if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL))
+		printf("UUID:  %s\n", data);
+
+	return 0;
+}
+
+/* Change the swap partition info */
+static int change_info(const char *devname, const char *label, const char *uuid)
+{
+	int fd;
+
+	fd = open(devname, O_RDWR);
+	if (fd < 0) {
+		warn(_("%s: failed to open"), devname);
+		goto err;
+	}
+#ifdef HAVE_LIBUUID
+	/* Write the uuid if it was provided */
+	if (uuid) {
+		uuid_t newuuid;
+
+		if (uuid_parse(uuid, newuuid) == -1)
+			warnx(_("failed to parse UUID: %s"), uuid);
+		else {
+			if (lseek(fd, SWAP_UUID_OFFSET, SEEK_SET) !=
+							SWAP_UUID_OFFSET) {
+				warn(_("%s: failed to seek to swap UUID"), devname);
+				goto err;
+
+			} else if (write_all(fd, newuuid, sizeof(newuuid))) {
+				warn(_("%s: failed to write UUID"), devname);
+				goto err;
+			}
+		}
+	}
+#endif
+	/* Write the label if it was provided */
+	if (label) {
+		char newlabel[SWAP_LABEL_LENGTH];
+
+		if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET) {
+			warn(_("%s: failed to seek to swap label "), devname);
+			goto err;
+		}
+		memset(newlabel, 0, sizeof(newlabel));
+		xstrncpy(newlabel, label, sizeof(newlabel));
+
+		if (strlen(label) > strlen(newlabel))
+			warnx(_("label is too long. Truncating it to '%s'"),
+					newlabel);
+		if (write_all(fd, newlabel, sizeof(newlabel))) {
+			warn(_("%s: failed to write label"), devname);
+			goto err;
+		}
+	}
+
+	close(fd);
+	return 0;
+err:
+	if (fd >= 0)
+		close(fd);
+	return -1;
+}
+
+static void __attribute__((__noreturn__)) usage(FILE *out)
+{
+	fprintf(out, _("Usage: %s [options] <device>\n\nOptions:\n"),
+			program_invocation_short_name);
+
+	fprintf(out, _(
+		" -h, --help          this help\n"
+		" -L, --label <label> specify a new label\n"
+		" -U, --uuid <uuid>   specify a new uuid\n"));
+
+	fprintf(out, _("\nFor more information see swaplabel(8).\n"));
+
+	exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+int main(int argc, char *argv[])
+{
+	blkid_probe pr = NULL;
+	char *uuid = NULL, *label = NULL, *devname;
+	int c, rc = -1;
+
+	struct option longopts[] = {
+	    { "help",      0, 0, 'h' },
+	    { "label",     1, 0, 'L' },
+	    { "uuid",      1, 0, 'U' },
+	    { NULL,        0, 0, 0 }
+	};
+
+	setlocale(LC_ALL, "");
+	bindtextdomain(PACKAGE, LOCALEDIR);
+	textdomain(PACKAGE);
+
+	while ((c = getopt_long(argc, argv, "hL:U:", longopts, NULL)) != -1) {
+		switch (c) {
+		case 'h':
+			usage(stdout);
+			break;
+		case 'L':
+			label = optarg;
+			break;
+		case 'U':
+#ifdef HAVE_LIBUUID
+			uuid = optarg;
+#else
+			warnx(_("ignore -U (UUIDs are unsupported)"));
+#endif
+			break;
+		default:
+			usage(stderr);
+			break;
+		}
+	}
+
+	if (optind == argc)
+		usage(stderr);
+
+	devname = argv[optind];
+	pr = get_swap_prober(devname);
+	if (pr) {
+		if (uuid || label)
+			rc = change_info(devname, label, uuid);
+		else
+			rc  = print_info(pr, devname);
+		blkid_free_probe(pr);
+	}
+	return rc ? EXIT_FAILURE : EXIT_SUCCESS;
+}
+
diff --git a/include/swapheader.h b/include/swapheader.h
index 6ff5390..42d521a 100644
--- a/include/swapheader.h
+++ b/include/swapheader.h
@@ -10,13 +10,17 @@ struct swap_header_v1 {
 	unsigned int badpages[1];
 };
 
+
+#define SWAP_UUID_LENGTH 16
+#define SWAP_LABEL_LENGTH 16
+
 struct swap_header_v1_2 {
 	char	      bootbits[1024];    /* Space for disklabel etc. */
 	unsigned int  version;
 	unsigned int  last_page;
 	unsigned int  nr_badpages;
-	unsigned char uuid[16];
-	char	      volume_name[16];
+	unsigned char uuid[SWAP_UUID_LENGTH];
+	char	      volume_name[SWAP_LABEL_LENGTH];
 	unsigned int  padding[117];
 	unsigned int  badpages[1];
 };
-- 
1.6.6

--
To unsubscribe from this list: send the line "unsubscribe util-linux-ng" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [Kernel Newbies]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux