/* * Function: set_bootfs * Description: Sets the bootfs property on the boot pool to be the * root dataset of the activated BE. * Parameters: * boot_pool - The pool we're setting bootfs in. * be_root_ds - The main dataset for the BE. * Return: * BE_SUCCESS - Success * be_errno_t - Failure * Scope: * Private */ static int set_bootfs(char *boot_rpool, char *be_root_ds) { zpool_handle_t *zhp; int err = BE_SUCCESS; if ((zhp = zpool_open(g_zfs, boot_rpool)) == NULL) { be_print_err(gettext("set_bootfs: failed to open pool " "(%s): %s\n"), boot_rpool, libzfs_error_description(g_zfs)); err = zfs_err_to_be_err(g_zfs); return (err); } err = zpool_set_prop(zhp, "bootfs", be_root_ds); if (err) { be_print_err(gettext("set_bootfs: failed to set " "bootfs property for pool %s: %s\n"), boot_rpool, libzfs_error_description(g_zfs)); err = zfs_err_to_be_err(g_zfs); zpool_close(zhp); return (err); } zpool_close(zhp); return (BE_SUCCESS); }
/* * given the path to a zvol, return the cXtYdZ name * returns < 0 on error, 0 if it isn't a zvol, > 1 on success */ static int ztop(char *arg, char *diskname) { zpool_handle_t *zpool_handle; nvlist_t *config, *nvroot; nvlist_t **child; uint_t children; libzfs_handle_t *lzfs; char *vname; char *p; char pool_name[MAXPATHLEN]; if (strncmp(arg, "/dev/zvol/dsk/", 14)) { return (0); } arg += 14; (void) strncpy(pool_name, arg, MAXPATHLEN); if ((p = strchr(pool_name, '/')) != NULL) *p = '\0'; STRCPYLIM(new_cc.cf_fs, p + 1, "statefile path"); if ((lzfs = libzfs_init()) == NULL) { mesg(MERR, "failed to initialize ZFS library\n"); return (-1); } if ((zpool_handle = zpool_open(lzfs, pool_name)) == NULL) { mesg(MERR, "couldn't open pool '%s'\n", pool_name); libzfs_fini(lzfs); return (-1); } config = zpool_get_config(zpool_handle, NULL); if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot) != 0) { zpool_close(zpool_handle); libzfs_fini(lzfs); return (-1); } verify(nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN, &child, &children) == 0); if (children != 1) { mesg(MERR, "expected one vdev, got %d\n", children); zpool_close(zpool_handle); libzfs_fini(lzfs); return (-1); } vname = zpool_vdev_name(lzfs, zpool_handle, child[0], B_FALSE); if (vname == NULL) { mesg(MERR, "couldn't determine vdev name\n"); zpool_close(zpool_handle); libzfs_fini(lzfs); return (-1); } (void) strcpy(diskname, "/dev/dsk/"); (void) strcat(diskname, vname); free(vname); zpool_close(zpool_handle); libzfs_fini(lzfs); return (1); }
static char * find_root_device_from_libzfs (const char *dir) { char *device; char *poolname; char *poolfs; grub_find_zpool_from_dir (dir, &poolname, &poolfs); if (! poolname) return NULL; { zpool_handle_t *zpool; libzfs_handle_t *libzfs; nvlist_t *nvlist; nvlist_t **nvlist_array; unsigned int nvlist_count; libzfs = grub_get_libzfs_handle (); if (! libzfs) return NULL; zpool = zpool_open (libzfs, poolname); nvlist = zpool_get_config (zpool, NULL); if (nvlist_lookup_nvlist (nvlist, "vdev_tree", &nvlist) != 0) error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")"); if (nvlist_lookup_nvlist_array (nvlist, "children", &nvlist_array, &nvlist_count) != 0) error (1, errno, "nvlist_lookup_nvlist_array (\"children\")"); do { assert (nvlist_count > 0); } while (nvlist_lookup_nvlist_array (nvlist_array[0], "children", &nvlist_array, &nvlist_count) == 0); if (nvlist_lookup_string (nvlist_array[0], "path", &device) != 0) error (1, errno, "nvlist_lookup_string (\"path\")"); zpool_close (zpool); } free (poolname); if (poolfs) free (poolfs); return device; }
int zfs_make_lustre(struct mkfs_opts *mop) { zfs_handle_t *zhp; zpool_handle_t *php; char *pool = NULL; char *mkfs_cmd = NULL; char *mkfs_tmp = NULL; char *ds = mop->mo_device; int pool_exists = 0, ret; if (osd_check_zfs_setup() == 0) return EINVAL; /* no automatic index with zfs backend */ if (mop->mo_ldd.ldd_flags & LDD_F_NEED_INDEX) { fatal(); fprintf(stderr, "The target index must be specified with " "--index\n"); return EINVAL; } pool = strdup(ds); if (pool == NULL) return ENOMEM; mkfs_cmd = malloc(PATH_MAX); if (mkfs_cmd == NULL) { ret = ENOMEM; goto out; } mkfs_tmp = malloc(PATH_MAX); if (mkfs_tmp == NULL) { ret = ENOMEM; goto out; } /* Due to zfs_prepare_lustre() check the '/' must exist */ strchr(pool, '/')[0] = '\0'; /* If --reformat was given attempt to destroy the previous dataset */ if ((mop->mo_flags & MO_FORCEFORMAT) && ((zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM)) != NULL)) { ret = zfs_destroy(zhp, 0); if (ret) { zfs_close(zhp); fprintf(stderr, "Failed destroy zfs dataset %s (%d)\n", ds, ret); goto out; } zfs_close(zhp); } /* * Create the zpool if the vdevs have been specified and the pool * does not already exists. The pool creation itself will be done * with the zpool command rather than the zpool_create() library call * so the existing zpool error handling can be leveraged. */ php = zpool_open(g_zfs, pool); if (php) { pool_exists = 1; zpool_close(php); } if ((mop->mo_pool_vdevs != NULL) && (pool_exists == 0)) { memset(mkfs_cmd, 0, PATH_MAX); snprintf(mkfs_cmd, PATH_MAX, "zpool create -f -O canmount=off %s", pool); /* Append the vdev config and create file vdevs as required */ while (*mop->mo_pool_vdevs != NULL) { strscat(mkfs_cmd, " ", PATH_MAX); strscat(mkfs_cmd, *mop->mo_pool_vdevs, PATH_MAX); ret = zfs_create_vdev(mop, *mop->mo_pool_vdevs); if (ret) goto out; mop->mo_pool_vdevs++; } vprint("mkfs_cmd = %s\n", mkfs_cmd); ret = run_command(mkfs_cmd, PATH_MAX); if (ret) { fatal(); fprintf(stderr, "Unable to create pool %s (%d)\n", pool, ret); goto out; } } /* * Create the ZFS filesystem with any required mkfs options: * - canmount=off is set to prevent zfs automounting * - version=4 is set because SA are not yet handled by the osd */ memset(mkfs_cmd, 0, PATH_MAX); snprintf(mkfs_cmd, PATH_MAX, "zfs create -o canmount=off -o xattr=sa%s %s", zfs_mkfs_opts(mop, mkfs_tmp, PATH_MAX), ds); vprint("mkfs_cmd = %s\n", mkfs_cmd); ret = run_command(mkfs_cmd, PATH_MAX); if (ret) { fatal(); fprintf(stderr, "Unable to create filesystem %s (%d)\n", ds, ret); goto out; } out: if (pool != NULL) free(pool); if (mkfs_cmd != NULL) free(mkfs_cmd); if (mkfs_tmp != NULL) free(mkfs_tmp); return ret; }
/* * Function: be_get_node_data * Description: Helper function used to collect all the information to fill * in the be_node_list structure to be returned by be_list. * Parameters: * zhp - Handle to the root dataset for the BE whose information * we're collecting. * be_node - a pointer to the node structure we're filling in. * be_name - The BE name of the node whose information we're * collecting. * current_be - the name of the currently active BE. * be_ds - The dataset name for the BE. * * Returns: * BE_SUCCESS - Success * be_errno_t - Failure * Scope: * Private */ static int be_get_node_data( zfs_handle_t *zhp, be_node_list_t *be_node, char *be_name, const char *rpool, char *current_be, char *be_ds) { char prop_buf[MAXPATHLEN]; nvlist_t *userprops = NULL; nvlist_t *propval = NULL; nvlist_t *zone_propval = NULL; char *prop_str = NULL; char *zone_prop_str = NULL; char *grub_default_bootfs = NULL; zpool_handle_t *zphp = NULL; int err = 0; if (be_node == NULL || be_name == NULL || current_be == NULL || be_ds == NULL) { be_print_err(gettext("be_get_node_data: invalid arguments, " "can not be NULL\n")); return (BE_ERR_INVAL); } errno = 0; be_node->be_root_ds = strdup(be_ds); if ((err = errno) != 0 || be_node->be_root_ds == NULL) { be_print_err(gettext("be_get_node_data: failed to " "copy root dataset name\n")); return (errno_to_be_err(err)); } be_node->be_node_name = strdup(be_name); if ((err = errno) != 0 || be_node->be_node_name == NULL) { be_print_err(gettext("be_get_node_data: failed to " "copy BE name\n")); return (errno_to_be_err(err)); } if (strncmp(be_name, current_be, MAXPATHLEN) == 0) be_node->be_active = B_TRUE; else be_node->be_active = B_FALSE; be_node->be_rpool = strdup(rpool); if (be_node->be_rpool == NULL || (err = errno) != 0) { be_print_err(gettext("be_get_node_data: failed to " "copy root pool name\n")); return (errno_to_be_err(err)); } be_node->be_space_used = zfs_prop_get_int(zhp, ZFS_PROP_USED); if (getzoneid() == GLOBAL_ZONEID) { if ((zphp = zpool_open(g_zfs, rpool)) == NULL) { be_print_err(gettext("be_get_node_data: failed to open " "pool (%s): %s\n"), rpool, libzfs_error_description(g_zfs)); return (zfs_err_to_be_err(g_zfs)); } (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf, ZFS_MAXPROPLEN, NULL, B_FALSE); if (be_has_grub() && (be_default_grub_bootfs(rpool, &grub_default_bootfs) == BE_SUCCESS) && grub_default_bootfs != NULL) if (strcmp(grub_default_bootfs, be_ds) == 0) be_node->be_active_on_boot = B_TRUE; else be_node->be_active_on_boot = B_FALSE; else if (prop_buf != NULL && strcmp(prop_buf, be_ds) == 0) be_node->be_active_on_boot = B_TRUE; else be_node->be_active_on_boot = B_FALSE; be_node->be_global_active = B_TRUE; free(grub_default_bootfs); zpool_close(zphp); } else { if (be_zone_compare_uuids(be_node->be_root_ds)) be_node->be_global_active = B_TRUE; else be_node->be_global_active = B_FALSE; } /* * If the dataset is mounted use the mount point * returned from the zfs_is_mounted call. If the * dataset is not mounted then pull the mount * point information out of the zfs properties. */ be_node->be_mounted = zfs_is_mounted(zhp, &(be_node->be_mntpt)); if (!be_node->be_mounted) { if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop_buf, ZFS_MAXPROPLEN, NULL, NULL, 0, B_FALSE) == 0) be_node->be_mntpt = strdup(prop_buf); else return (zfs_err_to_be_err(g_zfs)); } be_node->be_node_creation = (time_t)zfs_prop_get_int(zhp, ZFS_PROP_CREATION); /* Get all user properties used for libbe */ if ((userprops = zfs_get_user_props(zhp)) == NULL) { be_node->be_policy_type = strdup(be_default_policy()); } else { if (getzoneid() != GLOBAL_ZONEID) { if (nvlist_lookup_nvlist(userprops, BE_ZONE_ACTIVE_PROPERTY, &zone_propval) != 0 || zone_propval == NULL) { be_node->be_active_on_boot = B_FALSE; } else { verify(nvlist_lookup_string(zone_propval, ZPROP_VALUE, &zone_prop_str) == 0); if (strcmp(zone_prop_str, "on") == 0) { be_node->be_active_on_boot = B_TRUE; } else { be_node->be_active_on_boot = B_FALSE; } } } if (nvlist_lookup_nvlist(userprops, BE_POLICY_PROPERTY, &propval) != 0 || propval == NULL) { be_node->be_policy_type = strdup(be_default_policy()); } else { verify(nvlist_lookup_string(propval, ZPROP_VALUE, &prop_str) == 0); if (prop_str == NULL || strcmp(prop_str, "-") == 0 || strcmp(prop_str, "") == 0) be_node->be_policy_type = strdup(be_default_policy()); else be_node->be_policy_type = strdup(prop_str); } if (getzoneid() != GLOBAL_ZONEID) { if (nvlist_lookup_nvlist(userprops, BE_ZONE_PARENTBE_PROPERTY, &propval) != 0 && nvlist_lookup_string(propval, ZPROP_VALUE, &prop_str) == 0) { be_node->be_uuid_str = strdup(prop_str); } } else { if (nvlist_lookup_nvlist(userprops, BE_UUID_PROPERTY, &propval) == 0 && nvlist_lookup_string(propval, ZPROP_VALUE, &prop_str) == 0) { be_node->be_uuid_str = strdup(prop_str); } } } /* * Increment the dataset counter to include the root dataset * of the BE. */ be_node->be_node_num_datasets++; return (BE_SUCCESS); }
/* * Function: _be_list * Description: This does the actual work described in be_list. * 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 here 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: * Semi-private (library wide use only) */ int _be_list(char *be_name, be_node_list_t **be_nodes) { list_callback_data_t cb = { 0 }; be_transaction_data_t bt = { 0 }; int ret = BE_SUCCESS; zpool_handle_t *zphp; char *rpool = NULL; struct be_defaults be_defaults; if (be_nodes == NULL) return (BE_ERR_INVAL); be_get_defaults(&be_defaults); if (be_find_current_be(&bt) != BE_SUCCESS) { /* * We were unable to find a currently booted BE which * probably means that we're not booted in a BE envoronment. * None of the BE's will be marked as the active BE. */ (void) strcpy(cb.current_be, "-"); } else { (void) strncpy(cb.current_be, bt.obe_name, sizeof (cb.current_be)); rpool = bt.obe_zpool; } /* * If be_name is NULL we'll look for all BE's on the system. * If not then we will only return data for the specified BE. */ if (be_name != NULL) cb.be_name = strdup(be_name); if (be_defaults.be_deflt_rpool_container && rpool != NULL) { if ((zphp = zpool_open(g_zfs, rpool)) == NULL) { be_print_err(gettext("be_list: failed to " "open rpool (%s): %s\n"), rpool, libzfs_error_description(g_zfs)); free(cb.be_name); return (zfs_err_to_be_err(g_zfs)); } ret = be_get_list_callback(zphp, &cb); } else { if ((zpool_iter(g_zfs, be_get_list_callback, &cb)) != 0) { if (cb.be_nodes_head != NULL) { be_free_list(cb.be_nodes_head); cb.be_nodes_head = NULL; cb.be_nodes = NULL; } ret = BE_ERR_BE_NOENT; } } if (cb.be_nodes_head == NULL) { if (be_name != NULL) be_print_err(gettext("be_list: BE (%s) does not " "exist\n"), be_name); else be_print_err(gettext("be_list: No BE's found\n")); ret = BE_ERR_BE_NOENT; } *be_nodes = cb.be_nodes_head; free(cb.be_name); be_sort_list(be_nodes); return (ret); }
static char * find_root_device_from_libzfs (const char *dir) { char *device = NULL; char *poolname; char *poolfs; grub_find_zpool_from_dir (dir, &poolname, &poolfs); if (! poolname) return NULL; { zpool_handle_t *zpool; libzfs_handle_t *libzfs; nvlist_t *config, *vdev_tree; nvlist_t **children, **path; unsigned int nvlist_count; unsigned int i; libzfs = grub_get_libzfs_handle (); if (! libzfs) return NULL; zpool = zpool_open (libzfs, poolname); config = zpool_get_config (zpool, NULL); if (nvlist_lookup_nvlist (config, "vdev_tree", &vdev_tree) != 0) error (1, errno, "nvlist_lookup_nvlist (\"vdev_tree\")"); if (nvlist_lookup_nvlist_array (vdev_tree, "children", &children, &nvlist_count) != 0) error (1, errno, "nvlist_lookup_nvlist_array (\"children\")"); assert (nvlist_count > 0); while (nvlist_lookup_nvlist_array (children[0], "children", &children, &nvlist_count) == 0) assert (nvlist_count > 0); for (i = 0; i < nvlist_count; i++) { if (nvlist_lookup_string (children[i], "path", &device) != 0) error (1, errno, "nvlist_lookup_string (\"path\")"); struct stat st; if (stat (device, &st) == 0) { device = xstrdup (device); break; } device = NULL; } zpool_close (zpool); } free (poolname); if (poolfs) free (poolfs); return device; }
/* * Function: be_do_installgrub * Description: This function runs installgrub using the grub loader files * from the BE we're activating and installing them on the * pool the BE lives in. * * Parameters: * bt - The transaction data for the BE we're activating. * Return: * BE_SUCCESS - Success * be_errno_t - Failure * * Scope: * Private */ static int be_do_installgrub(be_transaction_data_t *bt) { zpool_handle_t *zphp = NULL; zfs_handle_t *zhp = NULL; nvlist_t **child, *nv, *config; uint_t c, children = 0; char *tmp_mntpt = NULL; char *pool_mntpnt = NULL; char *ptmp_mntpnt = NULL; char *orig_mntpnt = NULL; FILE *cap_fp = NULL; FILE *zpool_cap_fp = NULL; char line[BUFSIZ]; char cap_file[MAXPATHLEN]; char zpool_cap_file[MAXPATHLEN]; char stage1[MAXPATHLEN]; char stage2[MAXPATHLEN]; char installgrub_cmd[MAXPATHLEN]; char *vname; char be_run_cmd_errbuf[BUFSIZ]; int ret = BE_SUCCESS; int err = 0; boolean_t be_mounted = B_FALSE; boolean_t pool_mounted = B_FALSE; if (!be_has_grub()) { be_print_err(gettext("be_do_installgrub: Not supported " "on this architecture\n")); return (BE_ERR_NOTSUP); } if ((zhp = zfs_open(g_zfs, bt->obe_root_ds, ZFS_TYPE_FILESYSTEM)) == NULL) { be_print_err(gettext("be_do_installgrub: failed to " "open BE root dataset (%s): %s\n"), bt->obe_root_ds, libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); return (ret); } if (!zfs_is_mounted(zhp, &tmp_mntpt)) { if ((ret = _be_mount(bt->obe_name, &tmp_mntpt, BE_MOUNT_FLAG_NO_ZONES)) != BE_SUCCESS) { be_print_err(gettext("be_do_installgrub: failed to " "mount BE (%s)\n"), bt->obe_name); ZFS_CLOSE(zhp); return (ret); } be_mounted = B_TRUE; } ZFS_CLOSE(zhp); (void) snprintf(stage1, sizeof (stage1), "%s%s", tmp_mntpt, BE_STAGE_1); (void) snprintf(stage2, sizeof (stage2), "%s%s", tmp_mntpt, BE_STAGE_2); if ((zphp = zpool_open(g_zfs, bt->obe_zpool)) == NULL) { be_print_err(gettext("be_do_installgrub: failed to open " "pool (%s): %s\n"), bt->obe_zpool, libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); if (be_mounted) (void) _be_unmount(bt->obe_name, 0); free(tmp_mntpt); return (ret); } if ((config = zpool_get_config(zphp, NULL)) == NULL) { be_print_err(gettext("be_do_installgrub: failed to get zpool " "configuration information. %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } /* * Get the vdev tree */ if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nv) != 0) { be_print_err(gettext("be_do_installgrub: failed to get vdev " "tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) { be_print_err(gettext("be_do_installgrub: failed to traverse " "the vdev tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } for (c = 0; c < children; c++) { uint_t i, nchildren = 0; nvlist_t **nvchild; vname = zpool_vdev_name(g_zfs, zphp, child[c], B_FALSE); if (vname == NULL) { be_print_err(gettext( "be_do_installgrub: " "failed to get device name: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } if (strcmp(vname, "mirror") == 0 || vname[0] != 'c') { if (nvlist_lookup_nvlist_array(child[c], ZPOOL_CONFIG_CHILDREN, &nvchild, &nchildren) != 0) { be_print_err(gettext("be_do_installgrub: " "failed to traverse the vdev tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } for (i = 0; i < nchildren; i++) { vname = zpool_vdev_name(g_zfs, zphp, nvchild[i], B_FALSE); if (vname == NULL) { be_print_err(gettext( "be_do_installgrub: " "failed to get device name: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; } (void) snprintf(installgrub_cmd, sizeof (installgrub_cmd), "%s %s %s /dev/rdsk/%s", BE_INSTALL_GRUB, stage1, stage2, vname); if (be_run_cmd(installgrub_cmd, be_run_cmd_errbuf, BUFSIZ, NULL, 0) != BE_SUCCESS) { be_print_err(gettext( "be_do_installgrub: installgrub " "failed for device %s.\n"), vname); /* Assume localized cmd err output. */ be_print_err(gettext( " Command: \"%s\"\n"), installgrub_cmd); be_print_err("%s", be_run_cmd_errbuf); free(vname); ret = BE_ERR_BOOTFILE_INST; goto done; } free(vname); } } else { (void) snprintf(installgrub_cmd, sizeof (installgrub_cmd), "%s %s %s /dev/rdsk/%s", BE_INSTALL_GRUB, stage1, stage2, vname); if (be_run_cmd(installgrub_cmd, be_run_cmd_errbuf, BUFSIZ, NULL, 0) != BE_SUCCESS) { be_print_err(gettext( "be_do_installgrub: installgrub " "failed for device %s.\n"), vname); /* Assume localized cmd err output. */ be_print_err(gettext(" Command: \"%s\"\n"), installgrub_cmd); be_print_err("%s", be_run_cmd_errbuf); free(vname); ret = BE_ERR_BOOTFILE_INST; goto done; } free(vname); } } /* * Copy the grub capability file from the BE we're activating into * the root pool. */ (void) snprintf(cap_file, sizeof (cap_file), "%s%s", tmp_mntpt, BE_CAP_FILE); if ((zhp = zfs_open(g_zfs, bt->obe_zpool, ZFS_TYPE_FILESYSTEM)) == NULL) { be_print_err(gettext("be_do_installgrub: zfs_open " "failed: %s\n"), libzfs_error_description(g_zfs)); zpool_close(zphp); return (zfs_err_to_be_err(g_zfs)); } /* * Check to see if the pool's dataset is mounted. If it isn't we'll * attempt to mount it. */ if ((ret = be_mount_pool(zhp, &ptmp_mntpnt, &orig_mntpnt, &pool_mounted)) != BE_SUCCESS) { be_print_err(gettext("be_do_installgrub: pool dataset " "(%s) could not be mounted\n"), bt->obe_zpool); ZFS_CLOSE(zhp); zpool_close(zphp); return (ret); } /* * Get the mountpoint for the root pool dataset. */ if (!zfs_is_mounted(zhp, &pool_mntpnt)) { be_print_err(gettext("be_do_installgrub: pool " "dataset (%s) is not mounted. Can't check the grub " "version from the grub capability file.\n"), bt->obe_zpool); ret = BE_ERR_NO_MENU; goto done; } (void) snprintf(zpool_cap_file, sizeof (zpool_cap_file), "%s%s", pool_mntpnt, BE_CAP_FILE); free(pool_mntpnt); pool_mntpnt = NULL; if ((cap_fp = fopen(cap_file, "r")) == NULL) { err = errno; be_print_err(gettext("be_do_installgrub: failed to open grub " "capability file\n")); ret = errno_to_be_err(err); goto done; } if ((zpool_cap_fp = fopen(zpool_cap_file, "w")) == NULL) { err = errno; be_print_err(gettext("be_do_installgrub: failed to open new " "grub capability file\n")); ret = errno_to_be_err(err); (void) fclose(cap_fp); goto done; } while (fgets(line, BUFSIZ, cap_fp)) { (void) fputs(line, zpool_cap_fp); } (void) fclose(zpool_cap_fp); (void) fclose(cap_fp); done: if (pool_mounted) { int iret = 0; iret = be_unmount_pool(zhp, ptmp_mntpnt, orig_mntpnt); if (ret == BE_SUCCESS) ret = iret; free(orig_mntpnt); free(ptmp_mntpnt); } ZFS_CLOSE(zhp); if (be_mounted) (void) _be_unmount(bt->obe_name, 0); zpool_close(zphp); free(tmp_mntpt); return (ret); }