diff options
Diffstat (limited to 'usr/src/lib/pylibbe/common/libbe_py.c')
-rw-r--r-- | usr/src/lib/pylibbe/common/libbe_py.c | 1094 |
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); +} |