]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/swaplabel.c
docs: update v2.30-ReleaseNotes
[thirdparty/util-linux.git] / disk-utils / swaplabel.c
CommitLineData
4dddc2d4
JB
1/*
2 * swaplabel.c - Print or change the label / UUID of a swap partition
3 *
4 * Copyright (C) 2010 Jason Borden <jborden@bluehost.com>
5 * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
6 *
7 * Usage: swaplabel [-L label] [-U UUID] device
8 *
9 * This file may be redistributed under the terms of the GNU Public License
10 * version 2 or later.
11 *
12 */
13#include <stdio.h>
14#include <stddef.h>
15#include <string.h>
16#include <fcntl.h>
17#include <sys/types.h>
18#include <sys/stat.h>
19#include <unistd.h>
20#include <stdlib.h>
4dddc2d4
JB
21#include <getopt.h>
22
23#ifdef HAVE_LIBUUID
7ee96990 24# include <uuid.h>
4dddc2d4
JB
25#endif
26
27#include "c.h"
18b3e549 28#include "nls.h"
e12c9866 29#include "all-io.h"
8abcf290 30#include "strutils.h"
18b3e549
KZ
31#include "closestream.h"
32
33#include "swapheader.h"
34#include "swapprober.h"
4dddc2d4
JB
35
36#define SWAP_UUID_OFFSET (offsetof(struct swap_header_v1_2, uuid))
37#define SWAP_LABEL_OFFSET (offsetof(struct swap_header_v1_2, volume_name))
38
4dddc2d4 39/* Print the swap partition information */
ae7ec06b 40static int print_info(blkid_probe pr)
4dddc2d4
JB
41{
42 const char *data;
43
44 if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
45 printf("LABEL: %s\n", data);
46
47 if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL))
48 printf("UUID: %s\n", data);
49
50 return 0;
51}
52
53/* Change the swap partition info */
54static int change_info(const char *devname, const char *label, const char *uuid)
55{
56 int fd;
57
58 fd = open(devname, O_RDWR);
59 if (fd < 0) {
289dcc90 60 warn(_("cannot open %s"), devname);
4dddc2d4
JB
61 goto err;
62 }
63#ifdef HAVE_LIBUUID
64 /* Write the uuid if it was provided */
65 if (uuid) {
66 uuid_t newuuid;
67
68 if (uuid_parse(uuid, newuuid) == -1)
69 warnx(_("failed to parse UUID: %s"), uuid);
70 else {
71 if (lseek(fd, SWAP_UUID_OFFSET, SEEK_SET) !=
72 SWAP_UUID_OFFSET) {
73 warn(_("%s: failed to seek to swap UUID"), devname);
74 goto err;
75
76 } else if (write_all(fd, newuuid, sizeof(newuuid))) {
77 warn(_("%s: failed to write UUID"), devname);
78 goto err;
79 }
80 }
81 }
82#endif
83 /* Write the label if it was provided */
84 if (label) {
85 char newlabel[SWAP_LABEL_LENGTH];
86
87 if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET) {
88 warn(_("%s: failed to seek to swap label "), devname);
89 goto err;
90 }
91 memset(newlabel, 0, sizeof(newlabel));
92 xstrncpy(newlabel, label, sizeof(newlabel));
93
94 if (strlen(label) > strlen(newlabel))
95 warnx(_("label is too long. Truncating it to '%s'"),
96 newlabel);
97 if (write_all(fd, newlabel, sizeof(newlabel))) {
98 warn(_("%s: failed to write label"), devname);
99 goto err;
100 }
101 }
102
de2ca559
SK
103 if (close_fd(fd) != 0) {
104 warn(_("write failed: %s"), devname);
105 return -1;
106 }
4dddc2d4
JB
107 return 0;
108err:
109 if (fd >= 0)
110 close(fd);
111 return -1;
112}
113
114static void __attribute__((__noreturn__)) usage(FILE *out)
115{
1275d8a1
SK
116 fputs(USAGE_HEADER, out);
117 fprintf(out, _(" %s [options] <device>\n"),
118 program_invocation_short_name);
451dbcfa
BS
119
120 fputs(USAGE_SEPARATOR, out);
121 fputs(_("Display or change the label or UUID of a swap area.\n"), out);
122
1275d8a1
SK
123 fputs(USAGE_OPTIONS, out);
124 fputs(_(" -L, --label <label> specify a new label\n"
125 " -U, --uuid <uuid> specify a new uuid\n"), out);
126 fputs(USAGE_SEPARATOR, out);
127 fputs(USAGE_HELP, out);
128 fputs(USAGE_VERSION, out);
129 fprintf(out, USAGE_MAN_TAIL("swaplabel(8)"));
4dddc2d4
JB
130 exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
131}
132
133int main(int argc, char *argv[])
134{
135 blkid_probe pr = NULL;
136 char *uuid = NULL, *label = NULL, *devname;
137 int c, rc = -1;
138
6c7d5ae9 139 static const struct option longopts[] = {
87918040
SK
140 { "help", no_argument, NULL, 'h' },
141 { "version", no_argument, NULL, 'V' },
142 { "label", required_argument, NULL, 'L' },
143 { "uuid", required_argument, NULL, 'U' },
144 { NULL, 0, NULL, 0 }
4dddc2d4
JB
145 };
146
147 setlocale(LC_ALL, "");
148 bindtextdomain(PACKAGE, LOCALEDIR);
149 textdomain(PACKAGE);
45ca68ec 150 atexit(close_stdout);
4dddc2d4 151
1275d8a1 152 while ((c = getopt_long(argc, argv, "hVL:U:", longopts, NULL)) != -1) {
4dddc2d4
JB
153 switch (c) {
154 case 'h':
155 usage(stdout);
156 break;
1275d8a1
SK
157 case 'V':
158 printf(UTIL_LINUX_VERSION);
159 return EXIT_SUCCESS;
4dddc2d4
JB
160 case 'L':
161 label = optarg;
162 break;
163 case 'U':
164#ifdef HAVE_LIBUUID
165 uuid = optarg;
166#else
167 warnx(_("ignore -U (UUIDs are unsupported)"));
168#endif
169 break;
170 default:
677ec86c 171 errtryhelp(EXIT_FAILURE);
4dddc2d4
JB
172 }
173 }
174
175 if (optind == argc)
176 usage(stderr);
177
178 devname = argv[optind];
179 pr = get_swap_prober(devname);
180 if (pr) {
181 if (uuid || label)
182 rc = change_info(devname, label, uuid);
183 else
ae7ec06b 184 rc = print_info(pr);
4dddc2d4
JB
185 blkid_free_probe(pr);
186 }
187 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
188}
189