From a63c99a2145c99a38d5ff19422b132400428ed9d Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Tue, 7 Jul 2015 17:58:51 +0300 Subject: [PATCH] 6080 libbe should support installboot Reviewed by: Igor Kozhukhov Reviewed by: Alexander Pyhalov Reviewed by: Richard Lowe Approved by: Robert Mustacchi --- usr/src/lib/libbe/Makefile.com | 2 +- usr/src/lib/libbe/common/be_activate.c | 432 +++++++++++++++++++++------------ usr/src/lib/libbe/common/be_utils.c | 35 ++- usr/src/lib/libbe/common/libbe_priv.h | 9 +- 4 files changed, 317 insertions(+), 161 deletions(-) diff --git a/usr/src/lib/libbe/Makefile.com b/usr/src/lib/libbe/Makefile.com index bc04dd8a47..c51e6b50a5 100644 --- a/usr/src/lib/libbe/Makefile.com +++ b/usr/src/lib/libbe/Makefile.com @@ -46,7 +46,7 @@ LIBS= $(DYNLIB) $(LINTLIB) SRCDIR= ../common -INCS += -I$(SRCDIR) +INCS += -I$(SRCDIR) -I$(SRC)/cmd/boot/common C99MODE= $(C99_ENABLE) diff --git a/usr/src/lib/libbe/common/be_activate.c b/usr/src/lib/libbe/common/be_activate.c index da6ed3fb18..985a585094 100644 --- a/usr/src/lib/libbe/common/be_activate.c +++ b/usr/src/lib/libbe/common/be_activate.c @@ -53,10 +53,10 @@ char *mnttab = MNTTAB; */ static int set_bootfs(char *boot_rpool, char *be_root_ds); static int set_canmount(be_node_list_t *, char *); -static boolean_t be_do_installgrub_mbr(char *, nvlist_t *); -static int be_do_installgrub_helper(zpool_handle_t *, nvlist_t *, char *, +static boolean_t be_do_install_mbr(char *, nvlist_t *); +static int be_do_installboot_helper(zpool_handle_t *, nvlist_t *, char *, char *); -static int be_do_installgrub(be_transaction_data_t *); +static int be_do_installboot(be_transaction_data_t *); static int be_get_grub_vers(be_transaction_data_t *, char **, char **); static int get_ver_from_capfile(char *, char **); static int be_promote_zone_ds(char *, char *); @@ -142,7 +142,6 @@ _be_activate(char *be_name) zfs_handle_t *zhp = NULL; char root_ds[MAXPATHLEN]; char active_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; @@ -176,41 +175,14 @@ _be_activate(char *be_name) 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")); + if ((ret = be_do_installboot(&cb)) != BE_SUCCESS) 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"), + "add BE (%s) to the menu\n"), cb.obe_name); goto done; } @@ -619,8 +591,8 @@ be_get_grub_vers(be_transaction_data_t *bt, char **cur_vers, char **new_vers) */ if (!zfs_is_mounted(pool_zhp, &zpool_mntpt)) { be_print_err(gettext("be_get_grub_vers: pool " - "dataset (%s) is not mounted. Can't set the " - "default BE in the grub menu.\n"), bt->obe_zpool); + "dataset (%s) is not mounted. Can't read the " + "grub capability file.\n"), bt->obe_zpool); ret = BE_ERR_NO_MENU; goto cleanup; } @@ -756,14 +728,14 @@ get_ver_from_capfile(char *file, char **vers) } /* - * To be able to boot EFI labeled disks, GRUB stage1 needs to be written + * To be able to boot EFI labeled disks, stage1 needs to be written * into the MBR. We do not do this if we're on disks with a traditional * fdisk partition table only, or if any foreign EFI partitions exist. * In the trivial case of a whole-disk vdev we always write stage1 into * the MBR. */ static boolean_t -be_do_installgrub_mbr(char *diskname, nvlist_t *child) +be_do_install_mbr(char *diskname, nvlist_t *child) { struct uuid allowed_uuids[] = { EFI_UNUSED, @@ -821,18 +793,18 @@ be_do_installgrub_mbr(char *diskname, nvlist_t *child) } static int -be_do_installgrub_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1, +be_do_installboot_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1, char *stage2) { - char installgrub_cmd[MAXPATHLEN]; + char install_cmd[MAXPATHLEN]; char be_run_cmd_errbuf[BUFSIZ]; char diskname[MAXPATHLEN]; char *vname; char *path, *dsk_ptr; - char *m_flag = ""; + char *flag = ""; if (nvlist_lookup_string(child, ZPOOL_CONFIG_PATH, &path) != 0) { - be_print_err(gettext("be_do_installgrub: " + be_print_err(gettext("be_do_installboot: " "failed to get device path\n")); return (BE_ERR_NODEV); } @@ -855,27 +827,33 @@ be_do_installgrub_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1, (void) snprintf(diskname, sizeof (diskname), "%s/r%s", path, dsk_ptr); free(path); - if (be_do_installgrub_mbr(diskname, child)) - m_flag = "-m -f"; - vname = zpool_vdev_name(g_zfs, zphp, child, B_FALSE); if (vname == NULL) { - be_print_err(gettext("be_do_installgrub: " + be_print_err(gettext("be_do_installboot: " "failed to get device name: %s\n"), libzfs_error_description(g_zfs)); return (zfs_err_to_be_err(g_zfs)); } - (void) snprintf(installgrub_cmd, sizeof (installgrub_cmd), - "%s %s %s %s %s", BE_INSTALL_GRUB, m_flag, stage1, stage2, - diskname); - if (be_run_cmd(installgrub_cmd, be_run_cmd_errbuf, BUFSIZ, NULL, 0) + if (be_is_isa("i386")) { + if (be_do_install_mbr(diskname, child)) + flag = "-m -f"; + (void) snprintf(install_cmd, sizeof (install_cmd), + "%s %s %s %s %s", BE_INSTALL_GRUB, flag, + stage1, stage2, diskname); + } else { + flag = "-F zfs"; + (void) snprintf(install_cmd, sizeof (install_cmd), + "%s %s %s %s", BE_INSTALL_BOOT, flag, stage2, diskname); + } + + if (be_run_cmd(install_cmd, be_run_cmd_errbuf, BUFSIZ, NULL, 0) != BE_SUCCESS) { - be_print_err(gettext("be_do_installgrub: installgrub " + be_print_err(gettext("be_do_installboot: install " "failed for device %s.\n"), vname); /* Assume localized cmd err output. */ be_print_err(gettext(" Command: \"%s\"\n"), - installgrub_cmd); + install_cmd); be_print_err("%s", be_run_cmd_errbuf); free(vname); return (BE_ERR_BOOTFILE_INST); @@ -886,10 +864,8 @@ be_do_installgrub_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1, } /* - * 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. + * Function: be_do_copy_grub_cap + * Description: This function will copy grub capability file to BE. * * Parameters: * bt - The transaction data for the BE we're activating. @@ -901,38 +877,232 @@ be_do_installgrub_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1, * Private */ static int -be_do_installgrub(be_transaction_data_t *bt) +be_do_copy_grub_cap(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 cap_file[MAXPATHLEN]; + char zpool_cap_file[MAXPATHLEN]; + char line[BUFSIZ]; + char *tmp_mntpnt = NULL; + char *orig_mntpnt = 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]; + int err = 0; + int ret = BE_SUCCESS; + boolean_t pool_mounted = B_FALSE; + boolean_t be_mounted = B_FALSE; + + /* + * Copy the grub capability file from the BE we're activating + * into the root pool. + */ + zhp = zfs_open(g_zfs, bt->obe_zpool, ZFS_TYPE_FILESYSTEM); + if (zhp == NULL) { + be_print_err(gettext("be_do_installboot: 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_installboot: 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_installboot: 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); + + if ((zhp = zfs_open(g_zfs, bt->obe_root_ds, ZFS_TYPE_FILESYSTEM)) == + NULL) { + be_print_err(gettext("be_do_installboot: 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); + goto done; + } + + if (!zfs_is_mounted(zhp, &tmp_mntpnt)) { + if ((ret = _be_mount(bt->obe_name, &tmp_mntpnt, + BE_MOUNT_FLAG_NO_ZONES)) != BE_SUCCESS) { + be_print_err(gettext("be_do_installboot: failed to " + "mount BE (%s)\n"), bt->obe_name); + ZFS_CLOSE(zhp); + goto done; + } + be_mounted = B_TRUE; + } + ZFS_CLOSE(zhp); + + (void) snprintf(cap_file, sizeof (cap_file), "%s%s", tmp_mntpnt, + BE_CAP_FILE); + free(tmp_mntpnt); + + if ((cap_fp = fopen(cap_file, "r")) == NULL) { + err = errno; + be_print_err(gettext("be_do_installboot: 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_installboot: 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 (be_mounted) + (void) _be_unmount(bt->obe_name, 0); + + 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); + } + return (ret); +} + +/* + * Function: be_is_install_needed + * Description: Check detached version files to detect if bootloader + * install/update is needed. + * + * Parameters: + * bt - The transaction data for the BE we're activating. + * update - set B_TRUE is update is needed. + * Return: + * BE_SUCCESS - Success + * be_errno_t - Failure + * + * Scope: + * Private + */ +static int +be_is_install_needed(be_transaction_data_t *bt, boolean_t *update) +{ + int ret = BE_SUCCESS; + char *cur_vers = NULL, *new_vers = NULL; + + assert(bt != NULL); + assert(update != NULL); + + if (!be_has_grub()) { + /* + * no detached versioning, let installboot to manage + * versioning. + */ + *update = B_TRUE; + return (ret); + } + + *update = B_FALSE; /* set default */ + + /* + * We need to check to see if the version number from + * the BE being activated is greater than the current + * one. + */ + ret = be_get_grub_vers(bt, &cur_vers, &new_vers); + if (ret != BE_SUCCESS) { + be_print_err(gettext("be_activate: failed to get grub " + "versions from capability files.\n")); + return (ret); + } + /* update if we have both versions and can compare */ + if (cur_vers != NULL) { + if (new_vers != NULL) { + if (atof(cur_vers) < atof(new_vers)) + *update = B_TRUE; + free(new_vers); + } + free(cur_vers); + } else if (new_vers != NULL) { + /* we only got new version - update */ + *update = B_TRUE; + free(new_vers); + } + return (ret); +} + +/* + * Function: be_do_installboot + * Description: This function runs installgrub/installboot using the boot + * 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_installboot(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 stage1[MAXPATHLEN]; char stage2[MAXPATHLEN]; char *vname; int ret = BE_SUCCESS; - int err = 0; boolean_t be_mounted = B_FALSE; - boolean_t pool_mounted = B_FALSE; + boolean_t update = B_FALSE; - if (!be_has_grub()) { - be_print_err(gettext("be_do_installgrub: Not supported " - "on this architecture\n")); - return (BE_ERR_NOTSUP); - } + /* + * check versions. This call is to support detached + * version implementation like grub. Embedded versioning is + * checked by actual installer. + */ + ret = be_is_install_needed(bt, &update); + if (ret != BE_SUCCESS || update == B_FALSE) + return (ret); if ((zhp = zfs_open(g_zfs, bt->obe_root_ds, ZFS_TYPE_FILESYSTEM)) == NULL) { - be_print_err(gettext("be_do_installgrub: failed to " + be_print_err(gettext("be_do_installboot: 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); @@ -941,7 +1111,7 @@ be_do_installgrub(be_transaction_data_t *bt) 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 " + be_print_err(gettext("be_do_installboot: failed to " "mount BE (%s)\n"), bt->obe_name); ZFS_CLOSE(zhp); return (ret); @@ -950,11 +1120,31 @@ be_do_installgrub(be_transaction_data_t *bt) } 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 (be_has_grub()) { + (void) snprintf(stage1, sizeof (stage1), "%s%s", + tmp_mntpt, BE_GRUB_STAGE_1); + (void) snprintf(stage2, sizeof (stage2), "%s%s", + tmp_mntpt, BE_GRUB_STAGE_2); + } else { + char *platform = be_get_platform(); + + if (platform == NULL) { + be_print_err(gettext("be_do_installboot: failed to " + "detect system platform name\n")); + if (be_mounted) + (void) _be_unmount(bt->obe_name, 0); + free(tmp_mntpt); + return (BE_ERR_BOOTFILE_INST); + } + + stage1[0] = '\0'; /* sparc has no stage1 */ + (void) snprintf(stage2, sizeof (stage2), + "%s/usr/platform/%s%s", tmp_mntpt, + platform, BE_SPARC_BOOTBLK); + } if ((zphp = zpool_open(g_zfs, bt->obe_zpool)) == NULL) { - be_print_err(gettext("be_do_installgrub: failed to open " + be_print_err(gettext("be_do_installboot: failed to open " "pool (%s): %s\n"), bt->obe_zpool, libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); @@ -965,7 +1155,7 @@ be_do_installgrub(be_transaction_data_t *bt) } if ((config = zpool_get_config(zphp, NULL)) == NULL) { - be_print_err(gettext("be_do_installgrub: failed to get zpool " + be_print_err(gettext("be_do_installboot: failed to get zpool " "configuration information. %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); @@ -976,7 +1166,7 @@ be_do_installgrub(be_transaction_data_t *bt) * 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 " + be_print_err(gettext("be_do_installboot: failed to get vdev " "tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; @@ -984,7 +1174,7 @@ be_do_installgrub(be_transaction_data_t *bt) if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, &child, &children) != 0) { - be_print_err(gettext("be_do_installgrub: failed to traverse " + be_print_err(gettext("be_do_installboot: failed to traverse " "the vdev tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); goto done; @@ -995,7 +1185,7 @@ be_do_installgrub(be_transaction_data_t *bt) vname = zpool_vdev_name(g_zfs, zphp, child[c], B_FALSE); if (vname == NULL) { be_print_err(gettext( - "be_do_installgrub: " + "be_do_installboot: " "failed to get device name: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); @@ -1006,7 +1196,7 @@ be_do_installgrub(be_transaction_data_t *bt) if (nvlist_lookup_nvlist_array(child[c], ZPOOL_CONFIG_CHILDREN, &nvchild, &nchildren) != 0) { - be_print_err(gettext("be_do_installgrub: " + be_print_err(gettext("be_do_installboot: " "failed to traverse the vdev tree: %s\n"), libzfs_error_description(g_zfs)); ret = zfs_err_to_be_err(g_zfs); @@ -1014,7 +1204,7 @@ be_do_installgrub(be_transaction_data_t *bt) } for (i = 0; i < nchildren; i++) { - ret = be_do_installgrub_helper(zphp, nvchild[i], + ret = be_do_installboot_helper(zphp, nvchild[i], stage1, stage2); if (ret != BE_SUCCESS) goto done; @@ -1022,90 +1212,18 @@ be_do_installgrub(be_transaction_data_t *bt) } else { free(vname); - ret = be_do_installgrub_helper(zphp, child[c], stage1, + ret = be_do_installboot_helper(zphp, child[c], stage1, stage2); if (ret != BE_SUCCESS) goto done; } } - /* - * 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)); + if (be_has_grub()) { + ret = be_do_copy_grub_cap(bt); } - /* - * 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); diff --git a/usr/src/lib/libbe/common/be_utils.c b/usr/src/lib/libbe/common/be_utils.c index 681e72366d..4841302db3 100644 --- a/usr/src/lib/libbe/common/be_utils.c +++ b/usr/src/lib/libbe/common/be_utils.c @@ -25,6 +25,7 @@ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Toomas Soome */ @@ -57,6 +58,7 @@ #include #include +#include /* Private function prototypes */ static int update_dataset(char *, int, char *, char *, char *); @@ -2976,6 +2978,33 @@ be_get_default_isa(void) } /* + * Function: be_get_platform + * Description: + * Returns the platfom name + * Parameters: + * none + * Returns: + * NULL - the platform name returned by sysinfo() was too + * long for local variables + * char * - pointer to a string containing the platform name + * Scope: + * Semi-private (library wide use only) + */ +char * +be_get_platform(void) +{ + int i; + static char default_inst[ARCH_LENGTH] = ""; + + if (default_inst[0] == '\0') { + i = sysinfo(SI_PLATFORM, default_inst, ARCH_LENGTH); + if (i < 0 || i > ARCH_LENGTH) + return (NULL); + } + return (default_inst); +} + +/* * Function: be_run_cmd * Description: * Runs a command in a separate subprocess. Splits out stdout from stderr @@ -3087,7 +3116,11 @@ be_run_cmd(char *command, char *stderr_buf, int stderr_bufsize, rval = BE_ERR_EXTCMD; } else if (WIFEXITED(exit_status)) { exit_status = (int)((char)WEXITSTATUS(exit_status)); - if (exit_status != 0) { + /* + * error code BC_NOUPDT means more recent version + * is installed + */ + if (exit_status != BC_SUCCESS && exit_status != BC_NOUPDT) { (void) snprintf(oneline, BUFSIZ, gettext("be_run_cmd: " "command terminated with error status: %d\n"), exit_status); diff --git a/usr/src/lib/libbe/common/libbe_priv.h b/usr/src/lib/libbe/common/libbe_priv.h index 1453e5ee3e..cd5658f6d6 100644 --- a/usr/src/lib/libbe/common/libbe_priv.h +++ b/usr/src/lib/libbe/common/libbe_priv.h @@ -25,6 +25,7 @@ /* * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2015 Toomas Soome */ #ifndef _LIBBE_PRIV_H @@ -59,8 +60,11 @@ extern "C" { #define BE_WHITE_SPACE " \t\r\n" #define BE_CAP_FILE "/boot/grub/capability" #define BE_INSTALL_GRUB "/sbin/installgrub" -#define BE_STAGE_1 "/boot/grub/stage1" -#define BE_STAGE_2 "/boot/grub/stage2" +#define BE_GRUB_STAGE_1 "/boot/grub/stage1" +#define BE_GRUB_STAGE_2 "/boot/grub/stage2" +#define BE_INSTALL_BOOT "/usr/sbin/installboot" +#define BE_SPARC_BOOTBLK "/lib/fs/zfs/bootblk" + #define ZFS_CLOSE(_zhp) \ if (_zhp) { \ zfs_close(_zhp); \ @@ -210,6 +214,7 @@ boolean_t be_zone_compare_uuids(char *); /* check architecture functions */ char *be_get_default_isa(void); +char *be_get_platform(void); boolean_t be_is_isa(char *); boolean_t be_has_grub(void); -- 2.11.4.GIT