]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blame - db/uuid.c
Update copyright dates
[thirdparty/xfsprogs-dev.git] / db / uuid.c
CommitLineData
2bd0ea18 1/*
cc08d43e 2 * Copyright (c) 2000-2001 Silicon Graphics, Inc. All Rights Reserved.
2bd0ea18
NS
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include <libxfs.h>
34#include "command.h"
35#include "data.h"
36#include "type.h"
37#include "faddr.h"
38#include "fprint.h"
39#include "field.h"
40#include "io.h"
41#include "uuid.h"
42#include "bit.h"
43#include "output.h"
44#include "mount.h"
45
46static int uuid_f(int argc, char **argv);
47static void uuid_help(void);
48static int label_f(int argc, char **argv);
49static void label_help(void);
50
51static const cmdinfo_t uuid_cmd =
52 { "uuid", NULL, uuid_f, 0, 1, 1, "[uuid]",
53 "write/print FS uuid", uuid_help };
54static const cmdinfo_t label_cmd =
55 { "label", NULL, label_f, 0, 1, 1, "[label]",
56 "write/print FS label", label_help };
57static int warned;
58
59static void
60uuid_help(void)
61{
62 dbprintf(
63"\n"
64" write/print FS uuid\n"
65"\n"
66" Example:\n"
67"\n"
68" 'uuid' - print UUID\n"
69" 'uuid 01234567-0123-0123-0123-0123456789ab' - write UUID\n"
70" 'uuid generate' - generate and write\n"
71" 'uuid rewrite' - copy UUID from SB 0\n"
2bd0ea18
NS
72"\n"
73"The print function checks the UUID in each SB and will warn if the UUIDs\n"
74"differ between AGs (the log is not checked). The write commands will\n"
75"set the uuid in all AGs to either a specified value, a newly generated\n"
7242da3f
DM
76"value or the value found in the first superblock (SB 0) respectively.\n"
77"As a side effect of writing the UUID, the log is cleared (which is fine\n"
78"on a CLEANLY unmounted FS).\n"
2bd0ea18
NS
79"\n"
80);
81}
82
83static void
84label_help(void)
85{
86 dbprintf(
87"\n"
88" write/print FS label\n"
89"\n"
90" Example:\n"
91"\n"
92" 'label' - print label\n"
93" 'label 123456789012' - write label\n"
94" 'label --' - write an empty label\n"
95"\n"
96"The print function checks the label in each SB and will warn if the labels\n"
97"differ between AGs. The write commands will set the label in all AGs to the\n"
98"specified value. The maximum length of a label is 12 characters - use of a\n"
99"longer label will result in truncation and a warning will be issued.\n"
100"\n"
101);
102}
103
104static int
105get_sb(xfs_agnumber_t agno, xfs_sb_t *sb)
106{
107 push_cur();
108 set_cur(&typtab[TYP_SB], XFS_AG_DADDR(mp, agno, XFS_SB_DADDR), 1,
109 DB_RING_IGN, NULL);
110
111 if (!iocur_top->data) {
112 dbprintf("can't read superblock for AG %u\n", agno);
113 pop_cur();
114 return 0;
115 }
116
117 libxfs_xlate_sb(iocur_top->data, sb, 1, ARCH_CONVERT, XFS_SB_ALL_BITS);
118
119 if (sb->sb_magicnum != XFS_SB_MAGIC) {
120 dbprintf("bad sb magic # %#x in AG %u\n",
121 sb->sb_magicnum, agno);
122 return 0;
123 }
124 if (!XFS_SB_GOOD_VERSION(sb)) {
125 dbprintf("bad sb version # %#x in AG %u\n",
126 sb->sb_versionnum, agno);
127 return 0;
128 }
129 if (agno == 0 && sb->sb_inprogress != 0) {
130 dbprintf("mkfs not completed successfully\n");
131 return 0;
132 }
133 return 1;
134}
135
136static uuid_t *
137do_uuid(xfs_agnumber_t agno, uuid_t *uuid)
138{
139 xfs_sb_t tsb;
140 static uuid_t uu;
141
142 if (!get_sb(agno, &tsb))
143 return NULL;
144
145 if (!uuid) { /* get uuid */
146 memcpy(&uu, &tsb.sb_uuid, sizeof(uuid_t));
147 pop_cur();
148 return &uu;
149 }
150 /* set uuid */
151 memcpy(&tsb.sb_uuid, uuid, sizeof(uuid_t));
152 libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_UUID);
153 write_cur();
154 return uuid;
155}
156
157static char *
158do_label(xfs_agnumber_t agno, char *label)
159{
160 size_t len;
161 xfs_sb_t tsb;
162 static char lbl[sizeof(tsb.sb_fname) + 1];
163
164 if (!get_sb(agno, &tsb))
165 return NULL;
166
167 memset(&lbl[0], 0, sizeof(lbl));
168
169 if (!label) { /* get label */
170 pop_cur();
171 memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname));
172 return &lbl[0];
173 }
174 /* set label */
175 if ((len = strlen(label)) > sizeof(tsb.sb_fname)) {
176 if (!warned++)
7242da3f
DM
177 dbprintf("warning: truncating label from %lld to %lld "
178 "characters\n",
179 (long long)len, (long long)sizeof(tsb.sb_fname));
2bd0ea18
NS
180 len = sizeof(tsb.sb_fname);
181 }
182 if ( len == 2 &&
183 (strcmp(label, "\"\"") == 0 ||
184 strcmp(label, "''") == 0 ||
185 strcmp(label, "--") == 0) )
186 label[0] = label[1] = '\0';
187 memset(&tsb.sb_fname, 0, sizeof(tsb.sb_fname));
188 memcpy(&tsb.sb_fname, label, len);
189 memcpy(&lbl[0], &tsb.sb_fname, sizeof(tsb.sb_fname));
190 libxfs_xlate_sb(iocur_top->data, &tsb, -1, ARCH_CONVERT, XFS_SB_FNAME);
191 write_cur();
192 return &lbl[0];
193}
194
195static int
196uuid_f(
197 int argc,
198 char **argv)
199{
200 char bp[40];
201 xfs_agnumber_t agno;
202 uuid_t uu;
203 uuid_t *uup=NULL;
204
205 if (argc != 1 && argc != 2) {
206 dbprintf("invalid parameters\n");
207 return 0;
208 }
209
210 if (argc==2) {
211 /* write uuid */
212
213 if (flag_readonly || !flag_expert_mode) {
214 dbprintf("%s not started in read-write expert mode, writing disabled\n",
215 progname);
216 return 0;
217 }
218
219 if (!strcasecmp(argv[1], "generate")) {
220 uuid_generate(uu);
7242da3f 221 } else if (!strcasecmp(argv[1], "nil")) {
2bd0ea18
NS
222 uuid_clear(uu);
223 } else if (!strcasecmp(argv[1], "rewrite")) {
224 uup=do_uuid(0, NULL);
225 if (!uup) {
226 dbprintf("failed to read UUID from AG 0\n");
227 return 0;
228 }
229 memcpy(&uu, *uup, sizeof(uuid_t));
230 uuid_unparse(uu, bp);
231 dbprintf("old uuid = %s\n", bp);
232 } else {
233 if (uuid_parse(argv[1], uu)) {
234 dbprintf("invalid uuid\n");
235 return 0;
236 }
237 }
238
239 if (mp->m_sb.sb_logstart) {
240 if (xfsargs.logdev) {
241 dbprintf("external log specified for FS with internal log - aborting \n");
242 return 0;
243 }
244 } else {
245 if (!xfsargs.logdev) {
246 dbprintf("no external log specified for FS with external log - aborting\n");
247 return 0;
248 }
249 }
250
251 dbprintf("clearing log and setting uuid\n");
252
253 /* clear log (setting uuid) */
254
255 if (libxfs_log_clear(
256 (mp->m_sb.sb_logstart)?xfsargs.ddev:xfsargs.logdev,
257 XFS_FSB_TO_DADDR(mp, mp->m_sb.sb_logstart),
258 XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks),
259 &uu,
260 XLOG_FMT)) {
261 dbprintf("error clearing log\n");
262 return 0;
263 }
264
265
266 dbprintf("writing all SBs\n");
267
268 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++)
269 if (!do_uuid(agno, &uu)) {
270 dbprintf("failed to set uuid in AG %d\n", agno);
271 break;
272 }
273
274 uuid_unparse(uu, bp);
275 dbprintf("new uuid = %s\n", bp);
276
277 return 0;
278
279 } else {
280 /* get (check) uuid */
281
282 for (agno = 0; agno < mp->m_sb.sb_agcount; agno++) {
283 uup=do_uuid(agno, NULL);
284 if (!uup) {
285 dbprintf("failed to read UUID from AG %d\n", agno);
286 return 0;
287 }
288 if (agno) {
289 if (memcmp(&uu, uup, sizeof(uuid_t))) {
290 dbprintf("warning: uuid copies differ\n");
291 break;
292 }
293 } else {
294 memcpy(uu, uup, sizeof(uuid_t));
295 }
296 }
297 if (mp->m_sb.sb_logstart) {
298 if (xfsargs.logdev)
299 dbprintf("warning: external log specified for FS with internal log\n");
300 } else {
301 if (!xfsargs.logdev) {
302 dbprintf("warning: no external log specified for FS with external log\n");
303 }
304 }
305
306 uuid_unparse(uu, bp);
307 dbprintf("uuid = %s\n", bp);
308 }
309
310 return 0;
311}
312
313static int
314label_f(
315 int argc,
316 char **argv)
317{
318 char *p = NULL;
319 xfs_sb_t sb;
320 xfs_agnumber_t ag;
321
322 if (argc != 1 && argc != 2) {
323 dbprintf("invalid parameters\n");
324 return 0;
325 }
326
327 if (argc==2) { /* write label */
328 if (flag_readonly || !flag_expert_mode) {
329 dbprintf("%s not started in read-write expert mode, "
330 "writing disabled\n", progname);
331 return 0;
332 }
333
334 dbprintf("writing all SBs\n");
335 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++)
336 if ((p = do_label(ag, argv[1])) == NULL) {
337 dbprintf("failed to set label in AG %d\n", ag);
338 break;
339 }
340 dbprintf("new label = \"%s\"\n", p);
341 } else { /* print label */
342 for (ag = 0; ag < mp->m_sb.sb_agcount; ag++) {
343 p = do_label(ag, NULL);
344 if (!p) {
345 dbprintf("failed to read label in AG %d\n", ag);
346 return 0;
347 }
348 if (!ag)
349 memcpy(&sb.sb_fname, p, sizeof(sb.sb_fname));
350 else if (memcmp(&sb.sb_fname, p, sizeof(sb.sb_fname)))
7242da3f 351 dbprintf("warning: label in AG %d differs\n", ag);
2bd0ea18
NS
352 }
353 dbprintf("label = \"%s\"\n", p);
354 }
355 return 0;
356}
357
358void
359uuid_init(void)
360{
361 warned = 0;
362 add_command(&label_cmd);
363 add_command(&uuid_cmd);
364}