4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
30 * Description: Provide "zones" interface for install consolidation code
34 * _z_close_file_descriptors - close a file descriptor "a_fd" not in the
36 * _z_echo - Output an interactive message if interaction is enabled
37 * _z_echoDebug - Output a debugging message if debugging is enabled
38 * _z_is_directory - determine if specified path exists and is a directory
39 * _z_program_error - Output an error message to the appropriate destinations
40 * _z_pluginCatchSigint - SIGINT/SIGHUP interrupt handler
41 * _z_running_in_global_zone - Determine if this process is running in the
43 * _z_zones_are_implemented - Determine if zones are supported by the
45 * _z_brands_are_implemented - determine if branded zones are implemented on
58 #include <sys/types.h>
59 #include <sys/param.h>
77 #include "instzones_lib.h"
78 #include "zones_strings.h"
85 * these dynamic libraries are required in order to use the branded zones
86 * functionality. If these libraries are not available at runtime,
87 * then the zones we find are assumed to be native zones.
90 #define BRAND1_LIBRARY "libbrand.so.1"
91 #define BRAND_LIBRARY "libbrand.so"
94 * Library Function Prototypes
98 * Local Function Prototypes
101 static void error_and_exit(int error_num
);
103 static void (*fatal_err_func
)() = &error_and_exit
;
105 /* ----------------------- private functions -------------------------- */
108 * Abort routine. An exit code of '2' is used by all applications
109 * to indicate a non-recoverable fatal error.
111 * error_num - error index number:
119 error_and_exit(int error_num
)
121 if (error_num
== ERR_MALLOC_FAIL
)
122 (void) fprintf(stderr
, "Allocation of memory failed\n");
124 (void) fprintf(stderr
, "ERROR: code %d\n", error_num
);
129 * *****************************************************************************
130 * global external (public) functions
131 * *****************************************************************************
135 * Name: _z_close_file_descriptors
136 * Description: close a file descriptor "a_fd" not in the list "a_fds"
137 * This function is called from the fdwalk() library function.
138 * If the file descriptor passed in is NOT in the list passed in,
139 * the file is closed.
140 * Arguments: a_fds - [RO, *RO] - (void *)
141 * Pointer to list of file descriptors to keep open
142 * a_fd - [RO, *RO] - (int)
143 * File descriptor to check
149 _z_close_file_descriptors(void *a_fds
, int a_fd
)
154 /* do not close standard input, output, or error file descriptors */
156 if (a_fd
== STDIN_FILENO
|| a_fd
== STDOUT_FILENO
||
157 a_fd
== STDERR_FILENO
) {
161 /* if no file descriptor retention list, close this file */
163 if (a_fds
== (void *)NULL
) {
169 * retention list provided, skip this descriptor if its in the list
174 for (i
= 0; fds
[i
] != -1; i
++) {
175 if (fds
[i
] == a_fd
) {
180 /* this descriptor not in retention list - close this file */
189 * Synopsis: Output an interactive message if interaction is enabled
190 * Description: Main method for outputting an interactive message; call to
191 * output interactive message if interation has not been disabled
192 * by a previous call to echoSetFlag(0).
193 * Arguments: format - [RO, RO*] (char *)
194 * printf-style format for debugging message to be output
195 * VARG_LIST - [RO] (?)
196 * arguments as appropriate to 'format' specified
202 _z_echo(char *a_format
, ...)
205 char message
[MAX_MESSAGE_SIZE
];
207 /* entry assertions */
209 assert(a_format
!= NULL
);
211 /* return if no progerr function registered */
213 if (_z_global_data
._z_echo
== NULL
) {
217 /* capture message */
219 va_start(ap
, a_format
);
220 (void) vsnprintf(message
, sizeof (message
), a_format
, ap
);
223 /* pass message to registered function */
225 (_z_global_data
._z_echo
)("%s", message
);
230 * Synopsis: Output a debugging message if debugging is enabled
231 * Description: Main method for outputting a debugging message; call to
232 * output debugging message if debugging has been enabled
233 * by a previous call to _z_echoDebugSetFlag(1).
234 * Arguments: format - [RO, RO*] (char *)
235 * printf-style format for debugging message to be output
236 * VARG_LIST - [RO] (?)
237 * arguments as appropriate to 'format' specified
239 * NOTE: format of message will be:
240 * # [ aaa bbb ccc ] message
241 * where: aaa - process i.d.
243 * ccc - name of program
245 * # [ 25685 0 pkgadd ] unable to get package list
250 _z_echoDebug(char *a_format
, ...)
253 char message
[MAX_MESSAGE_SIZE
];
255 /* entry assertions */
257 assert(a_format
!= NULL
);
259 /* return if no progerr function registered */
261 if (_z_global_data
._z_echo_debug
== NULL
) {
265 /* capture message */
267 va_start(ap
, a_format
);
268 (void) vsnprintf(message
, sizeof (message
), a_format
, ap
);
271 /* pass message to registered function */
273 (_z_global_data
._z_echo_debug
)("%s", message
);
277 * Name: _z_is_directory
278 * Description: determine if specified path exists and is a directory
279 * Arguments: path - pointer to string representing the path to verify
280 * returns: 0 - directory exists
281 * 1 - directory does not exist or is not a directory
282 * NOTE: errno is set appropriately
286 _z_is_directory(char *path
)
290 /* entry assertions */
292 assert(path
!= NULL
);
293 assert(*path
!= '\0');
295 /* return error if path does not exist */
297 if (stat(path
, &statbuf
) != 0) {
301 /* return error if path is not a directory */
303 if ((statbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
308 /* path exists and is a directory */
314 * Name: _z_pluginCatchSigint
315 * Synopsis: SIGINT/SIGHUP interrupt handler
316 * Description: Catch the "SIGINT" and "SIGHUP" signals:
317 * -> increment _z_SigReceived global variable
318 * -> propagate signal to "_z_ChildProcessId" if registered (!= -1)
319 * Arguments: signo - [RO, *RO] - (int)
320 * Signal number that was caught
325 _z_sig_trap(int a_signo
)
327 /* bump signals received count */
329 _z_global_data
._z_SigReceived
++;
331 /* if child process registered, propagate signal to child */
333 if (_z_global_data
._z_ChildProcessId
> 0) {
334 (void) kill(_z_global_data
._z_ChildProcessId
, a_signo
);
339 * Name: _z_program_error
340 * Description: Output an error message to the appropriate destinations
341 * Arguments: format - [RO, RO*] (char *)
342 * printf-style format for debugging message to be output
343 * VARG_LIST - [RO] (?)
344 * arguments as appropriate to 'format' specified
346 * NOTE: format of message will be:
347 * [aaa: ] ERROR: message
348 * where: aaa - program name (if set)
349 * message - results of format and arguments
351 * ERROR: unable to get package list
356 _z_program_error(char *a_format
, ...)
359 char message
[MAX_MESSAGE_SIZE
];
361 /* entry assertions */
363 assert(a_format
!= NULL
);
365 /* return if no progerr function registered */
367 if (_z_global_data
._z_progerr
== NULL
) {
371 /* capture message */
373 va_start(ap
, a_format
);
374 (void) vsnprintf(message
, sizeof (message
), a_format
, ap
);
377 /* pass message to registered function */
379 (_z_global_data
._z_progerr
)(MSG_PROG_ERR
, message
);
383 * Name: _z_running_in_global_zone
384 * Synopsis: Determine if this process is running in the global zone
387 * == B_TRUE - this process is running in the global zone
388 * == B_FALSE - this process is running in a nonglobal zone
392 _z_running_in_global_zone(void)
394 zoneid_t zoneid
= (zoneid_t
)-1;
397 * if zones are not implemented, there is no way to tell if zones
398 * are supported or not - in this case, we can only be running in the
399 * global zone (since non-global zones cannot exist) so return TRUE
402 if (z_zones_are_implemented() == B_FALSE
) {
406 /* get the zone i.d. of the current zone */
408 zoneid
= getzoneid();
410 /* return TRUE if this is the global zone i.d. */
412 if (zoneid
== GLOBAL_ZONEID
) {
416 /* return FALSE - not in the global zone */
422 * Name: _z_zones_are_implemented
423 * Synopsis: Determine if zones are supported by the current system
426 * == B_TRUE - zones are supported
427 * == B_FALSE - zones are not supported
431 _z_zones_are_implemented(void)
435 /* locate zone cfg library */
437 libptr
= dlopen(ZONECFG_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
438 if (libptr
== (void *)NULL
) {
439 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, ZONECFG_LIBRARY
, dlerror());
440 libptr
= dlopen(ZONECFG1_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
443 /* return false if library not available */
445 if (libptr
== (void *)NULL
) {
446 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, ZONECFG1_LIBRARY
,
451 /* library available - close handle */
453 (void) dlclose(libptr
);
455 /* locate contract filesystem library */
457 libptr
= dlopen(CONTRACT_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
458 if (libptr
== (void *)NULL
) {
459 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, CONTRACT_LIBRARY
,
461 libptr
= dlopen(CONTRACT1_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
464 /* return false if library not available */
466 if (libptr
== (void *)NULL
) {
467 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, CONTRACT1_LIBRARY
,
472 /* library available - close handle */
474 (void) dlclose(libptr
);
482 _z_brands_are_implemented(void)
486 /* locate brand library */
488 libptr
= dlopen(BRAND_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
489 if (libptr
== NULL
) {
490 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, BRAND_LIBRARY
, dlerror());
491 libptr
= dlopen(BRAND1_LIBRARY
, RTLD_NOW
|RTLD_GLOBAL
);
494 /* return false if library not available */
496 if (libptr
== NULL
) {
497 _z_echoDebug(DBG_LIBRARY_NOT_FOUND
, BRAND1_LIBRARY
, dlerror());
501 /* library available - close handle */
503 (void) dlclose(libptr
);
512 * Allocate 'size' bytes from the heap using calloc()
514 * size - number of bytes to allocate
516 * NULL - calloc() failure
517 * void * - pointer to allocated structure
522 _z_calloc(size_t size
)
526 if ((tmp
= (void *) malloc(size
)) == NULL
) {
527 fatal_err_func(ERR_MALLOC_FAIL
);
531 (void) memset(tmp
, 0, size
);
537 * Alloc 'size' bytes from heap using malloc()
539 * size - number of bytes to malloc
541 * NULL - malloc() failure
542 * void * - pointer to allocated structure
547 _z_malloc(size_t size
)
551 if ((tmp
= (void *) malloc(size
)) == NULL
) {
552 fatal_err_func(ERR_MALLOC_FAIL
);
560 * Calls realloc() with the specfied parameters. _z_realloc()
561 * checks for realloc failures and adjusts the return value
564 * ptr - pointer to existing data block
565 * size - number of bytes additional
567 * NULL - realloc() failed
568 * void * - pointer to realloc'd structured
573 _z_realloc(void *ptr
, size_t size
)
577 if ((tmp
= (void *)realloc(ptr
, size
)) == (void *)NULL
) {
578 fatal_err_func(ERR_MALLOC_FAIL
);
579 return ((void *)NULL
);
586 * Allocate space for the string from the heap, copy 'str' into it,
587 * and return a pointer to it.
589 * str - string to duplicate
591 * NULL - duplication failed or 'str' was NULL
592 * char * - pointer to newly allocated/initialized structure
602 return ((char *)NULL
);
604 if ((tmp
= strdup(str
)) == NULL
) {
605 fatal_err_func(ERR_MALLOC_FAIL
);
606 return ((char *)NULL
);