Mercurial > illumos > illumos-gate
comparison usr/src/lib/libbe/tbeadm/tbeadm.c @ 13025:3c7681e3e323
PSARC 2010/059 SNAP BE Management
6964804 SNAP BE management into ON
6971379 libbe should capture and give useful error when installgrub or ict.py fails.
6971390 beadm does not support labeled brand zones
6971394 BEADM_ERR_BE_DOES_NOT_EXIST has an extra space
6971397 libbe error messages need internationalization
6971402 Remove be_get_last_zone_be_callback
6971409 be_create_menu returns errors from both be_errno_t and errno sets
author | Glenn Lagasse <glenn.lagasse@oracle.com> |
---|---|
date | Wed, 04 Aug 2010 12:28:19 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
13024:c176c071a066 | 13025:3c7681e3e323 |
---|---|
1 /* | |
2 * CDDL HEADER START | |
3 * | |
4 * The contents of this file are subject to the terms of the | |
5 * Common Development and Distribution License (the "License"). | |
6 * You may not use this file except in compliance with the License. | |
7 * | |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE | |
9 * or http://www.opensolaris.org/os/licensing. | |
10 * See the License for the specific language governing permissions | |
11 * and limitations under the License. | |
12 * | |
13 * When distributing Covered Code, include this CDDL HEADER in each | |
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. | |
15 * If applicable, add the following below this CDDL HEADER, with the | |
16 * fields enclosed by brackets "[]" replaced with your own identifying | |
17 * information: Portions Copyright [yyyy] [name of copyright owner] | |
18 * | |
19 * CDDL HEADER END | |
20 */ | |
21 | |
22 /* | |
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 */ | |
25 | |
26 /* | |
27 * System includes | |
28 */ | |
29 | |
30 #include <stdio.h> | |
31 #include <strings.h> | |
32 #include <libzfs.h> | |
33 | |
34 #include "libbe.h" | |
35 | |
36 static int be_do_create(int argc, char **argv); | |
37 static int be_do_destroy(int argc, char **argv); | |
38 static int be_do_list(int argc, char **argv); | |
39 static int be_do_mount(int argc, char **argv); | |
40 static int be_do_unmount(int argc, char **argv); | |
41 static int be_do_rename(int argc, char **argv); | |
42 static int be_do_activate(int argc, char **argv); | |
43 static int be_do_create_snapshot(int argc, char **argv); | |
44 static int be_do_destroy_snapshot(int argc, char **argv); | |
45 static int be_do_rollback(int argc, char **argv); | |
46 static void usage(void); | |
47 | |
48 typedef struct be_command { | |
49 const char *name; | |
50 int (*func)(int argc, char **argv); | |
51 } be_command_t; | |
52 | |
53 static be_command_t command_table[] = { | |
54 { "create", be_do_create }, | |
55 { "destroy", be_do_destroy }, | |
56 { "list", be_do_list }, | |
57 { "mount", be_do_mount }, | |
58 { "unmount", be_do_unmount }, | |
59 { "rename", be_do_rename }, | |
60 { "activate", be_do_activate }, | |
61 { "create_snap", be_do_create_snapshot }, | |
62 { "destroy_snap", be_do_destroy_snapshot }, | |
63 }; | |
64 | |
65 static int fs_num = 2; | |
66 static int shared_fs_num = 2; | |
67 static char *fs_names[2] = {"/", "/opt"}; | |
68 static char *shared_fs_names[4] = {"/export", "/export/home"}; | |
69 | |
70 static void | |
71 usage(void) | |
72 { | |
73 (void) printf("usage:\n" | |
74 "\ttbeadm\n" | |
75 "\ttbeadm create [-d BE_desc] [-e nonActiveBe | -i] \n" | |
76 "\t\t[-o property=value] ... [-p zpool] [beName]\n" | |
77 "\ttbeadm destroy [-fs] beName\n" | |
78 "\ttbeadm create_snap [-p policy] beName [snapshot]\n" | |
79 "\ttbeadm destroy_snap beName snapshot\n" | |
80 "\ttbeadm list [-s] [beName]\n" | |
81 "\ttbeadm mount [-s ro|rw] beName mountpoint\n" | |
82 "\ttbeadm unmount [-f] beName\n" | |
83 "\ttbeadm rename origBeName newBeName\n" | |
84 "\ttbeadm activate beName\n" | |
85 "\ttbeadm rollback beName snapshot\n"); | |
86 } | |
87 | |
88 int | |
89 main(int argc, char **argv) { | |
90 | |
91 if (argc < 2) { | |
92 usage(); | |
93 return (1); | |
94 } | |
95 | |
96 /* Turn error printing on */ | |
97 libbe_print_errors(B_TRUE); | |
98 | |
99 if (strcmp(argv[1], "create") == 0) { | |
100 return (be_do_create(argc - 1, argv + 1)); | |
101 } else if (strcmp(argv[1], "destroy") == 0) { | |
102 return (be_do_destroy(argc - 1, argv + 1)); | |
103 } else if (strcmp(argv[1], "list") == 0) { | |
104 return (be_do_list(argc - 1, argv + 1)); | |
105 } else if (strcmp(argv[1], "mount") == 0) { | |
106 return (be_do_mount(argc - 1, argv + 1)); | |
107 } else if (strcmp(argv[1], "unmount") == 0) { | |
108 return (be_do_unmount(argc - 1, argv + 1)); | |
109 } else if (strcmp(argv[1], "rename") == 0) { | |
110 return (be_do_rename(argc - 2, argv + 2)); | |
111 } else if (strcmp(argv[1], "activate") == 0) { | |
112 return (be_do_activate(argc - 2, argv + 2)); | |
113 } else if (strcmp(argv[1], "create_snap") == 0) { | |
114 return (be_do_create_snapshot(argc - 1, argv + 1)); | |
115 } else if (strcmp(argv[1], "destroy_snap") == 0) { | |
116 return (be_do_destroy_snapshot(argc - 2, argv + 2)); | |
117 } else if (strcmp(argv[1], "rollback") == 0) { | |
118 return (be_do_rollback(argc - 2, argv + 2)); | |
119 } else { | |
120 usage(); | |
121 return (1); | |
122 } | |
123 | |
124 /* NOTREACHED */ | |
125 } | |
126 | |
127 static int | |
128 be_do_create(int argc, char **argv) | |
129 { | |
130 nvlist_t *be_attrs; | |
131 char *obe_name = NULL; | |
132 char *snap_name = NULL; | |
133 char *nbe_zpool = NULL; | |
134 char *nbe_name = NULL; | |
135 char *nbe_desc = NULL; | |
136 nvlist_t *zfs_props = NULL; | |
137 char *propname = NULL; | |
138 char *propval = NULL; | |
139 char *strval = NULL; | |
140 boolean_t init = B_FALSE; | |
141 int c; | |
142 int ret = BE_SUCCESS; | |
143 | |
144 if (nvlist_alloc(&zfs_props, NV_UNIQUE_NAME, 0) != 0) { | |
145 printf("nvlist_alloc failed.\n"); | |
146 return (1); | |
147 } | |
148 | |
149 while ((c = getopt(argc, argv, "d:e:io:p:")) != -1) { | |
150 switch (c) { | |
151 case 'd': | |
152 nbe_desc = optarg; | |
153 break; | |
154 case 'e': | |
155 obe_name = optarg; | |
156 break; | |
157 case 'i': | |
158 /* Special option to test be_init() function */ | |
159 init = B_TRUE; | |
160 break; | |
161 case 'o': | |
162 if (zfs_props == NULL) { | |
163 if (nvlist_alloc(&zfs_props, NV_UNIQUE_NAME, | |
164 0) != 0) { | |
165 printf("nvlist_alloc failed.\n"); | |
166 return (1); | |
167 } | |
168 } | |
169 | |
170 propname = optarg; | |
171 if ((propval = strchr(propname, '=')) == NULL) { | |
172 (void) fprintf(stderr, "missing " | |
173 "'=' for -o option\n"); | |
174 return (1); | |
175 } | |
176 *propval = '\0'; | |
177 propval++; | |
178 if (nvlist_lookup_string(zfs_props, propname, | |
179 &strval) == 0) { | |
180 (void) fprintf(stderr, "property '%s' " | |
181 "specified multiple times\n", propname); | |
182 return (1); | |
183 } | |
184 if (nvlist_add_string(zfs_props, propname, propval) | |
185 != 0) { | |
186 (void) fprintf(stderr, "internal " | |
187 "error: out of memory\n"); | |
188 return (1); | |
189 } | |
190 break; | |
191 case 'p': | |
192 nbe_zpool = optarg; | |
193 break; | |
194 default: | |
195 usage(); | |
196 return (1); | |
197 } | |
198 } | |
199 | |
200 if (init && obe_name) { | |
201 printf("ERROR: -e and -i are exclusive options\n"); | |
202 usage(); | |
203 return (1); | |
204 } | |
205 | |
206 argc -= optind; | |
207 argv += optind; | |
208 | |
209 if (argc == 1) { | |
210 nbe_name = argv[0]; | |
211 } else if (argc > 1) { | |
212 usage(); | |
213 return (1); | |
214 } | |
215 | |
216 if (obe_name) { | |
217 /* | |
218 * Check if obe_name is really a snapshot name. | |
219 * If so, split it out. | |
220 */ | |
221 char *cp = NULL; | |
222 | |
223 cp = strrchr(obe_name, '@'); | |
224 if (cp != NULL) { | |
225 cp[0] = '\0'; | |
226 if (cp[1] != NULL && cp[1] != '\0') { | |
227 snap_name = cp+1; | |
228 } | |
229 } | |
230 } | |
231 | |
232 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
233 printf("nvlist_alloc failed.\n"); | |
234 return (1); | |
235 } | |
236 | |
237 if (zfs_props) { | |
238 if (nvlist_add_nvlist(be_attrs, BE_ATTR_ZFS_PROPERTIES, | |
239 zfs_props) != 0) { | |
240 printf("nvlist_add_string failed for " | |
241 "BE_ATTR_ZFS_PROPERTES (%s).\n", zfs_props); | |
242 return (1); | |
243 } | |
244 } | |
245 | |
246 if (obe_name != NULL) { | |
247 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
248 != 0) { | |
249 printf("nvlist_add_string failed for " | |
250 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
251 return (1); | |
252 } | |
253 } | |
254 | |
255 if (snap_name != NULL) { | |
256 if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) | |
257 != 0) { | |
258 printf("nvlist_add_string failed for " | |
259 "BE_ATTR_SNAP_NANE (%s).\n", snap_name); | |
260 return (1); | |
261 } | |
262 } | |
263 | |
264 if (nbe_zpool != NULL) { | |
265 if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_POOL, nbe_zpool) | |
266 != 0) { | |
267 printf("nvlist_add_string failed for " | |
268 "BE_ATTR_NEW_BE_POOL (%s).\n", nbe_zpool); | |
269 return (1); | |
270 } | |
271 } | |
272 | |
273 if (nbe_name) { | |
274 if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME, nbe_name) | |
275 != 0) { | |
276 printf("nvlist_add_string failed for " | |
277 "BE_ATTR_NEW_BE_NAME (%s).\n", nbe_name); | |
278 return (1); | |
279 } | |
280 } | |
281 | |
282 if (nbe_desc) { | |
283 if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_DESC, nbe_desc) | |
284 != 0) { | |
285 printf("nvlist_add_string failed for " | |
286 "BE_ATTR_NEW_BE_DESC (%s)\n", nbe_desc); | |
287 return (1); | |
288 } | |
289 } | |
290 | |
291 if (init) { | |
292 /* | |
293 * Add the default file system test values to test | |
294 * creating an initial BE. | |
295 */ | |
296 if (nvlist_add_uint16(be_attrs, BE_ATTR_FS_NUM, fs_num) != 0) { | |
297 printf("nvlist_add_uint16 failed for BE_ATTR_FS_NUM " | |
298 "(%d).\n", fs_num); | |
299 return (1); | |
300 } | |
301 | |
302 if (nvlist_add_string_array(be_attrs, BE_ATTR_FS_NAMES, | |
303 fs_names, fs_num) != 0) { | |
304 printf("nvlist_add_string_array failed for " | |
305 "BE_ATTR_FS_NAMES\n"); | |
306 return (1); | |
307 } | |
308 | |
309 if (nvlist_add_uint16(be_attrs, BE_ATTR_SHARED_FS_NUM, | |
310 shared_fs_num) != 0) { | |
311 printf("nvlist_add_uint16 failed for " | |
312 "BE_ATTR_SHARED_FS_NUM (%d).\n", shared_fs_num); | |
313 return (1); | |
314 } | |
315 | |
316 if (nvlist_add_string_array(be_attrs, BE_ATTR_SHARED_FS_NAMES, | |
317 shared_fs_names, shared_fs_num) != 0) { | |
318 printf("nvlist_add_string_array failed for " | |
319 "BE_ATTR_SHARED_FS_NAMES\n"); | |
320 return (1); | |
321 } | |
322 | |
323 return (be_init(be_attrs)); | |
324 } | |
325 | |
326 ret = be_copy(be_attrs); | |
327 | |
328 if (!nbe_name & ret == BE_SUCCESS) { | |
329 /* | |
330 * We requested an auto named BE; find out the | |
331 * name of the BE that was created for us and | |
332 * the auto snapshot created from the original BE. | |
333 */ | |
334 if (nvlist_lookup_string(be_attrs, BE_ATTR_NEW_BE_NAME, | |
335 &nbe_name) != 0) { | |
336 printf("failed to get BE_ATTR_NEW_BE_NAME attribute\n"); | |
337 ret = 1; | |
338 } else { | |
339 printf("Auto named BE: %s\n", nbe_name); | |
340 } | |
341 | |
342 if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME, | |
343 &snap_name) != 0) { | |
344 printf("failed to get BE_ATTR_SNAP_NAME attribute\n"); | |
345 ret = 1; | |
346 } else { | |
347 printf("Auto named snapshot: %s\n", snap_name); | |
348 } | |
349 } | |
350 | |
351 return (ret); | |
352 } | |
353 | |
354 static int | |
355 be_do_destroy(int argc, char **argv) | |
356 { | |
357 nvlist_t *be_attrs; | |
358 int c; | |
359 int destroy_flags = 0; | |
360 char *be_name; | |
361 | |
362 while ((c = getopt(argc, argv, "fs")) != -1) { | |
363 switch (c) { | |
364 case 'f': | |
365 destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT; | |
366 break; | |
367 case 's': | |
368 destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS; | |
369 break; | |
370 default: | |
371 usage(); | |
372 return (1); | |
373 } | |
374 } | |
375 | |
376 argc -= optind; | |
377 argv += optind; | |
378 | |
379 if (argc != 1) { | |
380 usage(); | |
381 return (1); | |
382 } | |
383 | |
384 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
385 printf("nvlist_alloc failed.\n"); | |
386 return (1); | |
387 } | |
388 | |
389 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, argv[0]) != 0) { | |
390 printf("nvlist_add_string failed for BE_ATTR_NEW_BE_NAME " | |
391 "(%s).\n", argv[0]); | |
392 return (1); | |
393 } | |
394 | |
395 if (nvlist_add_uint16(be_attrs, BE_ATTR_DESTROY_FLAGS, destroy_flags) | |
396 != 0) { | |
397 printf("nvlist_add_uint16 failed for " | |
398 "BE_ATTR_DESTROY_FLAGS.\n"); | |
399 return (1); | |
400 } | |
401 | |
402 return (be_destroy(be_attrs)); | |
403 } | |
404 | |
405 static int | |
406 be_do_list(int argc, char **argv) | |
407 { | |
408 int err = BE_SUCCESS; | |
409 be_node_list_t *be_nodes; | |
410 be_node_list_t *cur_be; | |
411 boolean_t snaps = B_FALSE; | |
412 int c = 0; | |
413 | |
414 while ((c = getopt(argc, argv, "s")) != -1) { | |
415 switch (c) { | |
416 case 's': | |
417 snaps = B_TRUE; | |
418 break; | |
419 default: | |
420 usage(); | |
421 return (1); | |
422 } | |
423 } | |
424 | |
425 argc -= optind; | |
426 argv += optind; | |
427 | |
428 | |
429 if (argc == 1) { | |
430 err = be_list(argv[0], &be_nodes); | |
431 } else { | |
432 err = be_list(NULL, &be_nodes); | |
433 } | |
434 | |
435 if (err == BE_SUCCESS) { | |
436 | |
437 printf( | |
438 "BE name\t\tActive\tActive \tDataset\t\t\tPolicy\tUUID\n"); | |
439 printf( | |
440 " \t\t \ton boot\t \t\t\t \t \n"); | |
441 printf( | |
442 "-------\t\t------\t-------\t-------\t\t\t------\t----\n"); | |
443 | |
444 for (cur_be = be_nodes; cur_be != NULL; | |
445 cur_be = cur_be->be_next_node) { | |
446 | |
447 int name_len = strlen(cur_be->be_node_name); | |
448 int ds_len = strlen(cur_be->be_root_ds); | |
449 | |
450 printf("%s%s%s\t%s\t%s%s%s\t%s\n", | |
451 cur_be->be_node_name, | |
452 name_len < 8 ? "\t\t" : "\t", | |
453 cur_be->be_active ? "yes" : "no", | |
454 cur_be->be_active_on_boot ? "yes" : "no", | |
455 cur_be->be_root_ds, | |
456 ds_len < 8 ? "\t\t\t" : | |
457 (ds_len < 16 ? "\t\t" : "\t"), | |
458 cur_be->be_policy_type, | |
459 cur_be->be_uuid_str ? cur_be->be_uuid_str : "-"); | |
460 if (snaps) { | |
461 be_snapshot_list_t *snapshots = NULL; | |
462 printf("Snapshot Name\n"); | |
463 printf("--------------\n"); | |
464 for (snapshots = cur_be->be_node_snapshots; | |
465 snapshots != NULL; snapshots = | |
466 snapshots->be_next_snapshot) { | |
467 printf("%s\n", | |
468 snapshots->be_snapshot_name); | |
469 } | |
470 } | |
471 } | |
472 } | |
473 | |
474 be_free_list(be_nodes); | |
475 return (err); | |
476 } | |
477 | |
478 static int | |
479 be_do_rename(int argc, char **argv) | |
480 { | |
481 nvlist_t *be_attrs; | |
482 char *obe_name; | |
483 char *nbe_name; | |
484 | |
485 if (argc < 1 || argc > 2) { | |
486 usage(); | |
487 return (1); | |
488 } | |
489 | |
490 obe_name = argv[0]; | |
491 nbe_name = argv[1]; | |
492 | |
493 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
494 printf("nvlist_alloc failed.\n"); | |
495 return (1); | |
496 } | |
497 | |
498 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
499 != 0) { | |
500 printf("nvlist_add_string failed for " | |
501 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
502 return (1); | |
503 } | |
504 | |
505 if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME, nbe_name) | |
506 != 0) { | |
507 printf("nvlist_add_string failed for " | |
508 "BE_ATTR_NEW_BE_NAME (%s).\n", nbe_name); | |
509 return (1); | |
510 } | |
511 | |
512 return (be_rename(be_attrs)); | |
513 | |
514 } | |
515 | |
516 static int | |
517 be_do_create_snapshot(int argc, char **argv) | |
518 { | |
519 nvlist_t *be_attrs; | |
520 char *obe_name = NULL; | |
521 char *snap_name = NULL; | |
522 char *policy = NULL; | |
523 int c; | |
524 int ret = BE_SUCCESS; | |
525 | |
526 while ((c = getopt(argc, argv, "p:")) != -1) { | |
527 switch (c) { | |
528 case 'p': | |
529 policy = optarg; | |
530 break; | |
531 default: | |
532 usage(); | |
533 return (1); | |
534 } | |
535 } | |
536 | |
537 argc -= optind; | |
538 argv += optind; | |
539 | |
540 if (argc < 1 || argc > 2) { | |
541 usage(); | |
542 return (1); | |
543 } | |
544 | |
545 obe_name = argv[0]; | |
546 | |
547 if (argc > 1) { | |
548 /* Snapshot name provided */ | |
549 snap_name = argv[1]; | |
550 } | |
551 | |
552 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
553 printf("nvlist_alloc failed.\n"); | |
554 return (1); | |
555 } | |
556 | |
557 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
558 != 0) { | |
559 printf("nvlist_add_string failed for " | |
560 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
561 return (1); | |
562 } | |
563 | |
564 if (policy) { | |
565 if (nvlist_add_string(be_attrs, BE_ATTR_POLICY, policy) != 0) { | |
566 printf("nvlist_add_string failed for " | |
567 "BE_ATTR_POLICY (%s).\n", policy); | |
568 return (1); | |
569 } | |
570 } | |
571 | |
572 if (snap_name) { | |
573 if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) | |
574 != 0) { | |
575 printf("nvlist_add_string failed for " | |
576 "BE_ATTR_SNAP_NAME (%s).\n", snap_name); | |
577 return (1); | |
578 } | |
579 } | |
580 | |
581 ret = be_create_snapshot(be_attrs); | |
582 | |
583 if (!snap_name && ret == BE_SUCCESS) { | |
584 /* | |
585 * We requested an auto named snapshot; find out | |
586 * the snapshot name that was created for us. | |
587 */ | |
588 if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME, | |
589 &snap_name) != 0) { | |
590 printf("failed to get BE_ATTR_SNAP_NAME attribute\n"); | |
591 ret = 1; | |
592 } else { | |
593 printf("Auto named snapshot: %s\n", snap_name); | |
594 } | |
595 } | |
596 | |
597 return (ret); | |
598 } | |
599 | |
600 static int | |
601 be_do_destroy_snapshot(int argc, char **argv) | |
602 { | |
603 nvlist_t *be_attrs; | |
604 char *obe_name; | |
605 char *snap_name; | |
606 | |
607 if (argc != 2) { | |
608 usage(); | |
609 return (1); | |
610 } | |
611 | |
612 obe_name = argv[0]; | |
613 snap_name = argv[1]; | |
614 | |
615 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
616 printf("nvlist_alloc failed.\n"); | |
617 return (1); | |
618 } | |
619 | |
620 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
621 != 0) { | |
622 printf("nvlist_add_string failed for " | |
623 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
624 return (1); | |
625 } | |
626 | |
627 if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) | |
628 != 0) { | |
629 printf("nvlist_add_string failed for " | |
630 "BE_ATTR_SNAP_NAME (%s).\n", snap_name); | |
631 return (1); | |
632 } | |
633 | |
634 return (be_destroy_snapshot(be_attrs)); | |
635 } | |
636 | |
637 static int | |
638 be_do_rollback(int argc, char **argv) | |
639 { | |
640 nvlist_t *be_attrs; | |
641 char *obe_name; | |
642 char *snap_name; | |
643 | |
644 if (argc < 1 || argc > 2) { | |
645 usage(); | |
646 return (1); | |
647 } | |
648 | |
649 obe_name = argv[0]; | |
650 snap_name = argv[1]; | |
651 | |
652 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
653 printf("nvlist_alloc failed.\n"); | |
654 return (1); | |
655 } | |
656 | |
657 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
658 != 0) { | |
659 printf("nvlist_add_string failed for " | |
660 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
661 return (1); | |
662 } | |
663 | |
664 if (nvlist_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) | |
665 != 0) { | |
666 printf("nvlist_add_string failed for " | |
667 "BE_ATTR_SNAP_NAME (%s).\n", snap_name); | |
668 return (1); | |
669 } | |
670 | |
671 return (be_rollback(be_attrs)); | |
672 } | |
673 | |
674 static int | |
675 be_do_activate(int argc, char **argv) | |
676 { | |
677 nvlist_t *be_attrs; | |
678 char *obe_name; | |
679 | |
680 if (argc < 1 || argc > 2) { | |
681 usage(); | |
682 return (1); | |
683 } | |
684 | |
685 obe_name = argv[0]; | |
686 | |
687 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
688 printf("nvlist_alloc failed.\n"); | |
689 return (1); | |
690 } | |
691 | |
692 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
693 != 0) { | |
694 printf("nvlist_add_string failed for " | |
695 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
696 return (1); | |
697 } | |
698 | |
699 return (be_activate(be_attrs)); | |
700 } | |
701 | |
702 static int | |
703 be_do_mount(int argc, char **argv) | |
704 { | |
705 nvlist_t *be_attrs; | |
706 int c; | |
707 boolean_t shared_fs = B_FALSE; | |
708 int mount_flags = 0; | |
709 char *obe_name; | |
710 char *mountpoint; | |
711 | |
712 while ((c = getopt(argc, argv, "s:")) != -1) { | |
713 switch (c) { | |
714 case 's': | |
715 shared_fs = B_TRUE; | |
716 | |
717 mount_flags |= BE_MOUNT_FLAG_SHARED_FS; | |
718 | |
719 if (strcmp(optarg, "rw") == 0) { | |
720 mount_flags |= BE_MOUNT_FLAG_SHARED_RW; | |
721 } else if (strcmp(optarg, "ro") != 0) { | |
722 printf("The -s flag requires an argument " | |
723 "[ rw | ro ]\n"); | |
724 usage(); | |
725 return (1); | |
726 } | |
727 | |
728 break; | |
729 default: | |
730 usage(); | |
731 return (1); | |
732 } | |
733 } | |
734 | |
735 argc -= optind; | |
736 argv += optind; | |
737 | |
738 if (argc < 1 || argc > 2) { | |
739 usage(); | |
740 return (1); | |
741 } | |
742 | |
743 obe_name = argv[0]; | |
744 | |
745 if (argc == 2) { | |
746 mountpoint = argv[1]; | |
747 } else { | |
748 /* | |
749 * XXX - Need to generate a random mountpoint here; | |
750 * right now we're just exitting if one isn't supplied. | |
751 */ | |
752 usage(); | |
753 return (1); | |
754 } | |
755 | |
756 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
757 printf("nvlist_alloc failed.\n"); | |
758 return (1); | |
759 } | |
760 | |
761 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
762 != 0) { | |
763 printf("nvlist_add_string failed for " | |
764 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
765 return (1); | |
766 } | |
767 | |
768 if (nvlist_add_string(be_attrs, BE_ATTR_MOUNTPOINT, mountpoint) | |
769 != 0) { | |
770 printf("nvlist_add_string failed for " | |
771 "BE_ATTR_MOUNTPOINT (%s).\n", mountpoint); | |
772 return (1); | |
773 } | |
774 | |
775 if (shared_fs) { | |
776 if (nvlist_add_uint16(be_attrs, BE_ATTR_MOUNT_FLAGS, | |
777 mount_flags) != 0) { | |
778 printf("nvlist_add_uint16 failed for " | |
779 "BE_ATTR_MOUNT_FLAGS (%d).\n", mount_flags); | |
780 return (1); | |
781 } | |
782 } | |
783 | |
784 return (be_mount(be_attrs)); | |
785 } | |
786 | |
787 | |
788 static int | |
789 be_do_unmount(int argc, char **argv) | |
790 { | |
791 nvlist_t *be_attrs; | |
792 int c; | |
793 int unmount_flags = 0; | |
794 char *obe_name; | |
795 | |
796 while ((c = getopt(argc, argv, "f")) != -1) { | |
797 switch (c) { | |
798 case 'f': | |
799 unmount_flags |= BE_UNMOUNT_FLAG_FORCE; | |
800 break; | |
801 default: | |
802 usage(); | |
803 return (1); | |
804 } | |
805 } | |
806 | |
807 argc -= optind; | |
808 argv += optind; | |
809 | |
810 if (argc != 1) { | |
811 usage(); | |
812 return (1); | |
813 } | |
814 | |
815 obe_name = argv[0]; | |
816 | |
817 if (nvlist_alloc(&be_attrs, NV_UNIQUE_NAME, 0) != 0) { | |
818 printf("nvlist_alloc failed.\n"); | |
819 return (1); | |
820 } | |
821 | |
822 if (nvlist_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) | |
823 != 0) { | |
824 printf("nvlist_add_string failed for " | |
825 "BE_ATTR_ORIG_BE_NAME (%s).\n", obe_name); | |
826 return (1); | |
827 } | |
828 | |
829 if (nvlist_add_uint16(be_attrs, BE_ATTR_UNMOUNT_FLAGS, unmount_flags) | |
830 != 0) { | |
831 printf("nvlist_add_uint16 failed for " | |
832 "BE_ATTR_UNMOUNT_FLAGS\n"); | |
833 return (1); | |
834 } | |
835 | |
836 return (be_unmount(be_attrs)); | |
837 } |