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