summaryrefslogtreecommitdiff
path: root/usr/src/lib/libbe
diff options
context:
space:
mode:
authorPatrick Mooney <patrick.f.mooney@gmail.com>2015-09-17 14:42:49 +0000
committerPatrick Mooney <patrick.f.mooney@gmail.com>2015-09-17 15:15:49 +0000
commit634d34a4560c78755739f904248f3adb463c2adf (patch)
tree193142bbab669e57a5ee90c12e63b85b1219e331 /usr/src/lib/libbe
parentdf3b36f3d97df979fb68b68560b333c9714fac70 (diff)
parent03bad06fbb261fd4a7151a70dfeff2f5041cce1f (diff)
downloadillumos-joyent-634d34a4560c78755739f904248f3adb463c2adf.tar.gz
[illumos-gate merge]
commit 03bad06fbb261fd4a7151a70dfeff2f5041cce1f 6171 dsl_prop_unregister() slows down dataset eviction. commit a725189c0accbf47b39f735d1f32a7b54ae91c6d 5433 at(1) doesn't properly handle being invoked from a path containing spaces commit caf590b518921f14033a11d17fafa827bb2caa4b 6216 prtdiag could display hardware in slots commit c7c0ceafd167e558cd8cb8195b8bd63cbc817b27 6085 export libbe installboot function 6086 add install bootblock option for bootadm commit be32284091554a41d4706e6653adeec1d9127a87 4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R (fix studio build) commit 45818ee124adeaaf947698996b4f4c722afc6d1f 4185 add new cryptographic checksums to ZFS: SHA-512, Skein, Edon-R Conflicts: usr/src/cmd/prtdiag/i386/smbios.c usr/src/uts/common/Makefile.rules usr/src/uts/common/sys/Makefile
Diffstat (limited to 'usr/src/lib/libbe')
-rw-r--r--usr/src/lib/libbe/common/be_activate.c153
-rw-r--r--usr/src/lib/libbe/common/libbe.h13
-rw-r--r--usr/src/lib/libbe/common/mapfile-vers1
3 files changed, 146 insertions, 21 deletions
diff --git a/usr/src/lib/libbe/common/be_activate.c b/usr/src/lib/libbe/common/be_activate.c
index 985a585094..6eda8eebba 100644
--- a/usr/src/lib/libbe/common/be_activate.c
+++ b/usr/src/lib/libbe/common/be_activate.c
@@ -55,8 +55,8 @@ 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_install_mbr(char *, nvlist_t *);
static int be_do_installboot_helper(zpool_handle_t *, nvlist_t *, char *,
- char *);
-static int be_do_installboot(be_transaction_data_t *);
+ char *, uint16_t);
+static int be_do_installboot(be_transaction_data_t *, uint16_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 *);
@@ -119,6 +119,82 @@ be_activate(nvlist_t *be_attrs)
return (ret);
}
+/*
+ * Function: be_installboot
+ * Description: Calls be_do_installboot to install/update bootloader on
+ * pool passed in through be_attrs. The primary consumer is
+ * bootadm command to avoid duplication of the code.
+ * Parameters:
+ * be_attrs - pointer to nvlist_t of attributes being passed in.
+ * The following attribute values are used:
+ *
+ * BE_ATTR_ORIG_BE_NAME *required
+ * BE_ATTR_ORIG_BE_POOL *required
+ * BE_ATTR_ORIG_BE_ROOT *required
+ * BE_ATTR_INSTALL_FLAGS optional
+ *
+ * Return:
+ * BE_SUCCESS - Success
+ * be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+int
+be_installboot(nvlist_t *be_attrs)
+{
+ int ret = BE_SUCCESS;
+ uint16_t flags = 0;
+ uint16_t verbose;
+ be_transaction_data_t bt = { 0 };
+
+ /* Get flags */
+ if (nvlist_lookup_pairs(be_attrs, NV_FLAG_NOENTOK,
+ BE_ATTR_INSTALL_FLAGS, DATA_TYPE_UINT16, &flags, NULL) != 0) {
+ be_print_err(gettext("be_installboot: failed to lookup "
+ "BE_ATTR_INSTALL_FLAGS attribute\n"));
+ return (BE_ERR_INVAL);
+ }
+
+ /* Set verbose early, so we get all messages */
+ verbose = flags & BE_INSTALLBOOT_FLAG_VERBOSE;
+ if (verbose == BE_INSTALLBOOT_FLAG_VERBOSE)
+ libbe_print_errors(B_TRUE);
+
+ ret = nvlist_lookup_string(be_attrs, BE_ATTR_ORIG_BE_NAME,
+ &bt.obe_name);
+ if (ret != 0) {
+ be_print_err(gettext("be_installboot: failed to "
+ "lookup BE_ATTR_ORIG_BE_NAME attribute\n"));
+ return (BE_ERR_INVAL);
+ }
+
+ ret = nvlist_lookup_string(be_attrs, BE_ATTR_ORIG_BE_POOL,
+ &bt.obe_zpool);
+ if (ret != 0) {
+ be_print_err(gettext("be_installboot: failed to "
+ "lookup BE_ATTR_ORIG_BE_POOL attribute\n"));
+ return (BE_ERR_INVAL);
+ }
+
+ ret = nvlist_lookup_string(be_attrs, BE_ATTR_ORIG_BE_ROOT,
+ &bt.obe_root_ds);
+ if (ret != 0) {
+ be_print_err(gettext("be_installboot: failed to "
+ "lookup BE_ATTR_ORIG_BE_ROOT attribute\n"));
+ return (BE_ERR_INVAL);
+ }
+
+ /* Initialize libzfs handle */
+ if (!be_zfs_init())
+ return (BE_ERR_INIT);
+
+ ret = be_do_installboot(&bt, flags);
+
+ be_zfs_fini();
+
+ return (ret);
+}
+
/* ******************************************************************** */
/* Semi Private Functions */
/* ******************************************************************** */
@@ -175,7 +251,8 @@ _be_activate(char *be_name)
cb.obe_root_ds = strdup(root_ds);
if (getzoneid() == GLOBAL_ZONEID) {
- if ((ret = be_do_installboot(&cb)) != BE_SUCCESS)
+ ret = be_do_installboot(&cb, BE_INSTALLBOOT_FLAG_NULL);
+ if (ret != BE_SUCCESS)
return (ret);
if (!be_has_menu_entry(root_ds, cb.obe_zpool, &entry)) {
@@ -794,14 +871,16 @@ be_do_install_mbr(char *diskname, nvlist_t *child)
static int
be_do_installboot_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1,
- char *stage2)
+ char *stage2, uint16_t flags)
{
char install_cmd[MAXPATHLEN];
char be_run_cmd_errbuf[BUFSIZ];
+ char be_run_cmd_outbuf[BUFSIZ];
char diskname[MAXPATHLEN];
char *vname;
char *path, *dsk_ptr;
char *flag = "";
+ int ret;
if (nvlist_lookup_string(child, ZPOOL_CONFIG_PATH, &path) != 0) {
be_print_err(gettext("be_do_installboot: "
@@ -836,31 +915,60 @@ be_do_installboot_helper(zpool_handle_t *zphp, nvlist_t *child, char *stage1,
}
if (be_is_isa("i386")) {
- if (be_do_install_mbr(diskname, child))
- flag = "-m -f";
+ uint16_t force = flags & BE_INSTALLBOOT_FLAG_FORCE;
+ uint16_t mbr = flags & BE_INSTALLBOOT_FLAG_MBR;
+
+ if (force == BE_INSTALLBOOT_FLAG_FORCE) {
+ if (mbr == BE_INSTALLBOOT_FLAG_MBR ||
+ be_do_install_mbr(diskname, child))
+ flag = "-F -m -f";
+ else
+ flag = "-F";
+ } else {
+ if (mbr == BE_INSTALLBOOT_FLAG_MBR ||
+ 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";
+ if ((flags & BE_INSTALLBOOT_FLAG_FORCE) ==
+ BE_INSTALLBOOT_FLAG_FORCE)
+ flag = "-f -F zfs";
+ 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_run_cmd_outbuf = '\0';
+ *be_run_cmd_errbuf = '\0';
+
+ ret = be_run_cmd(install_cmd, be_run_cmd_errbuf, BUFSIZ,
+ be_run_cmd_outbuf, BUFSIZ);
+
+ if (ret != BE_SUCCESS) {
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"),
- install_cmd);
+ ret = BE_ERR_BOOTFILE_INST;
+ }
+
+ be_print_err(gettext(" Command: \"%s\"\n"), install_cmd);
+ if (be_run_cmd_outbuf[0] != 0) {
+ be_print_err(gettext(" Output:\n"));
+ be_print_err("%s", be_run_cmd_outbuf);
+ }
+
+ if (be_run_cmd_errbuf[0] != 0) {
+ be_print_err(gettext(" Errors:\n"));
be_print_err("%s", be_run_cmd_errbuf);
- free(vname);
- return (BE_ERR_BOOTFILE_INST);
}
free(vname);
- return (BE_SUCCESS);
+ return (ret);
}
/*
@@ -1069,6 +1177,7 @@ be_is_install_needed(be_transaction_data_t *bt, boolean_t *update)
*
* Parameters:
* bt - The transaction data for the BE we're activating.
+ * flags - flags for bootloader install
* Return:
* BE_SUCCESS - Success
* be_errno_t - Failure
@@ -1077,7 +1186,7 @@ be_is_install_needed(be_transaction_data_t *bt, boolean_t *update)
* Private
*/
static int
-be_do_installboot(be_transaction_data_t *bt)
+be_do_installboot(be_transaction_data_t *bt, uint16_t flags)
{
zpool_handle_t *zphp = NULL;
zfs_handle_t *zhp = NULL;
@@ -1096,9 +1205,11 @@ be_do_installboot(be_transaction_data_t *bt)
* 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 ((flags & BE_INSTALLBOOT_FLAG_FORCE) != BE_INSTALLBOOT_FLAG_FORCE) {
+ 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) {
@@ -1205,7 +1316,7 @@ be_do_installboot(be_transaction_data_t *bt)
for (i = 0; i < nchildren; i++) {
ret = be_do_installboot_helper(zphp, nvchild[i],
- stage1, stage2);
+ stage1, stage2, flags);
if (ret != BE_SUCCESS)
goto done;
}
@@ -1213,7 +1324,7 @@ be_do_installboot(be_transaction_data_t *bt)
free(vname);
ret = be_do_installboot_helper(zphp, child[c], stage1,
- stage2);
+ stage2, flags);
if (ret != BE_SUCCESS)
goto done;
}
diff --git a/usr/src/lib/libbe/common/libbe.h b/usr/src/lib/libbe/common/libbe.h
index c5662893a2..994bc881ac 100644
--- a/usr/src/lib/libbe/common/libbe.h
+++ b/usr/src/lib/libbe/common/libbe.h
@@ -42,6 +42,7 @@ extern "C" {
#define BE_ATTR_ORIG_BE_NAME "orig_be_name"
#define BE_ATTR_ORIG_BE_POOL "orig_be_pool"
+#define BE_ATTR_ORIG_BE_ROOT "orig_be_root"
#define BE_ATTR_SNAP_NAME "snap_name"
#define BE_ATTR_NEW_BE_NAME "new_be_name"
@@ -59,6 +60,7 @@ extern "C" {
#define BE_ATTR_MOUNT_FLAGS "mount_flags"
#define BE_ATTR_UNMOUNT_FLAGS "unmount_flags"
#define BE_ATTR_DESTROY_FLAGS "destroy_flags"
+#define BE_ATTR_INSTALL_FLAGS "install_flags"
#define BE_ATTR_ROOT_DS "root_ds"
#define BE_ATTR_UUID_STR "uuid_str"
@@ -205,6 +207,12 @@ typedef struct be_node_list {
#define BE_DESTROY_FLAG_SNAPSHOTS 0x00000001
#define BE_DESTROY_FLAG_FORCE_UNMOUNT 0x00000002
+/* Flags for installboot */
+#define BE_INSTALLBOOT_FLAG_NULL 0x00000000
+#define BE_INSTALLBOOT_FLAG_MBR 0x00000001
+#define BE_INSTALLBOOT_FLAG_FORCE 0x00000002
+#define BE_INSTALLBOOT_FLAG_VERBOSE 0x00000004
+
/* sort rules for be_sort() */
typedef enum {
BE_SORT_UNSPECIFIED = -1,
@@ -244,6 +252,11 @@ char *be_err_to_str(int);
int be_sort(be_node_list_t **, int);
/*
+ * Installboot support
+ */
+int be_installboot(nvlist_t *);
+
+/*
* Library functions
*/
void libbe_print_errors(boolean_t);
diff --git a/usr/src/lib/libbe/common/mapfile-vers b/usr/src/lib/libbe/common/mapfile-vers
index 0e57583dab..0602bd7de3 100644
--- a/usr/src/lib/libbe/common/mapfile-vers
+++ b/usr/src/lib/libbe/common/mapfile-vers
@@ -49,6 +49,7 @@ SYMBOL_VERSION SUNWprivate_1.1 {
be_err_to_str;
be_free_list;
be_init;
+ be_installboot;
be_list;
be_mount;
be_rename;