--- a/usr/src/lib/libbe/common/be_create.c Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/lib/libbe/common/be_create.c Wed Apr 06 07:45:22 2011 -0700
@@ -24,6 +24,10 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
* System includes
*/
@@ -576,17 +580,20 @@
be_transaction_data_t bt = { 0 };
be_fs_list_data_t fld = { 0 };
zfs_handle_t *zhp = NULL;
+ zpool_handle_t *zphp = NULL;
nvlist_t *zfs_props = NULL;
uuid_t uu = { 0 };
char obe_root_ds[MAXPATHLEN];
char nbe_root_ds[MAXPATHLEN];
char ss[MAXPATHLEN];
char *new_mp = NULL;
+ char *obe_name = NULL;
boolean_t autoname = B_FALSE;
boolean_t be_created = B_FALSE;
int i;
int zret;
int ret = BE_SUCCESS;
+ struct be_defaults be_defaults;
/* Initialize libzfs handle */
if (!be_zfs_init())
@@ -594,18 +601,21 @@
/* Get original BE name */
if (nvlist_lookup_pairs(be_attrs, NV_FLAG_NOENTOK,
- BE_ATTR_ORIG_BE_NAME, DATA_TYPE_STRING, &bt.obe_name, NULL) != 0) {
+ BE_ATTR_ORIG_BE_NAME, DATA_TYPE_STRING, &obe_name, NULL) != 0) {
be_print_err(gettext("be_copy: failed to lookup "
"BE_ATTR_ORIG_BE_NAME attribute\n"));
return (BE_ERR_INVAL);
}
+ if ((ret = be_find_current_be(&bt)) != BE_SUCCESS) {
+ return (ret);
+ }
+
+ be_get_defaults(&be_defaults);
+
/* If original BE name not provided, use current BE */
- if (bt.obe_name == NULL) {
- if ((ret = be_find_current_be(&bt)) != BE_SUCCESS) {
- return (ret);
- }
- } else {
+ if (obe_name != NULL) {
+ bt.obe_name = obe_name;
/* Validate original BE name */
if (!be_valid_be_name(bt.obe_name)) {
be_print_err(gettext("be_copy: "
@@ -614,16 +624,29 @@
}
}
- /* Find which zpool obe_name lives in */
- if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &bt)) == 0) {
- be_print_err(gettext("be_copy: failed to "
- "find zpool for BE (%s)\n"), bt.obe_name);
- return (BE_ERR_BE_NOENT);
- } else if (zret < 0) {
- be_print_err(gettext("be_copy: "
- "zpool_iter failed: %s\n"),
- libzfs_error_description(g_zfs));
- return (zfs_err_to_be_err(g_zfs));
+ if (be_defaults.be_deflt_rpool_container) {
+ if ((zphp = zpool_open(g_zfs, bt.obe_zpool)) == NULL) {
+ be_print_err(gettext("be_get_node_data: failed to "
+ "open rpool (%s): %s\n"), bt.obe_zpool,
+ libzfs_error_description(g_zfs));
+ return (zfs_err_to_be_err(g_zfs));
+ }
+ if (be_find_zpool_callback(zphp, &bt) == 0) {
+ return (BE_ERR_BE_NOENT);
+ }
+ } else {
+ /* Find which zpool obe_name lives in */
+ if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &bt)) ==
+ 0) {
+ be_print_err(gettext("be_copy: failed to "
+ "find zpool for BE (%s)\n"), bt.obe_name);
+ return (BE_ERR_BE_NOENT);
+ } else if (zret < 0) {
+ be_print_err(gettext("be_copy: "
+ "zpool_iter failed: %s\n"),
+ libzfs_error_description(g_zfs));
+ return (zfs_err_to_be_err(g_zfs));
+ }
}
/* Get snapshot name of original BE if one was provided */
@@ -1414,7 +1437,8 @@
if (be_destroy_callback(zhp, dd) != 0) {
be_print_err(gettext("be_destroy: failed to "
"destroy BE %s\n"), root_ds);
- return (BE_ERR_DESTROY);
+ ret = zfs_err_to_be_err(g_zfs);
+ return (ret);
}
/* If BE has an origin */
--- a/usr/src/lib/libbe/common/be_list.c Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/lib/libbe/common/be_list.c Wed Apr 06 07:45:22 2011 -0700
@@ -23,6 +23,10 @@
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
*/
+/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
#include <assert.h>
#include <libintl.h>
#include <libnvpair.h>
@@ -153,10 +157,15 @@
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
@@ -167,6 +176,7 @@
} else {
(void) strncpy(cb.current_be, bt.obe_name,
sizeof (cb.current_be));
+ rpool = bt.obe_zpool;
}
/*
@@ -176,13 +186,25 @@
if (be_name != NULL)
cb.be_name = strdup(be_name);
- 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;
+ if (be_defaults.be_deflt_rpool_container && rpool != NULL) {
+ if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
+ be_print_err(gettext("be_get_node_data: 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_ERR_BE_NOENT;
+
+ 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) {
@@ -367,6 +389,8 @@
* the information for the specified BE.
*/
if (cb->be_name != NULL) {
+ if (!be_valid_be_name(cb->be_name))
+ return (BE_ERR_INVAL);
/*
* Generate string for the BE root dataset
*/
@@ -398,16 +422,6 @@
return (ret);
}
- if (cb->be_nodes_head == NULL) {
- if ((cb->be_nodes_head = be_list_alloc(&ret,
- sizeof (be_node_list_t))) == NULL) {
- ZFS_CLOSE(zhp);
- zpool_close(zlp);
- return (ret);
- }
- cb->be_nodes = cb->be_nodes_head;
- }
-
/*
* If a BE name was specified we iterate through the datasets
* and snapshots for this BE only. Otherwise we will iterate
@@ -415,6 +429,16 @@
* within the pool
*/
if (cb->be_name != NULL) {
+ if (cb->be_nodes_head == NULL) {
+ if ((cb->be_nodes_head = be_list_alloc(&ret,
+ sizeof (be_node_list_t))) == NULL) {
+ ZFS_CLOSE(zhp);
+ zpool_close(zlp);
+ return (ret);
+ }
+ cb->be_nodes = cb->be_nodes_head;
+ }
+
if ((ret = be_get_node_data(zhp, cb->be_nodes, cb->be_name,
rpool, cb->current_be, be_ds)) != BE_SUCCESS) {
ZFS_CLOSE(zhp);
@@ -454,6 +478,9 @@
list_callback_data_t *cb = (list_callback_data_t *)data;
char *str = NULL, *ds_path = NULL;
int ret = 0;
+ struct be_defaults be_defaults;
+
+ be_get_defaults(&be_defaults);
ds_path = str = strdup(zfs_get_name(zhp));
@@ -461,6 +488,21 @@
* get past the end of the container dataset plus the trailing "/"
*/
str = str + (strlen(be_container_ds) + 1);
+ if (be_defaults.be_deflt_bename_starts_with != '\0') {
+ /* just skip if invalid */
+ if (!be_valid_be_name(str))
+ return (BE_SUCCESS);
+ }
+
+ if (cb->be_nodes_head == NULL) {
+ if ((cb->be_nodes_head = be_list_alloc(&ret,
+ sizeof (be_node_list_t))) == NULL) {
+ ZFS_CLOSE(zhp);
+ return (ret);
+ }
+ cb->be_nodes = cb->be_nodes_head;
+ }
+
if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && !zone_be) {
be_snapshot_list_t *snapshots = NULL;
if (cb->be_nodes->be_node_snapshots == NULL) {
--- a/usr/src/lib/libbe/common/be_snapshot.c Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/lib/libbe/common/be_snapshot.c Wed Apr 06 07:45:22 2011 -0700
@@ -24,6 +24,10 @@
*/
/*
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
* System includes
*/
#include <assert.h>
@@ -248,27 +252,33 @@
{
be_transaction_data_t bt = { 0 };
zfs_handle_t *zhp = NULL;
+ zpool_handle_t *zphp;
char obe_root_ds[MAXPATHLEN];
+ char *obe_name = NULL;
int zret = 0, ret = BE_SUCCESS;
+ struct be_defaults be_defaults;
/* Initialize libzfs handle */
if (!be_zfs_init())
return (BE_ERR_INIT);
+ if ((ret = be_find_current_be(&bt)) != BE_SUCCESS) {
+ return (ret);
+ }
+
/* Get original BE name if one was provided */
if (nvlist_lookup_pairs(be_attrs, NV_FLAG_NOENTOK,
- BE_ATTR_ORIG_BE_NAME, DATA_TYPE_STRING, &bt.obe_name, NULL) != 0) {
+ BE_ATTR_ORIG_BE_NAME, DATA_TYPE_STRING, &obe_name, NULL) != 0) {
be_print_err(gettext("be_rollback: "
"failed to lookup BE_ATTR_ORIG_BE_NAME attribute\n"));
return (BE_ERR_INVAL);
}
+ be_get_defaults(&be_defaults);
+
/* If original BE name not provided, use current BE */
- if (bt.obe_name == NULL) {
- if ((ret = be_find_current_be(&bt)) != BE_SUCCESS) {
- return (ret);
- }
- } else {
+ if (obe_name != NULL) {
+ bt.obe_name = obe_name;
/* Validate original BE name */
if (!be_valid_be_name(bt.obe_name)) {
be_print_err(gettext("be_rollback: "
@@ -285,16 +295,27 @@
return (BE_ERR_INVAL);
}
- /* Find which zpool obe_name lives in */
- if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &bt)) == 0) {
- be_print_err(gettext("be_rollback: "
- "failed to find zpool for BE (%s)\n"), bt.obe_name);
- return (BE_ERR_BE_NOENT);
- } else if (zret < 0) {
- be_print_err(gettext("be_rollback: "
- "zpool_iter failed: %s\n"),
- libzfs_error_description(g_zfs));
- return (zfs_err_to_be_err(g_zfs));
+ if (be_defaults.be_deflt_rpool_container) {
+ if ((zphp = zpool_open(g_zfs, bt.obe_zpool)) == NULL) {
+ be_print_err(gettext("be_rollback: failed to "
+ "open rpool (%s): %s\n"), bt.obe_zpool,
+ libzfs_error_description(g_zfs));
+ return (zfs_err_to_be_err(g_zfs));
+ }
+ zret = be_find_zpool_callback(zphp, &bt);
+ } else {
+ /* Find which zpool obe_name lives in */
+ if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &bt)) ==
+ 0) {
+ be_print_err(gettext("be_rollback: "
+ "failed to find zpool for BE (%s)\n"), bt.obe_name);
+ return (BE_ERR_BE_NOENT);
+ } else if (zret < 0) {
+ be_print_err(gettext("be_rollback: "
+ "zpool_iter failed: %s\n"),
+ libzfs_error_description(g_zfs));
+ return (zfs_err_to_be_err(g_zfs));
+ }
}
/* Generate string for BE's root dataset */
--- a/usr/src/lib/libbe/common/be_utils.c Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/lib/libbe/common/be_utils.c Wed Apr 06 07:45:22 2011 -0700
@@ -50,6 +50,7 @@
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
+#include <deflt.h>
#include <wait.h>
#include <libdevinfo.h>
@@ -59,8 +60,8 @@
/* Private function prototypes */
static int update_dataset(char *, int, char *, char *, char *);
static int _update_vfstab(char *, char *, char *, char *, be_fs_list_data_t *);
-static int be_open_menu(char *, char *, char *, FILE **, char *, boolean_t);
-static int be_create_menu(char *, char *, char *, FILE **, char *);
+static int be_open_menu(char *, char *, FILE **, char *, boolean_t);
+static int be_create_menu(char *, char *, FILE **, char *);
static char *be_get_auto_name(char *, char *, boolean_t);
/*
@@ -181,6 +182,35 @@
}
/*
+ * Function: be_get_defaults
+ * Description: Open defaults and gets be default paramets
+ * Parameters:
+ * defaults - be defaults struct
+ * Returns:
+ * None
+ * Scope:
+ * Semi-private (library wide use only)
+ */
+void
+be_get_defaults(struct be_defaults *defaults)
+{
+ void *defp;
+
+ defaults->be_deflt_rpool_container = B_FALSE;
+ defaults->be_deflt_bename_starts_with[0] = '\0';
+
+ if ((defp = defopen_r(BE_DEFAULTS)) != NULL) {
+ const char *res = defread_r(BE_DFLT_BENAME_STARTS, defp);
+ if (res != NULL && res[0] != NULL) {
+ (void) strlcpy(defaults->be_deflt_bename_starts_with,
+ res, ZFS_MAXNAMELEN);
+ defaults->be_deflt_rpool_container = B_TRUE;
+ }
+ defclose_r(defp);
+ }
+}
+
+/*
* Function: be_make_root_ds
* Description: Generate string for BE's root dataset given the pool
* it lives in and the BE name.
@@ -198,8 +228,15 @@
be_make_root_ds(const char *zpool, const char *be_name, char *be_root_ds,
int be_root_ds_size)
{
- (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s/%s", zpool,
- BE_CONTAINER_DS_NAME, be_name);
+ struct be_defaults be_defaults;
+ be_get_defaults(&be_defaults);
+
+ if (be_defaults.be_deflt_rpool_container)
+ (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s", zpool,
+ be_name);
+ else
+ (void) snprintf(be_root_ds, be_root_ds_size, "%s/%s/%s", zpool,
+ BE_CONTAINER_DS_NAME, be_name);
}
/*
@@ -219,8 +256,14 @@
be_make_container_ds(const char *zpool, char *container_ds,
int container_ds_size)
{
- (void) snprintf(container_ds, container_ds_size, "%s/%s", zpool,
- BE_CONTAINER_DS_NAME);
+ struct be_defaults be_defaults;
+ be_get_defaults(&be_defaults);
+
+ if (be_defaults.be_deflt_rpool_container)
+ (void) snprintf(container_ds, container_ds_size, "%s", zpool);
+ else
+ (void) snprintf(container_ds, container_ds_size, "%s/%s", zpool,
+ BE_CONTAINER_DS_NAME);
}
/*
@@ -244,31 +287,41 @@
char ds[ZFS_MAXNAMELEN];
char *tok = NULL;
char *name = NULL;
+ struct be_defaults be_defaults;
+ int rlen = strlen(rc_loc);
+
+ be_get_defaults(&be_defaults);
/*
* First token is the location of where the root container dataset
* lives; it must match rc_loc.
*/
- if (strncmp(dataset, rc_loc, strlen(rc_loc)) == 0 &&
- dataset[strlen(rc_loc)] == '/') {
- (void) strlcpy(ds, dataset + strlen(rc_loc) + 1, sizeof (ds));
- } else {
+ if (strncmp(dataset, rc_loc, rlen) == 0 && dataset[rlen] == '/')
+ (void) strlcpy(ds, dataset + rlen + 1, sizeof (ds));
+ else
return (NULL);
- }
-
- /* Second token must be BE container dataset name */
- if ((tok = strtok(ds, "/")) == NULL ||
- strcmp(tok, BE_CONTAINER_DS_NAME) != 0)
- return (NULL);
-
- /* Return the remaining token if one exists */
- if ((tok = strtok(NULL, "")) == NULL)
- return (NULL);
-
- if ((name = strdup(tok)) == NULL) {
- be_print_err(gettext("be_make_name_from_ds: "
- "memory allocation failed\n"));
- return (NULL);
+
+ if (be_defaults.be_deflt_rpool_container) {
+ if ((name = strdup(ds)) == NULL) {
+ be_print_err(gettext("be_make_name_from_ds: "
+ "memory allocation failed\n"));
+ return (NULL);
+ }
+ } else {
+ /* Second token must be BE container dataset name */
+ if ((tok = strtok(ds, "/")) == NULL ||
+ strcmp(tok, BE_CONTAINER_DS_NAME) != 0)
+ return (NULL);
+
+ /* Return the remaining token if one exists */
+ if ((tok = strtok(NULL, "")) == NULL)
+ return (NULL);
+
+ if ((name = strdup(tok)) == NULL) {
+ be_print_err(gettext("be_make_name_from_ds: "
+ "memory allocation failed\n"));
+ return (NULL);
+ }
}
return (name);
@@ -393,7 +446,7 @@
* track of that BE's menu entry. We will then use the lines from
* that entry to create the entry for the new BE.
*/
- if ((ret = be_open_menu(be_root_pool, pool_mntpnt, menu_file,
+ if ((ret = be_open_menu(be_root_pool, menu_file,
&menu_fp, "r", B_TRUE)) != BE_SUCCESS) {
goto cleanup;
} else if (menu_fp == NULL) {
@@ -682,7 +735,7 @@
(void) strlcat(menu, BE_SPARC_MENU, sizeof (menu));
/* Get handle to boot menu file */
- if ((ret = be_open_menu(be_root_pool, pool_mntpnt, menu, &menu_fp, "r",
+ if ((ret = be_open_menu(be_root_pool, menu, &menu_fp, "r",
B_TRUE)) != BE_SUCCESS) {
goto cleanup;
} else if (menu_fp == NULL) {
@@ -1122,7 +1175,7 @@
(void) snprintf(grub_file, MAXPATHLEN, "%s%s",
pool_mntpnt, BE_GRUB_MENU);
- if ((ret = be_open_menu((char *)be_root_pool, pool_mntpnt, grub_file,
+ if ((ret = be_open_menu((char *)be_root_pool, grub_file,
&menu_fp, "r", B_FALSE)) != BE_SUCCESS) {
goto cleanup;
} else if (menu_fp == NULL) {
@@ -1283,7 +1336,7 @@
(void) snprintf(grub_file, MAXPATHLEN, "%s%s",
pool_mntpnt, BE_GRUB_MENU);
- if ((ret = be_open_menu(be_root_pool, pool_mntpnt, grub_file,
+ if ((ret = be_open_menu(be_root_pool, grub_file,
&grub_fp, "r+", B_TRUE)) != BE_SUCCESS) {
goto cleanup;
} else if (grub_fp == NULL) {
@@ -1521,7 +1574,7 @@
be_make_root_ds(be_root_pool, be_new_name, be_new_root_ds,
sizeof (be_new_root_ds));
- if ((ret = be_open_menu(be_root_pool, pool_mntpnt, menu_file,
+ if ((ret = be_open_menu(be_root_pool, menu_file,
&menu_fp, "r", B_TRUE)) != BE_SUCCESS) {
goto cleanup;
} else if (menu_fp == NULL) {
@@ -1787,7 +1840,7 @@
rpool_mntpnt, BE_SPARC_MENU);
}
- if (be_open_menu(be_root_pool, rpool_mntpnt, menu_file, &menu_fp, "r",
+ if (be_open_menu(be_root_pool, menu_file, &menu_fp, "r",
B_FALSE) != 0) {
ret = B_FALSE;
goto cleanup;
@@ -2098,10 +2151,13 @@
be_valid_be_name(const char *be_name)
{
const char *c = NULL;
+ struct be_defaults be_defaults;
if (be_name == NULL)
return (B_FALSE);
+ be_get_defaults(&be_defaults);
+
/*
* A BE name must not be a multi-level dataset name. We also check
* that it does not contain the ' ' and '%' characters. The ' ' is
@@ -2124,6 +2180,11 @@
strlen(be_name) > BE_NAME_MAX_LEN)
return (B_FALSE);
+ if (be_defaults.be_deflt_bename_starts_with[0] != '\0' &&
+ strstr(be_name, be_defaults.be_deflt_bename_starts_with) == NULL) {
+ return (B_FALSE);
+ }
+
return (B_TRUE);
}
@@ -2469,6 +2530,7 @@
ZFS_CLOSE(zhp);
return (0);
}
+
if ((bt->obe_name = strdup(basename(bt->obe_root_ds)))
== NULL) {
be_print_err(gettext(
@@ -3506,7 +3568,6 @@
* lines are added to the file.
* Parameters:
* pool - The name of the pool the menu.lst file is on
- * pool_mntpt - The mountpoint for the pool we're using.
* menu_file - The name of the file we're creating.
* menu_fp - A pointer to the file pointer of the file we
* created. This is also used to pass back the file
@@ -3522,7 +3583,6 @@
static int
be_create_menu(
char *pool,
- char *pool_mntpt,
char *menu_file,
FILE **menu_fp,
char *mode)
@@ -3653,9 +3713,6 @@
* exist it is simply opened using the mode passed in.
* Parameters:
* pool - The name of the pool the menu.lst file is on
- * pool_mntpt - The mountpoint for the pool we're using.
- * The mountpoint is used since the mountpoint
- * name can differ from the pool name.
* menu_file - The name of the file we're opening.
* menu_fp - A pointer to the file pointer of the file we're
* opening. This is also used to pass back the file
@@ -3675,7 +3732,6 @@
static int
be_open_menu(
char *pool,
- char *pool_mntpt,
char *menu_file,
FILE **menu_fp,
char *mode,
@@ -3700,7 +3756,7 @@
if (set_print)
do_print = B_FALSE;
err = 0;
- if ((err = be_create_menu(pool, pool_mntpt, menu_file,
+ if ((err = be_create_menu(pool, menu_file,
menu_fp, mode)) == ENOENT)
return (BE_ERR_NO_MENU);
else if (err != BE_SUCCESS)
--- a/usr/src/lib/libbe/common/libbe_priv.h Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/lib/libbe/common/libbe_priv.h Wed Apr 06 07:45:22 2011 -0700
@@ -41,6 +41,8 @@
#define ARCH_LENGTH MAXNAMELEN
#define BE_AUTO_NAME_MAX_TRY 3
#define BE_AUTO_NAME_DELIM '-'
+#define BE_DEFAULTS "/etc/default/be"
+#define BE_DFLT_BENAME_STARTS "BENAME_STARTS_WITH="
#define BE_CONTAINER_DS_NAME "ROOT"
#define BE_DEFAULT_CONSOLE "text"
#define BE_POLICY_PROPERTY "org.opensolaris.libbe:policy"
@@ -129,6 +131,11 @@
struct be_plcy_list *be_next_plcy;
}be_plcy_list_t;
+struct be_defaults {
+ boolean_t be_deflt_rpool_container;
+ char be_deflt_bename_starts_with[ZFS_MAXNAMELEN];
+};
+
/* Library globals */
extern libzfs_handle_t *g_zfs;
extern boolean_t do_print;
@@ -211,6 +218,9 @@
int be_zfs_find_current_be_callback(zfs_handle_t *, void *);
int be_check_be_roots_callback(zpool_handle_t *, void *);
+/* defaults */
+void be_get_defaults(struct be_defaults *defaults);
+
#ifdef __cplusplus
}
#endif
--- a/usr/src/man/man1m/beadm.1m Tue Apr 05 09:31:14 2011 -0700
+++ b/usr/src/man/man1m/beadm.1m Wed Apr 06 07:45:22 2011 -0700
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2011 Nexenta Systems, Inc. All rights reserved.
.TH beadm 1M "26 Feb 2011" "SunOS 5.11" "System Administration Commands"
.SH NAME
beadm \- utility for managing zfs boot environments
@@ -406,6 +407,13 @@
Makes beName the active BE on next reboot.
.RE
+.SH ALTERNATE BE LOCATION
+.LP
+The alternate BE location outside rpool/ROOT can be configured
+by modifying the BENAME_STARTS_WITH parameter in /etc/default/be.
+For example: BENAME_STARTS_WITH=rootfs
+.RE
+
.SH EXAMPLES
.LP
\fBExample 1\fR: Create a new BE named BE1, by cloning the current live BE.
@@ -685,6 +693,20 @@
.sp
.RE
.RE
+.sp
+.LP
+.sp
+.ne 2
+.mk
+.na
+\fB/etc/default/be\fR
+.ad
+.sp .6
+.RS 4n
+Contains default value for BENAME_STARTS_WITH parameter
+.sp
+.RE
+.RE
.SH ATTRIBUTES
.sp