summaryrefslogtreecommitdiff
path: root/usr/src/lib/pylibbe/common/libbe_py.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/pylibbe/common/libbe_py.c')
-rw-r--r--usr/src/lib/pylibbe/common/libbe_py.c1094
1 files changed, 1094 insertions, 0 deletions
diff --git a/usr/src/lib/pylibbe/common/libbe_py.c b/usr/src/lib/pylibbe/common/libbe_py.c
new file mode 100644
index 0000000000..b4f6ca0e52
--- /dev/null
+++ b/usr/src/lib/pylibbe/common/libbe_py.c
@@ -0,0 +1,1094 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ */
+
+#include <Python.h>
+#include <sys/varargs.h>
+#include <stdio.h>
+#include <libnvpair.h>
+
+#include <libbe.h>
+#include <libbe_priv.h>
+
+enum {
+ BE_PY_SUCCESS = 0,
+ BE_PY_ERR_APPEND = 6000,
+ BE_PY_ERR_DICT,
+ BE_PY_ERR_LIST,
+ BE_PY_ERR_NVLIST,
+ BE_PY_ERR_PARSETUPLE,
+ BE_PY_ERR_PRINT_ERR,
+ BE_PY_ERR_VAR_CONV,
+} bePyErr;
+
+/*
+ * public libbe functions
+ */
+
+PyObject *beCreateSnapshot(PyObject *, PyObject *);
+PyObject *beCopy(PyObject *, PyObject *);
+PyObject *beList(PyObject *, PyObject *);
+PyObject *beActivate(PyObject *, PyObject *);
+PyObject *beDestroy(PyObject *, PyObject *);
+PyObject *beDestroySnapshot(PyObject *, PyObject *);
+PyObject *beRename(PyObject *, PyObject *);
+PyObject *beMount(PyObject *, PyObject *);
+PyObject *beUnmount(PyObject *, PyObject *);
+PyObject *bePrintErrors(PyObject *, PyObject *);
+PyObject *beGetErrDesc(PyObject *, PyObject *);
+char *beMapLibbePyErrorToString(int);
+void initlibbe_py();
+
+static boolean_t convertBEInfoToDictionary(be_node_list_t *be,
+ PyObject **listDict);
+static boolean_t convertDatasetInfoToDictionary(be_dataset_list_t *ds,
+ PyObject **listDict);
+static boolean_t convertSnapshotInfoToDictionary(be_snapshot_list_t *ss,
+ PyObject **listDict);
+static boolean_t convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...);
+
+
+/* ~~~~~~~~~~~~~~~ */
+/* Public Funtions */
+/* ~~~~~~~~~~~~~~~ */
+
+/*
+ * Function: beCreateSnapshot
+ * Description: Convert Python args to nvlist pairs and
+ * call libbe:be_create_snapshot to create a
+ * snapshot of all the datasets within a BE
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the BE to create a snapshot of
+ * snapName - The name of the snapshot to create (optional)
+ *
+ * The following public attribute values. defined by libbe.h,
+ * are used by this function:
+ *
+ * Returns a pointer to a python object and an optional snapshot name:
+ * 0, [snapName] - Success
+ * 1, [snapName] - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beCreateSnapshot(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ char *snapName = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+ PyObject *retVals = NULL;
+
+ if (!PyArg_ParseTuple(args, "z|z", &beName, &snapName)) {
+ return (Py_BuildValue("[is]", BE_PY_ERR_PARSETUPLE, NULL));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 4,
+ BE_ATTR_ORIG_BE_NAME, beName,
+ BE_ATTR_SNAP_NAME, snapName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[is]", BE_PY_ERR_NVLIST, NULL));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if ((ret = be_create_snapshot(beAttrs)) != 0) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[is]", ret, NULL));
+ }
+ if (snapName == NULL) {
+ if (nvlist_lookup_pairs(beAttrs, NV_FLAG_NOENTOK,
+ BE_ATTR_SNAP_NAME, DATA_TYPE_STRING, &snapName,
+ NULL) != 0) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[is]",
+ BE_PY_ERR_NVLIST, NULL));
+ }
+ retVals = Py_BuildValue("[is]", ret, snapName);
+ nvlist_free(beAttrs);
+ return (retVals);
+ }
+ nvlist_free(beAttrs);
+
+ return (Py_BuildValue("[is]", ret, NULL));
+}
+
+/*
+ * Function: beCopy
+ * Description: Convert Python args to nvlist pairs and call libbe:be_copy
+ * to create a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * trgtBeName - The name of the BE to create
+ * srcBeName - The name of the BE used to create trgtBeName (optional)
+ * rpool - The pool to create the new BE in (optional)
+ * srcSnapName - The snapshot name (optional)
+ * beNameProperties - The properties to use when creating
+ * the BE (optional)
+ *
+ * Returns a pointer to a python object. That Python object will consist of
+ * the return code and optional attributes, trgtBeName and snapshotName
+ * BE_SUCCESS, [trgtBeName], [trgtSnapName] - Success
+ * 1, [trgtBeName], [trgtSnapName] - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beCopy(PyObject *self, PyObject *args)
+{
+ char *trgtBeName = NULL;
+ char *srcBeName = NULL;
+ char *srcSnapName = NULL;
+ char *trgtSnapName = NULL;
+ char *rpool = NULL;
+ char *beDescription = NULL;
+ int pos = 0;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+ nvlist_t *beProps = NULL;
+ PyObject *beNameProperties = NULL;
+ PyObject *pkey = NULL;
+ PyObject *pvalue = NULL;
+ PyObject *retVals = NULL;
+
+ if (!PyArg_ParseTuple(args, "|zzzzOz", &trgtBeName, &srcBeName,
+ &srcSnapName, &rpool, &beNameProperties, &beDescription)) {
+ return (Py_BuildValue("[iss]", BE_PY_ERR_PARSETUPLE,
+ NULL, NULL));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 10,
+ BE_ATTR_NEW_BE_NAME, trgtBeName,
+ BE_ATTR_ORIG_BE_NAME, srcBeName,
+ BE_ATTR_SNAP_NAME, srcSnapName,
+ BE_ATTR_NEW_BE_POOL, rpool,
+ BE_ATTR_NEW_BE_DESC, beDescription)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST, NULL, NULL));
+ }
+
+ if (beNameProperties != NULL) {
+ if (nvlist_alloc(&beProps, NV_UNIQUE_NAME, 0) != 0) {
+ (void) printf("nvlist_alloc failed.\n");
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
+ NULL, NULL));
+ }
+ while (PyDict_Next(beNameProperties, &pos, &pkey, &pvalue)) {
+ if (!convertPyArgsToNvlist(&beProps, 2,
+ PyString_AsString(pkey),
+ PyString_AsString(pvalue))) {
+ nvlist_free(beProps);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
+ NULL, NULL));
+ }
+ }
+ }
+
+ if (beProps != NULL && beAttrs != NULL &&
+ nvlist_add_nvlist(beAttrs, BE_ATTR_ZFS_PROPERTIES,
+ beProps) != 0) {
+ nvlist_free(beProps);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
+ NULL, NULL));
+ }
+
+ if (beProps != NULL) nvlist_free(beProps);
+
+ if (trgtBeName == NULL) {
+ /*
+ * Caller wants to get back the BE_ATTR_NEW_BE_NAME and
+ * BE_ATTR_SNAP_NAME
+ */
+ if ((ret = be_copy(beAttrs)) != BE_SUCCESS) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", ret, NULL, NULL));
+ }
+
+ /*
+ * When no trgtBeName is passed to be_copy, be_copy
+ * returns an auto generated beName and snapshot name.
+ */
+ if (nvlist_lookup_string(beAttrs, BE_ATTR_NEW_BE_NAME,
+ &trgtBeName) != 0) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
+ NULL, NULL));
+ }
+ if (nvlist_lookup_string(beAttrs, BE_ATTR_SNAP_NAME,
+ &trgtSnapName) != 0) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
+ NULL, NULL));
+ }
+
+ retVals = Py_BuildValue("[iss]", BE_PY_SUCCESS,
+ trgtBeName, trgtSnapName);
+ nvlist_free(beAttrs);
+ return (retVals);
+
+ } else {
+ ret = be_copy(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("[iss]", ret, NULL, NULL));
+ }
+}
+
+/*
+ * Function: beList
+ * Description: Convert Python args to nvlist pairs and call libbe:be_list
+ * to gather information about Boot Environments
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the BE to list (optional)
+ *
+ * Returns a pointer to a python object. That Python object will consist of
+ * the return code and a list of Dicts or NULL.
+ * BE_PY_SUCCESS, listOfDicts - Success
+ * bePyErr or be_errno_t, NULL - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beList(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ int ret = BE_PY_SUCCESS;
+ be_node_list_t *list = NULL;
+ be_node_list_t *be = NULL;
+ PyObject *dict = NULL;
+ PyObject *listOfDicts = NULL;
+
+ if ((listOfDicts = PyList_New(0)) == NULL) {
+ ret = BE_PY_ERR_DICT;
+ listOfDicts = Py_None;
+ goto done;
+ }
+
+ if (!PyArg_ParseTuple(args, "|z", &beName)) {
+ ret = BE_PY_ERR_PARSETUPLE;
+ goto done;
+ }
+
+ if ((ret = be_list(beName, &list)) != BE_SUCCESS) {
+ goto done;
+ }
+
+ for (be = list; be != NULL; be = be->be_next_node) {
+ be_dataset_list_t *ds = be->be_node_datasets;
+ be_snapshot_list_t *ss = be->be_node_snapshots;
+
+ if ((dict = PyDict_New()) == NULL) {
+ ret = BE_PY_ERR_DICT;
+ goto done;
+ }
+
+ if (!convertBEInfoToDictionary(be, &dict)) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_VAR_CONV;
+ goto done;
+ }
+
+ if (PyList_Append(listOfDicts, dict) != 0) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_APPEND;
+ goto done;
+ }
+
+ /* LINTED */
+ Py_DECREF(dict);
+
+ while (ds != NULL) {
+ if ((dict = PyDict_New()) == NULL) {
+ ret = BE_PY_ERR_DICT;
+ goto done;
+ }
+
+ if (!convertDatasetInfoToDictionary(ds, &dict)) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_VAR_CONV;
+ goto done;
+ }
+
+ if (PyList_Append(listOfDicts, dict) != 0) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_APPEND;
+ goto done;
+ }
+
+ ds = ds->be_next_dataset;
+
+ /* LINTED */
+ Py_DECREF(dict);
+ }
+
+
+ while (ss != NULL) {
+ if ((dict = PyDict_New()) == NULL) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_DICT;
+ goto done;
+ }
+
+ if (!convertSnapshotInfoToDictionary(ss, &dict)) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_VAR_CONV;
+ goto done;
+ }
+
+ if (PyList_Append(listOfDicts, dict) != 0) {
+ /* LINTED */
+ Py_DECREF(dict);
+ ret = BE_PY_ERR_APPEND;
+ goto done;
+ }
+
+ ss = ss->be_next_snapshot;
+
+ /* LINTED */
+ Py_DECREF(dict);
+ }
+ }
+
+done:
+ if (list != NULL)
+ be_free_list(list);
+ return (Py_BuildValue("[iO]", ret, listOfDicts));
+}
+
+/*
+ * Function: beActivate
+ * Description: Convert Python args to nvlist pairs and call libbe:be_activate
+ * to activate a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the BE to activate
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beActivate(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "z", &beName)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_activate(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beDestroy
+ * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
+ * to destroy a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the BE to destroy
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beDestroy(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ int destroy_snaps = 0;
+ int force_unmount = 0;
+ int destroy_flags = 0;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "z|ii", &beName, &destroy_snaps,
+ &force_unmount)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (destroy_snaps == 1)
+ destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
+
+ if (force_unmount == 1)
+ destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
+
+ if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (nvlist_add_uint16(beAttrs, BE_ATTR_DESTROY_FLAGS, destroy_flags)
+ != 0) {
+ (void) printf("nvlist_add_uint16 failed for "
+ "BE_ATTR_DESTROY_FLAGS (%d).\n", destroy_flags);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_destroy(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beDestroySnapshot
+ * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
+ * to destroy a snapshot of a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the BE to destroy
+ * snapName - The name of the snapshot to destroy
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beDestroySnapshot(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ char *snapName = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 4,
+ BE_ATTR_ORIG_BE_NAME, beName,
+ BE_ATTR_SNAP_NAME, snapName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_destroy_snapshot(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beRename
+ * Description: Convert Python args to nvlist pairs and call libbe:be_rename
+ * to rename a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * oldBeName - The name of the old Boot Environment
+ * newBeName - The name of the new Boot Environment
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beRename(PyObject *self, PyObject *args)
+{
+ char *oldBeName = NULL;
+ char *newBeName = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "zz", &oldBeName, &newBeName)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 4,
+ BE_ATTR_ORIG_BE_NAME, oldBeName,
+ BE_ATTR_NEW_BE_NAME, newBeName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_rename(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beMount
+ * Description: Convert Python args to nvlist pairs and call libbe:be_mount
+ * to mount a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the Boot Environment to mount
+ * mountpoint - The path of the mountpoint to mount the
+ * Boot Environment on (optional)
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beMount(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ char *mountpoint = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "zz", &beName, &mountpoint)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 4,
+ BE_ATTR_ORIG_BE_NAME, beName,
+ BE_ATTR_MOUNTPOINT, mountpoint)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_mount(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beUnmount
+ * Description: Convert Python args to nvlist pairs and call libbe:be_unmount
+ * to unmount a Boot Environment
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the Boot Environment to unmount
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beUnmount(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ int force_unmount = 0;
+ int unmount_flags = 0;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "z|i", &beName, &force_unmount)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (force_unmount == 1)
+ unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
+
+ if (!convertPyArgsToNvlist(&beAttrs, 2,
+ BE_ATTR_ORIG_BE_NAME, beName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (nvlist_add_uint16(beAttrs, BE_ATTR_UNMOUNT_FLAGS, unmount_flags)
+ != 0) {
+ (void) printf("nvlist_add_uint16 failed for "
+ "BE_ATTR_UNMOUNT_FLAGS (%d).\n", unmount_flags);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_unmount(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: beRollback
+ * Description: Convert Python args to nvlist pairs and call libbe:be_rollback
+ * to rollback a Boot Environment to a previously taken
+ * snapshot.
+ * Parameters:
+ * args - pointer to a python object containing:
+ * beName - The name of the Boot Environment to unmount
+ *
+ * Returns a pointer to a python object:
+ * BE_SUCCESS - Success
+ * bePyErr or be_errno_t - Failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beRollback(PyObject *self, PyObject *args)
+{
+ char *beName = NULL;
+ char *snapName = NULL;
+ int ret = BE_PY_SUCCESS;
+ nvlist_t *beAttrs = NULL;
+
+ if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
+ return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
+ }
+
+ if (!convertPyArgsToNvlist(&beAttrs, 4,
+ BE_ATTR_ORIG_BE_NAME, beName,
+ BE_ATTR_SNAP_NAME, snapName)) {
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ if (beAttrs == NULL) {
+ return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
+ }
+
+ ret = be_rollback(beAttrs);
+ nvlist_free(beAttrs);
+ return (Py_BuildValue("i", ret));
+}
+
+/*
+ * Function: bePrintErrors
+ * Description: Convert Python args to boolean and call libbe_print_errors to
+ * turn on/off error output for the library.
+ * Parameter:
+ * args - pointer to a python object containing:
+ * print_errors - Boolean that turns library error
+ * printing on or off.
+ * Parameters:
+ * args - pointer to a python object containing:
+ * 0 - do not print errors - Python boolean "False"
+ * 1 - print errors - Python boolean "True"
+ *
+ * Returns 1 on missing or invalid argument, 0 otherwise
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+bePrintErrors(PyObject *self, PyObject *args)
+{
+ int print_errors;
+
+ if (!PyArg_ParseTuple(args, "i", &print_errors) ||
+ (print_errors != 1 && print_errors != 0))
+ return (Py_BuildValue("i", BE_PY_ERR_PRINT_ERR));
+ libbe_print_errors(print_errors == 1);
+ return (Py_BuildValue("i", BE_PY_SUCCESS));
+}
+
+/*
+ * Function: beGetErrDesc
+ * Description: Convert Python args to an int and call be_err_to_str to
+ * map an error code to an error string.
+ * Parameter:
+ * args - pointer to a python object containing:
+ * errCode - value to map to an error string.
+ *
+ * Returns: error string or NULL
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beGetErrDesc(PyObject *self, PyObject *args)
+{
+ int errCode = 0;
+ char *beErrStr = NULL;
+
+ if (!PyArg_ParseTuple(args, "i", &errCode)) {
+ return (Py_BuildValue("s", NULL));
+ }
+
+ /*
+ * First check libbe_py errors. If NULL is returned check error codes
+ * in libbe.
+ */
+
+ if ((beErrStr = beMapLibbePyErrorToString(errCode)) == NULL) {
+ beErrStr = be_err_to_str(errCode);
+ }
+
+ return (Py_BuildValue("s", beErrStr));
+}
+
+/*
+ * Function: beVerifyBEName
+ * Description: Call be_valid_be_name() to verify the BE name.
+ * Parameter:
+ * args - pointer to a python object containing:
+ * string - value to map to a string.
+ *
+ * Returns: 0 for success or 1 for failure
+ * Scope:
+ * Public
+ */
+/* ARGSUSED */
+PyObject *
+beVerifyBEName(PyObject *self, PyObject *args)
+{
+ char *string = NULL;
+
+ if (!PyArg_ParseTuple(args, "s", &string)) {
+ return (Py_BuildValue("i", 1));
+ }
+
+ if (be_valid_be_name(string)) {
+ return (Py_BuildValue("i", 0));
+ } else {
+ return (Py_BuildValue("i", 1));
+ }
+}
+
+/* ~~~~~~~~~~~~~~~~~ */
+/* Private Functions */
+/* ~~~~~~~~~~~~~~~~~ */
+
+static boolean_t
+convertBEInfoToDictionary(be_node_list_t *be, PyObject **listDict)
+{
+ if (be->be_node_name != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_NAME,
+ PyString_FromString(be->be_node_name)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_rpool != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_POOL,
+ PyString_FromString(be->be_rpool)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_mntpt != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
+ PyString_FromString(be->be_mntpt)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
+ (be->be_mounted ? Py_True : Py_False)) != 0) {
+ return (B_FALSE);
+ }
+
+ if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE,
+ (be->be_active ? Py_True : Py_False)) != 0) {
+ return (B_FALSE);
+ }
+
+ if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE_ON_BOOT,
+ (be->be_active_on_boot ? Py_True : Py_False)) != 0) {
+ return (B_FALSE);
+ }
+
+ if (be->be_space_used != 0) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
+ PyLong_FromUnsignedLongLong(be->be_space_used)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_root_ds != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_ROOT_DS,
+ PyString_FromString(be->be_root_ds)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_node_creation != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
+ PyLong_FromLong(be->be_node_creation)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_policy_type != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
+ PyString_FromString(be->be_policy_type)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (be->be_uuid_str != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_UUID_STR,
+ PyString_FromString(be->be_uuid_str)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ return (B_TRUE);
+}
+
+static boolean_t
+convertDatasetInfoToDictionary(be_dataset_list_t *ds, PyObject **listDict)
+{
+ if (ds->be_dataset_name != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
+ PyString_FromString(ds->be_dataset_name)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (PyDict_SetItemString(*listDict, BE_ATTR_STATUS,
+ (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
+ return (B_FALSE);
+ }
+
+ if (ds->be_ds_mntpt != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
+ PyString_FromString(ds->be_ds_mntpt)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
+ (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
+ return (B_FALSE);
+ }
+
+ if (ds->be_ds_space_used != 0) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
+ PyLong_FromUnsignedLongLong(ds->be_ds_space_used))
+ != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ds->be_dataset_name != 0) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
+ PyString_FromString(ds->be_dataset_name)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ds->be_ds_plcy_type != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
+ PyString_FromString(ds->be_ds_plcy_type)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ds->be_ds_creation != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
+ PyLong_FromLong(ds->be_ds_creation)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ return (B_TRUE);
+}
+
+static boolean_t
+convertSnapshotInfoToDictionary(be_snapshot_list_t *ss, PyObject **listDict)
+{
+ if (ss->be_snapshot_name != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_SNAP_NAME,
+ PyString_FromString(ss->be_snapshot_name)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ss->be_snapshot_creation != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
+ PyLong_FromLong(ss->be_snapshot_creation)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ss->be_snapshot_type != NULL) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
+ PyString_FromString(ss->be_snapshot_type)) != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ if (ss->be_snapshot_space_used != 0) {
+ if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
+ PyLong_FromUnsignedLongLong(ss->be_snapshot_space_used))
+ != 0) {
+ return (B_FALSE);
+ }
+ }
+
+ return (B_TRUE);
+}
+
+/*
+ * Convert string arguments to nvlist attributes
+ */
+
+static boolean_t
+convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...)
+{
+ char *pt, *pt2;
+ va_list ap;
+ int i;
+
+ if (*nvList == NULL) {
+ if (nvlist_alloc(nvList, NV_UNIQUE_NAME, 0) != 0) {
+ (void) printf("nvlist_alloc failed.\n");
+ return (B_FALSE);
+ }
+ }
+
+ va_start(ap, numArgs);
+
+ for (i = 0; i < numArgs; i += 2) {
+ if ((pt = va_arg(ap, char *)) == NULL ||
+ (pt2 = va_arg(ap, char *)) == NULL) {
+ continue;
+ }
+ if (nvlist_add_string(*nvList, pt, pt2) != 0) {
+ (void) printf("nvlist_add_string failed for %s (%s).\n",
+ pt, pt2);
+ nvlist_free(*nvList);
+ return (B_FALSE);
+ }
+ }
+
+ va_end(ap);
+
+ return (B_TRUE);
+}
+
+/*
+ * Function: beMapLibbePyErrorToString
+ * Description: Convert Python args to an int and map an error code to an
+ * error string.
+ * Parameter:
+ * errCode - value to map to an error string.
+ *
+ * Returns error string or NULL
+ * Scope:
+ * Public
+ */
+
+char *
+beMapLibbePyErrorToString(int errCode)
+{
+ switch (errCode) {
+ case BE_PY_ERR_APPEND:
+ return ("Unable to append a dictionary to a list "
+ "of dictinaries.");
+ case BE_PY_ERR_DICT:
+ return ("Creation of a Python dictionary failed.");
+ case BE_PY_ERR_LIST:
+ return ("beList() failed.");
+ case BE_PY_ERR_NVLIST:
+ return ("An nvlist operation failed.");
+ case BE_PY_ERR_PARSETUPLE:
+ return ("PyArg_ParseTuple() failed to convert variable to C.");
+ case BE_PY_ERR_PRINT_ERR:
+ return ("bePrintErrors() failed.");
+ case BE_PY_ERR_VAR_CONV:
+ return ("Unable to add variables to a Python dictionary.");
+ default:
+ return (NULL);
+ }
+}
+
+/* Private python initialization structure */
+
+static struct PyMethodDef libbeMethods[] = {
+ {"beCopy", (PyCFunction)beCopy, METH_VARARGS, "Create/Copy a BE."},
+ {"beCreateSnapshot", (PyCFunction)beCreateSnapshot, METH_VARARGS,
+ "Create a snapshot."},
+ {"beDestroy", (PyCFunction)beDestroy, METH_VARARGS, "Destroy a BE."},
+ {"beDestroySnapshot", (PyCFunction)beDestroySnapshot, METH_VARARGS,
+ "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."},
+ {"beRename", (PyCFunction)beRename, METH_VARARGS, "Rename a BE."},
+ {"beActivate", (PyCFunction)beActivate, METH_VARARGS, "Activate a BE."},
+ {"beRollback", (PyCFunction)beRollback, METH_VARARGS, "Rollback a BE."},
+ {"bePrintErrors", (PyCFunction)bePrintErrors, METH_VARARGS,
+ "Enable/disable error printing."},
+ {"beGetErrDesc", (PyCFunction)beGetErrDesc, METH_VARARGS,
+ "Map Error codes to strings."},
+ {"beVerifyBEName", (PyCFunction)beVerifyBEName, METH_VARARGS,
+ "Verify BE name."},
+ {NULL, NULL, 0, NULL}
+};
+
+void
+initlibbe_py()
+{
+ /* PyMODINIT_FUNC; */
+ (void) Py_InitModule("libbe_py", libbeMethods);
+}