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 }