1*5c51f124SMoriah Waterland /* 2*5c51f124SMoriah Waterland * CDDL HEADER START 3*5c51f124SMoriah Waterland * 4*5c51f124SMoriah Waterland * The contents of this file are subject to the terms of the 5*5c51f124SMoriah Waterland * Common Development and Distribution License (the "License"). 6*5c51f124SMoriah Waterland * You may not use this file except in compliance with the License. 7*5c51f124SMoriah Waterland * 8*5c51f124SMoriah Waterland * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*5c51f124SMoriah Waterland * or http://www.opensolaris.org/os/licensing. 10*5c51f124SMoriah Waterland * See the License for the specific language governing permissions 11*5c51f124SMoriah Waterland * and limitations under the License. 12*5c51f124SMoriah Waterland * 13*5c51f124SMoriah Waterland * When distributing Covered Code, include this CDDL HEADER in each 14*5c51f124SMoriah Waterland * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*5c51f124SMoriah Waterland * If applicable, add the following below this CDDL HEADER, with the 16*5c51f124SMoriah Waterland * fields enclosed by brackets "[]" replaced with your own identifying 17*5c51f124SMoriah Waterland * information: Portions Copyright [yyyy] [name of copyright owner] 18*5c51f124SMoriah Waterland * 19*5c51f124SMoriah Waterland * CDDL HEADER END 20*5c51f124SMoriah Waterland */ 21*5c51f124SMoriah Waterland 22*5c51f124SMoriah Waterland /* 23*5c51f124SMoriah Waterland * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24*5c51f124SMoriah Waterland * Use is subject to license terms. 25*5c51f124SMoriah Waterland */ 26*5c51f124SMoriah Waterland 27*5c51f124SMoriah Waterland 28*5c51f124SMoriah Waterland /* 29*5c51f124SMoriah Waterland * Module: zones.c 30*5c51f124SMoriah Waterland * Group: libinstzones 31*5c51f124SMoriah Waterland * Description: Provide "zones" interface for install consolidation code 32*5c51f124SMoriah Waterland * 33*5c51f124SMoriah Waterland * Public Methods: 34*5c51f124SMoriah Waterland * z_create_zone_admin_file - Given a location to create the file, and 35*5c51f124SMoriah Waterland * optionally an existing administration file, generate an 36*5c51f124SMoriah Waterland * administration file that can be used to perform "non-interactive" 37*5c51f124SMoriah Waterland * operations in a non-global zone. 38*5c51f124SMoriah Waterland * z_free_zone_list - free contents of zoneList_t object 39*5c51f124SMoriah Waterland * z_get_nonglobal_zone_list - return zoneList_t object describing all 40*5c51f124SMoriah Waterland * non-global native zones 41*5c51f124SMoriah Waterland * z_get_nonglobal_zone_list_by_brand - return zoneList_t object describing 42*5c51f124SMoriah Waterland * all non-global zones matching the list of zone brands passed in. 43*5c51f124SMoriah Waterland * z_free_brand_list - free contents of a zoneBrandList_t object 44*5c51f124SMoriah Waterland * z_make_brand_list - return a zoneBrandList_t object describing the list 45*5c51f124SMoriah Waterland * of all zone brands passed in. 46*5c51f124SMoriah Waterland * z_get_zonename - return the name of the current zone 47*5c51f124SMoriah Waterland * z_global_only - Determine if the global zone is only zone on the spec list 48*5c51f124SMoriah Waterland * z_lock_this_zone - lock this zone 49*5c51f124SMoriah Waterland * z_lock_zones - lock specified zones 50*5c51f124SMoriah Waterland * z_mount_in_lz - Mount global zone directory in specified zone's root file 51*5c51f124SMoriah Waterland * system 52*5c51f124SMoriah Waterland * z_non_global_zones_exist - Determine if any non-global native zones exist 53*5c51f124SMoriah Waterland * z_on_zone_spec - Determine if named zone is on the zone_spec list 54*5c51f124SMoriah Waterland * z_running_in_global_zone - Determine if running in the "global" zone 55*5c51f124SMoriah Waterland * z_set_output_functions - Link program specific output functions 56*5c51f124SMoriah Waterland * z_set_zone_root - Set root for zones library operations 57*5c51f124SMoriah Waterland * z_set_zone_spec - Set list of zones on which actions will be performed 58*5c51f124SMoriah Waterland * z_umount_lz_mount - Unmount directory mounted with z_mount_in_lz 59*5c51f124SMoriah Waterland * z_unlock_this_zone - unlock this zone 60*5c51f124SMoriah Waterland * z_unlock_zones - unlock specified zones 61*5c51f124SMoriah Waterland * z_verify_zone_spec - Verify list of zones on which actions will be performed 62*5c51f124SMoriah Waterland * z_zlist_change_zone_state - Change the current state of the specified zone 63*5c51f124SMoriah Waterland * z_zlist_get_current_state - Determine the current kernel state of the 64*5c51f124SMoriah Waterland * specified zone 65*5c51f124SMoriah Waterland * z_zlist_get_inherited_pkg_dirs - Determine directories inherited by 66*5c51f124SMoriah Waterland * specified zone 67*5c51f124SMoriah Waterland * z_zlist_get_original_state - Return the original kernal state of the 68*5c51f124SMoriah Waterland * specified zone 69*5c51f124SMoriah Waterland * z_zlist_get_scratch - Determine name of scratch zone 70*5c51f124SMoriah Waterland * z_zlist_get_zonename - Determine name of specified zone 71*5c51f124SMoriah Waterland * z_zlist_get_zonepath - Determine zonepath of specified zone 72*5c51f124SMoriah Waterland * z_zlist_restore_zone_state - Return the zone to the state it was originally 73*5c51f124SMoriah Waterland * in 74*5c51f124SMoriah Waterland * z_zone_exec - Execute a Unix command in a specified zone and return results 75*5c51f124SMoriah Waterland * z_zones_are_implemented - Determine if any zone operations can be performed 76*5c51f124SMoriah Waterland * z_is_zone_branded - determine if zone has a non-native brand 77*5c51f124SMoriah Waterland * z_is_zone_brand_in_list - determine if the zone's brand matches the 78*5c51f124SMoriah Waterland * brand list passed in. 79*5c51f124SMoriah Waterland * z_brands_are_implemented - determine if branded zones are implemented on 80*5c51f124SMoriah Waterland * this system 81*5c51f124SMoriah Waterland */ 82*5c51f124SMoriah Waterland 83*5c51f124SMoriah Waterland /* 84*5c51f124SMoriah Waterland * System includes 85*5c51f124SMoriah Waterland */ 86*5c51f124SMoriah Waterland 87*5c51f124SMoriah Waterland #include <stdio.h> 88*5c51f124SMoriah Waterland #include <stdlib.h> 89*5c51f124SMoriah Waterland #include <unistd.h> 90*5c51f124SMoriah Waterland #include <fcntl.h> 91*5c51f124SMoriah Waterland #include <ctype.h> 92*5c51f124SMoriah Waterland #include <sys/types.h> 93*5c51f124SMoriah Waterland #include <sys/param.h> 94*5c51f124SMoriah Waterland #include <sys/sysmacros.h> 95*5c51f124SMoriah Waterland #include <string.h> 96*5c51f124SMoriah Waterland #include <strings.h> 97*5c51f124SMoriah Waterland #include <sys/stat.h> 98*5c51f124SMoriah Waterland #include <stdarg.h> 99*5c51f124SMoriah Waterland #include <limits.h> 100*5c51f124SMoriah Waterland #include <errno.h> 101*5c51f124SMoriah Waterland #include <time.h> 102*5c51f124SMoriah Waterland #include <signal.h> 103*5c51f124SMoriah Waterland #include <stropts.h> 104*5c51f124SMoriah Waterland #include <wait.h> 105*5c51f124SMoriah Waterland #include <zone.h> 106*5c51f124SMoriah Waterland #include <sys/brand.h> 107*5c51f124SMoriah Waterland #include <libintl.h> 108*5c51f124SMoriah Waterland #include <locale.h> 109*5c51f124SMoriah Waterland #include <libzonecfg.h> 110*5c51f124SMoriah Waterland #include <libcontract.h> 111*5c51f124SMoriah Waterland #include <sys/contract/process.h> 112*5c51f124SMoriah Waterland #include <sys/ctfs.h> 113*5c51f124SMoriah Waterland #include <assert.h> 114*5c51f124SMoriah Waterland #include <dlfcn.h> 115*5c51f124SMoriah Waterland #include <link.h> 116*5c51f124SMoriah Waterland #include <time.h> 117*5c51f124SMoriah Waterland 118*5c51f124SMoriah Waterland /* 119*5c51f124SMoriah Waterland * local includes 120*5c51f124SMoriah Waterland */ 121*5c51f124SMoriah Waterland 122*5c51f124SMoriah Waterland /* 123*5c51f124SMoriah Waterland * When _INSTZONES_LIB_Z_DEFINE_GLOBAL_DATA is defined, 124*5c51f124SMoriah Waterland * instzones_lib.h will define the z_global_data structure. 125*5c51f124SMoriah Waterland * Otherwise an extern to the structure is inserted. 126*5c51f124SMoriah Waterland */ 127*5c51f124SMoriah Waterland 128*5c51f124SMoriah Waterland #define _INSTZONES_LIB_Z_DEFINE_GLOBAL_DATA 129*5c51f124SMoriah Waterland #include "instzones_lib.h" 130*5c51f124SMoriah Waterland #include "zones_strings.h" 131*5c51f124SMoriah Waterland 132*5c51f124SMoriah Waterland /* 133*5c51f124SMoriah Waterland * Private structures 134*5c51f124SMoriah Waterland */ 135*5c51f124SMoriah Waterland 136*5c51f124SMoriah Waterland #define CLUSTER_BRAND_NAME "cluster" 137*5c51f124SMoriah Waterland 138*5c51f124SMoriah Waterland /* maximum number of arguments to exec() call */ 139*5c51f124SMoriah Waterland 140*5c51f124SMoriah Waterland #define UUID_FORMAT "%02d%02d%02d%03d-%02d%02d%02d%d-%016llx" 141*5c51f124SMoriah Waterland 142*5c51f124SMoriah Waterland /* 143*5c51f124SMoriah Waterland * Library Function Prototypes 144*5c51f124SMoriah Waterland */ 145*5c51f124SMoriah Waterland 146*5c51f124SMoriah Waterland #define streq(a, b) (strcmp((a), (b)) == 0) 147*5c51f124SMoriah Waterland 148*5c51f124SMoriah Waterland /* 149*5c51f124SMoriah Waterland * Local Function Prototypes 150*5c51f124SMoriah Waterland */ 151*5c51f124SMoriah Waterland 152*5c51f124SMoriah Waterland /* 153*5c51f124SMoriah Waterland * global internal (private) declarations 154*5c51f124SMoriah Waterland */ 155*5c51f124SMoriah Waterland 156*5c51f124SMoriah Waterland /* 157*5c51f124SMoriah Waterland * ***************************************************************************** 158*5c51f124SMoriah Waterland * global external (public) functions 159*5c51f124SMoriah Waterland * ***************************************************************************** 160*5c51f124SMoriah Waterland */ 161*5c51f124SMoriah Waterland 162*5c51f124SMoriah Waterland /* 163*5c51f124SMoriah Waterland * Name: z_create_zone_admin_file 164*5c51f124SMoriah Waterland * Description: Given a location to create the file, and optionally an existing 165*5c51f124SMoriah Waterland * administration file, generate an administration file that 166*5c51f124SMoriah Waterland * can be used to perform "non-interactive" operations in a 167*5c51f124SMoriah Waterland * non-global zone. 168*5c51f124SMoriah Waterland * Arguments: a_zoneAdminFilename - pointer to string representing the 169*5c51f124SMoriah Waterland * full path of zone admin file to create 170*5c51f124SMoriah Waterland * a_userAdminFilename - pointer to string representing the path 171*5c51f124SMoriah Waterland * to an existing "user" administration file - the 172*5c51f124SMoriah Waterland * administration file created will contain the 173*5c51f124SMoriah Waterland * settings contained in this file, modified as 174*5c51f124SMoriah Waterland * appropriate to supress any interaction; 175*5c51f124SMoriah Waterland * If this is == NULL then the administration file 176*5c51f124SMoriah Waterland * created will not contain any extra settings 177*5c51f124SMoriah Waterland * Returns: boolean_t 178*5c51f124SMoriah Waterland * == B_TRUE - admin file created 179*5c51f124SMoriah Waterland * == B_FALSE - failed to create admin file 180*5c51f124SMoriah Waterland */ 181*5c51f124SMoriah Waterland 182*5c51f124SMoriah Waterland boolean_t 183*5c51f124SMoriah Waterland z_create_zone_admin_file(char *a_zoneAdminFilename, char *a_userAdminFilename) 184*5c51f124SMoriah Waterland { 185*5c51f124SMoriah Waterland FILE *zFp; 186*5c51f124SMoriah Waterland FILE *uFp = (FILE *)NULL; 187*5c51f124SMoriah Waterland 188*5c51f124SMoriah Waterland /* entry assertions */ 189*5c51f124SMoriah Waterland 190*5c51f124SMoriah Waterland assert(a_zoneAdminFilename != NULL); 191*5c51f124SMoriah Waterland assert(*a_zoneAdminFilename != '\0'); 192*5c51f124SMoriah Waterland 193*5c51f124SMoriah Waterland /* create temporary zone admin file */ 194*5c51f124SMoriah Waterland 195*5c51f124SMoriah Waterland zFp = fopen(a_zoneAdminFilename, "w"); 196*5c51f124SMoriah Waterland if (zFp == (FILE *)NULL) { 197*5c51f124SMoriah Waterland return (B_FALSE); 198*5c51f124SMoriah Waterland } 199*5c51f124SMoriah Waterland 200*5c51f124SMoriah Waterland /* open user admin file if specified */ 201*5c51f124SMoriah Waterland 202*5c51f124SMoriah Waterland if (a_userAdminFilename != (char *)NULL) { 203*5c51f124SMoriah Waterland uFp = fopen(a_userAdminFilename, "r"); 204*5c51f124SMoriah Waterland } 205*5c51f124SMoriah Waterland 206*5c51f124SMoriah Waterland /* create default admin file for zone pkg ops if no user admin file */ 207*5c51f124SMoriah Waterland 208*5c51f124SMoriah Waterland if (uFp == (FILE *)NULL) { 209*5c51f124SMoriah Waterland /* create default admin file */ 210*5c51f124SMoriah Waterland (void) fprintf(zFp, "action=nocheck\nauthentication=nocheck\n" 211*5c51f124SMoriah Waterland "basedir=default\nconflict=nocheck\nidepend=nocheck\n" 212*5c51f124SMoriah Waterland "instance=unique\npartial=nocheck\nrdepend=nocheck\n" 213*5c51f124SMoriah Waterland "runlevel=nocheck\nsetuid=nocheck\nspace=nocheck\n" 214*5c51f124SMoriah Waterland "mail=\n"); 215*5c51f124SMoriah Waterland } else for (;;) { 216*5c51f124SMoriah Waterland /* copy user admin file substitute/change appropriate entries */ 217*5c51f124SMoriah Waterland char buf[LINE_MAX+1]; 218*5c51f124SMoriah Waterland char *p; 219*5c51f124SMoriah Waterland 220*5c51f124SMoriah Waterland /* read next line of user admin file */ 221*5c51f124SMoriah Waterland 222*5c51f124SMoriah Waterland p = fgets(buf, sizeof (buf), uFp); 223*5c51f124SMoriah Waterland if (p == (char *)NULL) { 224*5c51f124SMoriah Waterland (void) fclose(uFp); 225*5c51f124SMoriah Waterland break; 226*5c51f124SMoriah Waterland } 227*5c51f124SMoriah Waterland 228*5c51f124SMoriah Waterland /* modify / replace / accept as appropriate */ 229*5c51f124SMoriah Waterland 230*5c51f124SMoriah Waterland if (strncmp(buf, "instance=quit", 13) == 0) { 231*5c51f124SMoriah Waterland (void) fprintf(zFp, "%s", "instance=unique\n"); 232*5c51f124SMoriah Waterland /*LINTED*/ 233*5c51f124SMoriah Waterland } else if (strncmp(buf, "keystore=", 9) == 0) { 234*5c51f124SMoriah Waterland } else if (strncmp(buf, "action=", 7) == 0) { 235*5c51f124SMoriah Waterland (void) fprintf(zFp, "action=nocheck\n"); 236*5c51f124SMoriah Waterland } else if (strncmp(buf, "authentication=", 15) == 0) { 237*5c51f124SMoriah Waterland (void) fprintf(zFp, "authentication=nocheck\n"); 238*5c51f124SMoriah Waterland } else if (strncmp(buf, "conflict=", 9) == 0) { 239*5c51f124SMoriah Waterland (void) fprintf(zFp, "conflict=nocheck\n"); 240*5c51f124SMoriah Waterland } else if (strncmp(buf, "idepend=", 8) == 0) { 241*5c51f124SMoriah Waterland (void) fprintf(zFp, "idepend=nocheck\n"); 242*5c51f124SMoriah Waterland } else if (strncmp(buf, "mail=", 5) == 0) { 243*5c51f124SMoriah Waterland (void) fprintf(zFp, "mail=\n"); 244*5c51f124SMoriah Waterland } else if (strncmp(buf, "partial=", 8) == 0) { 245*5c51f124SMoriah Waterland (void) fprintf(zFp, "partial=nocheck\n"); 246*5c51f124SMoriah Waterland } else if (strncmp(buf, "rdepend=", 8) == 0) { 247*5c51f124SMoriah Waterland (void) fprintf(zFp, "rdepend=nocheck\n"); 248*5c51f124SMoriah Waterland } else if (strncmp(buf, "runlevel=", 9) == 0) { 249*5c51f124SMoriah Waterland (void) fprintf(zFp, "runlevel=nocheck\n"); 250*5c51f124SMoriah Waterland } else if (strncmp(buf, "setuid=", 7) == 0) { 251*5c51f124SMoriah Waterland (void) fprintf(zFp, "setuid=nocheck\n"); 252*5c51f124SMoriah Waterland } else if (strncmp(buf, "space=", 6) == 0) { 253*5c51f124SMoriah Waterland (void) fprintf(zFp, "space=nocheck\n"); 254*5c51f124SMoriah Waterland } else { 255*5c51f124SMoriah Waterland (void) fprintf(zFp, "%s", buf); 256*5c51f124SMoriah Waterland } 257*5c51f124SMoriah Waterland } 258*5c51f124SMoriah Waterland 259*5c51f124SMoriah Waterland /* close admin file and return success */ 260*5c51f124SMoriah Waterland 261*5c51f124SMoriah Waterland (void) fclose(zFp); 262*5c51f124SMoriah Waterland return (B_TRUE); 263*5c51f124SMoriah Waterland } 264*5c51f124SMoriah Waterland 265*5c51f124SMoriah Waterland /* 266*5c51f124SMoriah Waterland * Name: z_brands_are_implemented 267*5c51f124SMoriah Waterland * Description: Determine if any branded zones may be present 268*5c51f124SMoriah Waterland * Arguments: void 269*5c51f124SMoriah Waterland * Returns: boolean_t 270*5c51f124SMoriah Waterland * == B_TRUE - branded zones are supported 271*5c51f124SMoriah Waterland * == B_FALSE - branded zones are not supported 272*5c51f124SMoriah Waterland */ 273*5c51f124SMoriah Waterland 274*5c51f124SMoriah Waterland boolean_t 275*5c51f124SMoriah Waterland z_brands_are_implemented(void) 276*5c51f124SMoriah Waterland { 277*5c51f124SMoriah Waterland static boolean_t _brandsImplementedDetermined = B_FALSE; 278*5c51f124SMoriah Waterland static boolean_t _brandsAreImplemented = B_FALSE; 279*5c51f124SMoriah Waterland 280*5c51f124SMoriah Waterland /* if availability has not been determined, cache it now */ 281*5c51f124SMoriah Waterland 282*5c51f124SMoriah Waterland if (!_brandsImplementedDetermined) { 283*5c51f124SMoriah Waterland _brandsImplementedDetermined = B_TRUE; 284*5c51f124SMoriah Waterland _brandsAreImplemented = _z_brands_are_implemented(); 285*5c51f124SMoriah Waterland if (_brandsAreImplemented) { 286*5c51f124SMoriah Waterland _z_echoDebug(DBG_BRANDS_ARE_IMPLEMENTED); 287*5c51f124SMoriah Waterland } else { 288*5c51f124SMoriah Waterland _z_echoDebug(DBG_BRANDS_NOT_IMPLEMENTED); 289*5c51f124SMoriah Waterland } 290*5c51f124SMoriah Waterland } 291*5c51f124SMoriah Waterland 292*5c51f124SMoriah Waterland /* return cached answer */ 293*5c51f124SMoriah Waterland 294*5c51f124SMoriah Waterland return (_brandsAreImplemented); 295*5c51f124SMoriah Waterland } 296*5c51f124SMoriah Waterland 297*5c51f124SMoriah Waterland /* 298*5c51f124SMoriah Waterland * Name: z_free_zone_list 299*5c51f124SMoriah Waterland * Description: free contents of zoneList_t object 300*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object to free 301*5c51f124SMoriah Waterland * Returns: void 302*5c51f124SMoriah Waterland */ 303*5c51f124SMoriah Waterland 304*5c51f124SMoriah Waterland void 305*5c51f124SMoriah Waterland z_free_zone_list(zoneList_t a_zlst) 306*5c51f124SMoriah Waterland { 307*5c51f124SMoriah Waterland int numzones; 308*5c51f124SMoriah Waterland 309*5c51f124SMoriah Waterland /* ignore empty list */ 310*5c51f124SMoriah Waterland 311*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 312*5c51f124SMoriah Waterland return; 313*5c51f124SMoriah Waterland } 314*5c51f124SMoriah Waterland 315*5c51f124SMoriah Waterland /* free each entry in the zone list */ 316*5c51f124SMoriah Waterland 317*5c51f124SMoriah Waterland for (numzones = 0; a_zlst[numzones]._zlName != (char *)NULL; 318*5c51f124SMoriah Waterland numzones++) { 319*5c51f124SMoriah Waterland zoneListElement_t *zelm = &a_zlst[numzones]; 320*5c51f124SMoriah Waterland 321*5c51f124SMoriah Waterland /* free zone name string */ 322*5c51f124SMoriah Waterland 323*5c51f124SMoriah Waterland free(zelm->_zlName); 324*5c51f124SMoriah Waterland 325*5c51f124SMoriah Waterland /* free zonepath string */ 326*5c51f124SMoriah Waterland 327*5c51f124SMoriah Waterland if (zelm->_zlPath != (char *)NULL) { 328*5c51f124SMoriah Waterland free(zelm->_zlPath); 329*5c51f124SMoriah Waterland } 330*5c51f124SMoriah Waterland 331*5c51f124SMoriah Waterland /* free list of inherited package directories */ 332*5c51f124SMoriah Waterland 333*5c51f124SMoriah Waterland if (zelm->_zlInheritedDirs != (char **)NULL) { 334*5c51f124SMoriah Waterland int n; 335*5c51f124SMoriah Waterland 336*5c51f124SMoriah Waterland for (n = 0; 337*5c51f124SMoriah Waterland (zelm->_zlInheritedDirs)[n] != (char *)NULL; 338*5c51f124SMoriah Waterland n++) { 339*5c51f124SMoriah Waterland (void) free((zelm->_zlInheritedDirs)[n]); 340*5c51f124SMoriah Waterland } 341*5c51f124SMoriah Waterland (void) free(zelm->_zlInheritedDirs); 342*5c51f124SMoriah Waterland } 343*5c51f124SMoriah Waterland } 344*5c51f124SMoriah Waterland 345*5c51f124SMoriah Waterland /* free handle to the list */ 346*5c51f124SMoriah Waterland 347*5c51f124SMoriah Waterland free(a_zlst); 348*5c51f124SMoriah Waterland } 349*5c51f124SMoriah Waterland 350*5c51f124SMoriah Waterland /* 351*5c51f124SMoriah Waterland * Name: z_get_nonglobal_zone_list 352*5c51f124SMoriah Waterland * Description: return zoneList_t object describing all non-global 353*5c51f124SMoriah Waterland * native zones - branded zones are not included in list 354*5c51f124SMoriah Waterland * Arguments: None. 355*5c51f124SMoriah Waterland * Returns: zoneList_t 356*5c51f124SMoriah Waterland * == NULL - error, list could not be generated 357*5c51f124SMoriah Waterland * != NULL - success, list returned 358*5c51f124SMoriah Waterland * NOTE: Any zoneList_t returned is placed in new storage for the 359*5c51f124SMoriah Waterland * calling function. The caller must use 'z_free_zone_list' to 360*5c51f124SMoriah Waterland * dispose of the storage once the list is no longer needed. 361*5c51f124SMoriah Waterland */ 362*5c51f124SMoriah Waterland 363*5c51f124SMoriah Waterland zoneList_t 364*5c51f124SMoriah Waterland z_get_nonglobal_zone_list(void) 365*5c51f124SMoriah Waterland { 366*5c51f124SMoriah Waterland zoneList_t zones; 367*5c51f124SMoriah Waterland zoneBrandList_t *brands = NULL; 368*5c51f124SMoriah Waterland 369*5c51f124SMoriah Waterland if ((brands = z_make_brand_list("native cluster", " ")) == NULL) 370*5c51f124SMoriah Waterland return (NULL); 371*5c51f124SMoriah Waterland 372*5c51f124SMoriah Waterland zones = z_get_nonglobal_zone_list_by_brand(brands); 373*5c51f124SMoriah Waterland 374*5c51f124SMoriah Waterland z_free_brand_list(brands); 375*5c51f124SMoriah Waterland 376*5c51f124SMoriah Waterland return (zones); 377*5c51f124SMoriah Waterland } 378*5c51f124SMoriah Waterland 379*5c51f124SMoriah Waterland /* 380*5c51f124SMoriah Waterland * Name: z_free_brand_list 381*5c51f124SMoriah Waterland * Description: Free contents of zoneBrandList_t object 382*5c51f124SMoriah Waterland * Arguments: brands - pointer to zoneBrandList_t object to free 383*5c51f124SMoriah Waterland * Returns: void 384*5c51f124SMoriah Waterland */ 385*5c51f124SMoriah Waterland void 386*5c51f124SMoriah Waterland z_free_brand_list(zoneBrandList_t *brands) 387*5c51f124SMoriah Waterland { 388*5c51f124SMoriah Waterland while (brands != NULL) { 389*5c51f124SMoriah Waterland zoneBrandList_t *temp = brands; 390*5c51f124SMoriah Waterland free(brands->string_ptr); 391*5c51f124SMoriah Waterland brands = brands->next; 392*5c51f124SMoriah Waterland free(temp); 393*5c51f124SMoriah Waterland } 394*5c51f124SMoriah Waterland } 395*5c51f124SMoriah Waterland 396*5c51f124SMoriah Waterland /* 397*5c51f124SMoriah Waterland * Name: z_make_brand_list 398*5c51f124SMoriah Waterland * Description: Given a string with a list of brand name delimited by 399*5c51f124SMoriah Waterland * the delimeter passed in, build a zoneBrandList_t structure 400*5c51f124SMoriah Waterland * with the list of brand names and return it to the caller. 401*5c51f124SMoriah Waterland * Arguments: 402*5c51f124SMoriah Waterland * brands - const char pointer to string list of brand names 403*5c51f124SMoriah Waterland * delim - const char pointer to string representing the 404*5c51f124SMoriah Waterland * delimeter for brands string. 405*5c51f124SMoriah Waterland * Returns: zoneBrandList_t * 406*5c51f124SMoriah Waterland * == NULL - error, list could not be generated 407*5c51f124SMoriah Waterland * != NULL - success, list returned 408*5c51f124SMoriah Waterland * NOTE: Any zoneBrandList_t returned is placed in new storage for the 409*5c51f124SMoriah Waterland * calling function. The caller must use 'z_free_brand_list' to 410*5c51f124SMoriah Waterland * dispose of the storage once the list is no longer needed. 411*5c51f124SMoriah Waterland */ 412*5c51f124SMoriah Waterland zoneBrandList_t * 413*5c51f124SMoriah Waterland z_make_brand_list(const char *brands, const char *delim) 414*5c51f124SMoriah Waterland { 415*5c51f124SMoriah Waterland zoneBrandList_t *brand = NULL, *head = NULL; 416*5c51f124SMoriah Waterland char *blist = NULL; 417*5c51f124SMoriah Waterland char *str = NULL; 418*5c51f124SMoriah Waterland 419*5c51f124SMoriah Waterland if ((blist = strdup(brands)) == NULL) 420*5c51f124SMoriah Waterland return (NULL); 421*5c51f124SMoriah Waterland 422*5c51f124SMoriah Waterland if ((str = strtok(blist, delim)) != NULL) { 423*5c51f124SMoriah Waterland if ((brand = (zoneBrandList_t *) 424*5c51f124SMoriah Waterland malloc(sizeof (struct _zoneBrandList))) == NULL) { 425*5c51f124SMoriah Waterland return (NULL); 426*5c51f124SMoriah Waterland } 427*5c51f124SMoriah Waterland 428*5c51f124SMoriah Waterland head = brand; 429*5c51f124SMoriah Waterland brand->string_ptr = strdup(str); 430*5c51f124SMoriah Waterland brand->next = NULL; 431*5c51f124SMoriah Waterland 432*5c51f124SMoriah Waterland while ((str = strtok(NULL, delim)) != NULL) { 433*5c51f124SMoriah Waterland if ((brand->next = (zoneBrandList_t *) 434*5c51f124SMoriah Waterland malloc(sizeof (struct _zoneBrandList))) == NULL) { 435*5c51f124SMoriah Waterland return (NULL); 436*5c51f124SMoriah Waterland } 437*5c51f124SMoriah Waterland 438*5c51f124SMoriah Waterland brand = brand->next; 439*5c51f124SMoriah Waterland brand->string_ptr = strdup(str); 440*5c51f124SMoriah Waterland brand->next = NULL; 441*5c51f124SMoriah Waterland } 442*5c51f124SMoriah Waterland } 443*5c51f124SMoriah Waterland 444*5c51f124SMoriah Waterland free(blist); 445*5c51f124SMoriah Waterland return (head); 446*5c51f124SMoriah Waterland } 447*5c51f124SMoriah Waterland 448*5c51f124SMoriah Waterland /* 449*5c51f124SMoriah Waterland * Name: z_get_nonglobal_zone_list_by_brand 450*5c51f124SMoriah Waterland * Description: return zoneList_t object describing all non-global 451*5c51f124SMoriah Waterland * zones matching the list of brands passed in. 452*5c51f124SMoriah Waterland * Arguments: brands - The list of zone brands to look for. 453*5c51f124SMoriah Waterland * Returns: zoneList_t 454*5c51f124SMoriah Waterland * == NULL - error, list could not be generated 455*5c51f124SMoriah Waterland * != NULL - success, list returned 456*5c51f124SMoriah Waterland * NOTE: Any zoneList_t returned is placed in new storage for the 457*5c51f124SMoriah Waterland * calling function. The caller must use 'z_free_zone_list' to 458*5c51f124SMoriah Waterland * dispose of the storage once the list is no longer needed. 459*5c51f124SMoriah Waterland */ 460*5c51f124SMoriah Waterland zoneList_t 461*5c51f124SMoriah Waterland z_get_nonglobal_zone_list_by_brand(zoneBrandList_t *brands) 462*5c51f124SMoriah Waterland { 463*5c51f124SMoriah Waterland FILE *zoneIndexFP; 464*5c51f124SMoriah Waterland int numzones = 0; 465*5c51f124SMoriah Waterland struct zoneent *ze; 466*5c51f124SMoriah Waterland zoneList_t zlst = NULL; 467*5c51f124SMoriah Waterland FILE *mapFP; 468*5c51f124SMoriah Waterland char zonename[ZONENAME_MAX]; 469*5c51f124SMoriah Waterland zone_spec_t *zent; 470*5c51f124SMoriah Waterland 471*5c51f124SMoriah Waterland /* if zones are not implemented, return empty list */ 472*5c51f124SMoriah Waterland 473*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 474*5c51f124SMoriah Waterland return ((zoneList_t)NULL); 475*5c51f124SMoriah Waterland } 476*5c51f124SMoriah Waterland 477*5c51f124SMoriah Waterland /* 478*5c51f124SMoriah Waterland * Open the zone index file. Note that getzoneent_private() handles 479*5c51f124SMoriah Waterland * NULL. 480*5c51f124SMoriah Waterland */ 481*5c51f124SMoriah Waterland zoneIndexFP = setzoneent(); 482*5c51f124SMoriah Waterland 483*5c51f124SMoriah Waterland mapFP = zonecfg_open_scratch("", B_FALSE); 484*5c51f124SMoriah Waterland 485*5c51f124SMoriah Waterland /* index file open; scan all zones; see if any are at least installed */ 486*5c51f124SMoriah Waterland 487*5c51f124SMoriah Waterland while ((ze = getzoneent_private(zoneIndexFP)) != NULL) { 488*5c51f124SMoriah Waterland zone_state_t st; 489*5c51f124SMoriah Waterland 490*5c51f124SMoriah Waterland /* skip the global zone */ 491*5c51f124SMoriah Waterland 492*5c51f124SMoriah Waterland if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) { 493*5c51f124SMoriah Waterland free(ze); 494*5c51f124SMoriah Waterland continue; 495*5c51f124SMoriah Waterland } 496*5c51f124SMoriah Waterland 497*5c51f124SMoriah Waterland /* 498*5c51f124SMoriah Waterland * skip any zones with brands not on the brand list 499*5c51f124SMoriah Waterland */ 500*5c51f124SMoriah Waterland if (!z_is_zone_brand_in_list(ze->zone_name, brands)) { 501*5c51f124SMoriah Waterland free(ze); 502*5c51f124SMoriah Waterland continue; 503*5c51f124SMoriah Waterland } 504*5c51f124SMoriah Waterland 505*5c51f124SMoriah Waterland /* 506*5c51f124SMoriah Waterland * If the user specified an explicit zone list, then ignore any 507*5c51f124SMoriah Waterland * zones that aren't on that list. 508*5c51f124SMoriah Waterland */ 509*5c51f124SMoriah Waterland if ((zent = _z_global_data._zone_spec) != NULL) { 510*5c51f124SMoriah Waterland while (zent != NULL) { 511*5c51f124SMoriah Waterland if (strcmp(zent->zl_name, ze->zone_name) == 0) 512*5c51f124SMoriah Waterland break; 513*5c51f124SMoriah Waterland zent = zent->zl_next; 514*5c51f124SMoriah Waterland } 515*5c51f124SMoriah Waterland if (zent == NULL) { 516*5c51f124SMoriah Waterland free(ze); 517*5c51f124SMoriah Waterland continue; 518*5c51f124SMoriah Waterland } 519*5c51f124SMoriah Waterland } 520*5c51f124SMoriah Waterland 521*5c51f124SMoriah Waterland /* non-global zone: create entry for this zone */ 522*5c51f124SMoriah Waterland 523*5c51f124SMoriah Waterland if (numzones == 0) { 524*5c51f124SMoriah Waterland zlst = (zoneList_t)_z_calloc( 525*5c51f124SMoriah Waterland sizeof (zoneListElement_t)*2); 526*5c51f124SMoriah Waterland } else { 527*5c51f124SMoriah Waterland zlst = (zoneList_t)_z_realloc(zlst, 528*5c51f124SMoriah Waterland sizeof (zoneListElement_t)*(numzones+2)); 529*5c51f124SMoriah Waterland (void) memset(&zlst[numzones], 0L, 530*5c51f124SMoriah Waterland sizeof (zoneListElement_t)*2); 531*5c51f124SMoriah Waterland } 532*5c51f124SMoriah Waterland 533*5c51f124SMoriah Waterland /* 534*5c51f124SMoriah Waterland * remember the zone name, zonepath and the current 535*5c51f124SMoriah Waterland * zone state of the zone. 536*5c51f124SMoriah Waterland */ 537*5c51f124SMoriah Waterland zlst[numzones]._zlName = _z_strdup(ze->zone_name); 538*5c51f124SMoriah Waterland zlst[numzones]._zlPath = _z_strdup(ze->zone_path); 539*5c51f124SMoriah Waterland zlst[numzones]._zlOrigInstallState = ze->zone_state; 540*5c51f124SMoriah Waterland zlst[numzones]._zlCurrInstallState = ze->zone_state; 541*5c51f124SMoriah Waterland 542*5c51f124SMoriah Waterland /* get the zone kernel status */ 543*5c51f124SMoriah Waterland 544*5c51f124SMoriah Waterland if (zone_get_state(ze->zone_name, &st) != Z_OK) { 545*5c51f124SMoriah Waterland st = ZONE_STATE_INCOMPLETE; 546*5c51f124SMoriah Waterland } 547*5c51f124SMoriah Waterland 548*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_NGZ_LIST_STATES, 549*5c51f124SMoriah Waterland ze->zone_name, ze->zone_state, st); 550*5c51f124SMoriah Waterland 551*5c51f124SMoriah Waterland /* 552*5c51f124SMoriah Waterland * For a scratch zone, we need to know the kernel zone name. 553*5c51f124SMoriah Waterland */ 554*5c51f124SMoriah Waterland if (zonecfg_in_alt_root() && mapFP != NULL && 555*5c51f124SMoriah Waterland zonecfg_find_scratch(mapFP, ze->zone_name, 556*5c51f124SMoriah Waterland zonecfg_get_root(), zonename, sizeof (zonename)) != -1) { 557*5c51f124SMoriah Waterland free(zlst[numzones]._zlScratchName); 558*5c51f124SMoriah Waterland zlst[numzones]._zlScratchName = _z_strdup(zonename); 559*5c51f124SMoriah Waterland } 560*5c51f124SMoriah Waterland 561*5c51f124SMoriah Waterland /* 562*5c51f124SMoriah Waterland * remember the current kernel status of the zone. 563*5c51f124SMoriah Waterland */ 564*5c51f124SMoriah Waterland 565*5c51f124SMoriah Waterland zlst[numzones]._zlOrigKernelStatus = st; 566*5c51f124SMoriah Waterland zlst[numzones]._zlCurrKernelStatus = st; 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland zlst[numzones]._zlInheritedDirs = 569*5c51f124SMoriah Waterland _z_get_inherited_dirs(ze->zone_name); 570*5c51f124SMoriah Waterland 571*5c51f124SMoriah Waterland numzones++; 572*5c51f124SMoriah Waterland free(ze); 573*5c51f124SMoriah Waterland } 574*5c51f124SMoriah Waterland 575*5c51f124SMoriah Waterland /* close the index file */ 576*5c51f124SMoriah Waterland endzoneent(zoneIndexFP); 577*5c51f124SMoriah Waterland 578*5c51f124SMoriah Waterland if (mapFP != NULL) 579*5c51f124SMoriah Waterland zonecfg_close_scratch(mapFP); 580*5c51f124SMoriah Waterland 581*5c51f124SMoriah Waterland /* return generated list */ 582*5c51f124SMoriah Waterland 583*5c51f124SMoriah Waterland return (zlst); 584*5c51f124SMoriah Waterland } 585*5c51f124SMoriah Waterland 586*5c51f124SMoriah Waterland /* 587*5c51f124SMoriah Waterland * Name: z_get_zonename 588*5c51f124SMoriah Waterland * Description: return the name of the current zone 589*5c51f124SMoriah Waterland * Arguments: void 590*5c51f124SMoriah Waterland * Returns: char * 591*5c51f124SMoriah Waterland * - pointer to string representing the name of the current 592*5c51f124SMoriah Waterland * zone 593*5c51f124SMoriah Waterland * NOTE: Any string returned is placed in new storage for the 594*5c51f124SMoriah Waterland * calling function. The caller must use 'Free' to dispose 595*5c51f124SMoriah Waterland * of the storage once the string is no longer needed. 596*5c51f124SMoriah Waterland */ 597*5c51f124SMoriah Waterland 598*5c51f124SMoriah Waterland char * 599*5c51f124SMoriah Waterland z_get_zonename(void) 600*5c51f124SMoriah Waterland { 601*5c51f124SMoriah Waterland ssize_t zonenameLen; 602*5c51f124SMoriah Waterland char zonename[ZONENAME_MAX]; 603*5c51f124SMoriah Waterland zoneid_t zoneid = (zoneid_t)-1; 604*5c51f124SMoriah Waterland 605*5c51f124SMoriah Waterland /* if zones are not implemented, return "" */ 606*5c51f124SMoriah Waterland 607*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 608*5c51f124SMoriah Waterland return (_z_strdup("")); 609*5c51f124SMoriah Waterland } 610*5c51f124SMoriah Waterland 611*5c51f124SMoriah Waterland /* get the zone i.d. of the current zone */ 612*5c51f124SMoriah Waterland 613*5c51f124SMoriah Waterland zoneid = getzoneid(); 614*5c51f124SMoriah Waterland 615*5c51f124SMoriah Waterland /* get the name of the current zone */ 616*5c51f124SMoriah Waterland 617*5c51f124SMoriah Waterland zonenameLen = getzonenamebyid(zoneid, zonename, sizeof (zonename)); 618*5c51f124SMoriah Waterland 619*5c51f124SMoriah Waterland /* return "" if could not get zonename */ 620*5c51f124SMoriah Waterland 621*5c51f124SMoriah Waterland if (zonenameLen < 1) { 622*5c51f124SMoriah Waterland return (_z_strdup("")); 623*5c51f124SMoriah Waterland } 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland return (_z_strdup(zonename)); 626*5c51f124SMoriah Waterland } 627*5c51f124SMoriah Waterland 628*5c51f124SMoriah Waterland /* 629*5c51f124SMoriah Waterland * Name: z_global_only 630*5c51f124SMoriah Waterland * Description: Determine if the global zone is only zone on the spec list. 631*5c51f124SMoriah Waterland * Arguments: None 632*5c51f124SMoriah Waterland * Returns: B_TRUE if global zone is the only zone on the list, 633*5c51f124SMoriah Waterland * B_FALSE otherwise. 634*5c51f124SMoriah Waterland */ 635*5c51f124SMoriah Waterland 636*5c51f124SMoriah Waterland boolean_t 637*5c51f124SMoriah Waterland z_global_only(void) 638*5c51f124SMoriah Waterland { 639*5c51f124SMoriah Waterland /* return true if zones are not implemented - treate as global zone */ 640*5c51f124SMoriah Waterland 641*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 642*5c51f124SMoriah Waterland return (B_TRUE); 643*5c51f124SMoriah Waterland } 644*5c51f124SMoriah Waterland 645*5c51f124SMoriah Waterland /* return true if this is the global zone */ 646*5c51f124SMoriah Waterland 647*5c51f124SMoriah Waterland if (_z_global_data._zone_spec != NULL && 648*5c51f124SMoriah Waterland _z_global_data._zone_spec->zl_next == NULL && 649*5c51f124SMoriah Waterland strcmp(_z_global_data._zone_spec->zl_name, GLOBAL_ZONENAME) == 0) { 650*5c51f124SMoriah Waterland return (B_TRUE); 651*5c51f124SMoriah Waterland } 652*5c51f124SMoriah Waterland 653*5c51f124SMoriah Waterland /* return false - not the global zone */ 654*5c51f124SMoriah Waterland 655*5c51f124SMoriah Waterland return (B_FALSE); 656*5c51f124SMoriah Waterland } 657*5c51f124SMoriah Waterland 658*5c51f124SMoriah Waterland /* 659*5c51f124SMoriah Waterland * Name: z_lock_this_zone 660*5c51f124SMoriah Waterland * Description: lock this zone 661*5c51f124SMoriah Waterland * Arguments: a_lflags - [RO, *RO] - (ZLOCKS_T) 662*5c51f124SMoriah Waterland * Flags indicating which locks to acquire 663*5c51f124SMoriah Waterland * Returns: boolean_t 664*5c51f124SMoriah Waterland * == B_TRUE - success specified locks acquired 665*5c51f124SMoriah Waterland * == B_FALSE - failure specified locks not acquired 666*5c51f124SMoriah Waterland * NOTE: the lock objects for "this zone" are maintained internally. 667*5c51f124SMoriah Waterland */ 668*5c51f124SMoriah Waterland 669*5c51f124SMoriah Waterland boolean_t 670*5c51f124SMoriah Waterland z_lock_this_zone(ZLOCKS_T a_lflags) 671*5c51f124SMoriah Waterland { 672*5c51f124SMoriah Waterland boolean_t b; 673*5c51f124SMoriah Waterland char *zoneName; 674*5c51f124SMoriah Waterland pid_t pid = (pid_t)0; 675*5c51f124SMoriah Waterland 676*5c51f124SMoriah Waterland /* entry assertions */ 677*5c51f124SMoriah Waterland 678*5c51f124SMoriah Waterland assert(a_lflags != ZLOCKS_NONE); 679*5c51f124SMoriah Waterland 680*5c51f124SMoriah Waterland /* entry debugging info */ 681*5c51f124SMoriah Waterland 682*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_THIS, a_lflags); 683*5c51f124SMoriah Waterland 684*5c51f124SMoriah Waterland zoneName = z_get_zonename(); 685*5c51f124SMoriah Waterland pid = getpid(); 686*5c51f124SMoriah Waterland 687*5c51f124SMoriah Waterland /* lock zone administration */ 688*5c51f124SMoriah Waterland 689*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_ZONE_ADMIN) { 690*5c51f124SMoriah Waterland b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks, 691*5c51f124SMoriah Waterland zoneName, LOBJ_ZONEADMIN, pid, 692*5c51f124SMoriah Waterland MSG_ZONES_LCK_THIS_ZONEADM, 693*5c51f124SMoriah Waterland ERR_ZONES_LCK_THIS_ZONEADM); 694*5c51f124SMoriah Waterland if (!b) { 695*5c51f124SMoriah Waterland (void) free(zoneName); 696*5c51f124SMoriah Waterland return (B_FALSE); 697*5c51f124SMoriah Waterland } 698*5c51f124SMoriah Waterland } 699*5c51f124SMoriah Waterland 700*5c51f124SMoriah Waterland /* lock package administration always */ 701*5c51f124SMoriah Waterland 702*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PKG_ADMIN) { 703*5c51f124SMoriah Waterland b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks, 704*5c51f124SMoriah Waterland zoneName, LOBJ_PKGADMIN, pid, 705*5c51f124SMoriah Waterland MSG_ZONES_LCK_THIS_PKGADM, 706*5c51f124SMoriah Waterland ERR_ZONES_LCK_THIS_PKGADM); 707*5c51f124SMoriah Waterland if (!b) { 708*5c51f124SMoriah Waterland (void) z_unlock_this_zone(a_lflags); 709*5c51f124SMoriah Waterland (void) free(zoneName); 710*5c51f124SMoriah Waterland return (B_FALSE); 711*5c51f124SMoriah Waterland } 712*5c51f124SMoriah Waterland } 713*5c51f124SMoriah Waterland 714*5c51f124SMoriah Waterland /* lock patch administration always */ 715*5c51f124SMoriah Waterland 716*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PATCH_ADMIN) { 717*5c51f124SMoriah Waterland b = _z_lock_zone_object(&_z_global_data._z_ObjectLocks, 718*5c51f124SMoriah Waterland zoneName, LOBJ_PATCHADMIN, pid, 719*5c51f124SMoriah Waterland MSG_ZONES_LCK_THIS_PATCHADM, 720*5c51f124SMoriah Waterland ERR_ZONES_LCK_THIS_PATCHADM); 721*5c51f124SMoriah Waterland if (!b) { 722*5c51f124SMoriah Waterland (void) z_unlock_this_zone(a_lflags); 723*5c51f124SMoriah Waterland (void) free(zoneName); 724*5c51f124SMoriah Waterland return (B_FALSE); 725*5c51f124SMoriah Waterland } 726*5c51f124SMoriah Waterland } 727*5c51f124SMoriah Waterland 728*5c51f124SMoriah Waterland (void) free(zoneName); 729*5c51f124SMoriah Waterland 730*5c51f124SMoriah Waterland return (B_TRUE); 731*5c51f124SMoriah Waterland } 732*5c51f124SMoriah Waterland 733*5c51f124SMoriah Waterland /* 734*5c51f124SMoriah Waterland * Name: z_lock_zones 735*5c51f124SMoriah Waterland * Description: lock specified zones 736*5c51f124SMoriah Waterland * Arguments: a_zlst - zoneList_t object describing zones to lock 737*5c51f124SMoriah Waterland * a_lflags - [RO, *RO] - (ZLOCKS_T) 738*5c51f124SMoriah Waterland * Flags indicating which locks to acquire 739*5c51f124SMoriah Waterland * Returns: boolean_t 740*5c51f124SMoriah Waterland * == B_TRUE - success, zones locked 741*5c51f124SMoriah Waterland * == B_FALSE - failure, zones not locked 742*5c51f124SMoriah Waterland */ 743*5c51f124SMoriah Waterland 744*5c51f124SMoriah Waterland boolean_t 745*5c51f124SMoriah Waterland z_lock_zones(zoneList_t a_zlst, ZLOCKS_T a_lflags) 746*5c51f124SMoriah Waterland { 747*5c51f124SMoriah Waterland boolean_t b; 748*5c51f124SMoriah Waterland int i; 749*5c51f124SMoriah Waterland 750*5c51f124SMoriah Waterland /* entry assertions */ 751*5c51f124SMoriah Waterland 752*5c51f124SMoriah Waterland assert(a_lflags != ZLOCKS_NONE); 753*5c51f124SMoriah Waterland 754*5c51f124SMoriah Waterland /* entry debugging info */ 755*5c51f124SMoriah Waterland 756*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONES, a_lflags); 757*5c51f124SMoriah Waterland 758*5c51f124SMoriah Waterland /* if zones are not implemented, return TRUE */ 759*5c51f124SMoriah Waterland 760*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 761*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONES_UNIMP); 762*5c51f124SMoriah Waterland return (B_TRUE); 763*5c51f124SMoriah Waterland } 764*5c51f124SMoriah Waterland 765*5c51f124SMoriah Waterland /* lock this zone first before locking other zones */ 766*5c51f124SMoriah Waterland 767*5c51f124SMoriah Waterland b = z_lock_this_zone(a_lflags); 768*5c51f124SMoriah Waterland if (b == B_FALSE) { 769*5c51f124SMoriah Waterland return (b); 770*5c51f124SMoriah Waterland } 771*5c51f124SMoriah Waterland 772*5c51f124SMoriah Waterland /* ignore empty list */ 773*5c51f124SMoriah Waterland 774*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 775*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONES_NOZONES); 776*5c51f124SMoriah Waterland return (B_FALSE); 777*5c51f124SMoriah Waterland } 778*5c51f124SMoriah Waterland 779*5c51f124SMoriah Waterland /* zones exist */ 780*5c51f124SMoriah Waterland 781*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_LCK_ZONES_EXIST); 782*5c51f124SMoriah Waterland 783*5c51f124SMoriah Waterland /* 784*5c51f124SMoriah Waterland * lock each listed zone that is currently running 785*5c51f124SMoriah Waterland */ 786*5c51f124SMoriah Waterland 787*5c51f124SMoriah Waterland for (i = 0; (a_zlst[i]._zlName != (char *)NULL); i++) { 788*5c51f124SMoriah Waterland /* ignore zone if already locked */ 789*5c51f124SMoriah Waterland if (a_zlst[i]._zlStatus & ZST_LOCKED) { 790*5c51f124SMoriah Waterland continue; 791*5c51f124SMoriah Waterland } 792*5c51f124SMoriah Waterland 793*5c51f124SMoriah Waterland /* ignore zone if not running */ 794*5c51f124SMoriah Waterland if (a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_RUNNING && 795*5c51f124SMoriah Waterland a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_MOUNTED) { 796*5c51f124SMoriah Waterland continue; 797*5c51f124SMoriah Waterland } 798*5c51f124SMoriah Waterland 799*5c51f124SMoriah Waterland /* 800*5c51f124SMoriah Waterland * mark zone locked - if interrupted out during lock, an attempt 801*5c51f124SMoriah Waterland * will be made to release the lock 802*5c51f124SMoriah Waterland */ 803*5c51f124SMoriah Waterland a_zlst[i]._zlStatus |= ZST_LOCKED; 804*5c51f124SMoriah Waterland 805*5c51f124SMoriah Waterland /* lock this zone */ 806*5c51f124SMoriah Waterland b = _z_lock_zone(&a_zlst[i], a_lflags); 807*5c51f124SMoriah Waterland 808*5c51f124SMoriah Waterland /* on failure unlock all zones and return error */ 809*5c51f124SMoriah Waterland if (b != B_TRUE) { 810*5c51f124SMoriah Waterland _z_program_error(ERR_ZONES_LCK_ZONES_FAILED, 811*5c51f124SMoriah Waterland a_zlst[i]._zlName); 812*5c51f124SMoriah Waterland (void) z_unlock_zones(a_zlst, a_lflags); 813*5c51f124SMoriah Waterland return (B_FALSE); 814*5c51f124SMoriah Waterland } 815*5c51f124SMoriah Waterland } 816*5c51f124SMoriah Waterland 817*5c51f124SMoriah Waterland /* success */ 818*5c51f124SMoriah Waterland 819*5c51f124SMoriah Waterland return (B_TRUE); 820*5c51f124SMoriah Waterland } 821*5c51f124SMoriah Waterland 822*5c51f124SMoriah Waterland /* 823*5c51f124SMoriah Waterland * Name: z_mount_in_lz 824*5c51f124SMoriah Waterland * Description: Mount global zone directory in specified zone's root file system 825*5c51f124SMoriah Waterland * Arguments: r_lzMountPoint - pointer to handle to string - on success, the 826*5c51f124SMoriah Waterland * full path to the mount point relative to the global zone 827*5c51f124SMoriah Waterland * root file system is returned here - this is needed to 828*5c51f124SMoriah Waterland * unmount the directory when it is no longer needed 829*5c51f124SMoriah Waterland * r_lzRootPath - pointer to handle to string - on success, the 830*5c51f124SMoriah Waterland * full path to the mount point relative to the specified 831*5c51f124SMoriah Waterland * zone's root file system is returned here - this is 832*5c51f124SMoriah Waterland * passed to any command executing in the specified zone to 833*5c51f124SMoriah Waterland * access the directory mounted 834*5c51f124SMoriah Waterland * a_zoneName - pointer to string representing the name of the zone 835*5c51f124SMoriah Waterland * to mount the specified global zone directory in 836*5c51f124SMoriah Waterland * a_gzPath - pointer to string representing the full absolute path 837*5c51f124SMoriah Waterland * of the global zone directory to LOFS mount inside of the 838*5c51f124SMoriah Waterland * specified non-global zone 839*5c51f124SMoriah Waterland * a_mountPointPrefix - pointer to string representing the prefix 840*5c51f124SMoriah Waterland * to be used when creating the mount point name in the 841*5c51f124SMoriah Waterland * specified zone's root directory 842*5c51f124SMoriah Waterland * Returns: boolean_t 843*5c51f124SMoriah Waterland * == B_TRUE - global zone directory mounted successfully 844*5c51f124SMoriah Waterland * == B_FALSE - failed to mount directory in specified zone 845*5c51f124SMoriah Waterland * NOTE: Any strings returned is placed in new storage for the 846*5c51f124SMoriah Waterland * calling function. The caller must use 'Free' to dispose 847*5c51f124SMoriah Waterland * of the storage once the strings are no longer needed. 848*5c51f124SMoriah Waterland */ 849*5c51f124SMoriah Waterland 850*5c51f124SMoriah Waterland boolean_t 851*5c51f124SMoriah Waterland z_mount_in_lz(char **r_lzMountPoint, char **r_lzRootPath, char *a_zoneName, 852*5c51f124SMoriah Waterland char *a_gzPath, char *a_mountPointPrefix) 853*5c51f124SMoriah Waterland { 854*5c51f124SMoriah Waterland char lzRootPath[MAXPATHLEN] = {'\0'}; 855*5c51f124SMoriah Waterland char uuid[MAXPATHLEN] = {'\0'}; 856*5c51f124SMoriah Waterland char gzMountPoint[MAXPATHLEN] = {'\0'}; 857*5c51f124SMoriah Waterland char lzMountPoint[MAXPATHLEN] = {'\0'}; 858*5c51f124SMoriah Waterland hrtime_t hretime; 859*5c51f124SMoriah Waterland int err; 860*5c51f124SMoriah Waterland int slen; 861*5c51f124SMoriah Waterland struct tm tstruct; 862*5c51f124SMoriah Waterland time_t thetime; 863*5c51f124SMoriah Waterland zoneid_t zid; 864*5c51f124SMoriah Waterland 865*5c51f124SMoriah Waterland /* entry assertions */ 866*5c51f124SMoriah Waterland 867*5c51f124SMoriah Waterland assert(a_zoneName != (char *)NULL); 868*5c51f124SMoriah Waterland assert(*a_zoneName != '\0'); 869*5c51f124SMoriah Waterland assert(a_gzPath != (char *)NULL); 870*5c51f124SMoriah Waterland assert(*a_gzPath != '\0'); 871*5c51f124SMoriah Waterland assert(r_lzMountPoint != (char **)NULL); 872*5c51f124SMoriah Waterland assert(r_lzRootPath != (char **)NULL); 873*5c51f124SMoriah Waterland 874*5c51f124SMoriah Waterland /* entry debugging info */ 875*5c51f124SMoriah Waterland 876*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_MOUNT_IN_LZ_ENTRY, a_zoneName, a_gzPath); 877*5c51f124SMoriah Waterland 878*5c51f124SMoriah Waterland /* reset returned non-global zone mount point path handle */ 879*5c51f124SMoriah Waterland 880*5c51f124SMoriah Waterland *r_lzMountPoint = (char *)NULL; 881*5c51f124SMoriah Waterland *r_lzRootPath = (char *)NULL; 882*5c51f124SMoriah Waterland 883*5c51f124SMoriah Waterland /* if zones are not implemented, return FALSE */ 884*5c51f124SMoriah Waterland 885*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 886*5c51f124SMoriah Waterland return (B_FALSE); 887*5c51f124SMoriah Waterland } 888*5c51f124SMoriah Waterland 889*5c51f124SMoriah Waterland /* error if global zone path is not absolute */ 890*5c51f124SMoriah Waterland 891*5c51f124SMoriah Waterland if (*a_gzPath != '/') { 892*5c51f124SMoriah Waterland _z_program_error(ERR_GZPATH_NOT_ABSOLUTE, a_gzPath); 893*5c51f124SMoriah Waterland return (B_FALSE); 894*5c51f124SMoriah Waterland } 895*5c51f124SMoriah Waterland 896*5c51f124SMoriah Waterland /* error if global zone path does not exist */ 897*5c51f124SMoriah Waterland 898*5c51f124SMoriah Waterland if (_z_is_directory(a_gzPath) != 0) { 899*5c51f124SMoriah Waterland _z_program_error(ERR_GZPATH_NOT_DIR, a_gzPath, strerror(errno)); 900*5c51f124SMoriah Waterland return (B_FALSE); 901*5c51f124SMoriah Waterland } 902*5c51f124SMoriah Waterland 903*5c51f124SMoriah Waterland /* verify that specified non-global zone exists */ 904*5c51f124SMoriah Waterland 905*5c51f124SMoriah Waterland err = zone_get_id(a_zoneName, &zid); 906*5c51f124SMoriah Waterland if (err != Z_OK) { 907*5c51f124SMoriah Waterland _z_program_error(ERR_GET_ZONEID, a_zoneName, 908*5c51f124SMoriah Waterland zonecfg_strerror(err)); 909*5c51f124SMoriah Waterland return (B_FALSE); 910*5c51f124SMoriah Waterland } 911*5c51f124SMoriah Waterland 912*5c51f124SMoriah Waterland /* obtain global zone path to non-global zones root file system */ 913*5c51f124SMoriah Waterland 914*5c51f124SMoriah Waterland err = zone_get_rootpath(a_zoneName, lzRootPath, sizeof (lzRootPath)); 915*5c51f124SMoriah Waterland if (err != Z_OK) { 916*5c51f124SMoriah Waterland _z_program_error(ERR_NO_ZONE_ROOTPATH, a_zoneName, 917*5c51f124SMoriah Waterland zonecfg_strerror(err)); 918*5c51f124SMoriah Waterland return (B_FALSE); 919*5c51f124SMoriah Waterland } 920*5c51f124SMoriah Waterland 921*5c51f124SMoriah Waterland if (lzRootPath[0] == '\0') { 922*5c51f124SMoriah Waterland _z_program_error(ERR_ROOTPATH_EMPTY, a_zoneName); 923*5c51f124SMoriah Waterland return (B_FALSE); 924*5c51f124SMoriah Waterland } 925*5c51f124SMoriah Waterland 926*5c51f124SMoriah Waterland /* 927*5c51f124SMoriah Waterland * lofs resolve the non-global zone's root path first in case 928*5c51f124SMoriah Waterland * its in a path that's been lofs mounted read-only. 929*5c51f124SMoriah Waterland * (e.g. This happens when we're tyring to patch a zone in an ABE 930*5c51f124SMoriah Waterland * that lives on a filesystem that the ABE shares with the currently 931*5c51f124SMoriah Waterland * running BE.) 932*5c51f124SMoriah Waterland */ 933*5c51f124SMoriah Waterland z_resolve_lofs(lzRootPath, sizeof (lzRootPath)); 934*5c51f124SMoriah Waterland 935*5c51f124SMoriah Waterland /* verify that the root path exists */ 936*5c51f124SMoriah Waterland 937*5c51f124SMoriah Waterland if (_z_is_directory(lzRootPath) != 0) { 938*5c51f124SMoriah Waterland _z_program_error(ERR_LZROOT_NOTDIR, lzRootPath, 939*5c51f124SMoriah Waterland strerror(errno)); 940*5c51f124SMoriah Waterland return (B_FALSE); 941*5c51f124SMoriah Waterland } 942*5c51f124SMoriah Waterland 943*5c51f124SMoriah Waterland /* 944*5c51f124SMoriah Waterland * generate a unique key - the key is the same length as unique uid 945*5c51f124SMoriah Waterland * but contains different information that is as unique as can be made; 946*5c51f124SMoriah Waterland * include current hires time (nanosecond real timer). Such a unique 947*5c51f124SMoriah Waterland * i.d. will look like: 948*5c51f124SMoriah Waterland * 0203104092-1145345-0004e94d6af481a0 949*5c51f124SMoriah Waterland */ 950*5c51f124SMoriah Waterland 951*5c51f124SMoriah Waterland hretime = gethrtime(); 952*5c51f124SMoriah Waterland 953*5c51f124SMoriah Waterland thetime = time((time_t *)NULL); 954*5c51f124SMoriah Waterland (void) localtime_r(&thetime, &tstruct); 955*5c51f124SMoriah Waterland 956*5c51f124SMoriah Waterland slen = snprintf(uuid, sizeof (uuid), 957*5c51f124SMoriah Waterland UUID_FORMAT, 958*5c51f124SMoriah Waterland tstruct.tm_mday, tstruct.tm_mon, tstruct.tm_year, 959*5c51f124SMoriah Waterland tstruct.tm_yday, tstruct.tm_hour, tstruct.tm_min, 960*5c51f124SMoriah Waterland tstruct.tm_sec, tstruct.tm_wday, hretime); 961*5c51f124SMoriah Waterland if (slen > sizeof (uuid)) { 962*5c51f124SMoriah Waterland _z_program_error(ERR_GZMOUNT_SNPRINTFUUID_FAILED, 963*5c51f124SMoriah Waterland UUID_FORMAT, sizeof (uuid)); 964*5c51f124SMoriah Waterland return (B_FALSE); 965*5c51f124SMoriah Waterland } 966*5c51f124SMoriah Waterland 967*5c51f124SMoriah Waterland /* create the global zone mount point */ 968*5c51f124SMoriah Waterland 969*5c51f124SMoriah Waterland slen = snprintf(gzMountPoint, sizeof (gzMountPoint), "%s/.SUNW_%s_%s", 970*5c51f124SMoriah Waterland lzRootPath, 971*5c51f124SMoriah Waterland a_mountPointPrefix ? a_mountPointPrefix : "zones", uuid); 972*5c51f124SMoriah Waterland if (slen > sizeof (gzMountPoint)) { 973*5c51f124SMoriah Waterland _z_program_error(ERR_GZMOUNT_SNPRINTFGMP_FAILED, 974*5c51f124SMoriah Waterland "%s/.SUNW_%s_%s", lzRootPath, 975*5c51f124SMoriah Waterland a_mountPointPrefix ? a_mountPointPrefix : "zones", 976*5c51f124SMoriah Waterland uuid, sizeof (gzMountPoint)); 977*5c51f124SMoriah Waterland return (B_FALSE); 978*5c51f124SMoriah Waterland } 979*5c51f124SMoriah Waterland 980*5c51f124SMoriah Waterland slen = snprintf(lzMountPoint, sizeof (lzMountPoint), "%s", 981*5c51f124SMoriah Waterland gzMountPoint+strlen(lzRootPath)); 982*5c51f124SMoriah Waterland if (slen > sizeof (lzMountPoint)) { 983*5c51f124SMoriah Waterland _z_program_error(ERR_GZMOUNT_SNPRINTFLMP_FAILED, 984*5c51f124SMoriah Waterland "%s", gzMountPoint+strlen(lzRootPath), 985*5c51f124SMoriah Waterland sizeof (lzMountPoint)); 986*5c51f124SMoriah Waterland return (B_FALSE); 987*5c51f124SMoriah Waterland } 988*5c51f124SMoriah Waterland 989*5c51f124SMoriah Waterland _z_echoDebug(DBG_MNTPT_NAMES, a_gzPath, a_zoneName, gzMountPoint, 990*5c51f124SMoriah Waterland lzMountPoint); 991*5c51f124SMoriah Waterland 992*5c51f124SMoriah Waterland /* error if the mount point already exists */ 993*5c51f124SMoriah Waterland 994*5c51f124SMoriah Waterland if (_z_is_directory(gzMountPoint) == 0) { 995*5c51f124SMoriah Waterland _z_program_error(ERR_ZONEROOT_NOTDIR, gzMountPoint, 996*5c51f124SMoriah Waterland a_zoneName, strerror(errno)); 997*5c51f124SMoriah Waterland return (B_FALSE); 998*5c51f124SMoriah Waterland } 999*5c51f124SMoriah Waterland 1000*5c51f124SMoriah Waterland /* create the temporary mount point */ 1001*5c51f124SMoriah Waterland 1002*5c51f124SMoriah Waterland if (mkdir(gzMountPoint, 0600) != 0) { 1003*5c51f124SMoriah Waterland _z_program_error(ERR_MNTPT_MKDIR, gzMountPoint, a_zoneName, 1004*5c51f124SMoriah Waterland strerror(errno)); 1005*5c51f124SMoriah Waterland return (B_FALSE); 1006*5c51f124SMoriah Waterland } 1007*5c51f124SMoriah Waterland 1008*5c51f124SMoriah Waterland /* mount the global zone path on the non-global zone root file system */ 1009*5c51f124SMoriah Waterland 1010*5c51f124SMoriah Waterland err = mount(a_gzPath, gzMountPoint, MS_RDONLY|MS_DATA, "lofs", 1011*5c51f124SMoriah Waterland (char *)NULL, 0, (char *)NULL, 0); 1012*5c51f124SMoriah Waterland if (err != 0) { 1013*5c51f124SMoriah Waterland _z_program_error(ERR_GZMOUNT_FAILED, a_gzPath, 1014*5c51f124SMoriah Waterland gzMountPoint, a_zoneName, strerror(errno)); 1015*5c51f124SMoriah Waterland return (B_FALSE); 1016*5c51f124SMoriah Waterland } 1017*5c51f124SMoriah Waterland 1018*5c51f124SMoriah Waterland /* success - return both mountpoints to caller */ 1019*5c51f124SMoriah Waterland 1020*5c51f124SMoriah Waterland *r_lzMountPoint = _z_strdup(gzMountPoint); 1021*5c51f124SMoriah Waterland 1022*5c51f124SMoriah Waterland *r_lzRootPath = _z_strdup(lzMountPoint); 1023*5c51f124SMoriah Waterland 1024*5c51f124SMoriah Waterland /* return success */ 1025*5c51f124SMoriah Waterland 1026*5c51f124SMoriah Waterland return (B_TRUE); 1027*5c51f124SMoriah Waterland } 1028*5c51f124SMoriah Waterland 1029*5c51f124SMoriah Waterland /* 1030*5c51f124SMoriah Waterland * Name: z_non_global_zones_exist 1031*5c51f124SMoriah Waterland * Description: Determine if any non-global native zones exist 1032*5c51f124SMoriah Waterland * Arguments: None. 1033*5c51f124SMoriah Waterland * Returns: boolean_t 1034*5c51f124SMoriah Waterland * == B_TRUE - at least one non-global native zone exists 1035*5c51f124SMoriah Waterland * == B_FALSE - no non-global native zone exists 1036*5c51f124SMoriah Waterland */ 1037*5c51f124SMoriah Waterland 1038*5c51f124SMoriah Waterland boolean_t 1039*5c51f124SMoriah Waterland z_non_global_zones_exist(void) 1040*5c51f124SMoriah Waterland { 1041*5c51f124SMoriah Waterland FILE *zoneIndexFP; 1042*5c51f124SMoriah Waterland boolean_t anyExist = B_FALSE; 1043*5c51f124SMoriah Waterland struct zoneent *ze; 1044*5c51f124SMoriah Waterland zone_spec_t *zent; 1045*5c51f124SMoriah Waterland 1046*5c51f124SMoriah Waterland /* if zones are not implemented, return FALSE */ 1047*5c51f124SMoriah Waterland 1048*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 1049*5c51f124SMoriah Waterland return (B_FALSE); 1050*5c51f124SMoriah Waterland } 1051*5c51f124SMoriah Waterland 1052*5c51f124SMoriah Waterland /* determine if any zones are configured */ 1053*5c51f124SMoriah Waterland zoneIndexFP = setzoneent(); 1054*5c51f124SMoriah Waterland if (zoneIndexFP == NULL) { 1055*5c51f124SMoriah Waterland return (B_FALSE); 1056*5c51f124SMoriah Waterland } 1057*5c51f124SMoriah Waterland 1058*5c51f124SMoriah Waterland /* index file open; scan all zones; see if any are at least installed */ 1059*5c51f124SMoriah Waterland 1060*5c51f124SMoriah Waterland while ((ze = getzoneent_private(zoneIndexFP)) != NULL) { 1061*5c51f124SMoriah Waterland /* 1062*5c51f124SMoriah Waterland * If the user specified an explicit zone list, then ignore any 1063*5c51f124SMoriah Waterland * zones that aren't on that list. 1064*5c51f124SMoriah Waterland */ 1065*5c51f124SMoriah Waterland if ((zent = _z_global_data._zone_spec) != NULL) { 1066*5c51f124SMoriah Waterland while (zent != NULL) { 1067*5c51f124SMoriah Waterland if (strcmp(zent->zl_name, ze->zone_name) == 0) 1068*5c51f124SMoriah Waterland break; 1069*5c51f124SMoriah Waterland zent = zent->zl_next; 1070*5c51f124SMoriah Waterland } 1071*5c51f124SMoriah Waterland if (zent == NULL) { 1072*5c51f124SMoriah Waterland free(ze); 1073*5c51f124SMoriah Waterland continue; 1074*5c51f124SMoriah Waterland } 1075*5c51f124SMoriah Waterland } 1076*5c51f124SMoriah Waterland 1077*5c51f124SMoriah Waterland /* skip the global zone */ 1078*5c51f124SMoriah Waterland if (strcmp(ze->zone_name, GLOBAL_ZONENAME) == 0) { 1079*5c51f124SMoriah Waterland free(ze); 1080*5c51f124SMoriah Waterland continue; 1081*5c51f124SMoriah Waterland } 1082*5c51f124SMoriah Waterland 1083*5c51f124SMoriah Waterland /* skip any branded zones */ 1084*5c51f124SMoriah Waterland if (z_is_zone_branded(ze->zone_name)) { 1085*5c51f124SMoriah Waterland free(ze); 1086*5c51f124SMoriah Waterland continue; 1087*5c51f124SMoriah Waterland } 1088*5c51f124SMoriah Waterland 1089*5c51f124SMoriah Waterland /* is this zone installed? */ 1090*5c51f124SMoriah Waterland if (ze->zone_state >= ZONE_STATE_INSTALLED) { 1091*5c51f124SMoriah Waterland free(ze); 1092*5c51f124SMoriah Waterland anyExist = B_TRUE; 1093*5c51f124SMoriah Waterland break; 1094*5c51f124SMoriah Waterland } 1095*5c51f124SMoriah Waterland free(ze); 1096*5c51f124SMoriah Waterland } 1097*5c51f124SMoriah Waterland 1098*5c51f124SMoriah Waterland /* close the index file */ 1099*5c51f124SMoriah Waterland 1100*5c51f124SMoriah Waterland endzoneent(zoneIndexFP); 1101*5c51f124SMoriah Waterland 1102*5c51f124SMoriah Waterland /* return results */ 1103*5c51f124SMoriah Waterland 1104*5c51f124SMoriah Waterland return (anyExist); 1105*5c51f124SMoriah Waterland } 1106*5c51f124SMoriah Waterland 1107*5c51f124SMoriah Waterland /* 1108*5c51f124SMoriah Waterland * Name: z_on_zone_spec 1109*5c51f124SMoriah Waterland * Description: Determine if named zone is on the zone_spec list. 1110*5c51f124SMoriah Waterland * Arguments: Pointer to name to test. 1111*5c51f124SMoriah Waterland * Returns: B_TRUE if named zone is on the list or if the user specified 1112*5c51f124SMoriah Waterland * no list at all (all zones is the default), B_FALSE otherwise. 1113*5c51f124SMoriah Waterland */ 1114*5c51f124SMoriah Waterland 1115*5c51f124SMoriah Waterland boolean_t 1116*5c51f124SMoriah Waterland z_on_zone_spec(const char *zonename) 1117*5c51f124SMoriah Waterland { 1118*5c51f124SMoriah Waterland zone_spec_t *zent; 1119*5c51f124SMoriah Waterland 1120*5c51f124SMoriah Waterland /* entry assertions */ 1121*5c51f124SMoriah Waterland 1122*5c51f124SMoriah Waterland assert(zonename != NULL); 1123*5c51f124SMoriah Waterland assert(*zonename != '\0'); 1124*5c51f124SMoriah Waterland 1125*5c51f124SMoriah Waterland /* return true if zones not implemented or no zone spec list defined */ 1126*5c51f124SMoriah Waterland 1127*5c51f124SMoriah Waterland if (!z_zones_are_implemented() || _z_global_data._zone_spec == NULL) { 1128*5c51f124SMoriah Waterland return (B_TRUE); 1129*5c51f124SMoriah Waterland } 1130*5c51f124SMoriah Waterland 1131*5c51f124SMoriah Waterland /* return true if named zone is on the zone spec list */ 1132*5c51f124SMoriah Waterland 1133*5c51f124SMoriah Waterland for (zent = _z_global_data._zone_spec; 1134*5c51f124SMoriah Waterland zent != NULL; zent = zent->zl_next) { 1135*5c51f124SMoriah Waterland if (strcmp(zent->zl_name, zonename) == 0) 1136*5c51f124SMoriah Waterland return (B_TRUE); 1137*5c51f124SMoriah Waterland } 1138*5c51f124SMoriah Waterland 1139*5c51f124SMoriah Waterland /* named zone is not on the zone spec list */ 1140*5c51f124SMoriah Waterland 1141*5c51f124SMoriah Waterland return (B_FALSE); 1142*5c51f124SMoriah Waterland } 1143*5c51f124SMoriah Waterland 1144*5c51f124SMoriah Waterland /* 1145*5c51f124SMoriah Waterland * Name: z_running_in_global_zone 1146*5c51f124SMoriah Waterland * Description: Determine if running in the "global" zone 1147*5c51f124SMoriah Waterland * Arguments: void 1148*5c51f124SMoriah Waterland * Returns: boolean_t 1149*5c51f124SMoriah Waterland * == B_TRUE - running in global zone 1150*5c51f124SMoriah Waterland * == B_FALSE - not running in global zone 1151*5c51f124SMoriah Waterland */ 1152*5c51f124SMoriah Waterland 1153*5c51f124SMoriah Waterland boolean_t 1154*5c51f124SMoriah Waterland z_running_in_global_zone(void) 1155*5c51f124SMoriah Waterland { 1156*5c51f124SMoriah Waterland static boolean_t _zoneIdDetermined = B_FALSE; 1157*5c51f124SMoriah Waterland static boolean_t _zoneIsGlobal = B_FALSE; 1158*5c51f124SMoriah Waterland 1159*5c51f124SMoriah Waterland /* if ID has not been determined, cache it now */ 1160*5c51f124SMoriah Waterland 1161*5c51f124SMoriah Waterland if (!_zoneIdDetermined) { 1162*5c51f124SMoriah Waterland _zoneIdDetermined = B_TRUE; 1163*5c51f124SMoriah Waterland _zoneIsGlobal = _z_running_in_global_zone(); 1164*5c51f124SMoriah Waterland } 1165*5c51f124SMoriah Waterland 1166*5c51f124SMoriah Waterland return (_zoneIsGlobal); 1167*5c51f124SMoriah Waterland } 1168*5c51f124SMoriah Waterland 1169*5c51f124SMoriah Waterland /* 1170*5c51f124SMoriah Waterland * Name: z_set_output_functions 1171*5c51f124SMoriah Waterland * Description: Link program specific output functions to this library. 1172*5c51f124SMoriah Waterland * Arguments: a_echo_fcn - (_z_printf_fcn_t) 1173*5c51f124SMoriah Waterland * Function to call to cause "normal operation" messages 1174*5c51f124SMoriah Waterland * to be output/displayed 1175*5c51f124SMoriah Waterland * a_echo_debug_fcn - (_z_printf_fcn_t) 1176*5c51f124SMoriah Waterland * Function to call to cause "debugging" messages 1177*5c51f124SMoriah Waterland * to be output/displayed 1178*5c51f124SMoriah Waterland * a_progerr_fcn - (_z_printf_fcn_t) 1179*5c51f124SMoriah Waterland * Function to call to cause "program error" messages 1180*5c51f124SMoriah Waterland * to be output/displayed 1181*5c51f124SMoriah Waterland * Returns: void 1182*5c51f124SMoriah Waterland * NOTE: If NULL is specified for any function, then the functionality 1183*5c51f124SMoriah Waterland * associated with that function is disabled. 1184*5c51f124SMoriah Waterland * NOTE: The function pointers provided must call a function that 1185*5c51f124SMoriah Waterland * takes two arguments: 1186*5c51f124SMoriah Waterland * function(char *format, char *message) 1187*5c51f124SMoriah Waterland * Any registered function will be called like: 1188*5c51f124SMoriah Waterland * function("%s", "message") 1189*5c51f124SMoriah Waterland */ 1190*5c51f124SMoriah Waterland 1191*5c51f124SMoriah Waterland void 1192*5c51f124SMoriah Waterland z_set_output_functions(_z_printf_fcn_t a_echo_fcn, 1193*5c51f124SMoriah Waterland _z_printf_fcn_t a_echo_debug_fcn, 1194*5c51f124SMoriah Waterland _z_printf_fcn_t a_progerr_fcn) 1195*5c51f124SMoriah Waterland { 1196*5c51f124SMoriah Waterland _z_global_data._z_echo = a_echo_fcn; 1197*5c51f124SMoriah Waterland _z_global_data._z_echo_debug = a_echo_debug_fcn; 1198*5c51f124SMoriah Waterland _z_global_data._z_progerr = a_progerr_fcn; 1199*5c51f124SMoriah Waterland } 1200*5c51f124SMoriah Waterland 1201*5c51f124SMoriah Waterland /* 1202*5c51f124SMoriah Waterland * Name: z_set_zone_root 1203*5c51f124SMoriah Waterland * Description: Set root for zones library operations 1204*5c51f124SMoriah Waterland * Arguments: Path to root of boot environment containing zone; must be 1205*5c51f124SMoriah Waterland * absolute. 1206*5c51f124SMoriah Waterland * Returns: None. 1207*5c51f124SMoriah Waterland * NOTE: Must be called before performing any zone-related operations. 1208*5c51f124SMoriah Waterland * (Currently called directly by set_inst_root() during -R 1209*5c51f124SMoriah Waterland * argument handling.) 1210*5c51f124SMoriah Waterland */ 1211*5c51f124SMoriah Waterland 1212*5c51f124SMoriah Waterland void 1213*5c51f124SMoriah Waterland z_set_zone_root(const char *zroot) 1214*5c51f124SMoriah Waterland { 1215*5c51f124SMoriah Waterland char *rootdir; 1216*5c51f124SMoriah Waterland 1217*5c51f124SMoriah Waterland /* if zones are not implemented, just return */ 1218*5c51f124SMoriah Waterland 1219*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) 1220*5c51f124SMoriah Waterland return; 1221*5c51f124SMoriah Waterland 1222*5c51f124SMoriah Waterland /* entry assertions */ 1223*5c51f124SMoriah Waterland 1224*5c51f124SMoriah Waterland assert(zroot != NULL); 1225*5c51f124SMoriah Waterland 1226*5c51f124SMoriah Waterland rootdir = _z_strdup((char *)zroot); 1227*5c51f124SMoriah Waterland z_canoninplace(rootdir); 1228*5c51f124SMoriah Waterland 1229*5c51f124SMoriah Waterland if (strcmp(rootdir, "/") == 0) { 1230*5c51f124SMoriah Waterland rootdir[0] = '\0'; 1231*5c51f124SMoriah Waterland } 1232*5c51f124SMoriah Waterland 1233*5c51f124SMoriah Waterland /* free any existing cached root path */ 1234*5c51f124SMoriah Waterland 1235*5c51f124SMoriah Waterland if (*_z_global_data._z_root_dir != '\0') { 1236*5c51f124SMoriah Waterland free(_z_global_data._z_root_dir); 1237*5c51f124SMoriah Waterland } 1238*5c51f124SMoriah Waterland 1239*5c51f124SMoriah Waterland /* store duplicate of new zone root path */ 1240*5c51f124SMoriah Waterland 1241*5c51f124SMoriah Waterland if (*rootdir != '\0') { 1242*5c51f124SMoriah Waterland _z_global_data._z_root_dir = _z_strdup(rootdir); 1243*5c51f124SMoriah Waterland } else { 1244*5c51f124SMoriah Waterland *_z_global_data._z_root_dir = '\0'; 1245*5c51f124SMoriah Waterland } 1246*5c51f124SMoriah Waterland 1247*5c51f124SMoriah Waterland /* set zone root path */ 1248*5c51f124SMoriah Waterland 1249*5c51f124SMoriah Waterland zonecfg_set_root(rootdir); 1250*5c51f124SMoriah Waterland 1251*5c51f124SMoriah Waterland free(rootdir); 1252*5c51f124SMoriah Waterland } 1253*5c51f124SMoriah Waterland 1254*5c51f124SMoriah Waterland /* 1255*5c51f124SMoriah Waterland * Name: z_set_zone_spec 1256*5c51f124SMoriah Waterland * Description: Set list of zones on which actions will be performed. 1257*5c51f124SMoriah Waterland * Arguments: Whitespace-separated list of zone names. 1258*5c51f124SMoriah Waterland * Returns: 0 on success, -1 on error. 1259*5c51f124SMoriah Waterland * NOTES: Will call _z_program_error if argument can't be parsed or 1260*5c51f124SMoriah Waterland * memory not available. 1261*5c51f124SMoriah Waterland */ 1262*5c51f124SMoriah Waterland 1263*5c51f124SMoriah Waterland int 1264*5c51f124SMoriah Waterland z_set_zone_spec(const char *zlist) 1265*5c51f124SMoriah Waterland { 1266*5c51f124SMoriah Waterland const char *zend; 1267*5c51f124SMoriah Waterland ptrdiff_t zlen; 1268*5c51f124SMoriah Waterland zone_spec_t *zent; 1269*5c51f124SMoriah Waterland zone_spec_t *zhead; 1270*5c51f124SMoriah Waterland zone_spec_t **znextp = &zhead; 1271*5c51f124SMoriah Waterland 1272*5c51f124SMoriah Waterland /* entry assertions */ 1273*5c51f124SMoriah Waterland 1274*5c51f124SMoriah Waterland assert(zlist != NULL); 1275*5c51f124SMoriah Waterland 1276*5c51f124SMoriah Waterland /* parse list to zone_spec_t list, store in global data */ 1277*5c51f124SMoriah Waterland 1278*5c51f124SMoriah Waterland for (;;) { 1279*5c51f124SMoriah Waterland while (isspace(*zlist)) { 1280*5c51f124SMoriah Waterland zlist++; 1281*5c51f124SMoriah Waterland } 1282*5c51f124SMoriah Waterland if (*zlist == '\0') { 1283*5c51f124SMoriah Waterland break; 1284*5c51f124SMoriah Waterland } 1285*5c51f124SMoriah Waterland for (zend = zlist; *zend != '\0'; zend++) { 1286*5c51f124SMoriah Waterland if (isspace(*zend)) { 1287*5c51f124SMoriah Waterland break; 1288*5c51f124SMoriah Waterland } 1289*5c51f124SMoriah Waterland } 1290*5c51f124SMoriah Waterland zlen = ((ptrdiff_t)zend) - ((ptrdiff_t)zlist); 1291*5c51f124SMoriah Waterland if (zlen >= ZONENAME_MAX) { 1292*5c51f124SMoriah Waterland _z_program_error(ERR_ZONE_NAME_ILLEGAL, zlen, zlist); 1293*5c51f124SMoriah Waterland return (-1); 1294*5c51f124SMoriah Waterland } 1295*5c51f124SMoriah Waterland zent = _z_malloc(sizeof (*zent)); 1296*5c51f124SMoriah Waterland (void) memcpy(zent->zl_name, zlist, zlen); 1297*5c51f124SMoriah Waterland zent->zl_name[zlen] = '\0'; 1298*5c51f124SMoriah Waterland zent->zl_used = B_FALSE; 1299*5c51f124SMoriah Waterland *znextp = zent; 1300*5c51f124SMoriah Waterland znextp = &zent->zl_next; 1301*5c51f124SMoriah Waterland zlist = zend; 1302*5c51f124SMoriah Waterland } 1303*5c51f124SMoriah Waterland *znextp = NULL; 1304*5c51f124SMoriah Waterland 1305*5c51f124SMoriah Waterland if (zhead == NULL) { 1306*5c51f124SMoriah Waterland _z_program_error(ERR_ZONE_LIST_EMPTY); 1307*5c51f124SMoriah Waterland return (-1); 1308*5c51f124SMoriah Waterland } 1309*5c51f124SMoriah Waterland 1310*5c51f124SMoriah Waterland _z_global_data._zone_spec = zhead; 1311*5c51f124SMoriah Waterland return (0); 1312*5c51f124SMoriah Waterland } 1313*5c51f124SMoriah Waterland 1314*5c51f124SMoriah Waterland /* 1315*5c51f124SMoriah Waterland * Name: z_umount_lz_mount 1316*5c51f124SMoriah Waterland * Description: Unmount directory mounted with z_mount_in_lz 1317*5c51f124SMoriah Waterland * Arguments: a_lzMountPointer - pointer to string returned by z_mount_in_lz 1318*5c51f124SMoriah Waterland * Returns: boolean_t 1319*5c51f124SMoriah Waterland * == B_TRUE - successfully unmounted directory 1320*5c51f124SMoriah Waterland * == B_FALSE - failed to unmount directory 1321*5c51f124SMoriah Waterland */ 1322*5c51f124SMoriah Waterland 1323*5c51f124SMoriah Waterland boolean_t 1324*5c51f124SMoriah Waterland z_umount_lz_mount(char *a_lzMountPoint) 1325*5c51f124SMoriah Waterland { 1326*5c51f124SMoriah Waterland int err; 1327*5c51f124SMoriah Waterland 1328*5c51f124SMoriah Waterland /* entry assertions */ 1329*5c51f124SMoriah Waterland 1330*5c51f124SMoriah Waterland assert(a_lzMountPoint != (char *)NULL); 1331*5c51f124SMoriah Waterland assert(*a_lzMountPoint != '\0'); 1332*5c51f124SMoriah Waterland 1333*5c51f124SMoriah Waterland /* entry debugging info */ 1334*5c51f124SMoriah Waterland 1335*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_UNMOUNT_FROM_LZ_ENTRY, a_lzMountPoint); 1336*5c51f124SMoriah Waterland 1337*5c51f124SMoriah Waterland /* if zones are not implemented, return TRUE */ 1338*5c51f124SMoriah Waterland 1339*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 1340*5c51f124SMoriah Waterland return (B_FALSE); 1341*5c51f124SMoriah Waterland } 1342*5c51f124SMoriah Waterland 1343*5c51f124SMoriah Waterland /* error if global zone path is not absolute */ 1344*5c51f124SMoriah Waterland 1345*5c51f124SMoriah Waterland if (*a_lzMountPoint != '/') { 1346*5c51f124SMoriah Waterland _z_program_error(ERR_LZMNTPT_NOT_ABSOLUTE, a_lzMountPoint); 1347*5c51f124SMoriah Waterland return (B_FALSE); 1348*5c51f124SMoriah Waterland } 1349*5c51f124SMoriah Waterland 1350*5c51f124SMoriah Waterland /* verify mount point exists */ 1351*5c51f124SMoriah Waterland 1352*5c51f124SMoriah Waterland if (_z_is_directory(a_lzMountPoint) != 0) { 1353*5c51f124SMoriah Waterland _z_program_error(ERR_LZMNTPT_NOTDIR, a_lzMountPoint, 1354*5c51f124SMoriah Waterland strerror(errno)); 1355*5c51f124SMoriah Waterland return (B_FALSE); 1356*5c51f124SMoriah Waterland } 1357*5c51f124SMoriah Waterland 1358*5c51f124SMoriah Waterland /* unmount */ 1359*5c51f124SMoriah Waterland 1360*5c51f124SMoriah Waterland err = umount2(a_lzMountPoint, 0); 1361*5c51f124SMoriah Waterland if (err != 0) { 1362*5c51f124SMoriah Waterland _z_program_error(ERR_GZUMOUNT_FAILED, a_lzMountPoint, 1363*5c51f124SMoriah Waterland strerror(errno)); 1364*5c51f124SMoriah Waterland return (B_FALSE); 1365*5c51f124SMoriah Waterland } 1366*5c51f124SMoriah Waterland 1367*5c51f124SMoriah Waterland /* remove the mount point */ 1368*5c51f124SMoriah Waterland 1369*5c51f124SMoriah Waterland (void) remove(a_lzMountPoint); 1370*5c51f124SMoriah Waterland 1371*5c51f124SMoriah Waterland /* return success */ 1372*5c51f124SMoriah Waterland 1373*5c51f124SMoriah Waterland return (B_TRUE); 1374*5c51f124SMoriah Waterland } 1375*5c51f124SMoriah Waterland 1376*5c51f124SMoriah Waterland /* 1377*5c51f124SMoriah Waterland * Name: z_unlock_this_zone 1378*5c51f124SMoriah Waterland * Description: unlock this zone 1379*5c51f124SMoriah Waterland * Arguments: a_lflags - [RO, *RO] - (ZLOCKS_T) 1380*5c51f124SMoriah Waterland * Flags indicating which locks to release 1381*5c51f124SMoriah Waterland * Returns: boolean_t 1382*5c51f124SMoriah Waterland * == B_TRUE - success specified locks released 1383*5c51f124SMoriah Waterland * == B_FALSE - failure specified locks may not be released 1384*5c51f124SMoriah Waterland * NOTE: the lock objects for "this zone" are maintained internally. 1385*5c51f124SMoriah Waterland */ 1386*5c51f124SMoriah Waterland 1387*5c51f124SMoriah Waterland boolean_t 1388*5c51f124SMoriah Waterland z_unlock_this_zone(ZLOCKS_T a_lflags) 1389*5c51f124SMoriah Waterland { 1390*5c51f124SMoriah Waterland boolean_t b; 1391*5c51f124SMoriah Waterland boolean_t errors = B_FALSE; 1392*5c51f124SMoriah Waterland char *zoneName; 1393*5c51f124SMoriah Waterland 1394*5c51f124SMoriah Waterland /* entry assertions */ 1395*5c51f124SMoriah Waterland 1396*5c51f124SMoriah Waterland assert(a_lflags != ZLOCKS_NONE); 1397*5c51f124SMoriah Waterland 1398*5c51f124SMoriah Waterland /* entry debugging info */ 1399*5c51f124SMoriah Waterland 1400*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_THIS, a_lflags); 1401*5c51f124SMoriah Waterland 1402*5c51f124SMoriah Waterland /* return if no objects locked */ 1403*5c51f124SMoriah Waterland 1404*5c51f124SMoriah Waterland if ((_z_global_data._z_ObjectLocks == (char *)NULL) || 1405*5c51f124SMoriah Waterland (*_z_global_data._z_ObjectLocks == '\0')) { 1406*5c51f124SMoriah Waterland return (B_TRUE); 1407*5c51f124SMoriah Waterland } 1408*5c51f124SMoriah Waterland 1409*5c51f124SMoriah Waterland zoneName = z_get_zonename(); 1410*5c51f124SMoriah Waterland 1411*5c51f124SMoriah Waterland /* unlock patch administration */ 1412*5c51f124SMoriah Waterland 1413*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PATCH_ADMIN) { 1414*5c51f124SMoriah Waterland b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks, 1415*5c51f124SMoriah Waterland zoneName, LOBJ_PATCHADMIN, ERR_ZONES_ULK_THIS_PATCH); 1416*5c51f124SMoriah Waterland if (!b) { 1417*5c51f124SMoriah Waterland errors = B_TRUE; 1418*5c51f124SMoriah Waterland } 1419*5c51f124SMoriah Waterland } 1420*5c51f124SMoriah Waterland 1421*5c51f124SMoriah Waterland /* unlock package administration */ 1422*5c51f124SMoriah Waterland 1423*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_PKG_ADMIN) { 1424*5c51f124SMoriah Waterland b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks, 1425*5c51f124SMoriah Waterland zoneName, LOBJ_PKGADMIN, ERR_ZONES_ULK_THIS_PACKAGE); 1426*5c51f124SMoriah Waterland if (!b) { 1427*5c51f124SMoriah Waterland errors = B_TRUE; 1428*5c51f124SMoriah Waterland } 1429*5c51f124SMoriah Waterland } 1430*5c51f124SMoriah Waterland 1431*5c51f124SMoriah Waterland /* unlock zone administration */ 1432*5c51f124SMoriah Waterland 1433*5c51f124SMoriah Waterland if (a_lflags & ZLOCKS_ZONE_ADMIN) { 1434*5c51f124SMoriah Waterland b = _z_unlock_zone_object(&_z_global_data._z_ObjectLocks, 1435*5c51f124SMoriah Waterland zoneName, LOBJ_ZONEADMIN, ERR_ZONES_ULK_THIS_ZONES); 1436*5c51f124SMoriah Waterland if (!b) { 1437*5c51f124SMoriah Waterland errors = B_TRUE; 1438*5c51f124SMoriah Waterland } 1439*5c51f124SMoriah Waterland } 1440*5c51f124SMoriah Waterland 1441*5c51f124SMoriah Waterland (void) free(zoneName); 1442*5c51f124SMoriah Waterland return (!errors); 1443*5c51f124SMoriah Waterland } 1444*5c51f124SMoriah Waterland 1445*5c51f124SMoriah Waterland /* 1446*5c51f124SMoriah Waterland * Name: z_unlock_zones 1447*5c51f124SMoriah Waterland * Description: unlock specified zones 1448*5c51f124SMoriah Waterland * Arguments: a_zlst - zoneList_t object describing zones to unlock 1449*5c51f124SMoriah Waterland * a_lflags - [RO, *RO] - (ZLOCKS_T) 1450*5c51f124SMoriah Waterland * Flags indicating which locks to release 1451*5c51f124SMoriah Waterland * Returns: boolean_t 1452*5c51f124SMoriah Waterland * == B_TRUE - success, zones unlocked 1453*5c51f124SMoriah Waterland * == B_FALSE - failure, zones not unlocked 1454*5c51f124SMoriah Waterland */ 1455*5c51f124SMoriah Waterland 1456*5c51f124SMoriah Waterland boolean_t 1457*5c51f124SMoriah Waterland z_unlock_zones(zoneList_t a_zlst, ZLOCKS_T a_lflags) 1458*5c51f124SMoriah Waterland { 1459*5c51f124SMoriah Waterland boolean_t b; 1460*5c51f124SMoriah Waterland boolean_t errors = B_FALSE; 1461*5c51f124SMoriah Waterland int i; 1462*5c51f124SMoriah Waterland 1463*5c51f124SMoriah Waterland /* entry assertions */ 1464*5c51f124SMoriah Waterland 1465*5c51f124SMoriah Waterland assert(a_lflags != ZLOCKS_NONE); 1466*5c51f124SMoriah Waterland 1467*5c51f124SMoriah Waterland /* entry debugging info */ 1468*5c51f124SMoriah Waterland 1469*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONES, a_lflags); 1470*5c51f124SMoriah Waterland 1471*5c51f124SMoriah Waterland /* if zones are not implemented, return TRUE */ 1472*5c51f124SMoriah Waterland 1473*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 1474*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONES_UNIMP); 1475*5c51f124SMoriah Waterland return (B_TRUE); 1476*5c51f124SMoriah Waterland } 1477*5c51f124SMoriah Waterland 1478*5c51f124SMoriah Waterland /* ignore empty list */ 1479*5c51f124SMoriah Waterland 1480*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1481*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONES_NOZONES); 1482*5c51f124SMoriah Waterland /* unlock this zone before returning */ 1483*5c51f124SMoriah Waterland return (z_unlock_this_zone(a_lflags)); 1484*5c51f124SMoriah Waterland } 1485*5c51f124SMoriah Waterland 1486*5c51f124SMoriah Waterland /* zones exist */ 1487*5c51f124SMoriah Waterland 1488*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ULK_ZONES_EXIST); 1489*5c51f124SMoriah Waterland 1490*5c51f124SMoriah Waterland /* 1491*5c51f124SMoriah Waterland * unlock each listed zone that is currently running 1492*5c51f124SMoriah Waterland */ 1493*5c51f124SMoriah Waterland 1494*5c51f124SMoriah Waterland for (i = 0; (a_zlst[i]._zlName != (char *)NULL); i++) { 1495*5c51f124SMoriah Waterland /* ignore zone if not locked */ 1496*5c51f124SMoriah Waterland if (!(a_zlst[i]._zlStatus & ZST_LOCKED)) { 1497*5c51f124SMoriah Waterland continue; 1498*5c51f124SMoriah Waterland } 1499*5c51f124SMoriah Waterland 1500*5c51f124SMoriah Waterland /* ignore zone if not running */ 1501*5c51f124SMoriah Waterland if (a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_RUNNING && 1502*5c51f124SMoriah Waterland a_zlst[i]._zlCurrKernelStatus != ZONE_STATE_MOUNTED) { 1503*5c51f124SMoriah Waterland continue; 1504*5c51f124SMoriah Waterland } 1505*5c51f124SMoriah Waterland 1506*5c51f124SMoriah Waterland /* unlock this zone */ 1507*5c51f124SMoriah Waterland b = _z_unlock_zone(&a_zlst[i], a_lflags); 1508*5c51f124SMoriah Waterland 1509*5c51f124SMoriah Waterland if (b != B_TRUE) { 1510*5c51f124SMoriah Waterland errors = B_TRUE; 1511*5c51f124SMoriah Waterland } else { 1512*5c51f124SMoriah Waterland /* mark zone as unlocked */ 1513*5c51f124SMoriah Waterland a_zlst[i]._zlStatus &= ~ZST_LOCKED; 1514*5c51f124SMoriah Waterland } 1515*5c51f124SMoriah Waterland } 1516*5c51f124SMoriah Waterland 1517*5c51f124SMoriah Waterland /* unlock this zone */ 1518*5c51f124SMoriah Waterland 1519*5c51f124SMoriah Waterland if (z_unlock_this_zone(a_lflags) != B_TRUE) { 1520*5c51f124SMoriah Waterland errors = B_TRUE; 1521*5c51f124SMoriah Waterland } 1522*5c51f124SMoriah Waterland 1523*5c51f124SMoriah Waterland return (errors); 1524*5c51f124SMoriah Waterland } 1525*5c51f124SMoriah Waterland 1526*5c51f124SMoriah Waterland /* 1527*5c51f124SMoriah Waterland * Name: z_verify_zone_spec 1528*5c51f124SMoriah Waterland * Description: Verify list of zones on which actions will be performed. 1529*5c51f124SMoriah Waterland * Arguments: None. 1530*5c51f124SMoriah Waterland * Returns: 0 on success, -1 on error. 1531*5c51f124SMoriah Waterland * NOTES: Will call _z_program_error if there are zones on the specified 1532*5c51f124SMoriah Waterland * list that don't exist on the system. Requires that 1533*5c51f124SMoriah Waterland * z_set_zone_root is called first (if it is called at all). 1534*5c51f124SMoriah Waterland */ 1535*5c51f124SMoriah Waterland 1536*5c51f124SMoriah Waterland int 1537*5c51f124SMoriah Waterland z_verify_zone_spec(void) 1538*5c51f124SMoriah Waterland { 1539*5c51f124SMoriah Waterland FILE *zoneIndexFP; 1540*5c51f124SMoriah Waterland boolean_t errors; 1541*5c51f124SMoriah Waterland char zoneIndexPath[MAXPATHLEN]; 1542*5c51f124SMoriah Waterland struct zoneent *ze; 1543*5c51f124SMoriah Waterland zone_spec_t *zent; 1544*5c51f124SMoriah Waterland 1545*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 1546*5c51f124SMoriah Waterland _z_program_error(ERR_ZONES_NOT_IMPLEMENTED); 1547*5c51f124SMoriah Waterland return (-1); 1548*5c51f124SMoriah Waterland } 1549*5c51f124SMoriah Waterland 1550*5c51f124SMoriah Waterland zoneIndexFP = setzoneent(); 1551*5c51f124SMoriah Waterland if (zoneIndexFP == NULL) { 1552*5c51f124SMoriah Waterland _z_program_error(ERR_ZONEINDEX_OPEN, zoneIndexPath, 1553*5c51f124SMoriah Waterland strerror(errno)); 1554*5c51f124SMoriah Waterland return (-1); 1555*5c51f124SMoriah Waterland } 1556*5c51f124SMoriah Waterland 1557*5c51f124SMoriah Waterland while ((ze = getzoneent_private(zoneIndexFP)) != NULL) { 1558*5c51f124SMoriah Waterland for (zent = _z_global_data._zone_spec; 1559*5c51f124SMoriah Waterland zent != NULL; zent = zent->zl_next) { 1560*5c51f124SMoriah Waterland if (strcmp(zent->zl_name, ze->zone_name) == 0) { 1561*5c51f124SMoriah Waterland zent->zl_used = B_TRUE; 1562*5c51f124SMoriah Waterland break; 1563*5c51f124SMoriah Waterland } 1564*5c51f124SMoriah Waterland } 1565*5c51f124SMoriah Waterland free(ze); 1566*5c51f124SMoriah Waterland } 1567*5c51f124SMoriah Waterland endzoneent(zoneIndexFP); 1568*5c51f124SMoriah Waterland 1569*5c51f124SMoriah Waterland errors = B_FALSE; 1570*5c51f124SMoriah Waterland for (zent = _z_global_data._zone_spec; 1571*5c51f124SMoriah Waterland zent != NULL; zent = zent->zl_next) { 1572*5c51f124SMoriah Waterland if (!zent->zl_used) { 1573*5c51f124SMoriah Waterland _z_program_error(ERR_ZONE_NONEXISTENT, zent->zl_name); 1574*5c51f124SMoriah Waterland errors = B_TRUE; 1575*5c51f124SMoriah Waterland } 1576*5c51f124SMoriah Waterland } 1577*5c51f124SMoriah Waterland return (errors ? -1 : 0); 1578*5c51f124SMoriah Waterland } 1579*5c51f124SMoriah Waterland 1580*5c51f124SMoriah Waterland /* 1581*5c51f124SMoriah Waterland * Name: z_zlist_change_zone_state 1582*5c51f124SMoriah Waterland * Description: Change the current state of the specified zone 1583*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1584*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return the 1585*5c51f124SMoriah Waterland * a_newState - the state to put the specified zone in 1586*5c51f124SMoriah Waterland * Returns: boolean_t 1587*5c51f124SMoriah Waterland * == B_TRUE - the zone is in the new state 1588*5c51f124SMoriah Waterland * == B_FALSE - unable to transition the zone to the 1589*5c51f124SMoriah Waterland * specified state 1590*5c51f124SMoriah Waterland * NOTE: This changes the "current kernel" state of the specified 1591*5c51f124SMoriah Waterland * zone. For example, to boot the zone, change the state 1592*5c51f124SMoriah Waterland * to "ZONE_STATE_RUNNING". To halt the zone, change the 1593*5c51f124SMoriah Waterland * state to "ZONE_STATE_INSTALLED". 1594*5c51f124SMoriah Waterland */ 1595*5c51f124SMoriah Waterland 1596*5c51f124SMoriah Waterland boolean_t 1597*5c51f124SMoriah Waterland z_zlist_change_zone_state(zoneList_t a_zlst, int a_zoneIndex, 1598*5c51f124SMoriah Waterland zone_state_t a_newState) 1599*5c51f124SMoriah Waterland { 1600*5c51f124SMoriah Waterland int i; 1601*5c51f124SMoriah Waterland 1602*5c51f124SMoriah Waterland /* entry debugging info */ 1603*5c51f124SMoriah Waterland 1604*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_CHG_Z_STATE_ENTRY, a_zoneIndex, a_newState); 1605*5c51f124SMoriah Waterland 1606*5c51f124SMoriah Waterland /* ignore empty list */ 1607*5c51f124SMoriah Waterland 1608*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1609*5c51f124SMoriah Waterland return (B_FALSE); 1610*5c51f124SMoriah Waterland } 1611*5c51f124SMoriah Waterland 1612*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1613*5c51f124SMoriah Waterland 1614*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1615*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1616*5c51f124SMoriah Waterland ; 1617*5c51f124SMoriah Waterland 1618*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1619*5c51f124SMoriah Waterland 1620*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1621*5c51f124SMoriah Waterland return (B_FALSE); 1622*5c51f124SMoriah Waterland } 1623*5c51f124SMoriah Waterland 1624*5c51f124SMoriah Waterland /* return success if the zone is already in this state */ 1625*5c51f124SMoriah Waterland 1626*5c51f124SMoriah Waterland if (a_zlst[i]._zlCurrKernelStatus == a_newState) { 1627*5c51f124SMoriah Waterland return (B_TRUE); 1628*5c51f124SMoriah Waterland } 1629*5c51f124SMoriah Waterland 1630*5c51f124SMoriah Waterland /* take action on new state to set zone to */ 1631*5c51f124SMoriah Waterland 1632*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_CHG_Z_STATE, a_zlst[i]._zlName, 1633*5c51f124SMoriah Waterland a_zlst[i]._zlCurrKernelStatus, a_newState); 1634*5c51f124SMoriah Waterland 1635*5c51f124SMoriah Waterland switch (a_newState) { 1636*5c51f124SMoriah Waterland case ZONE_STATE_RUNNING: 1637*5c51f124SMoriah Waterland case ZONE_STATE_MOUNTED: 1638*5c51f124SMoriah Waterland /* these states mean "boot the zone" */ 1639*5c51f124SMoriah Waterland return (_z_make_zone_running(&a_zlst[i])); 1640*5c51f124SMoriah Waterland 1641*5c51f124SMoriah Waterland case ZONE_STATE_DOWN: 1642*5c51f124SMoriah Waterland case ZONE_STATE_INSTALLED: 1643*5c51f124SMoriah Waterland /* these states mean "halt the zone" */ 1644*5c51f124SMoriah Waterland return (_z_make_zone_down(&a_zlst[i])); 1645*5c51f124SMoriah Waterland 1646*5c51f124SMoriah Waterland case ZONE_STATE_READY: 1647*5c51f124SMoriah Waterland return (_z_make_zone_ready(&a_zlst[i])); 1648*5c51f124SMoriah Waterland 1649*5c51f124SMoriah Waterland case ZONE_STATE_CONFIGURED: 1650*5c51f124SMoriah Waterland case ZONE_STATE_INCOMPLETE: 1651*5c51f124SMoriah Waterland case ZONE_STATE_SHUTTING_DOWN: 1652*5c51f124SMoriah Waterland default: 1653*5c51f124SMoriah Waterland /* do not know how to change zone to this state */ 1654*5c51f124SMoriah Waterland return (B_FALSE); 1655*5c51f124SMoriah Waterland } 1656*5c51f124SMoriah Waterland } 1657*5c51f124SMoriah Waterland 1658*5c51f124SMoriah Waterland /* 1659*5c51f124SMoriah Waterland * Name: z_is_zone_branded 1660*5c51f124SMoriah Waterland * Description: Determine whether zone has a non-native brand 1661*5c51f124SMoriah Waterland * Arguments: a_zoneName - name of the zone to check for branding 1662*5c51f124SMoriah Waterland * Returns: boolean_t 1663*5c51f124SMoriah Waterland * == B_TRUE - zone has a non-native brand 1664*5c51f124SMoriah Waterland * == B_FALSE - zone is native 1665*5c51f124SMoriah Waterland */ 1666*5c51f124SMoriah Waterland boolean_t 1667*5c51f124SMoriah Waterland z_is_zone_branded(char *zoneName) 1668*5c51f124SMoriah Waterland { 1669*5c51f124SMoriah Waterland char brandname[MAXNAMELEN]; 1670*5c51f124SMoriah Waterland int err; 1671*5c51f124SMoriah Waterland 1672*5c51f124SMoriah Waterland /* if zones are not implemented, return FALSE */ 1673*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 1674*5c51f124SMoriah Waterland return (B_FALSE); 1675*5c51f124SMoriah Waterland } 1676*5c51f124SMoriah Waterland 1677*5c51f124SMoriah Waterland /* if brands are not implemented, return FALSE */ 1678*5c51f124SMoriah Waterland if (!z_brands_are_implemented()) { 1679*5c51f124SMoriah Waterland return (B_FALSE); 1680*5c51f124SMoriah Waterland } 1681*5c51f124SMoriah Waterland 1682*5c51f124SMoriah Waterland err = zone_get_brand(zoneName, brandname, sizeof (brandname)); 1683*5c51f124SMoriah Waterland if (err != Z_OK) { 1684*5c51f124SMoriah Waterland _z_program_error(ERR_BRAND_GETBRAND, zonecfg_strerror(err)); 1685*5c51f124SMoriah Waterland return (B_FALSE); 1686*5c51f124SMoriah Waterland } 1687*5c51f124SMoriah Waterland 1688*5c51f124SMoriah Waterland /* 1689*5c51f124SMoriah Waterland * Both "native" and "cluster" are native brands 1690*5c51f124SMoriah Waterland * that use the standard facilities in the areas 1691*5c51f124SMoriah Waterland * of packaging/installation/patching/update. 1692*5c51f124SMoriah Waterland */ 1693*5c51f124SMoriah Waterland if (streq(brandname, NATIVE_BRAND_NAME) || 1694*5c51f124SMoriah Waterland streq(brandname, CLUSTER_BRAND_NAME)) { 1695*5c51f124SMoriah Waterland return (B_FALSE); 1696*5c51f124SMoriah Waterland } else { 1697*5c51f124SMoriah Waterland return (B_TRUE); 1698*5c51f124SMoriah Waterland } 1699*5c51f124SMoriah Waterland } 1700*5c51f124SMoriah Waterland 1701*5c51f124SMoriah Waterland /* 1702*5c51f124SMoriah Waterland * Name: z_is_zone_brand_in_list 1703*5c51f124SMoriah Waterland * Description: Determine whether zone's brand has a match in the list 1704*5c51f124SMoriah Waterland * brands passed in. 1705*5c51f124SMoriah Waterland * Arguments: zoneName - name of the zone to check for branding 1706*5c51f124SMoriah Waterland * list - list of brands to check the zone against 1707*5c51f124SMoriah Waterland * Returns: boolean_t 1708*5c51f124SMoriah Waterland * == B_TRUE - zone has a matching brand 1709*5c51f124SMoriah Waterland * == B_FALSE - zone brand is not in list 1710*5c51f124SMoriah Waterland */ 1711*5c51f124SMoriah Waterland boolean_t 1712*5c51f124SMoriah Waterland z_is_zone_brand_in_list(char *zoneName, zoneBrandList_t *list) 1713*5c51f124SMoriah Waterland { 1714*5c51f124SMoriah Waterland char brandname[MAXNAMELEN]; 1715*5c51f124SMoriah Waterland int err; 1716*5c51f124SMoriah Waterland zoneBrandList_t *sp; 1717*5c51f124SMoriah Waterland 1718*5c51f124SMoriah Waterland if (zoneName == NULL || list == NULL) 1719*5c51f124SMoriah Waterland return (B_FALSE); 1720*5c51f124SMoriah Waterland 1721*5c51f124SMoriah Waterland /* if zones are not implemented, return FALSE */ 1722*5c51f124SMoriah Waterland if (!z_zones_are_implemented()) { 1723*5c51f124SMoriah Waterland return (B_FALSE); 1724*5c51f124SMoriah Waterland } 1725*5c51f124SMoriah Waterland 1726*5c51f124SMoriah Waterland /* if brands are not implemented, return FALSE */ 1727*5c51f124SMoriah Waterland if (!z_brands_are_implemented()) { 1728*5c51f124SMoriah Waterland return (B_FALSE); 1729*5c51f124SMoriah Waterland } 1730*5c51f124SMoriah Waterland 1731*5c51f124SMoriah Waterland err = zone_get_brand(zoneName, brandname, sizeof (brandname)); 1732*5c51f124SMoriah Waterland if (err != Z_OK) { 1733*5c51f124SMoriah Waterland _z_program_error(ERR_BRAND_GETBRAND, zonecfg_strerror(err)); 1734*5c51f124SMoriah Waterland return (B_FALSE); 1735*5c51f124SMoriah Waterland } 1736*5c51f124SMoriah Waterland 1737*5c51f124SMoriah Waterland for (sp = list; sp != NULL; sp = sp->next) { 1738*5c51f124SMoriah Waterland if (sp->string_ptr != NULL && 1739*5c51f124SMoriah Waterland strcmp(sp->string_ptr, brandname) == 0) { 1740*5c51f124SMoriah Waterland return (B_TRUE); 1741*5c51f124SMoriah Waterland } 1742*5c51f124SMoriah Waterland } 1743*5c51f124SMoriah Waterland 1744*5c51f124SMoriah Waterland return (B_FALSE); 1745*5c51f124SMoriah Waterland } 1746*5c51f124SMoriah Waterland 1747*5c51f124SMoriah Waterland /* 1748*5c51f124SMoriah Waterland * Name: z_zlist_get_current_state 1749*5c51f124SMoriah Waterland * Description: Determine the current kernel state of the specified zone 1750*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1751*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return 1752*5c51f124SMoriah Waterland * Returns: zone_state_t 1753*5c51f124SMoriah Waterland * The current state of the specified zone is returned 1754*5c51f124SMoriah Waterland */ 1755*5c51f124SMoriah Waterland 1756*5c51f124SMoriah Waterland zone_state_t 1757*5c51f124SMoriah Waterland z_zlist_get_current_state(zoneList_t a_zlst, int a_zoneIndex) 1758*5c51f124SMoriah Waterland { 1759*5c51f124SMoriah Waterland int i; 1760*5c51f124SMoriah Waterland 1761*5c51f124SMoriah Waterland /* ignore empty list */ 1762*5c51f124SMoriah Waterland 1763*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1764*5c51f124SMoriah Waterland return (ZONE_STATE_INCOMPLETE); 1765*5c51f124SMoriah Waterland } 1766*5c51f124SMoriah Waterland 1767*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1768*5c51f124SMoriah Waterland 1769*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1770*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1771*5c51f124SMoriah Waterland ; 1772*5c51f124SMoriah Waterland 1773*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1774*5c51f124SMoriah Waterland 1775*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1776*5c51f124SMoriah Waterland return (ZONE_STATE_INCOMPLETE); 1777*5c51f124SMoriah Waterland } 1778*5c51f124SMoriah Waterland 1779*5c51f124SMoriah Waterland /* return selected zone's current kernel state */ 1780*5c51f124SMoriah Waterland 1781*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_GET_ZONE_STATE, 1782*5c51f124SMoriah Waterland a_zlst[i]._zlName ? a_zlst[i]._zlName : "", 1783*5c51f124SMoriah Waterland a_zlst[i]._zlCurrKernelStatus); 1784*5c51f124SMoriah Waterland 1785*5c51f124SMoriah Waterland return (a_zlst[i]._zlCurrKernelStatus); 1786*5c51f124SMoriah Waterland } 1787*5c51f124SMoriah Waterland 1788*5c51f124SMoriah Waterland /* 1789*5c51f124SMoriah Waterland * Name: z_zlist_get_inherited_pkg_dirs 1790*5c51f124SMoriah Waterland * Description: Determine directories inherited by specified zone 1791*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1792*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return the 1793*5c51f124SMoriah Waterland * inherited directories list 1794*5c51f124SMoriah Waterland * Returns: char ** 1795*5c51f124SMoriah Waterland * == NULL - zone does not inherit any directories 1796*5c51f124SMoriah Waterland * - zone index is invalid 1797*5c51f124SMoriah Waterland * != NULL - array of inherited directories 1798*5c51f124SMoriah Waterland * NOTE: Any directory list returned is located in static storage that 1799*5c51f124SMoriah Waterland * must NEVER be free()ed by the caller. 1800*5c51f124SMoriah Waterland */ 1801*5c51f124SMoriah Waterland 1802*5c51f124SMoriah Waterland extern char ** 1803*5c51f124SMoriah Waterland z_zlist_get_inherited_pkg_dirs(zoneList_t a_zlst, int a_zoneIndex) 1804*5c51f124SMoriah Waterland { 1805*5c51f124SMoriah Waterland int i; 1806*5c51f124SMoriah Waterland 1807*5c51f124SMoriah Waterland /* if zones are not implemented, return empty list */ 1808*5c51f124SMoriah Waterland 1809*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 1810*5c51f124SMoriah Waterland return (NULL); 1811*5c51f124SMoriah Waterland } 1812*5c51f124SMoriah Waterland 1813*5c51f124SMoriah Waterland /* ignore empty list */ 1814*5c51f124SMoriah Waterland 1815*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1816*5c51f124SMoriah Waterland return (NULL); 1817*5c51f124SMoriah Waterland } 1818*5c51f124SMoriah Waterland 1819*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1820*5c51f124SMoriah Waterland 1821*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1822*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1823*5c51f124SMoriah Waterland ; 1824*5c51f124SMoriah Waterland 1825*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1826*5c51f124SMoriah Waterland 1827*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1828*5c51f124SMoriah Waterland return (NULL); 1829*5c51f124SMoriah Waterland } 1830*5c51f124SMoriah Waterland 1831*5c51f124SMoriah Waterland /* return selected zone's inherited directories */ 1832*5c51f124SMoriah Waterland 1833*5c51f124SMoriah Waterland return (a_zlst[i]._zlInheritedDirs); 1834*5c51f124SMoriah Waterland } 1835*5c51f124SMoriah Waterland 1836*5c51f124SMoriah Waterland /* 1837*5c51f124SMoriah Waterland * Name: z_zlist_get_original_state 1838*5c51f124SMoriah Waterland * Description: Return the original kernal state of the specified zone 1839*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1840*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return the 1841*5c51f124SMoriah Waterland * Returns: zone_state_t 1842*5c51f124SMoriah Waterland * The original state of the specified zone is returned. 1843*5c51f124SMoriah Waterland * This is the state of the zone when the zoneList_t 1844*5c51f124SMoriah Waterland * object was first generated. 1845*5c51f124SMoriah Waterland */ 1846*5c51f124SMoriah Waterland 1847*5c51f124SMoriah Waterland zone_state_t 1848*5c51f124SMoriah Waterland z_zlist_get_original_state(zoneList_t a_zlst, int a_zoneIndex) 1849*5c51f124SMoriah Waterland { 1850*5c51f124SMoriah Waterland int i; 1851*5c51f124SMoriah Waterland 1852*5c51f124SMoriah Waterland /* ignore empty list */ 1853*5c51f124SMoriah Waterland 1854*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1855*5c51f124SMoriah Waterland return (ZONE_STATE_INCOMPLETE); 1856*5c51f124SMoriah Waterland } 1857*5c51f124SMoriah Waterland 1858*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1859*5c51f124SMoriah Waterland 1860*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1861*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1862*5c51f124SMoriah Waterland ; 1863*5c51f124SMoriah Waterland 1864*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1865*5c51f124SMoriah Waterland 1866*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1867*5c51f124SMoriah Waterland return (ZONE_STATE_INCOMPLETE); 1868*5c51f124SMoriah Waterland } 1869*5c51f124SMoriah Waterland 1870*5c51f124SMoriah Waterland /* return selected zone's original kernel state */ 1871*5c51f124SMoriah Waterland 1872*5c51f124SMoriah Waterland return (a_zlst[i]._zlOrigKernelStatus); 1873*5c51f124SMoriah Waterland } 1874*5c51f124SMoriah Waterland 1875*5c51f124SMoriah Waterland /* 1876*5c51f124SMoriah Waterland * Name: z_zlist_get_scratch 1877*5c51f124SMoriah Waterland * Description: Determine name of scratch zone 1878*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1879*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to use 1880*5c51f124SMoriah Waterland * Return: char * 1881*5c51f124SMoriah Waterland * == NULL - zone name could not be determined 1882*5c51f124SMoriah Waterland * != NULL - pointer to string representing scratch zone 1883*5c51f124SMoriah Waterland * NOTE: Any name returned is placed in static storage that must 1884*5c51f124SMoriah Waterland * NEVER be free()ed by the caller. 1885*5c51f124SMoriah Waterland */ 1886*5c51f124SMoriah Waterland 1887*5c51f124SMoriah Waterland char * 1888*5c51f124SMoriah Waterland z_zlist_get_scratch(zoneList_t a_zlst, int a_zoneIndex) 1889*5c51f124SMoriah Waterland { 1890*5c51f124SMoriah Waterland int i; 1891*5c51f124SMoriah Waterland 1892*5c51f124SMoriah Waterland /* ignore empty list */ 1893*5c51f124SMoriah Waterland 1894*5c51f124SMoriah Waterland if (a_zlst == NULL) 1895*5c51f124SMoriah Waterland return (NULL); 1896*5c51f124SMoriah Waterland 1897*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1898*5c51f124SMoriah Waterland 1899*5c51f124SMoriah Waterland for (i = 0; i != a_zoneIndex; i++) { 1900*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == NULL) 1901*5c51f124SMoriah Waterland return (NULL); 1902*5c51f124SMoriah Waterland } 1903*5c51f124SMoriah Waterland 1904*5c51f124SMoriah Waterland /* return selected zone's scratch name */ 1905*5c51f124SMoriah Waterland 1906*5c51f124SMoriah Waterland return (a_zlst[i]._zlScratchName == NULL ? a_zlst[i]._zlName : 1907*5c51f124SMoriah Waterland a_zlst[i]._zlScratchName); 1908*5c51f124SMoriah Waterland } 1909*5c51f124SMoriah Waterland 1910*5c51f124SMoriah Waterland /* 1911*5c51f124SMoriah Waterland * Name: z_zlist_get_zonename 1912*5c51f124SMoriah Waterland * Description: Determine name of specified zone 1913*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1914*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return the 1915*5c51f124SMoriah Waterland * Return: char * 1916*5c51f124SMoriah Waterland * == NULL - zone name could not be determined 1917*5c51f124SMoriah Waterland * != NULL - pointer to string representing zone name 1918*5c51f124SMoriah Waterland * NOTE: Any zoneList_t returned is placed in static storage that must 1919*5c51f124SMoriah Waterland * NEVER be free()ed by the caller. 1920*5c51f124SMoriah Waterland */ 1921*5c51f124SMoriah Waterland 1922*5c51f124SMoriah Waterland char * 1923*5c51f124SMoriah Waterland z_zlist_get_zonename(zoneList_t a_zlst, int a_zoneIndex) 1924*5c51f124SMoriah Waterland { 1925*5c51f124SMoriah Waterland int i; 1926*5c51f124SMoriah Waterland 1927*5c51f124SMoriah Waterland /* ignore empty list */ 1928*5c51f124SMoriah Waterland 1929*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1930*5c51f124SMoriah Waterland return ((char *)NULL); 1931*5c51f124SMoriah Waterland } 1932*5c51f124SMoriah Waterland 1933*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1934*5c51f124SMoriah Waterland 1935*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1936*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1937*5c51f124SMoriah Waterland ; 1938*5c51f124SMoriah Waterland 1939*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1940*5c51f124SMoriah Waterland 1941*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1942*5c51f124SMoriah Waterland return (NULL); 1943*5c51f124SMoriah Waterland } 1944*5c51f124SMoriah Waterland 1945*5c51f124SMoriah Waterland /* return selected zone's name */ 1946*5c51f124SMoriah Waterland 1947*5c51f124SMoriah Waterland return (a_zlst[i]._zlName); 1948*5c51f124SMoriah Waterland } 1949*5c51f124SMoriah Waterland 1950*5c51f124SMoriah Waterland /* 1951*5c51f124SMoriah Waterland * Name: z_zlist_get_zonepath 1952*5c51f124SMoriah Waterland * Description: Determine zonepath of specified zone 1953*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 1954*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return 1955*5c51f124SMoriah Waterland * Return: char * 1956*5c51f124SMoriah Waterland * == NULL - zonepath could not be determined 1957*5c51f124SMoriah Waterland * != NULL - pointer to string representing zonepath 1958*5c51f124SMoriah Waterland * NOTE: Any zoneList_t returned is placed in static storage that must 1959*5c51f124SMoriah Waterland * NEVER be free()ed by the caller. 1960*5c51f124SMoriah Waterland */ 1961*5c51f124SMoriah Waterland 1962*5c51f124SMoriah Waterland char * 1963*5c51f124SMoriah Waterland z_zlist_get_zonepath(zoneList_t a_zlst, int a_zoneIndex) 1964*5c51f124SMoriah Waterland { 1965*5c51f124SMoriah Waterland int i; 1966*5c51f124SMoriah Waterland 1967*5c51f124SMoriah Waterland /* ignore empty list */ 1968*5c51f124SMoriah Waterland 1969*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 1970*5c51f124SMoriah Waterland return ((char *)NULL); 1971*5c51f124SMoriah Waterland } 1972*5c51f124SMoriah Waterland 1973*5c51f124SMoriah Waterland /* find the specified zone in the list */ 1974*5c51f124SMoriah Waterland 1975*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 1976*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 1977*5c51f124SMoriah Waterland ; 1978*5c51f124SMoriah Waterland 1979*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 1980*5c51f124SMoriah Waterland 1981*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 1982*5c51f124SMoriah Waterland return (NULL); 1983*5c51f124SMoriah Waterland } 1984*5c51f124SMoriah Waterland 1985*5c51f124SMoriah Waterland /* return selected zone's zonepath */ 1986*5c51f124SMoriah Waterland 1987*5c51f124SMoriah Waterland return (a_zlst[i]._zlPath); 1988*5c51f124SMoriah Waterland } 1989*5c51f124SMoriah Waterland 1990*5c51f124SMoriah Waterland boolean_t 1991*5c51f124SMoriah Waterland z_zlist_is_zone_runnable(zoneList_t a_zlst, int a_zoneIndex) 1992*5c51f124SMoriah Waterland { 1993*5c51f124SMoriah Waterland int i; 1994*5c51f124SMoriah Waterland 1995*5c51f124SMoriah Waterland /* if zones are not implemented, return error */ 1996*5c51f124SMoriah Waterland 1997*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 1998*5c51f124SMoriah Waterland return (B_FALSE); 1999*5c51f124SMoriah Waterland } 2000*5c51f124SMoriah Waterland 2001*5c51f124SMoriah Waterland /* ignore empty list */ 2002*5c51f124SMoriah Waterland 2003*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 2004*5c51f124SMoriah Waterland return (B_FALSE); 2005*5c51f124SMoriah Waterland } 2006*5c51f124SMoriah Waterland 2007*5c51f124SMoriah Waterland /* find the specified zone in the list */ 2008*5c51f124SMoriah Waterland 2009*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 2010*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 2011*5c51f124SMoriah Waterland ; 2012*5c51f124SMoriah Waterland 2013*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 2014*5c51f124SMoriah Waterland 2015*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 2016*5c51f124SMoriah Waterland return (B_FALSE); 2017*5c51f124SMoriah Waterland } 2018*5c51f124SMoriah Waterland 2019*5c51f124SMoriah Waterland /* choose based on current state */ 2020*5c51f124SMoriah Waterland 2021*5c51f124SMoriah Waterland switch (a_zlst[i]._zlCurrKernelStatus) { 2022*5c51f124SMoriah Waterland case ZONE_STATE_RUNNING: 2023*5c51f124SMoriah Waterland case ZONE_STATE_MOUNTED: 2024*5c51f124SMoriah Waterland /* already running */ 2025*5c51f124SMoriah Waterland return (B_TRUE); 2026*5c51f124SMoriah Waterland 2027*5c51f124SMoriah Waterland case ZONE_STATE_INSTALLED: 2028*5c51f124SMoriah Waterland case ZONE_STATE_DOWN: 2029*5c51f124SMoriah Waterland case ZONE_STATE_READY: 2030*5c51f124SMoriah Waterland case ZONE_STATE_SHUTTING_DOWN: 2031*5c51f124SMoriah Waterland /* return false if the zone cannot be booted */ 2032*5c51f124SMoriah Waterland 2033*5c51f124SMoriah Waterland if (a_zlst[i]._zlStatus & ZST_NOT_BOOTABLE) { 2034*5c51f124SMoriah Waterland return (B_FALSE); 2035*5c51f124SMoriah Waterland } 2036*5c51f124SMoriah Waterland 2037*5c51f124SMoriah Waterland return (B_TRUE); 2038*5c51f124SMoriah Waterland 2039*5c51f124SMoriah Waterland case ZONE_STATE_CONFIGURED: 2040*5c51f124SMoriah Waterland case ZONE_STATE_INCOMPLETE: 2041*5c51f124SMoriah Waterland default: 2042*5c51f124SMoriah Waterland /* cannot transition (boot) these states */ 2043*5c51f124SMoriah Waterland return (B_FALSE); 2044*5c51f124SMoriah Waterland } 2045*5c51f124SMoriah Waterland } 2046*5c51f124SMoriah Waterland 2047*5c51f124SMoriah Waterland /* 2048*5c51f124SMoriah Waterland * Name: z_zlist_restore_zone_state 2049*5c51f124SMoriah Waterland * Description: Return the zone to the state it was originally in 2050*5c51f124SMoriah Waterland * Arguments: a_zlst - handle to zoneList_t object describing all zones 2051*5c51f124SMoriah Waterland * a_zoneIndex - index into a_zlst of the zone to return the 2052*5c51f124SMoriah Waterland * Returns: boolean_t 2053*5c51f124SMoriah Waterland * == B_TRUE - the zone's state has been restored 2054*5c51f124SMoriah Waterland * == B_FALSE - unable to transition the zone to its 2055*5c51f124SMoriah Waterland * original state 2056*5c51f124SMoriah Waterland */ 2057*5c51f124SMoriah Waterland 2058*5c51f124SMoriah Waterland boolean_t 2059*5c51f124SMoriah Waterland z_zlist_restore_zone_state(zoneList_t a_zlst, int a_zoneIndex) 2060*5c51f124SMoriah Waterland { 2061*5c51f124SMoriah Waterland int i; 2062*5c51f124SMoriah Waterland 2063*5c51f124SMoriah Waterland /* ignore empty list */ 2064*5c51f124SMoriah Waterland 2065*5c51f124SMoriah Waterland if (a_zlst == (zoneList_t)NULL) { 2066*5c51f124SMoriah Waterland return (B_FALSE); 2067*5c51f124SMoriah Waterland } 2068*5c51f124SMoriah Waterland 2069*5c51f124SMoriah Waterland /* find the specified zone in the list */ 2070*5c51f124SMoriah Waterland 2071*5c51f124SMoriah Waterland for (i = 0; (i != a_zoneIndex) && 2072*5c51f124SMoriah Waterland (a_zlst[i]._zlName != (char *)NULL); i++) 2073*5c51f124SMoriah Waterland ; 2074*5c51f124SMoriah Waterland 2075*5c51f124SMoriah Waterland /* return error if the specified zone does not exist */ 2076*5c51f124SMoriah Waterland 2077*5c51f124SMoriah Waterland if (a_zlst[i]._zlName == (char *)NULL) { 2078*5c51f124SMoriah Waterland return (B_FALSE); 2079*5c51f124SMoriah Waterland } 2080*5c51f124SMoriah Waterland 2081*5c51f124SMoriah Waterland /* transition the zone back to its original state */ 2082*5c51f124SMoriah Waterland 2083*5c51f124SMoriah Waterland return (z_zlist_change_zone_state(a_zlst, 2084*5c51f124SMoriah Waterland a_zoneIndex, a_zlst[i]._zlOrigKernelStatus)); 2085*5c51f124SMoriah Waterland } 2086*5c51f124SMoriah Waterland 2087*5c51f124SMoriah Waterland /* 2088*5c51f124SMoriah Waterland * Name: z_zone_exec 2089*5c51f124SMoriah Waterland * Description: Execute a Unix command in a specified zone and return results 2090*5c51f124SMoriah Waterland * Arguments: a_zoneName - pointer to string representing the name of the zone 2091*5c51f124SMoriah Waterland * to execute the specified command in 2092*5c51f124SMoriah Waterland * a_path - pointer to string representing the full path *in the 2093*5c51f124SMoriah Waterland * non-global zone named by a_zoneName* of the Unix command 2094*5c51f124SMoriah Waterland * to be executed 2095*5c51f124SMoriah Waterland * a_argv[] - Pointer to array of character strings representing 2096*5c51f124SMoriah Waterland * the arguments to be passed to the Unix command. The list 2097*5c51f124SMoriah Waterland * must be termianted with an element that is (char *)NULL 2098*5c51f124SMoriah Waterland * NOTE: a_argv[0] is the "command name" passed to the command 2099*5c51f124SMoriah Waterland * a_stdoutPath - Pointer to string representing the path to a file 2100*5c51f124SMoriah Waterland * into which all output to "stdout" from the Unix command 2101*5c51f124SMoriah Waterland * is placed. 2102*5c51f124SMoriah Waterland * == (char *)NULL - leave stdout open and pass through 2103*5c51f124SMoriah Waterland * == "/dev/null" - discard stdout output 2104*5c51f124SMoriah Waterland * a_strerrPath - Pointer to string representing the path to a file 2105*5c51f124SMoriah Waterland * into which all output to "stderr" from the Unix command 2106*5c51f124SMoriah Waterland * is placed. 2107*5c51f124SMoriah Waterland * == (char *)NULL - leave stderr open and pass through 2108*5c51f124SMoriah Waterland * == "/dev/null" - discard stderr output 2109*5c51f124SMoriah Waterland * a_fds - Pointer to array of integers representing file 2110*5c51f124SMoriah Waterland * descriptors to remain open during the call - all 2111*5c51f124SMoriah Waterland * file descriptors above STDERR_FILENO not in this 2112*5c51f124SMoriah Waterland * list will be closed. 2113*5c51f124SMoriah Waterland * Returns: int 2114*5c51f124SMoriah Waterland * The return (exit) code from the specified Unix command 2115*5c51f124SMoriah Waterland * Special return codes: 2116*5c51f124SMoriah Waterland * -1 : failure to exec process 2117*5c51f124SMoriah Waterland * -2 : could not create contract for greenline 2118*5c51f124SMoriah Waterland * -3 : fork() failed 2119*5c51f124SMoriah Waterland * -4 : could not open stdout capture file 2120*5c51f124SMoriah Waterland * -5 : error from 'waitpid' other than EINTR 2121*5c51f124SMoriah Waterland * -6 : zones are not supported 2122*5c51f124SMoriah Waterland * NOTE: All file descriptores other than 0, 1 and 2 are closed except 2123*5c51f124SMoriah Waterland * for those file descriptors listed in the a_fds array. 2124*5c51f124SMoriah Waterland */ 2125*5c51f124SMoriah Waterland 2126*5c51f124SMoriah Waterland int 2127*5c51f124SMoriah Waterland z_zone_exec(const char *a_zoneName, const char *a_path, char *a_argv[], 2128*5c51f124SMoriah Waterland char *a_stdoutPath, char *a_stderrPath, int *a_fds) 2129*5c51f124SMoriah Waterland { 2130*5c51f124SMoriah Waterland int final_status; 2131*5c51f124SMoriah Waterland int lerrno; 2132*5c51f124SMoriah Waterland int status; 2133*5c51f124SMoriah Waterland int tmpl_fd; 2134*5c51f124SMoriah Waterland pid_t child_pid; 2135*5c51f124SMoriah Waterland pid_t result_pid; 2136*5c51f124SMoriah Waterland struct sigaction nact; 2137*5c51f124SMoriah Waterland struct sigaction oact; 2138*5c51f124SMoriah Waterland void (*funcSighup)(); 2139*5c51f124SMoriah Waterland void (*funcSigint)(); 2140*5c51f124SMoriah Waterland 2141*5c51f124SMoriah Waterland /* if zones are not implemented, return TRUE */ 2142*5c51f124SMoriah Waterland 2143*5c51f124SMoriah Waterland if (z_zones_are_implemented() == B_FALSE) { 2144*5c51f124SMoriah Waterland return (-6); /* -6 : zones are not supported */ 2145*5c51f124SMoriah Waterland } 2146*5c51f124SMoriah Waterland 2147*5c51f124SMoriah Waterland if ((tmpl_fd = _zexec_init_template()) == -1) { 2148*5c51f124SMoriah Waterland _z_program_error(ERR_CANNOT_CREATE_CONTRACT, strerror(errno)); 2149*5c51f124SMoriah Waterland return (-2); /* -2 : could not create greenline contract */ 2150*5c51f124SMoriah Waterland } 2151*5c51f124SMoriah Waterland 2152*5c51f124SMoriah Waterland /* 2153*5c51f124SMoriah Waterland * hold SIGINT/SIGHUP signals and reset signal received counter; 2154*5c51f124SMoriah Waterland * after the fork1() the parent and child need to setup their respective 2155*5c51f124SMoriah Waterland * interrupt handling and release the hold on the signals 2156*5c51f124SMoriah Waterland */ 2157*5c51f124SMoriah Waterland 2158*5c51f124SMoriah Waterland (void) sighold(SIGINT); 2159*5c51f124SMoriah Waterland (void) sighold(SIGHUP); 2160*5c51f124SMoriah Waterland 2161*5c51f124SMoriah Waterland _z_global_data._z_SigReceived = 0; /* no signals received */ 2162*5c51f124SMoriah Waterland 2163*5c51f124SMoriah Waterland /* 2164*5c51f124SMoriah Waterland * fork off a new process to execute command in; 2165*5c51f124SMoriah Waterland * fork1() is used instead of vfork() so the child process can 2166*5c51f124SMoriah Waterland * perform operations that would modify the parent process if 2167*5c51f124SMoriah Waterland * vfork() were used 2168*5c51f124SMoriah Waterland */ 2169*5c51f124SMoriah Waterland 2170*5c51f124SMoriah Waterland child_pid = fork1(); 2171*5c51f124SMoriah Waterland 2172*5c51f124SMoriah Waterland if (child_pid < 0) { 2173*5c51f124SMoriah Waterland /* 2174*5c51f124SMoriah Waterland * ************************************************************* 2175*5c51f124SMoriah Waterland * fork failed! 2176*5c51f124SMoriah Waterland * ************************************************************* 2177*5c51f124SMoriah Waterland */ 2178*5c51f124SMoriah Waterland 2179*5c51f124SMoriah Waterland (void) ct_tmpl_clear(tmpl_fd); 2180*5c51f124SMoriah Waterland (void) close(tmpl_fd); 2181*5c51f124SMoriah Waterland _z_program_error(ERR_FORK, strerror(errno)); 2182*5c51f124SMoriah Waterland 2183*5c51f124SMoriah Waterland /* release hold on signals */ 2184*5c51f124SMoriah Waterland 2185*5c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 2186*5c51f124SMoriah Waterland (void) sigrelse(SIGINT); 2187*5c51f124SMoriah Waterland 2188*5c51f124SMoriah Waterland return (-3); /* -3 : fork() failed */ 2189*5c51f124SMoriah Waterland } 2190*5c51f124SMoriah Waterland 2191*5c51f124SMoriah Waterland if (child_pid == 0) { 2192*5c51f124SMoriah Waterland int i; 2193*5c51f124SMoriah Waterland 2194*5c51f124SMoriah Waterland /* 2195*5c51f124SMoriah Waterland * ************************************************************* 2196*5c51f124SMoriah Waterland * This is the forked (child) process 2197*5c51f124SMoriah Waterland * ************************************************************* 2198*5c51f124SMoriah Waterland */ 2199*5c51f124SMoriah Waterland 2200*5c51f124SMoriah Waterland (void) ct_tmpl_clear(tmpl_fd); 2201*5c51f124SMoriah Waterland (void) close(tmpl_fd); 2202*5c51f124SMoriah Waterland 2203*5c51f124SMoriah Waterland /* reset any signals to default */ 2204*5c51f124SMoriah Waterland 2205*5c51f124SMoriah Waterland for (i = 0; i < NSIG; i++) { 2206*5c51f124SMoriah Waterland (void) sigset(i, SIG_DFL); 2207*5c51f124SMoriah Waterland } 2208*5c51f124SMoriah Waterland 2209*5c51f124SMoriah Waterland /* 2210*5c51f124SMoriah Waterland * close all file descriptors not in the a_fds list 2211*5c51f124SMoriah Waterland */ 2212*5c51f124SMoriah Waterland 2213*5c51f124SMoriah Waterland (void) fdwalk(&_z_close_file_descriptors, (void *)a_fds); 2214*5c51f124SMoriah Waterland 2215*5c51f124SMoriah Waterland /* 2216*5c51f124SMoriah Waterland * if a file for stdout is present, open the file and use the 2217*5c51f124SMoriah Waterland * file to capture stdout from the _zexec process 2218*5c51f124SMoriah Waterland */ 2219*5c51f124SMoriah Waterland 2220*5c51f124SMoriah Waterland if (a_stdoutPath != (char *)NULL) { 2221*5c51f124SMoriah Waterland int stdoutfd; 2222*5c51f124SMoriah Waterland 2223*5c51f124SMoriah Waterland stdoutfd = open(a_stdoutPath, 2224*5c51f124SMoriah Waterland O_WRONLY|O_CREAT|O_TRUNC, 0600); 2225*5c51f124SMoriah Waterland if (stdoutfd < 0) { 2226*5c51f124SMoriah Waterland _z_program_error(ERR_CAPTURE_FILE, a_stdoutPath, 2227*5c51f124SMoriah Waterland strerror(errno)); 2228*5c51f124SMoriah Waterland return (-4); 2229*5c51f124SMoriah Waterland } 2230*5c51f124SMoriah Waterland 2231*5c51f124SMoriah Waterland (void) dup2(stdoutfd, STDOUT_FILENO); 2232*5c51f124SMoriah Waterland (void) close(stdoutfd); 2233*5c51f124SMoriah Waterland } 2234*5c51f124SMoriah Waterland 2235*5c51f124SMoriah Waterland /* 2236*5c51f124SMoriah Waterland * if a file for stderr is present, open the file and use the 2237*5c51f124SMoriah Waterland * file to capture stderr from the _zexec process 2238*5c51f124SMoriah Waterland */ 2239*5c51f124SMoriah Waterland 2240*5c51f124SMoriah Waterland if (a_stderrPath != (char *)NULL) { 2241*5c51f124SMoriah Waterland int stderrfd; 2242*5c51f124SMoriah Waterland 2243*5c51f124SMoriah Waterland stderrfd = open(a_stderrPath, 2244*5c51f124SMoriah Waterland O_WRONLY|O_CREAT|O_TRUNC, 0600); 2245*5c51f124SMoriah Waterland if (stderrfd < 0) { 2246*5c51f124SMoriah Waterland _z_program_error(ERR_CAPTURE_FILE, a_stderrPath, 2247*5c51f124SMoriah Waterland strerror(errno)); 2248*5c51f124SMoriah Waterland return (-4); 2249*5c51f124SMoriah Waterland } 2250*5c51f124SMoriah Waterland 2251*5c51f124SMoriah Waterland (void) dup2(stderrfd, STDERR_FILENO); 2252*5c51f124SMoriah Waterland (void) close(stderrfd); 2253*5c51f124SMoriah Waterland } 2254*5c51f124SMoriah Waterland 2255*5c51f124SMoriah Waterland /* release all held signals */ 2256*5c51f124SMoriah Waterland 2257*5c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 2258*5c51f124SMoriah Waterland (void) sigrelse(SIGINT); 2259*5c51f124SMoriah Waterland 2260*5c51f124SMoriah Waterland /* execute command in the specified non-global zone */ 2261*5c51f124SMoriah Waterland 2262*5c51f124SMoriah Waterland _exit(_zexec(a_zoneName, a_path, a_argv)); 2263*5c51f124SMoriah Waterland } 2264*5c51f124SMoriah Waterland 2265*5c51f124SMoriah Waterland /* 2266*5c51f124SMoriah Waterland * ********************************************************************* 2267*5c51f124SMoriah Waterland * This is the forking (parent) process 2268*5c51f124SMoriah Waterland * ********************************************************************* 2269*5c51f124SMoriah Waterland */ 2270*5c51f124SMoriah Waterland 2271*5c51f124SMoriah Waterland /* register child process i.d. so signal handlers can pass signal on */ 2272*5c51f124SMoriah Waterland 2273*5c51f124SMoriah Waterland _z_global_data._z_ChildProcessId = child_pid; 2274*5c51f124SMoriah Waterland 2275*5c51f124SMoriah Waterland /* 2276*5c51f124SMoriah Waterland * setup signal handlers for SIGINT and SIGHUP and release hold 2277*5c51f124SMoriah Waterland */ 2278*5c51f124SMoriah Waterland 2279*5c51f124SMoriah Waterland /* hook SIGINT to _z_sig_trap() */ 2280*5c51f124SMoriah Waterland 2281*5c51f124SMoriah Waterland nact.sa_handler = _z_sig_trap; 2282*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 2283*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 2284*5c51f124SMoriah Waterland 2285*5c51f124SMoriah Waterland if (sigaction(SIGINT, &nact, &oact) < 0) { 2286*5c51f124SMoriah Waterland funcSigint = SIG_DFL; 2287*5c51f124SMoriah Waterland } else { 2288*5c51f124SMoriah Waterland funcSigint = oact.sa_handler; 2289*5c51f124SMoriah Waterland } 2290*5c51f124SMoriah Waterland 2291*5c51f124SMoriah Waterland /* hook SIGHUP to _z_sig_trap() */ 2292*5c51f124SMoriah Waterland 2293*5c51f124SMoriah Waterland nact.sa_handler = _z_sig_trap; 2294*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 2295*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 2296*5c51f124SMoriah Waterland 2297*5c51f124SMoriah Waterland if (sigaction(SIGHUP, &nact, &oact) < 0) { 2298*5c51f124SMoriah Waterland funcSighup = SIG_DFL; 2299*5c51f124SMoriah Waterland } else { 2300*5c51f124SMoriah Waterland funcSighup = oact.sa_handler; 2301*5c51f124SMoriah Waterland } 2302*5c51f124SMoriah Waterland 2303*5c51f124SMoriah Waterland /* release hold on signals */ 2304*5c51f124SMoriah Waterland 2305*5c51f124SMoriah Waterland (void) sigrelse(SIGHUP); 2306*5c51f124SMoriah Waterland (void) sigrelse(SIGINT); 2307*5c51f124SMoriah Waterland 2308*5c51f124SMoriah Waterland (void) ct_tmpl_clear(tmpl_fd); 2309*5c51f124SMoriah Waterland (void) close(tmpl_fd); 2310*5c51f124SMoriah Waterland 2311*5c51f124SMoriah Waterland /* 2312*5c51f124SMoriah Waterland * wait for the process to exit, reap child exit status 2313*5c51f124SMoriah Waterland */ 2314*5c51f124SMoriah Waterland 2315*5c51f124SMoriah Waterland for (;;) { 2316*5c51f124SMoriah Waterland result_pid = waitpid(child_pid, &status, 0L); 2317*5c51f124SMoriah Waterland lerrno = (result_pid == -1 ? errno : 0); 2318*5c51f124SMoriah Waterland 2319*5c51f124SMoriah Waterland /* break loop if child process status reaped */ 2320*5c51f124SMoriah Waterland 2321*5c51f124SMoriah Waterland if (result_pid != -1) { 2322*5c51f124SMoriah Waterland break; 2323*5c51f124SMoriah Waterland } 2324*5c51f124SMoriah Waterland 2325*5c51f124SMoriah Waterland /* break loop if not interrupted out of waitpid */ 2326*5c51f124SMoriah Waterland 2327*5c51f124SMoriah Waterland if (errno != EINTR) { 2328*5c51f124SMoriah Waterland break; 2329*5c51f124SMoriah Waterland } 2330*5c51f124SMoriah Waterland } 2331*5c51f124SMoriah Waterland 2332*5c51f124SMoriah Waterland /* reset child process i.d. so signal handlers do not pass signals on */ 2333*5c51f124SMoriah Waterland 2334*5c51f124SMoriah Waterland _z_global_data._z_ChildProcessId = -1; 2335*5c51f124SMoriah Waterland 2336*5c51f124SMoriah Waterland /* 2337*5c51f124SMoriah Waterland * If the child process terminated due to a call to exit(), then 2338*5c51f124SMoriah Waterland * set results equal to the 8-bit exit status of the child process; 2339*5c51f124SMoriah Waterland * otherwise, set the exit status to "-1" indicating that the child 2340*5c51f124SMoriah Waterland * exited via a signal. 2341*5c51f124SMoriah Waterland */ 2342*5c51f124SMoriah Waterland 2343*5c51f124SMoriah Waterland if (WIFEXITED(status)) { 2344*5c51f124SMoriah Waterland final_status = WEXITSTATUS(status); 2345*5c51f124SMoriah Waterland if ((_z_global_data._z_SigReceived != 0) && 2346*5c51f124SMoriah Waterland (final_status == 0)) { 2347*5c51f124SMoriah Waterland final_status = 1; 2348*5c51f124SMoriah Waterland } 2349*5c51f124SMoriah Waterland } else { 2350*5c51f124SMoriah Waterland final_status = -1; /* -1 : failure to exec process */ 2351*5c51f124SMoriah Waterland } 2352*5c51f124SMoriah Waterland 2353*5c51f124SMoriah Waterland /* determine proper exit code */ 2354*5c51f124SMoriah Waterland 2355*5c51f124SMoriah Waterland if (result_pid == -1) { 2356*5c51f124SMoriah Waterland final_status = -5; /* -5 : error from waitpid not EINTR */ 2357*5c51f124SMoriah Waterland } else if (_z_global_data._z_SigReceived != 0) { 2358*5c51f124SMoriah Waterland final_status = -7; /* -7 : interrupt received */ 2359*5c51f124SMoriah Waterland } 2360*5c51f124SMoriah Waterland 2361*5c51f124SMoriah Waterland /* 2362*5c51f124SMoriah Waterland * reset signal handlers 2363*5c51f124SMoriah Waterland */ 2364*5c51f124SMoriah Waterland 2365*5c51f124SMoriah Waterland /* reset SIGINT */ 2366*5c51f124SMoriah Waterland 2367*5c51f124SMoriah Waterland nact.sa_handler = funcSigint; 2368*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 2369*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 2370*5c51f124SMoriah Waterland 2371*5c51f124SMoriah Waterland (void) sigaction(SIGINT, &nact, (struct sigaction *)NULL); 2372*5c51f124SMoriah Waterland 2373*5c51f124SMoriah Waterland /* reset SIGHUP */ 2374*5c51f124SMoriah Waterland 2375*5c51f124SMoriah Waterland nact.sa_handler = funcSighup; 2376*5c51f124SMoriah Waterland nact.sa_flags = SA_RESTART; 2377*5c51f124SMoriah Waterland (void) sigemptyset(&nact.sa_mask); 2378*5c51f124SMoriah Waterland 2379*5c51f124SMoriah Waterland (void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL); 2380*5c51f124SMoriah Waterland 2381*5c51f124SMoriah Waterland /* 2382*5c51f124SMoriah Waterland * if signal received during command execution, interrupt 2383*5c51f124SMoriah Waterland * this process now. 2384*5c51f124SMoriah Waterland */ 2385*5c51f124SMoriah Waterland 2386*5c51f124SMoriah Waterland if (_z_global_data._z_SigReceived != 0) { 2387*5c51f124SMoriah Waterland (void) kill(getpid(), SIGINT); 2388*5c51f124SMoriah Waterland } 2389*5c51f124SMoriah Waterland 2390*5c51f124SMoriah Waterland /* set errno and return */ 2391*5c51f124SMoriah Waterland 2392*5c51f124SMoriah Waterland errno = lerrno; 2393*5c51f124SMoriah Waterland 2394*5c51f124SMoriah Waterland return (final_status); 2395*5c51f124SMoriah Waterland } 2396*5c51f124SMoriah Waterland 2397*5c51f124SMoriah Waterland /* 2398*5c51f124SMoriah Waterland * Name: z_zones_are_implemented 2399*5c51f124SMoriah Waterland * Description: Determine if any zone operations can be performed 2400*5c51f124SMoriah Waterland * Arguments: void 2401*5c51f124SMoriah Waterland * Returns: boolean_t 2402*5c51f124SMoriah Waterland * == B_TRUE - zone operations are available 2403*5c51f124SMoriah Waterland * == B_FALSE - no zone operations can be done 2404*5c51f124SMoriah Waterland */ 2405*5c51f124SMoriah Waterland 2406*5c51f124SMoriah Waterland boolean_t 2407*5c51f124SMoriah Waterland z_zones_are_implemented(void) 2408*5c51f124SMoriah Waterland { 2409*5c51f124SMoriah Waterland static boolean_t _zonesImplementedDetermined = B_FALSE; 2410*5c51f124SMoriah Waterland static boolean_t _zonesAreImplemented = B_FALSE; 2411*5c51f124SMoriah Waterland 2412*5c51f124SMoriah Waterland /* if availability has not been determined, cache it now */ 2413*5c51f124SMoriah Waterland 2414*5c51f124SMoriah Waterland if (!_zonesImplementedDetermined) { 2415*5c51f124SMoriah Waterland _zonesImplementedDetermined = B_TRUE; 2416*5c51f124SMoriah Waterland _zonesAreImplemented = _z_zones_are_implemented(); 2417*5c51f124SMoriah Waterland if (!_zonesAreImplemented) { 2418*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_NOT_IMPLEMENTED); 2419*5c51f124SMoriah Waterland } else { 2420*5c51f124SMoriah Waterland _z_echoDebug(DBG_ZONES_ARE_IMPLEMENTED); 2421*5c51f124SMoriah Waterland } 2422*5c51f124SMoriah Waterland } 2423*5c51f124SMoriah Waterland 2424*5c51f124SMoriah Waterland return (_zonesAreImplemented); 2425*5c51f124SMoriah Waterland } 2426