xref: /titanic_52/usr/src/lib/pylibbe/common/libbe_py.c (revision e16fe9a0ee69b445395c471fdca0a7748063d35d)
1f169c0eaSGlenn Lagasse /*
2f169c0eaSGlenn Lagasse  * CDDL HEADER START
3f169c0eaSGlenn Lagasse  *
4f169c0eaSGlenn Lagasse  * The contents of this file are subject to the terms of the
5f169c0eaSGlenn Lagasse  * Common Development and Distribution License (the "License").
6f169c0eaSGlenn Lagasse  * You may not use this file except in compliance with the License.
7f169c0eaSGlenn Lagasse  *
8f169c0eaSGlenn Lagasse  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f169c0eaSGlenn Lagasse  * or http://www.opensolaris.org/os/licensing.
10f169c0eaSGlenn Lagasse  * See the License for the specific language governing permissions
11f169c0eaSGlenn Lagasse  * and limitations under the License.
12f169c0eaSGlenn Lagasse  *
13f169c0eaSGlenn Lagasse  * When distributing Covered Code, include this CDDL HEADER in each
14f169c0eaSGlenn Lagasse  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f169c0eaSGlenn Lagasse  * If applicable, add the following below this CDDL HEADER, with the
16f169c0eaSGlenn Lagasse  * fields enclosed by brackets "[]" replaced with your own identifying
17f169c0eaSGlenn Lagasse  * information: Portions Copyright [yyyy] [name of copyright owner]
18f169c0eaSGlenn Lagasse  *
19f169c0eaSGlenn Lagasse  * CDDL HEADER END
20f169c0eaSGlenn Lagasse  */
21f169c0eaSGlenn Lagasse 
22f169c0eaSGlenn Lagasse /*
23f169c0eaSGlenn Lagasse  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24f5c2e7eaSTheo Schlossnagle  * Copyright 2012 OmniTI Computer Consulting, Inc.  All rights reserved.
2571668a2fSAndy Fiddaman  * Copyright 2018 OmniOS Community Edition (OmniOSce) Association.
26f169c0eaSGlenn Lagasse  */
27f169c0eaSGlenn Lagasse 
28f169c0eaSGlenn Lagasse #include <Python.h>
29f169c0eaSGlenn Lagasse #include <sys/varargs.h>
30f169c0eaSGlenn Lagasse #include <stdio.h>
31f169c0eaSGlenn Lagasse #include <libnvpair.h>
32f169c0eaSGlenn Lagasse 
33f169c0eaSGlenn Lagasse #include <libbe.h>
34f169c0eaSGlenn Lagasse #include <libbe_priv.h>
35f169c0eaSGlenn Lagasse 
36f169c0eaSGlenn Lagasse enum {
37f169c0eaSGlenn Lagasse 	BE_PY_SUCCESS = 0,
38f169c0eaSGlenn Lagasse 	BE_PY_ERR_APPEND = 6000,
39f169c0eaSGlenn Lagasse 	BE_PY_ERR_DICT,
40f169c0eaSGlenn Lagasse 	BE_PY_ERR_LIST,
41f169c0eaSGlenn Lagasse 	BE_PY_ERR_NVLIST,
42f169c0eaSGlenn Lagasse 	BE_PY_ERR_PARSETUPLE,
43f169c0eaSGlenn Lagasse 	BE_PY_ERR_PRINT_ERR,
44f169c0eaSGlenn Lagasse 	BE_PY_ERR_VAR_CONV,
45f169c0eaSGlenn Lagasse } bePyErr;
46f169c0eaSGlenn Lagasse 
47f169c0eaSGlenn Lagasse /*
48f169c0eaSGlenn Lagasse  * public libbe functions
49f169c0eaSGlenn Lagasse  */
50f169c0eaSGlenn Lagasse 
51f169c0eaSGlenn Lagasse PyObject *beCreateSnapshot(PyObject *, PyObject *);
52f169c0eaSGlenn Lagasse PyObject *beCopy(PyObject *, PyObject *);
5371668a2fSAndy Fiddaman PyObject *beList(PyObject *, PyObject *, PyObject *);
54f169c0eaSGlenn Lagasse PyObject *beActivate(PyObject *, PyObject *);
55f169c0eaSGlenn Lagasse PyObject *beDestroy(PyObject *, PyObject *);
56f169c0eaSGlenn Lagasse PyObject *beDestroySnapshot(PyObject *, PyObject *);
57f169c0eaSGlenn Lagasse PyObject *beRename(PyObject *, PyObject *);
58f169c0eaSGlenn Lagasse PyObject *beMount(PyObject *, PyObject *);
59f169c0eaSGlenn Lagasse PyObject *beUnmount(PyObject *, PyObject *);
60f169c0eaSGlenn Lagasse PyObject *bePrintErrors(PyObject *, PyObject *);
61f169c0eaSGlenn Lagasse PyObject *beGetErrDesc(PyObject *, PyObject *);
62f169c0eaSGlenn Lagasse char *beMapLibbePyErrorToString(int);
63f169c0eaSGlenn Lagasse 
64f169c0eaSGlenn Lagasse static boolean_t convertBEInfoToDictionary(be_node_list_t *be,
65f169c0eaSGlenn Lagasse     PyObject **listDict);
66f169c0eaSGlenn Lagasse static boolean_t convertDatasetInfoToDictionary(be_dataset_list_t *ds,
67f169c0eaSGlenn Lagasse     PyObject **listDict);
68f169c0eaSGlenn Lagasse static boolean_t convertSnapshotInfoToDictionary(be_snapshot_list_t *ss,
69f169c0eaSGlenn Lagasse     PyObject **listDict);
70f169c0eaSGlenn Lagasse static boolean_t convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...);
71f169c0eaSGlenn Lagasse 
72f169c0eaSGlenn Lagasse 
73f169c0eaSGlenn Lagasse /* ~~~~~~~~~~~~~~~ */
74f169c0eaSGlenn Lagasse /* Public Funtions */
75f169c0eaSGlenn Lagasse /* ~~~~~~~~~~~~~~~ */
76f169c0eaSGlenn Lagasse 
77f169c0eaSGlenn Lagasse /*
78f169c0eaSGlenn Lagasse  * Function:    beCreateSnapshot
79f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and
80f169c0eaSGlenn Lagasse  *              call libbe:be_create_snapshot to create a
81f169c0eaSGlenn Lagasse  *              snapshot of all the datasets within a BE
82f169c0eaSGlenn Lagasse  * Parameters:
83f169c0eaSGlenn Lagasse  *   args -          pointer to a python object containing:
84f169c0eaSGlenn Lagasse  *        beName -   The name of the BE to create a snapshot of
85f169c0eaSGlenn Lagasse  *        snapName - The name of the snapshot to create (optional)
86f169c0eaSGlenn Lagasse  *
87f169c0eaSGlenn Lagasse  *        The following public attribute values. defined by libbe.h,
88f169c0eaSGlenn Lagasse  *        are used by this function:
89f169c0eaSGlenn Lagasse  *
90f169c0eaSGlenn Lagasse  * Returns a pointer to a python object and an optional snapshot name:
91f169c0eaSGlenn Lagasse  *      0, [snapName] - Success
92f169c0eaSGlenn Lagasse  *      1, [snapName] - Failure
93f169c0eaSGlenn Lagasse  * Scope:
94f169c0eaSGlenn Lagasse  *      Public
95f169c0eaSGlenn Lagasse  */
96f169c0eaSGlenn Lagasse /* ARGSUSED */
97f169c0eaSGlenn Lagasse PyObject *
98f169c0eaSGlenn Lagasse beCreateSnapshot(PyObject *self, PyObject *args)
99f169c0eaSGlenn Lagasse {
100f169c0eaSGlenn Lagasse 	char	*beName = NULL;
101f169c0eaSGlenn Lagasse 	char	*snapName = NULL;
102f169c0eaSGlenn Lagasse 	int	ret = BE_PY_SUCCESS;
103f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
104f169c0eaSGlenn Lagasse 	PyObject	*retVals = NULL;
105f169c0eaSGlenn Lagasse 
106f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "z|z", &beName, &snapName)) {
107f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[is]", BE_PY_ERR_PARSETUPLE, NULL));
108f169c0eaSGlenn Lagasse 	}
109f169c0eaSGlenn Lagasse 
110f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 4,
111f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, beName,
112f169c0eaSGlenn Lagasse 	    BE_ATTR_SNAP_NAME, snapName)) {
113f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
114f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[is]", BE_PY_ERR_NVLIST, NULL));
115f169c0eaSGlenn Lagasse 	}
116f169c0eaSGlenn Lagasse 
117f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
118f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
119f169c0eaSGlenn Lagasse 	}
120f169c0eaSGlenn Lagasse 
121f169c0eaSGlenn Lagasse 	if ((ret = be_create_snapshot(beAttrs)) != 0) {
122f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
123f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[is]", ret, NULL));
124f169c0eaSGlenn Lagasse 	}
125f169c0eaSGlenn Lagasse 	if (snapName == NULL) {
126f169c0eaSGlenn Lagasse 		if (nvlist_lookup_pairs(beAttrs, NV_FLAG_NOENTOK,
127f169c0eaSGlenn Lagasse 		    BE_ATTR_SNAP_NAME, DATA_TYPE_STRING, &snapName,
128f169c0eaSGlenn Lagasse 		    NULL) != 0) {
129f169c0eaSGlenn Lagasse 			nvlist_free(beAttrs);
130f169c0eaSGlenn Lagasse 			return (Py_BuildValue("[is]",
131f169c0eaSGlenn Lagasse 			    BE_PY_ERR_NVLIST, NULL));
132f169c0eaSGlenn Lagasse 		}
133f169c0eaSGlenn Lagasse 		retVals = Py_BuildValue("[is]", ret, snapName);
134f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
135f169c0eaSGlenn Lagasse 		return (retVals);
136f169c0eaSGlenn Lagasse 	}
137f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
138f169c0eaSGlenn Lagasse 
139f169c0eaSGlenn Lagasse 	return (Py_BuildValue("[is]", ret, NULL));
140f169c0eaSGlenn Lagasse }
141f169c0eaSGlenn Lagasse 
142f169c0eaSGlenn Lagasse /*
143f169c0eaSGlenn Lagasse  * Function:    beCopy
144f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_copy
145f169c0eaSGlenn Lagasse  *              to create a Boot Environment
146f169c0eaSGlenn Lagasse  * Parameters:
147f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
148f169c0eaSGlenn Lagasse  *     trgtBeName - The name of the BE to create
149f169c0eaSGlenn Lagasse  *     srcBeName - The name of the BE used to create trgtBeName (optional)
150f169c0eaSGlenn Lagasse  *     rpool - The pool to create the new BE in (optional)
151f169c0eaSGlenn Lagasse  *     srcSnapName - The snapshot name (optional)
152f169c0eaSGlenn Lagasse  *     beNameProperties - The properties to use when creating
153f169c0eaSGlenn Lagasse  *                        the BE (optional)
154f169c0eaSGlenn Lagasse  *
155f169c0eaSGlenn Lagasse  * Returns a pointer to a python object. That Python object will consist of
156f169c0eaSGlenn Lagasse  * the return code and optional attributes, trgtBeName and snapshotName
157f169c0eaSGlenn Lagasse  *      BE_SUCCESS, [trgtBeName], [trgtSnapName] - Success
158f169c0eaSGlenn Lagasse  *      1, [trgtBeName], [trgtSnapName] - Failure
159f169c0eaSGlenn Lagasse  * Scope:
160f169c0eaSGlenn Lagasse  *      Public
161f169c0eaSGlenn Lagasse  */
162f169c0eaSGlenn Lagasse /* ARGSUSED */
163f169c0eaSGlenn Lagasse PyObject *
164f169c0eaSGlenn Lagasse beCopy(PyObject *self, PyObject *args)
165f169c0eaSGlenn Lagasse {
166f169c0eaSGlenn Lagasse 	char	*trgtBeName = NULL;
167f169c0eaSGlenn Lagasse 	char	*srcBeName = NULL;
168f169c0eaSGlenn Lagasse 	char	*srcSnapName = NULL;
169f169c0eaSGlenn Lagasse 	char	*trgtSnapName = NULL;
170f169c0eaSGlenn Lagasse 	char	*rpool = NULL;
171f169c0eaSGlenn Lagasse 	char	*beDescription = NULL;
172f5c2e7eaSTheo Schlossnagle 	Py_ssize_t	pos = 0;
173f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
174f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
175f169c0eaSGlenn Lagasse 	nvlist_t	*beProps = NULL;
176f169c0eaSGlenn Lagasse 	PyObject	*beNameProperties = NULL;
177f169c0eaSGlenn Lagasse 	PyObject	*pkey = NULL;
178f169c0eaSGlenn Lagasse 	PyObject	*pvalue = NULL;
179f169c0eaSGlenn Lagasse 	PyObject	*retVals = NULL;
180f169c0eaSGlenn Lagasse 
181f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "|zzzzOz", &trgtBeName, &srcBeName,
182f169c0eaSGlenn Lagasse 	    &srcSnapName, &rpool, &beNameProperties, &beDescription)) {
183f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[iss]", BE_PY_ERR_PARSETUPLE,
184f169c0eaSGlenn Lagasse 		    NULL, NULL));
185f169c0eaSGlenn Lagasse 	}
186f169c0eaSGlenn Lagasse 
187f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 10,
188f169c0eaSGlenn Lagasse 	    BE_ATTR_NEW_BE_NAME, trgtBeName,
189f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, srcBeName,
190f169c0eaSGlenn Lagasse 	    BE_ATTR_SNAP_NAME, srcSnapName,
191f169c0eaSGlenn Lagasse 	    BE_ATTR_NEW_BE_POOL, rpool,
192f169c0eaSGlenn Lagasse 	    BE_ATTR_NEW_BE_DESC, beDescription)) {
193f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
194f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST, NULL, NULL));
195f169c0eaSGlenn Lagasse 	}
196f169c0eaSGlenn Lagasse 
197f169c0eaSGlenn Lagasse 	if (beNameProperties != NULL) {
198f169c0eaSGlenn Lagasse 		if (nvlist_alloc(&beProps, NV_UNIQUE_NAME, 0) != 0) {
199f169c0eaSGlenn Lagasse 			(void) printf("nvlist_alloc failed.\n");
200f169c0eaSGlenn Lagasse 			nvlist_free(beAttrs);
201f169c0eaSGlenn Lagasse 			return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
202f169c0eaSGlenn Lagasse 			    NULL, NULL));
203f169c0eaSGlenn Lagasse 		}
204f169c0eaSGlenn Lagasse 		while (PyDict_Next(beNameProperties, &pos, &pkey, &pvalue)) {
205*e16fe9a0SAlexander Pyhalov #if PY_MAJOR_VERSION >= 3
206f169c0eaSGlenn Lagasse 			if (!convertPyArgsToNvlist(&beProps, 2,
207*e16fe9a0SAlexander Pyhalov 			    PyUnicode_AsUTF8(pkey),
208*e16fe9a0SAlexander Pyhalov 			    PyUnicode_AsUTF8(pvalue))) {
209*e16fe9a0SAlexander Pyhalov #else
210*e16fe9a0SAlexander Pyhalov 			if (!convertPyArgsToNvlist(&beProps, 2,
211*e16fe9a0SAlexander Pyhalov 			    PyString_AsString(pkey),
212*e16fe9a0SAlexander Pyhalov 			    PyString_AsString(pvalue))) {
213*e16fe9a0SAlexander Pyhalov #endif
214f169c0eaSGlenn Lagasse 				nvlist_free(beProps);
215f169c0eaSGlenn Lagasse 				nvlist_free(beAttrs);
216f169c0eaSGlenn Lagasse 				return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
217f169c0eaSGlenn Lagasse 				    NULL, NULL));
218f169c0eaSGlenn Lagasse 			}
219f169c0eaSGlenn Lagasse 		}
220f169c0eaSGlenn Lagasse 	}
221f169c0eaSGlenn Lagasse 
222f169c0eaSGlenn Lagasse 	if (beProps != NULL && beAttrs != NULL &&
223f169c0eaSGlenn Lagasse 	    nvlist_add_nvlist(beAttrs, BE_ATTR_ZFS_PROPERTIES,
224f169c0eaSGlenn Lagasse 	    beProps) != 0) {
225f169c0eaSGlenn Lagasse 		nvlist_free(beProps);
226f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
227f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
228f169c0eaSGlenn Lagasse 		    NULL, NULL));
229f169c0eaSGlenn Lagasse 	}
230f169c0eaSGlenn Lagasse 
231aab83bb8SJosef 'Jeff' Sipek 	nvlist_free(beProps);
232f169c0eaSGlenn Lagasse 
233f169c0eaSGlenn Lagasse 	if (trgtBeName == NULL) {
234f169c0eaSGlenn Lagasse 		/*
235f169c0eaSGlenn Lagasse 		 * Caller wants to get back the BE_ATTR_NEW_BE_NAME and
236f169c0eaSGlenn Lagasse 		 * BE_ATTR_SNAP_NAME
237f169c0eaSGlenn Lagasse 		 */
238f169c0eaSGlenn Lagasse 		if ((ret = be_copy(beAttrs)) != BE_SUCCESS) {
239f169c0eaSGlenn Lagasse 			nvlist_free(beAttrs);
240f169c0eaSGlenn Lagasse 			return (Py_BuildValue("[iss]", ret, NULL, NULL));
241f169c0eaSGlenn Lagasse 		}
242f169c0eaSGlenn Lagasse 
243f169c0eaSGlenn Lagasse 		/*
244f169c0eaSGlenn Lagasse 		 * When no trgtBeName is passed to be_copy, be_copy
245f169c0eaSGlenn Lagasse 		 * returns an auto generated beName and snapshot name.
246f169c0eaSGlenn Lagasse 		 */
247f169c0eaSGlenn Lagasse 		if (nvlist_lookup_string(beAttrs, BE_ATTR_NEW_BE_NAME,
248f169c0eaSGlenn Lagasse 		    &trgtBeName) != 0) {
249f169c0eaSGlenn Lagasse 			nvlist_free(beAttrs);
250f169c0eaSGlenn Lagasse 			return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
251f169c0eaSGlenn Lagasse 			    NULL, NULL));
252f169c0eaSGlenn Lagasse 		}
253f169c0eaSGlenn Lagasse 		if (nvlist_lookup_string(beAttrs, BE_ATTR_SNAP_NAME,
254f169c0eaSGlenn Lagasse 		    &trgtSnapName) != 0) {
255f169c0eaSGlenn Lagasse 			nvlist_free(beAttrs);
256f169c0eaSGlenn Lagasse 			return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
257f169c0eaSGlenn Lagasse 			    NULL, NULL));
258f169c0eaSGlenn Lagasse 		}
259f169c0eaSGlenn Lagasse 
260f169c0eaSGlenn Lagasse 		retVals = Py_BuildValue("[iss]", BE_PY_SUCCESS,
261f169c0eaSGlenn Lagasse 		    trgtBeName, trgtSnapName);
262f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
263f169c0eaSGlenn Lagasse 		return (retVals);
264f169c0eaSGlenn Lagasse 
265f169c0eaSGlenn Lagasse 	} else {
266f169c0eaSGlenn Lagasse 		ret = be_copy(beAttrs);
267f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
268f169c0eaSGlenn Lagasse 		return (Py_BuildValue("[iss]", ret, NULL, NULL));
269f169c0eaSGlenn Lagasse 	}
270f169c0eaSGlenn Lagasse }
271f169c0eaSGlenn Lagasse 
272f169c0eaSGlenn Lagasse /*
273f169c0eaSGlenn Lagasse  * Function:    beList
274f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_list
275f169c0eaSGlenn Lagasse  *              to gather information about Boot Environments
276f169c0eaSGlenn Lagasse  * Parameters:
277f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
27871668a2fSAndy Fiddaman  *     bename  - The name of the BE to list (optional)
27971668a2fSAndy Fiddaman  *     nosnaps - boolean indicating whether to exclude snapshots (optional)
280f169c0eaSGlenn Lagasse  *
281f169c0eaSGlenn Lagasse  * Returns a pointer to a python object. That Python object will consist of
282f169c0eaSGlenn Lagasse  * the return code and a list of Dicts or NULL.
283f169c0eaSGlenn Lagasse  *      BE_PY_SUCCESS, listOfDicts - Success
284f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t, NULL - Failure
285f169c0eaSGlenn Lagasse  * Scope:
286f169c0eaSGlenn Lagasse  *      Public
287f169c0eaSGlenn Lagasse  */
288f169c0eaSGlenn Lagasse /* ARGSUSED */
289f169c0eaSGlenn Lagasse PyObject *
29071668a2fSAndy Fiddaman beList(PyObject *self, PyObject *args, PyObject *keywds)
291f169c0eaSGlenn Lagasse {
292f169c0eaSGlenn Lagasse 	char	*beName = NULL;
29371668a2fSAndy Fiddaman 	int	noSnaps = 0;
294f169c0eaSGlenn Lagasse 	int	ret = BE_PY_SUCCESS;
295f169c0eaSGlenn Lagasse 	be_node_list_t *list = NULL;
296f169c0eaSGlenn Lagasse 	be_node_list_t *be = NULL;
297f169c0eaSGlenn Lagasse 	PyObject *dict = NULL;
298f169c0eaSGlenn Lagasse 	PyObject *listOfDicts = NULL;
29971668a2fSAndy Fiddaman 	uint64_t listopts = BE_LIST_SNAPSHOTS;
30071668a2fSAndy Fiddaman 
30171668a2fSAndy Fiddaman 	static char *kwlist[] = {"bename", "nosnaps", NULL};
302f169c0eaSGlenn Lagasse 
303f169c0eaSGlenn Lagasse 	if ((listOfDicts = PyList_New(0)) == NULL) {
304f169c0eaSGlenn Lagasse 		ret = BE_PY_ERR_DICT;
305f169c0eaSGlenn Lagasse 		listOfDicts = Py_None;
306f169c0eaSGlenn Lagasse 		goto done;
307f169c0eaSGlenn Lagasse 	}
308f169c0eaSGlenn Lagasse 
30971668a2fSAndy Fiddaman 	if (!PyArg_ParseTupleAndKeywords(args, keywds, "|zi",
31071668a2fSAndy Fiddaman 	    kwlist, &beName, &noSnaps)) {
311f169c0eaSGlenn Lagasse 		ret = BE_PY_ERR_PARSETUPLE;
312f169c0eaSGlenn Lagasse 		goto done;
313f169c0eaSGlenn Lagasse 	}
314f169c0eaSGlenn Lagasse 
31571668a2fSAndy Fiddaman 	if (noSnaps)
31671668a2fSAndy Fiddaman 		listopts &= ~BE_LIST_SNAPSHOTS;
31771668a2fSAndy Fiddaman 
31871668a2fSAndy Fiddaman 	if ((ret = be_list(beName, &list, listopts)) != BE_SUCCESS) {
319f169c0eaSGlenn Lagasse 		goto done;
320f169c0eaSGlenn Lagasse 	}
321f169c0eaSGlenn Lagasse 
322f169c0eaSGlenn Lagasse 	for (be = list; be != NULL; be = be->be_next_node) {
323f169c0eaSGlenn Lagasse 		be_dataset_list_t *ds = be->be_node_datasets;
324f169c0eaSGlenn Lagasse 		be_snapshot_list_t *ss = be->be_node_snapshots;
325f169c0eaSGlenn Lagasse 
326f169c0eaSGlenn Lagasse 		if ((dict = PyDict_New()) == NULL) {
327f169c0eaSGlenn Lagasse 			ret = BE_PY_ERR_DICT;
328f169c0eaSGlenn Lagasse 			goto done;
329f169c0eaSGlenn Lagasse 		}
330f169c0eaSGlenn Lagasse 
331f169c0eaSGlenn Lagasse 		if (!convertBEInfoToDictionary(be, &dict)) {
332f169c0eaSGlenn Lagasse 			/* LINTED */
333f169c0eaSGlenn Lagasse 			Py_DECREF(dict);
334f169c0eaSGlenn Lagasse 			ret = BE_PY_ERR_VAR_CONV;
335f169c0eaSGlenn Lagasse 			goto done;
336f169c0eaSGlenn Lagasse 		}
337f169c0eaSGlenn Lagasse 
338f169c0eaSGlenn Lagasse 		if (PyList_Append(listOfDicts, dict) != 0) {
339f169c0eaSGlenn Lagasse 			/* LINTED */
340f169c0eaSGlenn Lagasse 			Py_DECREF(dict);
341f169c0eaSGlenn Lagasse 			ret = BE_PY_ERR_APPEND;
342f169c0eaSGlenn Lagasse 			goto done;
343f169c0eaSGlenn Lagasse 		}
344f169c0eaSGlenn Lagasse 
345f169c0eaSGlenn Lagasse 		/* LINTED */
346f169c0eaSGlenn Lagasse 		Py_DECREF(dict);
347f169c0eaSGlenn Lagasse 
348f169c0eaSGlenn Lagasse 		while (ds != NULL) {
349f169c0eaSGlenn Lagasse 			if ((dict = PyDict_New()) == NULL) {
350f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_DICT;
351f169c0eaSGlenn Lagasse 				goto done;
352f169c0eaSGlenn Lagasse 			}
353f169c0eaSGlenn Lagasse 
354f169c0eaSGlenn Lagasse 			if (!convertDatasetInfoToDictionary(ds, &dict)) {
355f169c0eaSGlenn Lagasse 				/* LINTED */
356f169c0eaSGlenn Lagasse 				Py_DECREF(dict);
357f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_VAR_CONV;
358f169c0eaSGlenn Lagasse 				goto done;
359f169c0eaSGlenn Lagasse 			}
360f169c0eaSGlenn Lagasse 
361f169c0eaSGlenn Lagasse 			if (PyList_Append(listOfDicts, dict) != 0) {
362f169c0eaSGlenn Lagasse 				/* LINTED */
363f169c0eaSGlenn Lagasse 				Py_DECREF(dict);
364f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_APPEND;
365f169c0eaSGlenn Lagasse 				goto done;
366f169c0eaSGlenn Lagasse 			}
367f169c0eaSGlenn Lagasse 
368f169c0eaSGlenn Lagasse 			ds = ds->be_next_dataset;
369f169c0eaSGlenn Lagasse 
370f169c0eaSGlenn Lagasse 			/* LINTED */
371f169c0eaSGlenn Lagasse 			Py_DECREF(dict);
372f169c0eaSGlenn Lagasse 		}
373f169c0eaSGlenn Lagasse 
374f169c0eaSGlenn Lagasse 
375f169c0eaSGlenn Lagasse 		while (ss != NULL) {
376f169c0eaSGlenn Lagasse 			if ((dict = PyDict_New()) == NULL) {
377f169c0eaSGlenn Lagasse 				/* LINTED */
378f169c0eaSGlenn Lagasse 				Py_DECREF(dict);
379f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_DICT;
380f169c0eaSGlenn Lagasse 				goto done;
381f169c0eaSGlenn Lagasse 			}
382f169c0eaSGlenn Lagasse 
383f169c0eaSGlenn Lagasse 			if (!convertSnapshotInfoToDictionary(ss, &dict)) {
384f169c0eaSGlenn Lagasse 				/* LINTED */
385f169c0eaSGlenn Lagasse 				Py_DECREF(dict);
386f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_VAR_CONV;
387f169c0eaSGlenn Lagasse 				goto done;
388f169c0eaSGlenn Lagasse 			}
389f169c0eaSGlenn Lagasse 
390f169c0eaSGlenn Lagasse 			if (PyList_Append(listOfDicts, dict) != 0) {
391f169c0eaSGlenn Lagasse 				/* LINTED */
392f169c0eaSGlenn Lagasse 				Py_DECREF(dict);
393f169c0eaSGlenn Lagasse 				ret = BE_PY_ERR_APPEND;
394f169c0eaSGlenn Lagasse 				goto done;
395f169c0eaSGlenn Lagasse 			}
396f169c0eaSGlenn Lagasse 
397f169c0eaSGlenn Lagasse 			ss = ss->be_next_snapshot;
398f169c0eaSGlenn Lagasse 
399f169c0eaSGlenn Lagasse 			/* LINTED */
400f169c0eaSGlenn Lagasse 			Py_DECREF(dict);
401f169c0eaSGlenn Lagasse 		}
402f169c0eaSGlenn Lagasse 	}
403f169c0eaSGlenn Lagasse 
404f169c0eaSGlenn Lagasse done:
405f169c0eaSGlenn Lagasse 	if (list != NULL)
406f169c0eaSGlenn Lagasse 		be_free_list(list);
407f169c0eaSGlenn Lagasse 	return (Py_BuildValue("[iO]", ret, listOfDicts));
408f169c0eaSGlenn Lagasse }
409f169c0eaSGlenn Lagasse 
410f169c0eaSGlenn Lagasse /*
411f169c0eaSGlenn Lagasse  * Function:    beActivate
412f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_activate
413f169c0eaSGlenn Lagasse  *              to activate a Boot Environment
414f169c0eaSGlenn Lagasse  * Parameters:
415f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
416f169c0eaSGlenn Lagasse  *     beName - The name of the BE to activate
417f169c0eaSGlenn Lagasse  *
418f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
419f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
420f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
421f169c0eaSGlenn Lagasse  * Scope:
422f169c0eaSGlenn Lagasse  *      Public
423f169c0eaSGlenn Lagasse  */
424f169c0eaSGlenn Lagasse /* ARGSUSED */
425f169c0eaSGlenn Lagasse PyObject *
426f169c0eaSGlenn Lagasse beActivate(PyObject *self, PyObject *args)
427f169c0eaSGlenn Lagasse {
428f169c0eaSGlenn Lagasse 	char		*beName = NULL;
429f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
430f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
431f169c0eaSGlenn Lagasse 
432f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "z", &beName)) {
433f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
434f169c0eaSGlenn Lagasse 	}
435f169c0eaSGlenn Lagasse 
436f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
437f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
438f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
439f169c0eaSGlenn Lagasse 	}
440f169c0eaSGlenn Lagasse 
441f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
442f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
443f169c0eaSGlenn Lagasse 	}
444f169c0eaSGlenn Lagasse 
445f169c0eaSGlenn Lagasse 	ret = be_activate(beAttrs);
446f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
447f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
448f169c0eaSGlenn Lagasse }
449f169c0eaSGlenn Lagasse 
450f169c0eaSGlenn Lagasse /*
451f169c0eaSGlenn Lagasse  * Function:    beDestroy
452f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
453f169c0eaSGlenn Lagasse  *              to destroy a Boot Environment
454f169c0eaSGlenn Lagasse  * Parameters:
455f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
456f169c0eaSGlenn Lagasse  *     beName - The name of the BE to destroy
457f169c0eaSGlenn Lagasse  *
458f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
459f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
460f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
461f169c0eaSGlenn Lagasse  * Scope:
462f169c0eaSGlenn Lagasse  *      Public
463f169c0eaSGlenn Lagasse  */
464f169c0eaSGlenn Lagasse /* ARGSUSED */
465f169c0eaSGlenn Lagasse PyObject *
466f169c0eaSGlenn Lagasse beDestroy(PyObject *self, PyObject *args)
467f169c0eaSGlenn Lagasse {
468f169c0eaSGlenn Lagasse 	char		*beName = NULL;
469f169c0eaSGlenn Lagasse 	int		destroy_snaps = 0;
470f169c0eaSGlenn Lagasse 	int		force_unmount = 0;
471f169c0eaSGlenn Lagasse 	int		destroy_flags = 0;
472f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
473f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
474f169c0eaSGlenn Lagasse 
475f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "z|ii", &beName, &destroy_snaps,
476f169c0eaSGlenn Lagasse 	    &force_unmount)) {
477f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
478f169c0eaSGlenn Lagasse 	}
479f169c0eaSGlenn Lagasse 
480f169c0eaSGlenn Lagasse 	if (destroy_snaps == 1)
481f169c0eaSGlenn Lagasse 		destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
482f169c0eaSGlenn Lagasse 
483f169c0eaSGlenn Lagasse 	if (force_unmount == 1)
484f169c0eaSGlenn Lagasse 		destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
485f169c0eaSGlenn Lagasse 
486f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
487f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
488f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
489f169c0eaSGlenn Lagasse 	}
490f169c0eaSGlenn Lagasse 
491f169c0eaSGlenn Lagasse 	if (nvlist_add_uint16(beAttrs, BE_ATTR_DESTROY_FLAGS, destroy_flags)
492f169c0eaSGlenn Lagasse 	    != 0) {
493f169c0eaSGlenn Lagasse 		(void) printf("nvlist_add_uint16 failed for "
494f169c0eaSGlenn Lagasse 		    "BE_ATTR_DESTROY_FLAGS (%d).\n", destroy_flags);
495f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
496f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
497f169c0eaSGlenn Lagasse 	}
498f169c0eaSGlenn Lagasse 
499f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
500f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
501f169c0eaSGlenn Lagasse 	}
502f169c0eaSGlenn Lagasse 
503f169c0eaSGlenn Lagasse 	ret = be_destroy(beAttrs);
504f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
505f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
506f169c0eaSGlenn Lagasse }
507f169c0eaSGlenn Lagasse 
508f169c0eaSGlenn Lagasse /*
509f169c0eaSGlenn Lagasse  * Function:    beDestroySnapshot
510f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
511f169c0eaSGlenn Lagasse  *              to destroy a snapshot of a Boot Environment
512f169c0eaSGlenn Lagasse  * Parameters:
513f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
514f169c0eaSGlenn Lagasse  *     beName - The name of the BE to destroy
515f169c0eaSGlenn Lagasse  *     snapName - The name of the snapshot to destroy
516f169c0eaSGlenn Lagasse  *
517f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
518f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
519f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
520f169c0eaSGlenn Lagasse  * Scope:
521f169c0eaSGlenn Lagasse  *      Public
522f169c0eaSGlenn Lagasse  */
523f169c0eaSGlenn Lagasse /* ARGSUSED */
524f169c0eaSGlenn Lagasse PyObject *
525f169c0eaSGlenn Lagasse beDestroySnapshot(PyObject *self, PyObject *args)
526f169c0eaSGlenn Lagasse {
527f169c0eaSGlenn Lagasse 	char		*beName = NULL;
528f169c0eaSGlenn Lagasse 	char		*snapName = NULL;
529f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
530f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
531f169c0eaSGlenn Lagasse 
532f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
533f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
534f169c0eaSGlenn Lagasse 	}
535f169c0eaSGlenn Lagasse 
536f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 4,
537f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, beName,
538f169c0eaSGlenn Lagasse 	    BE_ATTR_SNAP_NAME, snapName)) {
539f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
540f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
541f169c0eaSGlenn Lagasse 	}
542f169c0eaSGlenn Lagasse 
543f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
544f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
545f169c0eaSGlenn Lagasse 	}
546f169c0eaSGlenn Lagasse 
547f169c0eaSGlenn Lagasse 	ret = be_destroy_snapshot(beAttrs);
548f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
549f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
550f169c0eaSGlenn Lagasse }
551f169c0eaSGlenn Lagasse 
552f169c0eaSGlenn Lagasse /*
553f169c0eaSGlenn Lagasse  * Function:    beRename
554f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_rename
555f169c0eaSGlenn Lagasse  *              to rename a Boot Environment
556f169c0eaSGlenn Lagasse  * Parameters:
557f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
558f169c0eaSGlenn Lagasse  *     oldBeName - The name of the old Boot Environment
559f169c0eaSGlenn Lagasse  *     newBeName - The name of the new Boot Environment
560f169c0eaSGlenn Lagasse  *
561f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
562f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
563f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
564f169c0eaSGlenn Lagasse  * Scope:
565f169c0eaSGlenn Lagasse  *      Public
566f169c0eaSGlenn Lagasse  */
567f169c0eaSGlenn Lagasse /* ARGSUSED */
568f169c0eaSGlenn Lagasse PyObject *
569f169c0eaSGlenn Lagasse beRename(PyObject *self, PyObject *args)
570f169c0eaSGlenn Lagasse {
571f169c0eaSGlenn Lagasse 	char		*oldBeName = NULL;
572f169c0eaSGlenn Lagasse 	char		*newBeName = NULL;
573f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
574f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
575f169c0eaSGlenn Lagasse 
576f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "zz", &oldBeName, &newBeName)) {
577f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
578f169c0eaSGlenn Lagasse 	}
579f169c0eaSGlenn Lagasse 
580f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 4,
581f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, oldBeName,
582f169c0eaSGlenn Lagasse 	    BE_ATTR_NEW_BE_NAME, newBeName)) {
583f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
584f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
585f169c0eaSGlenn Lagasse 	}
586f169c0eaSGlenn Lagasse 
587f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
588f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
589f169c0eaSGlenn Lagasse 	}
590f169c0eaSGlenn Lagasse 
591f169c0eaSGlenn Lagasse 	ret = be_rename(beAttrs);
592f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
593f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
594f169c0eaSGlenn Lagasse }
595f169c0eaSGlenn Lagasse 
596f169c0eaSGlenn Lagasse /*
597f169c0eaSGlenn Lagasse  * Function:    beMount
598f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_mount
599f169c0eaSGlenn Lagasse  *              to mount a Boot Environment
600f169c0eaSGlenn Lagasse  * Parameters:
601f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
602f169c0eaSGlenn Lagasse  *     beName - The name of the Boot Environment to mount
603f169c0eaSGlenn Lagasse  *     mountpoint - The path of the mountpoint to mount the
604f169c0eaSGlenn Lagasse  *                  Boot Environment on (optional)
605f169c0eaSGlenn Lagasse  *
606f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
607f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
608f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
609f169c0eaSGlenn Lagasse  * Scope:
610f169c0eaSGlenn Lagasse  *      Public
611f169c0eaSGlenn Lagasse  */
612f169c0eaSGlenn Lagasse /* ARGSUSED */
613f169c0eaSGlenn Lagasse PyObject *
614f169c0eaSGlenn Lagasse beMount(PyObject *self, PyObject *args)
615f169c0eaSGlenn Lagasse {
616f169c0eaSGlenn Lagasse 	char		*beName = NULL;
617f169c0eaSGlenn Lagasse 	char		*mountpoint = NULL;
618f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
619f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
620f169c0eaSGlenn Lagasse 
621f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "zz", &beName, &mountpoint)) {
622f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
623f169c0eaSGlenn Lagasse 	}
624f169c0eaSGlenn Lagasse 
625f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 4,
626f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, beName,
627f169c0eaSGlenn Lagasse 	    BE_ATTR_MOUNTPOINT, mountpoint)) {
628f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
629f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
630f169c0eaSGlenn Lagasse 	}
631f169c0eaSGlenn Lagasse 
632f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
633f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
634f169c0eaSGlenn Lagasse 	}
635f169c0eaSGlenn Lagasse 
636f169c0eaSGlenn Lagasse 	ret = be_mount(beAttrs);
637f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
638f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
639f169c0eaSGlenn Lagasse }
640f169c0eaSGlenn Lagasse 
641f169c0eaSGlenn Lagasse /*
642f169c0eaSGlenn Lagasse  * Function:    beUnmount
643f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_unmount
644f169c0eaSGlenn Lagasse  *              to unmount a Boot Environment
645f169c0eaSGlenn Lagasse  * Parameters:
646f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
647f169c0eaSGlenn Lagasse  *     beName - The name of the Boot Environment to unmount
648f169c0eaSGlenn Lagasse  *
649f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
650f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
651f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
652f169c0eaSGlenn Lagasse  * Scope:
653f169c0eaSGlenn Lagasse  *      Public
654f169c0eaSGlenn Lagasse  */
655f169c0eaSGlenn Lagasse /* ARGSUSED */
656f169c0eaSGlenn Lagasse PyObject *
657f169c0eaSGlenn Lagasse beUnmount(PyObject *self, PyObject *args)
658f169c0eaSGlenn Lagasse {
659f169c0eaSGlenn Lagasse 	char		*beName = NULL;
660f169c0eaSGlenn Lagasse 	int		force_unmount = 0;
661f169c0eaSGlenn Lagasse 	int		unmount_flags = 0;
662f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
663f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
664f169c0eaSGlenn Lagasse 
665f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "z|i", &beName, &force_unmount)) {
666f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
667f169c0eaSGlenn Lagasse 	}
668f169c0eaSGlenn Lagasse 
669f169c0eaSGlenn Lagasse 	if (force_unmount == 1)
670f169c0eaSGlenn Lagasse 		unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
671f169c0eaSGlenn Lagasse 
672f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 2,
673f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, beName)) {
674f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
675f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
676f169c0eaSGlenn Lagasse 	}
677f169c0eaSGlenn Lagasse 
678f169c0eaSGlenn Lagasse 	if (nvlist_add_uint16(beAttrs, BE_ATTR_UNMOUNT_FLAGS, unmount_flags)
679f169c0eaSGlenn Lagasse 	    != 0) {
680f169c0eaSGlenn Lagasse 		(void) printf("nvlist_add_uint16 failed for "
681f169c0eaSGlenn Lagasse 		    "BE_ATTR_UNMOUNT_FLAGS (%d).\n", unmount_flags);
682f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
683f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
684f169c0eaSGlenn Lagasse 	}
685f169c0eaSGlenn Lagasse 
686f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
687f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
688f169c0eaSGlenn Lagasse 	}
689f169c0eaSGlenn Lagasse 
690f169c0eaSGlenn Lagasse 	ret = be_unmount(beAttrs);
691f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
692f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
693f169c0eaSGlenn Lagasse }
694f169c0eaSGlenn Lagasse 
695f169c0eaSGlenn Lagasse /*
696f169c0eaSGlenn Lagasse  * Function:    beRollback
697f169c0eaSGlenn Lagasse  * Description: Convert Python args to nvlist pairs and call libbe:be_rollback
698f169c0eaSGlenn Lagasse  *              to rollback a Boot Environment to a previously taken
699f169c0eaSGlenn Lagasse  *               snapshot.
700f169c0eaSGlenn Lagasse  * Parameters:
701f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
702f169c0eaSGlenn Lagasse  *     beName - The name of the Boot Environment to unmount
703f169c0eaSGlenn Lagasse  *
704f169c0eaSGlenn Lagasse  * Returns a pointer to a python object:
705f169c0eaSGlenn Lagasse  *      BE_SUCCESS - Success
706f169c0eaSGlenn Lagasse  *      bePyErr or be_errno_t - Failure
707f169c0eaSGlenn Lagasse  * Scope:
708f169c0eaSGlenn Lagasse  *      Public
709f169c0eaSGlenn Lagasse  */
710f169c0eaSGlenn Lagasse /* ARGSUSED */
711f169c0eaSGlenn Lagasse PyObject *
712f169c0eaSGlenn Lagasse beRollback(PyObject *self, PyObject *args)
713f169c0eaSGlenn Lagasse {
714f169c0eaSGlenn Lagasse 	char		*beName = NULL;
715f169c0eaSGlenn Lagasse 	char		*snapName = NULL;
716f169c0eaSGlenn Lagasse 	int		ret = BE_PY_SUCCESS;
717f169c0eaSGlenn Lagasse 	nvlist_t	*beAttrs = NULL;
718f169c0eaSGlenn Lagasse 
719f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
720f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
721f169c0eaSGlenn Lagasse 	}
722f169c0eaSGlenn Lagasse 
723f169c0eaSGlenn Lagasse 	if (!convertPyArgsToNvlist(&beAttrs, 4,
724f169c0eaSGlenn Lagasse 	    BE_ATTR_ORIG_BE_NAME, beName,
725f169c0eaSGlenn Lagasse 	    BE_ATTR_SNAP_NAME, snapName)) {
726f169c0eaSGlenn Lagasse 		nvlist_free(beAttrs);
727f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
728f169c0eaSGlenn Lagasse 	}
729f169c0eaSGlenn Lagasse 
730f169c0eaSGlenn Lagasse 	if (beAttrs == NULL) {
731f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
732f169c0eaSGlenn Lagasse 	}
733f169c0eaSGlenn Lagasse 
734f169c0eaSGlenn Lagasse 	ret = be_rollback(beAttrs);
735f169c0eaSGlenn Lagasse 	nvlist_free(beAttrs);
736f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", ret));
737f169c0eaSGlenn Lagasse }
738f169c0eaSGlenn Lagasse 
739f169c0eaSGlenn Lagasse /*
740f169c0eaSGlenn Lagasse  * Function:    bePrintErrors
741f169c0eaSGlenn Lagasse  * Description: Convert Python args to boolean and call libbe_print_errors to
742f169c0eaSGlenn Lagasse  *			turn on/off error output for the library.
743f169c0eaSGlenn Lagasse  * Parameter:
744f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
745f169c0eaSGlenn Lagasse  *		print_errors - Boolean that turns library error
746f169c0eaSGlenn Lagasse  *			       printing on or off.
747f169c0eaSGlenn Lagasse  * Parameters:
748f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
749f169c0eaSGlenn Lagasse  *     0 - do not print errors - Python boolean "False"
750f169c0eaSGlenn Lagasse  *     1 - print errors - Python boolean "True"
751f169c0eaSGlenn Lagasse  *
752f169c0eaSGlenn Lagasse  * Returns 1 on missing or invalid argument, 0 otherwise
753f169c0eaSGlenn Lagasse  * Scope:
754f169c0eaSGlenn Lagasse  *      Public
755f169c0eaSGlenn Lagasse  */
756f169c0eaSGlenn Lagasse /* ARGSUSED */
757f169c0eaSGlenn Lagasse PyObject *
758f169c0eaSGlenn Lagasse bePrintErrors(PyObject *self, PyObject *args)
759f169c0eaSGlenn Lagasse {
760f169c0eaSGlenn Lagasse 	int		print_errors;
761f169c0eaSGlenn Lagasse 
762f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "i", &print_errors) ||
763f169c0eaSGlenn Lagasse 	    (print_errors != 1 && print_errors != 0))
764f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", BE_PY_ERR_PRINT_ERR));
765f169c0eaSGlenn Lagasse 	libbe_print_errors(print_errors == 1);
766f169c0eaSGlenn Lagasse 	return (Py_BuildValue("i", BE_PY_SUCCESS));
767f169c0eaSGlenn Lagasse }
768f169c0eaSGlenn Lagasse 
769f169c0eaSGlenn Lagasse /*
770f169c0eaSGlenn Lagasse  * Function:    beGetErrDesc
771f169c0eaSGlenn Lagasse  * Description: Convert Python args to an int and call be_err_to_str to
772f169c0eaSGlenn Lagasse  *			map an error code to an error string.
773f169c0eaSGlenn Lagasse  * Parameter:
774f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
775f169c0eaSGlenn Lagasse  *		errCode - value to map to an error string.
776f169c0eaSGlenn Lagasse  *
777f169c0eaSGlenn Lagasse  * Returns: error string or NULL
778f169c0eaSGlenn Lagasse  * Scope:
779f169c0eaSGlenn Lagasse  *      Public
780f169c0eaSGlenn Lagasse  */
781f169c0eaSGlenn Lagasse /* ARGSUSED */
782f169c0eaSGlenn Lagasse PyObject *
783f169c0eaSGlenn Lagasse beGetErrDesc(PyObject *self, PyObject *args)
784f169c0eaSGlenn Lagasse {
785f169c0eaSGlenn Lagasse 	int	errCode = 0;
786f169c0eaSGlenn Lagasse 	char	*beErrStr = NULL;
787f169c0eaSGlenn Lagasse 
788f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "i", &errCode)) {
789f169c0eaSGlenn Lagasse 		return (Py_BuildValue("s", NULL));
790f169c0eaSGlenn Lagasse 	}
791f169c0eaSGlenn Lagasse 
792f169c0eaSGlenn Lagasse 	/*
793f169c0eaSGlenn Lagasse 	 * First check libbe_py errors. If NULL is returned check error codes
794f169c0eaSGlenn Lagasse 	 * in libbe.
795f169c0eaSGlenn Lagasse 	 */
796f169c0eaSGlenn Lagasse 
797f169c0eaSGlenn Lagasse 	if ((beErrStr = beMapLibbePyErrorToString(errCode)) == NULL) {
798f169c0eaSGlenn Lagasse 		beErrStr = be_err_to_str(errCode);
799f169c0eaSGlenn Lagasse 	}
800f169c0eaSGlenn Lagasse 
801f169c0eaSGlenn Lagasse 	return (Py_BuildValue("s", beErrStr));
802f169c0eaSGlenn Lagasse }
803f169c0eaSGlenn Lagasse 
804f169c0eaSGlenn Lagasse /*
805f169c0eaSGlenn Lagasse  * Function:    beVerifyBEName
806f169c0eaSGlenn Lagasse  * Description: Call be_valid_be_name() to verify the BE name.
807f169c0eaSGlenn Lagasse  * Parameter:
808f169c0eaSGlenn Lagasse  *   args -     pointer to a python object containing:
809f169c0eaSGlenn Lagasse  *		string - value to map to a string.
810f169c0eaSGlenn Lagasse  *
811f169c0eaSGlenn Lagasse  * Returns:  0 for success or 1 for failure
812f169c0eaSGlenn Lagasse  * Scope:
813f169c0eaSGlenn Lagasse  *      Public
814f169c0eaSGlenn Lagasse  */
815f169c0eaSGlenn Lagasse /* ARGSUSED */
816f169c0eaSGlenn Lagasse PyObject *
817f169c0eaSGlenn Lagasse beVerifyBEName(PyObject *self, PyObject *args)
818f169c0eaSGlenn Lagasse {
819f169c0eaSGlenn Lagasse 	char	*string = NULL;
820f169c0eaSGlenn Lagasse 
821f169c0eaSGlenn Lagasse 	if (!PyArg_ParseTuple(args, "s", &string)) {
822f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", 1));
823f169c0eaSGlenn Lagasse 	}
824f169c0eaSGlenn Lagasse 
825f169c0eaSGlenn Lagasse 	if (be_valid_be_name(string)) {
826f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", 0));
827f169c0eaSGlenn Lagasse 	} else {
828f169c0eaSGlenn Lagasse 		return (Py_BuildValue("i", 1));
829f169c0eaSGlenn Lagasse 	}
830f169c0eaSGlenn Lagasse }
831f169c0eaSGlenn Lagasse 
832f169c0eaSGlenn Lagasse /* ~~~~~~~~~~~~~~~~~ */
833f169c0eaSGlenn Lagasse /* Private Functions */
834f169c0eaSGlenn Lagasse /* ~~~~~~~~~~~~~~~~~ */
835f169c0eaSGlenn Lagasse 
836f169c0eaSGlenn Lagasse static boolean_t
837f169c0eaSGlenn Lagasse convertBEInfoToDictionary(be_node_list_t *be, PyObject **listDict)
838f169c0eaSGlenn Lagasse {
839f169c0eaSGlenn Lagasse 	if (be->be_node_name != NULL) {
840f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_NAME,
841d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_node_name)) != 0) {
842f169c0eaSGlenn Lagasse 			return (B_FALSE);
843f169c0eaSGlenn Lagasse 		}
844f169c0eaSGlenn Lagasse 	}
845f169c0eaSGlenn Lagasse 
846f169c0eaSGlenn Lagasse 	if (be->be_rpool != NULL) {
847f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_POOL,
848d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_rpool)) != 0) {
849f169c0eaSGlenn Lagasse 			return (B_FALSE);
850f169c0eaSGlenn Lagasse 		}
851f169c0eaSGlenn Lagasse 	}
852f169c0eaSGlenn Lagasse 
853f169c0eaSGlenn Lagasse 	if (be->be_mntpt != NULL) {
854f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
855d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_mntpt)) != 0) {
856f169c0eaSGlenn Lagasse 			return (B_FALSE);
857f169c0eaSGlenn Lagasse 		}
858f169c0eaSGlenn Lagasse 	}
859f169c0eaSGlenn Lagasse 
860f169c0eaSGlenn Lagasse 	if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
861f169c0eaSGlenn Lagasse 	    (be->be_mounted ? Py_True : Py_False)) != 0) {
862f169c0eaSGlenn Lagasse 		return (B_FALSE);
863f169c0eaSGlenn Lagasse 	}
864f169c0eaSGlenn Lagasse 
865f169c0eaSGlenn Lagasse 	if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE,
866f169c0eaSGlenn Lagasse 	    (be->be_active ? Py_True : Py_False)) != 0) {
867f169c0eaSGlenn Lagasse 		return (B_FALSE);
868f169c0eaSGlenn Lagasse 	}
869f169c0eaSGlenn Lagasse 
870f169c0eaSGlenn Lagasse 	if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE_ON_BOOT,
871f169c0eaSGlenn Lagasse 	    (be->be_active_on_boot ? Py_True : Py_False)) != 0) {
872f169c0eaSGlenn Lagasse 		return (B_FALSE);
873f169c0eaSGlenn Lagasse 	}
874f169c0eaSGlenn Lagasse 
875a74909fdSAlexander Pyhalov 	if (PyDict_SetItemString(*listDict, BE_ATTR_GLOBAL_ACTIVE,
876a74909fdSAlexander Pyhalov 	    (be->be_global_active ? Py_True : Py_False)) != 0) {
877a74909fdSAlexander Pyhalov 		return (B_FALSE);
878a74909fdSAlexander Pyhalov 	}
879a74909fdSAlexander Pyhalov 
880f169c0eaSGlenn Lagasse 	if (be->be_space_used != 0) {
881f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
882f169c0eaSGlenn Lagasse 		    PyLong_FromUnsignedLongLong(be->be_space_used)) != 0) {
883f169c0eaSGlenn Lagasse 			return (B_FALSE);
884f169c0eaSGlenn Lagasse 		}
885f169c0eaSGlenn Lagasse 	}
886f169c0eaSGlenn Lagasse 
887f169c0eaSGlenn Lagasse 	if (be->be_root_ds != NULL) {
888f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_ROOT_DS,
889d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_root_ds)) != 0) {
890f169c0eaSGlenn Lagasse 			return (B_FALSE);
891f169c0eaSGlenn Lagasse 		}
892f169c0eaSGlenn Lagasse 	}
893f169c0eaSGlenn Lagasse 
894f169c0eaSGlenn Lagasse 	if (be->be_node_creation != NULL) {
895f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
896f169c0eaSGlenn Lagasse 		    PyLong_FromLong(be->be_node_creation)) != 0) {
897f169c0eaSGlenn Lagasse 			return (B_FALSE);
898f169c0eaSGlenn Lagasse 		}
899f169c0eaSGlenn Lagasse 	}
900f169c0eaSGlenn Lagasse 
901f169c0eaSGlenn Lagasse 	if (be->be_policy_type != NULL) {
902f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
903d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_policy_type)) != 0) {
904f169c0eaSGlenn Lagasse 			return (B_FALSE);
905f169c0eaSGlenn Lagasse 		}
906f169c0eaSGlenn Lagasse 	}
907f169c0eaSGlenn Lagasse 
908f169c0eaSGlenn Lagasse 	if (be->be_uuid_str != NULL) {
909f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_UUID_STR,
910d561bb99SAndy Fiddaman 		    PyUnicode_FromString(be->be_uuid_str)) != 0) {
911f169c0eaSGlenn Lagasse 			return (B_FALSE);
912f169c0eaSGlenn Lagasse 		}
913f169c0eaSGlenn Lagasse 	}
914f169c0eaSGlenn Lagasse 
915f169c0eaSGlenn Lagasse 	return (B_TRUE);
916f169c0eaSGlenn Lagasse }
917f169c0eaSGlenn Lagasse 
918f169c0eaSGlenn Lagasse static boolean_t
919f169c0eaSGlenn Lagasse convertDatasetInfoToDictionary(be_dataset_list_t *ds, PyObject **listDict)
920f169c0eaSGlenn Lagasse {
921f169c0eaSGlenn Lagasse 	if (ds->be_dataset_name != NULL) {
922f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
923d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ds->be_dataset_name)) != 0) {
924f169c0eaSGlenn Lagasse 			return (B_FALSE);
925f169c0eaSGlenn Lagasse 		}
926f169c0eaSGlenn Lagasse 	}
927f169c0eaSGlenn Lagasse 
928f169c0eaSGlenn Lagasse 	if (PyDict_SetItemString(*listDict, BE_ATTR_STATUS,
929f169c0eaSGlenn Lagasse 	    (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
930f169c0eaSGlenn Lagasse 			return (B_FALSE);
931f169c0eaSGlenn Lagasse 	}
932f169c0eaSGlenn Lagasse 
933f169c0eaSGlenn Lagasse 	if (ds->be_ds_mntpt != NULL) {
934f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
935d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ds->be_ds_mntpt)) != 0) {
936f169c0eaSGlenn Lagasse 			return (B_FALSE);
937f169c0eaSGlenn Lagasse 		}
938f169c0eaSGlenn Lagasse 	}
939f169c0eaSGlenn Lagasse 
940f169c0eaSGlenn Lagasse 	if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
941f169c0eaSGlenn Lagasse 	    (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
942f169c0eaSGlenn Lagasse 		return (B_FALSE);
943f169c0eaSGlenn Lagasse 	}
944f169c0eaSGlenn Lagasse 
945f169c0eaSGlenn Lagasse 	if (ds->be_ds_space_used != 0) {
946f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
947f169c0eaSGlenn Lagasse 		    PyLong_FromUnsignedLongLong(ds->be_ds_space_used))
948f169c0eaSGlenn Lagasse 		    != 0) {
949f169c0eaSGlenn Lagasse 			return (B_FALSE);
950f169c0eaSGlenn Lagasse 		}
951f169c0eaSGlenn Lagasse 	}
952f169c0eaSGlenn Lagasse 
953f169c0eaSGlenn Lagasse 	if (ds->be_dataset_name != 0) {
954f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
955d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ds->be_dataset_name)) != 0) {
956f169c0eaSGlenn Lagasse 			return (B_FALSE);
957f169c0eaSGlenn Lagasse 		}
958f169c0eaSGlenn Lagasse 	}
959f169c0eaSGlenn Lagasse 
960f169c0eaSGlenn Lagasse 	if (ds->be_ds_plcy_type != NULL) {
961f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
962d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ds->be_ds_plcy_type)) != 0) {
963f169c0eaSGlenn Lagasse 			return (B_FALSE);
964f169c0eaSGlenn Lagasse 		}
965f169c0eaSGlenn Lagasse 	}
966f169c0eaSGlenn Lagasse 
967f169c0eaSGlenn Lagasse 	if (ds->be_ds_creation != NULL) {
968f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
969f169c0eaSGlenn Lagasse 		    PyLong_FromLong(ds->be_ds_creation)) != 0) {
970f169c0eaSGlenn Lagasse 			return (B_FALSE);
971f169c0eaSGlenn Lagasse 		}
972f169c0eaSGlenn Lagasse 	}
973f169c0eaSGlenn Lagasse 
974f169c0eaSGlenn Lagasse 	return (B_TRUE);
975f169c0eaSGlenn Lagasse }
976f169c0eaSGlenn Lagasse 
977f169c0eaSGlenn Lagasse static boolean_t
978f169c0eaSGlenn Lagasse convertSnapshotInfoToDictionary(be_snapshot_list_t *ss, PyObject **listDict)
979f169c0eaSGlenn Lagasse {
980f169c0eaSGlenn Lagasse 	if (ss->be_snapshot_name != NULL) {
981f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_SNAP_NAME,
982d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ss->be_snapshot_name)) != 0) {
983f169c0eaSGlenn Lagasse 			return (B_FALSE);
984f169c0eaSGlenn Lagasse 		}
985f169c0eaSGlenn Lagasse 	}
986f169c0eaSGlenn Lagasse 
987f169c0eaSGlenn Lagasse 	if (ss->be_snapshot_creation != NULL) {
988f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
989f169c0eaSGlenn Lagasse 		    PyLong_FromLong(ss->be_snapshot_creation)) != 0) {
990f169c0eaSGlenn Lagasse 			return (B_FALSE);
991f169c0eaSGlenn Lagasse 		}
992f169c0eaSGlenn Lagasse 	}
993f169c0eaSGlenn Lagasse 
994f169c0eaSGlenn Lagasse 	if (ss->be_snapshot_type != NULL) {
995f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
996d561bb99SAndy Fiddaman 		    PyUnicode_FromString(ss->be_snapshot_type)) != 0) {
997f169c0eaSGlenn Lagasse 			return (B_FALSE);
998f169c0eaSGlenn Lagasse 		}
999f169c0eaSGlenn Lagasse 	}
1000f169c0eaSGlenn Lagasse 
1001f169c0eaSGlenn Lagasse 	if (ss->be_snapshot_space_used != 0) {
1002f169c0eaSGlenn Lagasse 		if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
1003f169c0eaSGlenn Lagasse 		    PyLong_FromUnsignedLongLong(ss->be_snapshot_space_used))
1004f169c0eaSGlenn Lagasse 		    != 0) {
1005f169c0eaSGlenn Lagasse 			return (B_FALSE);
1006f169c0eaSGlenn Lagasse 		}
1007f169c0eaSGlenn Lagasse 	}
1008f169c0eaSGlenn Lagasse 
1009f169c0eaSGlenn Lagasse 	return (B_TRUE);
1010f169c0eaSGlenn Lagasse }
1011f169c0eaSGlenn Lagasse 
1012f169c0eaSGlenn Lagasse /*
1013f169c0eaSGlenn Lagasse  * Convert string arguments to nvlist attributes
1014f169c0eaSGlenn Lagasse  */
1015f169c0eaSGlenn Lagasse 
1016f169c0eaSGlenn Lagasse static boolean_t
1017f169c0eaSGlenn Lagasse convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...)
1018f169c0eaSGlenn Lagasse {
1019f169c0eaSGlenn Lagasse 	char *pt, *pt2;
1020f169c0eaSGlenn Lagasse 	va_list ap;
1021f169c0eaSGlenn Lagasse 	int i;
1022f169c0eaSGlenn Lagasse 
1023f169c0eaSGlenn Lagasse 	if (*nvList == NULL) {
1024f169c0eaSGlenn Lagasse 		if (nvlist_alloc(nvList, NV_UNIQUE_NAME, 0) != 0) {
1025f169c0eaSGlenn Lagasse 			(void) printf("nvlist_alloc failed.\n");
1026f169c0eaSGlenn Lagasse 			return (B_FALSE);
1027f169c0eaSGlenn Lagasse 		}
1028f169c0eaSGlenn Lagasse 	}
1029f169c0eaSGlenn Lagasse 
1030f169c0eaSGlenn Lagasse 	va_start(ap, numArgs);
1031f169c0eaSGlenn Lagasse 
1032f169c0eaSGlenn Lagasse 	for (i = 0; i < numArgs; i += 2) {
1033f169c0eaSGlenn Lagasse 		if ((pt = va_arg(ap, char *)) == NULL ||
1034f169c0eaSGlenn Lagasse 		    (pt2 = va_arg(ap, char *)) == NULL) {
1035f169c0eaSGlenn Lagasse 			continue;
1036f169c0eaSGlenn Lagasse 		}
1037f169c0eaSGlenn Lagasse 		if (nvlist_add_string(*nvList, pt, pt2) != 0) {
1038f169c0eaSGlenn Lagasse 			(void) printf("nvlist_add_string failed for %s (%s).\n",
1039f169c0eaSGlenn Lagasse 			    pt, pt2);
1040f169c0eaSGlenn Lagasse 			nvlist_free(*nvList);
1041f169c0eaSGlenn Lagasse 			return (B_FALSE);
1042f169c0eaSGlenn Lagasse 		}
1043f169c0eaSGlenn Lagasse 	}
1044f169c0eaSGlenn Lagasse 
1045f169c0eaSGlenn Lagasse 	va_end(ap);
1046f169c0eaSGlenn Lagasse 
1047f169c0eaSGlenn Lagasse 	return (B_TRUE);
1048f169c0eaSGlenn Lagasse }
1049f169c0eaSGlenn Lagasse 
1050f169c0eaSGlenn Lagasse /*
1051f169c0eaSGlenn Lagasse  * Function:    beMapLibbePyErrorToString
1052f169c0eaSGlenn Lagasse  * Description: Convert Python args to an int and map an error code to an
1053f169c0eaSGlenn Lagasse  *			error string.
1054f169c0eaSGlenn Lagasse  * Parameter:
1055f169c0eaSGlenn Lagasse  *		errCode - value to map to an error string.
1056f169c0eaSGlenn Lagasse  *
1057f169c0eaSGlenn Lagasse  * Returns error string or NULL
1058f169c0eaSGlenn Lagasse  * Scope:
1059f169c0eaSGlenn Lagasse  *      Public
1060f169c0eaSGlenn Lagasse  */
1061f169c0eaSGlenn Lagasse 
1062f169c0eaSGlenn Lagasse char *
1063f169c0eaSGlenn Lagasse beMapLibbePyErrorToString(int errCode)
1064f169c0eaSGlenn Lagasse {
1065f169c0eaSGlenn Lagasse 	switch (errCode) {
1066f169c0eaSGlenn Lagasse 	case BE_PY_ERR_APPEND:
1067f169c0eaSGlenn Lagasse 		return ("Unable to append a dictionary to a list "
1068f169c0eaSGlenn Lagasse 		    "of dictinaries.");
1069f169c0eaSGlenn Lagasse 	case BE_PY_ERR_DICT:
1070f169c0eaSGlenn Lagasse 		return ("Creation of a Python dictionary failed.");
1071f169c0eaSGlenn Lagasse 	case BE_PY_ERR_LIST:
1072f169c0eaSGlenn Lagasse 		return ("beList() failed.");
1073f169c0eaSGlenn Lagasse 	case BE_PY_ERR_NVLIST:
1074f169c0eaSGlenn Lagasse 		return ("An nvlist operation failed.");
1075f169c0eaSGlenn Lagasse 	case BE_PY_ERR_PARSETUPLE:
1076f169c0eaSGlenn Lagasse 		return ("PyArg_ParseTuple() failed to convert variable to C.");
1077f169c0eaSGlenn Lagasse 	case BE_PY_ERR_PRINT_ERR:
1078f169c0eaSGlenn Lagasse 		return ("bePrintErrors() failed.");
1079f169c0eaSGlenn Lagasse 	case BE_PY_ERR_VAR_CONV:
1080f169c0eaSGlenn Lagasse 		return ("Unable to add variables to a Python dictionary.");
1081f169c0eaSGlenn Lagasse 	default:
1082f169c0eaSGlenn Lagasse 		return (NULL);
1083f169c0eaSGlenn Lagasse 	}
1084f169c0eaSGlenn Lagasse }
1085f169c0eaSGlenn Lagasse 
1086f169c0eaSGlenn Lagasse /* Private python initialization structure */
1087f169c0eaSGlenn Lagasse 
1088f169c0eaSGlenn Lagasse static struct PyMethodDef libbeMethods[] = {
1089f169c0eaSGlenn Lagasse 	{"beCopy", (PyCFunction)beCopy, METH_VARARGS, "Create/Copy a BE."},
1090f169c0eaSGlenn Lagasse 	{"beCreateSnapshot", (PyCFunction)beCreateSnapshot, METH_VARARGS,
1091f169c0eaSGlenn Lagasse 	    "Create a snapshot."},
1092f169c0eaSGlenn Lagasse 	{"beDestroy", (PyCFunction)beDestroy, METH_VARARGS, "Destroy a BE."},
1093f169c0eaSGlenn Lagasse 	{"beDestroySnapshot", (PyCFunction)beDestroySnapshot, METH_VARARGS,
1094f169c0eaSGlenn Lagasse 	    "Destroy a snapshot."},
1095f169c0eaSGlenn Lagasse 	{"beMount", (PyCFunction)beMount, METH_VARARGS, "Mount a BE."},
1096f169c0eaSGlenn Lagasse 	{"beUnmount", (PyCFunction)beUnmount, METH_VARARGS, "Unmount a BE."},
109771668a2fSAndy Fiddaman 	{"beList", (PyCFunction)beList, METH_VARARGS | METH_KEYWORDS,
109871668a2fSAndy Fiddaman 	    "List BE info."},
1099f169c0eaSGlenn Lagasse 	{"beRename", (PyCFunction)beRename, METH_VARARGS, "Rename a BE."},
1100f169c0eaSGlenn Lagasse 	{"beActivate", (PyCFunction)beActivate, METH_VARARGS, "Activate a BE."},
1101f169c0eaSGlenn Lagasse 	{"beRollback", (PyCFunction)beRollback, METH_VARARGS, "Rollback a BE."},
1102f169c0eaSGlenn Lagasse 	{"bePrintErrors", (PyCFunction)bePrintErrors, METH_VARARGS,
1103f169c0eaSGlenn Lagasse 	    "Enable/disable error printing."},
1104f169c0eaSGlenn Lagasse 	{"beGetErrDesc", (PyCFunction)beGetErrDesc, METH_VARARGS,
1105f169c0eaSGlenn Lagasse 	    "Map Error codes to strings."},
1106f169c0eaSGlenn Lagasse 	{"beVerifyBEName", (PyCFunction)beVerifyBEName, METH_VARARGS,
1107f169c0eaSGlenn Lagasse 	    "Verify BE name."},
1108f169c0eaSGlenn Lagasse 	{NULL, NULL, 0, NULL}
1109f169c0eaSGlenn Lagasse };
1110f169c0eaSGlenn Lagasse 
1111d561bb99SAndy Fiddaman #if PY_MAJOR_VERSION >= 3
1112d561bb99SAndy Fiddaman static struct PyModuleDef libbe_module = {
1113d561bb99SAndy Fiddaman 	PyModuleDef_HEAD_INIT,
1114d561bb99SAndy Fiddaman 	"libbe_py",
1115d561bb99SAndy Fiddaman 	NULL,
1116d561bb99SAndy Fiddaman 	-1,
1117d561bb99SAndy Fiddaman 	libbeMethods
1118d561bb99SAndy Fiddaman };
1119d561bb99SAndy Fiddaman #endif
1120d561bb99SAndy Fiddaman 
1121d561bb99SAndy Fiddaman static PyObject *
1122d561bb99SAndy Fiddaman moduleinit()
1123f169c0eaSGlenn Lagasse {
1124f169c0eaSGlenn Lagasse 	/* PyMODINIT_FUNC; */
1125d561bb99SAndy Fiddaman #if PY_MAJOR_VERSION >= 3
1126d561bb99SAndy Fiddaman 	return (PyModule_Create(&libbe_module));
1127d561bb99SAndy Fiddaman #else
1128d561bb99SAndy Fiddaman 	/*
1129d561bb99SAndy Fiddaman 	 * Python2 module initialisation functions are void and may not return
1130d561bb99SAndy Fiddaman 	 * a value. However, they will set an exception if appropriate.
1131d561bb99SAndy Fiddaman 	 */
1132f169c0eaSGlenn Lagasse 	(void) Py_InitModule("libbe_py", libbeMethods);
1133d561bb99SAndy Fiddaman 	return (NULL);
1134d561bb99SAndy Fiddaman #endif
1135f169c0eaSGlenn Lagasse }
1136d561bb99SAndy Fiddaman 
1137d561bb99SAndy Fiddaman #if PY_MAJOR_VERSION >= 3
1138d561bb99SAndy Fiddaman PyMODINIT_FUNC
1139d561bb99SAndy Fiddaman PyInit_libbe_py(void)
1140d561bb99SAndy Fiddaman {
1141d561bb99SAndy Fiddaman 	return (moduleinit());
1142d561bb99SAndy Fiddaman }
1143d561bb99SAndy Fiddaman #else
1144d561bb99SAndy Fiddaman PyMODINIT_FUNC
1145d561bb99SAndy Fiddaman initlibbe_py(void)
1146d561bb99SAndy Fiddaman {
1147d561bb99SAndy Fiddaman 	(void) moduleinit();
1148d561bb99SAndy Fiddaman }
1149d561bb99SAndy Fiddaman #endif
1150