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

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

 



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

diff --git a/disk-utils/Makefile.am b/disk-utils/Makefile.am
index ed0a6e4..af9c3d2 100644
--- a/disk-utils/Makefile.am
+++ b/disk-utils/Makefile.am
@@ -6,13 +6,15 @@ utils_common += ../lib/linux_version.c
 endif
 
 dist_man_MANS = isosize.8 mkfs.8 mkswap.8 \
-           fsck.minix.8 mkfs.minix.8 mkfs.bfs.8
+           fsck.minix.8 mkfs.minix.8 mkfs.bfs.8 swapinfo.8
 
-sbin_PROGRAMS = mkfs mkswap fsck.minix mkfs.minix mkfs.bfs
+sbin_PROGRAMS = mkfs mkswap fsck.minix mkfs.minix mkfs.bfs swapinfo
 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)
-
+swapinfo_SOURCES = swapinfo.c $(utils_common)
+swapinfo_LDADD =
+swapinfo_CFLAGS = $(AM_CFLAGS)
 mkswap_SOURCES = mkswap.c $(utils_common) ../lib/wholedisk.c
 mkswap_LDADD =
 mkswap_CFLAGS = $(AM_CFLAGS)
@@ -53,9 +55,13 @@ if HAVE_UUID
 if BUILD_LIBUUID
 mkswap_LDADD += $(ul_libuuid_la)
 mkswap_CFLAGS += -I$(ul_libuuid_srcdir)
+swapinfo_LDADD += $(ul_libuuid_la)
+swapinfo_CFLAGS += -I$(ul_libuuid_srcdir)
 else
 mkswap_LDADD += $(UUID_LIBS)
 mkswap_CFLAGS += $(UUID_CFLAGS)
+swapinfo_LDADD += $(UUID_LIBS)
+swapinfo_CFLAGS += $(UUID_CFLAGS)
 endif
 endif
 
@@ -63,6 +69,8 @@ if BUILD_LIBBLKID
 # only in-tree libblkid has partitions parsing support
 mkswap_LDADD += $(ul_libblkid_la)
 mkswap_CFLAGS += -I$(ul_libblkid_incdir)
+swapinfo_LDADD += $(ul_libblkid_la)
+swapinfo_CFLAGS += -I$(ul_libblkid_incdir)
 endif
 
 if HAVE_SELINUX
diff --git a/disk-utils/swapinfo.8 b/disk-utils/swapinfo.8
new file mode 100644
index 0000000..eb300ac
--- /dev/null
+++ b/disk-utils/swapinfo.8
@@ -0,0 +1,62 @@
+.\" Copyright 2010 Jason Borden <jborden@xxxxxxxxxxxx>
+.\"
+.\" This file may be copied under the terms of the GNU Public License.
+.\"
+.TH SWAPINFO 8 "4 March 2010" "Linux" "Linux Programmer's Manual"
+.SH NAME
+swapinfo \- Print or change the label / UUID of a swap partition
+.SH SYNOPSIS
+.B swapinfo
+.RB [ \-L
+.IR label ]
+.RB [ \-U
+.IR UUID ]
+.I device
+.SH DESCRIPTION
+.B swapinfo
+will display or change the label / UUID of a swap partition located on
+.IR device .
+.PP
+If the optional arguments
+.B \-L 
+and
+.B \-U 
+are not present,
+.B swapinfo
+will simply display the partiton label and UUID of
+.IR device .
+.PP
+If an optional argument is present, then
+.B swapinfo
+will change the appropriate value of
+.IR device .
+These values can also be set during swap creation using
+.BR mkswap (8).
+.SH OPTIONS
+.TP
+.BI \-L \ label
+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.
+.TP
+.BI \-U \ UUID
+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 swapinfo
+was written by Jason Borden <jborden@xxxxxxxxxxxx>.
+.SH AVAILABILITY
+.B swapinfo
+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/swapinfo.c b/disk-utils/swapinfo.c
new file mode 100644
index 0000000..9af14b0
--- /dev/null
+++ b/disk-utils/swapinfo.c
@@ -0,0 +1,170 @@
+/*
+ * swapinfo.c - Print or change the label / UUID of a swap partition
+ *
+ * Copyright 2010 Jason Borden <jborden@xxxxxxxxxxxx>
+ *
+ * Usage: swapinfo [-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 <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>
+
+#ifdef HAVE_LIBUUID
+# ifdef HAVE_UUID_UUID_H
+#  include <uuid/uuid.h>
+# else
+#  include <uuid.h>
+# endif
+#endif
+
+#include "c.h"
+#include "nls.h"
+
+#define SWAP_UUID_OFFSET 0x40C
+#define SWAP_UUID_LENGTH 16
+
+#define SWAP_LABEL_OFFSET 0x41C
+#define SWAP_LABEL_LENGTH 16
+
+char *swap_filter[] = { "swap", 0 };
+
+/* Print the swap partition information */
+static void print_info(const char *devname)
+{
+    const char *version, *label, *uuid;
+    blkid_probe bprobe;
+    int retcode;
+
+    bprobe = blkid_new_probe_from_filename(devname);
+    if (!bprobe)
+        err(EXIT_FAILURE, _("Unable to probe device %s"), devname);
+    
+    blkid_probe_enable_superblocks(bprobe, TRUE);
+    blkid_probe_set_superblocks_flags(bprobe, BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
+        BLKID_SUBLKS_VERSION);
+    blkid_probe_filter_superblocks_type(bprobe, BLKID_FLTR_ONLYIN, swap_filter);
+
+    retcode = blkid_do_safeprobe(bprobe);
+    if (retcode == -1)
+        err(EXIT_FAILURE, _("Unable to probe device %s"), devname);
+    else if (retcode == 1)
+        errx(EXIT_FAILURE, _("%s is not a valid swap partition"), devname);
+
+    blkid_probe_lookup_value(bprobe, "VERSION", &version, NULL);
+    blkid_probe_lookup_value(bprobe, "LABEL", &label, NULL);
+    blkid_probe_lookup_value(bprobe, "UUID", &uuid, NULL);
+
+    if (*version == '1')
+        printf(_("Version 1 swap partitions do not have labels or UUIDs\n"));
+    else
+    {
+        printf(_("LABEL: %s\n"), label);
+        printf(_("UUID: %s\n"), uuid);
+    }
+    blkid_free_probe(bprobe);
+}
+
+/* Change the swap partition info */
+static void change_info(const char *label,  
+        const char *uuid, const char *devname)
+{
+    const char *version;
+    char newlabel[SWAP_LABEL_LENGTH + 1];
+    uuid_t newuuid;
+    blkid_probe bprobe;
+    int retcode, fd;
+
+    bprobe = blkid_new_probe_from_filename(devname);
+    if (!bprobe)
+        err(EXIT_FAILURE, _("Unable to probe device %s"), devname);
+    
+    blkid_probe_enable_superblocks(bprobe, TRUE);
+    blkid_probe_set_superblocks_flags(bprobe, BLKID_SUBLKS_VERSION);
+    blkid_probe_filter_superblocks_type(bprobe, BLKID_FLTR_ONLYIN, swap_filter);
+
+    retcode = blkid_do_safeprobe(bprobe);
+    if (retcode == -1)
+        err(EXIT_FAILURE, _("Unable to probe device %s"), devname);
+    else if (retcode == 1)
+        errx(EXIT_FAILURE, _("%s is not a valid swap partition"), devname);
+
+    blkid_probe_lookup_value(bprobe, "VERSION", &version, NULL);
+
+    /* Validate the swap is version 2 */
+    if (*version != '2')
+        errx(EXIT_FAILURE, _("Cannot set label or UUID on version %s swap partitions"), version);
+    else 
+    {
+        blkid_free_probe(bprobe);
+        fd = open(devname, O_RDWR);
+        if (fd < 0)
+            err(EXIT_FAILURE, _("Unable to open %s"), devname);
+
+        /* Write the uuid if it was provided */
+        if (uuid)
+        {
+            if (uuid_parse(uuid, newuuid) == -1)
+                errx(EXIT_FAILURE, _("Invalid UUID: %s"), uuid);
+            if (lseek(fd, SWAP_UUID_OFFSET, SEEK_SET) != SWAP_UUID_OFFSET)
+                err(EXIT_FAILURE, _("Cannot seek to swap UUID"));
+            if (write(fd, newuuid, SWAP_UUID_LENGTH) != SWAP_UUID_LENGTH)
+                err(EXIT_FAILURE, _("Error writing UUID"));            
+        }
+
+        /* Write the label if it was provided */
+        if (label)
+        {
+            if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET)
+                err(EXIT_FAILURE, _("Cannot seek to swap label"));
+            memset(newlabel, 0, sizeof(newlabel));
+            strncpy(newlabel, label, SWAP_LABEL_LENGTH);
+            if (strlen(label) > SWAP_LABEL_LENGTH)
+                warnx(_("Label is too long. Truncating it to %s"), newlabel);
+            if (write(fd, newlabel, SWAP_LABEL_LENGTH) != SWAP_LABEL_LENGTH)
+                err(EXIT_FAILURE, _("Error writing label"));
+        }
+        close(fd);
+    }
+}
+
+int main(int argc, char *argv[])
+{
+    char *uuid = NULL, *label = NULL, *devname;
+    int opt;
+
+    while ((opt = getopt(argc, argv, "L:U:")) != -1)
+    {
+        switch (opt)
+        {
+            case 'L':
+                label = optarg;
+                break;
+            case 'U':
+                uuid = optarg;
+                break;
+            default:
+                errx(EXIT_FAILURE, _("Usage: %s [-L label] [-U UUID] device"), argv[0]);
+        }
+    }
+    if (optind != argc-1)
+        errx(EXIT_FAILURE, _("Usage: %s [-L label] [-U uuid] device"), argv[0]);
+    devname = argv[optind];
+
+    if (label || uuid)
+        change_info(label, uuid, devname);
+    else
+        print_info(devname);
+    return EXIT_SUCCESS;
+}
+
-- 
1.7.0.2


[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