예제 #1
0
/*
 * Function:	be_is_active_on_boot
 * Description:	Checks if the BE name passed in has the "active on boot"
 *		property set to B_TRUE.
 * Paramters:
 *		be_name - the name of the BE to check
 * Returns:
 *		B_TRUE - if active on boot.
 *		B_FALSE - if not active on boot.
 * Scope:
 *		Semi-private (library wide use only)
 */
boolean_t
be_is_active_on_boot(char *be_name)
{
	be_node_list_t *be_node = NULL;

	if (be_name == NULL) {
		be_print_err(gettext("be_is_active_on_boot: "
		    "be_name must not be NULL\n"));
		return (B_FALSE);
	}

	if (_be_list(be_name, &be_node) != BE_SUCCESS) {
		return (B_FALSE);
	}

	if (be_node == NULL) {
		return (B_FALSE);
	}

	if (be_node->be_active_on_boot) {
		be_free_list(be_node);
		return (B_TRUE);
	} else {
		be_free_list(be_node);
		return (B_FALSE);
	}
}
예제 #2
0
/*
 * Function:	be_list
 * Description:	Calls _be_list which finds all the BEs on the system and
 *		returns the datasets and snapshots belonging to each BE.
 *		Also data, such as dataset and snapshot properties,
 *		for each BE and their snapshots and datasets is
 *		returned. The data returned is as described in the
 *		be_dataset_list_t, be_snapshot_list_t and be_node_list_t
 *		structures.
 * Parameters:
 *		be_name - The name of the BE to look up.
 *			  If NULL a list of all BEs will be returned.
 *		be_nodes - A reference pointer to the list of BEs. The list
 *			   structure will be allocated by _be_list and must
 *			   be freed by a call to be_free_list. If there are no
 *			   BEs found on the system this reference will be
 *			   set to NULL.
 * Return:
 *		BE_SUCCESS - Success
 *		be_errno_t - Failure
 * Scope:
 *		Public
 */
int
be_list(char *be_name, be_node_list_t **be_nodes)
{
	int	ret = BE_SUCCESS;

	/* Initialize libzfs handle */
	if (!be_zfs_init())
		return (BE_ERR_INIT);

	/* Validate be_name if its not NULL */
	if (be_name != NULL) {
		if (!be_valid_be_name(be_name)) {
			be_print_err(gettext("be_list: "
			    "invalid BE name %s\n"), be_name);
			return (BE_ERR_INVAL);
		}
	}

	ret = _be_list(be_name, be_nodes);

	be_zfs_fini();

	return (ret);
}
예제 #3
0
/*
 * Function:	_be_activate
 * Description:	This does the actual work described in be_activate.
 * Parameters:
 *		be_name - pointer to the name of BE to activate.
 *
 * Return:
 *		BE_SUCCESS - Success
 *		be_errnot_t - Failure
 * Scope:
 *		Public
 */
int
_be_activate(char *be_name)
{
	be_transaction_data_t cb = { 0 };
	zfs_handle_t	*zhp = NULL;
	char		root_ds[MAXPATHLEN];
	char		*cur_vers = NULL, *new_vers = NULL;
	be_node_list_t	*be_nodes = NULL;
	uuid_t		uu = {0};
	int		entry, ret = BE_SUCCESS;
	int		zret = 0;

	/*
	 * TODO: The BE needs to be validated to make sure that it is actually
	 * a bootable BE.
	 */

	if (be_name == NULL)
		return (BE_ERR_INVAL);

	/* Set obe_name to be_name in the cb structure */
	cb.obe_name = be_name;

	/* find which zpool the be is in */
	if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &cb)) == 0) {
		be_print_err(gettext("be_activate: failed to "
		    "find zpool for BE (%s)\n"), cb.obe_name);
		return (BE_ERR_BE_NOENT);
	} else if (zret < 0) {
		be_print_err(gettext("be_activate: "
		    "zpool_iter failed: %s\n"),
		    libzfs_error_description(g_zfs));
		ret = zfs_err_to_be_err(g_zfs);
		return (ret);
	}

	be_make_root_ds(cb.obe_zpool, cb.obe_name, root_ds, sizeof (root_ds));
	cb.obe_root_ds = strdup(root_ds);

	if (getzoneid() == GLOBAL_ZONEID) {
		if (be_has_grub() && (ret = be_get_grub_vers(&cb, &cur_vers,
		    &new_vers)) != BE_SUCCESS) {
			be_print_err(gettext("be_activate: failed to get grub "
			    "versions from capability files.\n"));
			return (ret);
		}
		if (cur_vers != NULL) {
			/*
			 * We need to check to see if the version number from
			 * the BE being activated is greater than the current
			 * one.
			 */
			if (new_vers != NULL &&
			    atof(cur_vers) < atof(new_vers)) {
				if ((ret = be_do_installgrub(&cb))
				    != BE_SUCCESS) {
					free(new_vers);
					free(cur_vers);
					return (ret);
				}
				free(new_vers);
			}
			free(cur_vers);
		} else if (new_vers != NULL) {
			if ((ret = be_do_installgrub(&cb)) != BE_SUCCESS) {
				free(new_vers);
				return (ret);
			}
			free(new_vers);
		}
		if (!be_has_menu_entry(root_ds, cb.obe_zpool, &entry)) {
			if ((ret = be_append_menu(cb.obe_name, cb.obe_zpool,
			    NULL, NULL, NULL)) != BE_SUCCESS) {
				be_print_err(gettext("be_activate: Failed to "
				    "add BE (%s) to the GRUB menu\n"),
				    cb.obe_name);
				goto done;
			}
		}
		if (be_has_grub()) {
			if ((ret = be_change_grub_default(cb.obe_name,
			    cb.obe_zpool)) != BE_SUCCESS) {
				be_print_err(gettext("be_activate: failed to "
				    "change the default entry in menu.lst\n"));
				goto done;
			}
		}
	}

	if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
		return (ret);
	}

	if ((ret = set_canmount(be_nodes, "noauto")) != BE_SUCCESS) {
		be_print_err(gettext("be_activate: failed to set "
		    "canmount dataset property\n"));
		goto done;
	}

	if ((ret = set_bootfs(be_nodes->be_rpool, root_ds)) != BE_SUCCESS) {
		be_print_err(gettext("be_activate: failed to set "
		    "bootfs pool property for %s\n"), root_ds);
		goto done;
	}

	if ((zhp = zfs_open(g_zfs, root_ds, ZFS_TYPE_FILESYSTEM)) != NULL) {
		/*
		 * We don't need to close the zfs handle at this
		 * point because The callback funtion
		 * be_promote_ds_callback() will close it for us.
		 */
		if (be_promote_ds_callback(zhp, NULL) != 0) {
			be_print_err(gettext("be_activate: "
			    "failed to activate the "
			    "datasets for %s: %s\n"),
			    root_ds,
			    libzfs_error_description(g_zfs));
			ret = BE_ERR_PROMOTE;
			goto done;
		}
	} else {
		be_print_err(gettext("be_activate:: failed to open "
		    "dataset (%s): %s\n"), root_ds,
		    libzfs_error_description(g_zfs));
		ret = zfs_err_to_be_err(g_zfs);
		goto done;
	}

	if (getzoneid() == GLOBAL_ZONEID &&
	    be_get_uuid(cb.obe_root_ds, &uu) == BE_SUCCESS &&
	    (ret = be_promote_zone_ds(cb.obe_name, cb.obe_root_ds))
	    != BE_SUCCESS) {
		be_print_err(gettext("be_activate: failed to promote "
		    "the active zonepath datasets for zones in BE %s\n"),
		    cb.obe_name);
	}

done:
	be_free_list(be_nodes);
	return (ret);
}