9892 Most consumers of be_list() do not need snapshots
Reviewed by: Dominik Hassler <hadfl@omniosce.org>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Jim Klimov <jim@cos.ru>
Reviewed by: Dan McDonald <danmcd@joyent.com>
Approved by: Gordon Ross <gordon.w.ross@gmail.com>
diff --git a/usr/src/cmd/beadm/beadm.c b/usr/src/cmd/beadm/beadm.c
index 3667c76..ee18dcd 100644
--- a/usr/src/cmd/beadm/beadm.c
+++ b/usr/src/cmd/beadm/beadm.c
@@ -26,6 +26,7 @@
  * Copyright 2015 Gary Mills
  * Copyright (c) 2015 by Delphix. All rights reserved.
  * Copyright 2017 Jason King
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 /*
@@ -1147,7 +1148,8 @@
 	if (argc == 1)
 		be_name = argv[0];
 
-	err = be_list(be_name, &be_nodes);
+	err = be_list(be_name, &be_nodes,
+	    snaps ? BE_LIST_SNAPSHOTS : BE_LIST_DEFAULT);
 
 	switch (err) {
 	case BE_SUCCESS:
diff --git a/usr/src/cmd/boot/bootadm/bootadm.c b/usr/src/cmd/boot/bootadm/bootadm.c
index bedca2a..36d167f 100644
--- a/usr/src/cmd/boot/bootadm/bootadm.c
+++ b/usr/src/cmd/boot/bootadm/bootadm.c
@@ -1137,7 +1137,7 @@
 			goto done;
 		}
 
-		if (be_list(NULL, &be_nodes) != BE_SUCCESS) {
+		if (be_list(NULL, &be_nodes, BE_LIST_DEFAULT) != BE_SUCCESS) {
 			bam_error(_("No BE's found\n"));
 			goto done;
 		}
@@ -1197,7 +1197,7 @@
 		}
 	}
 
-	if (be_list(NULL, &be_nodes) != BE_SUCCESS) {
+	if (be_list(NULL, &be_nodes, BE_LIST_DEFAULT) != BE_SUCCESS) {
 		bam_error(_("No BE's found\n"));
 		ret = BAM_ERROR;
 		goto done;
@@ -3312,7 +3312,7 @@
 	/*
 	 * Check if the current dataset is BE
 	 */
-	if (be_list(NULL, &be_nodes) == BE_SUCCESS) {
+	if (be_list(NULL, &be_nodes, BE_LIST_DEFAULT) == BE_SUCCESS) {
 		for (cur_be = be_nodes; cur_be != NULL;
 		    cur_be = cur_be->be_next_node) {
 
diff --git a/usr/src/cmd/boot/bootadm/bootadm_loader.c b/usr/src/cmd/boot/bootadm/bootadm_loader.c
index 56b509b..6f96f4b 100644
--- a/usr/src/cmd/boot/bootadm/bootadm_loader.c
+++ b/usr/src/cmd/boot/bootadm/bootadm_loader.c
@@ -26,6 +26,7 @@
 /*
  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2016 Toomas Soome <tsoome@me.com>
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 /*
@@ -282,7 +283,7 @@
 	if (fp == NULL)
 		return (BAM_ERROR);
 
-	if (be_list(NULL, &be_nodes) != BE_SUCCESS)
+	if (be_list(NULL, &be_nodes, BE_LIST_DEFAULT) != BE_SUCCESS)
 		be_nodes = NULL;
 
 	/*
@@ -718,7 +719,7 @@
 		goto out;
 	}
 
-	ret = be_list(NULL, &be_nodes);
+	ret = be_list(NULL, &be_nodes, BE_LIST_DEFAULT);
 	if (ret != BE_SUCCESS) {
 		goto out;
 	}
@@ -1028,7 +1029,7 @@
 	FILE *fp;
 
 	(void) snprintf(path, PATH_MAX, "%s%s", menu_root, MENU);
-	rv = be_list(NULL, &be_nodes);
+	rv = be_list(NULL, &be_nodes, BE_LIST_DEFAULT);
 
 	if (rv != BE_SUCCESS)
 		return (BAM_ERROR);
@@ -1205,7 +1206,7 @@
 
 	/* find default entry */
 	if (entry == -1) {
-		ret = be_list(NULL, &be_nodes);
+		ret = be_list(NULL, &be_nodes, BE_LIST_DEFAULT);
 		if (ret != BE_SUCCESS) {
 			bam_error(_("No BE's found\n"));
 			return (BAM_ERROR);
diff --git a/usr/src/lib/libbe/common/be_activate.c b/usr/src/lib/libbe/common/be_activate.c
index 7b0f3cd..9fd95e1 100644
--- a/usr/src/lib/libbe/common/be_activate.c
+++ b/usr/src/lib/libbe/common/be_activate.c
@@ -26,6 +26,7 @@
 /*
  * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2016 Toomas Soome <tsoome@me.com>
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #include <assert.h>
@@ -275,7 +276,8 @@
 		}
 	}
 
-	if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
+	if ((ret = _be_list(cb.obe_name, &be_nodes, BE_LIST_DEFAULT))
+	    != BE_SUCCESS) {
 		return (ret);
 	}
 
@@ -445,7 +447,7 @@
 		return (B_FALSE);
 	}
 
-	if (_be_list(be_name, &be_node) != BE_SUCCESS) {
+	if (_be_list(be_name, &be_node, BE_LIST_DEFAULT) != BE_SUCCESS) {
 		return (B_FALSE);
 	}
 
diff --git a/usr/src/lib/libbe/common/be_list.c b/usr/src/lib/libbe/common/be_list.c
index 7dce228..e2a5bf9 100644
--- a/usr/src/lib/libbe/common/be_list.c
+++ b/usr/src/lib/libbe/common/be_list.c
@@ -59,6 +59,7 @@
 	be_snapshot_list_t **be_snapshots_tail;
 	char current_be[MAXPATHLEN];
 	struct be_defaults be_defaults;
+	uint64_t flags;
 } list_callback_data_t;
 
 /*
@@ -120,7 +121,7 @@
  *		Public
  */
 int
-be_list(char *be_name, be_node_list_t **be_nodes)
+be_list(char *be_name, be_node_list_t **be_nodes, uint64_t flags)
 {
 	int	ret = BE_SUCCESS;
 
@@ -137,7 +138,7 @@
 		}
 	}
 
-	ret = _be_list(be_name, be_nodes);
+	ret = _be_list(be_name, be_nodes, flags);
 
 	be_zfs_fini();
 
@@ -217,7 +218,7 @@
  *		Semi-private (library wide use only)
  */
 int
-_be_list(char *be_name, be_node_list_t **be_nodes)
+_be_list(char *be_name, be_node_list_t **be_nodes, uint64_t flags)
 {
 	list_callback_data_t cb = { 0 };
 	be_transaction_data_t bt = { 0 };
@@ -230,6 +231,7 @@
 		return (BE_ERR_INVAL);
 
 	be_get_defaults(&cb.be_defaults);
+	cb.flags = flags;
 
 	if (be_find_current_be(&bt) != BE_SUCCESS) {
 		/*
@@ -502,8 +504,9 @@
 			zpool_close(zlp);
 			return (ret);
 		}
-		ret = zfs_iter_snapshots(zhp, B_FALSE, be_add_children_callback,
-		    cb);
+		if (cb->flags & BE_LIST_SNAPSHOTS)
+			ret = zfs_iter_snapshots(zhp, B_FALSE,
+			    be_add_children_callback, cb);
 	}
 
 	if (ret == 0)
@@ -656,7 +659,10 @@
 		*cb->be_datasets_tail = dataset;
 		cb->be_datasets_tail = &dataset->be_next_dataset;
 	}
-	ret = zfs_iter_children(zhp, be_add_children_callback, cb);
+	if (cb->flags & BE_LIST_SNAPSHOTS)
+		ret = zfs_iter_children(zhp, be_add_children_callback, cb);
+	else
+		ret = zfs_iter_filesystems(zhp, be_add_children_callback, cb);
 	if (ret != 0) {
 		be_print_err(gettext("be_add_children_callback: "
 		    "encountered error: %s\n"),
diff --git a/usr/src/lib/libbe/common/be_utils.c b/usr/src/lib/libbe/common/be_utils.c
index fb2f662..b29120c 100644
--- a/usr/src/lib/libbe/common/be_utils.c
+++ b/usr/src/lib/libbe/common/be_utils.c
@@ -24,6 +24,7 @@
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2016 Toomas Soome <tsoome@me.com>
  * Copyright (c) 2015 by Delphix. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 
@@ -140,7 +141,7 @@
 		goto done;
 	}
 
-	ret = _be_list(NULL, &be_nodes);
+	ret = _be_list(NULL, &be_nodes, BE_LIST_DEFAULT);
 	if (ret != BE_SUCCESS)
 		goto done;
 
@@ -2627,7 +2628,7 @@
 /*
  * Function:	be_find_current_be
  * Description:	Find the currently "active" BE. Fill in the
- * 		passed in be_transaction_data_t reference with the
+ *		passed in be_transaction_data_t reference with the
  *		active BE's data.
  * Paramters:
  *		none
@@ -3679,7 +3680,7 @@
 			    "be_get_zone_be_list failed\n"));
 			return (NULL);
 		}
-	} else if (_be_list(NULL, &be_nodes) != BE_SUCCESS) {
+	} else if (_be_list(NULL, &be_nodes, BE_LIST_DEFAULT) != BE_SUCCESS) {
 		be_print_err(gettext("be_get_auto_name: be_list failed\n"));
 		return (NULL);
 	}
@@ -3971,7 +3972,7 @@
 	/*
 	 * Now we need to add all the BE's back into the the file.
 	 */
-	if (_be_list(NULL, &be_nodes) == BE_SUCCESS) {
+	if (_be_list(NULL, &be_nodes, BE_LIST_DEFAULT) == BE_SUCCESS) {
 		while (be_nodes != NULL) {
 			if (strcmp(pool, be_nodes->be_rpool) == 0) {
 				(void) be_append_menu(be_nodes->be_node_name,
diff --git a/usr/src/lib/libbe/common/libbe.h b/usr/src/lib/libbe/common/libbe.h
index a78f7a6..83dffd2 100644
--- a/usr/src/lib/libbe/common/libbe.h
+++ b/usr/src/lib/libbe/common/libbe.h
@@ -27,6 +27,7 @@
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2016 Toomas Soome <tsoome@me.com>
  * Copyright 2015 Gary Mills
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #ifndef _LIBBE_H
@@ -103,7 +104,7 @@
 	BE_ERR_INVALMOUNTPOINT,	/* Unexpected mountpoint */
 	BE_ERR_MOUNT,		/* mount failed */
 	BE_ERR_MOUNTED,		/* already mounted */
-	BE_ERR_NAMETOOLONG, 	/* name > BUFSIZ */
+	BE_ERR_NAMETOOLONG,	/* name > BUFSIZ */
 	BE_ERR_NOENT,		/* Doesn't exist */
 	BE_ERR_POOL_NOENT,	/* No such pool */
 	BE_ERR_NODEV,		/* No such device */
@@ -213,6 +214,11 @@
 #define	BE_INSTALLBOOT_FLAG_FORCE	0x00000002
 #define	BE_INSTALLBOOT_FLAG_VERBOSE	0x00000004
 
+/* Flags for be_list() */
+#define	BE_LIST_DEFAULT			0x00000000
+#define	BE_LIST_SNAPSHOTS		0x00000001
+#define	BE_LIST_ALL			BE_LIST_SNAPSHOTS
+
 /* sort rules for be_sort() */
 typedef enum {
 	BE_SORT_UNSPECIFIED = -1,
@@ -247,7 +253,7 @@
 /*
  * Functions for listing and getting information about existing BEs.
  */
-int be_list(char *, be_node_list_t **);
+int be_list(char *, be_node_list_t **, uint64_t);
 void be_free_list(be_node_list_t *);
 int be_max_avail(char *, uint64_t *);
 char *be_err_to_str(int);
diff --git a/usr/src/lib/libbe/common/libbe_priv.h b/usr/src/lib/libbe/common/libbe_priv.h
index d9cb964..cdae3a7 100644
--- a/usr/src/lib/libbe/common/libbe_priv.h
+++ b/usr/src/lib/libbe/common/libbe_priv.h
@@ -24,6 +24,7 @@
  * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  * Copyright 2016 Toomas Soome <tsoome@me.com>
  * Copyright (c) 2015 by Delphix. All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #ifndef	_LIBBE_PRIV_H
@@ -89,7 +90,7 @@
 	char		*obe_zpool;	/* Original BE pool */
 	char		*obe_snap_name;	/* Original BE snapshot name */
 	char		*obe_altroot;	/* Original BE altroot */
-	char 		*nbe_name;	/* New BE name */
+	char		*nbe_name;	/* New BE name */
 	char		*nbe_root_ds;	/* New BE root dataset */
 	char		*nbe_zpool;	/* New BE pool */
 	char		*nbe_desc;	/* New BE description */
@@ -151,7 +152,7 @@
 int be_get_uuid(const char *, uuid_t *);
 
 /* be_list.c */
-int _be_list(char *, be_node_list_t **);
+int _be_list(char *, be_node_list_t **, uint64_t);
 int be_get_zone_be_list(char *, char *, be_node_list_t **);
 
 /* be_mount.c */
diff --git a/usr/src/lib/pylibbe/common/libbe_py.c b/usr/src/lib/pylibbe/common/libbe_py.c
index 9cc1a7a..fb5102b 100644
--- a/usr/src/lib/pylibbe/common/libbe_py.c
+++ b/usr/src/lib/pylibbe/common/libbe_py.c
@@ -22,6 +22,7 @@
 /*
  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2012 OmniTI Computer Consulting, Inc.  All rights reserved.
+ * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
  */
 
 #include <Python.h>
@@ -49,7 +50,7 @@
 
 PyObject *beCreateSnapshot(PyObject *, PyObject *);
 PyObject *beCopy(PyObject *, PyObject *);
-PyObject *beList(PyObject *, PyObject *);
+PyObject *beList(PyObject *, PyObject *, PyObject *);
 PyObject *beActivate(PyObject *, PyObject *);
 PyObject *beDestroy(PyObject *, PyObject *);
 PyObject *beDestroySnapshot(PyObject *, PyObject *);
@@ -269,7 +270,8 @@
  *              to gather information about Boot Environments
  * Parameters:
  *   args -     pointer to a python object containing:
- *     beName - The name of the BE to list (optional)
+ *     bename  - The name of the BE to list (optional)
+ *     nosnaps - boolean indicating whether to exclude snapshots (optional)
  *
  * Returns a pointer to a python object. That Python object will consist of
  * the return code and a list of Dicts or NULL.
@@ -280,14 +282,18 @@
  */
 /* ARGSUSED */
 PyObject *
-beList(PyObject *self, PyObject *args)
+beList(PyObject *self, PyObject *args, PyObject *keywds)
 {
 	char	*beName = NULL;
+	int	noSnaps = 0;
 	int	ret = BE_PY_SUCCESS;
 	be_node_list_t *list = NULL;
 	be_node_list_t *be = NULL;
 	PyObject *dict = NULL;
 	PyObject *listOfDicts = NULL;
+	uint64_t listopts = BE_LIST_SNAPSHOTS;
+
+	static char *kwlist[] = {"bename", "nosnaps", NULL};
 
 	if ((listOfDicts = PyList_New(0)) == NULL) {
 		ret = BE_PY_ERR_DICT;
@@ -295,12 +301,16 @@
 		goto done;
 	}
 
-	if (!PyArg_ParseTuple(args, "|z", &beName)) {
+	if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zi",
+	    kwlist, &beName, &noSnaps)) {
 		ret = BE_PY_ERR_PARSETUPLE;
 		goto done;
 	}
 
-	if ((ret = be_list(beName, &list)) != BE_SUCCESS) {
+	if (noSnaps)
+		listopts &= ~BE_LIST_SNAPSHOTS;
+
+	if ((ret = be_list(beName, &list, listopts)) != BE_SUCCESS) {
 		goto done;
 	}
 
@@ -641,7 +651,7 @@
 PyObject *
 beUnmount(PyObject *self, PyObject *args)
 {
-	char 		*beName = NULL;
+	char		*beName = NULL;
 	int		force_unmount = 0;
 	int		unmount_flags = 0;
 	int		ret = BE_PY_SUCCESS;
@@ -1079,7 +1089,8 @@
 	    "Destroy a snapshot."},
 	{"beMount", (PyCFunction)beMount, METH_VARARGS, "Mount a BE."},
 	{"beUnmount", (PyCFunction)beUnmount, METH_VARARGS, "Unmount a BE."},
-	{"beList", (PyCFunction)beList, METH_VARARGS, "List BE info."},
+	{"beList", (PyCFunction)beList, METH_VARARGS | METH_KEYWORDS,
+	    "List BE info."},
 	{"beRename", (PyCFunction)beRename, METH_VARARGS, "Rename a BE."},
 	{"beActivate", (PyCFunction)beActivate, METH_VARARGS, "Activate a BE."},
 	{"beRollback", (PyCFunction)beRollback, METH_VARARGS, "Rollback a BE."},