xref: /onnv-gate/usr/src/lib/libbe/tbeadm/tbeadm.c (revision 13013: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
usage(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
main(int argc,char ** argv)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
be_do_create(int argc,char ** argv)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
be_do_destroy(int argc,char ** argv)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
be_do_list(int argc,char ** argv)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
be_do_rename(int argc,char ** argv)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
be_do_create_snapshot(int argc,char ** argv)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
be_do_destroy_snapshot(int argc,char ** argv)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
be_do_rollback(int argc,char ** argv)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
be_do_activate(int argc,char ** argv)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
be_do_mount(int argc,char ** argv)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
be_do_unmount(int argc,char ** argv)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 }
838