swaplabel: new command
Print or change the label / UUID of a swap area. [kzak@redhat.com: - code refactoring - add long options - clean up Makefile.am] Signed-off-by: Jason Borden <jborden@bluehost.com> Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
1f7a33f135
commit
4dddc2d4aa
2
AUTHORS
2
AUTHORS
|
@ -35,6 +35,8 @@ AUTHORS (merged projects & commands):
|
|||
Jeremy Katz <katzj@redhat.com>
|
||||
unshare: Mikhail Gusarov <dottedmag@dottedmag.net>
|
||||
wipefs: Karel Zak <kzak@redhat.com>
|
||||
swaplabel: Jason Borden <jborden@bluehost.com>
|
||||
Karel Zak <kzak@redhat.com>
|
||||
|
||||
|
||||
CONTRIBUTORS:
|
||||
|
|
|
@ -10,3 +10,4 @@ mkswap
|
|||
mkfs.cramfs
|
||||
elvtune
|
||||
raw
|
||||
swaplabel
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
.\" Copyright 2010 Jason Borden <jborden@bluehost.com>
|
||||
.\"
|
||||
.\" 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@bluehost.com> and Karel Zak <kzak@redhat.com>.
|
||||
.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)
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* swaplabel.c - Print or change the label / UUID of a swap partition
|
||||
*
|
||||
* Copyright (C) 2010 Jason Borden <jborden@bluehost.com>
|
||||
* Copyright (C) 2010 Karel Zak <kzak@redhat.com>
|
||||
*
|
||||
* 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;
|
||||
}
|
||||
|
|
@ -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];
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue