/* * 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); } }
/* * 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); }
/* * 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); }