2320 DC needs a C-python interface for the TI module Build92
authorJean McCormack <Jean.McCormack@Sun.COM>
Mon, 30 Jun 2008 08:40:58 -0600
changeset 169 f4cf4ac4caa3
parent 168 471f3e47cf61
child 170 bb382aaa18a8
2320 DC needs a C-python interface for the TI module
usr/src/lib/Makefile
usr/src/lib/libti/ti_api.h
usr/src/lib/libti_pymod/Makefile
usr/src/lib/libti_pymod/libti.c
usr/src/pkgdefs/SUNWinstall/prototype_com
--- a/usr/src/lib/Makefile	Thu Jun 26 10:19:59 2008 -0700
+++ b/usr/src/lib/Makefile	Mon Jun 30 08:40:58 2008 -0600
@@ -43,6 +43,7 @@
 		libspmizones \
 		libtd \
 		libti \
+		libti_pymod \
 		libtransfer
 
 HDRSUBDIRS=	libadmldb libadmutil
@@ -75,6 +76,7 @@
 
 # library dependencies
 libbe_pymod:		libbe
+libti_pymod:		libti
 libgendb:		libpkgdb
 libinst:		libpkg
 liborchestrator:	libtd liblogsvc libti libtransfer libbe
--- a/usr/src/lib/libti/ti_api.h	Thu Jun 26 10:19:59 2008 -0700
+++ b/usr/src/lib/libti/ti_api.h	Mon Jun 30 08:40:58 2008 -0600
@@ -62,7 +62,8 @@
 	TI_E_NEWFS_FAILED,		/* */
 	TI_E_MKDIR_FAILED,		/* */
 	TI_E_MOUNT_FAILED,		/* */
-	TI_E_RMDIR_FAILED		/* */
+	TI_E_RMDIR_FAILED,		/* */
+	TI_E_PY_INVALID_ARG		/* invalid arg in Python interface */ 
 } ti_errno_t;
 
 /* type of callback function reporting progress */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libti_pymod/Makefile	Mon Jun 30 08:40:58 2008 -0600
@@ -0,0 +1,59 @@
+#
+# 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 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 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 2008 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+LIBRARY		= libti
+
+OBJECTS		= libti.o
+
+CPYTHONLIBS	= libti.so
+
+PRIVHDRS	=
+EXPHDRS		=
+HDRS		= $(EXPHDRS) $(PRIVHDRS)
+
+include ../Makefile.lib
+
+INCLUDE		= -I/usr/include/python2.4 -I../libti
+
+CPPFLAGS	+= ${INCLUDE} $(CPPFLAGS.master) -D_FILE_OFFSET_BITS=64
+CFLAGS		+= $(DEBUG_CFLAGS) -Xa ${CPPFLAGS} 
+SOFLAGS		+= -L$(ROOTADMINLIB) -R$(ROOTADMINLIB:$(ROOT)%=%) \
+		-lti -lnvpair
+
+static:	
+
+dynamic:	$(CPYTHONLIB)
+
+all:		$(HDRS) dynamic
+
+install_h:
+
+install:	all .WAIT \
+		$(ROOTPYTHONVENDOR) $(ROOTPYTHONVENDORLIBS)
+
+lint:		lint_SRCS
+
+include ../Makefile.targ
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libti_pymod/libti.c	Mon Jun 30 08:40:58 2008 -0600
@@ -0,0 +1,693 @@
+/*
+ * 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 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+#include <Python.h>
+#include <libnvpair.h>
+#include <ti_api.h>
+#include <sys/types.h>
+
+static PyObject	*py_ti_create_target(PyObject *self, PyObject *args);
+static PyObject	*py_ti_release_target(PyObject *self, PyObject *args);
+
+/*
+ * Create the method table that translates the method called
+ * by the python program (ex. ti_create_target) to the associated
+ * c function (ex. py_ti_create_target)
+ */
+static	PyMethodDef libtiMethods[] = {
+    {"ti_create_target", py_ti_create_target, METH_VARARGS,
+    "Create a target"},
+    {"ti_release_target", py_ti_release_target, METH_VARARGS,
+    "Release a target"},
+    {NULL, NULL, 0, NULL} };
+
+struct attr_node {
+	char		*attribute;
+	data_type_t	type;
+};
+
+/*
+ * The attr_table is used in the bsearch, thus it must
+ * be kept sorted for proper functionality.
+ */
+static struct attr_node attr_table[] = {
+	{TI_ATTR_BE_FS_NAMES, DATA_TYPE_STRING_ARRAY},
+	{TI_ATTR_BE_FS_NUM, DATA_TYPE_UINT16},
+	{TI_ATTR_BE_MOUNTPOINT, DATA_TYPE_STRING},
+	{TI_ATTR_BE_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_BE_RPOOL_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_BE_SHARED_FS_NAMES, DATA_TYPE_STRING_ARRAY},
+	{TI_ATTR_BE_SHARED_FS_NUM, DATA_TYPE_UINT16},
+	{TI_ATTR_DC_RAMDISK_BOOTARCH_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_DC_RAMDISK_DEST,DATA_TYPE_STRING},
+	{TI_ATTR_DC_RAMDISK_FS_TYPE, DATA_TYPE_UINT16},
+	{TI_ATTR_DC_RAMDISK_SIZE, DATA_TYPE_UINT32},
+	{TI_ATTR_DC_UFS_DEST, DATA_TYPE_STRING},
+	{TI_ATTR_FDISK_DISK_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_FDISK_PART_ACTIVE, DATA_TYPE_UINT8_ARRAY},
+	{TI_ATTR_FDISK_PART_BCYLS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_BHEADS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_BSECTS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_ECYLS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_EHEADS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_ESECTS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_IDS, DATA_TYPE_UINT8_ARRAY},
+	{TI_ATTR_FDISK_PART_NUM, DATA_TYPE_UINT16},
+	{TI_ATTR_FDISK_PART_NUMSECTS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_PART_PRESERVE, DATA_TYPE_BOOLEAN_ARRAY},
+	{TI_ATTR_FDISK_PART_RSECTS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_FDISK_WDISK_FL, DATA_TYPE_BOOLEAN},
+	{TI_ATTR_SLICE_DEFAULT_LAYOUT, DATA_TYPE_BOOLEAN},
+	{TI_ATTR_SLICE_DISK_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_SLICE_FLAGS, DATA_TYPE_UINT16_ARRAY},
+	{TI_ATTR_SLICE_NUM, DATA_TYPE_UINT16},
+	{TI_ATTR_SLICE_PARTS, DATA_TYPE_UINT16_ARRAY},
+	{TI_ATTR_SLICE_SIZES, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_SLICE_TAGS, DATA_TYPE_UINT16_ARRAY},
+	{TI_ATTR_SLICE_1STSECS, DATA_TYPE_UINT64_ARRAY},
+	{TI_ATTR_TARGET_TYPE, DATA_TYPE_UINT32},
+	{TI_ATTR_ZFS_FS_NAMES, DATA_TYPE_STRING_ARRAY},
+	{TI_ATTR_ZFS_FS_NUM, DATA_TYPE_UINT16},
+	{TI_ATTR_ZFS_FS_POOL_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_ZFS_FS_PROP_NAMES, DATA_TYPE_STRING_ARRAY},
+	{TI_ATTR_ZFS_FS_PROP_VALUES, DATA_TYPE_STRING_ARRAY},
+	{TI_ATTR_ZFS_FS_PROPERTIES, DATA_TYPE_NVLIST_ARRAY},
+	{TI_ATTR_ZFS_RPOOL_DEVICE, DATA_TYPE_STRING},
+	{TI_ATTR_ZFS_RPOOL_NAME, DATA_TYPE_STRING},
+	{TI_ATTR_ZFS_RPOOL_PRESERVE, DATA_TYPE_BOOLEAN},
+	{TI_ATTR_ZFS_VOL_NUM, DATA_TYPE_UINT16}
+};
+
+/*
+ * Initialize libti module.
+ */
+PyMODINIT_FUNC
+initlibti(void)
+{
+	(void) Py_InitModule("libti", libtiMethods);
+}
+
+/*
+ * add_uint8_array
+ * Add a uint8_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the uint8 array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of uint8_ts
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_uint8_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	uint8_t		*val_array;
+	int		len, index;
+
+	/*
+	 * Find out how big the list of uint8_ts is.
+	 */
+	len = PyList_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+	/*
+	 * malloc the array accoringly
+	 */
+	val_array = malloc(len * sizeof (uint8_t));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+	/*
+	 * Get each uint8_t in the list, convert from PyObject
+	 * to uint8_t and put into the array.
+	 */
+	for (index = 0; index < len; index++) { 
+		val_array[index] = (uint8_t)PyInt_AsLong(
+		    PyList_GetItem(pvalue, index));
+	}	
+
+	/*
+	 * and place the array into the nvlist
+	 */
+        if (nvlist_add_uint8_array(attrs, attribute, val_array, len) != 0) {
+		free(val_array);
+		return (B_FALSE);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+/*
+ * add_uint16_array
+ * Add a uint16_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the uint16 array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of uint16_ts
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_uint16_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	uint16_t	*val_array;
+	int		len, index;
+
+	/*
+	 * Find out how big the list of uint16_ts is.
+	 */
+	len = PyList_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * malloc the array accoringly
+	 */
+	val_array = malloc(len * sizeof (uint16_t));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * Get each uint16_t in the list, convert from PyObject
+	 * to uint16_t and put into the array.
+	 */
+	for (index = 0; index < len; index++) { 
+		val_array[index] = (uint16_t)PyInt_AsLong(
+		    PyList_GetItem(pvalue, index));
+	}	
+
+	/*
+	 * and place the array into the nvlist
+	 */
+        if (nvlist_add_uint16_array(attrs, attribute, val_array, len) != 0) {
+		free(val_array);
+		return (B_FALSE);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+/*
+ * add_uint64_array
+ * Add a uint64_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the uint64 array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of uint64_ts
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_uint64_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	uint64_t	*val_array;
+	int		len, index;
+
+	/*
+	 * Find out how big the list of uint64_TS IS.
+	 */
+	len = PyList_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+	/*
+	 * malloc the array accoringly
+	 */
+	val_array = malloc(len * sizeof (uint64_t));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * Get each uint64_t in the list, convert from PyObject
+	 * to uint64_t and put into the array.
+	 */
+	for (index = 0; index < len ; index++) { 
+		val_array[index] = (uint64_t)PyLong_AsUnsignedLong(
+		    PyList_GetItem(pvalue, index));
+	}	
+
+	/*
+	 * and place the array into the nvlist
+	 */
+        if (nvlist_add_uint64_array(attrs, attribute,
+	    val_array, len) != 0) {
+		free(val_array);
+		return (B_FALSE);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+/*
+ * add_boolean_array
+ * Add a boolean_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the boolean array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of booleans 
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_boolean_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	boolean_t	*val_array;
+	int		len, index;
+
+	/*
+	 * Find out how big the list of booleans is. 
+	 */
+	len = PyList_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * malloc the array accoringly
+	 */
+	val_array = malloc(len * sizeof(boolean_t));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * Get each boolean in the list, convert from PyObject
+	 * to boolean and put into the array.
+	 */
+	for (index = 0; index < len ; index++) { 
+		if (PyList_GetItem(pvalue, index) == Py_True)
+			val_array[index] = B_TRUE;
+		else
+			val_array[index] = B_FALSE;
+	}	
+
+	/*
+	 * and place the array into the nvlist
+	 */
+        if (nvlist_add_boolean_array(attrs, attribute,
+	    val_array, len) != 0) {
+		free(val_array);
+		return (B_FALSE);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+/*
+ * add_string_array
+ * Add a string_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the string array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of strings 
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_string_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	char	**val_array;
+	char	*value;
+	int	len, index;
+
+
+	/*
+	 * Find out how big the list of strings is. 
+	 */
+	len = PyList_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * malloc the array accoringly
+	 */
+	val_array = malloc(len * sizeof (char *));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * Get each string in the list, convert from PyObject
+	 * to string and put into the array.
+	 */
+	for (index = 0; index < len ; index++) { 
+		value = PyString_AsString(
+		    PyList_GetItem(pvalue,0));
+   		val_array[index] = value;
+	}
+
+	/*
+	 * and place the array into the nvlist
+	 */
+	if (nvlist_add_string_array(attrs, attribute,
+	    val_array, len) != 0) {
+		free(val_array);
+		return (B_FALSE);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+/*
+ * add_nvlist_array
+ * Add a nvlist_array into the nvlist
+ * Arguments: attrs - nvlist_t to put the nvlist array into
+ *	      attribute - the name of the nvlist
+ *            pvalue - list of nvlist_ts 
+ * Returns: B_TRUE on success
+ *          B_FALSE on failure
+ */
+static boolean_t
+add_nvlist_array(nvlist_t *attrs, char *attribute, PyObject *pvalue)
+{
+	PyObject	*fs_properties = NULL;
+	nvlist_t	*fs_attrs;
+	char		*fs_attribute;
+	PyObject	*pfs_key = NULL;
+	PyObject	*pfs_value = NULL;
+	int		fs_pos = 0;
+	nvlist_t	**val_array;
+	PyObject	*list_obj;
+	int		len, index, i;
+	struct attr_node	*node_ptr, node;
+
+	/*
+	 * Find out how big the list of nvlists is. 
+	 */
+	len = PyTuple_Size(pvalue);
+	if (len <= 0) {
+		return (B_FALSE);
+	}
+
+
+	/*
+	 * malloc the array accordingly
+	 */
+	val_array = malloc(len * sizeof (nvlist_t *));
+	if (val_array == NULL) {
+		return (B_FALSE);
+	}
+
+	/*
+	 * Get each nvlist in the list, convert from PyObject
+	 * to nvlist and put into the array.
+	 */
+	for (index = 0; index < len ; index++) { 
+		/*
+		 * Get the list
+		 */
+		list_obj = PyTuple_GetItem(pvalue,index);
+		if (list_obj == NULL) {
+			for (i = 0; i < index; i++) { 
+				nvlist_free(val_array[i]);
+			}
+			free(val_array);
+			return (B_FALSE);
+		}
+
+		if (nvlist_alloc(&fs_attrs, NV_UNIQUE_NAME, 0)) {
+			for (i = 0; i < index; i++) { 
+				nvlist_free(val_array[i]);
+			}
+			free(val_array);
+			return (B_FALSE);
+		}
+
+		if ((ti_setup_nvlist(fs_attrs, list_obj)) != TI_E_SUCCESS) {
+			nvlist_free(fs_attrs);
+			for (i = 0; i < index; i++) { 
+				nvlist_free(val_array[i]);
+			}
+			free(val_array);
+			return (B_FALSE);
+		}
+
+		/*
+		 * And add the nvlist to the array of nvlists
+		 */
+		val_array[index] = fs_attrs;
+	}
+
+	/*
+	 * Add the array of nvlists to the nvlist
+	 */
+	if (nvlist_add_nvlist_array(attrs, attribute, val_array, len)) {
+		for (index; index < len; index++) { 
+			nvlist_free(val_array[index]);
+		}
+		free(val_array);
+		return (B_FALSE);
+	}
+	for (index = 0; index < len ; index++) { 
+		nvlist_free(val_array[index]);
+	}
+	free(val_array);
+	return (B_TRUE);
+}
+
+
+/*
+ * attr_compare
+ * function used by the bsearch to compare the string
+ * field in the nodes.
+ */
+static
+int attr_compare(const void *attr1, const void *attr2)
+{
+	return (strcmp(((const struct attr_node *)attr1)->attribute,
+	    ((const struct attr_node *)attr2)->attribute));
+}
+
+/*
+ * ti_setup_nvlist 
+ * This will place the python args into the C nvlist
+ */
+int
+ti_setup_nvlist(nvlist_t *attrs, PyObject *ti_properties)
+{
+	PyObject	*pkey = NULL;
+	PyObject	*pvalue = NULL;
+	int		pos = 0;
+	char		*attribute;
+	int		status;
+	data_type_t	type;
+	boolean_t	value;
+	struct attr_node	*node_ptr, node;
+
+	/*
+	 * Loop through the list pulling out key (name) value pairs
+	 * for each entry in the list.
+	 */
+
+	while (PyDict_Next(ti_properties, &pos, &pkey, &pvalue)) {
+		node.attribute = PyString_AsString(pkey);
+
+		node_ptr = bsearch(&node, attr_table, sizeof(attr_table)/sizeof(struct attr_node),
+		    sizeof(struct attr_node), attr_compare);
+
+		if (node_ptr == NULL)
+			return (TI_E_PY_INVALID_ARG);
+
+		switch (node_ptr->type) {
+			case DATA_TYPE_UINT32:
+				/*
+		 	 	 * Place the uint32 properties into the nvlist
+		 	 	 */
+				if (nvlist_add_uint32(attrs,
+				    attribute, (uint32_t)PyInt_AsLong(pvalue)) != 0) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_STRING:
+				/*
+		 		 * Place the string properties into the nvlist
+		 		 */
+				if (nvlist_add_string(attrs, attribute,
+	    			    PyString_AsString(pvalue)) != 0) {
+
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_UINT16:
+				/*
+		 		 * Place the uint 16 properties into the nvlist
+		 		 */
+                		if (nvlist_add_uint16(attrs, attribute,
+				    (uint16_t)PyInt_AsLong(pvalue)) != 0) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_BOOLEAN:
+				/*
+		 		 * Place the boolean properties into the nvlist
+		 		 */
+				if (pvalue == Py_True)
+					value = B_TRUE;
+				else
+					value = B_FALSE;
+                		if (nvlist_add_boolean_value(attrs, attribute,
+				    value) != 0) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_UINT8_ARRAY:
+				if (!add_uint8_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_UINT16_ARRAY:
+				if (!add_uint16_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_UINT64_ARRAY:
+				if (!add_uint64_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_BOOLEAN_ARRAY:
+				if (!add_boolean_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_STRING_ARRAY:
+				if (!add_string_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			case DATA_TYPE_NVLIST_ARRAY:
+				if (!add_nvlist_array(attrs, attribute, pvalue)) {
+					return (TI_E_PY_INVALID_ARG);
+				}
+				break;
+			default:
+				return (TI_E_PY_INVALID_ARG);
+				break;
+		}
+	}
+	return (TI_E_SUCCESS);
+}
+
+/*
+ * py_ti_create_target
+ * Main function. This is the wrapper for a python function to call the
+ * C function, ti_create_target.
+ */
+static PyObject *
+py_ti_create_target(PyObject *self, PyObject *args)
+{
+	int		ret;
+	nvlist_t	*attrs;
+	PyObject	*ti_properties;
+
+	if (!Py_IsInitialized()) {
+        	Py_Initialize();
+	}
+
+	/*
+	 * Parse the List input
+	 */
+	if (!PyArg_ParseTuple(args, "O", &ti_properties)) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if (ti_properties == NULL) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if (nvlist_alloc(&attrs, NV_UNIQUE_NAME, 0) != 0) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if ((ret = ti_setup_nvlist(attrs, ti_properties)) != TI_E_SUCCESS) {
+                nvlist_free(attrs);
+		return Py_BuildValue("i", ret);
+	}
+
+	
+	ret = ti_create_target(attrs, NULL);
+	if (ret != TI_E_SUCCESS) {
+                nvlist_free(attrs);
+		return Py_BuildValue("i", ret);
+	}
+
+        nvlist_free(attrs);
+	return Py_BuildValue("i", TI_E_SUCCESS);
+}
+
+/*
+ * py_ti_release_target
+ * Main function. This is the wrapper for a python function to call the
+ * C function, ti_release_target.
+ */
+static PyObject *
+py_ti_release_target(PyObject *self, PyObject *args)
+{
+	int		ret;
+	nvlist_t	*attrs;
+	PyObject	*ti_properties;
+
+	if (!Py_IsInitialized()) {
+        	Py_Initialize();
+	}
+
+	/*
+	 * Parse the List input
+	 */
+	if (!PyArg_ParseTuple(args, "O", &ti_properties)) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if (ti_properties == NULL) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if (nvlist_alloc(&attrs, NV_UNIQUE_NAME, 0) != 0) {
+		return Py_BuildValue("i", TI_E_PY_INVALID_ARG);
+	}
+
+	if ((ret = ti_setup_nvlist(attrs, ti_properties)) != TI_E_SUCCESS) {
+                nvlist_free(attrs);
+		return Py_BuildValue("i", ret);
+	}
+
+	ret = ti_release_target(attrs);
+	if (ret != TI_E_SUCCESS) {
+                nvlist_free(attrs);
+		return Py_BuildValue("i", ret);
+	}
+
+        nvlist_free(attrs);
+	return Py_BuildValue("i", TI_E_SUCCESS);
+}
--- a/usr/src/pkgdefs/SUNWinstall/prototype_com	Thu Jun 26 10:19:59 2008 -0700
+++ b/usr/src/pkgdefs/SUNWinstall/prototype_com	Mon Jun 30 08:40:58 2008 -0600
@@ -140,7 +140,7 @@
 f none usr/lib/python2.4/vendor-packages/beadm/__init__.pyc 0444 root bin
 f none usr/lib/python2.4/vendor-packages/transfer_mod.py 0644 root bin
 f none usr/lib/python2.4/vendor-packages/transfer_mod.pyc 0644 root bin
-
+f none usr/lib/python2.4/vendor-packages/libti.so 0755 root bin
 
 d none usr/snadm 0755 root bin
 d none usr/snadm/lib 0755 root bin