]> git.ipfire.org Git - thirdparty/util-linux.git/blame - disk-utils/swaplabel.c
wipefs: add --lock and LOCK_BLOCK_DEVICE
[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 */
3da94b11 54#ifdef HAVE_LIBUUID
4dddc2d4 55static int change_info(const char *devname, const char *label, const char *uuid)
3da94b11
KZ
56#else
57static int change_info(const char *devname, const char *label,
58 const char *uuid __attribute__((__unused__)))
59#endif
4dddc2d4
JB
60{
61 int fd;
62
63 fd = open(devname, O_RDWR);
64 if (fd < 0) {
289dcc90 65 warn(_("cannot open %s"), devname);
4dddc2d4
JB
66 goto err;
67 }
68#ifdef HAVE_LIBUUID
69 /* Write the uuid if it was provided */
70 if (uuid) {
71 uuid_t newuuid;
72
73 if (uuid_parse(uuid, newuuid) == -1)
74 warnx(_("failed to parse UUID: %s"), uuid);
75 else {
76 if (lseek(fd, SWAP_UUID_OFFSET, SEEK_SET) !=
77 SWAP_UUID_OFFSET) {
78 warn(_("%s: failed to seek to swap UUID"), devname);
79 goto err;
80
81 } else if (write_all(fd, newuuid, sizeof(newuuid))) {
82 warn(_("%s: failed to write UUID"), devname);
83 goto err;
84 }
85 }
86 }
87#endif
88 /* Write the label if it was provided */
89 if (label) {
90 char newlabel[SWAP_LABEL_LENGTH];
91
92 if (lseek(fd, SWAP_LABEL_OFFSET, SEEK_SET) != SWAP_LABEL_OFFSET) {
93 warn(_("%s: failed to seek to swap label "), devname);
94 goto err;
95 }
96 memset(newlabel, 0, sizeof(newlabel));
97 xstrncpy(newlabel, label, sizeof(newlabel));
98
99 if (strlen(label) > strlen(newlabel))
100 warnx(_("label is too long. Truncating it to '%s'"),
101 newlabel);
102 if (write_all(fd, newlabel, sizeof(newlabel))) {
103 warn(_("%s: failed to write label"), devname);
104 goto err;
105 }
106 }
107
de2ca559
SK
108 if (close_fd(fd) != 0) {
109 warn(_("write failed: %s"), devname);
110 return -1;
111 }
4dddc2d4
JB
112 return 0;
113err:
114 if (fd >= 0)
115 close(fd);
116 return -1;
117}
118
6e1eda6f 119static void __attribute__((__noreturn__)) usage(void)
4dddc2d4 120{
6e1eda6f 121 FILE *out = stdout;
1275d8a1
SK
122 fputs(USAGE_HEADER, out);
123 fprintf(out, _(" %s [options] <device>\n"),
124 program_invocation_short_name);
451dbcfa
BS
125
126 fputs(USAGE_SEPARATOR, out);
127 fputs(_("Display or change the label or UUID of a swap area.\n"), out);
128
1275d8a1
SK
129 fputs(USAGE_OPTIONS, out);
130 fputs(_(" -L, --label <label> specify a new label\n"
131 " -U, --uuid <uuid> specify a new uuid\n"), out);
132 fputs(USAGE_SEPARATOR, out);
f45f3ec3
RM
133 printf(USAGE_HELP_OPTIONS(21));
134 printf(USAGE_MAN_TAIL("swaplabel(8)"));
6e1eda6f 135 exit(EXIT_SUCCESS);
4dddc2d4
JB
136}
137
138int main(int argc, char *argv[])
139{
140 blkid_probe pr = NULL;
141 char *uuid = NULL, *label = NULL, *devname;
142 int c, rc = -1;
143
6c7d5ae9 144 static const struct option longopts[] = {
87918040
SK
145 { "help", no_argument, NULL, 'h' },
146 { "version", no_argument, NULL, 'V' },
147 { "label", required_argument, NULL, 'L' },
148 { "uuid", required_argument, NULL, 'U' },
149 { NULL, 0, NULL, 0 }
4dddc2d4
JB
150 };
151
152 setlocale(LC_ALL, "");
153 bindtextdomain(PACKAGE, LOCALEDIR);
154 textdomain(PACKAGE);
2c308875 155 close_stdout_atexit();
4dddc2d4 156
1275d8a1 157 while ((c = getopt_long(argc, argv, "hVL:U:", longopts, NULL)) != -1) {
4dddc2d4
JB
158 switch (c) {
159 case 'h':
6e1eda6f 160 usage();
4dddc2d4 161 break;
1275d8a1 162 case 'V':
2c308875 163 print_version(EXIT_SUCCESS);
4dddc2d4
JB
164 case 'L':
165 label = optarg;
166 break;
167 case 'U':
168#ifdef HAVE_LIBUUID
169 uuid = optarg;
170#else
171 warnx(_("ignore -U (UUIDs are unsupported)"));
172#endif
173 break;
174 default:
677ec86c 175 errtryhelp(EXIT_FAILURE);
4dddc2d4
JB
176 }
177 }
178
6e1eda6f
RM
179 if (optind == argc) {
180 warnx(_("no device specified"));
181 errtryhelp(EXIT_FAILURE);
182 }
4dddc2d4
JB
183 devname = argv[optind];
184 pr = get_swap_prober(devname);
185 if (pr) {
186 if (uuid || label)
187 rc = change_info(devname, label, uuid);
188 else
ae7ec06b 189 rc = print_info(pr);
4dddc2d4
JB
190 blkid_free_probe(pr);
191 }
192 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
193}
194