PSARC 2010/059 SNAP BE Management
[illumos-gate.git] / usr / src / lib / pylibbe / common / libbe_py.c
blobb4f6ca0e524091cdc0420b4cbbf75ef51f37ebd4
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <Python.h>
27 #include <sys/varargs.h>
28 #include <stdio.h>
29 #include <libnvpair.h>
31 #include <libbe.h>
32 #include <libbe_priv.h>
34 enum {
35 BE_PY_SUCCESS = 0,
36 BE_PY_ERR_APPEND = 6000,
37 BE_PY_ERR_DICT,
38 BE_PY_ERR_LIST,
39 BE_PY_ERR_NVLIST,
40 BE_PY_ERR_PARSETUPLE,
41 BE_PY_ERR_PRINT_ERR,
42 BE_PY_ERR_VAR_CONV,
43 } bePyErr;
46 * public libbe functions
49 PyObject *beCreateSnapshot(PyObject *, PyObject *);
50 PyObject *beCopy(PyObject *, PyObject *);
51 PyObject *beList(PyObject *, PyObject *);
52 PyObject *beActivate(PyObject *, PyObject *);
53 PyObject *beDestroy(PyObject *, PyObject *);
54 PyObject *beDestroySnapshot(PyObject *, PyObject *);
55 PyObject *beRename(PyObject *, PyObject *);
56 PyObject *beMount(PyObject *, PyObject *);
57 PyObject *beUnmount(PyObject *, PyObject *);
58 PyObject *bePrintErrors(PyObject *, PyObject *);
59 PyObject *beGetErrDesc(PyObject *, PyObject *);
60 char *beMapLibbePyErrorToString(int);
61 void initlibbe_py();
63 static boolean_t convertBEInfoToDictionary(be_node_list_t *be,
64 PyObject **listDict);
65 static boolean_t convertDatasetInfoToDictionary(be_dataset_list_t *ds,
66 PyObject **listDict);
67 static boolean_t convertSnapshotInfoToDictionary(be_snapshot_list_t *ss,
68 PyObject **listDict);
69 static boolean_t convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...);
72 /* ~~~~~~~~~~~~~~~ */
73 /* Public Funtions */
74 /* ~~~~~~~~~~~~~~~ */
77 * Function: beCreateSnapshot
78 * Description: Convert Python args to nvlist pairs and
79 * call libbe:be_create_snapshot to create a
80 * snapshot of all the datasets within a BE
81 * Parameters:
82 * args - pointer to a python object containing:
83 * beName - The name of the BE to create a snapshot of
84 * snapName - The name of the snapshot to create (optional)
86 * The following public attribute values. defined by libbe.h,
87 * are used by this function:
89 * Returns a pointer to a python object and an optional snapshot name:
90 * 0, [snapName] - Success
91 * 1, [snapName] - Failure
92 * Scope:
93 * Public
95 /* ARGSUSED */
96 PyObject *
97 beCreateSnapshot(PyObject *self, PyObject *args)
99 char *beName = NULL;
100 char *snapName = NULL;
101 int ret = BE_PY_SUCCESS;
102 nvlist_t *beAttrs = NULL;
103 PyObject *retVals = NULL;
105 if (!PyArg_ParseTuple(args, "z|z", &beName, &snapName)) {
106 return (Py_BuildValue("[is]", BE_PY_ERR_PARSETUPLE, NULL));
109 if (!convertPyArgsToNvlist(&beAttrs, 4,
110 BE_ATTR_ORIG_BE_NAME, beName,
111 BE_ATTR_SNAP_NAME, snapName)) {
112 nvlist_free(beAttrs);
113 return (Py_BuildValue("[is]", BE_PY_ERR_NVLIST, NULL));
116 if (beAttrs == NULL) {
117 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
120 if ((ret = be_create_snapshot(beAttrs)) != 0) {
121 nvlist_free(beAttrs);
122 return (Py_BuildValue("[is]", ret, NULL));
124 if (snapName == NULL) {
125 if (nvlist_lookup_pairs(beAttrs, NV_FLAG_NOENTOK,
126 BE_ATTR_SNAP_NAME, DATA_TYPE_STRING, &snapName,
127 NULL) != 0) {
128 nvlist_free(beAttrs);
129 return (Py_BuildValue("[is]",
130 BE_PY_ERR_NVLIST, NULL));
132 retVals = Py_BuildValue("[is]", ret, snapName);
133 nvlist_free(beAttrs);
134 return (retVals);
136 nvlist_free(beAttrs);
138 return (Py_BuildValue("[is]", ret, NULL));
142 * Function: beCopy
143 * Description: Convert Python args to nvlist pairs and call libbe:be_copy
144 * to create a Boot Environment
145 * Parameters:
146 * args - pointer to a python object containing:
147 * trgtBeName - The name of the BE to create
148 * srcBeName - The name of the BE used to create trgtBeName (optional)
149 * rpool - The pool to create the new BE in (optional)
150 * srcSnapName - The snapshot name (optional)
151 * beNameProperties - The properties to use when creating
152 * the BE (optional)
154 * Returns a pointer to a python object. That Python object will consist of
155 * the return code and optional attributes, trgtBeName and snapshotName
156 * BE_SUCCESS, [trgtBeName], [trgtSnapName] - Success
157 * 1, [trgtBeName], [trgtSnapName] - Failure
158 * Scope:
159 * Public
161 /* ARGSUSED */
162 PyObject *
163 beCopy(PyObject *self, PyObject *args)
165 char *trgtBeName = NULL;
166 char *srcBeName = NULL;
167 char *srcSnapName = NULL;
168 char *trgtSnapName = NULL;
169 char *rpool = NULL;
170 char *beDescription = NULL;
171 int pos = 0;
172 int ret = BE_PY_SUCCESS;
173 nvlist_t *beAttrs = NULL;
174 nvlist_t *beProps = NULL;
175 PyObject *beNameProperties = NULL;
176 PyObject *pkey = NULL;
177 PyObject *pvalue = NULL;
178 PyObject *retVals = NULL;
180 if (!PyArg_ParseTuple(args, "|zzzzOz", &trgtBeName, &srcBeName,
181 &srcSnapName, &rpool, &beNameProperties, &beDescription)) {
182 return (Py_BuildValue("[iss]", BE_PY_ERR_PARSETUPLE,
183 NULL, NULL));
186 if (!convertPyArgsToNvlist(&beAttrs, 10,
187 BE_ATTR_NEW_BE_NAME, trgtBeName,
188 BE_ATTR_ORIG_BE_NAME, srcBeName,
189 BE_ATTR_SNAP_NAME, srcSnapName,
190 BE_ATTR_NEW_BE_POOL, rpool,
191 BE_ATTR_NEW_BE_DESC, beDescription)) {
192 nvlist_free(beAttrs);
193 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST, NULL, NULL));
196 if (beNameProperties != NULL) {
197 if (nvlist_alloc(&beProps, NV_UNIQUE_NAME, 0) != 0) {
198 (void) printf("nvlist_alloc failed.\n");
199 nvlist_free(beAttrs);
200 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
201 NULL, NULL));
203 while (PyDict_Next(beNameProperties, &pos, &pkey, &pvalue)) {
204 if (!convertPyArgsToNvlist(&beProps, 2,
205 PyString_AsString(pkey),
206 PyString_AsString(pvalue))) {
207 nvlist_free(beProps);
208 nvlist_free(beAttrs);
209 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
210 NULL, NULL));
215 if (beProps != NULL && beAttrs != NULL &&
216 nvlist_add_nvlist(beAttrs, BE_ATTR_ZFS_PROPERTIES,
217 beProps) != 0) {
218 nvlist_free(beProps);
219 nvlist_free(beAttrs);
220 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
221 NULL, NULL));
224 if (beProps != NULL) nvlist_free(beProps);
226 if (trgtBeName == NULL) {
228 * Caller wants to get back the BE_ATTR_NEW_BE_NAME and
229 * BE_ATTR_SNAP_NAME
231 if ((ret = be_copy(beAttrs)) != BE_SUCCESS) {
232 nvlist_free(beAttrs);
233 return (Py_BuildValue("[iss]", ret, NULL, NULL));
237 * When no trgtBeName is passed to be_copy, be_copy
238 * returns an auto generated beName and snapshot name.
240 if (nvlist_lookup_string(beAttrs, BE_ATTR_NEW_BE_NAME,
241 &trgtBeName) != 0) {
242 nvlist_free(beAttrs);
243 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
244 NULL, NULL));
246 if (nvlist_lookup_string(beAttrs, BE_ATTR_SNAP_NAME,
247 &trgtSnapName) != 0) {
248 nvlist_free(beAttrs);
249 return (Py_BuildValue("[iss]", BE_PY_ERR_NVLIST,
250 NULL, NULL));
253 retVals = Py_BuildValue("[iss]", BE_PY_SUCCESS,
254 trgtBeName, trgtSnapName);
255 nvlist_free(beAttrs);
256 return (retVals);
258 } else {
259 ret = be_copy(beAttrs);
260 nvlist_free(beAttrs);
261 return (Py_BuildValue("[iss]", ret, NULL, NULL));
266 * Function: beList
267 * Description: Convert Python args to nvlist pairs and call libbe:be_list
268 * to gather information about Boot Environments
269 * Parameters:
270 * args - pointer to a python object containing:
271 * beName - The name of the BE to list (optional)
273 * Returns a pointer to a python object. That Python object will consist of
274 * the return code and a list of Dicts or NULL.
275 * BE_PY_SUCCESS, listOfDicts - Success
276 * bePyErr or be_errno_t, NULL - Failure
277 * Scope:
278 * Public
280 /* ARGSUSED */
281 PyObject *
282 beList(PyObject *self, PyObject *args)
284 char *beName = NULL;
285 int ret = BE_PY_SUCCESS;
286 be_node_list_t *list = NULL;
287 be_node_list_t *be = NULL;
288 PyObject *dict = NULL;
289 PyObject *listOfDicts = NULL;
291 if ((listOfDicts = PyList_New(0)) == NULL) {
292 ret = BE_PY_ERR_DICT;
293 listOfDicts = Py_None;
294 goto done;
297 if (!PyArg_ParseTuple(args, "|z", &beName)) {
298 ret = BE_PY_ERR_PARSETUPLE;
299 goto done;
302 if ((ret = be_list(beName, &list)) != BE_SUCCESS) {
303 goto done;
306 for (be = list; be != NULL; be = be->be_next_node) {
307 be_dataset_list_t *ds = be->be_node_datasets;
308 be_snapshot_list_t *ss = be->be_node_snapshots;
310 if ((dict = PyDict_New()) == NULL) {
311 ret = BE_PY_ERR_DICT;
312 goto done;
315 if (!convertBEInfoToDictionary(be, &dict)) {
316 /* LINTED */
317 Py_DECREF(dict);
318 ret = BE_PY_ERR_VAR_CONV;
319 goto done;
322 if (PyList_Append(listOfDicts, dict) != 0) {
323 /* LINTED */
324 Py_DECREF(dict);
325 ret = BE_PY_ERR_APPEND;
326 goto done;
329 /* LINTED */
330 Py_DECREF(dict);
332 while (ds != NULL) {
333 if ((dict = PyDict_New()) == NULL) {
334 ret = BE_PY_ERR_DICT;
335 goto done;
338 if (!convertDatasetInfoToDictionary(ds, &dict)) {
339 /* LINTED */
340 Py_DECREF(dict);
341 ret = BE_PY_ERR_VAR_CONV;
342 goto done;
345 if (PyList_Append(listOfDicts, dict) != 0) {
346 /* LINTED */
347 Py_DECREF(dict);
348 ret = BE_PY_ERR_APPEND;
349 goto done;
352 ds = ds->be_next_dataset;
354 /* LINTED */
355 Py_DECREF(dict);
359 while (ss != NULL) {
360 if ((dict = PyDict_New()) == NULL) {
361 /* LINTED */
362 Py_DECREF(dict);
363 ret = BE_PY_ERR_DICT;
364 goto done;
367 if (!convertSnapshotInfoToDictionary(ss, &dict)) {
368 /* LINTED */
369 Py_DECREF(dict);
370 ret = BE_PY_ERR_VAR_CONV;
371 goto done;
374 if (PyList_Append(listOfDicts, dict) != 0) {
375 /* LINTED */
376 Py_DECREF(dict);
377 ret = BE_PY_ERR_APPEND;
378 goto done;
381 ss = ss->be_next_snapshot;
383 /* LINTED */
384 Py_DECREF(dict);
388 done:
389 if (list != NULL)
390 be_free_list(list);
391 return (Py_BuildValue("[iO]", ret, listOfDicts));
395 * Function: beActivate
396 * Description: Convert Python args to nvlist pairs and call libbe:be_activate
397 * to activate a Boot Environment
398 * Parameters:
399 * args - pointer to a python object containing:
400 * beName - The name of the BE to activate
402 * Returns a pointer to a python object:
403 * BE_SUCCESS - Success
404 * bePyErr or be_errno_t - Failure
405 * Scope:
406 * Public
408 /* ARGSUSED */
409 PyObject *
410 beActivate(PyObject *self, PyObject *args)
412 char *beName = NULL;
413 int ret = BE_PY_SUCCESS;
414 nvlist_t *beAttrs = NULL;
416 if (!PyArg_ParseTuple(args, "z", &beName)) {
417 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
420 if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
421 nvlist_free(beAttrs);
422 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
425 if (beAttrs == NULL) {
426 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
429 ret = be_activate(beAttrs);
430 nvlist_free(beAttrs);
431 return (Py_BuildValue("i", ret));
435 * Function: beDestroy
436 * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
437 * to destroy a Boot Environment
438 * Parameters:
439 * args - pointer to a python object containing:
440 * beName - The name of the BE to destroy
442 * Returns a pointer to a python object:
443 * BE_SUCCESS - Success
444 * bePyErr or be_errno_t - Failure
445 * Scope:
446 * Public
448 /* ARGSUSED */
449 PyObject *
450 beDestroy(PyObject *self, PyObject *args)
452 char *beName = NULL;
453 int destroy_snaps = 0;
454 int force_unmount = 0;
455 int destroy_flags = 0;
456 int ret = BE_PY_SUCCESS;
457 nvlist_t *beAttrs = NULL;
459 if (!PyArg_ParseTuple(args, "z|ii", &beName, &destroy_snaps,
460 &force_unmount)) {
461 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
464 if (destroy_snaps == 1)
465 destroy_flags |= BE_DESTROY_FLAG_SNAPSHOTS;
467 if (force_unmount == 1)
468 destroy_flags |= BE_DESTROY_FLAG_FORCE_UNMOUNT;
470 if (!convertPyArgsToNvlist(&beAttrs, 2, BE_ATTR_ORIG_BE_NAME, beName)) {
471 nvlist_free(beAttrs);
472 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
475 if (nvlist_add_uint16(beAttrs, BE_ATTR_DESTROY_FLAGS, destroy_flags)
476 != 0) {
477 (void) printf("nvlist_add_uint16 failed for "
478 "BE_ATTR_DESTROY_FLAGS (%d).\n", destroy_flags);
479 nvlist_free(beAttrs);
480 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
483 if (beAttrs == NULL) {
484 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
487 ret = be_destroy(beAttrs);
488 nvlist_free(beAttrs);
489 return (Py_BuildValue("i", ret));
493 * Function: beDestroySnapshot
494 * Description: Convert Python args to nvlist pairs and call libbe:be_destroy
495 * to destroy a snapshot of a Boot Environment
496 * Parameters:
497 * args - pointer to a python object containing:
498 * beName - The name of the BE to destroy
499 * snapName - The name of the snapshot to destroy
501 * Returns a pointer to a python object:
502 * BE_SUCCESS - Success
503 * bePyErr or be_errno_t - Failure
504 * Scope:
505 * Public
507 /* ARGSUSED */
508 PyObject *
509 beDestroySnapshot(PyObject *self, PyObject *args)
511 char *beName = NULL;
512 char *snapName = NULL;
513 int ret = BE_PY_SUCCESS;
514 nvlist_t *beAttrs = NULL;
516 if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
517 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
520 if (!convertPyArgsToNvlist(&beAttrs, 4,
521 BE_ATTR_ORIG_BE_NAME, beName,
522 BE_ATTR_SNAP_NAME, snapName)) {
523 nvlist_free(beAttrs);
524 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
527 if (beAttrs == NULL) {
528 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
531 ret = be_destroy_snapshot(beAttrs);
532 nvlist_free(beAttrs);
533 return (Py_BuildValue("i", ret));
537 * Function: beRename
538 * Description: Convert Python args to nvlist pairs and call libbe:be_rename
539 * to rename a Boot Environment
540 * Parameters:
541 * args - pointer to a python object containing:
542 * oldBeName - The name of the old Boot Environment
543 * newBeName - The name of the new Boot Environment
545 * Returns a pointer to a python object:
546 * BE_SUCCESS - Success
547 * bePyErr or be_errno_t - Failure
548 * Scope:
549 * Public
551 /* ARGSUSED */
552 PyObject *
553 beRename(PyObject *self, PyObject *args)
555 char *oldBeName = NULL;
556 char *newBeName = NULL;
557 int ret = BE_PY_SUCCESS;
558 nvlist_t *beAttrs = NULL;
560 if (!PyArg_ParseTuple(args, "zz", &oldBeName, &newBeName)) {
561 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
564 if (!convertPyArgsToNvlist(&beAttrs, 4,
565 BE_ATTR_ORIG_BE_NAME, oldBeName,
566 BE_ATTR_NEW_BE_NAME, newBeName)) {
567 nvlist_free(beAttrs);
568 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
571 if (beAttrs == NULL) {
572 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
575 ret = be_rename(beAttrs);
576 nvlist_free(beAttrs);
577 return (Py_BuildValue("i", ret));
581 * Function: beMount
582 * Description: Convert Python args to nvlist pairs and call libbe:be_mount
583 * to mount a Boot Environment
584 * Parameters:
585 * args - pointer to a python object containing:
586 * beName - The name of the Boot Environment to mount
587 * mountpoint - The path of the mountpoint to mount the
588 * Boot Environment on (optional)
590 * Returns a pointer to a python object:
591 * BE_SUCCESS - Success
592 * bePyErr or be_errno_t - Failure
593 * Scope:
594 * Public
596 /* ARGSUSED */
597 PyObject *
598 beMount(PyObject *self, PyObject *args)
600 char *beName = NULL;
601 char *mountpoint = NULL;
602 int ret = BE_PY_SUCCESS;
603 nvlist_t *beAttrs = NULL;
605 if (!PyArg_ParseTuple(args, "zz", &beName, &mountpoint)) {
606 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
609 if (!convertPyArgsToNvlist(&beAttrs, 4,
610 BE_ATTR_ORIG_BE_NAME, beName,
611 BE_ATTR_MOUNTPOINT, mountpoint)) {
612 nvlist_free(beAttrs);
613 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
616 if (beAttrs == NULL) {
617 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
620 ret = be_mount(beAttrs);
621 nvlist_free(beAttrs);
622 return (Py_BuildValue("i", ret));
626 * Function: beUnmount
627 * Description: Convert Python args to nvlist pairs and call libbe:be_unmount
628 * to unmount a Boot Environment
629 * Parameters:
630 * args - pointer to a python object containing:
631 * beName - The name of the Boot Environment to unmount
633 * Returns a pointer to a python object:
634 * BE_SUCCESS - Success
635 * bePyErr or be_errno_t - Failure
636 * Scope:
637 * Public
639 /* ARGSUSED */
640 PyObject *
641 beUnmount(PyObject *self, PyObject *args)
643 char *beName = NULL;
644 int force_unmount = 0;
645 int unmount_flags = 0;
646 int ret = BE_PY_SUCCESS;
647 nvlist_t *beAttrs = NULL;
649 if (!PyArg_ParseTuple(args, "z|i", &beName, &force_unmount)) {
650 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
653 if (force_unmount == 1)
654 unmount_flags |= BE_UNMOUNT_FLAG_FORCE;
656 if (!convertPyArgsToNvlist(&beAttrs, 2,
657 BE_ATTR_ORIG_BE_NAME, beName)) {
658 nvlist_free(beAttrs);
659 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
662 if (nvlist_add_uint16(beAttrs, BE_ATTR_UNMOUNT_FLAGS, unmount_flags)
663 != 0) {
664 (void) printf("nvlist_add_uint16 failed for "
665 "BE_ATTR_UNMOUNT_FLAGS (%d).\n", unmount_flags);
666 nvlist_free(beAttrs);
667 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
670 if (beAttrs == NULL) {
671 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
674 ret = be_unmount(beAttrs);
675 nvlist_free(beAttrs);
676 return (Py_BuildValue("i", ret));
680 * Function: beRollback
681 * Description: Convert Python args to nvlist pairs and call libbe:be_rollback
682 * to rollback a Boot Environment to a previously taken
683 * snapshot.
684 * Parameters:
685 * args - pointer to a python object containing:
686 * beName - The name of the Boot Environment to unmount
688 * Returns a pointer to a python object:
689 * BE_SUCCESS - Success
690 * bePyErr or be_errno_t - Failure
691 * Scope:
692 * Public
694 /* ARGSUSED */
695 PyObject *
696 beRollback(PyObject *self, PyObject *args)
698 char *beName = NULL;
699 char *snapName = NULL;
700 int ret = BE_PY_SUCCESS;
701 nvlist_t *beAttrs = NULL;
703 if (!PyArg_ParseTuple(args, "zz", &beName, &snapName)) {
704 return (Py_BuildValue("i", BE_PY_ERR_PARSETUPLE));
707 if (!convertPyArgsToNvlist(&beAttrs, 4,
708 BE_ATTR_ORIG_BE_NAME, beName,
709 BE_ATTR_SNAP_NAME, snapName)) {
710 nvlist_free(beAttrs);
711 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
714 if (beAttrs == NULL) {
715 return (Py_BuildValue("i", BE_PY_ERR_NVLIST));
718 ret = be_rollback(beAttrs);
719 nvlist_free(beAttrs);
720 return (Py_BuildValue("i", ret));
724 * Function: bePrintErrors
725 * Description: Convert Python args to boolean and call libbe_print_errors to
726 * turn on/off error output for the library.
727 * Parameter:
728 * args - pointer to a python object containing:
729 * print_errors - Boolean that turns library error
730 * printing on or off.
731 * Parameters:
732 * args - pointer to a python object containing:
733 * 0 - do not print errors - Python boolean "False"
734 * 1 - print errors - Python boolean "True"
736 * Returns 1 on missing or invalid argument, 0 otherwise
737 * Scope:
738 * Public
740 /* ARGSUSED */
741 PyObject *
742 bePrintErrors(PyObject *self, PyObject *args)
744 int print_errors;
746 if (!PyArg_ParseTuple(args, "i", &print_errors) ||
747 (print_errors != 1 && print_errors != 0))
748 return (Py_BuildValue("i", BE_PY_ERR_PRINT_ERR));
749 libbe_print_errors(print_errors == 1);
750 return (Py_BuildValue("i", BE_PY_SUCCESS));
754 * Function: beGetErrDesc
755 * Description: Convert Python args to an int and call be_err_to_str to
756 * map an error code to an error string.
757 * Parameter:
758 * args - pointer to a python object containing:
759 * errCode - value to map to an error string.
761 * Returns: error string or NULL
762 * Scope:
763 * Public
765 /* ARGSUSED */
766 PyObject *
767 beGetErrDesc(PyObject *self, PyObject *args)
769 int errCode = 0;
770 char *beErrStr = NULL;
772 if (!PyArg_ParseTuple(args, "i", &errCode)) {
773 return (Py_BuildValue("s", NULL));
777 * First check libbe_py errors. If NULL is returned check error codes
778 * in libbe.
781 if ((beErrStr = beMapLibbePyErrorToString(errCode)) == NULL) {
782 beErrStr = be_err_to_str(errCode);
785 return (Py_BuildValue("s", beErrStr));
789 * Function: beVerifyBEName
790 * Description: Call be_valid_be_name() to verify the BE name.
791 * Parameter:
792 * args - pointer to a python object containing:
793 * string - value to map to a string.
795 * Returns: 0 for success or 1 for failure
796 * Scope:
797 * Public
799 /* ARGSUSED */
800 PyObject *
801 beVerifyBEName(PyObject *self, PyObject *args)
803 char *string = NULL;
805 if (!PyArg_ParseTuple(args, "s", &string)) {
806 return (Py_BuildValue("i", 1));
809 if (be_valid_be_name(string)) {
810 return (Py_BuildValue("i", 0));
811 } else {
812 return (Py_BuildValue("i", 1));
816 /* ~~~~~~~~~~~~~~~~~ */
817 /* Private Functions */
818 /* ~~~~~~~~~~~~~~~~~ */
820 static boolean_t
821 convertBEInfoToDictionary(be_node_list_t *be, PyObject **listDict)
823 if (be->be_node_name != NULL) {
824 if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_NAME,
825 PyString_FromString(be->be_node_name)) != 0) {
826 return (B_FALSE);
830 if (be->be_rpool != NULL) {
831 if (PyDict_SetItemString(*listDict, BE_ATTR_ORIG_BE_POOL,
832 PyString_FromString(be->be_rpool)) != 0) {
833 return (B_FALSE);
837 if (be->be_mntpt != NULL) {
838 if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
839 PyString_FromString(be->be_mntpt)) != 0) {
840 return (B_FALSE);
844 if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
845 (be->be_mounted ? Py_True : Py_False)) != 0) {
846 return (B_FALSE);
849 if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE,
850 (be->be_active ? Py_True : Py_False)) != 0) {
851 return (B_FALSE);
854 if (PyDict_SetItemString(*listDict, BE_ATTR_ACTIVE_ON_BOOT,
855 (be->be_active_on_boot ? Py_True : Py_False)) != 0) {
856 return (B_FALSE);
859 if (be->be_space_used != 0) {
860 if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
861 PyLong_FromUnsignedLongLong(be->be_space_used)) != 0) {
862 return (B_FALSE);
866 if (be->be_root_ds != NULL) {
867 if (PyDict_SetItemString(*listDict, BE_ATTR_ROOT_DS,
868 PyString_FromString(be->be_root_ds)) != 0) {
869 return (B_FALSE);
873 if (be->be_node_creation != NULL) {
874 if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
875 PyLong_FromLong(be->be_node_creation)) != 0) {
876 return (B_FALSE);
880 if (be->be_policy_type != NULL) {
881 if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
882 PyString_FromString(be->be_policy_type)) != 0) {
883 return (B_FALSE);
887 if (be->be_uuid_str != NULL) {
888 if (PyDict_SetItemString(*listDict, BE_ATTR_UUID_STR,
889 PyString_FromString(be->be_uuid_str)) != 0) {
890 return (B_FALSE);
894 return (B_TRUE);
897 static boolean_t
898 convertDatasetInfoToDictionary(be_dataset_list_t *ds, PyObject **listDict)
900 if (ds->be_dataset_name != NULL) {
901 if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
902 PyString_FromString(ds->be_dataset_name)) != 0) {
903 return (B_FALSE);
907 if (PyDict_SetItemString(*listDict, BE_ATTR_STATUS,
908 (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
909 return (B_FALSE);
912 if (ds->be_ds_mntpt != NULL) {
913 if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTPOINT,
914 PyString_FromString(ds->be_ds_mntpt)) != 0) {
915 return (B_FALSE);
919 if (PyDict_SetItemString(*listDict, BE_ATTR_MOUNTED,
920 (ds->be_ds_mounted ? Py_True : Py_False)) != 0) {
921 return (B_FALSE);
924 if (ds->be_ds_space_used != 0) {
925 if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
926 PyLong_FromUnsignedLongLong(ds->be_ds_space_used))
927 != 0) {
928 return (B_FALSE);
932 if (ds->be_dataset_name != 0) {
933 if (PyDict_SetItemString(*listDict, BE_ATTR_DATASET,
934 PyString_FromString(ds->be_dataset_name)) != 0) {
935 return (B_FALSE);
939 if (ds->be_ds_plcy_type != NULL) {
940 if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
941 PyString_FromString(ds->be_ds_plcy_type)) != 0) {
942 return (B_FALSE);
946 if (ds->be_ds_creation != NULL) {
947 if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
948 PyLong_FromLong(ds->be_ds_creation)) != 0) {
949 return (B_FALSE);
953 return (B_TRUE);
956 static boolean_t
957 convertSnapshotInfoToDictionary(be_snapshot_list_t *ss, PyObject **listDict)
959 if (ss->be_snapshot_name != NULL) {
960 if (PyDict_SetItemString(*listDict, BE_ATTR_SNAP_NAME,
961 PyString_FromString(ss->be_snapshot_name)) != 0) {
962 return (B_FALSE);
966 if (ss->be_snapshot_creation != NULL) {
967 if (PyDict_SetItemString(*listDict, BE_ATTR_DATE,
968 PyLong_FromLong(ss->be_snapshot_creation)) != 0) {
969 return (B_FALSE);
973 if (ss->be_snapshot_type != NULL) {
974 if (PyDict_SetItemString(*listDict, BE_ATTR_POLICY,
975 PyString_FromString(ss->be_snapshot_type)) != 0) {
976 return (B_FALSE);
980 if (ss->be_snapshot_space_used != 0) {
981 if (PyDict_SetItemString(*listDict, BE_ATTR_SPACE,
982 PyLong_FromUnsignedLongLong(ss->be_snapshot_space_used))
983 != 0) {
984 return (B_FALSE);
988 return (B_TRUE);
992 * Convert string arguments to nvlist attributes
995 static boolean_t
996 convertPyArgsToNvlist(nvlist_t **nvList, int numArgs, ...)
998 char *pt, *pt2;
999 va_list ap;
1000 int i;
1002 if (*nvList == NULL) {
1003 if (nvlist_alloc(nvList, NV_UNIQUE_NAME, 0) != 0) {
1004 (void) printf("nvlist_alloc failed.\n");
1005 return (B_FALSE);
1009 va_start(ap, numArgs);
1011 for (i = 0; i < numArgs; i += 2) {
1012 if ((pt = va_arg(ap, char *)) == NULL ||
1013 (pt2 = va_arg(ap, char *)) == NULL) {
1014 continue;
1016 if (nvlist_add_string(*nvList, pt, pt2) != 0) {
1017 (void) printf("nvlist_add_string failed for %s (%s).\n",
1018 pt, pt2);
1019 nvlist_free(*nvList);
1020 return (B_FALSE);
1024 va_end(ap);
1026 return (B_TRUE);
1030 * Function: beMapLibbePyErrorToString
1031 * Description: Convert Python args to an int and map an error code to an
1032 * error string.
1033 * Parameter:
1034 * errCode - value to map to an error string.
1036 * Returns error string or NULL
1037 * Scope:
1038 * Public
1041 char *
1042 beMapLibbePyErrorToString(int errCode)
1044 switch (errCode) {
1045 case BE_PY_ERR_APPEND:
1046 return ("Unable to append a dictionary to a list "
1047 "of dictinaries.");
1048 case BE_PY_ERR_DICT:
1049 return ("Creation of a Python dictionary failed.");
1050 case BE_PY_ERR_LIST:
1051 return ("beList() failed.");
1052 case BE_PY_ERR_NVLIST:
1053 return ("An nvlist operation failed.");
1054 case BE_PY_ERR_PARSETUPLE:
1055 return ("PyArg_ParseTuple() failed to convert variable to C.");
1056 case BE_PY_ERR_PRINT_ERR:
1057 return ("bePrintErrors() failed.");
1058 case BE_PY_ERR_VAR_CONV:
1059 return ("Unable to add variables to a Python dictionary.");
1060 default:
1061 return (NULL);
1065 /* Private python initialization structure */
1067 static struct PyMethodDef libbeMethods[] = {
1068 {"beCopy", (PyCFunction)beCopy, METH_VARARGS, "Create/Copy a BE."},
1069 {"beCreateSnapshot", (PyCFunction)beCreateSnapshot, METH_VARARGS,
1070 "Create a snapshot."},
1071 {"beDestroy", (PyCFunction)beDestroy, METH_VARARGS, "Destroy a BE."},
1072 {"beDestroySnapshot", (PyCFunction)beDestroySnapshot, METH_VARARGS,
1073 "Destroy a snapshot."},
1074 {"beMount", (PyCFunction)beMount, METH_VARARGS, "Mount a BE."},
1075 {"beUnmount", (PyCFunction)beUnmount, METH_VARARGS, "Unmount a BE."},
1076 {"beList", (PyCFunction)beList, METH_VARARGS, "List BE info."},
1077 {"beRename", (PyCFunction)beRename, METH_VARARGS, "Rename a BE."},
1078 {"beActivate", (PyCFunction)beActivate, METH_VARARGS, "Activate a BE."},
1079 {"beRollback", (PyCFunction)beRollback, METH_VARARGS, "Rollback a BE."},
1080 {"bePrintErrors", (PyCFunction)bePrintErrors, METH_VARARGS,
1081 "Enable/disable error printing."},
1082 {"beGetErrDesc", (PyCFunction)beGetErrDesc, METH_VARARGS,
1083 "Map Error codes to strings."},
1084 {"beVerifyBEName", (PyCFunction)beVerifyBEName, METH_VARARGS,
1085 "Verify BE name."},
1086 {NULL, NULL, 0, NULL}
1089 void
1090 initlibbe_py()
1092 /* PyMODINIT_FUNC; */
1093 (void) Py_InitModule("libbe_py", libbeMethods);