summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbe
diff options
context:
space:
mode:
authorToomas Soome <tsoome@me.com>2015-07-07 17:58:51 +0300
committerRobert Mustacchi <rm@joyent.com>2015-08-23 09:04:35 -0700
commita63c99a2145c99a38d5ff19422b132400428ed9d (patch)
tree589aec0039eba59c107a36ab9250975ed118a45c /usr/src/lib/libbe
parent359db861fd14071f8a25831efe3bf3790980d071 (diff)
downloadillumos-joyent-a63c99a2145c99a38d5ff19422b132400428ed9d.tar.gz
6080 libbe should support installboot
Reviewed by: Igor Kozhukhov <ikozhukhov@gmail.com> Reviewed by: Alexander Pyhalov <apyhalov@gmail.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src/lib/libbe')
-rw-r--r--usr/src/lib/libbe/Makefile.com2
-rw-r--r--usr/src/lib/libbe/common/be_activate.c432
-rw-r--r--usr/src/lib/libbe/common/be_utils.c35
-rw-r--r--usr/src/lib/libbe/common/libbe_priv.h9
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 <tsoome@me.com>
*/
@@ -57,6 +58,7 @@
#include <libbe.h>
#include <libbe_priv.h>
+#include <boot_utils.h>
/* 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 <tsoome@me.com>
*/
#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);