/* * 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. * Copyright 2012 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2021 OmniOS Community Edition (OmniOSce) Association. */ #include #include #include #include #include #include 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 *); PyObject *beActivate(PyObject *, 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); 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 */ 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 */ PyObject * beCopy(PyObject *self, PyObject *args) { char *trgtBeName = NULL; char *srcBeName = NULL; char *srcSnapName = NULL; char *trgtSnapName = NULL; char *rpool = NULL; char *beDescription = NULL; Py_ssize_t 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 PY_MAJOR_VERSION >= 3 if (!convertPyArgsToNvlist(&beProps, 2, PyUnicode_AsUTF8(pkey), PyUnicode_AsUTF8(pvalue))) { #else if (!convertPyArgsToNvlist(&beProps, 2, PyString_AsString(pkey), PyString_AsString(pvalue))) { #endif 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)); } 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) * 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. * BE_PY_SUCCESS, listOfDicts - Success * bePyErr or be_errno_t, NULL - Failure * Scope: * Public */ PyObject * 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; listOfDicts = Py_None; goto done; } if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zi", kwlist, &beName, &noSnaps)) { ret = BE_PY_ERR_PARSETUPLE; goto done; } if (noSnaps) listopts &= ~BE_LIST_SNAPSHOTS; if ((ret = be_list(beName, &list, listopts)) != 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 * temporary - If True, perform a temporary BE activation * If False, remove a temporary BE activation * If not present, do nothing in regard to temporary activation * * Returns a pointer to a python object: * BE_SUCCESS - Success * bePyErr or be_errno_t - Failure * Scope: * Public */ PyObject * beActivate(PyObject *self, PyObject *args, PyObject *keywds) { char *beName = NULL; int ret = BE_PY_SUCCESS; nvlist_t *beAttrs = NULL; int temp = -1; static char *kwlist[] = {"bename", "temporary", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "z|i", kwlist, &beName, &temp)) { ret = BE_PY_ERR_PARSETUPLE; goto done; } if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName) || beAttrs == NULL) { ret = BE_PY_ERR_NVLIST; goto done; } if (temp != -1 && nvlist_add_boolean_value(beAttrs, BE_ATTR_ACTIVE_NEXTBOOT, temp == 0 ? B_FALSE : B_TRUE) != 0) { ret = BE_PY_ERR_NVLIST; goto done; } ret = be_activate(beAttrs); done: 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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, PyUnicode_FromString(be->be_node_name)) != 0) { return (B_FALSE); } } if (be->be_rpool != NULL) { if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_POOL, PyUnicode_FromString(be->be_rpool)) != 0) { return (B_FALSE); } } if (be->be_mntpt != NULL) { if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT, PyUnicode_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 (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE_NEXTBOOT, (be->be_active_next ? Py_True : Py_False)) != 0) { return (B_FALSE); } if (PyDict_SetItemString(*listDict, BE_ATTR_GLOBAL_ACTIVE, (be->be_global_active ? 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, PyUnicode_FromString(be->be_root_ds)) != 0) { return (B_FALSE); } } if (be->be_node_creation != 0) { 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, PyUnicode_FromString(be->be_policy_type)) != 0) { return (B_FALSE); } } if (be->be_uuid_str != NULL) { if (PyDict_SetItemString(*listDict, BE_ATTR_UUID_STR, PyUnicode_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, PyUnicode_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, PyUnicode_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, PyUnicode_FromString(ds->be_dataset_name)) != 0) { return (B_FALSE); } } if (ds->be_ds_plcy_type != NULL) { if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY, PyUnicode_FromString(ds->be_ds_plcy_type)) != 0) { return (B_FALSE); } } if (ds->be_ds_creation != 0) { 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, PyUnicode_FromString(ss->be_snapshot_name)) != 0) { return (B_FALSE); } } if (ss->be_snapshot_creation != 0) { 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, PyUnicode_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); *nvList = NULL; 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 dictionaries."); 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", beCopy, METH_VARARGS, "Create/Copy a BE."}, {"beCreateSnapshot", beCreateSnapshot, METH_VARARGS, "Create a snapshot."}, {"beDestroy", beDestroy, METH_VARARGS, "Destroy a BE."}, {"beDestroySnapshot", beDestroySnapshot, METH_VARARGS, "Destroy a snapshot."}, {"beMount", beMount, METH_VARARGS, "Mount a BE."}, {"beUnmount", beUnmount, METH_VARARGS, "Unmount a BE."}, {"beList", (PyCFunction)(uintptr_t)beList, METH_VARARGS | METH_KEYWORDS, "List BE info."}, {"beRename", beRename, METH_VARARGS, "Rename a BE."}, {"beActivate", (PyCFunction)(uintptr_t)beActivate, METH_VARARGS | METH_KEYWORDS, "Activate a BE."}, {"beRollback", beRollback, METH_VARARGS, "Rollback a BE."}, {"bePrintErrors", bePrintErrors, METH_VARARGS, "Enable/disable error printing."}, {"beGetErrDesc", beGetErrDesc, METH_VARARGS, "Map Error codes to strings."}, {"beVerifyBEName", beVerifyBEName, METH_VARARGS, "Verify BE name."}, {NULL, NULL, 0, NULL} }; #if PY_MAJOR_VERSION >= 3 static struct PyModuleDef libbe_module = { PyModuleDef_HEAD_INIT, "libbe_py", NULL, -1, libbeMethods }; #endif static PyObject * moduleinit() { /* PyMODINIT_FUNC; */ #if PY_MAJOR_VERSION >= 3 return (PyModule_Create(&libbe_module)); #else /* * Python2 module initialisation functions are void and may not return * a value. However, they will set an exception if appropriate. */ (void) Py_InitModule("libbe_py", libbeMethods); return (NULL); #endif } #if PY_MAJOR_VERSION >= 3 PyMODINIT_FUNC PyInit_libbe_py(void) { return (moduleinit()); } #else PyMODINIT_FUNC initlibbe_py(void) { (void) moduleinit(); } #endif