xref: /titanic_53/usr/src/lib/libinstzones/common/zones.c (revision 94a65b20fd6706171eba5212ea3ca67570ba7e12)
15c51f124SMoriah Waterland /*
25c51f124SMoriah Waterland  * CDDL HEADER START
35c51f124SMoriah Waterland  *
45c51f124SMoriah Waterland  * The contents of this file are subject to the terms of the
55c51f124SMoriah Waterland  * Common Development and Distribution License (the "License").
65c51f124SMoriah Waterland  * You may not use this file except in compliance with the License.
75c51f124SMoriah Waterland  *
85c51f124SMoriah Waterland  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95c51f124SMoriah Waterland  * or http://www.opensolaris.org/os/licensing.
105c51f124SMoriah Waterland  * See the License for the specific language governing permissions
115c51f124SMoriah Waterland  * and limitations under the License.
125c51f124SMoriah Waterland  *
135c51f124SMoriah Waterland  * When distributing Covered Code, include this CDDL HEADER in each
145c51f124SMoriah Waterland  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155c51f124SMoriah Waterland  * If applicable, add the following below this CDDL HEADER, with the
165c51f124SMoriah Waterland  * fields enclosed by brackets "[]" replaced with your own identifying
175c51f124SMoriah Waterland  * information: Portions Copyright [yyyy] [name of copyright owner]
185c51f124SMoriah Waterland  *
195c51f124SMoriah Waterland  * CDDL HEADER END
205c51f124SMoriah Waterland  */
215c51f124SMoriah Waterland 
225c51f124SMoriah Waterland /*
235c51f124SMoriah Waterland  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
245c51f124SMoriah Waterland  * Use is subject to license terms.
255c51f124SMoriah Waterland  */
265c51f124SMoriah Waterland 
275c51f124SMoriah Waterland 
285c51f124SMoriah Waterland /*
295c51f124SMoriah Waterland  * Module:	zones.c
305c51f124SMoriah Waterland  * Group:	libinstzones
315c51f124SMoriah Waterland  * Description:	Provide "zones" interface for install consolidation code
325c51f124SMoriah Waterland  *
335c51f124SMoriah Waterland  * Public Methods:
345c51f124SMoriah Waterland  *  z_create_zone_admin_file - Given a location to create the file, and
355c51f124SMoriah Waterland  *	optionally an existing administration file, generate an
365c51f124SMoriah Waterland  *	administration file that can be used to perform "non-interactive"
375c51f124SMoriah Waterland  *	operations in a non-global zone.
385c51f124SMoriah Waterland  *  z_free_zone_list - free contents of zoneList_t object
395c51f124SMoriah Waterland  *  z_get_nonglobal_zone_list - return zoneList_t object describing all
405c51f124SMoriah Waterland  *	non-global native zones
415c51f124SMoriah Waterland  *  z_get_nonglobal_zone_list_by_brand - return zoneList_t object describing
425c51f124SMoriah Waterland  *      all non-global zones matching the list of zone brands passed in.
435c51f124SMoriah Waterland  *  z_free_brand_list - free contents of a zoneBrandList_t object
445c51f124SMoriah Waterland  *  z_make_brand_list - return a zoneBrandList_t object describing the list
455c51f124SMoriah Waterland  *	of all zone brands passed in.
465c51f124SMoriah Waterland  *  z_get_zonename - return the name of the current zone
475c51f124SMoriah Waterland  *  z_global_only - Determine if the global zone is only zone on the spec list
485c51f124SMoriah Waterland  *  z_lock_this_zone - lock this zone
495c51f124SMoriah Waterland  *  z_lock_zones - lock specified zones
505c51f124SMoriah Waterland  *  z_mount_in_lz - Mount global zone directory in specified zone's root file
515c51f124SMoriah Waterland  *	system
525c51f124SMoriah Waterland  *  z_non_global_zones_exist - Determine if any non-global native zones exist
535c51f124SMoriah Waterland  *  z_on_zone_spec - Determine if named zone is on the zone_spec list
545c51f124SMoriah Waterland  *  z_running_in_global_zone - Determine if running in the "global" zone
555c51f124SMoriah Waterland  *  z_set_output_functions - Link program specific output functions
565c51f124SMoriah Waterland  *  z_set_zone_root - Set root for zones library operations
575c51f124SMoriah Waterland  *  z_set_zone_spec - Set list of zones on which actions will be performed
585c51f124SMoriah Waterland  *  z_umount_lz_mount - Unmount directory mounted with z_mount_in_lz
595c51f124SMoriah Waterland  *  z_unlock_this_zone - unlock this zone
605c51f124SMoriah Waterland  *  z_unlock_zones - unlock specified zones
615c51f124SMoriah Waterland  *  z_verify_zone_spec - Verify list of zones on which actions will be performed
625c51f124SMoriah Waterland  *  z_zlist_change_zone_state - Change the current state of the specified zone
635c51f124SMoriah Waterland  *  z_zlist_get_current_state - Determine the current kernel state of the
645c51f124SMoriah Waterland  *	specified zone
655c51f124SMoriah Waterland  *  z_zlist_get_inherited_pkg_dirs - Determine directories inherited by
665c51f124SMoriah Waterland  *	specified zone
675c51f124SMoriah Waterland  *  z_zlist_get_original_state - Return the original kernal state of the
685c51f124SMoriah Waterland  *	specified zone
695c51f124SMoriah Waterland  *  z_zlist_get_scratch - Determine name of scratch zone
705c51f124SMoriah Waterland  *  z_zlist_get_zonename - Determine name of specified zone
715c51f124SMoriah Waterland  *  z_zlist_get_zonepath - Determine zonepath of specified zone
725c51f124SMoriah Waterland  *  z_zlist_restore_zone_state - Return the zone to the state it was originally
735c51f124SMoriah Waterland  *	in
745c51f124SMoriah Waterland  *  z_zone_exec - Execute a Unix command in a specified zone and return results
755c51f124SMoriah Waterland  *  z_zones_are_implemented - Determine if any zone operations can be performed
765c51f124SMoriah Waterland  *  z_is_zone_branded - determine if zone has a non-native brand
775c51f124SMoriah Waterland  *  z_is_zone_brand_in_list - determine if the zone's brand matches the
785c51f124SMoriah Waterland  *      brand list passed in.
795c51f124SMoriah Waterland  *  z_brands_are_implemented - determine if branded zones are implemented on
805c51f124SMoriah Waterland  *			this system
815c51f124SMoriah Waterland  */
825c51f124SMoriah Waterland 
835c51f124SMoriah Waterland /*
845c51f124SMoriah Waterland  * System includes
855c51f124SMoriah Waterland  */
865c51f124SMoriah Waterland 
875c51f124SMoriah Waterland #include <stdio.h>
885c51f124SMoriah Waterland #include <stdlib.h>
895c51f124SMoriah Waterland #include <unistd.h>
905c51f124SMoriah Waterland #include <fcntl.h>
915c51f124SMoriah Waterland #include <ctype.h>
925c51f124SMoriah Waterland #include <sys/types.h>
935c51f124SMoriah Waterland #include <sys/param.h>
945c51f124SMoriah Waterland #include <sys/sysmacros.h>
955c51f124SMoriah Waterland #include <string.h>
965c51f124SMoriah Waterland #include <strings.h>
975c51f124SMoriah Waterland #include <sys/stat.h>
985c51f124SMoriah Waterland #include <stdarg.h>
995c51f124SMoriah Waterland #include <limits.h>
1005c51f124SMoriah Waterland #include <errno.h>
1015c51f124SMoriah Waterland #include <time.h>
1025c51f124SMoriah Waterland #include <signal.h>
1035c51f124SMoriah Waterland #include <stropts.h>
1045c51f124SMoriah Waterland #include <wait.h>
1055c51f124SMoriah Waterland #include <zone.h>
1065c51f124SMoriah Waterland #include <sys/brand.h>
1075c51f124SMoriah Waterland #include <libintl.h>
1085c51f124SMoriah Waterland #include <locale.h>
1095c51f124SMoriah Waterland #include <libzonecfg.h>
1105c51f124SMoriah Waterland #include <libcontract.h>
1115c51f124SMoriah Waterland #include <sys/contract/process.h>
1125c51f124SMoriah Waterland #include <sys/ctfs.h>
1135c51f124SMoriah Waterland #include <assert.h>
1145c51f124SMoriah Waterland #include <dlfcn.h>
1155c51f124SMoriah Waterland #include <link.h>
1165c51f124SMoriah Waterland #include <time.h>
1175c51f124SMoriah Waterland 
1185c51f124SMoriah Waterland /*
1195c51f124SMoriah Waterland  * local includes
1205c51f124SMoriah Waterland  */
1215c51f124SMoriah Waterland 
1225c51f124SMoriah Waterland /*
1235c51f124SMoriah Waterland  * When _INSTZONES_LIB_Z_DEFINE_GLOBAL_DATA is defined,
1245c51f124SMoriah Waterland  * instzones_lib.h will define the z_global_data structure.
1255c51f124SMoriah Waterland  * Otherwise an extern to the structure is inserted.
1265c51f124SMoriah Waterland  */
1275c51f124SMoriah Waterland 
1285c51f124SMoriah Waterland #define	_INSTZONES_LIB_Z_DEFINE_GLOBAL_DATA
1295c51f124SMoriah Waterland #include "instzones_lib.h"
1305c51f124SMoriah Waterland #include "zones_strings.h"
1315c51f124SMoriah Waterland 
1325c51f124SMoriah Waterland /*
1335c51f124SMoriah Waterland  * Private structures
1345c51f124SMoriah Waterland  */
1355c51f124SMoriah Waterland 
1365c51f124SMoriah Waterland #define	CLUSTER_BRAND_NAME	"cluster"
1375c51f124SMoriah Waterland 
1385c51f124SMoriah Waterland /* maximum number of arguments to exec() call */
1395c51f124SMoriah Waterland 
1405c51f124SMoriah Waterland #define	UUID_FORMAT	"%02d%02d%02d%03d-%02d%02d%02d%d-%016llx"
1415c51f124SMoriah Waterland 
1425c51f124SMoriah Waterland /*
1435c51f124SMoriah Waterland  * Library Function Prototypes
1445c51f124SMoriah Waterland  */
1455c51f124SMoriah Waterland 
1465c51f124SMoriah Waterland #define	streq(a, b) (strcmp((a), (b)) == 0)
1475c51f124SMoriah Waterland 
1485c51f124SMoriah Waterland /*
1495c51f124SMoriah Waterland  * Local Function Prototypes
1505c51f124SMoriah Waterland  */
1515c51f124SMoriah Waterland 
1525c51f124SMoriah Waterland /*
1535c51f124SMoriah Waterland  * global internal (private) declarations
1545c51f124SMoriah Waterland  */
1555c51f124SMoriah Waterland 
1565c51f124SMoriah Waterland /*
1575c51f124SMoriah Waterland  * *****************************************************************************
1585c51f124SMoriah Waterland  * global external (public) functions
1595c51f124SMoriah Waterland  * *****************************************************************************
1605c51f124SMoriah Waterland  */
1615c51f124SMoriah Waterland 
1625c51f124SMoriah Waterland /*
1635c51f124SMoriah Waterland  * Name:	z_create_zone_admin_file
1645c51f124SMoriah Waterland  * Description:	Given a location to create the file, and optionally an existing
1655c51f124SMoriah Waterland  *		administration file, generate an administration file that
1665c51f124SMoriah Waterland  *		can be used to perform "non-interactive" operations in a
1675c51f124SMoriah Waterland  *		non-global zone.
1685c51f124SMoriah Waterland  * Arguments:	a_zoneAdminFilename - pointer to string representing the
1695c51f124SMoriah Waterland  *			full path of zone admin file to create
1705c51f124SMoriah Waterland  *		a_userAdminFilename - pointer to string representing the path
1715c51f124SMoriah Waterland  *			to an existing "user" administration file - the
1725c51f124SMoriah Waterland  *			administration file created will contain the
1735c51f124SMoriah Waterland  *			settings contained in this file, modified as
1745c51f124SMoriah Waterland  *			appropriate to supress any interaction;
1755c51f124SMoriah Waterland  *			If this is == NULL then the administration file
1765c51f124SMoriah Waterland  *			created will not contain any extra settings
1775c51f124SMoriah Waterland  * Returns:	boolean_t
1785c51f124SMoriah Waterland  *			== B_TRUE - admin file created
1795c51f124SMoriah Waterland  *			== B_FALSE - failed to create admin file
1805c51f124SMoriah Waterland  */
1815c51f124SMoriah Waterland 
1825c51f124SMoriah Waterland boolean_t
1835c51f124SMoriah Waterland z_create_zone_admin_file(char *a_zoneAdminFilename, char *a_userAdminFilename)
1845c51f124SMoriah Waterland {
1855c51f124SMoriah Waterland 	FILE	*zFp;
1865c51f124SMoriah Waterland 	FILE	*uFp = (FILE *)NULL;
1875c51f124SMoriah Waterland 
1885c51f124SMoriah Waterland 	/* entry assertions */
1895c51f124SMoriah Waterland 
1905c51f124SMoriah Waterland 	assert(a_zoneAdminFilename != NULL);
1915c51f124SMoriah Waterland 	assert(*a_zoneAdminFilename != '\0');
1925c51f124SMoriah Waterland 
1935c51f124SMoriah Waterland 	/* create temporary zone admin file */
1945c51f124SMoriah Waterland 
1955c51f124SMoriah Waterland 	zFp = fopen(a_zoneAdminFilename, "w");
1965c51f124SMoriah Waterland 	if (zFp == (FILE *)NULL) {
1975c51f124SMoriah Waterland 		return (B_FALSE);
1985c51f124SMoriah Waterland 	}
1995c51f124SMoriah Waterland 
2005c51f124SMoriah Waterland 	/* open user admin file if specified */
2015c51f124SMoriah Waterland 
2025c51f124SMoriah Waterland 	if (a_userAdminFilename != (char *)NULL) {
2035c51f124SMoriah Waterland 		uFp = fopen(a_userAdminFilename, "r");
2045c51f124SMoriah Waterland 	}
2055c51f124SMoriah Waterland 
2065c51f124SMoriah Waterland 	/* create default admin file for zone pkg ops if no user admin file */
2075c51f124SMoriah Waterland 
2085c51f124SMoriah Waterland 	if (uFp == (FILE *)NULL) {
2095c51f124SMoriah Waterland 		/* create default admin file */
2105c51f124SMoriah Waterland 		(void) fprintf(zFp, "action=nocheck\nauthentication=nocheck\n"
2115c51f124SMoriah Waterland 		    "basedir=default\nconflict=nocheck\nidepend=nocheck\n"
2125c51f124SMoriah Waterland 		    "instance=unique\npartial=nocheck\nrdepend=nocheck\n"
2135c51f124SMoriah Waterland 		    "runlevel=nocheck\nsetuid=nocheck\nspace=nocheck\n"
2145c51f124SMoriah Waterland 		    "mail=\n");
2155c51f124SMoriah Waterland 	} else for (;;) {
2165c51f124SMoriah Waterland 		/* copy user admin file substitute/change appropriate entries */
2175c51f124SMoriah Waterland 		char	buf[LINE_MAX+1];
2185c51f124SMoriah Waterland 		char	*p;
2195c51f124SMoriah Waterland 
2205c51f124SMoriah Waterland 		/* read next line of user admin file */
2215c51f124SMoriah Waterland 
2225c51f124SMoriah Waterland 		p = fgets(buf, sizeof (buf), uFp);
2235c51f124SMoriah Waterland 		if (p == (char *)NULL) {
2245c51f124SMoriah Waterland 			(void) fclose(uFp);
2255c51f124SMoriah Waterland 			break;
2265c51f124SMoriah Waterland 		}
2275c51f124SMoriah Waterland 
2285c51f124SMoriah Waterland 		/* modify / replace / accept as appropriate */
2295c51f124SMoriah Waterland 
2305c51f124SMoriah Waterland 		if (strncmp(buf, "instance=quit", 13) == 0) {
2315c51f124SMoriah Waterland 			(void) fprintf(zFp, "%s", "instance=unique\n");
2325c51f124SMoriah Waterland 			/*LINTED*/
2335c51f124SMoriah Waterland 		} else if (strncmp(buf, "keystore=", 9) == 0) {
2345c51f124SMoriah Waterland 		} else if (strncmp(buf, "action=", 7) == 0) {
2355c51f124SMoriah Waterland 			(void) fprintf(zFp, "action=nocheck\n");
2365c51f124SMoriah Waterland 		} else if (strncmp(buf, "authentication=", 15) == 0) {
2375c51f124SMoriah Waterland 			(void) fprintf(zFp, "authentication=nocheck\n");
2385c51f124SMoriah Waterland 		} else if (strncmp(buf, "conflict=", 9) == 0) {
2395c51f124SMoriah Waterland 			(void) fprintf(zFp, "conflict=nocheck\n");
2405c51f124SMoriah Waterland 		} else if (strncmp(buf, "idepend=", 8) == 0) {
2415c51f124SMoriah Waterland 			(void) fprintf(zFp, "idepend=nocheck\n");
2425c51f124SMoriah Waterland 		} else if (strncmp(buf, "mail=", 5) == 0) {
2435c51f124SMoriah Waterland 			(void) fprintf(zFp, "mail=\n");
2445c51f124SMoriah Waterland 		} else if (strncmp(buf, "partial=", 8) == 0) {
2455c51f124SMoriah Waterland 			(void) fprintf(zFp, "partial=nocheck\n");
2465c51f124SMoriah Waterland 		} else if (strncmp(buf, "rdepend=", 8) == 0) {
2475c51f124SMoriah Waterland 			(void) fprintf(zFp, "rdepend=nocheck\n");
2485c51f124SMoriah Waterland 		} else if (strncmp(buf, "runlevel=", 9) == 0) {
2495c51f124SMoriah Waterland 			(void) fprintf(zFp, "runlevel=nocheck\n");
2505c51f124SMoriah Waterland 		} else if (strncmp(buf, "setuid=", 7) == 0) {
2515c51f124SMoriah Waterland 			(void) fprintf(zFp, "setuid=nocheck\n");
2525c51f124SMoriah Waterland 		} else if (strncmp(buf, "space=", 6) == 0) {
2535c51f124SMoriah Waterland 			(void) fprintf(zFp, "space=nocheck\n");
2545c51f124SMoriah Waterland 		} else {
2555c51f124SMoriah Waterland 			(void) fprintf(zFp, "%s", buf);
2565c51f124SMoriah Waterland 		}
2575c51f124SMoriah Waterland 	}
2585c51f124SMoriah Waterland 
2595c51f124SMoriah Waterland 	/* close admin file and return success */
2605c51f124SMoriah Waterland 
2615c51f124SMoriah Waterland 	(void) fclose(zFp);
2625c51f124SMoriah Waterland 	return (B_TRUE);
2635c51f124SMoriah Waterland }
2645c51f124SMoriah Waterland 
2655c51f124SMoriah Waterland /*
2665c51f124SMoriah Waterland  * Name:	z_brands_are_implemented
2675c51f124SMoriah Waterland  * Description:	Determine if any branded zones may be present
2685c51f124SMoriah Waterland  * Arguments:	void
2695c51f124SMoriah Waterland  * Returns:	boolean_t
2705c51f124SMoriah Waterland  *			== B_TRUE - branded zones are supported
2715c51f124SMoriah Waterland  *			== B_FALSE - branded zones are not supported
2725c51f124SMoriah Waterland  */
2735c51f124SMoriah Waterland 
2745c51f124SMoriah Waterland boolean_t
2755c51f124SMoriah Waterland z_brands_are_implemented(void)
2765c51f124SMoriah Waterland {
2775c51f124SMoriah Waterland static	boolean_t	_brandsImplementedDetermined = B_FALSE;
2785c51f124SMoriah Waterland static	boolean_t	_brandsAreImplemented = B_FALSE;
2795c51f124SMoriah Waterland 
2805c51f124SMoriah Waterland 	/* if availability has not been determined, cache it now */
2815c51f124SMoriah Waterland 
2825c51f124SMoriah Waterland 	if (!_brandsImplementedDetermined) {
2835c51f124SMoriah Waterland 		_brandsImplementedDetermined = B_TRUE;
2845c51f124SMoriah Waterland 		_brandsAreImplemented = _z_brands_are_implemented();
2855c51f124SMoriah Waterland 		if (_brandsAreImplemented) {
2865c51f124SMoriah Waterland 			_z_echoDebug(DBG_BRANDS_ARE_IMPLEMENTED);
2875c51f124SMoriah Waterland 		} else {
2885c51f124SMoriah Waterland 			_z_echoDebug(DBG_BRANDS_NOT_IMPLEMENTED);
2895c51f124SMoriah Waterland 		}
2905c51f124SMoriah Waterland 	}
2915c51f124SMoriah Waterland 
2925c51f124SMoriah Waterland 	/* return cached answer */
2935c51f124SMoriah Waterland 
2945c51f124SMoriah Waterland 	return (_brandsAreImplemented);
2955c51f124SMoriah Waterland }
2965c51f124SMoriah Waterland 
2975c51f124SMoriah Waterland /*
2985c51f124SMoriah Waterland  * Name:	z_free_zone_list
2995c51f124SMoriah Waterland  * Description:	free contents of zoneList_t object
3005c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object to free
3015c51f124SMoriah Waterland  * Returns:	void
3025c51f124SMoriah Waterland  */
3035c51f124SMoriah Waterland 
3045c51f124SMoriah Waterland void
3055c51f124SMoriah Waterland z_free_zone_list(zoneList_t a_zlst)
3065c51f124SMoriah Waterland {
3075c51f124SMoriah Waterland 	int	numzones;
3085c51f124SMoriah Waterland 
3095c51f124SMoriah Waterland 	/* ignore empty list */
3105c51f124SMoriah Waterland 
3115c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
3125c51f124SMoriah Waterland 		return;
3135c51f124SMoriah Waterland 	}
3145c51f124SMoriah Waterland 
3155c51f124SMoriah Waterland 	/* free each entry in the zone list */
3165c51f124SMoriah Waterland 
3175c51f124SMoriah Waterland 	for (numzones = 0; a_zlst[numzones]._zlName != (char *)NULL;
3185c51f124SMoriah Waterland 	    numzones++) {
3195c51f124SMoriah Waterland 		zoneListElement_t *zelm = &a_zlst[numzones];
3205c51f124SMoriah Waterland 
3215c51f124SMoriah Waterland 		/* free zone name string */
3225c51f124SMoriah Waterland 
3235c51f124SMoriah Waterland 		free(zelm->_zlName);
3245c51f124SMoriah Waterland 
3255c51f124SMoriah Waterland 		/* free zonepath string */
3265c51f124SMoriah Waterland 
3275c51f124SMoriah Waterland 		if (zelm->_zlPath != (char *)NULL) {
3285c51f124SMoriah Waterland 			free(zelm->_zlPath);
3295c51f124SMoriah Waterland 		}
3305c51f124SMoriah Waterland 
3315c51f124SMoriah Waterland 		/* free list of inherited package directories */
3325c51f124SMoriah Waterland 
3335c51f124SMoriah Waterland 		if (zelm->_zlInheritedDirs != (char **)NULL) {
3345c51f124SMoriah Waterland 			int	n;
3355c51f124SMoriah Waterland 
3365c51f124SMoriah Waterland 			for (n = 0;
3375c51f124SMoriah Waterland 			    (zelm->_zlInheritedDirs)[n] != (char *)NULL;
3385c51f124SMoriah Waterland 			    n++) {
3395c51f124SMoriah Waterland 				(void) free((zelm->_zlInheritedDirs)[n]);
3405c51f124SMoriah Waterland 			}
3415c51f124SMoriah Waterland 			(void) free(zelm->_zlInheritedDirs);
3425c51f124SMoriah Waterland 		}
3435c51f124SMoriah Waterland 	}
3445c51f124SMoriah Waterland 
3455c51f124SMoriah Waterland 	/* free handle to the list */
3465c51f124SMoriah Waterland 
3475c51f124SMoriah Waterland 	free(a_zlst);
3485c51f124SMoriah Waterland }
3495c51f124SMoriah Waterland 
3505c51f124SMoriah Waterland /*
3515c51f124SMoriah Waterland  * Name:	z_get_nonglobal_zone_list
3525c51f124SMoriah Waterland  * Description: return zoneList_t object describing all non-global
3535c51f124SMoriah Waterland  *              native zones - branded zones are not included in list
3545c51f124SMoriah Waterland  * Arguments:	None.
3555c51f124SMoriah Waterland  * Returns:	zoneList_t
3565c51f124SMoriah Waterland  *			== NULL - error, list could not be generated
3575c51f124SMoriah Waterland  *			!= NULL - success, list returned
3585c51f124SMoriah Waterland  * NOTE:    	Any zoneList_t returned is placed in new storage for the
3595c51f124SMoriah Waterland  *		calling function. The caller must use 'z_free_zone_list' to
3605c51f124SMoriah Waterland  *		dispose of the storage once the list is no longer needed.
3615c51f124SMoriah Waterland  */
3625c51f124SMoriah Waterland 
3635c51f124SMoriah Waterland zoneList_t
3645c51f124SMoriah Waterland z_get_nonglobal_zone_list(void)
3655c51f124SMoriah Waterland {
3665c51f124SMoriah Waterland 	zoneList_t zones;
3675c51f124SMoriah Waterland 	zoneBrandList_t *brands = NULL;
3685c51f124SMoriah Waterland 
3695c51f124SMoriah Waterland 	if ((brands = z_make_brand_list("native cluster", " ")) == NULL)
3705c51f124SMoriah Waterland 		return (NULL);
3715c51f124SMoriah Waterland 
3725c51f124SMoriah Waterland 	zones = z_get_nonglobal_zone_list_by_brand(brands);
3735c51f124SMoriah Waterland 
3745c51f124SMoriah Waterland 	z_free_brand_list(brands);
3755c51f124SMoriah Waterland 
3765c51f124SMoriah Waterland 	return (zones);
3775c51f124SMoriah Waterland }
3785c51f124SMoriah Waterland 
3795c51f124SMoriah Waterland /*
3805c51f124SMoriah Waterland  * Name:	z_free_brand_list
3815c51f124SMoriah Waterland  * Description: Free contents of zoneBrandList_t object
3825c51f124SMoriah Waterland  * Arguments:	brands - pointer to zoneBrandList_t object to free
3835c51f124SMoriah Waterland  * Returns: 	void
3845c51f124SMoriah Waterland  */
3855c51f124SMoriah Waterland void
3865c51f124SMoriah Waterland z_free_brand_list(zoneBrandList_t *brands)
3875c51f124SMoriah Waterland {
3885c51f124SMoriah Waterland 	while (brands != NULL) {
3895c51f124SMoriah Waterland 		zoneBrandList_t *temp = brands;
3905c51f124SMoriah Waterland 		free(brands->string_ptr);
3915c51f124SMoriah Waterland 		brands = brands->next;
3925c51f124SMoriah Waterland 		free(temp);
3935c51f124SMoriah Waterland 	}
3945c51f124SMoriah Waterland }
3955c51f124SMoriah Waterland 
3965c51f124SMoriah Waterland /*
3975c51f124SMoriah Waterland  * Name:	z_make_brand_list
3985c51f124SMoriah Waterland  * Description:	Given a string with a list of brand name delimited by
3995c51f124SMoriah Waterland  *		the delimeter passed in, build a zoneBrandList_t structure
4005c51f124SMoriah Waterland  *		with the list of brand names and return it to the caller.
4015c51f124SMoriah Waterland  * Arguments:
4025c51f124SMoriah Waterland  *		brands - const char pointer to string list of brand names
4035c51f124SMoriah Waterland  *		delim - const char pointer to string representing the
4045c51f124SMoriah Waterland  *			delimeter for brands string.
4055c51f124SMoriah Waterland  * Returns:	zoneBrandList_t *
4065c51f124SMoriah Waterland  *			== NULL - error, list could not be generated
4075c51f124SMoriah Waterland  *			!= NULL - success, list returned
4085c51f124SMoriah Waterland  * NOTE:	Any zoneBrandList_t returned is placed in new storage for the
4095c51f124SMoriah Waterland  *		calling function.  The caller must use 'z_free_brand_list' to
4105c51f124SMoriah Waterland  *		dispose of the storage once the list is no longer needed.
4115c51f124SMoriah Waterland  */
4125c51f124SMoriah Waterland zoneBrandList_t *
4135c51f124SMoriah Waterland z_make_brand_list(const char *brands, const char *delim)
4145c51f124SMoriah Waterland {
4155c51f124SMoriah Waterland 	zoneBrandList_t *brand = NULL, *head = NULL;
4165c51f124SMoriah Waterland 	char		*blist = NULL;
4175c51f124SMoriah Waterland 	char		*str = NULL;
4185c51f124SMoriah Waterland 
4195c51f124SMoriah Waterland 	if ((blist = strdup(brands)) == NULL)
4205c51f124SMoriah Waterland 		return (NULL);
4215c51f124SMoriah Waterland 
4225c51f124SMoriah Waterland 	if ((str = strtok(blist, delim)) != NULL) {
4235c51f124SMoriah Waterland 		if ((brand = (zoneBrandList_t *)
4245c51f124SMoriah Waterland 		    malloc(sizeof (struct _zoneBrandList))) == NULL) {
4255c51f124SMoriah Waterland 			return (NULL);
4265c51f124SMoriah Waterland 		}
4275c51f124SMoriah Waterland 
4285c51f124SMoriah Waterland 		head = brand;
4295c51f124SMoriah Waterland 		brand->string_ptr = strdup(str);
4305c51f124SMoriah Waterland 		brand->next = NULL;
4315c51f124SMoriah Waterland 
4325c51f124SMoriah Waterland 		while ((str = strtok(NULL, delim)) != NULL) {
4335c51f124SMoriah Waterland 			if ((brand->next = (zoneBrandList_t *)
4345c51f124SMoriah Waterland 			    malloc(sizeof (struct _zoneBrandList))) == NULL) {
4355c51f124SMoriah Waterland 				return (NULL);
4365c51f124SMoriah Waterland 			}
4375c51f124SMoriah Waterland 
4385c51f124SMoriah Waterland 			brand = brand->next;
4395c51f124SMoriah Waterland 			brand->string_ptr = strdup(str);
4405c51f124SMoriah Waterland 			brand->next = NULL;
4415c51f124SMoriah Waterland 		}
4425c51f124SMoriah Waterland 	}
4435c51f124SMoriah Waterland 
4445c51f124SMoriah Waterland 	free(blist);
4455c51f124SMoriah Waterland 	return (head);
4465c51f124SMoriah Waterland }
4475c51f124SMoriah Waterland 
4485c51f124SMoriah Waterland /*
4495c51f124SMoriah Waterland  * Name:	z_get_nonglobal_zone_list_by_brand
4505c51f124SMoriah Waterland  * Description: return zoneList_t object describing all non-global
4515c51f124SMoriah Waterland  *              zones matching the list of brands passed in.
4525c51f124SMoriah Waterland  * Arguments:	brands - The list of zone brands to look for.
4535c51f124SMoriah Waterland  * Returns:	zoneList_t
4545c51f124SMoriah Waterland  *			== NULL - error, list could not be generated
4555c51f124SMoriah Waterland  *			!= NULL - success, list returned
4565c51f124SMoriah Waterland  * NOTE:    	Any zoneList_t returned is placed in new storage for the
4575c51f124SMoriah Waterland  *		calling function. The caller must use 'z_free_zone_list' to
4585c51f124SMoriah Waterland  *		dispose of the storage once the list is no longer needed.
4595c51f124SMoriah Waterland  */
4605c51f124SMoriah Waterland zoneList_t
4615c51f124SMoriah Waterland z_get_nonglobal_zone_list_by_brand(zoneBrandList_t *brands)
4625c51f124SMoriah Waterland {
4635c51f124SMoriah Waterland 	FILE		*zoneIndexFP;
4645c51f124SMoriah Waterland 	int		numzones = 0;
4655c51f124SMoriah Waterland 	struct zoneent	*ze;
4665c51f124SMoriah Waterland 	zoneList_t	zlst = NULL;
4675c51f124SMoriah Waterland 	FILE		*mapFP;
4685c51f124SMoriah Waterland 	char		zonename[ZONENAME_MAX];
4695c51f124SMoriah Waterland 	zone_spec_t	*zent;
4705c51f124SMoriah Waterland 
4715c51f124SMoriah Waterland 	/* if zones are not implemented, return empty list */
4725c51f124SMoriah Waterland 
4735c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
4745c51f124SMoriah Waterland 		return ((zoneList_t)NULL);
4755c51f124SMoriah Waterland 	}
4765c51f124SMoriah Waterland 
4775c51f124SMoriah Waterland 	/*
4785c51f124SMoriah Waterland 	 * Open the zone index file.  Note that getzoneent_private() handles
4795c51f124SMoriah Waterland 	 * NULL.
4805c51f124SMoriah Waterland 	 */
4815c51f124SMoriah Waterland 	zoneIndexFP = setzoneent();
4825c51f124SMoriah Waterland 
4835c51f124SMoriah Waterland 	mapFP = zonecfg_open_scratch("", B_FALSE);
4845c51f124SMoriah Waterland 
4855c51f124SMoriah Waterland 	/* index file open; scan all zones; see if any are at least installed */
4865c51f124SMoriah Waterland 
4875c51f124SMoriah Waterland 	while ((ze = getzoneent_private(zoneIndexFP)) != NULL) {
4885c51f124SMoriah Waterland 		zone_state_t	st;
4895c51f124SMoriah Waterland 
4905c51f124SMoriah Waterland 		/* skip the global zone */
4915c51f124SMoriah Waterland 
4925c51f124SMoriah Waterland 		if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) {
4935c51f124SMoriah Waterland 			free(ze);
4945c51f124SMoriah Waterland 			continue;
4955c51f124SMoriah Waterland 		}
4965c51f124SMoriah Waterland 
4975c51f124SMoriah Waterland 		/*
4985c51f124SMoriah Waterland 		 * skip any zones with brands not on the brand list
4995c51f124SMoriah Waterland 		 */
5005c51f124SMoriah Waterland 		if (!z_is_zone_brand_in_list(ze->zone_name, brands)) {
5015c51f124SMoriah Waterland 			free(ze);
5025c51f124SMoriah Waterland 			continue;
5035c51f124SMoriah Waterland 		}
5045c51f124SMoriah Waterland 
5055c51f124SMoriah Waterland 		/*
5065c51f124SMoriah Waterland 		 * If the user specified an explicit zone list, then ignore any
5075c51f124SMoriah Waterland 		 * zones that aren't on that list.
5085c51f124SMoriah Waterland 		 */
5095c51f124SMoriah Waterland 		if ((zent = _z_global_data._zone_spec) != NULL) {
5105c51f124SMoriah Waterland 			while (zent != NULL) {
5115c51f124SMoriah Waterland 				if (strcmp(zent->zl_name, ze->zone_name) == 0)
5125c51f124SMoriah Waterland 					break;
5135c51f124SMoriah Waterland 				zent = zent->zl_next;
5145c51f124SMoriah Waterland 			}
5155c51f124SMoriah Waterland 			if (zent == NULL) {
5165c51f124SMoriah Waterland 				free(ze);
5175c51f124SMoriah Waterland 				continue;
5185c51f124SMoriah Waterland 			}
5195c51f124SMoriah Waterland 		}
5205c51f124SMoriah Waterland 
5215c51f124SMoriah Waterland 		/* non-global zone: create entry for this zone */
5225c51f124SMoriah Waterland 
5235c51f124SMoriah Waterland 		if (numzones == 0) {
5245c51f124SMoriah Waterland 			zlst = (zoneList_t)_z_calloc(
5255c51f124SMoriah Waterland 			    sizeof (zoneListElement_t)*2);
5265c51f124SMoriah Waterland 		} else {
5275c51f124SMoriah Waterland 			zlst = (zoneList_t)_z_realloc(zlst,
5285c51f124SMoriah Waterland 			    sizeof (zoneListElement_t)*(numzones+2));
5295c51f124SMoriah Waterland 			(void) memset(&zlst[numzones], 0L,
5305c51f124SMoriah Waterland 			    sizeof (zoneListElement_t)*2);
5315c51f124SMoriah Waterland 		}
5325c51f124SMoriah Waterland 
5335c51f124SMoriah Waterland 		/*
5345c51f124SMoriah Waterland 		 * remember the zone name, zonepath and the current
5355c51f124SMoriah Waterland 		 * zone state of the zone.
5365c51f124SMoriah Waterland 		 */
5375c51f124SMoriah Waterland 		zlst[numzones]._zlName = _z_strdup(ze->zone_name);
5385c51f124SMoriah Waterland 		zlst[numzones]._zlPath = _z_strdup(ze->zone_path);
5395c51f124SMoriah Waterland 		zlst[numzones]._zlOrigInstallState = ze->zone_state;
5405c51f124SMoriah Waterland 		zlst[numzones]._zlCurrInstallState = ze->zone_state;
5415c51f124SMoriah Waterland 
5425c51f124SMoriah Waterland 		/* get the zone kernel status */
5435c51f124SMoriah Waterland 
5445c51f124SMoriah Waterland 		if (zone_get_state(ze->zone_name, &st) != Z_OK) {
5455c51f124SMoriah Waterland 			st = ZONE_STATE_INCOMPLETE;
5465c51f124SMoriah Waterland 		}
5475c51f124SMoriah Waterland 
5485c51f124SMoriah Waterland 		_z_echoDebug(DBG_ZONES_NGZ_LIST_STATES,
5495c51f124SMoriah Waterland 		    ze->zone_name, ze->zone_state, st);
5505c51f124SMoriah Waterland 
5515c51f124SMoriah Waterland 		/*
5525c51f124SMoriah Waterland 		 * For a scratch zone, we need to know the kernel zone name.
5535c51f124SMoriah Waterland 		 */
5545c51f124SMoriah Waterland 		if (zonecfg_in_alt_root() && mapFP != NULL &&
5555c51f124SMoriah Waterland 		    zonecfg_find_scratch(mapFP, ze->zone_name,
5565c51f124SMoriah Waterland 		    zonecfg_get_root(), zonename, sizeof (zonename)) != -1) {
5575c51f124SMoriah Waterland 			free(zlst[numzones]._zlScratchName);
5585c51f124SMoriah Waterland 			zlst[numzones]._zlScratchName = _z_strdup(zonename);
5595c51f124SMoriah Waterland 		}
5605c51f124SMoriah Waterland 
5615c51f124SMoriah Waterland 		/*
5625c51f124SMoriah Waterland 		 * remember the current kernel status of the zone.
5635c51f124SMoriah Waterland 		 */
5645c51f124SMoriah Waterland 
5655c51f124SMoriah Waterland 		zlst[numzones]._zlOrigKernelStatus = st;
5665c51f124SMoriah Waterland 		zlst[numzones]._zlCurrKernelStatus = st;
5675c51f124SMoriah Waterland 
5685c51f124SMoriah Waterland 		zlst[numzones]._zlInheritedDirs =
5695c51f124SMoriah Waterland 		    _z_get_inherited_dirs(ze->zone_name);
5705c51f124SMoriah Waterland 
5715c51f124SMoriah Waterland 		numzones++;
5725c51f124SMoriah Waterland 		free(ze);
5735c51f124SMoriah Waterland 	}
5745c51f124SMoriah Waterland 
5755c51f124SMoriah Waterland 	/* close the index file */
5765c51f124SMoriah Waterland 	endzoneent(zoneIndexFP);
5775c51f124SMoriah Waterland 
5785c51f124SMoriah Waterland 	if (mapFP != NULL)
5795c51f124SMoriah Waterland 		zonecfg_close_scratch(mapFP);
5805c51f124SMoriah Waterland 
5815c51f124SMoriah Waterland 	/* return generated list */
5825c51f124SMoriah Waterland 
5835c51f124SMoriah Waterland 	return (zlst);
5845c51f124SMoriah Waterland }
5855c51f124SMoriah Waterland 
5865c51f124SMoriah Waterland /*
5875c51f124SMoriah Waterland  * Name:	z_get_zonename
5885c51f124SMoriah Waterland  * Description:	return the name of the current zone
5895c51f124SMoriah Waterland  * Arguments:	void
5905c51f124SMoriah Waterland  * Returns:	char *
5915c51f124SMoriah Waterland  *			- pointer to string representing the name of the current
5925c51f124SMoriah Waterland  *			zone
5935c51f124SMoriah Waterland  * NOTE:    	Any string returned is placed in new storage for the
5945c51f124SMoriah Waterland  *		calling function. The caller must use 'Free' to dispose
5955c51f124SMoriah Waterland  *		of the storage once the string is no longer needed.
5965c51f124SMoriah Waterland  */
5975c51f124SMoriah Waterland 
5985c51f124SMoriah Waterland char *
5995c51f124SMoriah Waterland z_get_zonename(void)
6005c51f124SMoriah Waterland {
6015c51f124SMoriah Waterland 	ssize_t		zonenameLen;
6025c51f124SMoriah Waterland 	char		zonename[ZONENAME_MAX];
6035c51f124SMoriah Waterland 	zoneid_t	zoneid = (zoneid_t)-1;
6045c51f124SMoriah Waterland 
6055c51f124SMoriah Waterland 	/* if zones are not implemented, return "" */
6065c51f124SMoriah Waterland 
6075c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
6085c51f124SMoriah Waterland 		return (_z_strdup(""));
6095c51f124SMoriah Waterland 	}
6105c51f124SMoriah Waterland 
6115c51f124SMoriah Waterland 	/* get the zone i.d. of the current zone */
6125c51f124SMoriah Waterland 
6135c51f124SMoriah Waterland 	zoneid = getzoneid();
6145c51f124SMoriah Waterland 
6155c51f124SMoriah Waterland 	/* get the name of the current zone */
6165c51f124SMoriah Waterland 
6175c51f124SMoriah Waterland 	zonenameLen = getzonenamebyid(zoneid, zonename, sizeof (zonename));
6185c51f124SMoriah Waterland 
6195c51f124SMoriah Waterland 	/* return "" if could not get zonename */
6205c51f124SMoriah Waterland 
6215c51f124SMoriah Waterland 	if (zonenameLen < 1) {
6225c51f124SMoriah Waterland 		return (_z_strdup(""));
6235c51f124SMoriah Waterland 	}
6245c51f124SMoriah Waterland 
6255c51f124SMoriah Waterland 	return (_z_strdup(zonename));
6265c51f124SMoriah Waterland }
6275c51f124SMoriah Waterland 
6285c51f124SMoriah Waterland /*
6295c51f124SMoriah Waterland  * Name:	z_global_only
6305c51f124SMoriah Waterland  * Description:	Determine if the global zone is only zone on the spec list.
6315c51f124SMoriah Waterland  * Arguments:	None
6325c51f124SMoriah Waterland  * Returns:	B_TRUE if global zone is the only zone on the list,
6335c51f124SMoriah Waterland  *		B_FALSE otherwise.
6345c51f124SMoriah Waterland  */
6355c51f124SMoriah Waterland 
6365c51f124SMoriah Waterland boolean_t
6375c51f124SMoriah Waterland z_global_only(void)
6385c51f124SMoriah Waterland {
6395c51f124SMoriah Waterland 	/* return true if zones are not implemented - treate as global zone */
6405c51f124SMoriah Waterland 
6415c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
6425c51f124SMoriah Waterland 		return (B_TRUE);
6435c51f124SMoriah Waterland 	}
6445c51f124SMoriah Waterland 
6455c51f124SMoriah Waterland 	/* return true if this is the global zone */
6465c51f124SMoriah Waterland 
6475c51f124SMoriah Waterland 	if (_z_global_data._zone_spec != NULL &&
6485c51f124SMoriah Waterland 	    _z_global_data._zone_spec->zl_next == NULL &&
6495c51f124SMoriah Waterland 	    strcmp(_z_global_data._zone_spec->zl_name, GLOBAL_ZONENAME) == 0) {
6505c51f124SMoriah Waterland 		return (B_TRUE);
6515c51f124SMoriah Waterland 	}
6525c51f124SMoriah Waterland 
6535c51f124SMoriah Waterland 	/* return false - not the global zone */
6545c51f124SMoriah Waterland 
6555c51f124SMoriah Waterland 	return (B_FALSE);
6565c51f124SMoriah Waterland }
6575c51f124SMoriah Waterland 
6585c51f124SMoriah Waterland /*
6595c51f124SMoriah Waterland  * Name:	z_lock_this_zone
6605c51f124SMoriah Waterland  * Description:	lock this zone
6615c51f124SMoriah Waterland  * Arguments:	a_lflags - [RO, *RO] - (ZLOCKS_T)
6625c51f124SMoriah Waterland  *			Flags indicating which locks to acquire
6635c51f124SMoriah Waterland  * Returns:	boolean_t
6645c51f124SMoriah Waterland  *			== B_TRUE - success specified locks acquired
6655c51f124SMoriah Waterland  *			== B_FALSE - failure specified locks not acquired
6665c51f124SMoriah Waterland  * NOTE: the lock objects for "this zone" are maintained internally.
6675c51f124SMoriah Waterland  */
6685c51f124SMoriah Waterland 
6695c51f124SMoriah Waterland boolean_t
6705c51f124SMoriah Waterland z_lock_this_zone(ZLOCKS_T a_lflags)
6715c51f124SMoriah Waterland {
6725c51f124SMoriah Waterland 	boolean_t	b;
6735c51f124SMoriah Waterland 	char		*zoneName;
6745c51f124SMoriah Waterland 	pid_t		pid = (pid_t)0;
6755c51f124SMoriah Waterland 
6765c51f124SMoriah Waterland 	/* entry assertions */
6775c51f124SMoriah Waterland 
6785c51f124SMoriah Waterland 	assert(a_lflags != ZLOCKS_NONE);
6795c51f124SMoriah Waterland 
6805c51f124SMoriah Waterland 	/* entry debugging info */
6815c51f124SMoriah Waterland 
6825c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_LCK_THIS, a_lflags);
6835c51f124SMoriah Waterland 
6845c51f124SMoriah Waterland 	zoneName = z_get_zonename();
6855c51f124SMoriah Waterland 	pid = getpid();
6865c51f124SMoriah Waterland 
6875c51f124SMoriah Waterland 	/* lock zone administration */
6885c51f124SMoriah Waterland 
6895c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_ZONE_ADMIN) {
6905c51f124SMoriah Waterland 		b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks,
6915c51f124SMoriah Waterland 		    zoneName, LOBJ_ZONEADMIN, pid,
6925c51f124SMoriah Waterland 		    MSG_ZONES_LCK_THIS_ZONEADM,
6935c51f124SMoriah Waterland 		    ERR_ZONES_LCK_THIS_ZONEADM);
6945c51f124SMoriah Waterland 		if (!b) {
6955c51f124SMoriah Waterland 			(void) free(zoneName);
6965c51f124SMoriah Waterland 			return (B_FALSE);
6975c51f124SMoriah Waterland 		}
6985c51f124SMoriah Waterland 	}
6995c51f124SMoriah Waterland 
7005c51f124SMoriah Waterland 	/* lock package administration always */
7015c51f124SMoriah Waterland 
7025c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_PKG_ADMIN) {
7035c51f124SMoriah Waterland 		b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks,
7045c51f124SMoriah Waterland 		    zoneName, LOBJ_PKGADMIN, pid,
7055c51f124SMoriah Waterland 		    MSG_ZONES_LCK_THIS_PKGADM,
7065c51f124SMoriah Waterland 		    ERR_ZONES_LCK_THIS_PKGADM);
7075c51f124SMoriah Waterland 		if (!b) {
7085c51f124SMoriah Waterland 			(void) z_unlock_this_zone(a_lflags);
7095c51f124SMoriah Waterland 			(void) free(zoneName);
7105c51f124SMoriah Waterland 			return (B_FALSE);
7115c51f124SMoriah Waterland 		}
7125c51f124SMoriah Waterland 	}
7135c51f124SMoriah Waterland 
7145c51f124SMoriah Waterland 	/* lock patch administration always */
7155c51f124SMoriah Waterland 
7165c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_PATCH_ADMIN) {
7175c51f124SMoriah Waterland 		b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks,
7185c51f124SMoriah Waterland 		    zoneName, LOBJ_PATCHADMIN, pid,
7195c51f124SMoriah Waterland 		    MSG_ZONES_LCK_THIS_PATCHADM,
7205c51f124SMoriah Waterland 		    ERR_ZONES_LCK_THIS_PATCHADM);
7215c51f124SMoriah Waterland 		if (!b) {
7225c51f124SMoriah Waterland 			(void) z_unlock_this_zone(a_lflags);
7235c51f124SMoriah Waterland 			(void) free(zoneName);
7245c51f124SMoriah Waterland 			return (B_FALSE);
7255c51f124SMoriah Waterland 		}
7265c51f124SMoriah Waterland 	}
7275c51f124SMoriah Waterland 
7285c51f124SMoriah Waterland 	(void) free(zoneName);
7295c51f124SMoriah Waterland 
7305c51f124SMoriah Waterland 	return (B_TRUE);
7315c51f124SMoriah Waterland }
7325c51f124SMoriah Waterland 
7335c51f124SMoriah Waterland /*
7345c51f124SMoriah Waterland  * Name:	z_lock_zones
7355c51f124SMoriah Waterland  * Description:	lock specified zones
7365c51f124SMoriah Waterland  * Arguments:	a_zlst - zoneList_t object describing zones to lock
7375c51f124SMoriah Waterland  *		a_lflags - [RO, *RO] - (ZLOCKS_T)
7385c51f124SMoriah Waterland  *			Flags indicating which locks to acquire
7395c51f124SMoriah Waterland  * Returns:	boolean_t
7405c51f124SMoriah Waterland  *			== B_TRUE - success, zones locked
7415c51f124SMoriah Waterland  *			== B_FALSE - failure, zones not locked
7425c51f124SMoriah Waterland  */
7435c51f124SMoriah Waterland 
7445c51f124SMoriah Waterland boolean_t
7455c51f124SMoriah Waterland z_lock_zones(zoneList_t a_zlst, ZLOCKS_T a_lflags)
7465c51f124SMoriah Waterland {
7475c51f124SMoriah Waterland 	boolean_t	b;
7485c51f124SMoriah Waterland 	int		i;
7495c51f124SMoriah Waterland 
7505c51f124SMoriah Waterland 	/* entry assertions */
7515c51f124SMoriah Waterland 
7525c51f124SMoriah Waterland 	assert(a_lflags != ZLOCKS_NONE);
7535c51f124SMoriah Waterland 
7545c51f124SMoriah Waterland 	/* entry debugging info */
7555c51f124SMoriah Waterland 
7565c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_LCK_ZONES, a_lflags);
7575c51f124SMoriah Waterland 
7585c51f124SMoriah Waterland 	/* if zones are not implemented, return TRUE */
7595c51f124SMoriah Waterland 
7605c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
7615c51f124SMoriah Waterland 		_z_echoDebug(DBG_ZONES_LCK_ZONES_UNIMP);
7625c51f124SMoriah Waterland 		return (B_TRUE);
7635c51f124SMoriah Waterland 	}
7645c51f124SMoriah Waterland 
7655c51f124SMoriah Waterland 	/* lock this zone first before locking other zones */
7665c51f124SMoriah Waterland 
7675c51f124SMoriah Waterland 	b = z_lock_this_zone(a_lflags);
7685c51f124SMoriah Waterland 	if (b == B_FALSE) {
7695c51f124SMoriah Waterland 		return (b);
7705c51f124SMoriah Waterland 	}
7715c51f124SMoriah Waterland 
7725c51f124SMoriah Waterland 	/* ignore empty list */
7735c51f124SMoriah Waterland 
7745c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
7755c51f124SMoriah Waterland 		_z_echoDebug(DBG_ZONES_LCK_ZONES_NOZONES);
7765c51f124SMoriah Waterland 		return (B_FALSE);
7775c51f124SMoriah Waterland 	}
7785c51f124SMoriah Waterland 
7795c51f124SMoriah Waterland 	/* zones exist */
7805c51f124SMoriah Waterland 
7815c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_LCK_ZONES_EXIST);
7825c51f124SMoriah Waterland 
7835c51f124SMoriah Waterland 	/*
7845c51f124SMoriah Waterland 	 * lock each listed zone that is currently running
7855c51f124SMoriah Waterland 	 */
7865c51f124SMoriah Waterland 
7875c51f124SMoriah Waterland 	for (i = 0; (a_zlst[i]._zlName != (char *)NULL); i++) {
7885c51f124SMoriah Waterland 		/* ignore zone if already locked */
7895c51f124SMoriah Waterland 		if (a_zlst[i]._zlStatus & ZST_LOCKED) {
7905c51f124SMoriah Waterland 			continue;
7915c51f124SMoriah Waterland 		}
7925c51f124SMoriah Waterland 
7935c51f124SMoriah Waterland 		/* ignore zone if not running */
7945c51f124SMoriah Waterland 		if (a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_RUNNING &&
7955c51f124SMoriah Waterland 		    a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_MOUNTED) {
7965c51f124SMoriah Waterland 			continue;
7975c51f124SMoriah Waterland 		}
7985c51f124SMoriah Waterland 
7995c51f124SMoriah Waterland 		/*
8005c51f124SMoriah Waterland 		 * mark zone locked - if interrupted out during lock, an attempt
8015c51f124SMoriah Waterland 		 * will be made to release the lock
8025c51f124SMoriah Waterland 		 */
8035c51f124SMoriah Waterland 		a_zlst[i]._zlStatus |= ZST_LOCKED;
8045c51f124SMoriah Waterland 
8055c51f124SMoriah Waterland 		/* lock this zone */
8065c51f124SMoriah Waterland 		b = _z_lock_zone(&a_zlst[i], a_lflags);
8075c51f124SMoriah Waterland 
8085c51f124SMoriah Waterland 		/* on failure unlock all zones and return error */
8095c51f124SMoriah Waterland 		if (b != B_TRUE) {
8105c51f124SMoriah Waterland 			_z_program_error(ERR_ZONES_LCK_ZONES_FAILED,
8115c51f124SMoriah Waterland 			    a_zlst[i]._zlName);
8125c51f124SMoriah Waterland 			(void) z_unlock_zones(a_zlst, a_lflags);
8135c51f124SMoriah Waterland 			return (B_FALSE);
8145c51f124SMoriah Waterland 		}
8155c51f124SMoriah Waterland 	}
8165c51f124SMoriah Waterland 
8175c51f124SMoriah Waterland 	/* success */
8185c51f124SMoriah Waterland 
8195c51f124SMoriah Waterland 	return (B_TRUE);
8205c51f124SMoriah Waterland }
8215c51f124SMoriah Waterland 
8225c51f124SMoriah Waterland /*
8235c51f124SMoriah Waterland  * Name:	z_mount_in_lz
8245c51f124SMoriah Waterland  * Description:	Mount global zone directory in specified zone's root file system
8255c51f124SMoriah Waterland  * Arguments:	r_lzMountPoint - pointer to handle to string - on success, the
8265c51f124SMoriah Waterland  *			full path to the mount point relative to the global zone
8275c51f124SMoriah Waterland  *			root file system is returned here - this is needed to
8285c51f124SMoriah Waterland  *			unmount the directory when it is no longer needed
8295c51f124SMoriah Waterland  *		r_lzRootPath - pointer to handle to string - on success, the
8305c51f124SMoriah Waterland  *			full path to the mount point relative to the specified
8315c51f124SMoriah Waterland  *			zone's root file system is returned here - this is
8325c51f124SMoriah Waterland  *			passed to any command executing in the specified zone to
8335c51f124SMoriah Waterland  *			access the directory mounted
8345c51f124SMoriah Waterland  *		a_zoneName - pointer to string representing the name of the zone
8355c51f124SMoriah Waterland  *			to mount the specified global zone directory in
8365c51f124SMoriah Waterland  *		a_gzPath - pointer to string representing the full absolute path
8375c51f124SMoriah Waterland  *			of the global zone directory to LOFS mount inside of the
8385c51f124SMoriah Waterland  *			specified non-global zone
8395c51f124SMoriah Waterland  *		a_mountPointPrefix - pointer to string representing the prefix
8405c51f124SMoriah Waterland  *			to be used when creating the mount point name in the
8415c51f124SMoriah Waterland  *			specified zone's root directory
8425c51f124SMoriah Waterland  * Returns:	boolean_t
8435c51f124SMoriah Waterland  *			== B_TRUE - global zone directory mounted successfully
8445c51f124SMoriah Waterland  *			== B_FALSE - failed to mount directory in specified zone
8455c51f124SMoriah Waterland  * NOTE:    	Any strings returned is placed in new storage for the
8465c51f124SMoriah Waterland  *		calling function. The caller must use 'Free' to dispose
8475c51f124SMoriah Waterland  *		of the storage once the strings are no longer needed.
8485c51f124SMoriah Waterland  */
8495c51f124SMoriah Waterland 
8505c51f124SMoriah Waterland boolean_t
8515c51f124SMoriah Waterland z_mount_in_lz(char **r_lzMountPoint, char **r_lzRootPath, char *a_zoneName,
8525c51f124SMoriah Waterland 	char *a_gzPath, char *a_mountPointPrefix)
8535c51f124SMoriah Waterland {
8545c51f124SMoriah Waterland 	char		lzRootPath[MAXPATHLEN] = {'\0'};
8555c51f124SMoriah Waterland 	char		uuid[MAXPATHLEN] = {'\0'};
8565c51f124SMoriah Waterland 	char		gzMountPoint[MAXPATHLEN] = {'\0'};
8575c51f124SMoriah Waterland 	char		lzMountPoint[MAXPATHLEN] = {'\0'};
8585c51f124SMoriah Waterland 	hrtime_t	hretime;
8595c51f124SMoriah Waterland 	int		err;
8605c51f124SMoriah Waterland 	int		slen;
8615c51f124SMoriah Waterland 	struct tm	tstruct;
8625c51f124SMoriah Waterland 	time_t		thetime;
8635c51f124SMoriah Waterland 	zoneid_t	zid;
8645c51f124SMoriah Waterland 
8655c51f124SMoriah Waterland 	/* entry assertions */
8665c51f124SMoriah Waterland 
8675c51f124SMoriah Waterland 	assert(a_zoneName != (char *)NULL);
8685c51f124SMoriah Waterland 	assert(*a_zoneName != '\0');
8695c51f124SMoriah Waterland 	assert(a_gzPath != (char *)NULL);
8705c51f124SMoriah Waterland 	assert(*a_gzPath != '\0');
8715c51f124SMoriah Waterland 	assert(r_lzMountPoint != (char **)NULL);
8725c51f124SMoriah Waterland 	assert(r_lzRootPath != (char **)NULL);
8735c51f124SMoriah Waterland 
8745c51f124SMoriah Waterland 	/* entry debugging info */
8755c51f124SMoriah Waterland 
8765c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_MOUNT_IN_LZ_ENTRY, a_zoneName, a_gzPath);
8775c51f124SMoriah Waterland 
8785c51f124SMoriah Waterland 	/* reset returned non-global zone mount point path handle */
8795c51f124SMoriah Waterland 
8805c51f124SMoriah Waterland 	*r_lzMountPoint = (char *)NULL;
8815c51f124SMoriah Waterland 	*r_lzRootPath = (char *)NULL;
8825c51f124SMoriah Waterland 
8835c51f124SMoriah Waterland 	/* if zones are not implemented, return FALSE */
8845c51f124SMoriah Waterland 
8855c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
8865c51f124SMoriah Waterland 		return (B_FALSE);
8875c51f124SMoriah Waterland 	}
8885c51f124SMoriah Waterland 
8895c51f124SMoriah Waterland 	/* error if global zone path is not absolute */
8905c51f124SMoriah Waterland 
8915c51f124SMoriah Waterland 	if (*a_gzPath != '/') {
8925c51f124SMoriah Waterland 		_z_program_error(ERR_GZPATH_NOT_ABSOLUTE, a_gzPath);
8935c51f124SMoriah Waterland 		return (B_FALSE);
8945c51f124SMoriah Waterland 	}
8955c51f124SMoriah Waterland 
8965c51f124SMoriah Waterland 	/* error if global zone path does not exist */
8975c51f124SMoriah Waterland 
8985c51f124SMoriah Waterland 	if (_z_is_directory(a_gzPath) != 0) {
8995c51f124SMoriah Waterland 		_z_program_error(ERR_GZPATH_NOT_DIR, a_gzPath, strerror(errno));
9005c51f124SMoriah Waterland 		return (B_FALSE);
9015c51f124SMoriah Waterland 	}
9025c51f124SMoriah Waterland 
9035c51f124SMoriah Waterland 	/* verify that specified non-global zone exists */
9045c51f124SMoriah Waterland 
9055c51f124SMoriah Waterland 	err = zone_get_id(a_zoneName, &zid);
9065c51f124SMoriah Waterland 	if (err != Z_OK) {
9075c51f124SMoriah Waterland 		_z_program_error(ERR_GET_ZONEID, a_zoneName,
9085c51f124SMoriah Waterland 		    zonecfg_strerror(err));
9095c51f124SMoriah Waterland 		return (B_FALSE);
9105c51f124SMoriah Waterland 	}
9115c51f124SMoriah Waterland 
9125c51f124SMoriah Waterland 	/* obtain global zone path to non-global zones root file system */
9135c51f124SMoriah Waterland 
9145c51f124SMoriah Waterland 	err = zone_get_rootpath(a_zoneName, lzRootPath, sizeof (lzRootPath));
9155c51f124SMoriah Waterland 	if (err != Z_OK) {
9165c51f124SMoriah Waterland 		_z_program_error(ERR_NO_ZONE_ROOTPATH, a_zoneName,
9175c51f124SMoriah Waterland 		    zonecfg_strerror(err));
9185c51f124SMoriah Waterland 		return (B_FALSE);
9195c51f124SMoriah Waterland 	}
9205c51f124SMoriah Waterland 
9215c51f124SMoriah Waterland 	if (lzRootPath[0] == '\0') {
9225c51f124SMoriah Waterland 		_z_program_error(ERR_ROOTPATH_EMPTY, a_zoneName);
9235c51f124SMoriah Waterland 		return (B_FALSE);
9245c51f124SMoriah Waterland 	}
9255c51f124SMoriah Waterland 
9265c51f124SMoriah Waterland 	/*
9275c51f124SMoriah Waterland 	 * lofs resolve the non-global zone's root path first in case
9285c51f124SMoriah Waterland 	 * its in a path that's been lofs mounted read-only.
9295c51f124SMoriah Waterland 	 * (e.g. This happens when we're tyring to patch a zone in an ABE
9305c51f124SMoriah Waterland 	 * that lives on a filesystem that the ABE shares with the currently
9315c51f124SMoriah Waterland 	 * running BE.)
9325c51f124SMoriah Waterland 	 */
9335c51f124SMoriah Waterland 	z_resolve_lofs(lzRootPath, sizeof (lzRootPath));
9345c51f124SMoriah Waterland 
9355c51f124SMoriah Waterland 	/* verify that the root path exists */
9365c51f124SMoriah Waterland 
9375c51f124SMoriah Waterland 	if (_z_is_directory(lzRootPath) != 0) {
9385c51f124SMoriah Waterland 		_z_program_error(ERR_LZROOT_NOTDIR, lzRootPath,
9395c51f124SMoriah Waterland 		    strerror(errno));
9405c51f124SMoriah Waterland 		return (B_FALSE);
9415c51f124SMoriah Waterland 	}
9425c51f124SMoriah Waterland 
9435c51f124SMoriah Waterland 	/*
9445c51f124SMoriah Waterland 	 * generate a unique key - the key is the same length as unique uid
9455c51f124SMoriah Waterland 	 * but contains different information that is as unique as can be made;
9465c51f124SMoriah Waterland 	 * include current hires time (nanosecond real timer). Such a unique
9475c51f124SMoriah Waterland 	 * i.d. will look like:
9485c51f124SMoriah Waterland 	 *		0203104092-1145345-0004e94d6af481a0
9495c51f124SMoriah Waterland 	 */
9505c51f124SMoriah Waterland 
9515c51f124SMoriah Waterland 	hretime = gethrtime();
9525c51f124SMoriah Waterland 
9535c51f124SMoriah Waterland 	thetime = time((time_t *)NULL);
9545c51f124SMoriah Waterland 	(void) localtime_r(&thetime, &tstruct);
9555c51f124SMoriah Waterland 
9565c51f124SMoriah Waterland 	slen = snprintf(uuid, sizeof (uuid),
9575c51f124SMoriah Waterland 	    UUID_FORMAT,
9585c51f124SMoriah Waterland 	    tstruct.tm_mday, tstruct.tm_mon, tstruct.tm_year,
9595c51f124SMoriah Waterland 	    tstruct.tm_yday, tstruct.tm_hour, tstruct.tm_min,
9605c51f124SMoriah Waterland 	    tstruct.tm_sec,	tstruct.tm_wday, hretime);
9615c51f124SMoriah Waterland 	if (slen > sizeof (uuid)) {
9625c51f124SMoriah Waterland 		_z_program_error(ERR_GZMOUNT_SNPRINTFUUID_FAILED,
9635c51f124SMoriah Waterland 		    UUID_FORMAT, sizeof (uuid));
9645c51f124SMoriah Waterland 		return (B_FALSE);
9655c51f124SMoriah Waterland 	}
9665c51f124SMoriah Waterland 
9675c51f124SMoriah Waterland 	/* create the global zone mount point */
9685c51f124SMoriah Waterland 
9695c51f124SMoriah Waterland 	slen = snprintf(gzMountPoint, sizeof (gzMountPoint), "%s/.SUNW_%s_%s",
9705c51f124SMoriah Waterland 	    lzRootPath,
9715c51f124SMoriah Waterland 	    a_mountPointPrefix ? a_mountPointPrefix : "zones", uuid);
9725c51f124SMoriah Waterland 	if (slen > sizeof (gzMountPoint)) {
9735c51f124SMoriah Waterland 		_z_program_error(ERR_GZMOUNT_SNPRINTFGMP_FAILED,
9745c51f124SMoriah Waterland 		    "%s/.SUNW_%s_%s", lzRootPath,
9755c51f124SMoriah Waterland 		    a_mountPointPrefix ? a_mountPointPrefix : "zones",
9765c51f124SMoriah Waterland 		    uuid, sizeof (gzMountPoint));
9775c51f124SMoriah Waterland 		return (B_FALSE);
9785c51f124SMoriah Waterland 	}
9795c51f124SMoriah Waterland 
9805c51f124SMoriah Waterland 	slen = snprintf(lzMountPoint, sizeof (lzMountPoint), "%s",
9815c51f124SMoriah Waterland 	    gzMountPoint+strlen(lzRootPath));
9825c51f124SMoriah Waterland 	if (slen > sizeof (lzMountPoint)) {
9835c51f124SMoriah Waterland 		_z_program_error(ERR_GZMOUNT_SNPRINTFLMP_FAILED,
9845c51f124SMoriah Waterland 		    "%s", gzMountPoint+strlen(lzRootPath),
9855c51f124SMoriah Waterland 		    sizeof (lzMountPoint));
9865c51f124SMoriah Waterland 		return (B_FALSE);
9875c51f124SMoriah Waterland 	}
9885c51f124SMoriah Waterland 
9895c51f124SMoriah Waterland 	_z_echoDebug(DBG_MNTPT_NAMES, a_gzPath, a_zoneName, gzMountPoint,
9905c51f124SMoriah Waterland 	    lzMountPoint);
9915c51f124SMoriah Waterland 
9925c51f124SMoriah Waterland 	/* error if the mount point already exists */
9935c51f124SMoriah Waterland 
9945c51f124SMoriah Waterland 	if (_z_is_directory(gzMountPoint) == 0) {
9955c51f124SMoriah Waterland 		_z_program_error(ERR_ZONEROOT_NOTDIR, gzMountPoint,
9965c51f124SMoriah Waterland 		    a_zoneName, strerror(errno));
9975c51f124SMoriah Waterland 		return (B_FALSE);
9985c51f124SMoriah Waterland 	}
9995c51f124SMoriah Waterland 
10005c51f124SMoriah Waterland 	/* create the temporary mount point */
10015c51f124SMoriah Waterland 
10025c51f124SMoriah Waterland 	if (mkdir(gzMountPoint, 0600) != 0) {
10035c51f124SMoriah Waterland 		_z_program_error(ERR_MNTPT_MKDIR, gzMountPoint, a_zoneName,
10045c51f124SMoriah Waterland 		    strerror(errno));
10055c51f124SMoriah Waterland 		return (B_FALSE);
10065c51f124SMoriah Waterland 	}
10075c51f124SMoriah Waterland 
10085c51f124SMoriah Waterland 	/* mount the global zone path on the non-global zone root file system */
10095c51f124SMoriah Waterland 
10105c51f124SMoriah Waterland 	err = mount(a_gzPath, gzMountPoint, MS_RDONLY|MS_DATA, "lofs",
10115c51f124SMoriah Waterland 	    (char *)NULL, 0, (char *)NULL, 0);
10125c51f124SMoriah Waterland 	if (err != 0) {
10135c51f124SMoriah Waterland 		_z_program_error(ERR_GZMOUNT_FAILED, a_gzPath,
10145c51f124SMoriah Waterland 		    gzMountPoint, a_zoneName, strerror(errno));
10155c51f124SMoriah Waterland 		return (B_FALSE);
10165c51f124SMoriah Waterland 	}
10175c51f124SMoriah Waterland 
10185c51f124SMoriah Waterland 	/* success - return both mountpoints to caller */
10195c51f124SMoriah Waterland 
10205c51f124SMoriah Waterland 	*r_lzMountPoint = _z_strdup(gzMountPoint);
10215c51f124SMoriah Waterland 
10225c51f124SMoriah Waterland 	*r_lzRootPath = _z_strdup(lzMountPoint);
10235c51f124SMoriah Waterland 
10245c51f124SMoriah Waterland 	/* return success */
10255c51f124SMoriah Waterland 
10265c51f124SMoriah Waterland 	return (B_TRUE);
10275c51f124SMoriah Waterland }
10285c51f124SMoriah Waterland 
10295c51f124SMoriah Waterland /*
10305c51f124SMoriah Waterland  * Name:	z_non_global_zones_exist
10315c51f124SMoriah Waterland  * Description:	Determine if any non-global native zones exist
10325c51f124SMoriah Waterland  * Arguments:	None.
10335c51f124SMoriah Waterland  * Returns:	boolean_t
10345c51f124SMoriah Waterland  *	== B_TRUE - at least one non-global native zone exists
10355c51f124SMoriah Waterland  *	== B_FALSE - no non-global native zone exists
10365c51f124SMoriah Waterland  */
10375c51f124SMoriah Waterland 
10385c51f124SMoriah Waterland boolean_t
10395c51f124SMoriah Waterland z_non_global_zones_exist(void)
10405c51f124SMoriah Waterland {
10415c51f124SMoriah Waterland 	FILE		*zoneIndexFP;
10425c51f124SMoriah Waterland 	boolean_t	anyExist = B_FALSE;
10435c51f124SMoriah Waterland 	struct zoneent	*ze;
10445c51f124SMoriah Waterland 	zone_spec_t	*zent;
10455c51f124SMoriah Waterland 
10465c51f124SMoriah Waterland 	/* if zones are not implemented, return FALSE */
10475c51f124SMoriah Waterland 
10485c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
10495c51f124SMoriah Waterland 		return (B_FALSE);
10505c51f124SMoriah Waterland 	}
10515c51f124SMoriah Waterland 
10525c51f124SMoriah Waterland 	/* determine if any zones are configured */
10535c51f124SMoriah Waterland 	zoneIndexFP = setzoneent();
10545c51f124SMoriah Waterland 	if (zoneIndexFP == NULL) {
10555c51f124SMoriah Waterland 		return (B_FALSE);
10565c51f124SMoriah Waterland 	}
10575c51f124SMoriah Waterland 
10585c51f124SMoriah Waterland 	/* index file open; scan all zones; see if any are at least installed */
10595c51f124SMoriah Waterland 
10605c51f124SMoriah Waterland 	while ((ze = getzoneent_private(zoneIndexFP)) != NULL) {
10615c51f124SMoriah Waterland 		/*
10625c51f124SMoriah Waterland 		 * If the user specified an explicit zone list, then ignore any
10635c51f124SMoriah Waterland 		 * zones that aren't on that list.
10645c51f124SMoriah Waterland 		 */
10655c51f124SMoriah Waterland 		if ((zent = _z_global_data._zone_spec) != NULL) {
10665c51f124SMoriah Waterland 			while (zent != NULL) {
10675c51f124SMoriah Waterland 				if (strcmp(zent->zl_name, ze->zone_name) == 0)
10685c51f124SMoriah Waterland 					break;
10695c51f124SMoriah Waterland 				zent = zent->zl_next;
10705c51f124SMoriah Waterland 			}
10715c51f124SMoriah Waterland 			if (zent == NULL) {
10725c51f124SMoriah Waterland 				free(ze);
10735c51f124SMoriah Waterland 				continue;
10745c51f124SMoriah Waterland 			}
10755c51f124SMoriah Waterland 		}
10765c51f124SMoriah Waterland 
10775c51f124SMoriah Waterland 		/* skip the global zone */
10785c51f124SMoriah Waterland 		if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) {
10795c51f124SMoriah Waterland 			free(ze);
10805c51f124SMoriah Waterland 			continue;
10815c51f124SMoriah Waterland 		}
10825c51f124SMoriah Waterland 
10835c51f124SMoriah Waterland 		/* skip any branded zones */
10845c51f124SMoriah Waterland 		if (z_is_zone_branded(ze->zone_name)) {
10855c51f124SMoriah Waterland 			free(ze);
10865c51f124SMoriah Waterland 			continue;
10875c51f124SMoriah Waterland 		}
10885c51f124SMoriah Waterland 
10895c51f124SMoriah Waterland 		/* is this zone installed? */
10905c51f124SMoriah Waterland 		if (ze->zone_state >= ZONE_STATE_INSTALLED) {
10915c51f124SMoriah Waterland 			free(ze);
10925c51f124SMoriah Waterland 			anyExist = B_TRUE;
10935c51f124SMoriah Waterland 			break;
10945c51f124SMoriah Waterland 		}
10955c51f124SMoriah Waterland 		free(ze);
10965c51f124SMoriah Waterland 	}
10975c51f124SMoriah Waterland 
10985c51f124SMoriah Waterland 	/* close the index file */
10995c51f124SMoriah Waterland 
11005c51f124SMoriah Waterland 	endzoneent(zoneIndexFP);
11015c51f124SMoriah Waterland 
11025c51f124SMoriah Waterland 	/* return results */
11035c51f124SMoriah Waterland 
11045c51f124SMoriah Waterland 	return (anyExist);
11055c51f124SMoriah Waterland }
11065c51f124SMoriah Waterland 
11075c51f124SMoriah Waterland /*
11085c51f124SMoriah Waterland  * Name:	z_on_zone_spec
11095c51f124SMoriah Waterland  * Description:	Determine if named zone is on the zone_spec list.
11105c51f124SMoriah Waterland  * Arguments:	Pointer to name to test.
11115c51f124SMoriah Waterland  * Returns:	B_TRUE if named zone is on the list or if the user specified
11125c51f124SMoriah Waterland  *		no list at all (all zones is the default), B_FALSE otherwise.
11135c51f124SMoriah Waterland  */
11145c51f124SMoriah Waterland 
11155c51f124SMoriah Waterland boolean_t
11165c51f124SMoriah Waterland z_on_zone_spec(const char *zonename)
11175c51f124SMoriah Waterland {
11185c51f124SMoriah Waterland 	zone_spec_t	*zent;
11195c51f124SMoriah Waterland 
11205c51f124SMoriah Waterland 	/* entry assertions */
11215c51f124SMoriah Waterland 
11225c51f124SMoriah Waterland 	assert(zonename != NULL);
11235c51f124SMoriah Waterland 	assert(*zonename != '\0');
11245c51f124SMoriah Waterland 
11255c51f124SMoriah Waterland 	/* return true if zones not implemented or no zone spec list defined */
11265c51f124SMoriah Waterland 
11275c51f124SMoriah Waterland 	if (!z_zones_are_implemented() || _z_global_data._zone_spec == NULL) {
11285c51f124SMoriah Waterland 		return (B_TRUE);
11295c51f124SMoriah Waterland 	}
11305c51f124SMoriah Waterland 
11315c51f124SMoriah Waterland 	/* return true if named zone is on the zone spec list */
11325c51f124SMoriah Waterland 
11335c51f124SMoriah Waterland 	for (zent = _z_global_data._zone_spec;
11345c51f124SMoriah Waterland 	    zent != NULL; zent = zent->zl_next) {
11355c51f124SMoriah Waterland 		if (strcmp(zent->zl_name, zonename) == 0)
11365c51f124SMoriah Waterland 			return (B_TRUE);
11375c51f124SMoriah Waterland 	}
11385c51f124SMoriah Waterland 
11395c51f124SMoriah Waterland 	/* named zone is not on the zone spec list */
11405c51f124SMoriah Waterland 
11415c51f124SMoriah Waterland 	return (B_FALSE);
11425c51f124SMoriah Waterland }
11435c51f124SMoriah Waterland 
11445c51f124SMoriah Waterland /*
11455c51f124SMoriah Waterland  * Name:	z_running_in_global_zone
11465c51f124SMoriah Waterland  * Description:	Determine if running in the "global" zone
11475c51f124SMoriah Waterland  * Arguments:	void
11485c51f124SMoriah Waterland  * Returns:	boolean_t
11495c51f124SMoriah Waterland  *			== B_TRUE - running in global zone
11505c51f124SMoriah Waterland  *			== B_FALSE - not running in global zone
11515c51f124SMoriah Waterland  */
11525c51f124SMoriah Waterland 
11535c51f124SMoriah Waterland boolean_t
11545c51f124SMoriah Waterland z_running_in_global_zone(void)
11555c51f124SMoriah Waterland {
11565c51f124SMoriah Waterland 	static	boolean_t	_zoneIdDetermined = B_FALSE;
11575c51f124SMoriah Waterland 	static	boolean_t	_zoneIsGlobal = B_FALSE;
11585c51f124SMoriah Waterland 
11595c51f124SMoriah Waterland 	/* if ID has not been determined, cache it now */
11605c51f124SMoriah Waterland 
11615c51f124SMoriah Waterland 	if (!_zoneIdDetermined) {
11625c51f124SMoriah Waterland 		_zoneIdDetermined = B_TRUE;
11635c51f124SMoriah Waterland 		_zoneIsGlobal = _z_running_in_global_zone();
11645c51f124SMoriah Waterland 	}
11655c51f124SMoriah Waterland 
11665c51f124SMoriah Waterland 	return (_zoneIsGlobal);
11675c51f124SMoriah Waterland }
11685c51f124SMoriah Waterland 
11695c51f124SMoriah Waterland /*
11705c51f124SMoriah Waterland  * Name:	z_set_output_functions
11715c51f124SMoriah Waterland  * Description:	Link program specific output functions to this library.
11725c51f124SMoriah Waterland  * Arguments:	a_echo_fcn - (_z_printf_fcn_t)
11735c51f124SMoriah Waterland  *			Function to call to cause "normal operation" messages
11745c51f124SMoriah Waterland  *			to be output/displayed
11755c51f124SMoriah Waterland  *		a_echo_debug_fcn - (_z_printf_fcn_t)
11765c51f124SMoriah Waterland  *			Function to call to cause "debugging" messages
11775c51f124SMoriah Waterland  *			to be output/displayed
11785c51f124SMoriah Waterland  *		a_progerr_fcn - (_z_printf_fcn_t)
11795c51f124SMoriah Waterland  *			Function to call to cause "program error" messages
11805c51f124SMoriah Waterland  *			to be output/displayed
11815c51f124SMoriah Waterland  * Returns:	void
11825c51f124SMoriah Waterland  * NOTE:	If NULL is specified for any function, then the functionality
11835c51f124SMoriah Waterland  *		associated with that function is disabled.
11845c51f124SMoriah Waterland  * NOTE:	The function pointers provided must call a function that
11855c51f124SMoriah Waterland  *		takes two arguments:
11865c51f124SMoriah Waterland  *			function(char *format, char *message)
11875c51f124SMoriah Waterland  *		Any registered function will be called like:
11885c51f124SMoriah Waterland  *			function("%s", "message")
11895c51f124SMoriah Waterland  */
11905c51f124SMoriah Waterland 
11915c51f124SMoriah Waterland void
11925c51f124SMoriah Waterland z_set_output_functions(_z_printf_fcn_t a_echo_fcn,
11935c51f124SMoriah Waterland     _z_printf_fcn_t a_echo_debug_fcn,
11945c51f124SMoriah Waterland     _z_printf_fcn_t a_progerr_fcn)
11955c51f124SMoriah Waterland {
11965c51f124SMoriah Waterland 	_z_global_data._z_echo = a_echo_fcn;
11975c51f124SMoriah Waterland 	_z_global_data._z_echo_debug = a_echo_debug_fcn;
11985c51f124SMoriah Waterland 	_z_global_data._z_progerr = a_progerr_fcn;
11995c51f124SMoriah Waterland }
12005c51f124SMoriah Waterland 
12015c51f124SMoriah Waterland /*
12025c51f124SMoriah Waterland  * Name:	z_set_zone_root
12035c51f124SMoriah Waterland  * Description:	Set root for zones library operations
12045c51f124SMoriah Waterland  * Arguments:	Path to root of boot environment containing zone; must be
12055c51f124SMoriah Waterland  *		absolute.
12065c51f124SMoriah Waterland  * Returns:	None.
12075c51f124SMoriah Waterland  * NOTE:	Must be called before performing any zone-related operations.
12085c51f124SMoriah Waterland  *		(Currently called directly by set_inst_root() during -R
12095c51f124SMoriah Waterland  *		argument handling.)
12105c51f124SMoriah Waterland  */
12115c51f124SMoriah Waterland 
12125c51f124SMoriah Waterland void
12135c51f124SMoriah Waterland z_set_zone_root(const char *zroot)
12145c51f124SMoriah Waterland {
12155c51f124SMoriah Waterland 	char *rootdir;
12165c51f124SMoriah Waterland 
12175c51f124SMoriah Waterland 	/* if zones are not implemented, just return */
12185c51f124SMoriah Waterland 
12195c51f124SMoriah Waterland 	if (!z_zones_are_implemented())
12205c51f124SMoriah Waterland 		return;
12215c51f124SMoriah Waterland 
12225c51f124SMoriah Waterland 	/* entry assertions */
12235c51f124SMoriah Waterland 
12245c51f124SMoriah Waterland 	assert(zroot != NULL);
12255c51f124SMoriah Waterland 
12265c51f124SMoriah Waterland 	rootdir = _z_strdup((char *)zroot);
12275c51f124SMoriah Waterland 	z_canoninplace(rootdir);
12285c51f124SMoriah Waterland 
12295c51f124SMoriah Waterland 	if (strcmp(rootdir, "/") == 0) {
12305c51f124SMoriah Waterland 		rootdir[0] = '\0';
12315c51f124SMoriah Waterland 	}
12325c51f124SMoriah Waterland 
12335c51f124SMoriah Waterland 	/* free any existing cached root path */
12345c51f124SMoriah Waterland 	if (*_z_global_data._z_root_dir != '\0') {
12355c51f124SMoriah Waterland 		free(_z_global_data._z_root_dir);
1236*94a65b20SAbhinandan Ekande 		_z_global_data._z_root_dir = NULL;
12375c51f124SMoriah Waterland 	}
12385c51f124SMoriah Waterland 
12395c51f124SMoriah Waterland 	/* store duplicate of new zone root path */
12405c51f124SMoriah Waterland 
12415c51f124SMoriah Waterland 	if (*rootdir != '\0') {
12425c51f124SMoriah Waterland 		_z_global_data._z_root_dir = _z_strdup(rootdir);
12435c51f124SMoriah Waterland 	} else {
1244*94a65b20SAbhinandan Ekande 		_z_global_data._z_root_dir = "";
12455c51f124SMoriah Waterland 	}
12465c51f124SMoriah Waterland 
12475c51f124SMoriah Waterland 	/* set zone root path */
12485c51f124SMoriah Waterland 
12495c51f124SMoriah Waterland 	zonecfg_set_root(rootdir);
12505c51f124SMoriah Waterland 
12515c51f124SMoriah Waterland 	free(rootdir);
12525c51f124SMoriah Waterland }
12535c51f124SMoriah Waterland 
12545c51f124SMoriah Waterland /*
12555c51f124SMoriah Waterland  * Name:	z_set_zone_spec
12565c51f124SMoriah Waterland  * Description:	Set list of zones on which actions will be performed.
12575c51f124SMoriah Waterland  * Arguments:	Whitespace-separated list of zone names.
12585c51f124SMoriah Waterland  * Returns:	0 on success, -1 on error.
12595c51f124SMoriah Waterland  * NOTES:	Will call _z_program_error if argument can't be parsed or
12605c51f124SMoriah Waterland  *		memory not available.
12615c51f124SMoriah Waterland  */
12625c51f124SMoriah Waterland 
12635c51f124SMoriah Waterland int
12645c51f124SMoriah Waterland z_set_zone_spec(const char *zlist)
12655c51f124SMoriah Waterland {
12665c51f124SMoriah Waterland 	const char	*zend;
12675c51f124SMoriah Waterland 	ptrdiff_t	zlen;
12685c51f124SMoriah Waterland 	zone_spec_t	*zent;
12695c51f124SMoriah Waterland 	zone_spec_t	*zhead;
12705c51f124SMoriah Waterland 	zone_spec_t	**znextp = &zhead;
12715c51f124SMoriah Waterland 
12725c51f124SMoriah Waterland 	/* entry assertions */
12735c51f124SMoriah Waterland 
12745c51f124SMoriah Waterland 	assert(zlist != NULL);
12755c51f124SMoriah Waterland 
12765c51f124SMoriah Waterland 	/* parse list to zone_spec_t list, store in global data */
12775c51f124SMoriah Waterland 
12785c51f124SMoriah Waterland 	for (;;) {
12795c51f124SMoriah Waterland 		while (isspace(*zlist)) {
12805c51f124SMoriah Waterland 			zlist++;
12815c51f124SMoriah Waterland 		}
12825c51f124SMoriah Waterland 		if (*zlist == '\0') {
12835c51f124SMoriah Waterland 			break;
12845c51f124SMoriah Waterland 		}
12855c51f124SMoriah Waterland 		for (zend = zlist; *zend != '\0'; zend++) {
12865c51f124SMoriah Waterland 			if (isspace(*zend)) {
12875c51f124SMoriah Waterland 				break;
12885c51f124SMoriah Waterland 			}
12895c51f124SMoriah Waterland 		}
12905c51f124SMoriah Waterland 		zlen = ((ptrdiff_t)zend) - ((ptrdiff_t)zlist);
12915c51f124SMoriah Waterland 		if (zlen >= ZONENAME_MAX) {
12925c51f124SMoriah Waterland 			_z_program_error(ERR_ZONE_NAME_ILLEGAL, zlen, zlist);
12935c51f124SMoriah Waterland 			return (-1);
12945c51f124SMoriah Waterland 		}
12955c51f124SMoriah Waterland 		zent = _z_malloc(sizeof (*zent));
12965c51f124SMoriah Waterland 		(void) memcpy(zent->zl_name, zlist, zlen);
12975c51f124SMoriah Waterland 		zent->zl_name[zlen] = '\0';
12985c51f124SMoriah Waterland 		zent->zl_used = B_FALSE;
12995c51f124SMoriah Waterland 		*znextp = zent;
13005c51f124SMoriah Waterland 		znextp = &zent->zl_next;
13015c51f124SMoriah Waterland 		zlist = zend;
13025c51f124SMoriah Waterland 	}
13035c51f124SMoriah Waterland 	*znextp = NULL;
13045c51f124SMoriah Waterland 
13055c51f124SMoriah Waterland 	if (zhead == NULL) {
13065c51f124SMoriah Waterland 		_z_program_error(ERR_ZONE_LIST_EMPTY);
13075c51f124SMoriah Waterland 		return (-1);
13085c51f124SMoriah Waterland 	}
13095c51f124SMoriah Waterland 
13105c51f124SMoriah Waterland 	_z_global_data._zone_spec = zhead;
13115c51f124SMoriah Waterland 	return (0);
13125c51f124SMoriah Waterland }
13135c51f124SMoriah Waterland 
13145c51f124SMoriah Waterland /*
13155c51f124SMoriah Waterland  * Name:	z_umount_lz_mount
13165c51f124SMoriah Waterland  * Description:	Unmount directory mounted with z_mount_in_lz
13175c51f124SMoriah Waterland  * Arguments:	a_lzMountPointer - pointer to string returned by z_mount_in_lz
13185c51f124SMoriah Waterland  * Returns:	boolean_t
13195c51f124SMoriah Waterland  *			== B_TRUE - successfully unmounted directory
13205c51f124SMoriah Waterland  *			== B_FALSE - failed to unmount directory
13215c51f124SMoriah Waterland  */
13225c51f124SMoriah Waterland 
13235c51f124SMoriah Waterland boolean_t
13245c51f124SMoriah Waterland z_umount_lz_mount(char *a_lzMountPoint)
13255c51f124SMoriah Waterland {
13265c51f124SMoriah Waterland 	int	err;
13275c51f124SMoriah Waterland 
13285c51f124SMoriah Waterland 	/* entry assertions */
13295c51f124SMoriah Waterland 
13305c51f124SMoriah Waterland 	assert(a_lzMountPoint != (char *)NULL);
13315c51f124SMoriah Waterland 	assert(*a_lzMountPoint != '\0');
13325c51f124SMoriah Waterland 
13335c51f124SMoriah Waterland 	/* entry debugging info */
13345c51f124SMoriah Waterland 
13355c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_UNMOUNT_FROM_LZ_ENTRY, a_lzMountPoint);
13365c51f124SMoriah Waterland 
13375c51f124SMoriah Waterland 	/* if zones are not implemented, return TRUE */
13385c51f124SMoriah Waterland 
13395c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
13405c51f124SMoriah Waterland 		return (B_FALSE);
13415c51f124SMoriah Waterland 	}
13425c51f124SMoriah Waterland 
13435c51f124SMoriah Waterland 	/* error if global zone path is not absolute */
13445c51f124SMoriah Waterland 
13455c51f124SMoriah Waterland 	if (*a_lzMountPoint != '/') {
13465c51f124SMoriah Waterland 		_z_program_error(ERR_LZMNTPT_NOT_ABSOLUTE, a_lzMountPoint);
13475c51f124SMoriah Waterland 		return (B_FALSE);
13485c51f124SMoriah Waterland 	}
13495c51f124SMoriah Waterland 
13505c51f124SMoriah Waterland 	/* verify mount point exists */
13515c51f124SMoriah Waterland 
13525c51f124SMoriah Waterland 	if (_z_is_directory(a_lzMountPoint) != 0) {
13535c51f124SMoriah Waterland 		_z_program_error(ERR_LZMNTPT_NOTDIR, a_lzMountPoint,
13545c51f124SMoriah Waterland 		    strerror(errno));
13555c51f124SMoriah Waterland 		return (B_FALSE);
13565c51f124SMoriah Waterland 	}
13575c51f124SMoriah Waterland 
13585c51f124SMoriah Waterland 	/* unmount */
13595c51f124SMoriah Waterland 
13605c51f124SMoriah Waterland 	err = umount2(a_lzMountPoint, 0);
13615c51f124SMoriah Waterland 	if (err != 0) {
13625c51f124SMoriah Waterland 		_z_program_error(ERR_GZUMOUNT_FAILED, a_lzMountPoint,
13635c51f124SMoriah Waterland 		    strerror(errno));
13645c51f124SMoriah Waterland 		return (B_FALSE);
13655c51f124SMoriah Waterland 	}
13665c51f124SMoriah Waterland 
13675c51f124SMoriah Waterland 	/* remove the mount point */
13685c51f124SMoriah Waterland 
13695c51f124SMoriah Waterland 	(void) remove(a_lzMountPoint);
13705c51f124SMoriah Waterland 
13715c51f124SMoriah Waterland 	/* return success */
13725c51f124SMoriah Waterland 
13735c51f124SMoriah Waterland 	return (B_TRUE);
13745c51f124SMoriah Waterland }
13755c51f124SMoriah Waterland 
13765c51f124SMoriah Waterland /*
13775c51f124SMoriah Waterland  * Name:	z_unlock_this_zone
13785c51f124SMoriah Waterland  * Description:	unlock this zone
13795c51f124SMoriah Waterland  * Arguments:	a_lflags - [RO, *RO] - (ZLOCKS_T)
13805c51f124SMoriah Waterland  *			Flags indicating which locks to release
13815c51f124SMoriah Waterland  * Returns:	boolean_t
13825c51f124SMoriah Waterland  *			== B_TRUE - success specified locks released
13835c51f124SMoriah Waterland  *			== B_FALSE - failure specified locks may not be released
13845c51f124SMoriah Waterland  * NOTE: the lock objects for "this zone" are maintained internally.
13855c51f124SMoriah Waterland  */
13865c51f124SMoriah Waterland 
13875c51f124SMoriah Waterland boolean_t
13885c51f124SMoriah Waterland z_unlock_this_zone(ZLOCKS_T a_lflags)
13895c51f124SMoriah Waterland {
13905c51f124SMoriah Waterland 	boolean_t	b;
13915c51f124SMoriah Waterland 	boolean_t	errors = B_FALSE;
13925c51f124SMoriah Waterland 	char		*zoneName;
13935c51f124SMoriah Waterland 
13945c51f124SMoriah Waterland 	/* entry assertions */
13955c51f124SMoriah Waterland 
13965c51f124SMoriah Waterland 	assert(a_lflags != ZLOCKS_NONE);
13975c51f124SMoriah Waterland 
13985c51f124SMoriah Waterland 	/* entry debugging info */
13995c51f124SMoriah Waterland 
14005c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_ULK_THIS, a_lflags);
14015c51f124SMoriah Waterland 
14025c51f124SMoriah Waterland 	/* return if no objects locked */
14035c51f124SMoriah Waterland 
14045c51f124SMoriah Waterland 	if ((_z_global_data._z_ObjectLocks == (char *)NULL) ||
14055c51f124SMoriah Waterland 	    (*_z_global_data._z_ObjectLocks == '\0')) {
14065c51f124SMoriah Waterland 		return (B_TRUE);
14075c51f124SMoriah Waterland 	}
14085c51f124SMoriah Waterland 
14095c51f124SMoriah Waterland 	zoneName = z_get_zonename();
14105c51f124SMoriah Waterland 
14115c51f124SMoriah Waterland 	/* unlock patch administration */
14125c51f124SMoriah Waterland 
14135c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_PATCH_ADMIN) {
14145c51f124SMoriah Waterland 		b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks,
14155c51f124SMoriah Waterland 		    zoneName, LOBJ_PATCHADMIN, ERR_ZONES_ULK_THIS_PATCH);
14165c51f124SMoriah Waterland 		if (!b) {
14175c51f124SMoriah Waterland 			errors = B_TRUE;
14185c51f124SMoriah Waterland 		}
14195c51f124SMoriah Waterland 	}
14205c51f124SMoriah Waterland 
14215c51f124SMoriah Waterland 	/* unlock package administration */
14225c51f124SMoriah Waterland 
14235c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_PKG_ADMIN) {
14245c51f124SMoriah Waterland 		b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks,
14255c51f124SMoriah Waterland 		    zoneName, LOBJ_PKGADMIN, ERR_ZONES_ULK_THIS_PACKAGE);
14265c51f124SMoriah Waterland 		if (!b) {
14275c51f124SMoriah Waterland 			errors = B_TRUE;
14285c51f124SMoriah Waterland 		}
14295c51f124SMoriah Waterland 	}
14305c51f124SMoriah Waterland 
14315c51f124SMoriah Waterland 	/* unlock zone administration */
14325c51f124SMoriah Waterland 
14335c51f124SMoriah Waterland 	if (a_lflags & ZLOCKS_ZONE_ADMIN) {
14345c51f124SMoriah Waterland 		b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks,
14355c51f124SMoriah Waterland 		    zoneName, LOBJ_ZONEADMIN, ERR_ZONES_ULK_THIS_ZONES);
14365c51f124SMoriah Waterland 		if (!b) {
14375c51f124SMoriah Waterland 			errors = B_TRUE;
14385c51f124SMoriah Waterland 		}
14395c51f124SMoriah Waterland 	}
14405c51f124SMoriah Waterland 
14415c51f124SMoriah Waterland 	(void) free(zoneName);
14425c51f124SMoriah Waterland 	return (!errors);
14435c51f124SMoriah Waterland }
14445c51f124SMoriah Waterland 
14455c51f124SMoriah Waterland /*
14465c51f124SMoriah Waterland  * Name:	z_unlock_zones
14475c51f124SMoriah Waterland  * Description:	unlock specified zones
14485c51f124SMoriah Waterland  * Arguments:	a_zlst - zoneList_t object describing zones to unlock
14495c51f124SMoriah Waterland  *		a_lflags - [RO, *RO] - (ZLOCKS_T)
14505c51f124SMoriah Waterland  *			Flags indicating which locks to release
14515c51f124SMoriah Waterland  * Returns:	boolean_t
14525c51f124SMoriah Waterland  *			== B_TRUE - success, zones unlocked
14535c51f124SMoriah Waterland  *			== B_FALSE - failure, zones not unlocked
14545c51f124SMoriah Waterland  */
14555c51f124SMoriah Waterland 
14565c51f124SMoriah Waterland boolean_t
14575c51f124SMoriah Waterland z_unlock_zones(zoneList_t a_zlst, ZLOCKS_T a_lflags)
14585c51f124SMoriah Waterland {
14595c51f124SMoriah Waterland 	boolean_t	b;
14605c51f124SMoriah Waterland 	boolean_t	errors = B_FALSE;
14615c51f124SMoriah Waterland 	int		i;
14625c51f124SMoriah Waterland 
14635c51f124SMoriah Waterland 	/* entry assertions */
14645c51f124SMoriah Waterland 
14655c51f124SMoriah Waterland 	assert(a_lflags != ZLOCKS_NONE);
14665c51f124SMoriah Waterland 
14675c51f124SMoriah Waterland 	/* entry debugging info */
14685c51f124SMoriah Waterland 
14695c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_ULK_ZONES, a_lflags);
14705c51f124SMoriah Waterland 
14715c51f124SMoriah Waterland 	/* if zones are not implemented, return TRUE */
14725c51f124SMoriah Waterland 
14735c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
14745c51f124SMoriah Waterland 		_z_echoDebug(DBG_ZONES_ULK_ZONES_UNIMP);
14755c51f124SMoriah Waterland 		return (B_TRUE);
14765c51f124SMoriah Waterland 	}
14775c51f124SMoriah Waterland 
14785c51f124SMoriah Waterland 	/* ignore empty list */
14795c51f124SMoriah Waterland 
14805c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
14815c51f124SMoriah Waterland 		_z_echoDebug(DBG_ZONES_ULK_ZONES_NOZONES);
14825c51f124SMoriah Waterland 		/* unlock this zone before returning */
14835c51f124SMoriah Waterland 		return (z_unlock_this_zone(a_lflags));
14845c51f124SMoriah Waterland 	}
14855c51f124SMoriah Waterland 
14865c51f124SMoriah Waterland 	/* zones exist */
14875c51f124SMoriah Waterland 
14885c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_ULK_ZONES_EXIST);
14895c51f124SMoriah Waterland 
14905c51f124SMoriah Waterland 	/*
14915c51f124SMoriah Waterland 	 * unlock each listed zone that is currently running
14925c51f124SMoriah Waterland 	 */
14935c51f124SMoriah Waterland 
14945c51f124SMoriah Waterland 	for (i = 0; (a_zlst[i]._zlName != (char *)NULL); i++) {
14955c51f124SMoriah Waterland 		/* ignore zone if not locked */
14965c51f124SMoriah Waterland 		if (!(a_zlst[i]._zlStatus & ZST_LOCKED)) {
14975c51f124SMoriah Waterland 			continue;
14985c51f124SMoriah Waterland 		}
14995c51f124SMoriah Waterland 
15005c51f124SMoriah Waterland 		/* ignore zone if not running */
15015c51f124SMoriah Waterland 		if (a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_RUNNING &&
15025c51f124SMoriah Waterland 		    a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_MOUNTED) {
15035c51f124SMoriah Waterland 			continue;
15045c51f124SMoriah Waterland 		}
15055c51f124SMoriah Waterland 
15065c51f124SMoriah Waterland 		/* unlock this zone */
15075c51f124SMoriah Waterland 		b = _z_unlock_zone(&a_zlst[i], a_lflags);
15085c51f124SMoriah Waterland 
15095c51f124SMoriah Waterland 		if (b != B_TRUE) {
15105c51f124SMoriah Waterland 			errors = B_TRUE;
15115c51f124SMoriah Waterland 		} else {
15125c51f124SMoriah Waterland 			/* mark zone as unlocked */
15135c51f124SMoriah Waterland 			a_zlst[i]._zlStatus &= ~ZST_LOCKED;
15145c51f124SMoriah Waterland 		}
15155c51f124SMoriah Waterland 	}
15165c51f124SMoriah Waterland 
15175c51f124SMoriah Waterland 	/* unlock this zone */
15185c51f124SMoriah Waterland 
15195c51f124SMoriah Waterland 	if (z_unlock_this_zone(a_lflags) != B_TRUE) {
15205c51f124SMoriah Waterland 		errors = B_TRUE;
15215c51f124SMoriah Waterland 	}
15225c51f124SMoriah Waterland 
15235c51f124SMoriah Waterland 	return (errors);
15245c51f124SMoriah Waterland }
15255c51f124SMoriah Waterland 
15265c51f124SMoriah Waterland /*
15275c51f124SMoriah Waterland  * Name:	z_verify_zone_spec
15285c51f124SMoriah Waterland  * Description:	Verify list of zones on which actions will be performed.
15295c51f124SMoriah Waterland  * Arguments:	None.
15305c51f124SMoriah Waterland  * Returns:	0 on success, -1 on error.
15315c51f124SMoriah Waterland  * NOTES:	Will call _z_program_error if there are zones on the specified
15325c51f124SMoriah Waterland  *		list that don't exist on the system. Requires that
15335c51f124SMoriah Waterland  *		z_set_zone_root is called first (if it is called at all).
15345c51f124SMoriah Waterland  */
15355c51f124SMoriah Waterland 
15365c51f124SMoriah Waterland int
15375c51f124SMoriah Waterland z_verify_zone_spec(void)
15385c51f124SMoriah Waterland {
15395c51f124SMoriah Waterland 	FILE		*zoneIndexFP;
15405c51f124SMoriah Waterland 	boolean_t	errors;
15415c51f124SMoriah Waterland 	char		zoneIndexPath[MAXPATHLEN];
15425c51f124SMoriah Waterland 	struct zoneent	*ze;
15435c51f124SMoriah Waterland 	zone_spec_t	*zent;
15445c51f124SMoriah Waterland 
15455c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
15465c51f124SMoriah Waterland 		_z_program_error(ERR_ZONES_NOT_IMPLEMENTED);
15475c51f124SMoriah Waterland 		return (-1);
15485c51f124SMoriah Waterland 	}
15495c51f124SMoriah Waterland 
15505c51f124SMoriah Waterland 	zoneIndexFP = setzoneent();
15515c51f124SMoriah Waterland 	if (zoneIndexFP == NULL) {
15525c51f124SMoriah Waterland 		_z_program_error(ERR_ZONEINDEX_OPEN, zoneIndexPath,
15535c51f124SMoriah Waterland 		    strerror(errno));
15545c51f124SMoriah Waterland 		return (-1);
15555c51f124SMoriah Waterland 	}
15565c51f124SMoriah Waterland 
15575c51f124SMoriah Waterland 	while ((ze = getzoneent_private(zoneIndexFP)) != NULL) {
15585c51f124SMoriah Waterland 		for (zent = _z_global_data._zone_spec;
15595c51f124SMoriah Waterland 		    zent != NULL; zent = zent->zl_next) {
15605c51f124SMoriah Waterland 			if (strcmp(zent->zl_name, ze->zone_name) == 0) {
15615c51f124SMoriah Waterland 				zent->zl_used = B_TRUE;
15625c51f124SMoriah Waterland 				break;
15635c51f124SMoriah Waterland 			}
15645c51f124SMoriah Waterland 		}
15655c51f124SMoriah Waterland 		free(ze);
15665c51f124SMoriah Waterland 	}
15675c51f124SMoriah Waterland 	endzoneent(zoneIndexFP);
15685c51f124SMoriah Waterland 
15695c51f124SMoriah Waterland 	errors = B_FALSE;
15705c51f124SMoriah Waterland 	for (zent = _z_global_data._zone_spec;
15715c51f124SMoriah Waterland 	    zent != NULL; zent = zent->zl_next) {
15725c51f124SMoriah Waterland 		if (!zent->zl_used) {
15735c51f124SMoriah Waterland 			_z_program_error(ERR_ZONE_NONEXISTENT, zent->zl_name);
15745c51f124SMoriah Waterland 			errors = B_TRUE;
15755c51f124SMoriah Waterland 		}
15765c51f124SMoriah Waterland 	}
15775c51f124SMoriah Waterland 	return (errors ? -1 : 0);
15785c51f124SMoriah Waterland }
15795c51f124SMoriah Waterland 
15805c51f124SMoriah Waterland /*
15815c51f124SMoriah Waterland  * Name:	z_zlist_change_zone_state
15825c51f124SMoriah Waterland  * Description:	Change the current state of the specified zone
15835c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
15845c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return the
15855c51f124SMoriah Waterland  *		a_newState - the state to put the specified zone in
15865c51f124SMoriah Waterland  * Returns:	boolean_t
15875c51f124SMoriah Waterland  *			== B_TRUE - the zone is in the new state
15885c51f124SMoriah Waterland  *			== B_FALSE - unable to transition the zone to the
15895c51f124SMoriah Waterland  *				specified state
15905c51f124SMoriah Waterland  * NOTE:	This changes the "current kernel" state of the specified
15915c51f124SMoriah Waterland  *		zone. For example, to boot the zone, change the state
15925c51f124SMoriah Waterland  *		to "ZONE_STATE_RUNNING". To halt the zone, change the
15935c51f124SMoriah Waterland  *		state to "ZONE_STATE_INSTALLED".
15945c51f124SMoriah Waterland  */
15955c51f124SMoriah Waterland 
15965c51f124SMoriah Waterland boolean_t
15975c51f124SMoriah Waterland z_zlist_change_zone_state(zoneList_t a_zlst, int a_zoneIndex,
15985c51f124SMoriah Waterland 	zone_state_t a_newState)
15995c51f124SMoriah Waterland {
16005c51f124SMoriah Waterland 	int	i;
16015c51f124SMoriah Waterland 
16025c51f124SMoriah Waterland 	/* entry debugging info */
16035c51f124SMoriah Waterland 
16045c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_CHG_Z_STATE_ENTRY, a_zoneIndex, a_newState);
16055c51f124SMoriah Waterland 
16065c51f124SMoriah Waterland 	/* ignore empty list */
16075c51f124SMoriah Waterland 
16085c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
16095c51f124SMoriah Waterland 		return (B_FALSE);
16105c51f124SMoriah Waterland 	}
16115c51f124SMoriah Waterland 
16125c51f124SMoriah Waterland 	/* find the specified zone in the list */
16135c51f124SMoriah Waterland 
16145c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
16155c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
16165c51f124SMoriah Waterland 		;
16175c51f124SMoriah Waterland 
16185c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
16195c51f124SMoriah Waterland 
16205c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
16215c51f124SMoriah Waterland 		return (B_FALSE);
16225c51f124SMoriah Waterland 	}
16235c51f124SMoriah Waterland 
16245c51f124SMoriah Waterland 	/* return success if the zone is already in this state */
16255c51f124SMoriah Waterland 
16265c51f124SMoriah Waterland 	if (a_zlst[i]._zlCurrKernelStatus == a_newState) {
16275c51f124SMoriah Waterland 		return (B_TRUE);
16285c51f124SMoriah Waterland 	}
16295c51f124SMoriah Waterland 
16305c51f124SMoriah Waterland 	/* take action on new state to set zone to */
16315c51f124SMoriah Waterland 
16325c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_CHG_Z_STATE, a_zlst[i]._zlName,
16335c51f124SMoriah Waterland 	    a_zlst[i]._zlCurrKernelStatus, a_newState);
16345c51f124SMoriah Waterland 
16355c51f124SMoriah Waterland 	switch (a_newState) {
16365c51f124SMoriah Waterland 	case ZONE_STATE_RUNNING:
16375c51f124SMoriah Waterland 	case ZONE_STATE_MOUNTED:
16385c51f124SMoriah Waterland 		/* these states mean "boot the zone" */
16395c51f124SMoriah Waterland 		return (_z_make_zone_running(&a_zlst[i]));
16405c51f124SMoriah Waterland 
16415c51f124SMoriah Waterland 	case ZONE_STATE_DOWN:
16425c51f124SMoriah Waterland 	case ZONE_STATE_INSTALLED:
16435c51f124SMoriah Waterland 		/* these states mean "halt the zone" */
16445c51f124SMoriah Waterland 		return (_z_make_zone_down(&a_zlst[i]));
16455c51f124SMoriah Waterland 
16465c51f124SMoriah Waterland 	case ZONE_STATE_READY:
16475c51f124SMoriah Waterland 		return (_z_make_zone_ready(&a_zlst[i]));
16485c51f124SMoriah Waterland 
16495c51f124SMoriah Waterland 	case ZONE_STATE_CONFIGURED:
16505c51f124SMoriah Waterland 	case ZONE_STATE_INCOMPLETE:
16515c51f124SMoriah Waterland 	case ZONE_STATE_SHUTTING_DOWN:
16525c51f124SMoriah Waterland 	default:
16535c51f124SMoriah Waterland 		/* do not know how to change zone to this state */
16545c51f124SMoriah Waterland 		return (B_FALSE);
16555c51f124SMoriah Waterland 	}
16565c51f124SMoriah Waterland }
16575c51f124SMoriah Waterland 
16585c51f124SMoriah Waterland /*
16595c51f124SMoriah Waterland  * Name:	z_is_zone_branded
16605c51f124SMoriah Waterland  * Description:	Determine whether zone has a non-native brand
16615c51f124SMoriah Waterland  * Arguments:	a_zoneName - name of the zone to check for branding
16625c51f124SMoriah Waterland  * Returns:	boolean_t
16635c51f124SMoriah Waterland  *			== B_TRUE - zone has a non-native brand
16645c51f124SMoriah Waterland  *			== B_FALSE - zone is native
16655c51f124SMoriah Waterland  */
16665c51f124SMoriah Waterland boolean_t
16675c51f124SMoriah Waterland z_is_zone_branded(char *zoneName)
16685c51f124SMoriah Waterland {
16695c51f124SMoriah Waterland 	char			brandname[MAXNAMELEN];
16705c51f124SMoriah Waterland 	int			err;
16715c51f124SMoriah Waterland 
16725c51f124SMoriah Waterland 	/* if zones are not implemented, return FALSE */
16735c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
16745c51f124SMoriah Waterland 		return (B_FALSE);
16755c51f124SMoriah Waterland 	}
16765c51f124SMoriah Waterland 
16775c51f124SMoriah Waterland 	/* if brands are not implemented, return FALSE */
16785c51f124SMoriah Waterland 	if (!z_brands_are_implemented()) {
16795c51f124SMoriah Waterland 		return (B_FALSE);
16805c51f124SMoriah Waterland 	}
16815c51f124SMoriah Waterland 
16825c51f124SMoriah Waterland 	err = zone_get_brand(zoneName, brandname, sizeof (brandname));
16835c51f124SMoriah Waterland 	if (err != Z_OK) {
16845c51f124SMoriah Waterland 		_z_program_error(ERR_BRAND_GETBRAND, zonecfg_strerror(err));
16855c51f124SMoriah Waterland 		return (B_FALSE);
16865c51f124SMoriah Waterland 	}
16875c51f124SMoriah Waterland 
16885c51f124SMoriah Waterland 	/*
16895c51f124SMoriah Waterland 	 * Both "native" and "cluster" are native brands
16905c51f124SMoriah Waterland 	 * that use the standard facilities in the areas
16915c51f124SMoriah Waterland 	 * of packaging/installation/patching/update.
16925c51f124SMoriah Waterland 	 */
16935c51f124SMoriah Waterland 	if (streq(brandname, NATIVE_BRAND_NAME) ||
16945c51f124SMoriah Waterland 	    streq(brandname, CLUSTER_BRAND_NAME)) {
16955c51f124SMoriah Waterland 		return (B_FALSE);
16965c51f124SMoriah Waterland 	} else {
16975c51f124SMoriah Waterland 		return (B_TRUE);
16985c51f124SMoriah Waterland 	}
16995c51f124SMoriah Waterland }
17005c51f124SMoriah Waterland 
17015c51f124SMoriah Waterland /*
17025c51f124SMoriah Waterland  * Name:	z_is_zone_brand_in_list
17035c51f124SMoriah Waterland  * Description:	Determine whether zone's brand has a match in the list
17045c51f124SMoriah Waterland  *              brands passed in.
17055c51f124SMoriah Waterland  * Arguments:	zoneName - name of the zone to check for branding
17065c51f124SMoriah Waterland  *              list - list of brands to check the zone against
17075c51f124SMoriah Waterland  * Returns:	boolean_t
17085c51f124SMoriah Waterland  *			== B_TRUE - zone has a matching brand
17095c51f124SMoriah Waterland  *			== B_FALSE - zone brand is not in list
17105c51f124SMoriah Waterland  */
17115c51f124SMoriah Waterland boolean_t
17125c51f124SMoriah Waterland z_is_zone_brand_in_list(char *zoneName, zoneBrandList_t *list)
17135c51f124SMoriah Waterland {
17145c51f124SMoriah Waterland 	char			brandname[MAXNAMELEN];
17155c51f124SMoriah Waterland 	int			err;
17165c51f124SMoriah Waterland 	zoneBrandList_t		*sp;
17175c51f124SMoriah Waterland 
17185c51f124SMoriah Waterland 	if (zoneName == NULL || list == NULL)
17195c51f124SMoriah Waterland 		return (B_FALSE);
17205c51f124SMoriah Waterland 
17215c51f124SMoriah Waterland 	/* if zones are not implemented, return FALSE */
17225c51f124SMoriah Waterland 	if (!z_zones_are_implemented()) {
17235c51f124SMoriah Waterland 		return (B_FALSE);
17245c51f124SMoriah Waterland 	}
17255c51f124SMoriah Waterland 
17265c51f124SMoriah Waterland 	/* if brands are not implemented, return FALSE */
17275c51f124SMoriah Waterland 	if (!z_brands_are_implemented()) {
17285c51f124SMoriah Waterland 		return (B_FALSE);
17295c51f124SMoriah Waterland 	}
17305c51f124SMoriah Waterland 
17315c51f124SMoriah Waterland 	err = zone_get_brand(zoneName, brandname, sizeof (brandname));
17325c51f124SMoriah Waterland 	if (err != Z_OK) {
17335c51f124SMoriah Waterland 		_z_program_error(ERR_BRAND_GETBRAND, zonecfg_strerror(err));
17345c51f124SMoriah Waterland 		return (B_FALSE);
17355c51f124SMoriah Waterland 	}
17365c51f124SMoriah Waterland 
17375c51f124SMoriah Waterland 	for (sp = list; sp != NULL; sp = sp->next) {
17385c51f124SMoriah Waterland 		if (sp->string_ptr != NULL &&
17395c51f124SMoriah Waterland 		    strcmp(sp->string_ptr, brandname) == 0) {
17405c51f124SMoriah Waterland 			return (B_TRUE);
17415c51f124SMoriah Waterland 		}
17425c51f124SMoriah Waterland 	}
17435c51f124SMoriah Waterland 
17445c51f124SMoriah Waterland 	return (B_FALSE);
17455c51f124SMoriah Waterland }
17465c51f124SMoriah Waterland 
17475c51f124SMoriah Waterland /*
17485c51f124SMoriah Waterland  * Name:	z_zlist_get_current_state
17495c51f124SMoriah Waterland  * Description:	Determine the current kernel state of the specified zone
17505c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
17515c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return
17525c51f124SMoriah Waterland  * Returns:	zone_state_t
17535c51f124SMoriah Waterland  *			The current state of the specified zone is returned
17545c51f124SMoriah Waterland  */
17555c51f124SMoriah Waterland 
17565c51f124SMoriah Waterland zone_state_t
17575c51f124SMoriah Waterland z_zlist_get_current_state(zoneList_t a_zlst, int a_zoneIndex)
17585c51f124SMoriah Waterland {
17595c51f124SMoriah Waterland 	int	i;
17605c51f124SMoriah Waterland 
17615c51f124SMoriah Waterland 	/* ignore empty list */
17625c51f124SMoriah Waterland 
17635c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
17645c51f124SMoriah Waterland 		return (ZONE_STATE_INCOMPLETE);
17655c51f124SMoriah Waterland 	}
17665c51f124SMoriah Waterland 
17675c51f124SMoriah Waterland 	/* find the specified zone in the list */
17685c51f124SMoriah Waterland 
17695c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
17705c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
17715c51f124SMoriah Waterland 		;
17725c51f124SMoriah Waterland 
17735c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
17745c51f124SMoriah Waterland 
17755c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
17765c51f124SMoriah Waterland 		return (ZONE_STATE_INCOMPLETE);
17775c51f124SMoriah Waterland 	}
17785c51f124SMoriah Waterland 
17795c51f124SMoriah Waterland 	/* return selected zone's current kernel state */
17805c51f124SMoriah Waterland 
17815c51f124SMoriah Waterland 	_z_echoDebug(DBG_ZONES_GET_ZONE_STATE,
17825c51f124SMoriah Waterland 	    a_zlst[i]._zlName ? a_zlst[i]._zlName : "",
17835c51f124SMoriah Waterland 	    a_zlst[i]._zlCurrKernelStatus);
17845c51f124SMoriah Waterland 
17855c51f124SMoriah Waterland 	return (a_zlst[i]._zlCurrKernelStatus);
17865c51f124SMoriah Waterland }
17875c51f124SMoriah Waterland 
17885c51f124SMoriah Waterland /*
17895c51f124SMoriah Waterland  * Name:	z_zlist_get_inherited_pkg_dirs
17905c51f124SMoriah Waterland  * Description:	Determine directories inherited by specified zone
17915c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
17925c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return the
17935c51f124SMoriah Waterland  *			inherited directories list
17945c51f124SMoriah Waterland  * Returns:	char **
17955c51f124SMoriah Waterland  *			== NULL - zone does not inherit any directories
17965c51f124SMoriah Waterland  *				- zone index is invalid
17975c51f124SMoriah Waterland  *			!= NULL - array of inherited directories
17985c51f124SMoriah Waterland  * NOTE:    	Any directory list returned is located in static storage that
17995c51f124SMoriah Waterland  *		must NEVER be free()ed by the caller.
18005c51f124SMoriah Waterland  */
18015c51f124SMoriah Waterland 
18025c51f124SMoriah Waterland extern char **
18035c51f124SMoriah Waterland z_zlist_get_inherited_pkg_dirs(zoneList_t a_zlst, int a_zoneIndex)
18045c51f124SMoriah Waterland {
18055c51f124SMoriah Waterland 	int	i;
18065c51f124SMoriah Waterland 
18075c51f124SMoriah Waterland 	/* if zones are not implemented, return empty list */
18085c51f124SMoriah Waterland 
18095c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
18105c51f124SMoriah Waterland 		return (NULL);
18115c51f124SMoriah Waterland 	}
18125c51f124SMoriah Waterland 
18135c51f124SMoriah Waterland 	/* ignore empty list */
18145c51f124SMoriah Waterland 
18155c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
18165c51f124SMoriah Waterland 		return (NULL);
18175c51f124SMoriah Waterland 	}
18185c51f124SMoriah Waterland 
18195c51f124SMoriah Waterland 	/* find the specified zone in the list */
18205c51f124SMoriah Waterland 
18215c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
18225c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
18235c51f124SMoriah Waterland 		;
18245c51f124SMoriah Waterland 
18255c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
18265c51f124SMoriah Waterland 
18275c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
18285c51f124SMoriah Waterland 		return (NULL);
18295c51f124SMoriah Waterland 	}
18305c51f124SMoriah Waterland 
18315c51f124SMoriah Waterland 	/* return selected zone's inherited directories */
18325c51f124SMoriah Waterland 
18335c51f124SMoriah Waterland 	return (a_zlst[i]._zlInheritedDirs);
18345c51f124SMoriah Waterland }
18355c51f124SMoriah Waterland 
18365c51f124SMoriah Waterland /*
18375c51f124SMoriah Waterland  * Name:	z_zlist_get_original_state
18385c51f124SMoriah Waterland  * Description:	Return the original kernal state of the specified zone
18395c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
18405c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return the
18415c51f124SMoriah Waterland  * Returns:	zone_state_t
18425c51f124SMoriah Waterland  *			The original state of the specified zone is returned.
18435c51f124SMoriah Waterland  *			This is the state of the zone when the zoneList_t
18445c51f124SMoriah Waterland  *			object was first generated.
18455c51f124SMoriah Waterland  */
18465c51f124SMoriah Waterland 
18475c51f124SMoriah Waterland zone_state_t
18485c51f124SMoriah Waterland z_zlist_get_original_state(zoneList_t a_zlst, int a_zoneIndex)
18495c51f124SMoriah Waterland {
18505c51f124SMoriah Waterland 	int	i;
18515c51f124SMoriah Waterland 
18525c51f124SMoriah Waterland 	/* ignore empty list */
18535c51f124SMoriah Waterland 
18545c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
18555c51f124SMoriah Waterland 		return (ZONE_STATE_INCOMPLETE);
18565c51f124SMoriah Waterland 	}
18575c51f124SMoriah Waterland 
18585c51f124SMoriah Waterland 	/* find the specified zone in the list */
18595c51f124SMoriah Waterland 
18605c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
18615c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
18625c51f124SMoriah Waterland 		;
18635c51f124SMoriah Waterland 
18645c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
18655c51f124SMoriah Waterland 
18665c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
18675c51f124SMoriah Waterland 		return (ZONE_STATE_INCOMPLETE);
18685c51f124SMoriah Waterland 	}
18695c51f124SMoriah Waterland 
18705c51f124SMoriah Waterland 	/* return selected zone's original kernel state */
18715c51f124SMoriah Waterland 
18725c51f124SMoriah Waterland 	return (a_zlst[i]._zlOrigKernelStatus);
18735c51f124SMoriah Waterland }
18745c51f124SMoriah Waterland 
18755c51f124SMoriah Waterland /*
18765c51f124SMoriah Waterland  * Name:	z_zlist_get_scratch
18775c51f124SMoriah Waterland  * Description:	Determine name of scratch zone
18785c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
18795c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to use
18805c51f124SMoriah Waterland  * Return:	char *
18815c51f124SMoriah Waterland  *			== NULL - zone name could not be determined
18825c51f124SMoriah Waterland  *			!= NULL - pointer to string representing scratch zone
18835c51f124SMoriah Waterland  * NOTE:    	Any name returned is placed in static storage that must
18845c51f124SMoriah Waterland  *		NEVER be free()ed by the caller.
18855c51f124SMoriah Waterland  */
18865c51f124SMoriah Waterland 
18875c51f124SMoriah Waterland char *
18885c51f124SMoriah Waterland z_zlist_get_scratch(zoneList_t a_zlst, int a_zoneIndex)
18895c51f124SMoriah Waterland {
18905c51f124SMoriah Waterland 	int	i;
18915c51f124SMoriah Waterland 
18925c51f124SMoriah Waterland 	/* ignore empty list */
18935c51f124SMoriah Waterland 
18945c51f124SMoriah Waterland 	if (a_zlst == NULL)
18955c51f124SMoriah Waterland 		return (NULL);
18965c51f124SMoriah Waterland 
18975c51f124SMoriah Waterland 	/* find the specified zone in the list */
18985c51f124SMoriah Waterland 
18995c51f124SMoriah Waterland 	for (i = 0; i != a_zoneIndex; i++) {
19005c51f124SMoriah Waterland 		if (a_zlst[i]._zlName == NULL)
19015c51f124SMoriah Waterland 			return (NULL);
19025c51f124SMoriah Waterland 	}
19035c51f124SMoriah Waterland 
19045c51f124SMoriah Waterland 	/* return selected zone's scratch name */
19055c51f124SMoriah Waterland 
19065c51f124SMoriah Waterland 	return (a_zlst[i]._zlScratchName == NULL ? a_zlst[i]._zlName :
19075c51f124SMoriah Waterland 	    a_zlst[i]._zlScratchName);
19085c51f124SMoriah Waterland }
19095c51f124SMoriah Waterland 
19105c51f124SMoriah Waterland /*
19115c51f124SMoriah Waterland  * Name:	z_zlist_get_zonename
19125c51f124SMoriah Waterland  * Description:	Determine name of specified zone
19135c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
19145c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return the
19155c51f124SMoriah Waterland  * Return:	char *
19165c51f124SMoriah Waterland  *			== NULL - zone name could not be determined
19175c51f124SMoriah Waterland  *			!= NULL - pointer to string representing zone name
19185c51f124SMoriah Waterland  * NOTE:    	Any zoneList_t returned is placed in static storage that must
19195c51f124SMoriah Waterland  *		NEVER be free()ed by the caller.
19205c51f124SMoriah Waterland  */
19215c51f124SMoriah Waterland 
19225c51f124SMoriah Waterland char *
19235c51f124SMoriah Waterland z_zlist_get_zonename(zoneList_t a_zlst, int a_zoneIndex)
19245c51f124SMoriah Waterland {
19255c51f124SMoriah Waterland 	int	i;
19265c51f124SMoriah Waterland 
19275c51f124SMoriah Waterland 	/* ignore empty list */
19285c51f124SMoriah Waterland 
19295c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
19305c51f124SMoriah Waterland 		return ((char *)NULL);
19315c51f124SMoriah Waterland 	}
19325c51f124SMoriah Waterland 
19335c51f124SMoriah Waterland 	/* find the specified zone in the list */
19345c51f124SMoriah Waterland 
19355c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
19365c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
19375c51f124SMoriah Waterland 		;
19385c51f124SMoriah Waterland 
19395c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
19405c51f124SMoriah Waterland 
19415c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
19425c51f124SMoriah Waterland 		return (NULL);
19435c51f124SMoriah Waterland 	}
19445c51f124SMoriah Waterland 
19455c51f124SMoriah Waterland 	/* return selected zone's name */
19465c51f124SMoriah Waterland 
19475c51f124SMoriah Waterland 	return (a_zlst[i]._zlName);
19485c51f124SMoriah Waterland }
19495c51f124SMoriah Waterland 
19505c51f124SMoriah Waterland /*
19515c51f124SMoriah Waterland  * Name:	z_zlist_get_zonepath
19525c51f124SMoriah Waterland  * Description:	Determine zonepath of specified zone
19535c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
19545c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return
19555c51f124SMoriah Waterland  * Return:	char *
19565c51f124SMoriah Waterland  *			== NULL - zonepath could not be determined
19575c51f124SMoriah Waterland  *			!= NULL - pointer to string representing zonepath
19585c51f124SMoriah Waterland  * NOTE:    	Any zoneList_t returned is placed in static storage that must
19595c51f124SMoriah Waterland  *		NEVER be free()ed by the caller.
19605c51f124SMoriah Waterland  */
19615c51f124SMoriah Waterland 
19625c51f124SMoriah Waterland char *
19635c51f124SMoriah Waterland z_zlist_get_zonepath(zoneList_t a_zlst, int a_zoneIndex)
19645c51f124SMoriah Waterland {
19655c51f124SMoriah Waterland 	int	i;
19665c51f124SMoriah Waterland 
19675c51f124SMoriah Waterland 	/* ignore empty list */
19685c51f124SMoriah Waterland 
19695c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
19705c51f124SMoriah Waterland 		return ((char *)NULL);
19715c51f124SMoriah Waterland 	}
19725c51f124SMoriah Waterland 
19735c51f124SMoriah Waterland 	/* find the specified zone in the list */
19745c51f124SMoriah Waterland 
19755c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
19765c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
19775c51f124SMoriah Waterland 		;
19785c51f124SMoriah Waterland 
19795c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
19805c51f124SMoriah Waterland 
19815c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
19825c51f124SMoriah Waterland 		return (NULL);
19835c51f124SMoriah Waterland 	}
19845c51f124SMoriah Waterland 
19855c51f124SMoriah Waterland 	/* return selected zone's zonepath */
19865c51f124SMoriah Waterland 
19875c51f124SMoriah Waterland 	return (a_zlst[i]._zlPath);
19885c51f124SMoriah Waterland }
19895c51f124SMoriah Waterland 
19905c51f124SMoriah Waterland boolean_t
19915c51f124SMoriah Waterland z_zlist_is_zone_runnable(zoneList_t a_zlst, int a_zoneIndex)
19925c51f124SMoriah Waterland {
19935c51f124SMoriah Waterland 	int	i;
19945c51f124SMoriah Waterland 
19955c51f124SMoriah Waterland 	/* if zones are not implemented, return error */
19965c51f124SMoriah Waterland 
19975c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
19985c51f124SMoriah Waterland 		return (B_FALSE);
19995c51f124SMoriah Waterland 	}
20005c51f124SMoriah Waterland 
20015c51f124SMoriah Waterland 	/* ignore empty list */
20025c51f124SMoriah Waterland 
20035c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
20045c51f124SMoriah Waterland 		return (B_FALSE);
20055c51f124SMoriah Waterland 	}
20065c51f124SMoriah Waterland 
20075c51f124SMoriah Waterland 	/* find the specified zone in the list */
20085c51f124SMoriah Waterland 
20095c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
20105c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
20115c51f124SMoriah Waterland 		;
20125c51f124SMoriah Waterland 
20135c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
20145c51f124SMoriah Waterland 
20155c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
20165c51f124SMoriah Waterland 		return (B_FALSE);
20175c51f124SMoriah Waterland 	}
20185c51f124SMoriah Waterland 
20195c51f124SMoriah Waterland 	/* choose based on current state */
20205c51f124SMoriah Waterland 
20215c51f124SMoriah Waterland 	switch (a_zlst[i]._zlCurrKernelStatus) {
20225c51f124SMoriah Waterland 	case ZONE_STATE_RUNNING:
20235c51f124SMoriah Waterland 	case ZONE_STATE_MOUNTED:
20245c51f124SMoriah Waterland 		/* already running */
20255c51f124SMoriah Waterland 		return (B_TRUE);
20265c51f124SMoriah Waterland 
20275c51f124SMoriah Waterland 	case ZONE_STATE_INSTALLED:
20285c51f124SMoriah Waterland 	case ZONE_STATE_DOWN:
20295c51f124SMoriah Waterland 	case ZONE_STATE_READY:
20305c51f124SMoriah Waterland 	case ZONE_STATE_SHUTTING_DOWN:
20315c51f124SMoriah Waterland 		/* return false if the zone cannot be booted */
20325c51f124SMoriah Waterland 
20335c51f124SMoriah Waterland 		if (a_zlst[i]._zlStatus & ZST_NOT_BOOTABLE) {
20345c51f124SMoriah Waterland 			return (B_FALSE);
20355c51f124SMoriah Waterland 		}
20365c51f124SMoriah Waterland 
20375c51f124SMoriah Waterland 		return (B_TRUE);
20385c51f124SMoriah Waterland 
20395c51f124SMoriah Waterland 	case ZONE_STATE_CONFIGURED:
20405c51f124SMoriah Waterland 	case ZONE_STATE_INCOMPLETE:
20415c51f124SMoriah Waterland 	default:
20425c51f124SMoriah Waterland 		/* cannot transition (boot) these states */
20435c51f124SMoriah Waterland 		return (B_FALSE);
20445c51f124SMoriah Waterland 	}
20455c51f124SMoriah Waterland }
20465c51f124SMoriah Waterland 
20475c51f124SMoriah Waterland /*
20485c51f124SMoriah Waterland  * Name:	z_zlist_restore_zone_state
20495c51f124SMoriah Waterland  * Description:	Return the zone to the state it was originally in
20505c51f124SMoriah Waterland  * Arguments:	a_zlst - handle to zoneList_t object describing all zones
20515c51f124SMoriah Waterland  *		a_zoneIndex - index into a_zlst of the zone to return the
20525c51f124SMoriah Waterland  * Returns:	boolean_t
20535c51f124SMoriah Waterland  *			== B_TRUE - the zone's state has been restored
20545c51f124SMoriah Waterland  *			== B_FALSE - unable to transition the zone to its
20555c51f124SMoriah Waterland  *				original state
20565c51f124SMoriah Waterland  */
20575c51f124SMoriah Waterland 
20585c51f124SMoriah Waterland boolean_t
20595c51f124SMoriah Waterland z_zlist_restore_zone_state(zoneList_t a_zlst, int a_zoneIndex)
20605c51f124SMoriah Waterland {
20615c51f124SMoriah Waterland 	int		i;
20625c51f124SMoriah Waterland 
20635c51f124SMoriah Waterland 	/* ignore empty list */
20645c51f124SMoriah Waterland 
20655c51f124SMoriah Waterland 	if (a_zlst == (zoneList_t)NULL) {
20665c51f124SMoriah Waterland 		return (B_FALSE);
20675c51f124SMoriah Waterland 	}
20685c51f124SMoriah Waterland 
20695c51f124SMoriah Waterland 	/* find the specified zone in the list */
20705c51f124SMoriah Waterland 
20715c51f124SMoriah Waterland 	for (i = 0; (i != a_zoneIndex) &&
20725c51f124SMoriah Waterland 	    (a_zlst[i]._zlName != (char *)NULL); i++)
20735c51f124SMoriah Waterland 		;
20745c51f124SMoriah Waterland 
20755c51f124SMoriah Waterland 	/* return error if the specified zone does not exist */
20765c51f124SMoriah Waterland 
20775c51f124SMoriah Waterland 	if (a_zlst[i]._zlName == (char *)NULL) {
20785c51f124SMoriah Waterland 		return (B_FALSE);
20795c51f124SMoriah Waterland 	}
20805c51f124SMoriah Waterland 
20815c51f124SMoriah Waterland 	/* transition the zone back to its original state */
20825c51f124SMoriah Waterland 
20835c51f124SMoriah Waterland 	return (z_zlist_change_zone_state(a_zlst,
20845c51f124SMoriah Waterland 	    a_zoneIndex, a_zlst[i]._zlOrigKernelStatus));
20855c51f124SMoriah Waterland }
20865c51f124SMoriah Waterland 
20875c51f124SMoriah Waterland /*
20885c51f124SMoriah Waterland  * Name:	z_zone_exec
20895c51f124SMoriah Waterland  * Description:	Execute a Unix command in a specified zone and return results
20905c51f124SMoriah Waterland  * Arguments:	a_zoneName - pointer to string representing the name of the zone
20915c51f124SMoriah Waterland  *			to execute the specified command in
20925c51f124SMoriah Waterland  *		a_path - pointer to string representing the full path *in the
20935c51f124SMoriah Waterland  *			non-global zone named by a_zoneName* of the Unix command
20945c51f124SMoriah Waterland  *			to be executed
20955c51f124SMoriah Waterland  *		a_argv[] - Pointer to array of character strings representing
20965c51f124SMoriah Waterland  *			the arguments to be passed to the Unix command. The list
20975c51f124SMoriah Waterland  *			must be termianted with an element that is (char *)NULL
20985c51f124SMoriah Waterland  *		NOTE: a_argv[0] is the "command name" passed to the command
20995c51f124SMoriah Waterland  *		a_stdoutPath - Pointer to string representing the path to a file
21005c51f124SMoriah Waterland  *			into which all output to "stdout" from the Unix command
21015c51f124SMoriah Waterland  *			is placed.
21025c51f124SMoriah Waterland  *			== (char *)NULL - leave stdout open and pass through
21035c51f124SMoriah Waterland  *			== "/dev/null" - discard stdout output
21045c51f124SMoriah Waterland  *		a_strerrPath - Pointer to string representing the path to a file
21055c51f124SMoriah Waterland  *			into which all output to "stderr" from the Unix command
21065c51f124SMoriah Waterland  *			is placed.
21075c51f124SMoriah Waterland  *			== (char *)NULL - leave stderr open and pass through
21085c51f124SMoriah Waterland  *			== "/dev/null" - discard stderr output
21095c51f124SMoriah Waterland  *		a_fds - Pointer to array of integers representing file
21105c51f124SMoriah Waterland  *			descriptors to remain open during the call - all
21115c51f124SMoriah Waterland  *			file descriptors above STDERR_FILENO not in this
21125c51f124SMoriah Waterland  *			list will be closed.
21135c51f124SMoriah Waterland  * Returns:	int
21145c51f124SMoriah Waterland  *			The return (exit) code from the specified Unix command
21155c51f124SMoriah Waterland  *			Special return codes:
21165c51f124SMoriah Waterland  *			-1 : failure to exec process
21175c51f124SMoriah Waterland  *			-2 : could not create contract for greenline
21185c51f124SMoriah Waterland  *			-3 : fork() failed
21195c51f124SMoriah Waterland  *			-4 : could not open stdout capture file
21205c51f124SMoriah Waterland  *			-5 : error from 'waitpid' other than EINTR
21215c51f124SMoriah Waterland  *			-6 : zones are not supported
21225c51f124SMoriah Waterland  * NOTE:	All file descriptores other than 0, 1 and 2 are closed except
21235c51f124SMoriah Waterland  *		for those file descriptors listed in the a_fds array.
21245c51f124SMoriah Waterland  */
21255c51f124SMoriah Waterland 
21265c51f124SMoriah Waterland int
21275c51f124SMoriah Waterland z_zone_exec(const char *a_zoneName, const char *a_path, char *a_argv[],
21285c51f124SMoriah Waterland 	char *a_stdoutPath, char *a_stderrPath, int *a_fds)
21295c51f124SMoriah Waterland {
21305c51f124SMoriah Waterland 	int			final_status;
21315c51f124SMoriah Waterland 	int			lerrno;
21325c51f124SMoriah Waterland 	int			status;
21335c51f124SMoriah Waterland 	int			tmpl_fd;
21345c51f124SMoriah Waterland 	pid_t			child_pid;
21355c51f124SMoriah Waterland 	pid_t			result_pid;
21365c51f124SMoriah Waterland 	struct sigaction	nact;
21375c51f124SMoriah Waterland 	struct sigaction	oact;
21385c51f124SMoriah Waterland 	void			(*funcSighup)();
21395c51f124SMoriah Waterland 	void			(*funcSigint)();
21405c51f124SMoriah Waterland 
21415c51f124SMoriah Waterland 	/* if zones are not implemented, return TRUE */
21425c51f124SMoriah Waterland 
21435c51f124SMoriah Waterland 	if (z_zones_are_implemented() == B_FALSE) {
21445c51f124SMoriah Waterland 		return (-6);	/* -6 : zones are not supported */
21455c51f124SMoriah Waterland 	}
21465c51f124SMoriah Waterland 
21475c51f124SMoriah Waterland 	if ((tmpl_fd = _zexec_init_template()) == -1) {
21485c51f124SMoriah Waterland 		_z_program_error(ERR_CANNOT_CREATE_CONTRACT, strerror(errno));
21495c51f124SMoriah Waterland 		return (-2);	/* -2 : could not create greenline contract */
21505c51f124SMoriah Waterland 	}
21515c51f124SMoriah Waterland 
21525c51f124SMoriah Waterland 	/*
21535c51f124SMoriah Waterland 	 * hold SIGINT/SIGHUP signals and reset signal received counter;
21545c51f124SMoriah Waterland 	 * after the fork1() the parent and child need to setup their respective
21555c51f124SMoriah Waterland 	 * interrupt handling and release the hold on the signals
21565c51f124SMoriah Waterland 	 */
21575c51f124SMoriah Waterland 
21585c51f124SMoriah Waterland 	(void) sighold(SIGINT);
21595c51f124SMoriah Waterland 	(void) sighold(SIGHUP);
21605c51f124SMoriah Waterland 
21615c51f124SMoriah Waterland 	_z_global_data._z_SigReceived = 0;	/* no signals received */
21625c51f124SMoriah Waterland 
21635c51f124SMoriah Waterland 	/*
21645c51f124SMoriah Waterland 	 * fork off a new process to execute command in;
21655c51f124SMoriah Waterland 	 * fork1() is used instead of vfork() so the child process can
21665c51f124SMoriah Waterland 	 * perform operations that would modify the parent process if
21675c51f124SMoriah Waterland 	 * vfork() were used
21685c51f124SMoriah Waterland 	 */
21695c51f124SMoriah Waterland 
21705c51f124SMoriah Waterland 	child_pid = fork1();
21715c51f124SMoriah Waterland 
21725c51f124SMoriah Waterland 	if (child_pid < 0) {
21735c51f124SMoriah Waterland 		/*
21745c51f124SMoriah Waterland 		 * *************************************************************
21755c51f124SMoriah Waterland 		 * fork failed!
21765c51f124SMoriah Waterland 		 * *************************************************************
21775c51f124SMoriah Waterland 		 */
21785c51f124SMoriah Waterland 
21795c51f124SMoriah Waterland 		(void) ct_tmpl_clear(tmpl_fd);
21805c51f124SMoriah Waterland 		(void) close(tmpl_fd);
21815c51f124SMoriah Waterland 		_z_program_error(ERR_FORK, strerror(errno));
21825c51f124SMoriah Waterland 
21835c51f124SMoriah Waterland 		/* release hold on signals */
21845c51f124SMoriah Waterland 
21855c51f124SMoriah Waterland 		(void) sigrelse(SIGHUP);
21865c51f124SMoriah Waterland 		(void) sigrelse(SIGINT);
21875c51f124SMoriah Waterland 
21885c51f124SMoriah Waterland 		return (-3);	/* -3 : fork() failed */
21895c51f124SMoriah Waterland 	}
21905c51f124SMoriah Waterland 
21915c51f124SMoriah Waterland 	if (child_pid == 0) {
21925c51f124SMoriah Waterland 		int	i;
21935c51f124SMoriah Waterland 
21945c51f124SMoriah Waterland 		/*
21955c51f124SMoriah Waterland 		 * *************************************************************
21965c51f124SMoriah Waterland 		 * This is the forked (child) process
21975c51f124SMoriah Waterland 		 * *************************************************************
21985c51f124SMoriah Waterland 		 */
21995c51f124SMoriah Waterland 
22005c51f124SMoriah Waterland 		(void) ct_tmpl_clear(tmpl_fd);
22015c51f124SMoriah Waterland 		(void) close(tmpl_fd);
22025c51f124SMoriah Waterland 
22035c51f124SMoriah Waterland 		/* reset any signals to default */
22045c51f124SMoriah Waterland 
22055c51f124SMoriah Waterland 		for (i = 0; i < NSIG; i++) {
22065c51f124SMoriah Waterland 			(void) sigset(i, SIG_DFL);
22075c51f124SMoriah Waterland 		}
22085c51f124SMoriah Waterland 
22095c51f124SMoriah Waterland 		/*
22105c51f124SMoriah Waterland 		 * close all file descriptors not in the a_fds list
22115c51f124SMoriah Waterland 		 */
22125c51f124SMoriah Waterland 
22135c51f124SMoriah Waterland 		(void) fdwalk(&_z_close_file_descriptors, (void *)a_fds);
22145c51f124SMoriah Waterland 
22155c51f124SMoriah Waterland 		/*
22165c51f124SMoriah Waterland 		 * if a file for stdout is present, open the file and use the
22175c51f124SMoriah Waterland 		 * file to capture stdout from the _zexec process
22185c51f124SMoriah Waterland 		 */
22195c51f124SMoriah Waterland 
22205c51f124SMoriah Waterland 		if (a_stdoutPath != (char *)NULL) {
22215c51f124SMoriah Waterland 			int	stdoutfd;
22225c51f124SMoriah Waterland 
22235c51f124SMoriah Waterland 			stdoutfd = open(a_stdoutPath,
22245c51f124SMoriah Waterland 			    O_WRONLY|O_CREAT|O_TRUNC, 0600);
22255c51f124SMoriah Waterland 			if (stdoutfd < 0) {
22265c51f124SMoriah Waterland 				_z_program_error(ERR_CAPTURE_FILE, a_stdoutPath,
22275c51f124SMoriah Waterland 				    strerror(errno));
22285c51f124SMoriah Waterland 				return (-4);
22295c51f124SMoriah Waterland 			}
22305c51f124SMoriah Waterland 
22315c51f124SMoriah Waterland 			(void) dup2(stdoutfd, STDOUT_FILENO);
22325c51f124SMoriah Waterland 			(void) close(stdoutfd);
22335c51f124SMoriah Waterland 		}
22345c51f124SMoriah Waterland 
22355c51f124SMoriah Waterland 		/*
22365c51f124SMoriah Waterland 		 * if a file for stderr is present, open the file and use the
22375c51f124SMoriah Waterland 		 * file to capture stderr from the _zexec process
22385c51f124SMoriah Waterland 		 */
22395c51f124SMoriah Waterland 
22405c51f124SMoriah Waterland 		if (a_stderrPath != (char *)NULL) {
22415c51f124SMoriah Waterland 			int	stderrfd;
22425c51f124SMoriah Waterland 
22435c51f124SMoriah Waterland 			stderrfd = open(a_stderrPath,
22445c51f124SMoriah Waterland 			    O_WRONLY|O_CREAT|O_TRUNC, 0600);
22455c51f124SMoriah Waterland 			if (stderrfd < 0) {
22465c51f124SMoriah Waterland 				_z_program_error(ERR_CAPTURE_FILE, a_stderrPath,
22475c51f124SMoriah Waterland 				    strerror(errno));
22485c51f124SMoriah Waterland 				return (-4);
22495c51f124SMoriah Waterland 			}
22505c51f124SMoriah Waterland 
22515c51f124SMoriah Waterland 			(void) dup2(stderrfd, STDERR_FILENO);
22525c51f124SMoriah Waterland 			(void) close(stderrfd);
22535c51f124SMoriah Waterland 		}
22545c51f124SMoriah Waterland 
22555c51f124SMoriah Waterland 		/* release all held signals */
22565c51f124SMoriah Waterland 
22575c51f124SMoriah Waterland 		(void) sigrelse(SIGHUP);
22585c51f124SMoriah Waterland 		(void) sigrelse(SIGINT);
22595c51f124SMoriah Waterland 
22605c51f124SMoriah Waterland 		/* execute command in the specified non-global zone */
22615c51f124SMoriah Waterland 
22625c51f124SMoriah Waterland 		_exit(_zexec(a_zoneName, a_path, a_argv));
22635c51f124SMoriah Waterland 	}
22645c51f124SMoriah Waterland 
22655c51f124SMoriah Waterland 	/*
22665c51f124SMoriah Waterland 	 * *********************************************************************
22675c51f124SMoriah Waterland 	 * This is the forking (parent) process
22685c51f124SMoriah Waterland 	 * *********************************************************************
22695c51f124SMoriah Waterland 	 */
22705c51f124SMoriah Waterland 
22715c51f124SMoriah Waterland 	/* register child process i.d. so signal handlers can pass signal on */
22725c51f124SMoriah Waterland 
22735c51f124SMoriah Waterland 	_z_global_data._z_ChildProcessId = child_pid;
22745c51f124SMoriah Waterland 
22755c51f124SMoriah Waterland 	/*
22765c51f124SMoriah Waterland 	 * setup signal handlers for SIGINT and SIGHUP and release hold
22775c51f124SMoriah Waterland 	 */
22785c51f124SMoriah Waterland 
22795c51f124SMoriah Waterland 	/* hook SIGINT to _z_sig_trap() */
22805c51f124SMoriah Waterland 
22815c51f124SMoriah Waterland 	nact.sa_handler = _z_sig_trap;
22825c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
22835c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
22845c51f124SMoriah Waterland 
22855c51f124SMoriah Waterland 	if (sigaction(SIGINT, &nact, &oact) < 0) {
22865c51f124SMoriah Waterland 		funcSigint = SIG_DFL;
22875c51f124SMoriah Waterland 	} else {
22885c51f124SMoriah Waterland 		funcSigint = oact.sa_handler;
22895c51f124SMoriah Waterland 	}
22905c51f124SMoriah Waterland 
22915c51f124SMoriah Waterland 	/* hook SIGHUP to _z_sig_trap() */
22925c51f124SMoriah Waterland 
22935c51f124SMoriah Waterland 	nact.sa_handler = _z_sig_trap;
22945c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
22955c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
22965c51f124SMoriah Waterland 
22975c51f124SMoriah Waterland 	if (sigaction(SIGHUP, &nact, &oact) < 0) {
22985c51f124SMoriah Waterland 		funcSighup = SIG_DFL;
22995c51f124SMoriah Waterland 	} else {
23005c51f124SMoriah Waterland 		funcSighup = oact.sa_handler;
23015c51f124SMoriah Waterland 	}
23025c51f124SMoriah Waterland 
23035c51f124SMoriah Waterland 	/* release hold on signals */
23045c51f124SMoriah Waterland 
23055c51f124SMoriah Waterland 	(void) sigrelse(SIGHUP);
23065c51f124SMoriah Waterland 	(void) sigrelse(SIGINT);
23075c51f124SMoriah Waterland 
23085c51f124SMoriah Waterland 	(void) ct_tmpl_clear(tmpl_fd);
23095c51f124SMoriah Waterland 	(void) close(tmpl_fd);
23105c51f124SMoriah Waterland 
23115c51f124SMoriah Waterland 	/*
23125c51f124SMoriah Waterland 	 * wait for the process to exit, reap child exit status
23135c51f124SMoriah Waterland 	 */
23145c51f124SMoriah Waterland 
23155c51f124SMoriah Waterland 	for (;;) {
23165c51f124SMoriah Waterland 		result_pid = waitpid(child_pid, &status, 0L);
23175c51f124SMoriah Waterland 		lerrno = (result_pid == -1 ? errno : 0);
23185c51f124SMoriah Waterland 
23195c51f124SMoriah Waterland 		/* break loop if child process status reaped */
23205c51f124SMoriah Waterland 
23215c51f124SMoriah Waterland 		if (result_pid != -1) {
23225c51f124SMoriah Waterland 			break;
23235c51f124SMoriah Waterland 		}
23245c51f124SMoriah Waterland 
23255c51f124SMoriah Waterland 		/* break loop if not interrupted out of waitpid */
23265c51f124SMoriah Waterland 
23275c51f124SMoriah Waterland 		if (errno != EINTR) {
23285c51f124SMoriah Waterland 			break;
23295c51f124SMoriah Waterland 		}
23305c51f124SMoriah Waterland 	}
23315c51f124SMoriah Waterland 
23325c51f124SMoriah Waterland 	/* reset child process i.d. so signal handlers do not pass signals on */
23335c51f124SMoriah Waterland 
23345c51f124SMoriah Waterland 	_z_global_data._z_ChildProcessId = -1;
23355c51f124SMoriah Waterland 
23365c51f124SMoriah Waterland 	/*
23375c51f124SMoriah Waterland 	 * If the child process terminated due to a call to exit(), then
23385c51f124SMoriah Waterland 	 * set results equal to the 8-bit exit status of the child process;
23395c51f124SMoriah Waterland 	 * otherwise, set the exit status to "-1" indicating that the child
23405c51f124SMoriah Waterland 	 * exited via a signal.
23415c51f124SMoriah Waterland 	 */
23425c51f124SMoriah Waterland 
23435c51f124SMoriah Waterland 	if (WIFEXITED(status)) {
23445c51f124SMoriah Waterland 		final_status = WEXITSTATUS(status);
23455c51f124SMoriah Waterland 		if ((_z_global_data._z_SigReceived != 0) &&
23465c51f124SMoriah Waterland 		    (final_status == 0)) {
23475c51f124SMoriah Waterland 			final_status = 1;
23485c51f124SMoriah Waterland 		}
23495c51f124SMoriah Waterland 	} else {
23505c51f124SMoriah Waterland 		final_status = -1;	/* -1 : failure to exec process */
23515c51f124SMoriah Waterland 	}
23525c51f124SMoriah Waterland 
23535c51f124SMoriah Waterland 	/* determine proper exit code */
23545c51f124SMoriah Waterland 
23555c51f124SMoriah Waterland 	if (result_pid == -1) {
23565c51f124SMoriah Waterland 		final_status = -5;	/* -5 : error from waitpid not EINTR */
23575c51f124SMoriah Waterland 	} else if (_z_global_data._z_SigReceived != 0) {
23585c51f124SMoriah Waterland 		final_status = -7;	/* -7 : interrupt received */
23595c51f124SMoriah Waterland 	}
23605c51f124SMoriah Waterland 
23615c51f124SMoriah Waterland 	/*
23625c51f124SMoriah Waterland 	 * reset signal handlers
23635c51f124SMoriah Waterland 	 */
23645c51f124SMoriah Waterland 
23655c51f124SMoriah Waterland 	/* reset SIGINT */
23665c51f124SMoriah Waterland 
23675c51f124SMoriah Waterland 	nact.sa_handler = funcSigint;
23685c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
23695c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
23705c51f124SMoriah Waterland 
23715c51f124SMoriah Waterland 	(void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);
23725c51f124SMoriah Waterland 
23735c51f124SMoriah Waterland 	/* reset SIGHUP */
23745c51f124SMoriah Waterland 
23755c51f124SMoriah Waterland 	nact.sa_handler = funcSighup;
23765c51f124SMoriah Waterland 	nact.sa_flags = SA_RESTART;
23775c51f124SMoriah Waterland 	(void) sigemptyset(&nact.sa_mask);
23785c51f124SMoriah Waterland 
23795c51f124SMoriah Waterland 	(void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);
23805c51f124SMoriah Waterland 
23815c51f124SMoriah Waterland 	/*
23825c51f124SMoriah Waterland 	 * if signal received during command execution, interrupt
23835c51f124SMoriah Waterland 	 * this process now.
23845c51f124SMoriah Waterland 	 */
23855c51f124SMoriah Waterland 
23865c51f124SMoriah Waterland 	if (_z_global_data._z_SigReceived != 0) {
23875c51f124SMoriah Waterland 		(void) kill(getpid(), SIGINT);
23885c51f124SMoriah Waterland 	}
23895c51f124SMoriah Waterland 
23905c51f124SMoriah Waterland 	/* set errno and return */
23915c51f124SMoriah Waterland 
23925c51f124SMoriah Waterland 	errno = lerrno;
23935c51f124SMoriah Waterland 
23945c51f124SMoriah Waterland 	return (final_status);
23955c51f124SMoriah Waterland }
23965c51f124SMoriah Waterland 
23975c51f124SMoriah Waterland /*
23985c51f124SMoriah Waterland  * Name:	z_zones_are_implemented
23995c51f124SMoriah Waterland  * Description:	Determine if any zone operations can be performed
24005c51f124SMoriah Waterland  * Arguments:	void
24015c51f124SMoriah Waterland  * Returns:	boolean_t
24025c51f124SMoriah Waterland  *			== B_TRUE - zone operations are available
24035c51f124SMoriah Waterland  *			== B_FALSE - no zone operations can be done
24045c51f124SMoriah Waterland  */
24055c51f124SMoriah Waterland 
24065c51f124SMoriah Waterland boolean_t
24075c51f124SMoriah Waterland z_zones_are_implemented(void)
24085c51f124SMoriah Waterland {
24095c51f124SMoriah Waterland 	static	boolean_t	_zonesImplementedDetermined = B_FALSE;
24105c51f124SMoriah Waterland 	static	boolean_t	_zonesAreImplemented = B_FALSE;
24115c51f124SMoriah Waterland 
24125c51f124SMoriah Waterland 	/* if availability has not been determined, cache it now */
24135c51f124SMoriah Waterland 
24145c51f124SMoriah Waterland 	if (!_zonesImplementedDetermined) {
24155c51f124SMoriah Waterland 		_zonesImplementedDetermined = B_TRUE;
24165c51f124SMoriah Waterland 		_zonesAreImplemented = _z_zones_are_implemented();
24175c51f124SMoriah Waterland 		if (!_zonesAreImplemented) {
24185c51f124SMoriah Waterland 			_z_echoDebug(DBG_ZONES_NOT_IMPLEMENTED);
24195c51f124SMoriah Waterland 		} else {
24205c51f124SMoriah Waterland 			_z_echoDebug(DBG_ZONES_ARE_IMPLEMENTED);
24215c51f124SMoriah Waterland 		}
24225c51f124SMoriah Waterland 	}
24235c51f124SMoriah Waterland 
24245c51f124SMoriah Waterland 	return (_zonesAreImplemented);
24255c51f124SMoriah Waterland }
2426