예제 #1
0
static int
be_do_destroy(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	boolean_t	is_snap = B_FALSE;
	boolean_t	suppress_prompt = B_FALSE;
	int		err = 1;
	int		c;
	int		destroy_flags = 0;
	char		*snap_name;
	char		*be_name;

	while ((c = getopt(argc, argv, "fFsv")) != -1) {
		switch (c) {
		case 'f':
			destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
			break;
		case 's':
			destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
			break;
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		case 'F':
			suppress_prompt = B_TRUE;
			break;
		default:
			usage();
			return (1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage();
		return (1);
	}

	be_name = argv[0];
	if (!suppress_prompt && !confirm_destroy(be_name)) {
		(void) printf(_("%s has not been destroyed.\n"), be_name);
		return (0);
	}

	if ((snap_name = strrchr(be_name, '@')) != NULL) {
		if (snap_name[1] == '\0') {
			usage();
			return (1);
		}

		is_snap = B_TRUE;
		*snap_name = '\0';
		snap_name++;
	}

	if (be_nvl_alloc(&be_attrs) != 0)
		return (1);


	if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, be_name) != 0)
		goto out;

	if (is_snap) {
		if (be_nvl_add_string(be_attrs, BE_ATTR_SNAP_NAME,
		    snap_name) != 0)
			goto out;

		err = be_destroy_snapshot(be_attrs);
	} else {
		if (be_nvl_add_uint16(be_attrs, BE_ATTR_DESTROY_FLAGS,
		    destroy_flags) != 0)
			goto out;

		err = be_destroy(be_attrs);
	}

	switch (err) {
	case BE_SUCCESS:
		(void) printf(_("Destroyed successfully\n"));
		break;
	case BE_ERR_MOUNTED:
		(void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
		(void) fprintf(stderr, _("It is currently mounted and must be "
		    "unmounted before it can be destroyed.\n" "Use 'beadm "
		    "unmount %s' to unmount the BE before destroying\nit or "
		    "'beadm destroy -f %s'.\n"), be_name, be_name);
		break;
	case BE_ERR_DESTROY_CURR_BE:
		(void) fprintf(stderr, _("%s is the currently active BE and "
		    "cannot be destroyed.\nYou must boot from another BE in "
		    "order to destroy %s.\n"), be_name, be_name);
		break;
	case BE_ERR_ZONES_UNMOUNT:
		(void) fprintf(stderr, _("Unable to destroy one of " "%s's "
		    "zone BE's.\nUse 'beadm destroy -f %s' or "
		    "'zfs -f destroy <dataset>'.\n"), be_name, be_name);
		break;
	case BE_ERR_SS_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid snapshot.\nPlease check that the name of "
		    "the snapshot provided is correct.\n"), snap_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		(void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	case BE_ERR_SS_EXISTS:
		(void) fprintf(stderr, _("Unable to destroy %s: "
		    "BE has snapshots.\nUse 'beadm destroy -s %s' or "
		    "'zfs -r destroy <dataset>'.\n"), be_name, be_name);
		break;
	default:
		(void) fprintf(stderr, _("Unable to destroy %s.\n"), be_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	nvlist_free(be_attrs);
	return (err);
}
예제 #2
0
static int
be_do_list(int argc, char **argv)
{
	be_node_list_t	*be_nodes = NULL;
	boolean_t	all = B_FALSE;
	boolean_t	dsets = B_FALSE;
	boolean_t	snaps = B_FALSE;
	boolean_t	parsable = B_FALSE;
	int		err = 1;
	int		c = 0;
	char		*be_name = NULL;
	be_sort_t	order = BE_SORT_UNSPECIFIED;

	while ((c = getopt(argc, argv, "adk:svHK:")) != -1) {
		switch (c) {
		case 'a':
			all = B_TRUE;
			break;
		case 'd':
			dsets = B_TRUE;
			break;
		case 'k':
		case 'K':
			if (order != BE_SORT_UNSPECIFIED) {
				(void) fprintf(stderr, _("Sort key can be "
				    "specified only once.\n"));
				usage();
				return (1);
			}
			if (strcmp(optarg, "date") == 0) {
				if (c == 'k')
					order = BE_SORT_DATE;
				else
					order = BE_SORT_DATE_REV;
				break;
			}
			if (strcmp(optarg, "name") == 0) {
				if (c == 'k')
					order = BE_SORT_NAME;
				else
					order = BE_SORT_NAME_REV;
				break;
			}
			if (strcmp(optarg, "space") == 0) {
				if (c == 'k')
					order = BE_SORT_SPACE;
				else
					order = BE_SORT_SPACE_REV;
				break;
			}
			(void) fprintf(stderr, _("Unknown sort key: %s\n"),
			    optarg);
			usage();
			return (1);
		case 's':
			snaps = B_TRUE;
			break;
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		case 'H':
			parsable = B_TRUE;
			break;
		default:
			usage();
			return (1);
		}
	}

	if (all) {
		if (dsets) {
			(void) fprintf(stderr, _("Invalid options: -a and %s "
			    "are mutually exclusive.\n"), "-d");
			usage();
			return (1);
		}
		if (snaps) {
			(void) fprintf(stderr, _("Invalid options: -a and %s "
			    "are mutually exclusive.\n"), "-s");
			usage();
			return (1);
		}

		dsets = B_TRUE;
		snaps = B_TRUE;
	}

	argc -= optind;
	argv += optind;


	if (argc == 1)
		be_name = argv[0];

	err = be_list(be_name, &be_nodes);

	switch (err) {
	case BE_SUCCESS:
		/* the default sort is ascending date, no need to sort twice */
		if (order == BE_SORT_UNSPECIFIED)
			order = BE_SORT_DATE;

		if (order != BE_SORT_DATE) {
			err = be_sort(&be_nodes, order);
			if (err != BE_SUCCESS) {
				(void) fprintf(stderr, _("Unable to sort Boot "
				    "Environment\n"));
				(void) fprintf(stderr, "%s\n",
				    be_err_to_str(err));
				break;
			}
		}

		print_nodes(be_name, dsets, snaps, parsable, be_nodes);
		break;
	case BE_ERR_BE_NOENT:
		if (be_name == NULL)
			(void) fprintf(stderr, _("No boot environments found "
			    "on this system.\n"));
		else {
			(void) fprintf(stderr, _("%s does not exist or appear "
			    "to be a valid BE.\nPlease check that the name of "
			    "the BE provided is correct.\n"), be_name);
		}
		break;
	default:
		(void) fprintf(stderr, _("Unable to display Boot "
		    "Environment\n"));
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

	if (be_nodes != NULL)
		be_free_list(be_nodes);
	return (err);
}
예제 #3
0
static int
be_do_create(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	nvlist_t	*zfs_props = NULL;
	boolean_t	activate = B_FALSE;
	boolean_t	is_snap = B_FALSE;
	int		c;
	int		err = 1;
	char		*obe_name = NULL;
	char		*snap_name = NULL;
	char		*nbe_zpool = NULL;
	char		*nbe_name = NULL;
	char		*nbe_desc = NULL;
	char		*propname = NULL;
	char		*propval = NULL;
	char		*strval = NULL;

	while ((c = getopt(argc, argv, "ad:e:io:p:v")) != -1) {
		switch (c) {
		case 'a':
			activate = B_TRUE;
			break;
		case 'd':
			nbe_desc = optarg;
			break;
		case 'e':
			obe_name = optarg;
			break;
		case 'o':
			if (zfs_props == NULL && be_nvl_alloc(&zfs_props) != 0)
				return (1);

			propname = optarg;
			if ((propval = strchr(propname, '=')) == NULL) {
				(void) fprintf(stderr, _("missing "
				    "'=' for -o option\n"));
				goto out2;
			}
			*propval = '\0';
			propval++;
			if (nvlist_lookup_string(zfs_props, propname,
			    &strval) == 0) {
				(void) fprintf(stderr, _("property '%s' "
				    "specified multiple times\n"), propname);
				goto out2;

			}
			if (be_nvl_add_string(zfs_props, propname, propval)
			    != 0)
				goto out2;

			break;
		case 'p':
			nbe_zpool = optarg;
			break;
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		default:
			usage();
			goto out2;
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage();
		goto out2;
	}

	nbe_name = argv[0];

	if ((snap_name = strrchr(nbe_name, '@')) != NULL) {
		if (snap_name[1] == '\0') {
			usage();
			goto out2;
		}

		snap_name[0] = '\0';
		snap_name++;
		is_snap = B_TRUE;
	}

	if (obe_name) {
		if (is_snap) {
			usage();
			goto out2;
		}

		/*
		 * Check if obe_name is really a snapshot name.
		 * If so, split it out.
		 */
		if ((snap_name = strrchr(obe_name, '@')) != NULL) {
			if (snap_name[1] == '\0') {
				usage();
				goto out2;
			}

			snap_name[0] = '\0';
			snap_name++;
		}
	} else if (is_snap) {
		obe_name = nbe_name;
		nbe_name = NULL;
	}

	if (be_nvl_alloc(&be_attrs) != 0)
		goto out2;


	if (zfs_props != NULL && be_nvl_add_nvlist(be_attrs,
	    BE_ATTR_ORIG_BE_NAME, zfs_props) != 0)
		goto out;

	if (obe_name != NULL && be_nvl_add_string(be_attrs,
	    BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
		goto out;

	if (snap_name != NULL && be_nvl_add_string(be_attrs,
	    BE_ATTR_SNAP_NAME, snap_name) != 0)
		goto out;

	if (nbe_zpool != NULL && be_nvl_add_string(be_attrs,
	    BE_ATTR_NEW_BE_POOL, nbe_zpool) != 0)
		goto out;

	if (nbe_name != NULL && be_nvl_add_string(be_attrs,
	    BE_ATTR_NEW_BE_NAME, nbe_name) != 0)
		goto out;

	if (nbe_desc != NULL && be_nvl_add_string(be_attrs,
	    BE_ATTR_NEW_BE_DESC, nbe_desc) != 0)
		goto out;

	if (is_snap)
		err = be_create_snapshot(be_attrs);
	else
		err = be_copy(be_attrs);

	switch (err) {
	case BE_SUCCESS:
		if (!is_snap && !nbe_name) {
			/*
			 * We requested an auto named BE; find out the
			 * name of the BE that was created for us and
			 * the auto snapshot created from the original BE.
			 */
			if (nvlist_lookup_string(be_attrs, BE_ATTR_NEW_BE_NAME,
			    &nbe_name) != 0) {
				(void) fprintf(stderr, _("failed to get %s "
				    "attribute\n"), BE_ATTR_NEW_BE_NAME);
				break;
			} else
				(void) printf(_("Auto named BE: %s\n"),
				    nbe_name);

			if (nvlist_lookup_string(be_attrs, BE_ATTR_SNAP_NAME,
			    &snap_name) != 0) {
				(void) fprintf(stderr, _("failed to get %s "
				    "attribute\n"), BE_ATTR_SNAP_NAME);
				break;
			} else
				(void) printf(_("Auto named snapshot: %s\n"),
				    snap_name);
		}

		if (!is_snap && activate) {
			char *args[] = { "activate", "", NULL };
			args[1] = nbe_name;
			optind = 1;

			err = be_do_activate(2, args);
			goto out;
		}

		(void) printf(_("Created successfully\n"));
		break;
	case BE_ERR_BE_EXISTS:
		(void) fprintf(stderr, _("BE %s already exists\n."
		    "Please choose a different BE name.\n"), nbe_name);
		break;
	case BE_ERR_SS_EXISTS:
		(void) fprintf(stderr, _("BE %s snapshot %s already exists.\n"
		    "Please choose a different snapshot name.\n"), obe_name,
		    snap_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		if (is_snap)
			(void) fprintf(stderr, _("Unable to create snapshot "
			    "%s.\n"), snap_name);
		else
			(void) fprintf(stderr, _("Unable to create %s.\n"),
			    nbe_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	default:
		if (is_snap)
			(void) fprintf(stderr, _("Unable to create snapshot "
			    "%s.\n"), snap_name);
		else
			(void) fprintf(stderr, _("Unable to create %s.\n"),
			    nbe_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	nvlist_free(be_attrs);
out2:
	if (zfs_props != NULL)
		nvlist_free(zfs_props);

	return (err);
}
예제 #4
0
static int
be_do_activate(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	int		err = 1;
	int		c;
	char		*obe_name;

	while ((c = getopt(argc, argv, "v")) != -1) {
		switch (c) {
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		default:
			usage();
			return (1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage();
		return (1);
	}

	obe_name = argv[0];

	if (be_nvl_alloc(&be_attrs) != 0)
		return (1);

	if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
		goto out;

	err = be_activate(be_attrs);

	switch (err) {
	case BE_SUCCESS:
		(void) printf(_("Activated successfully\n"));
		break;
	case BE_ERR_BE_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid BE.\nPlease check that the name of "
		    "the BE provided is correct.\n"), obe_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		(void) fprintf(stderr, _("Unable to activate %s.\n"), obe_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	case BE_ERR_ACTIVATE_CURR:
	default:
		(void) fprintf(stderr, _("Unable to activate %s.\n"), obe_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	nvlist_free(be_attrs);
	return (err);
}
예제 #5
0
static int
be_do_rollback(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	char		*obe_name;
	char		*snap_name;
	int		err = 1;
	int		c;

	while ((c = getopt(argc, argv, "v")) != -1) {
		switch (c) {
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		default:
			usage();
			return (1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1 || argc > 2) {
		usage();
		return (1);
	}

	obe_name = argv[0];
	if (argc == 2)
		snap_name = argv[1];
	else { /* argc == 1 */
		if ((snap_name = strrchr(obe_name, '@')) != NULL) {
			if (snap_name[1] == '\0') {
				usage();
				return (1);
			}

			snap_name[0] = '\0';
			snap_name++;
		} else {
			usage();
			return (1);
		}
	}

	if (be_nvl_alloc(&be_attrs) != 0)
		return (1);

	if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
		goto out;

	if (be_nvl_add_string(be_attrs, BE_ATTR_SNAP_NAME, snap_name) != 0)
		goto out;

	err = be_rollback(be_attrs);

	switch (err) {
	case BE_SUCCESS:
		(void) printf(_("Rolled back successfully\n"));
		break;
	case BE_ERR_BE_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid BE.\nPlease check that the name of "
		    "the BE provided is correct.\n"), obe_name);
		break;
	case BE_ERR_SS_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid snapshot.\nPlease check that the name of "
		    "the snapshot provided is correct.\n"), snap_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		(void) fprintf(stderr, _("Rollback of BE %s snapshot %s "
		    "failed.\n"), obe_name, snap_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	default:
		(void) fprintf(stderr, _("Rollback of BE %s snapshot %s "
		    "failed.\n"), obe_name, snap_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	nvlist_free(be_attrs);
	return (err);
}
예제 #6
0
static int
be_do_unmount(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	char		*obe_name;
	int		err = 1;
	int		c;
	int		unmount_flags = 0;

	while ((c = getopt(argc, argv, "fv")) != -1) {
		switch (c) {
		case 'f':
			unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
			break;
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		default:
			usage();
			return (1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc != 1) {
		usage();
		return (1);
	}

	obe_name = argv[0];

	if (be_nvl_alloc(&be_attrs) != 0)
		return (1);


	if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
		goto out;

	if (be_nvl_add_uint16(be_attrs, BE_ATTR_UNMOUNT_FLAGS,
	    unmount_flags) != 0)
		goto out;

	err = be_unmount(be_attrs);

	switch (err) {
	case BE_SUCCESS:
		(void) printf(_("Unmounted successfully\n"));
		break;
	case BE_ERR_BE_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid BE.\nPlease check that the name of "
		    "the BE provided is correct.\n"), obe_name);
		break;
	case BE_ERR_UMOUNT_CURR_BE:
		(void) fprintf(stderr, _("%s is the currently active BE.\n"
		    "It cannot be unmounted unless another BE is the "
		    "currently active BE.\n"), obe_name);
		break;
	case BE_ERR_UMOUNT_SHARED:
		(void) fprintf(stderr, _("%s is a shared file system and it "
		    "cannot be unmounted.\n"), obe_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		(void) fprintf(stderr, _("Unable to unmount %s.\n"), obe_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	default:
		(void) fprintf(stderr, _("Unable to unmount %s.\n"), obe_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	nvlist_free(be_attrs);
	return (err);
}
예제 #7
0
static int
be_do_mount(int argc, char **argv)
{
	nvlist_t	*be_attrs;
	boolean_t	shared_fs = B_FALSE;
	int		err = 1;
	int		c;
	int		mount_flags = 0;
	char		*obe_name;
	char		*mountpoint;
	char		*tmp_mp = NULL;

	while ((c = getopt(argc, argv, "s:v")) != -1) {
		switch (c) {
		case 's':
			shared_fs = B_TRUE;

			mount_flags |= BE_MOUNT_FLAG_SHARED_FS;

			if (strcmp(optarg, "rw") == 0) {
				mount_flags |= BE_MOUNT_FLAG_SHARED_RW;
			} else if (strcmp(optarg, "ro") != 0) {
				(void) fprintf(stderr, _("The -s flag "
				    "requires an argument [ rw | ro ]\n"));
				usage();
				return (1);
			}

			break;
		case 'v':
			libbe_print_errors(B_TRUE);
			break;
		default:
			usage();
			return (1);
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < 1 || argc > 2) {
		usage();
		return (1);
	}

	obe_name = argv[0];

	if (argc == 2) {
		mountpoint = argv[1];
		if (mountpoint[0] != '/') {
			(void) fprintf(stderr, _("Invalid mount point %s. "
			    "Mount point must start with a /.\n"), mountpoint);
			return (1);
		}
	} else {
		const char *tmpdir = getenv("TMPDIR");
		const char *tmpname = "tmp.XXXXXX";
		int sz;

		if (tmpdir == NULL)
			tmpdir = "/tmp";

		sz = asprintf(&tmp_mp, "%s/%s", tmpdir, tmpname);
		if (sz < 0) {
			(void) fprintf(stderr, _("internal error: "
			    "out of memory\n"));
			return (1);
		}

		mountpoint = mkdtemp(tmp_mp);
	}

	if (be_nvl_alloc(&be_attrs) != 0)
		return (1);

	if (be_nvl_add_string(be_attrs, BE_ATTR_ORIG_BE_NAME, obe_name) != 0)
		goto out;

	if (be_nvl_add_string(be_attrs, BE_ATTR_MOUNTPOINT, mountpoint) != 0)
		goto out;

	if (shared_fs && be_nvl_add_uint16(be_attrs, BE_ATTR_MOUNT_FLAGS,
	    mount_flags) != 0)
		goto out;

	err = be_mount(be_attrs);

	switch (err) {
	case BE_SUCCESS:
		(void) printf(_("Mounted successfully on: '%s'\n"), mountpoint);
		break;
	case BE_ERR_BE_NOENT:
		(void) fprintf(stderr, _("%s does not exist or appear "
		    "to be a valid BE.\nPlease check that the name of "
		    "the BE provided is correct.\n"), obe_name);
		break;
	case BE_ERR_MOUNTED:
		(void) fprintf(stderr, _("%s is already mounted.\n"
		    "Please unmount the BE before mounting it again.\n"),
		    obe_name);
		break;
	case BE_ERR_PERM:
	case BE_ERR_ACCESS:
		(void) fprintf(stderr, _("Unable to mount %s.\n"), obe_name);
		(void) fprintf(stderr, _("You have insufficient privileges to "
		    "execute this command.\n"));
		break;
	case BE_ERR_NO_MOUNTED_ZONE:
		(void) fprintf(stderr, _("Mounted on '%s'.\nUnable to mount "
		    "one of %s's zone BE's.\n"), mountpoint, obe_name);
		break;
	default:
		(void) fprintf(stderr, _("Unable to mount %s.\n"), obe_name);
		(void) fprintf(stderr, "%s\n", be_err_to_str(err));
	}

out:
	if (tmp_mp != NULL)
		free(tmp_mp);
	nvlist_free(be_attrs);
	return (err);
}