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_states.c
30*5c51f124SMoriah Waterland  * Group:	libinstzones
31*5c51f124SMoriah Waterland  * Description:	Provide "zones" state interfaces for install consolidation code
32*5c51f124SMoriah Waterland  *
33*5c51f124SMoriah Waterland  * Public Methods:
34*5c51f124SMoriah Waterland  *
35*5c51f124SMoriah Waterland  *  z_make_zone_running - change state of non-global zone to "running"
36*5c51f124SMoriah Waterland  * _z_make_zone_ready - change state of non-global zone to "ready"
37*5c51f124SMoriah Waterland  * _z_make_zone_down - change state of non-global zone to "down"
38*5c51f124SMoriah Waterland  */
39*5c51f124SMoriah Waterland 
40*5c51f124SMoriah Waterland /*
41*5c51f124SMoriah Waterland  * System includes
42*5c51f124SMoriah Waterland  */
43*5c51f124SMoriah Waterland 
44*5c51f124SMoriah Waterland #include <stdio.h>
45*5c51f124SMoriah Waterland #include <stdlib.h>
46*5c51f124SMoriah Waterland #include <unistd.h>
47*5c51f124SMoriah Waterland #include <fcntl.h>
48*5c51f124SMoriah Waterland #include <ctype.h>
49*5c51f124SMoriah Waterland #include <sys/types.h>
50*5c51f124SMoriah Waterland #include <sys/param.h>
51*5c51f124SMoriah Waterland #include <string.h>
52*5c51f124SMoriah Waterland #include <strings.h>
53*5c51f124SMoriah Waterland #include <sys/stat.h>
54*5c51f124SMoriah Waterland #include <stdarg.h>
55*5c51f124SMoriah Waterland #include <limits.h>
56*5c51f124SMoriah Waterland #include <errno.h>
57*5c51f124SMoriah Waterland #include <stropts.h>
58*5c51f124SMoriah Waterland #include <libintl.h>
59*5c51f124SMoriah Waterland #include <locale.h>
60*5c51f124SMoriah Waterland #include <assert.h>
61*5c51f124SMoriah Waterland 
62*5c51f124SMoriah Waterland /*
63*5c51f124SMoriah Waterland  * local includes
64*5c51f124SMoriah Waterland  */
65*5c51f124SMoriah Waterland 
66*5c51f124SMoriah Waterland #include "instzones_lib.h"
67*5c51f124SMoriah Waterland #include "zones_strings.h"
68*5c51f124SMoriah Waterland 
69*5c51f124SMoriah Waterland /*
70*5c51f124SMoriah Waterland  * Private structures
71*5c51f124SMoriah Waterland  */
72*5c51f124SMoriah Waterland 
73*5c51f124SMoriah Waterland /*
74*5c51f124SMoriah Waterland  * Library Function Prototypes
75*5c51f124SMoriah Waterland  */
76*5c51f124SMoriah Waterland 
77*5c51f124SMoriah Waterland /*
78*5c51f124SMoriah Waterland  * Local Function Prototypes
79*5c51f124SMoriah Waterland  */
80*5c51f124SMoriah Waterland 
81*5c51f124SMoriah Waterland /*
82*5c51f124SMoriah Waterland  * global internal (private) declarations
83*5c51f124SMoriah Waterland  */
84*5c51f124SMoriah Waterland 
85*5c51f124SMoriah Waterland /*
86*5c51f124SMoriah Waterland  * *****************************************************************************
87*5c51f124SMoriah Waterland  * global external (public) functions
88*5c51f124SMoriah Waterland  * *****************************************************************************
89*5c51f124SMoriah Waterland  */
90*5c51f124SMoriah Waterland 
91*5c51f124SMoriah Waterland /*
92*5c51f124SMoriah Waterland  * Name:	_z_make_zone_running
93*5c51f124SMoriah Waterland  * Description:	Given a zone element entry for the non-global zone to affect,
94*5c51f124SMoriah Waterland  *		change the state of that non-global zone to "running"
95*5c51f124SMoriah Waterland  * Arguments:	a_zlem - [RO, *RW] - (zoneListElement_t)
96*5c51f124SMoriah Waterland  *			Zone list element describing the non-global zone to
97*5c51f124SMoriah Waterland  *			make running
98*5c51f124SMoriah Waterland  * Returns:	boolean_t
99*5c51f124SMoriah Waterland  *			B_TRUE - non-global zone state changed successfully
100*5c51f124SMoriah Waterland  *			B_FALSE - failed to make the non-global zone run
101*5c51f124SMoriah Waterland  */
102*5c51f124SMoriah Waterland 
103*5c51f124SMoriah Waterland boolean_t
_z_make_zone_running(zoneListElement_t * a_zlem)104*5c51f124SMoriah Waterland _z_make_zone_running(zoneListElement_t *a_zlem)
105*5c51f124SMoriah Waterland {
106*5c51f124SMoriah Waterland 	FILE		*fp;
107*5c51f124SMoriah Waterland 	argArray_t	*args;
108*5c51f124SMoriah Waterland 	char		 zonename[ZONENAME_MAX];
109*5c51f124SMoriah Waterland 	char		*results = (char *)NULL;
110*5c51f124SMoriah Waterland 	int		ret;
111*5c51f124SMoriah Waterland 	int		status = 0;
112*5c51f124SMoriah Waterland 
113*5c51f124SMoriah Waterland 	/* entry assertions */
114*5c51f124SMoriah Waterland 
115*5c51f124SMoriah Waterland 	assert(a_zlem != NULL);
116*5c51f124SMoriah Waterland 
117*5c51f124SMoriah Waterland 	/* act based on the zone's current kernel state */
118*5c51f124SMoriah Waterland 
119*5c51f124SMoriah Waterland 	switch (a_zlem->_zlCurrKernelStatus) {
120*5c51f124SMoriah Waterland 	case ZONE_STATE_RUNNING:
121*5c51f124SMoriah Waterland 	case ZONE_STATE_MOUNTED:
122*5c51f124SMoriah Waterland 		/* already running */
123*5c51f124SMoriah Waterland 		return (B_TRUE);
124*5c51f124SMoriah Waterland 
125*5c51f124SMoriah Waterland 	case ZONE_STATE_READY:
126*5c51f124SMoriah Waterland 		/* This should never happen */
127*5c51f124SMoriah Waterland 		if (zonecfg_in_alt_root())
128*5c51f124SMoriah Waterland 			return (B_FALSE);
129*5c51f124SMoriah Waterland 
130*5c51f124SMoriah Waterland 		/*
131*5c51f124SMoriah Waterland 		 * We're going to upset the zone anyway, so might as well just
132*5c51f124SMoriah Waterland 		 * halt it now and fall through to normal mounting.
133*5c51f124SMoriah Waterland 		 */
134*5c51f124SMoriah Waterland 
135*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONEHALT, a_zlem->_zlName);
136*5c51f124SMoriah Waterland 
137*5c51f124SMoriah Waterland 		args = _z_new_args(5);		/* generate new arg list */
138*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
139*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
140*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, a_zlem->_zlName);
141*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "halt");
142*5c51f124SMoriah Waterland 
143*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, (char *)NULL,
144*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
145*5c51f124SMoriah Waterland 
146*5c51f124SMoriah Waterland 		/* free generated argument list */
147*5c51f124SMoriah Waterland 
148*5c51f124SMoriah Waterland 		_z_free_args(args);
149*5c51f124SMoriah Waterland 
150*5c51f124SMoriah Waterland 		if (ret != 0) {
151*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEHALT_EXEC, ZONEADM_CMD,
152*5c51f124SMoriah Waterland 			    strerror(errno));
153*5c51f124SMoriah Waterland 			free(results);
154*5c51f124SMoriah Waterland 			return (B_FALSE);
155*5c51f124SMoriah Waterland 		}
156*5c51f124SMoriah Waterland 		if (status != 0) {
157*5c51f124SMoriah Waterland 			if (status == -1) {
158*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_SIGNAL,
159*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName);
160*5c51f124SMoriah Waterland 			} else {
161*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_ERROR,
162*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName, status,
163*5c51f124SMoriah Waterland 				    results == NULL ? "" : "\n",
164*5c51f124SMoriah Waterland 				    results == NULL ? "" : results);
165*5c51f124SMoriah Waterland 			}
166*5c51f124SMoriah Waterland 			free(results);
167*5c51f124SMoriah Waterland 			return (B_FALSE);
168*5c51f124SMoriah Waterland 		}
169*5c51f124SMoriah Waterland 
170*5c51f124SMoriah Waterland 		free(results);
171*5c51f124SMoriah Waterland 
172*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_INSTALLED;
173*5c51f124SMoriah Waterland 		/* FALLTHROUGH */
174*5c51f124SMoriah Waterland 
175*5c51f124SMoriah Waterland 	case ZONE_STATE_INSTALLED:
176*5c51f124SMoriah Waterland 	case ZONE_STATE_DOWN:
177*5c51f124SMoriah Waterland 		/* return false if the zone cannot be booted */
178*5c51f124SMoriah Waterland 
179*5c51f124SMoriah Waterland 		if (a_zlem->_zlStatus & ZST_NOT_BOOTABLE) {
180*5c51f124SMoriah Waterland 			return (B_FALSE);
181*5c51f124SMoriah Waterland 		}
182*5c51f124SMoriah Waterland 
183*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONERUNNING, a_zlem->_zlName);
184*5c51f124SMoriah Waterland 
185*5c51f124SMoriah Waterland 		/* these states can be booted - do so */
186*5c51f124SMoriah Waterland 
187*5c51f124SMoriah Waterland 		args = _z_new_args(10);		/* generate new arg list */
188*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
189*5c51f124SMoriah Waterland 		if (zonecfg_in_alt_root()) {
190*5c51f124SMoriah Waterland 			(void) _z_add_arg(args, "-R");
191*5c51f124SMoriah Waterland 			(void) _z_add_arg(args, "%s",
192*5c51f124SMoriah Waterland 			    (char *)zonecfg_get_root());
193*5c51f124SMoriah Waterland 		}
194*5c51f124SMoriah Waterland 
195*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
196*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "%s", a_zlem->_zlName);
197*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "mount");
198*5c51f124SMoriah Waterland 
199*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, (char *)NULL,
200*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
201*5c51f124SMoriah Waterland 
202*5c51f124SMoriah Waterland 		/* free generated argument list */
203*5c51f124SMoriah Waterland 
204*5c51f124SMoriah Waterland 		_z_free_args(args);
205*5c51f124SMoriah Waterland 
206*5c51f124SMoriah Waterland 		if (ret != 0) {
207*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEBOOT_EXEC, ZONEADM_CMD,
208*5c51f124SMoriah Waterland 			    strerror(errno));
209*5c51f124SMoriah Waterland 			free(results);
210*5c51f124SMoriah Waterland 			return (B_FALSE);
211*5c51f124SMoriah Waterland 		}
212*5c51f124SMoriah Waterland 
213*5c51f124SMoriah Waterland 		if (status != 0) {
214*5c51f124SMoriah Waterland 			if (status == -1) {
215*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_SIGNAL,
216*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName);
217*5c51f124SMoriah Waterland 			} else {
218*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_ERROR,
219*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName, status,
220*5c51f124SMoriah Waterland 				    results == NULL ? "" : "\n",
221*5c51f124SMoriah Waterland 				    results == NULL ? "" : results);
222*5c51f124SMoriah Waterland 			}
223*5c51f124SMoriah Waterland 			free(results);
224*5c51f124SMoriah Waterland 
225*5c51f124SMoriah Waterland 			/* remember this zone cannot be booted */
226*5c51f124SMoriah Waterland 
227*5c51f124SMoriah Waterland 			a_zlem->_zlStatus |= ZST_NOT_BOOTABLE;
228*5c51f124SMoriah Waterland 
229*5c51f124SMoriah Waterland 			return (B_FALSE);
230*5c51f124SMoriah Waterland 		}
231*5c51f124SMoriah Waterland 		free(results);
232*5c51f124SMoriah Waterland 
233*5c51f124SMoriah Waterland 		if (zonecfg_in_alt_root()) {
234*5c51f124SMoriah Waterland 			if ((fp = zonecfg_open_scratch("", B_FALSE)) == NULL ||
235*5c51f124SMoriah Waterland 			    zonecfg_find_scratch(fp, a_zlem->_zlName,
236*5c51f124SMoriah Waterland 			    zonecfg_get_root(), zonename,
237*5c51f124SMoriah Waterland 			    sizeof (zonename)) == -1) {
238*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_DIDNT_BOOT,
239*5c51f124SMoriah Waterland 				    a_zlem->_zlName);
240*5c51f124SMoriah Waterland 				if (fp != NULL)
241*5c51f124SMoriah Waterland 					zonecfg_close_scratch(fp);
242*5c51f124SMoriah Waterland 				return (B_FALSE);
243*5c51f124SMoriah Waterland 			}
244*5c51f124SMoriah Waterland 			zonecfg_close_scratch(fp);
245*5c51f124SMoriah Waterland 			free(a_zlem->_zlScratchName);
246*5c51f124SMoriah Waterland 			a_zlem->_zlScratchName = _z_strdup(zonename);
247*5c51f124SMoriah Waterland 		}
248*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_MOUNTED;
249*5c51f124SMoriah Waterland 		return (B_TRUE);
250*5c51f124SMoriah Waterland 
251*5c51f124SMoriah Waterland 	case ZONE_STATE_CONFIGURED:
252*5c51f124SMoriah Waterland 	case ZONE_STATE_INCOMPLETE:
253*5c51f124SMoriah Waterland 	case ZONE_STATE_SHUTTING_DOWN:
254*5c51f124SMoriah Waterland 	default:
255*5c51f124SMoriah Waterland 		/* cannot transition (boot) these states */
256*5c51f124SMoriah Waterland 		return (B_FALSE);
257*5c51f124SMoriah Waterland 	}
258*5c51f124SMoriah Waterland }
259*5c51f124SMoriah Waterland 
260*5c51f124SMoriah Waterland /*
261*5c51f124SMoriah Waterland  * Name:	_z_make_zone_ready
262*5c51f124SMoriah Waterland  * Description:	Given a zone element entry for the non-global zone to affect,
263*5c51f124SMoriah Waterland  *		restore the ready state of the zone when the zone is currently
264*5c51f124SMoriah Waterland  *		in the running state.
265*5c51f124SMoriah Waterland  * Arguments:	a_zlem - [RO, *RW] - (zoneListElement_t)
266*5c51f124SMoriah Waterland  *			Zone list element describing the non-global zone to
267*5c51f124SMoriah Waterland  *			make ready
268*5c51f124SMoriah Waterland  * Returns:	boolean_t
269*5c51f124SMoriah Waterland  *			B_TRUE - non-global zone state changed successfully
270*5c51f124SMoriah Waterland  *			B_FALSE - failed to make the non-global zone ready
271*5c51f124SMoriah Waterland  */
272*5c51f124SMoriah Waterland 
273*5c51f124SMoriah Waterland boolean_t
_z_make_zone_ready(zoneListElement_t * a_zlem)274*5c51f124SMoriah Waterland _z_make_zone_ready(zoneListElement_t *a_zlem)
275*5c51f124SMoriah Waterland {
276*5c51f124SMoriah Waterland 	argArray_t	*args;
277*5c51f124SMoriah Waterland 	char		*results = (char *)NULL;
278*5c51f124SMoriah Waterland 	int		status = 0;
279*5c51f124SMoriah Waterland 	int		i;
280*5c51f124SMoriah Waterland 	int		ret;
281*5c51f124SMoriah Waterland 	zone_state_t	st;
282*5c51f124SMoriah Waterland 
283*5c51f124SMoriah Waterland 	/* entry assertions */
284*5c51f124SMoriah Waterland 
285*5c51f124SMoriah Waterland 	assert(a_zlem != (zoneListElement_t *)NULL);
286*5c51f124SMoriah Waterland 
287*5c51f124SMoriah Waterland 	/* act based on the zone's current kernel state */
288*5c51f124SMoriah Waterland 
289*5c51f124SMoriah Waterland 	switch (a_zlem->_zlCurrKernelStatus) {
290*5c51f124SMoriah Waterland 	case ZONE_STATE_DOWN:
291*5c51f124SMoriah Waterland 	case ZONE_STATE_READY:
292*5c51f124SMoriah Waterland 		/* already down */
293*5c51f124SMoriah Waterland 		return (B_TRUE);
294*5c51f124SMoriah Waterland 
295*5c51f124SMoriah Waterland 	case ZONE_STATE_MOUNTED:
296*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONEUNMOUNT, a_zlem->_zlName);
297*5c51f124SMoriah Waterland 
298*5c51f124SMoriah Waterland 		args = _z_new_args(10);		/* generate new arg list */
299*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
300*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
301*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "%s", a_zlem->_zlName);
302*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "unmount");
303*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, NULL,
304*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
305*5c51f124SMoriah Waterland 		if (ret != 0) {
306*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEUNMOUNT_EXEC,
307*5c51f124SMoriah Waterland 			    ZONEADM_CMD, strerror(errno));
308*5c51f124SMoriah Waterland 			free(results);
309*5c51f124SMoriah Waterland 			_z_free_args(args);
310*5c51f124SMoriah Waterland 			return (B_FALSE);
311*5c51f124SMoriah Waterland 		}
312*5c51f124SMoriah Waterland 		if (status != 0) {
313*5c51f124SMoriah Waterland 			if (status == -1) {
314*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEUNMOUNT_CMD_SIGNAL,
315*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName);
316*5c51f124SMoriah Waterland 			} else {
317*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEUNMOUNT_CMD_ERROR,
318*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName, status,
319*5c51f124SMoriah Waterland 				    results == NULL ? "" : "\n",
320*5c51f124SMoriah Waterland 				    results == NULL ? "" : results);
321*5c51f124SMoriah Waterland 			}
322*5c51f124SMoriah Waterland 			if (results != NULL) {
323*5c51f124SMoriah Waterland 				free(results);
324*5c51f124SMoriah Waterland 			}
325*5c51f124SMoriah Waterland 			_z_free_args(args);
326*5c51f124SMoriah Waterland 			return (B_FALSE);
327*5c51f124SMoriah Waterland 		}
328*5c51f124SMoriah Waterland 		if (results != NULL) {
329*5c51f124SMoriah Waterland 			free(results);
330*5c51f124SMoriah Waterland 		}
331*5c51f124SMoriah Waterland 		_z_free_args(args);
332*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_INSTALLED;
333*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONEREADY, a_zlem->_zlName);
334*5c51f124SMoriah Waterland 
335*5c51f124SMoriah Waterland 		args = _z_new_args(10);		/* generate new arg list */
336*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
337*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
338*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "%s", a_zlem->_zlName);
339*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "ready");
340*5c51f124SMoriah Waterland 
341*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, NULL,
342*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
343*5c51f124SMoriah Waterland 		if (ret != 0) {
344*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEREADY_EXEC, ZONEADM_CMD,
345*5c51f124SMoriah Waterland 			    strerror(errno));
346*5c51f124SMoriah Waterland 			free(results);
347*5c51f124SMoriah Waterland 			_z_free_args(args);
348*5c51f124SMoriah Waterland 			return (B_FALSE);
349*5c51f124SMoriah Waterland 		}
350*5c51f124SMoriah Waterland 		if (status != 0) {
351*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEREADY_CMDFAIL, ZONEADM_CMD,
352*5c51f124SMoriah Waterland 			    a_zlem->_zlName, strerror(errno),
353*5c51f124SMoriah Waterland 			    results == NULL ? "" : "\n",
354*5c51f124SMoriah Waterland 			    results == NULL ? "" : results);
355*5c51f124SMoriah Waterland 			if (results != NULL) {
356*5c51f124SMoriah Waterland 				free(results);
357*5c51f124SMoriah Waterland 			}
358*5c51f124SMoriah Waterland 			_z_free_args(args);
359*5c51f124SMoriah Waterland 			return (B_FALSE);
360*5c51f124SMoriah Waterland 		}
361*5c51f124SMoriah Waterland 		if (results != NULL) {
362*5c51f124SMoriah Waterland 			free(results);
363*5c51f124SMoriah Waterland 		}
364*5c51f124SMoriah Waterland 		/* success - zone is now in the ready state */
365*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_READY;
366*5c51f124SMoriah Waterland 		return (B_TRUE);
367*5c51f124SMoriah Waterland 
368*5c51f124SMoriah Waterland 	case ZONE_STATE_RUNNING:
369*5c51f124SMoriah Waterland 
370*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONEREADY, a_zlem->_zlName);
371*5c51f124SMoriah Waterland 
372*5c51f124SMoriah Waterland 		args = _z_new_args(10);		/* generate new arg list */
373*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
374*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
375*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "%s", a_zlem->_zlName);
376*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "ready");
377*5c51f124SMoriah Waterland 
378*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, (char *)NULL,
379*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
380*5c51f124SMoriah Waterland 
381*5c51f124SMoriah Waterland 		/* free generated argument list */
382*5c51f124SMoriah Waterland 
383*5c51f124SMoriah Waterland 		_z_free_args(args);
384*5c51f124SMoriah Waterland 
385*5c51f124SMoriah Waterland 		if (ret != 0) {
386*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEREADY_EXEC, ZONEADM_CMD,
387*5c51f124SMoriah Waterland 			    strerror(errno));
388*5c51f124SMoriah Waterland 			free(results);
389*5c51f124SMoriah Waterland 			_z_free_args(args);
390*5c51f124SMoriah Waterland 			return (B_FALSE);
391*5c51f124SMoriah Waterland 		}
392*5c51f124SMoriah Waterland 		if (status != 0) {
393*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEREADY_CMDFAIL, ZONEADM_CMD,
394*5c51f124SMoriah Waterland 			    a_zlem->_zlName, strerror(errno),
395*5c51f124SMoriah Waterland 			    results == (char *)NULL ? "" : "\n",
396*5c51f124SMoriah Waterland 			    results == (char *)NULL ? "" : results);
397*5c51f124SMoriah Waterland 			if (results != (char *)NULL) {
398*5c51f124SMoriah Waterland 				(void) free(results);
399*5c51f124SMoriah Waterland 			}
400*5c51f124SMoriah Waterland 			return (B_FALSE);
401*5c51f124SMoriah Waterland 		}
402*5c51f124SMoriah Waterland 
403*5c51f124SMoriah Waterland 		if (results != (char *)NULL) {
404*5c51f124SMoriah Waterland 			(void) free(results);
405*5c51f124SMoriah Waterland 		}
406*5c51f124SMoriah Waterland 
407*5c51f124SMoriah Waterland 		for (i = 0; i < MAX_RETRIES; i++) {
408*5c51f124SMoriah Waterland 			if (zone_get_state(a_zlem->_zlName, &st) != Z_OK) {
409*5c51f124SMoriah Waterland 				break;
410*5c51f124SMoriah Waterland 			}
411*5c51f124SMoriah Waterland 			if ((st == ZONE_STATE_DOWN) ||
412*5c51f124SMoriah Waterland 			    (st == ZONE_STATE_INSTALLED)||
413*5c51f124SMoriah Waterland 			    (st == ZONE_STATE_READY)) {
414*5c51f124SMoriah Waterland 				break;
415*5c51f124SMoriah Waterland 			}
416*5c51f124SMoriah Waterland 			(void) sleep(RETRY_DELAY_SECS);
417*5c51f124SMoriah Waterland 		}
418*5c51f124SMoriah Waterland 
419*5c51f124SMoriah Waterland 		/* failure if maximum retries reached */
420*5c51f124SMoriah Waterland 
421*5c51f124SMoriah Waterland 		if (i >= MAX_RETRIES) {
422*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEREADY_DIDNT_READY,
423*5c51f124SMoriah Waterland 			    a_zlem->_zlName);
424*5c51f124SMoriah Waterland 			a_zlem->_zlCurrKernelStatus = st;
425*5c51f124SMoriah Waterland 			return (B_FALSE);
426*5c51f124SMoriah Waterland 		}
427*5c51f124SMoriah Waterland 
428*5c51f124SMoriah Waterland 		/* success - zone is now in the ready state  */
429*5c51f124SMoriah Waterland 
430*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_READY;
431*5c51f124SMoriah Waterland 
432*5c51f124SMoriah Waterland 		return (B_TRUE);
433*5c51f124SMoriah Waterland 
434*5c51f124SMoriah Waterland 	case ZONE_STATE_INSTALLED:
435*5c51f124SMoriah Waterland 	case ZONE_STATE_CONFIGURED:
436*5c51f124SMoriah Waterland 	case ZONE_STATE_INCOMPLETE:
437*5c51f124SMoriah Waterland 	case ZONE_STATE_SHUTTING_DOWN:
438*5c51f124SMoriah Waterland 	default:
439*5c51f124SMoriah Waterland 		return (B_FALSE);
440*5c51f124SMoriah Waterland 	}
441*5c51f124SMoriah Waterland }
442*5c51f124SMoriah Waterland 
443*5c51f124SMoriah Waterland /*
444*5c51f124SMoriah Waterland  * Name:	_z_make_zone_down
445*5c51f124SMoriah Waterland  * Description:	Given a zone element entry for the non-global zone to affect,
446*5c51f124SMoriah Waterland  *		change the state of that non-global zone to "down"
447*5c51f124SMoriah Waterland  * Arguments:	a_zlem - [RO, *RW] - (zoneListElement_t)
448*5c51f124SMoriah Waterland  *			Zone list element describing the non-global zone to
449*5c51f124SMoriah Waterland  *			make down
450*5c51f124SMoriah Waterland  * Returns:	boolean_t
451*5c51f124SMoriah Waterland  *			B_TRUE - non-global zone state changed successfully
452*5c51f124SMoriah Waterland  *			B_FALSE - failed to make the non-global zone down
453*5c51f124SMoriah Waterland  */
454*5c51f124SMoriah Waterland 
455*5c51f124SMoriah Waterland boolean_t
_z_make_zone_down(zoneListElement_t * a_zlem)456*5c51f124SMoriah Waterland _z_make_zone_down(zoneListElement_t *a_zlem)
457*5c51f124SMoriah Waterland {
458*5c51f124SMoriah Waterland 	argArray_t	*args;
459*5c51f124SMoriah Waterland 	char		*results = (char *)NULL;
460*5c51f124SMoriah Waterland 	int		status = 0;
461*5c51f124SMoriah Waterland 	int		ret;
462*5c51f124SMoriah Waterland 
463*5c51f124SMoriah Waterland 	/* entry assertions */
464*5c51f124SMoriah Waterland 
465*5c51f124SMoriah Waterland 	assert(a_zlem != NULL);
466*5c51f124SMoriah Waterland 
467*5c51f124SMoriah Waterland 	/* act based on the zone's current kernel state */
468*5c51f124SMoriah Waterland 
469*5c51f124SMoriah Waterland 	switch (a_zlem->_zlCurrKernelStatus) {
470*5c51f124SMoriah Waterland 	case ZONE_STATE_DOWN:
471*5c51f124SMoriah Waterland 	case ZONE_STATE_READY:
472*5c51f124SMoriah Waterland 	case ZONE_STATE_RUNNING:
473*5c51f124SMoriah Waterland 		/* shouldn't be touched */
474*5c51f124SMoriah Waterland 		return (B_TRUE);
475*5c51f124SMoriah Waterland 
476*5c51f124SMoriah Waterland 	case ZONE_STATE_MOUNTED:
477*5c51f124SMoriah Waterland 
478*5c51f124SMoriah Waterland 		_z_echoDebug(DBG_TO_ZONEHALT, a_zlem->_zlName);
479*5c51f124SMoriah Waterland 
480*5c51f124SMoriah Waterland 		/* these states can be halted - do so */
481*5c51f124SMoriah Waterland 
482*5c51f124SMoriah Waterland 		args = _z_new_args(10);		/* generate new arg list */
483*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, ZONEADM_CMD);
484*5c51f124SMoriah Waterland 
485*5c51f124SMoriah Waterland 		if (zonecfg_in_alt_root()) {
486*5c51f124SMoriah Waterland 			(void) _z_add_arg(args, "-R");
487*5c51f124SMoriah Waterland 			(void) _z_add_arg(args, "%s",
488*5c51f124SMoriah Waterland 			    (char *)zonecfg_get_root());
489*5c51f124SMoriah Waterland 		}
490*5c51f124SMoriah Waterland 
491*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "-z");
492*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "%s", a_zlem->_zlName);
493*5c51f124SMoriah Waterland 		(void) _z_add_arg(args, "unmount");
494*5c51f124SMoriah Waterland 
495*5c51f124SMoriah Waterland 		ret = z_ExecCmdArray(&status, &results, (char *)NULL,
496*5c51f124SMoriah Waterland 		    ZONEADM_CMD, _z_get_argv(args));
497*5c51f124SMoriah Waterland 
498*5c51f124SMoriah Waterland 		/* free generated argument list */
499*5c51f124SMoriah Waterland 
500*5c51f124SMoriah Waterland 		_z_free_args(args);
501*5c51f124SMoriah Waterland 
502*5c51f124SMoriah Waterland 		if (ret != 0) {
503*5c51f124SMoriah Waterland 			_z_program_error(ERR_ZONEHALT_EXEC, ZONEADM_CMD,
504*5c51f124SMoriah Waterland 			    strerror(errno));
505*5c51f124SMoriah Waterland 			free(results);
506*5c51f124SMoriah Waterland 			return (B_FALSE);
507*5c51f124SMoriah Waterland 		}
508*5c51f124SMoriah Waterland 		if (status != 0) {
509*5c51f124SMoriah Waterland 			if (status == -1) {
510*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_SIGNAL,
511*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName);
512*5c51f124SMoriah Waterland 			} else {
513*5c51f124SMoriah Waterland 				_z_program_error(ERR_ZONEBOOT_CMD_ERROR,
514*5c51f124SMoriah Waterland 				    ZONEADM_CMD, a_zlem->_zlName, status,
515*5c51f124SMoriah Waterland 				    results == NULL ? "" : "\n",
516*5c51f124SMoriah Waterland 				    results == NULL ? "" : results);
517*5c51f124SMoriah Waterland 			}
518*5c51f124SMoriah Waterland 			free(results);
519*5c51f124SMoriah Waterland 			return (B_FALSE);
520*5c51f124SMoriah Waterland 		}
521*5c51f124SMoriah Waterland 
522*5c51f124SMoriah Waterland 		free(results);
523*5c51f124SMoriah Waterland 
524*5c51f124SMoriah Waterland 		a_zlem->_zlCurrKernelStatus = ZONE_STATE_INSTALLED;
525*5c51f124SMoriah Waterland 		/*
526*5c51f124SMoriah Waterland 		 * Leave the scratch name in place because the upper level
527*5c51f124SMoriah Waterland 		 * software may have used it to construct file names and the
528*5c51f124SMoriah Waterland 		 * like.
529*5c51f124SMoriah Waterland 		 */
530*5c51f124SMoriah Waterland 		return (B_TRUE);
531*5c51f124SMoriah Waterland 
532*5c51f124SMoriah Waterland 	case ZONE_STATE_INSTALLED:
533*5c51f124SMoriah Waterland 	case ZONE_STATE_CONFIGURED:
534*5c51f124SMoriah Waterland 	case ZONE_STATE_INCOMPLETE:
535*5c51f124SMoriah Waterland 	case ZONE_STATE_SHUTTING_DOWN:
536*5c51f124SMoriah Waterland 	default:
537*5c51f124SMoriah Waterland 		return (B_FALSE);
538*5c51f124SMoriah Waterland 	}
539*5c51f124SMoriah Waterland }
540*5c51f124SMoriah Waterland 
541*5c51f124SMoriah Waterland /*
542*5c51f124SMoriah Waterland  * Function:    UmountAllZones
543*5c51f124SMoriah Waterland  * Description: Unmount all mounted zones under a specified directory.
544*5c51f124SMoriah Waterland  *
545*5c51f124SMoriah Waterland  * Scope:   public
546*5c51f124SMoriah Waterland  * Parameters:  mntpnt  [RO, *RO]
547*5c51f124SMoriah Waterland  *          Non-NULL pointer to name of directory to be unmounted.
548*5c51f124SMoriah Waterland  * Return:   0  - successfull
549*5c51f124SMoriah Waterland  *      -1  - unmount failed; see errno for reason
550*5c51f124SMoriah Waterland  */
551*5c51f124SMoriah Waterland int
UmountAllZones(char * mntpnt)552*5c51f124SMoriah Waterland UmountAllZones(char *mntpnt) {
553*5c51f124SMoriah Waterland 
554*5c51f124SMoriah Waterland 	zoneList_t  zlst;
555*5c51f124SMoriah Waterland 	int	 k;
556*5c51f124SMoriah Waterland 	int  ret = 0;
557*5c51f124SMoriah Waterland 
558*5c51f124SMoriah Waterland 	if (z_zones_are_implemented()) {
559*5c51f124SMoriah Waterland 
560*5c51f124SMoriah Waterland 		z_set_zone_root(mntpnt);
561*5c51f124SMoriah Waterland 
562*5c51f124SMoriah Waterland 		zlst = z_get_nonglobal_zone_list();
563*5c51f124SMoriah Waterland 		if (zlst == (zoneList_t)NULL) {
564*5c51f124SMoriah Waterland 			return (0);
565*5c51f124SMoriah Waterland 		}
566*5c51f124SMoriah Waterland 
567*5c51f124SMoriah Waterland 		for (k = 0; z_zlist_get_zonename(zlst, k) != (char *)NULL;
568*5c51f124SMoriah Waterland 		    k++) {
569*5c51f124SMoriah Waterland 			if (z_zlist_get_current_state(zlst, k) >
570*5c51f124SMoriah Waterland 			    ZONE_STATE_INSTALLED) {
571*5c51f124SMoriah Waterland 				if (!z_zlist_change_zone_state(zlst, k,
572*5c51f124SMoriah Waterland 				    ZONE_STATE_INSTALLED)) {
573*5c51f124SMoriah Waterland 					ret = -1;
574*5c51f124SMoriah Waterland 					break;
575*5c51f124SMoriah Waterland 				}
576*5c51f124SMoriah Waterland 			}
577*5c51f124SMoriah Waterland 		}
578*5c51f124SMoriah Waterland 
579*5c51f124SMoriah Waterland 		/* Free zlst */
580*5c51f124SMoriah Waterland 		z_free_zone_list(zlst);
581*5c51f124SMoriah Waterland 	}
582*5c51f124SMoriah Waterland 
583*5c51f124SMoriah Waterland 	return (ret);
584*5c51f124SMoriah Waterland 
585*5c51f124SMoriah Waterland }
586