2 * swaplabel.c - Print or change the label / UUID of a swap partition
4 * Copyright (C) 2010 Jason Borden <jborden@bluehost.com>
5 * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
7 * Usage: swaplabel [-L label] [-U UUID] device
9 * This file may be redistributed under the terms of the GNU Public License
17 #include <sys/types.h>
29 #include "closestream.h"
31 #include "swapheader.h"
35 #define SWAP_UUID_OFFSET (offsetof(struct swap_header_v1_2, uuid))
36 #define SWAP_LABEL_OFFSET (offsetof(struct swap_header_v1_2, volume_name))
39 * Returns new libblkid prober. This function call exit() on error.
41 static blkid_probe
get_swap_prober(const char *devname
)
45 const char *version
= NULL
;
46 char *swap_filter
[] = { "swap", NULL
};
48 pr
= blkid_new_probe_from_filename(devname
);
50 warn(_("%s: unable to probe device"), devname
);
54 blkid_probe_enable_superblocks(pr
, TRUE
);
55 blkid_probe_set_superblocks_flags(pr
,
56 BLKID_SUBLKS_LABEL
| BLKID_SUBLKS_UUID
|
57 BLKID_SUBLKS_VERSION
);
59 blkid_probe_filter_superblocks_type(pr
, BLKID_FLTR_ONLYIN
, swap_filter
);
61 rc
= blkid_do_safeprobe(pr
);
63 warn(_("%s: unable to probe device"), devname
);
65 warnx(_("%s: ambivalent probing result, use wipefs(8)"), devname
);
67 warnx(_("%s: not a valid swap partition"), devname
);
70 /* supported is SWAPSPACE2 only */
71 if (blkid_probe_lookup_value(pr
, "VERSION", &version
, NULL
) == 0
73 && strcmp(version
, "2"))
74 warnx(_("%s: unsupported swap version '%s'"),
84 /* Print the swap partition information */
85 static int print_info(blkid_probe pr
)
89 if (!blkid_probe_lookup_value(pr
, "LABEL", &data
, NULL
))
90 printf("LABEL: %s\n", data
);
92 if (!blkid_probe_lookup_value(pr
, "UUID", &data
, NULL
))
93 printf("UUID: %s\n", data
);
98 /* Change the swap partition info */
99 static int change_info(const char *devname
, const char *label
, const char *uuid
)
103 fd
= open(devname
, O_RDWR
);
105 warn(_("cannot open %s"), devname
);
109 /* Write the uuid if it was provided */
113 if (uuid_parse(uuid
, newuuid
) == -1)
114 warnx(_("failed to parse UUID: %s"), uuid
);
116 if (lseek(fd
, SWAP_UUID_OFFSET
, SEEK_SET
) !=
118 warn(_("%s: failed to seek to swap UUID"), devname
);
121 } else if (write_all(fd
, newuuid
, sizeof(newuuid
))) {
122 warn(_("%s: failed to write UUID"), devname
);
128 /* Write the label if it was provided */
130 char newlabel
[SWAP_LABEL_LENGTH
];
132 if (lseek(fd
, SWAP_LABEL_OFFSET
, SEEK_SET
) != SWAP_LABEL_OFFSET
) {
133 warn(_("%s: failed to seek to swap label "), devname
);
136 memset(newlabel
, 0, sizeof(newlabel
));
137 xstrncpy(newlabel
, label
, sizeof(newlabel
));
139 if (strlen(label
) > strlen(newlabel
))
140 warnx(_("label is too long. Truncating it to '%s'"),
142 if (write_all(fd
, newlabel
, sizeof(newlabel
))) {
143 warn(_("%s: failed to write label"), devname
);
156 static void __attribute__((__noreturn__
)) usage(FILE *out
)
158 fputs(USAGE_HEADER
, out
);
159 fprintf(out
, _(" %s [options] <device>\n"),
160 program_invocation_short_name
);
161 fputs(USAGE_OPTIONS
, out
);
162 fputs(_(" -L, --label <label> specify a new label\n"
163 " -U, --uuid <uuid> specify a new uuid\n"), out
);
164 fputs(USAGE_SEPARATOR
, out
);
165 fputs(USAGE_HELP
, out
);
166 fputs(USAGE_VERSION
, out
);
167 fprintf(out
, USAGE_MAN_TAIL("swaplabel(8)"));
168 exit(out
== stderr
? EXIT_FAILURE
: EXIT_SUCCESS
);
171 int main(int argc
, char *argv
[])
173 blkid_probe pr
= NULL
;
174 char *uuid
= NULL
, *label
= NULL
, *devname
;
177 static const struct option longopts
[] = {
178 { "help", 0, 0, 'h' },
179 { "version", 0, 0, 'V' },
180 { "label", 1, 0, 'L' },
181 { "uuid", 1, 0, 'U' },
185 setlocale(LC_ALL
, "");
186 bindtextdomain(PACKAGE
, LOCALEDIR
);
188 atexit(close_stdout
);
190 while ((c
= getopt_long(argc
, argv
, "hVL:U:", longopts
, NULL
)) != -1) {
196 printf(UTIL_LINUX_VERSION
);
205 warnx(_("ignore -U (UUIDs are unsupported)"));
217 devname
= argv
[optind
];
218 pr
= get_swap_prober(devname
);
221 rc
= change_info(devname
, label
, uuid
);
224 blkid_free_probe(pr
);
226 return rc
? EXIT_FAILURE
: EXIT_SUCCESS
;