/* * swaplabel.c - Print or change the label / UUID of a swap partition * * Copyright (C) 2010 Jason Borden * Copyright (C) 2010 Karel Zak * * 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 #include #include #include #include #include #include #include #include #include #ifdef HAVE_LIBUUID # include #endif #include "c.h" #include "writeall.h" #include "swapheader.h" #include "strutils.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] \n\nOptions:\n"), program_invocation_short_name); fprintf(out, _( " -h, --help this help\n" " -L, --label