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 * Program: pkgcond 30*5c51f124SMoriah Waterland * 31*5c51f124SMoriah Waterland * Function: Implements the package command suite public utility pkgcond(1M) 32*5c51f124SMoriah Waterland * 33*5c51f124SMoriah Waterland * Usage: pkgcond [-nv] [-O debug] condition [ argument ] 34*5c51f124SMoriah Waterland * 35*5c51f124SMoriah Waterland * command options: 36*5c51f124SMoriah Waterland * -n - negate results of condition test 37*5c51f124SMoriah Waterland * -v - verbose output of condition testing 38*5c51f124SMoriah Waterland * 39*5c51f124SMoriah Waterland * <condition> may be any one of: 40*5c51f124SMoriah Waterland * can_add_driver [path] 41*5c51f124SMoriah Waterland * can_remove_driver [path] 42*5c51f124SMoriah Waterland * can_update_driver [path] 43*5c51f124SMoriah Waterland * is_alternative_root [path] 44*5c51f124SMoriah Waterland * is_boot_environment [path] 45*5c51f124SMoriah Waterland * is_diskless_client [path] 46*5c51f124SMoriah Waterland * is_global_zone [path] 47*5c51f124SMoriah Waterland * is_mounted_miniroot [path] 48*5c51f124SMoriah Waterland * is_netinstall_image [path] 49*5c51f124SMoriah Waterland * is_nonglobal_zone [path] 50*5c51f124SMoriah Waterland * is_path_writable path 51*5c51f124SMoriah Waterland * is_running_system [path] 52*5c51f124SMoriah Waterland * is_sparse_root_nonglobal_zone [path] 53*5c51f124SMoriah Waterland * is_what [path] 54*5c51f124SMoriah Waterland * is_whole_root_nonglobal_zone [path] 55*5c51f124SMoriah Waterland * 56*5c51f124SMoriah Waterland * <option(s)> are specific to the condition used 57*5c51f124SMoriah Waterland * 58*5c51f124SMoriah Waterland * Input: depends on command 59*5c51f124SMoriah Waterland * 60*5c51f124SMoriah Waterland * Output: depends on command 61*5c51f124SMoriah Waterland * 62*5c51f124SMoriah Waterland * Exit status: If the -n option is not specified: 63*5c51f124SMoriah Waterland * == 0 - the specified condition is true (or exists). 64*5c51f124SMoriah Waterland * == 1 - the specified condition is false (or does not exist). 65*5c51f124SMoriah Waterland * == 2 - command line usage errors (including bad keywords) 66*5c51f124SMoriah Waterland * == 3 - command failed to perform the test due to a fatal error 67*5c51f124SMoriah Waterland * 68*5c51f124SMoriah Waterland * If the -n option is specified: 69*5c51f124SMoriah Waterland * == 0 - the specified condition is false (or does not exist). 70*5c51f124SMoriah Waterland * == 1 - the specified condition is true (or exists). 71*5c51f124SMoriah Waterland * == 2 - command line usage errors (including bad keywords) 72*5c51f124SMoriah Waterland * == 3 - command failed to perform the test due to a fatal error 73*5c51f124SMoriah Waterland */ 74*5c51f124SMoriah Waterland 75*5c51f124SMoriah Waterland #include <stdio.h> 76*5c51f124SMoriah Waterland #include <sys/mnttab.h> 77*5c51f124SMoriah Waterland #include <sys/mntent.h> 78*5c51f124SMoriah Waterland #include <stdarg.h> 79*5c51f124SMoriah Waterland #include <stdlib.h> 80*5c51f124SMoriah Waterland #include <string.h> 81*5c51f124SMoriah Waterland #include <strings.h> 82*5c51f124SMoriah Waterland #include <fcntl.h> 83*5c51f124SMoriah Waterland #include <ctype.h> 84*5c51f124SMoriah Waterland #include <sys/types.h> 85*5c51f124SMoriah Waterland #include <sys/stat.h> 86*5c51f124SMoriah Waterland #include <unistd.h> 87*5c51f124SMoriah Waterland #include <locale.h> 88*5c51f124SMoriah Waterland #include <errno.h> 89*5c51f124SMoriah Waterland #include <sys/param.h> 90*5c51f124SMoriah Waterland #include <assert.h> 91*5c51f124SMoriah Waterland 92*5c51f124SMoriah Waterland #include <instzones_api.h> 93*5c51f124SMoriah Waterland #include <pkglib.h> 94*5c51f124SMoriah Waterland #include <install.h> 95*5c51f124SMoriah Waterland #include <libinst.h> 96*5c51f124SMoriah Waterland #include <libadm.h> 97*5c51f124SMoriah Waterland #include <messages.h> 98*5c51f124SMoriah Waterland #include "pkgcond.h" 99*5c51f124SMoriah Waterland #include "pkgcond_msgs.h" 100*5c51f124SMoriah Waterland 101*5c51f124SMoriah Waterland /* Should be defined by cc -D */ 102*5c51f124SMoriah Waterland 103*5c51f124SMoriah Waterland #if !defined(TEXT_DOMAIN) 104*5c51f124SMoriah Waterland #define TEXT_DOMAIN "SYS_TEST" 105*5c51f124SMoriah Waterland #endif 106*5c51f124SMoriah Waterland 107*5c51f124SMoriah Waterland /* commands to execute */ 108*5c51f124SMoriah Waterland 109*5c51f124SMoriah Waterland #define LS_CMD "/usr/bin/ls" 110*5c51f124SMoriah Waterland 111*5c51f124SMoriah Waterland /* 112*5c51f124SMoriah Waterland * type definition and "types" for testPath() 113*5c51f124SMoriah Waterland */ 114*5c51f124SMoriah Waterland 115*5c51f124SMoriah Waterland typedef enum { 116*5c51f124SMoriah Waterland TEST_EXISTS = 0x01, 117*5c51f124SMoriah Waterland TEST_NOT_EXISTS = 0x02, 118*5c51f124SMoriah Waterland TEST_IS_DIRECTORY = 0x04, 119*5c51f124SMoriah Waterland TEST_IS_FILE = 0x08, 120*5c51f124SMoriah Waterland TEST_NOT_DIRECTORY = 0x10, 121*5c51f124SMoriah Waterland TEST_NOT_FILE = 0x20, 122*5c51f124SMoriah Waterland TEST_IS_SYMBOLIC_LINK = 0x40, 123*5c51f124SMoriah Waterland TEST_NOT_SYMBOLIC_LINK = 0x80, 124*5c51f124SMoriah Waterland TEST_GLOBAL_TOKEN_IN_FILE = 0x100 125*5c51f124SMoriah Waterland } TEST_TYPES; 126*5c51f124SMoriah Waterland 127*5c51f124SMoriah Waterland /* holds file system info */ 128*5c51f124SMoriah Waterland 129*5c51f124SMoriah Waterland struct fsi_t { 130*5c51f124SMoriah Waterland char *fsi_mntOptions; 131*5c51f124SMoriah Waterland char *fsi_fsType; 132*5c51f124SMoriah Waterland char *fsi_mntPoint; 133*5c51f124SMoriah Waterland }; 134*5c51f124SMoriah Waterland typedef struct fsi_t FSI_T; 135*5c51f124SMoriah Waterland 136*5c51f124SMoriah Waterland /* holds parsed global data */ 137*5c51f124SMoriah Waterland 138*5c51f124SMoriah Waterland struct globalData_t { 139*5c51f124SMoriah Waterland /* sparse root (are any file systems mounted read-only)? */ 140*5c51f124SMoriah Waterland boolean_t gd_srFsMountedRO; 141*5c51f124SMoriah Waterland /* initial install: PKG_INIT_INSTALL=true */ 142*5c51f124SMoriah Waterland boolean_t gd_initialInstall; 143*5c51f124SMoriah Waterland /* global zone install: SUNW_PKG_INSTALL_ZONENAME=global */ 144*5c51f124SMoriah Waterland boolean_t gd_globalZoneInstall; 145*5c51f124SMoriah Waterland /* non-global zone install: SUNW_PKG_INSTALL_ZONENAME!=global */ 146*5c51f124SMoriah Waterland boolean_t gd_nonglobalZoneInstall; 147*5c51f124SMoriah Waterland /* non-global zone is in a mounted state */ 148*5c51f124SMoriah Waterland boolean_t inMountedState; 149*5c51f124SMoriah Waterland /* sorted list of all mounted file systems */ 150*5c51f124SMoriah Waterland FSI_T *gd_fileSystemConfig; 151*5c51f124SMoriah Waterland /* number of mounted file systems in list */ 152*5c51f124SMoriah Waterland long gd_fileSystemConfigLen; 153*5c51f124SMoriah Waterland /* current zone name */ 154*5c51f124SMoriah Waterland char *gd_zoneName; 155*5c51f124SMoriah Waterland /* version of target: PATCH_CLIENT_VERSION */ 156*5c51f124SMoriah Waterland char *gd_patchClientVersion; 157*5c51f124SMoriah Waterland /* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneName */ 158*5c51f124SMoriah Waterland char *gd_parentZoneName; 159*5c51f124SMoriah Waterland /* SUNW_PKGCOND_GLOBAL_DATA:parentZone:zoneType */ 160*5c51f124SMoriah Waterland char *gd_parentZoneType; 161*5c51f124SMoriah Waterland /* root path to target: PKG_INSTALL_ROOT */ 162*5c51f124SMoriah Waterland char *gd_installRoot; 163*5c51f124SMoriah Waterland /* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneName */ 164*5c51f124SMoriah Waterland char *gd_currentZoneName; 165*5c51f124SMoriah Waterland /* SUNW_PKGCOND_GLOBAL_DATA:currentZone:zoneType */ 166*5c51f124SMoriah Waterland char *gd_currentZoneType; 167*5c51f124SMoriah Waterland /* list of inherited file systems */ 168*5c51f124SMoriah Waterland char **gd_inheritedFileSystems; 169*5c51f124SMoriah Waterland /* path provided on command line */ 170*5c51f124SMoriah Waterland char *gd_cmdline_path; 171*5c51f124SMoriah Waterland }; 172*5c51f124SMoriah Waterland typedef struct globalData_t GLOBALDATA_T; 173*5c51f124SMoriah Waterland 174*5c51f124SMoriah Waterland /* holds subcommands and their definitions */ 175*5c51f124SMoriah Waterland 176*5c51f124SMoriah Waterland struct cmd_t { 177*5c51f124SMoriah Waterland char *c_name; 178*5c51f124SMoriah Waterland char *c_args; 179*5c51f124SMoriah Waterland int (*c_func)(int argc, char **argv, GLOBALDATA_T *a_gdt); 180*5c51f124SMoriah Waterland }; 181*5c51f124SMoriah Waterland typedef struct cmd_t CMD_T; 182*5c51f124SMoriah Waterland 183*5c51f124SMoriah Waterland /* Command function prototypes */ 184*5c51f124SMoriah Waterland 185*5c51f124SMoriah Waterland static int cmd_can_add_driver(int argc, char **argv, 186*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 187*5c51f124SMoriah Waterland static int cmd_can_remove_driver(int argc, char **argv, 188*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 189*5c51f124SMoriah Waterland static int cmd_can_update_driver(int argc, char **argv, 190*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 191*5c51f124SMoriah Waterland static int cmd_is_alternative_root(int argc, char **argv, 192*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 193*5c51f124SMoriah Waterland static int cmd_is_boot_environment(int argc, char **argv, 194*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 195*5c51f124SMoriah Waterland static int cmd_is_diskless_client(int argc, char **argv, 196*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 197*5c51f124SMoriah Waterland static int cmd_is_global_zone(int argc, char **argv, 198*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 199*5c51f124SMoriah Waterland static int cmd_is_mounted_miniroot(int argc, char **argv, 200*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 201*5c51f124SMoriah Waterland static int cmd_is_netinstall_image(int argc, char **argv, 202*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 203*5c51f124SMoriah Waterland static int cmd_is_nonglobal_zone(int argc, char **argv, 204*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 205*5c51f124SMoriah Waterland static int cmd_is_path_writable(int argc, char **argv, 206*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 207*5c51f124SMoriah Waterland static int cmd_is_running_system(int argc, char **argv, 208*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 209*5c51f124SMoriah Waterland static int cmd_is_sparse_root_ng_zone(int argc, char **argv, 210*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 211*5c51f124SMoriah Waterland static int cmd_is_what(int argc, char **argv, 212*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 213*5c51f124SMoriah Waterland static int cmd_is_whole_root_ng_zone(int argc, char **argv, 214*5c51f124SMoriah Waterland GLOBALDATA_T *a_gdt); 215*5c51f124SMoriah Waterland 216*5c51f124SMoriah Waterland /* Utility function Prototypes */ 217*5c51f124SMoriah Waterland 218*5c51f124SMoriah Waterland static boolean_t getNegateResults(void); 219*5c51f124SMoriah Waterland static boolean_t recursionCheck(int *r_recursion, char *a_function); 220*5c51f124SMoriah Waterland static boolean_t checkForReadOnlyMount(GLOBALDATA_T *a_gdt, 221*5c51f124SMoriah Waterland char *a_mntPoint, char *a_fsType, char *a_mntOptions); 222*5c51f124SMoriah Waterland static int adjustResults(int a_result); 223*5c51f124SMoriah Waterland static int calculateFileSystemConfig(GLOBALDATA_T *a_gdt); 224*5c51f124SMoriah Waterland static int getRootPath(char **r_rootPath); 225*5c51f124SMoriah Waterland static int getZoneName(char **r_zoneName); 226*5c51f124SMoriah Waterland static int mountOptionPresent(char *a_mntOptions, char *a_opt); 227*5c51f124SMoriah Waterland static int parseGlobalData(char *a_envVar, GLOBALDATA_T **a_gdt); 228*5c51f124SMoriah Waterland static int resolvePath(char **r_path); 229*5c51f124SMoriah Waterland static int setRootPath(char *a_path, char *a_envVar, 230*5c51f124SMoriah Waterland boolean_t a_mustExist); 231*5c51f124SMoriah Waterland static int testPath(TEST_TYPES a_tt, char *format, ...); 232*5c51f124SMoriah Waterland static int usage(char *a_format, ...); 233*5c51f124SMoriah Waterland static int findToken(char *path, char *token); 234*5c51f124SMoriah Waterland static char *getMountOption(char **p); 235*5c51f124SMoriah Waterland static void dumpGlobalData(GLOBALDATA_T *a_gdt); 236*5c51f124SMoriah Waterland static void removeLeadingWhitespace(char **a_str); 237*5c51f124SMoriah Waterland static void setNegateResults(boolean_t setting); 238*5c51f124SMoriah Waterland static void setVerbose(boolean_t); 239*5c51f124SMoriah Waterland static void sortedInsert(FSI_T **r_list, long *a_listSize, 240*5c51f124SMoriah Waterland char *a_mntPoint, char *a_fsType, char *a_mntOptions); 241*5c51f124SMoriah Waterland static void setCmdLinePath(char **a_path, char **args, 242*5c51f124SMoriah Waterland int num_args); 243*5c51f124SMoriah Waterland 244*5c51f124SMoriah Waterland /* local static data */ 245*5c51f124SMoriah Waterland 246*5c51f124SMoriah Waterland static boolean_t _negateResults = B_FALSE; 247*5c51f124SMoriah Waterland static char *_rootPath = "/"; 248*5c51f124SMoriah Waterland 249*5c51f124SMoriah Waterland /* define subcommand data structure */ 250*5c51f124SMoriah Waterland 251*5c51f124SMoriah Waterland static CMD_T cmds[] = { 252*5c51f124SMoriah Waterland { "can_add_driver", " [path]", 253*5c51f124SMoriah Waterland cmd_can_add_driver }, 254*5c51f124SMoriah Waterland { "can_remove_driver", " [path]", 255*5c51f124SMoriah Waterland cmd_can_remove_driver }, 256*5c51f124SMoriah Waterland { "can_update_driver", " [path]", 257*5c51f124SMoriah Waterland cmd_can_update_driver }, 258*5c51f124SMoriah Waterland { "is_alternative_root", " [path]", 259*5c51f124SMoriah Waterland cmd_is_alternative_root }, 260*5c51f124SMoriah Waterland { "is_boot_environment", " [path]", 261*5c51f124SMoriah Waterland cmd_is_boot_environment }, 262*5c51f124SMoriah Waterland { "is_diskless_client", " [path]", 263*5c51f124SMoriah Waterland cmd_is_diskless_client }, 264*5c51f124SMoriah Waterland { "is_global_zone", " [path]", 265*5c51f124SMoriah Waterland cmd_is_global_zone }, 266*5c51f124SMoriah Waterland { "is_mounted_miniroot", " [path]", 267*5c51f124SMoriah Waterland cmd_is_mounted_miniroot }, 268*5c51f124SMoriah Waterland { "is_netinstall_image", " [path]", 269*5c51f124SMoriah Waterland cmd_is_netinstall_image }, 270*5c51f124SMoriah Waterland { "is_nonglobal_zone", " [path]", 271*5c51f124SMoriah Waterland cmd_is_nonglobal_zone }, 272*5c51f124SMoriah Waterland { "is_path_writable", " path", 273*5c51f124SMoriah Waterland cmd_is_path_writable }, 274*5c51f124SMoriah Waterland { "is_running_system", " [path]", 275*5c51f124SMoriah Waterland cmd_is_running_system }, 276*5c51f124SMoriah Waterland { "is_sparse_root_nonglobal_zone", " [path]", 277*5c51f124SMoriah Waterland cmd_is_sparse_root_ng_zone }, 278*5c51f124SMoriah Waterland { "is_what", " [path]", 279*5c51f124SMoriah Waterland cmd_is_what }, 280*5c51f124SMoriah Waterland { "is_whole_root_nonglobal_zone", " [path]", 281*5c51f124SMoriah Waterland cmd_is_whole_root_ng_zone }, 282*5c51f124SMoriah Waterland /* last one must be all NULLs */ 283*5c51f124SMoriah Waterland { NULL, NULL } 284*5c51f124SMoriah Waterland }; 285*5c51f124SMoriah Waterland 286*5c51f124SMoriah Waterland /* 287*5c51f124SMoriah Waterland * ***************************************************************************** 288*5c51f124SMoriah Waterland * main 289*5c51f124SMoriah Waterland * ***************************************************************************** 290*5c51f124SMoriah Waterland */ 291*5c51f124SMoriah Waterland 292*5c51f124SMoriah Waterland /* 293*5c51f124SMoriah Waterland * Name: main 294*5c51f124SMoriah Waterland * Description: main processing loop for pkgcond * 295*5c51f124SMoriah Waterland * Return: 0 - condition is satisfied (true) 296*5c51f124SMoriah Waterland * 1 - condition is not satisfied (false) 297*5c51f124SMoriah Waterland * 2 - command line usage errors 298*5c51f124SMoriah Waterland * 3 - failure to determine condition 299*5c51f124SMoriah Waterland */ 300*5c51f124SMoriah Waterland 301*5c51f124SMoriah Waterland int 302*5c51f124SMoriah Waterland main(int argc, char **argv) 303*5c51f124SMoriah Waterland { 304*5c51f124SMoriah Waterland GLOBALDATA_T *gdt = NULL; 305*5c51f124SMoriah Waterland char **newargv; 306*5c51f124SMoriah Waterland char *p; 307*5c51f124SMoriah Waterland int cur_cmd; 308*5c51f124SMoriah Waterland int i; 309*5c51f124SMoriah Waterland int newargc; 310*5c51f124SMoriah Waterland 311*5c51f124SMoriah Waterland /* make standard output non-buffered */ 312*5c51f124SMoriah Waterland 313*5c51f124SMoriah Waterland setbuf(stdout, NULL); 314*5c51f124SMoriah Waterland 315*5c51f124SMoriah Waterland /* set the default text domain for messaging */ 316*5c51f124SMoriah Waterland 317*5c51f124SMoriah Waterland (void) setlocale(LC_ALL, ""); 318*5c51f124SMoriah Waterland (void) textdomain(TEXT_DOMAIN); 319*5c51f124SMoriah Waterland 320*5c51f124SMoriah Waterland /* remember command name */ 321*5c51f124SMoriah Waterland 322*5c51f124SMoriah Waterland set_prog_name(argv[0]); 323*5c51f124SMoriah Waterland 324*5c51f124SMoriah Waterland /* tell spmi zones interface how to access package output functions */ 325*5c51f124SMoriah Waterland 326*5c51f124SMoriah Waterland z_set_output_functions(echo, echoDebug, progerr); 327*5c51f124SMoriah Waterland 328*5c51f124SMoriah Waterland /* set verbose mode if appropriate environment variable is set */ 329*5c51f124SMoriah Waterland 330*5c51f124SMoriah Waterland if (getenv(ENV_VAR_VERBOSE)) { 331*5c51f124SMoriah Waterland /* same as -v */ 332*5c51f124SMoriah Waterland setVerbose(B_TRUE); 333*5c51f124SMoriah Waterland } 334*5c51f124SMoriah Waterland 335*5c51f124SMoriah Waterland /* set debug mode if appropriate environment variable is set */ 336*5c51f124SMoriah Waterland 337*5c51f124SMoriah Waterland if (getenv(ENV_VAR_DEBUG)) { 338*5c51f124SMoriah Waterland /* same as -O debug */ 339*5c51f124SMoriah Waterland 340*5c51f124SMoriah Waterland /* set sml tracing (sml.c) */ 341*5c51f124SMoriah Waterland smlSetVerbose(B_TRUE); 342*5c51f124SMoriah Waterland 343*5c51f124SMoriah Waterland /* set log and echo (interactive) message tracing */ 344*5c51f124SMoriah Waterland setVerbose(B_TRUE); 345*5c51f124SMoriah Waterland 346*5c51f124SMoriah Waterland /* enable echoDebug debugging messages */ 347*5c51f124SMoriah Waterland echoDebugSetFlag(B_TRUE); 348*5c51f124SMoriah Waterland } 349*5c51f124SMoriah Waterland 350*5c51f124SMoriah Waterland /* generate usage if no options or arguments specified */ 351*5c51f124SMoriah Waterland 352*5c51f124SMoriah Waterland if (argc <= 1) { 353*5c51f124SMoriah Waterland (void) usage(MSG_NO_ARGUMENTS_SPECIFIED); 354*5c51f124SMoriah Waterland return (R_USAGE); 355*5c51f124SMoriah Waterland } 356*5c51f124SMoriah Waterland 357*5c51f124SMoriah Waterland /* 358*5c51f124SMoriah Waterland * process any arguments that can appear before the subcommand 359*5c51f124SMoriah Waterland */ 360*5c51f124SMoriah Waterland 361*5c51f124SMoriah Waterland while ((i = getopt(argc, argv, ":O:vn?")) != EOF) { 362*5c51f124SMoriah Waterland switch (i) { 363*5c51f124SMoriah Waterland /* 364*5c51f124SMoriah Waterland * Not a public interface: the -O option allows the behavior 365*5c51f124SMoriah Waterland * of the package tools to be modified. Recognized options: 366*5c51f124SMoriah Waterland * -> debug 367*5c51f124SMoriah Waterland * ---> enable debugging output 368*5c51f124SMoriah Waterland */ 369*5c51f124SMoriah Waterland 370*5c51f124SMoriah Waterland case 'O': 371*5c51f124SMoriah Waterland for (p = strtok(optarg, ","); p != NULL; 372*5c51f124SMoriah Waterland p = strtok(NULL, ",")) { 373*5c51f124SMoriah Waterland 374*5c51f124SMoriah Waterland /* debug - enable all tracing */ 375*5c51f124SMoriah Waterland 376*5c51f124SMoriah Waterland if (strcmp(p, "debug") == 0) { 377*5c51f124SMoriah Waterland /* set sml tracing */ 378*5c51f124SMoriah Waterland smlSetVerbose(B_TRUE); 379*5c51f124SMoriah Waterland /* set log/echo tracing */ 380*5c51f124SMoriah Waterland setVerbose(B_TRUE); 381*5c51f124SMoriah Waterland /* enable debugging messages */ 382*5c51f124SMoriah Waterland echoDebugSetFlag(B_TRUE); 383*5c51f124SMoriah Waterland continue; 384*5c51f124SMoriah Waterland } 385*5c51f124SMoriah Waterland 386*5c51f124SMoriah Waterland progerr(ERR_INVALID_O_OPTION, p); 387*5c51f124SMoriah Waterland return (adjustResults(R_USAGE)); 388*5c51f124SMoriah Waterland } 389*5c51f124SMoriah Waterland break; 390*5c51f124SMoriah Waterland 391*5c51f124SMoriah Waterland /* 392*5c51f124SMoriah Waterland * Public interface: enable verbose (debug) output. 393*5c51f124SMoriah Waterland */ 394*5c51f124SMoriah Waterland 395*5c51f124SMoriah Waterland case 'v': /* verbose mode enabled */ 396*5c51f124SMoriah Waterland /* set command tracing only */ 397*5c51f124SMoriah Waterland setVerbose(B_TRUE); 398*5c51f124SMoriah Waterland break; 399*5c51f124SMoriah Waterland 400*5c51f124SMoriah Waterland /* 401*5c51f124SMoriah Waterland * Public interface: negate output results. 402*5c51f124SMoriah Waterland */ 403*5c51f124SMoriah Waterland 404*5c51f124SMoriah Waterland case 'n': 405*5c51f124SMoriah Waterland setNegateResults(B_TRUE); 406*5c51f124SMoriah Waterland break; 407*5c51f124SMoriah Waterland 408*5c51f124SMoriah Waterland /* 409*5c51f124SMoriah Waterland * unrecognized option 410*5c51f124SMoriah Waterland */ 411*5c51f124SMoriah Waterland 412*5c51f124SMoriah Waterland case '?': 413*5c51f124SMoriah Waterland default: 414*5c51f124SMoriah Waterland (void) usage(MSG_INVALID_OPTION_SPECIFIED, optopt); 415*5c51f124SMoriah Waterland return (R_USAGE); 416*5c51f124SMoriah Waterland } 417*5c51f124SMoriah Waterland } 418*5c51f124SMoriah Waterland 419*5c51f124SMoriah Waterland /* 420*5c51f124SMoriah Waterland * done processing options that can preceed subcommand 421*5c51f124SMoriah Waterland */ 422*5c51f124SMoriah Waterland 423*5c51f124SMoriah Waterland /* error if no subcommand specified */ 424*5c51f124SMoriah Waterland 425*5c51f124SMoriah Waterland if ((argc-optind) <= 0) { 426*5c51f124SMoriah Waterland (void) usage(MSG_NO_ARGUMENTS_SPECIFIED); 427*5c51f124SMoriah Waterland return (R_USAGE); 428*5c51f124SMoriah Waterland } 429*5c51f124SMoriah Waterland 430*5c51f124SMoriah Waterland /* parse global data if environment variable set */ 431*5c51f124SMoriah Waterland 432*5c51f124SMoriah Waterland if (parseGlobalData(PKGCOND_GLOBAL_VARIABLE, &gdt) != R_SUCCESS) { 433*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_CANNOT_USE_GLOBAL_DATA, 434*5c51f124SMoriah Waterland PKGCOND_GLOBAL_VARIABLE); 435*5c51f124SMoriah Waterland return (R_ERROR); 436*5c51f124SMoriah Waterland } 437*5c51f124SMoriah Waterland 438*5c51f124SMoriah Waterland if (setRootPath(gdt->gd_installRoot, 439*5c51f124SMoriah Waterland (strcmp(gdt->gd_installRoot, "/") == 0) ? NULL : 440*5c51f124SMoriah Waterland ENV_VAR_SET, B_TRUE) != R_SUCCESS) { 441*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_CANNOT_SET_ROOT_PATH, 442*5c51f124SMoriah Waterland ENV_VAR_PKGROOT); 443*5c51f124SMoriah Waterland return (R_ERROR); 444*5c51f124SMoriah Waterland } 445*5c51f124SMoriah Waterland 446*5c51f124SMoriah Waterland /* set path provided on the command line */ 447*5c51f124SMoriah Waterland 448*5c51f124SMoriah Waterland setCmdLinePath(&(gdt->gd_cmdline_path), argv, argc); 449*5c51f124SMoriah Waterland echoDebug(DBG_CMDLINE_PATH, 450*5c51f124SMoriah Waterland gdt->gd_cmdline_path == NULL ? "" : gdt->gd_cmdline_path); 451*5c51f124SMoriah Waterland 452*5c51f124SMoriah Waterland /* determine how file systems are layered in this zone */ 453*5c51f124SMoriah Waterland 454*5c51f124SMoriah Waterland if (calculateFileSystemConfig(gdt) != R_SUCCESS) { 455*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_CANNOT_CALC_FS_CONFIG); 456*5c51f124SMoriah Waterland return (R_ERROR); 457*5c51f124SMoriah Waterland } 458*5c51f124SMoriah Waterland 459*5c51f124SMoriah Waterland /* dump global data read in (only if debugging) */ 460*5c51f124SMoriah Waterland 461*5c51f124SMoriah Waterland dumpGlobalData(gdt); 462*5c51f124SMoriah Waterland 463*5c51f124SMoriah Waterland /* search for specified subcommand and execute if found */ 464*5c51f124SMoriah Waterland 465*5c51f124SMoriah Waterland for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) { 466*5c51f124SMoriah Waterland if (ci_streq(argv[optind], cmds[cur_cmd].c_name)) { 467*5c51f124SMoriah Waterland int result; 468*5c51f124SMoriah Waterland 469*5c51f124SMoriah Waterland /* make subcommand the first option */ 470*5c51f124SMoriah Waterland 471*5c51f124SMoriah Waterland newargc = argc - optind; 472*5c51f124SMoriah Waterland newargv = argv + optind; 473*5c51f124SMoriah Waterland opterr = optind = 1; optopt = 0; 474*5c51f124SMoriah Waterland 475*5c51f124SMoriah Waterland 476*5c51f124SMoriah Waterland /* call subcommand with its own argc/argv */ 477*5c51f124SMoriah Waterland 478*5c51f124SMoriah Waterland result = cmds[cur_cmd].c_func(newargc, newargv, gdt); 479*5c51f124SMoriah Waterland 480*5c51f124SMoriah Waterland /* process result code and exit */ 481*5c51f124SMoriah Waterland 482*5c51f124SMoriah Waterland result = adjustResults(result); 483*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_RESULTS, result); 484*5c51f124SMoriah Waterland return (result); 485*5c51f124SMoriah Waterland } 486*5c51f124SMoriah Waterland } 487*5c51f124SMoriah Waterland 488*5c51f124SMoriah Waterland /* subcommand not found - output error message and exit with error */ 489*5c51f124SMoriah Waterland 490*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_BAD_SUB, argv[optind]); 491*5c51f124SMoriah Waterland (void) usage(MSG_UNRECOGNIZED_CONDITION_SPECIFIED); 492*5c51f124SMoriah Waterland return (R_USAGE); 493*5c51f124SMoriah Waterland } 494*5c51f124SMoriah Waterland 495*5c51f124SMoriah Waterland /* 496*5c51f124SMoriah Waterland * ***************************************************************************** 497*5c51f124SMoriah Waterland * command implementation functions 498*5c51f124SMoriah Waterland * ***************************************************************************** 499*5c51f124SMoriah Waterland */ 500*5c51f124SMoriah Waterland 501*5c51f124SMoriah Waterland /* 502*5c51f124SMoriah Waterland * Name: cmd_is_diskless_client 503*5c51f124SMoriah Waterland * Description: determine if target is a diskless client 504*5c51f124SMoriah Waterland * Scope: public 505*5c51f124SMoriah Waterland * Arguments: argc,argv: 506*5c51f124SMoriah Waterland * - optional path to target to test 507*5c51f124SMoriah Waterland * Returns: int 508*5c51f124SMoriah Waterland * == 0 - success 509*5c51f124SMoriah Waterland * != 0 - failure 510*5c51f124SMoriah Waterland * IMPLEMENTATION: 511*5c51f124SMoriah Waterland * - must not be initial installation to the install root 512*5c51f124SMoriah Waterland * - must not be installation of a zone 513*5c51f124SMoriah Waterland * - must not be a whole root non-global zone 514*5c51f124SMoriah Waterland * - must not be a non-global zone 515*5c51f124SMoriah Waterland * - must not be a mounted mini-root 516*5c51f124SMoriah Waterland * - must not be a netinstall image 517*5c51f124SMoriah Waterland * - must not be a boot environment 518*5c51f124SMoriah Waterland * - The package "SUNWdclnt" must be installed at "/" 519*5c51f124SMoriah Waterland * - The root path must not be "/" 520*5c51f124SMoriah Waterland * - The path "/export/exec/Solaris_\*\/usr" must exist at "/" 521*5c51f124SMoriah Waterland * - The directory "$ROOTDIR/../templates" must exist 522*5c51f124SMoriah Waterland */ 523*5c51f124SMoriah Waterland 524*5c51f124SMoriah Waterland static int 525*5c51f124SMoriah Waterland cmd_is_diskless_client(int argc, char **argv, GLOBALDATA_T *a_gdt) 526*5c51f124SMoriah Waterland { 527*5c51f124SMoriah Waterland char *rootPath = NULL; 528*5c51f124SMoriah Waterland char cmd[MAXPATHLEN+1]; 529*5c51f124SMoriah Waterland int c; 530*5c51f124SMoriah Waterland int r; 531*5c51f124SMoriah Waterland int rc; 532*5c51f124SMoriah Waterland static char *cmdName = "is_diskless_client"; 533*5c51f124SMoriah Waterland static int recursion = 0; 534*5c51f124SMoriah Waterland 535*5c51f124SMoriah Waterland /* process any command line options */ 536*5c51f124SMoriah Waterland 537*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 538*5c51f124SMoriah Waterland switch (c) { 539*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 540*5c51f124SMoriah Waterland break; 541*5c51f124SMoriah Waterland case '?': 542*5c51f124SMoriah Waterland default: 543*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 544*5c51f124SMoriah Waterland return (R_USAGE); 545*5c51f124SMoriah Waterland } 546*5c51f124SMoriah Waterland } 547*5c51f124SMoriah Waterland 548*5c51f124SMoriah Waterland /* prevent recursion */ 549*5c51f124SMoriah Waterland 550*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 551*5c51f124SMoriah Waterland 552*5c51f124SMoriah Waterland /* 553*5c51f124SMoriah Waterland * a diskless client cannot be any of the following 554*5c51f124SMoriah Waterland */ 555*5c51f124SMoriah Waterland 556*5c51f124SMoriah Waterland /* cannot be whole root non-global zone */ 557*5c51f124SMoriah Waterland 558*5c51f124SMoriah Waterland r = cmd_is_whole_root_ng_zone(argc, argv, a_gdt); 559*5c51f124SMoriah Waterland 560*5c51f124SMoriah Waterland /* cannot be nonglobal zone */ 561*5c51f124SMoriah Waterland 562*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 563*5c51f124SMoriah Waterland r = cmd_is_nonglobal_zone(argc, argv, a_gdt); 564*5c51f124SMoriah Waterland } 565*5c51f124SMoriah Waterland 566*5c51f124SMoriah Waterland /* cannot be mounted miniroot */ 567*5c51f124SMoriah Waterland 568*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 569*5c51f124SMoriah Waterland r = cmd_is_mounted_miniroot(argc, argv, a_gdt); 570*5c51f124SMoriah Waterland } 571*5c51f124SMoriah Waterland 572*5c51f124SMoriah Waterland /* cannot be a netinstall image */ 573*5c51f124SMoriah Waterland 574*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 575*5c51f124SMoriah Waterland r = cmd_is_netinstall_image(argc, argv, a_gdt); 576*5c51f124SMoriah Waterland } 577*5c51f124SMoriah Waterland 578*5c51f124SMoriah Waterland /* cannot be a boot environment */ 579*5c51f124SMoriah Waterland 580*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 581*5c51f124SMoriah Waterland r = cmd_is_boot_environment(argc, argv, a_gdt); 582*5c51f124SMoriah Waterland } 583*5c51f124SMoriah Waterland 584*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 585*5c51f124SMoriah Waterland 586*5c51f124SMoriah Waterland recursion--; 587*5c51f124SMoriah Waterland 588*5c51f124SMoriah Waterland /* return failure if any of the preceeding are true */ 589*5c51f124SMoriah Waterland 590*5c51f124SMoriah Waterland switch (r) { 591*5c51f124SMoriah Waterland case R_SUCCESS: 592*5c51f124SMoriah Waterland return (R_FAILURE); 593*5c51f124SMoriah Waterland case R_FAILURE: 594*5c51f124SMoriah Waterland break; 595*5c51f124SMoriah Waterland case R_USAGE: 596*5c51f124SMoriah Waterland case R_ERROR: 597*5c51f124SMoriah Waterland default: 598*5c51f124SMoriah Waterland return (r); 599*5c51f124SMoriah Waterland } 600*5c51f124SMoriah Waterland } 601*5c51f124SMoriah Waterland 602*5c51f124SMoriah Waterland /* normalize argc/argv */ 603*5c51f124SMoriah Waterland 604*5c51f124SMoriah Waterland argc -= optind; 605*5c51f124SMoriah Waterland argv += optind; 606*5c51f124SMoriah Waterland 607*5c51f124SMoriah Waterland /* error if more than one argument */ 608*5c51f124SMoriah Waterland 609*5c51f124SMoriah Waterland if (argc > 1) { 610*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 611*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 612*5c51f124SMoriah Waterland return (R_USAGE); 613*5c51f124SMoriah Waterland } 614*5c51f124SMoriah Waterland 615*5c51f124SMoriah Waterland /* process root path if first argument present */ 616*5c51f124SMoriah Waterland 617*5c51f124SMoriah Waterland if (argc == 1) { 618*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 619*5c51f124SMoriah Waterland return (R_ERROR); 620*5c51f124SMoriah Waterland } 621*5c51f124SMoriah Waterland } 622*5c51f124SMoriah Waterland 623*5c51f124SMoriah Waterland /* get current root path */ 624*5c51f124SMoriah Waterland 625*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 626*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 627*5c51f124SMoriah Waterland return (r); 628*5c51f124SMoriah Waterland } 629*5c51f124SMoriah Waterland 630*5c51f124SMoriah Waterland /* start of command debugging information */ 631*5c51f124SMoriah Waterland 632*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 633*5c51f124SMoriah Waterland 634*5c51f124SMoriah Waterland /* SUNWdclnt must be installed */ 635*5c51f124SMoriah Waterland 636*5c51f124SMoriah Waterland if (pkgTestInstalled("SUNWdclnt", "/") != B_TRUE) { 637*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_PKG_NOT_INSTALLED, 638*5c51f124SMoriah Waterland rootPath, "SUNWdclnt", "/"); 639*5c51f124SMoriah Waterland return (R_FAILURE); 640*5c51f124SMoriah Waterland } 641*5c51f124SMoriah Waterland 642*5c51f124SMoriah Waterland /* - $ROOTDIR must not be "/" */ 643*5c51f124SMoriah Waterland 644*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") == 0) { 645*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_ROOTPATH_BAD, rootPath, "/"); 646*5c51f124SMoriah Waterland return (R_FAILURE); 647*5c51f124SMoriah Waterland } 648*5c51f124SMoriah Waterland 649*5c51f124SMoriah Waterland /* - zone name must be global */ 650*5c51f124SMoriah Waterland 651*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { 652*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_BAD, rootPath, 653*5c51f124SMoriah Waterland GLOBAL_ZONENAME); 654*5c51f124SMoriah Waterland return (R_FAILURE); 655*5c51f124SMoriah Waterland } 656*5c51f124SMoriah Waterland 657*5c51f124SMoriah Waterland /* 658*5c51f124SMoriah Waterland * /export/exec/Solaris_"*"/usr must exist; 659*5c51f124SMoriah Waterland * create ls command to test: 660*5c51f124SMoriah Waterland * /usr/bin/ls /export/exec/Solaris_"*"/usr 661*5c51f124SMoriah Waterland */ 662*5c51f124SMoriah Waterland 663*5c51f124SMoriah Waterland (void) snprintf(cmd, sizeof (cmd), "%s %s >/dev/null 2>&1", 664*5c51f124SMoriah Waterland LS_CMD, "/export/exec/Solaris_*/usr"); 665*5c51f124SMoriah Waterland 666*5c51f124SMoriah Waterland /* execute command */ 667*5c51f124SMoriah Waterland 668*5c51f124SMoriah Waterland rc = system(cmd); 669*5c51f124SMoriah Waterland 670*5c51f124SMoriah Waterland /* return error if ls returns something other than "0" */ 671*5c51f124SMoriah Waterland 672*5c51f124SMoriah Waterland if (rc != 0) { 673*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_MISSING, 674*5c51f124SMoriah Waterland rootPath, "/export/exec/Solaris_*/usr"); 675*5c51f124SMoriah Waterland return (R_FAILURE); 676*5c51f124SMoriah Waterland } 677*5c51f124SMoriah Waterland 678*5c51f124SMoriah Waterland /* 679*5c51f124SMoriah Waterland * /usr must be empty on a diskless client: 680*5c51f124SMoriah Waterland * create ls command to test: 681*5c51f124SMoriah Waterland * /usr/bin/ls -d1 $ROOTDIR/usr/\* 682*5c51f124SMoriah Waterland */ 683*5c51f124SMoriah Waterland (void) snprintf(cmd, sizeof (cmd), "%s %s %s/%s >/dev/null 2>&1", 684*5c51f124SMoriah Waterland LS_CMD, "-1d", rootPath, "usr/*"); 685*5c51f124SMoriah Waterland 686*5c51f124SMoriah Waterland /* execute command */ 687*5c51f124SMoriah Waterland 688*5c51f124SMoriah Waterland rc = system(cmd); 689*5c51f124SMoriah Waterland 690*5c51f124SMoriah Waterland /* return error if ls returns "0" */ 691*5c51f124SMoriah Waterland 692*5c51f124SMoriah Waterland if (rc == 0) { 693*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_USR_IS_NOT_EMPTY, 694*5c51f124SMoriah Waterland rootPath); 695*5c51f124SMoriah Waterland return (R_FAILURE); 696*5c51f124SMoriah Waterland } 697*5c51f124SMoriah Waterland 698*5c51f124SMoriah Waterland /* there must be a templates directory at ${ROOTPATH}/../templates */ 699*5c51f124SMoriah Waterland 700*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 701*5c51f124SMoriah Waterland "%s/%s", rootPath, "../templates"); 702*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 703*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_NO_TEMPLATES_PATH, 704*5c51f124SMoriah Waterland rootPath, rootPath, "../templates"); 705*5c51f124SMoriah Waterland return (R_FAILURE); 706*5c51f124SMoriah Waterland } 707*5c51f124SMoriah Waterland 708*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 709*5c51f124SMoriah Waterland 710*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 711*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 712*5c51f124SMoriah Waterland /* initial install: install root cannot be diskless client */ 713*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_INITIAL_INSTALL, rootPath); 714*5c51f124SMoriah Waterland return (R_FAILURE); 715*5c51f124SMoriah Waterland } 716*5c51f124SMoriah Waterland 717*5c51f124SMoriah Waterland /* must not be installation of a zone */ 718*5c51f124SMoriah Waterland 719*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 720*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 721*5c51f124SMoriah Waterland /* initial zone install: no path can be diskless client */ 722*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_ZONE_INSTALL, rootPath); 723*5c51f124SMoriah Waterland return (R_FAILURE); 724*5c51f124SMoriah Waterland } 725*5c51f124SMoriah Waterland 726*5c51f124SMoriah Waterland /* the path is a diskless client */ 727*5c51f124SMoriah Waterland 728*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IDLC_PATH_IS_DISKLESS_CLIENT, rootPath); 729*5c51f124SMoriah Waterland 730*5c51f124SMoriah Waterland return (R_SUCCESS); 731*5c51f124SMoriah Waterland } 732*5c51f124SMoriah Waterland 733*5c51f124SMoriah Waterland /* 734*5c51f124SMoriah Waterland * Name: cmd_is_global_zone 735*5c51f124SMoriah Waterland * Description: determine if target is a global zone 736*5c51f124SMoriah Waterland * Scope: public 737*5c51f124SMoriah Waterland * Arguments: argc,argv: 738*5c51f124SMoriah Waterland * - optional path to target to test 739*5c51f124SMoriah Waterland * Returns: int 740*5c51f124SMoriah Waterland * == 0 - success 741*5c51f124SMoriah Waterland * != 0 - failure 742*5c51f124SMoriah Waterland * IMPLEMENTATION: 743*5c51f124SMoriah Waterland * - must not be initial installation to the install root 744*5c51f124SMoriah Waterland * - must not be installation of a non-global zone 745*5c51f124SMoriah Waterland * - must not be a non-global zone 746*5c51f124SMoriah Waterland * - must not be a mounted mini-root 747*5c51f124SMoriah Waterland * - must not be a netinstall image 748*5c51f124SMoriah Waterland * - must not be a diskless client 749*5c51f124SMoriah Waterland * - if $ROOTDIR is "/": 750*5c51f124SMoriah Waterland * -- if zone name is "GLOBAL", then is a global zone; 751*5c51f124SMoriah Waterland * -- else not a global zone. 752*5c51f124SMoriah Waterland * - $ROOTDIR/etc/zones must exist and be a directory 753*5c51f124SMoriah Waterland * - $ROOTDIR/.tmp_proto must not exist 754*5c51f124SMoriah Waterland * - $ROOTDIR/var must exist and must not be a symbolic link 755*5c51f124SMoriah Waterland */ 756*5c51f124SMoriah Waterland 757*5c51f124SMoriah Waterland static int 758*5c51f124SMoriah Waterland cmd_is_global_zone(int argc, char **argv, GLOBALDATA_T *a_gdt) 759*5c51f124SMoriah Waterland { 760*5c51f124SMoriah Waterland char *rootPath = NULL; 761*5c51f124SMoriah Waterland int c; 762*5c51f124SMoriah Waterland int r; 763*5c51f124SMoriah Waterland static char *cmdName = "is_global_zone"; 764*5c51f124SMoriah Waterland static int recursion = 0; 765*5c51f124SMoriah Waterland 766*5c51f124SMoriah Waterland /* process any command line options */ 767*5c51f124SMoriah Waterland 768*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 769*5c51f124SMoriah Waterland switch (c) { 770*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 771*5c51f124SMoriah Waterland break; 772*5c51f124SMoriah Waterland case '?': 773*5c51f124SMoriah Waterland default: 774*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 775*5c51f124SMoriah Waterland return (R_USAGE); 776*5c51f124SMoriah Waterland } 777*5c51f124SMoriah Waterland } 778*5c51f124SMoriah Waterland 779*5c51f124SMoriah Waterland /* prevent recursion */ 780*5c51f124SMoriah Waterland 781*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 782*5c51f124SMoriah Waterland 783*5c51f124SMoriah Waterland /* 784*5c51f124SMoriah Waterland * a global zone cannot be any of the following 785*5c51f124SMoriah Waterland */ 786*5c51f124SMoriah Waterland 787*5c51f124SMoriah Waterland /* cannot be a non-global zone */ 788*5c51f124SMoriah Waterland 789*5c51f124SMoriah Waterland r = cmd_is_nonglobal_zone(argc, argv, a_gdt); 790*5c51f124SMoriah Waterland 791*5c51f124SMoriah Waterland /* cannot be a mounted miniroot */ 792*5c51f124SMoriah Waterland 793*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 794*5c51f124SMoriah Waterland r = cmd_is_mounted_miniroot(argc, argv, a_gdt); 795*5c51f124SMoriah Waterland } 796*5c51f124SMoriah Waterland 797*5c51f124SMoriah Waterland /* cannot be a netinstall image */ 798*5c51f124SMoriah Waterland 799*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 800*5c51f124SMoriah Waterland r = cmd_is_netinstall_image(argc, argv, a_gdt); 801*5c51f124SMoriah Waterland } 802*5c51f124SMoriah Waterland 803*5c51f124SMoriah Waterland /* cannot be a diskless client */ 804*5c51f124SMoriah Waterland 805*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 806*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 807*5c51f124SMoriah Waterland } 808*5c51f124SMoriah Waterland 809*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 810*5c51f124SMoriah Waterland 811*5c51f124SMoriah Waterland recursion--; 812*5c51f124SMoriah Waterland 813*5c51f124SMoriah Waterland /* return failure if any of the preceeding are true */ 814*5c51f124SMoriah Waterland 815*5c51f124SMoriah Waterland switch (r) { 816*5c51f124SMoriah Waterland case R_SUCCESS: 817*5c51f124SMoriah Waterland return (R_FAILURE); 818*5c51f124SMoriah Waterland case R_FAILURE: 819*5c51f124SMoriah Waterland break; 820*5c51f124SMoriah Waterland case R_USAGE: 821*5c51f124SMoriah Waterland case R_ERROR: 822*5c51f124SMoriah Waterland default: 823*5c51f124SMoriah Waterland return (r); 824*5c51f124SMoriah Waterland } 825*5c51f124SMoriah Waterland } 826*5c51f124SMoriah Waterland 827*5c51f124SMoriah Waterland /* normalize argc/argv */ 828*5c51f124SMoriah Waterland 829*5c51f124SMoriah Waterland argc -= optind; 830*5c51f124SMoriah Waterland argv += optind; 831*5c51f124SMoriah Waterland 832*5c51f124SMoriah Waterland /* error if more than one argument */ 833*5c51f124SMoriah Waterland 834*5c51f124SMoriah Waterland if (argc > 1) { 835*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 836*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 837*5c51f124SMoriah Waterland return (R_USAGE); 838*5c51f124SMoriah Waterland } 839*5c51f124SMoriah Waterland 840*5c51f124SMoriah Waterland /* process root path if first argument present */ 841*5c51f124SMoriah Waterland 842*5c51f124SMoriah Waterland if (argc == 1) { 843*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 844*5c51f124SMoriah Waterland return (R_ERROR); 845*5c51f124SMoriah Waterland } 846*5c51f124SMoriah Waterland } 847*5c51f124SMoriah Waterland 848*5c51f124SMoriah Waterland /* get current root path */ 849*5c51f124SMoriah Waterland 850*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 851*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 852*5c51f124SMoriah Waterland return (r); 853*5c51f124SMoriah Waterland } 854*5c51f124SMoriah Waterland 855*5c51f124SMoriah Waterland /* start of command debugging information */ 856*5c51f124SMoriah Waterland 857*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 858*5c51f124SMoriah Waterland 859*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 860*5c51f124SMoriah Waterland 861*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 862*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 863*5c51f124SMoriah Waterland /* initial install: install root cannot be global zone */ 864*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_INITIAL_INSTALL, rootPath); 865*5c51f124SMoriah Waterland return (R_FAILURE); 866*5c51f124SMoriah Waterland } 867*5c51f124SMoriah Waterland 868*5c51f124SMoriah Waterland /* must not be installation of a non-global zone */ 869*5c51f124SMoriah Waterland 870*5c51f124SMoriah Waterland if (a_gdt->gd_nonglobalZoneInstall == B_TRUE) { 871*5c51f124SMoriah Waterland /* initial nonglobal zone install: no path can be global zone */ 872*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_NGZ_ZONE_INSTALL, rootPath); 873*5c51f124SMoriah Waterland return (R_FAILURE); 874*5c51f124SMoriah Waterland } 875*5c51f124SMoriah Waterland 876*5c51f124SMoriah Waterland /* handle if global zone installation to the install root */ 877*5c51f124SMoriah Waterland 878*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) && 879*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 880*5c51f124SMoriah Waterland /* the path is a global zone */ 881*5c51f124SMoriah Waterland 882*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, 883*5c51f124SMoriah Waterland rootPath); 884*5c51f124SMoriah Waterland 885*5c51f124SMoriah Waterland return (R_SUCCESS); 886*5c51f124SMoriah Waterland } 887*5c51f124SMoriah Waterland 888*5c51f124SMoriah Waterland /* true if current root is "/" and zone name is GLOBAL_ZONENAME */ 889*5c51f124SMoriah Waterland 890*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") == 0) { 891*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) { 892*5c51f124SMoriah Waterland /* the path is a global zone */ 893*5c51f124SMoriah Waterland 894*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, 895*5c51f124SMoriah Waterland rootPath); 896*5c51f124SMoriah Waterland 897*5c51f124SMoriah Waterland return (R_SUCCESS); 898*5c51f124SMoriah Waterland } 899*5c51f124SMoriah Waterland 900*5c51f124SMoriah Waterland /* inside a non-global zone */ 901*5c51f124SMoriah Waterland 902*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_ZONENAME_ISNT_GLOBAL, 903*5c51f124SMoriah Waterland rootPath, a_gdt->gd_zoneName); 904*5c51f124SMoriah Waterland 905*5c51f124SMoriah Waterland return (R_FAILURE); 906*5c51f124SMoriah Waterland } 907*5c51f124SMoriah Waterland 908*5c51f124SMoriah Waterland /* 909*5c51f124SMoriah Waterland * current root is not "/" - see if target looks like a global zone 910*5c51f124SMoriah Waterland * 911*5c51f124SMoriah Waterland * - rootpath is not "/" 912*5c51f124SMoriah Waterland * - and $ROOTDIR/etc/zones exists 913*5c51f124SMoriah Waterland * - and $ROOTDIR/.tmp_proto does not exist 914*5c51f124SMoriah Waterland * - and $ROOTDIR/var is not a symbolic link 915*5c51f124SMoriah Waterland */ 916*5c51f124SMoriah Waterland 917*5c51f124SMoriah Waterland /* not global zone if /etc/zones does not exist */ 918*5c51f124SMoriah Waterland 919*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 920*5c51f124SMoriah Waterland "%s/%s", rootPath, "/etc/zones"); 921*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 922*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_ISNT_DIRECTORY, 923*5c51f124SMoriah Waterland rootPath, "/etc/zones"); 924*5c51f124SMoriah Waterland return (R_FAILURE); 925*5c51f124SMoriah Waterland } 926*5c51f124SMoriah Waterland 927*5c51f124SMoriah Waterland /* .tmp_proto must not exist */ 928*5c51f124SMoriah Waterland 929*5c51f124SMoriah Waterland r = testPath(TEST_NOT_EXISTS, 930*5c51f124SMoriah Waterland "%s/%s", rootPath, ".tmp_proto"); 931*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 932*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_EXISTS, 933*5c51f124SMoriah Waterland rootPath, "/.tmp_proto"); 934*5c51f124SMoriah Waterland return (R_FAILURE); 935*5c51f124SMoriah Waterland } 936*5c51f124SMoriah Waterland 937*5c51f124SMoriah Waterland /* /var must not be a symbolic link */ 938*5c51f124SMoriah Waterland 939*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 940*5c51f124SMoriah Waterland "%s/%s", rootPath, "/var"); 941*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 942*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_SYMLINK, 943*5c51f124SMoriah Waterland rootPath, "/var"); 944*5c51f124SMoriah Waterland return (R_FAILURE); 945*5c51f124SMoriah Waterland } 946*5c51f124SMoriah Waterland 947*5c51f124SMoriah Waterland /* the path is a global zone */ 948*5c51f124SMoriah Waterland 949*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ISGZ_PATH_IS_GLOBAL_ZONE, rootPath); 950*5c51f124SMoriah Waterland 951*5c51f124SMoriah Waterland return (R_SUCCESS); 952*5c51f124SMoriah Waterland } 953*5c51f124SMoriah Waterland 954*5c51f124SMoriah Waterland /* 955*5c51f124SMoriah Waterland * Name: cmd_is_netinstall_image 956*5c51f124SMoriah Waterland * Description: determine if target is a net install image 957*5c51f124SMoriah Waterland * Scope: public 958*5c51f124SMoriah Waterland * Arguments: argc,argv: 959*5c51f124SMoriah Waterland * - optional path to target to test 960*5c51f124SMoriah Waterland * Returns: int 961*5c51f124SMoriah Waterland * == 0 - success 962*5c51f124SMoriah Waterland * != 0 - failure 963*5c51f124SMoriah Waterland * IMPLEMENTATION: 964*5c51f124SMoriah Waterland * - must not be initial installation to the install root 965*5c51f124SMoriah Waterland * - must not be installation of a zone 966*5c51f124SMoriah Waterland * - must not be a global zone 967*5c51f124SMoriah Waterland * - must not be a mounted mini-root 968*5c51f124SMoriah Waterland * - zone name must be "global" 969*5c51f124SMoriah Waterland * - $ROOTDIR/.tmp_proto must exist and must be a directory 970*5c51f124SMoriah Waterland * - $ROOTDIR/var must exist and must be a symbolic link 971*5c51f124SMoriah Waterland * - $ROOTDIR/tmp/kernel must exist and must be a directory 972*5c51f124SMoriah Waterland * - $ROOTDIR/.tmp_proto/kernel must exist and must be a symbolic link 973*5c51f124SMoriah Waterland */ 974*5c51f124SMoriah Waterland 975*5c51f124SMoriah Waterland static int 976*5c51f124SMoriah Waterland cmd_is_netinstall_image(int argc, char **argv, GLOBALDATA_T *a_gdt) 977*5c51f124SMoriah Waterland { 978*5c51f124SMoriah Waterland char *rootPath = NULL; 979*5c51f124SMoriah Waterland int c; 980*5c51f124SMoriah Waterland int r; 981*5c51f124SMoriah Waterland static char *cmdName = "is_netinstall_image"; 982*5c51f124SMoriah Waterland static int recursion = 0; 983*5c51f124SMoriah Waterland 984*5c51f124SMoriah Waterland /* process any command line options */ 985*5c51f124SMoriah Waterland 986*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 987*5c51f124SMoriah Waterland switch (c) { 988*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 989*5c51f124SMoriah Waterland break; 990*5c51f124SMoriah Waterland case '?': 991*5c51f124SMoriah Waterland default: 992*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 993*5c51f124SMoriah Waterland return (R_USAGE); 994*5c51f124SMoriah Waterland } 995*5c51f124SMoriah Waterland } 996*5c51f124SMoriah Waterland 997*5c51f124SMoriah Waterland /* prevent recursion */ 998*5c51f124SMoriah Waterland 999*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1000*5c51f124SMoriah Waterland 1001*5c51f124SMoriah Waterland /* a netinstall image cannot be a global zone */ 1002*5c51f124SMoriah Waterland 1003*5c51f124SMoriah Waterland r = cmd_is_global_zone(argc, argv, a_gdt); 1004*5c51f124SMoriah Waterland 1005*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 1006*5c51f124SMoriah Waterland 1007*5c51f124SMoriah Waterland recursion--; 1008*5c51f124SMoriah Waterland 1009*5c51f124SMoriah Waterland switch (r) { 1010*5c51f124SMoriah Waterland case R_SUCCESS: 1011*5c51f124SMoriah Waterland return (R_FAILURE); 1012*5c51f124SMoriah Waterland case R_FAILURE: 1013*5c51f124SMoriah Waterland break; 1014*5c51f124SMoriah Waterland case R_USAGE: 1015*5c51f124SMoriah Waterland case R_ERROR: 1016*5c51f124SMoriah Waterland default: 1017*5c51f124SMoriah Waterland return (r); 1018*5c51f124SMoriah Waterland } 1019*5c51f124SMoriah Waterland } 1020*5c51f124SMoriah Waterland 1021*5c51f124SMoriah Waterland /* normalize argc/argv */ 1022*5c51f124SMoriah Waterland 1023*5c51f124SMoriah Waterland argc -= optind; 1024*5c51f124SMoriah Waterland argv += optind; 1025*5c51f124SMoriah Waterland 1026*5c51f124SMoriah Waterland /* error if more than one argument */ 1027*5c51f124SMoriah Waterland 1028*5c51f124SMoriah Waterland if (argc > 1) { 1029*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1030*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1031*5c51f124SMoriah Waterland return (R_USAGE); 1032*5c51f124SMoriah Waterland } 1033*5c51f124SMoriah Waterland 1034*5c51f124SMoriah Waterland /* process root path if first argument present */ 1035*5c51f124SMoriah Waterland 1036*5c51f124SMoriah Waterland if (argc == 1) { 1037*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1038*5c51f124SMoriah Waterland return (R_ERROR); 1039*5c51f124SMoriah Waterland } 1040*5c51f124SMoriah Waterland } 1041*5c51f124SMoriah Waterland 1042*5c51f124SMoriah Waterland /* get current root path */ 1043*5c51f124SMoriah Waterland 1044*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1045*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1046*5c51f124SMoriah Waterland return (r); 1047*5c51f124SMoriah Waterland } 1048*5c51f124SMoriah Waterland 1049*5c51f124SMoriah Waterland /* start of command debugging information */ 1050*5c51f124SMoriah Waterland 1051*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1052*5c51f124SMoriah Waterland 1053*5c51f124SMoriah Waterland /* current zone name must be "global" */ 1054*5c51f124SMoriah Waterland 1055*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { 1056*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_BAD_CURRENT_ZONE, 1057*5c51f124SMoriah Waterland rootPath, GLOBAL_ZONENAME); 1058*5c51f124SMoriah Waterland return (R_FAILURE); 1059*5c51f124SMoriah Waterland } 1060*5c51f124SMoriah Waterland 1061*5c51f124SMoriah Waterland /* cannot be a mounted_miniroot */ 1062*5c51f124SMoriah Waterland 1063*5c51f124SMoriah Waterland if (cmd_is_mounted_miniroot(argc, argv, a_gdt) == R_SUCCESS) { 1064*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT, 1065*5c51f124SMoriah Waterland rootPath); 1066*5c51f124SMoriah Waterland return (R_FAILURE); 1067*5c51f124SMoriah Waterland } 1068*5c51f124SMoriah Waterland 1069*5c51f124SMoriah Waterland /* $ROOTDIR/.tmp_proto exists */ 1070*5c51f124SMoriah Waterland 1071*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 1072*5c51f124SMoriah Waterland "%s/%s", rootPath, ".tmp_proto"); 1073*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1074*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY, 1075*5c51f124SMoriah Waterland rootPath, "/.tmp_proto"); 1076*5c51f124SMoriah Waterland return (R_FAILURE); 1077*5c51f124SMoriah Waterland } 1078*5c51f124SMoriah Waterland 1079*5c51f124SMoriah Waterland /* $ROOTDIR/var is a symbolic link */ 1080*5c51f124SMoriah Waterland 1081*5c51f124SMoriah Waterland r = testPath(TEST_IS_SYMBOLIC_LINK, 1082*5c51f124SMoriah Waterland "%s/%s", rootPath, "/var"); 1083*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1084*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK, 1085*5c51f124SMoriah Waterland rootPath, "/var"); 1086*5c51f124SMoriah Waterland return (R_FAILURE); 1087*5c51f124SMoriah Waterland } 1088*5c51f124SMoriah Waterland 1089*5c51f124SMoriah Waterland /* $ROOTDIR/tmp/kernel does exist */ 1090*5c51f124SMoriah Waterland 1091*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 1092*5c51f124SMoriah Waterland "%s/%s", rootPath, "/tmp/kernel"); 1093*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1094*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_DIRECTORY, 1095*5c51f124SMoriah Waterland rootPath, "/tmp/kernel"); 1096*5c51f124SMoriah Waterland return (R_FAILURE); 1097*5c51f124SMoriah Waterland } 1098*5c51f124SMoriah Waterland 1099*5c51f124SMoriah Waterland /* $ROOTDIR/.tmp_proto/kernel is a symbolic link */ 1100*5c51f124SMoriah Waterland 1101*5c51f124SMoriah Waterland r = testPath(TEST_IS_SYMBOLIC_LINK, 1102*5c51f124SMoriah Waterland "%s/%s", rootPath, "/.tmp_proto/kernel"); 1103*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1104*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_ISNT_SYMLINK, 1105*5c51f124SMoriah Waterland rootPath, "/.tmp_proto/kernel"); 1106*5c51f124SMoriah Waterland return (R_FAILURE); 1107*5c51f124SMoriah Waterland } 1108*5c51f124SMoriah Waterland 1109*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 1110*5c51f124SMoriah Waterland 1111*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 1112*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 1113*5c51f124SMoriah Waterland /* initial install: install root cannot be netinstall image */ 1114*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_INITIAL_INSTALL, rootPath); 1115*5c51f124SMoriah Waterland return (R_FAILURE); 1116*5c51f124SMoriah Waterland } 1117*5c51f124SMoriah Waterland 1118*5c51f124SMoriah Waterland /* must not be installation of a zone */ 1119*5c51f124SMoriah Waterland 1120*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 1121*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 1122*5c51f124SMoriah Waterland /* initial zone install: no path can be netinstall image */ 1123*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_ZONE_INSTALL, rootPath); 1124*5c51f124SMoriah Waterland return (R_FAILURE); 1125*5c51f124SMoriah Waterland } 1126*5c51f124SMoriah Waterland 1127*5c51f124SMoriah Waterland /* target is a netinstall image */ 1128*5c51f124SMoriah Waterland 1129*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_INIM_PATH_IS_NETINSTALL_IMAGE, rootPath); 1130*5c51f124SMoriah Waterland 1131*5c51f124SMoriah Waterland return (R_SUCCESS); 1132*5c51f124SMoriah Waterland } 1133*5c51f124SMoriah Waterland 1134*5c51f124SMoriah Waterland /* 1135*5c51f124SMoriah Waterland * Name: cmd_is_mounted_miniroot 1136*5c51f124SMoriah Waterland * Description: determine if target is a mounted miniroot image 1137*5c51f124SMoriah Waterland * Scope: public 1138*5c51f124SMoriah Waterland * Arguments: argc,argv: 1139*5c51f124SMoriah Waterland * - optional path to target to test 1140*5c51f124SMoriah Waterland * Returns: int 1141*5c51f124SMoriah Waterland * == 0 - success 1142*5c51f124SMoriah Waterland * != 0 - failure 1143*5c51f124SMoriah Waterland * IMPLEMENTATION: 1144*5c51f124SMoriah Waterland * - must not be initial installation to the install root 1145*5c51f124SMoriah Waterland * - must not be installation of a zone 1146*5c51f124SMoriah Waterland * - zone name must be "global" 1147*5c51f124SMoriah Waterland * - $ROOTDIR/tmp/kernel must exist and must be a symbolic link 1148*5c51f124SMoriah Waterland * - $ROOTDIR/tmp/root/kernel must exist and must be a directory 1149*5c51f124SMoriah Waterland */ 1150*5c51f124SMoriah Waterland 1151*5c51f124SMoriah Waterland static int 1152*5c51f124SMoriah Waterland cmd_is_mounted_miniroot(int argc, char **argv, GLOBALDATA_T *a_gdt) 1153*5c51f124SMoriah Waterland { 1154*5c51f124SMoriah Waterland char *rootPath = NULL; 1155*5c51f124SMoriah Waterland int c; 1156*5c51f124SMoriah Waterland int r; 1157*5c51f124SMoriah Waterland static char *cmdName = "is_mounted_miniroot"; 1158*5c51f124SMoriah Waterland static int recursion = 0; 1159*5c51f124SMoriah Waterland 1160*5c51f124SMoriah Waterland /* process any command line options */ 1161*5c51f124SMoriah Waterland 1162*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1163*5c51f124SMoriah Waterland switch (c) { 1164*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1165*5c51f124SMoriah Waterland break; 1166*5c51f124SMoriah Waterland case '?': 1167*5c51f124SMoriah Waterland default: 1168*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1169*5c51f124SMoriah Waterland return (R_USAGE); 1170*5c51f124SMoriah Waterland } 1171*5c51f124SMoriah Waterland } 1172*5c51f124SMoriah Waterland 1173*5c51f124SMoriah Waterland /* prevent recursion */ 1174*5c51f124SMoriah Waterland 1175*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1176*5c51f124SMoriah Waterland recursion--; 1177*5c51f124SMoriah Waterland } 1178*5c51f124SMoriah Waterland 1179*5c51f124SMoriah Waterland /* normalize argc/argv */ 1180*5c51f124SMoriah Waterland 1181*5c51f124SMoriah Waterland argc -= optind; 1182*5c51f124SMoriah Waterland argv += optind; 1183*5c51f124SMoriah Waterland 1184*5c51f124SMoriah Waterland /* error if more than one argument */ 1185*5c51f124SMoriah Waterland 1186*5c51f124SMoriah Waterland if (argc > 1) { 1187*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1188*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1189*5c51f124SMoriah Waterland return (R_USAGE); 1190*5c51f124SMoriah Waterland } 1191*5c51f124SMoriah Waterland 1192*5c51f124SMoriah Waterland /* process root path if first argument present */ 1193*5c51f124SMoriah Waterland 1194*5c51f124SMoriah Waterland if (argc == 1) { 1195*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1196*5c51f124SMoriah Waterland return (R_ERROR); 1197*5c51f124SMoriah Waterland } 1198*5c51f124SMoriah Waterland } 1199*5c51f124SMoriah Waterland 1200*5c51f124SMoriah Waterland /* get current root path */ 1201*5c51f124SMoriah Waterland 1202*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1203*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1204*5c51f124SMoriah Waterland return (r); 1205*5c51f124SMoriah Waterland } 1206*5c51f124SMoriah Waterland 1207*5c51f124SMoriah Waterland /* start of command debugging information */ 1208*5c51f124SMoriah Waterland 1209*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1210*5c51f124SMoriah Waterland 1211*5c51f124SMoriah Waterland /* current zone name must be "global" */ 1212*5c51f124SMoriah Waterland 1213*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { 1214*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_BAD_CURRENT_ZONE, 1215*5c51f124SMoriah Waterland rootPath, GLOBAL_ZONENAME); 1216*5c51f124SMoriah Waterland return (R_FAILURE); 1217*5c51f124SMoriah Waterland } 1218*5c51f124SMoriah Waterland 1219*5c51f124SMoriah Waterland /* $ROOTDIR/tmp/kernel is a symbolic link */ 1220*5c51f124SMoriah Waterland 1221*5c51f124SMoriah Waterland r = testPath(TEST_IS_SYMBOLIC_LINK, 1222*5c51f124SMoriah Waterland "%s/%s", rootPath, "/tmp/kernel"); 1223*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1224*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_SYMLINK, 1225*5c51f124SMoriah Waterland rootPath, "/tmp/kernel"); 1226*5c51f124SMoriah Waterland return (R_FAILURE); 1227*5c51f124SMoriah Waterland } 1228*5c51f124SMoriah Waterland 1229*5c51f124SMoriah Waterland /* $ROOTDIR/tmp/root/kernel is a directory */ 1230*5c51f124SMoriah Waterland 1231*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 1232*5c51f124SMoriah Waterland "%s/%s", rootPath, "/tmp/root/kernel"); 1233*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1234*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_ISNT_DIRECTORY, 1235*5c51f124SMoriah Waterland rootPath, "/tmp/root/kernel"); 1236*5c51f124SMoriah Waterland return (R_FAILURE); 1237*5c51f124SMoriah Waterland } 1238*5c51f124SMoriah Waterland 1239*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 1240*5c51f124SMoriah Waterland 1241*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 1242*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 1243*5c51f124SMoriah Waterland /* initial install: install root cannot be mounted miniroot */ 1244*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_INITIAL_INSTALL, rootPath); 1245*5c51f124SMoriah Waterland return (R_FAILURE); 1246*5c51f124SMoriah Waterland } 1247*5c51f124SMoriah Waterland 1248*5c51f124SMoriah Waterland /* must not be installation of a zone */ 1249*5c51f124SMoriah Waterland 1250*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 1251*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 1252*5c51f124SMoriah Waterland /* initial zone install: no path can be mounted miniroot */ 1253*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_ZONE_INSTALL, rootPath); 1254*5c51f124SMoriah Waterland return (R_FAILURE); 1255*5c51f124SMoriah Waterland } 1256*5c51f124SMoriah Waterland 1257*5c51f124SMoriah Waterland /* target is a mounted miniroot */ 1258*5c51f124SMoriah Waterland 1259*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IMRT_PATH_IS_MOUNTED_MINIROOT, rootPath); 1260*5c51f124SMoriah Waterland 1261*5c51f124SMoriah Waterland return (R_SUCCESS); 1262*5c51f124SMoriah Waterland } 1263*5c51f124SMoriah Waterland 1264*5c51f124SMoriah Waterland /* 1265*5c51f124SMoriah Waterland * Name: cmd_is_nonglobal_zone 1266*5c51f124SMoriah Waterland * Description: determine if target is a global zone 1267*5c51f124SMoriah Waterland * Scope: public 1268*5c51f124SMoriah Waterland * Arguments: argc,argv: 1269*5c51f124SMoriah Waterland * - optional path to target to test 1270*5c51f124SMoriah Waterland * Returns: int 1271*5c51f124SMoriah Waterland * == 0 - success 1272*5c51f124SMoriah Waterland * != 0 - failure 1273*5c51f124SMoriah Waterland * - must not be initial installation to the install root 1274*5c51f124SMoriah Waterland * - must not be installation of a global zone 1275*5c51f124SMoriah Waterland * - success if installation of a non-global zone 1276*5c51f124SMoriah Waterland */ 1277*5c51f124SMoriah Waterland 1278*5c51f124SMoriah Waterland static int 1279*5c51f124SMoriah Waterland cmd_is_nonglobal_zone(int argc, char **argv, GLOBALDATA_T *a_gdt) 1280*5c51f124SMoriah Waterland { 1281*5c51f124SMoriah Waterland char *rootPath = NULL; 1282*5c51f124SMoriah Waterland int c; 1283*5c51f124SMoriah Waterland int r; 1284*5c51f124SMoriah Waterland static char *cmdName = "is_nonglobal_zone"; 1285*5c51f124SMoriah Waterland static int recursion = 0; 1286*5c51f124SMoriah Waterland 1287*5c51f124SMoriah Waterland /* process any command line options */ 1288*5c51f124SMoriah Waterland 1289*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1290*5c51f124SMoriah Waterland switch (c) { 1291*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1292*5c51f124SMoriah Waterland break; 1293*5c51f124SMoriah Waterland case '?': 1294*5c51f124SMoriah Waterland default: 1295*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1296*5c51f124SMoriah Waterland return (R_USAGE); 1297*5c51f124SMoriah Waterland } 1298*5c51f124SMoriah Waterland } 1299*5c51f124SMoriah Waterland 1300*5c51f124SMoriah Waterland /* prevent recursion */ 1301*5c51f124SMoriah Waterland 1302*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1303*5c51f124SMoriah Waterland recursion--; 1304*5c51f124SMoriah Waterland } 1305*5c51f124SMoriah Waterland 1306*5c51f124SMoriah Waterland /* normalize argc/argv */ 1307*5c51f124SMoriah Waterland 1308*5c51f124SMoriah Waterland argc -= optind; 1309*5c51f124SMoriah Waterland argv += optind; 1310*5c51f124SMoriah Waterland 1311*5c51f124SMoriah Waterland /* error if more than one argument */ 1312*5c51f124SMoriah Waterland 1313*5c51f124SMoriah Waterland if (argc > 1) { 1314*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1315*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1316*5c51f124SMoriah Waterland return (R_USAGE); 1317*5c51f124SMoriah Waterland } 1318*5c51f124SMoriah Waterland 1319*5c51f124SMoriah Waterland /* process root path if first argument present */ 1320*5c51f124SMoriah Waterland 1321*5c51f124SMoriah Waterland if (argc == 1) { 1322*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1323*5c51f124SMoriah Waterland return (R_ERROR); 1324*5c51f124SMoriah Waterland } 1325*5c51f124SMoriah Waterland } 1326*5c51f124SMoriah Waterland 1327*5c51f124SMoriah Waterland /* get current root path */ 1328*5c51f124SMoriah Waterland 1329*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1330*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1331*5c51f124SMoriah Waterland return (r); 1332*5c51f124SMoriah Waterland } 1333*5c51f124SMoriah Waterland 1334*5c51f124SMoriah Waterland /* start of command debugging information */ 1335*5c51f124SMoriah Waterland 1336*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1337*5c51f124SMoriah Waterland 1338*5c51f124SMoriah Waterland /* handle if non-global zone installation to the install root */ 1339*5c51f124SMoriah Waterland 1340*5c51f124SMoriah Waterland if ((a_gdt->gd_nonglobalZoneInstall == B_TRUE) && 1341*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 1342*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_INSTALL_ZONENAME_IS_NGZ, 1343*5c51f124SMoriah Waterland rootPath, a_gdt->gd_zoneName); 1344*5c51f124SMoriah Waterland return (R_SUCCESS); 1345*5c51f124SMoriah Waterland } 1346*5c51f124SMoriah Waterland 1347*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 1348*5c51f124SMoriah Waterland 1349*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 1350*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 1351*5c51f124SMoriah Waterland /* initial install: install root cannot be non-global zone */ 1352*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_INITIAL_INSTALL, rootPath); 1353*5c51f124SMoriah Waterland return (R_FAILURE); 1354*5c51f124SMoriah Waterland } 1355*5c51f124SMoriah Waterland 1356*5c51f124SMoriah Waterland /* must not be installation of a global zone */ 1357*5c51f124SMoriah Waterland 1358*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 1359*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 1360*5c51f124SMoriah Waterland /* initial global zone install: no path can be nonglobal zone */ 1361*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_GLOBAL_ZONE_INSTALL, rootPath); 1362*5c51f124SMoriah Waterland return (R_FAILURE); 1363*5c51f124SMoriah Waterland } 1364*5c51f124SMoriah Waterland 1365*5c51f124SMoriah Waterland /* 1366*5c51f124SMoriah Waterland * ********************************************************************* 1367*5c51f124SMoriah Waterland * if root directory is "/" then the only thing that needs to be done is 1368*5c51f124SMoriah Waterland * to test the zone name directly - if the zone name is "global" then 1369*5c51f124SMoriah Waterland * the target is not a non-global zone; otherwise if the zone name is 1370*5c51f124SMoriah Waterland * not "global" then the target IS a non-global zone. 1371*5c51f124SMoriah Waterland * ********************************************************************* 1372*5c51f124SMoriah Waterland */ 1373*5c51f124SMoriah Waterland 1374*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") == 0) { 1375*5c51f124SMoriah Waterland /* target is current running root */ 1376*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) { 1377*5c51f124SMoriah Waterland /* in the global zone */ 1378*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ, 1379*5c51f124SMoriah Waterland rootPath, a_gdt->gd_zoneName); 1380*5c51f124SMoriah Waterland return (R_FAILURE); 1381*5c51f124SMoriah Waterland } 1382*5c51f124SMoriah Waterland /* in a non-global zone */ 1383*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_IS_NGZ, 1384*5c51f124SMoriah Waterland rootPath, a_gdt->gd_zoneName); 1385*5c51f124SMoriah Waterland return (R_SUCCESS); 1386*5c51f124SMoriah Waterland } 1387*5c51f124SMoriah Waterland 1388*5c51f124SMoriah Waterland /* 1389*5c51f124SMoriah Waterland * $ROOTDIR/etc/zones/index must exist in a global zone. It also 1390*5c51f124SMoriah Waterland * exists in a non-global zone after s10u4 but we can't check that 1391*5c51f124SMoriah Waterland * since it is undeterministic for all releases so we only check 1392*5c51f124SMoriah Waterland * for the global zone here. 1393*5c51f124SMoriah Waterland */ 1394*5c51f124SMoriah Waterland 1395*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/zones/index"); 1396*5c51f124SMoriah Waterland if (r == R_SUCCESS) { 1397*5c51f124SMoriah Waterland 1398*5c51f124SMoriah Waterland /* See if "global" exists in .../etc/zones/index */ 1399*5c51f124SMoriah Waterland 1400*5c51f124SMoriah Waterland if (testPath(TEST_GLOBAL_TOKEN_IN_FILE, "%s/%s", rootPath, 1401*5c51f124SMoriah Waterland "/etc/zones/index") != R_SUCCESS) { 1402*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_ZONENAME_ISNT_NGZ, 1403*5c51f124SMoriah Waterland rootPath, GLOBAL_ZONENAME); 1404*5c51f124SMoriah Waterland return (R_FAILURE); 1405*5c51f124SMoriah Waterland } 1406*5c51f124SMoriah Waterland } 1407*5c51f124SMoriah Waterland 1408*5c51f124SMoriah Waterland /* 1409*5c51f124SMoriah Waterland * ********************************************************************* 1410*5c51f124SMoriah Waterland * If the root directory is "/" then you can use only the zone 1411*5c51f124SMoriah Waterland * name to determine if the zone is non-global or not since the 1412*5c51f124SMoriah Waterland * package is being installed or removed to the current "zone". 1413*5c51f124SMoriah Waterland * 1414*5c51f124SMoriah Waterland * Since the root directory being tested is not "/" then you have to 1415*5c51f124SMoriah Waterland * look into the target to try and infer zone type using means other 1416*5c51f124SMoriah Waterland * than the zone name only. 1417*5c51f124SMoriah Waterland * ********************************************************************* 1418*5c51f124SMoriah Waterland */ 1419*5c51f124SMoriah Waterland 1420*5c51f124SMoriah Waterland /* reject if any items found that cannot be in a non-global zone */ 1421*5c51f124SMoriah Waterland 1422*5c51f124SMoriah Waterland /* .tmp_proto must not exist */ 1423*5c51f124SMoriah Waterland 1424*5c51f124SMoriah Waterland r = testPath(TEST_NOT_EXISTS, "%s/%s", rootPath, ".tmp_proto"); 1425*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1426*5c51f124SMoriah Waterland /* $R/.tmp_proto cannot exist in a non-global zone */ 1427*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS, 1428*5c51f124SMoriah Waterland rootPath, "/.tmp_proto"); 1429*5c51f124SMoriah Waterland return (R_FAILURE); 1430*5c51f124SMoriah Waterland } 1431*5c51f124SMoriah Waterland 1432*5c51f124SMoriah Waterland /* /var must not be a symbolic link */ 1433*5c51f124SMoriah Waterland 1434*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1435*5c51f124SMoriah Waterland "%s/%s", rootPath, "/var"); 1436*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1437*5c51f124SMoriah Waterland /* $R/var cannot be a symbolic link in a non-global zone */ 1438*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_DOES_NOT_EXIST, 1439*5c51f124SMoriah Waterland rootPath, "/var"); 1440*5c51f124SMoriah Waterland return (R_FAILURE); 1441*5c51f124SMoriah Waterland } 1442*5c51f124SMoriah Waterland 1443*5c51f124SMoriah Waterland /* $ROOTDIR/tmp/root/kernel must not exist */ 1444*5c51f124SMoriah Waterland 1445*5c51f124SMoriah Waterland r = testPath(TEST_NOT_EXISTS, 1446*5c51f124SMoriah Waterland "%s/%s", rootPath, "/tmp/root/kernel"); 1447*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1448*5c51f124SMoriah Waterland /* $R/tmp/root/kernel cannot exist in a non-global zone */ 1449*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_PATH_EXISTS, 1450*5c51f124SMoriah Waterland rootPath, "/tmp/root/kernel"); 1451*5c51f124SMoriah Waterland return (R_FAILURE); 1452*5c51f124SMoriah Waterland } 1453*5c51f124SMoriah Waterland 1454*5c51f124SMoriah Waterland /* 1455*5c51f124SMoriah Waterland * ********************************************************************* 1456*5c51f124SMoriah Waterland * no items exist in $ROOTDIR that identify something other than 1457*5c51f124SMoriah Waterland * a non-global zone. 1458*5c51f124SMoriah Waterland * 1459*5c51f124SMoriah Waterland * if in global zone no more tests possible: is a non-global zone 1460*5c51f124SMoriah Waterland * ********************************************************************* 1461*5c51f124SMoriah Waterland */ 1462*5c51f124SMoriah Waterland 1463*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) == 0) { 1464*5c51f124SMoriah Waterland /* in the global zone */ 1465*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_IN_GZ_IS_NONGLOBAL_ZONE, 1466*5c51f124SMoriah Waterland rootPath); 1467*5c51f124SMoriah Waterland return (R_SUCCESS); 1468*5c51f124SMoriah Waterland } 1469*5c51f124SMoriah Waterland 1470*5c51f124SMoriah Waterland /* 1471*5c51f124SMoriah Waterland * ********************************************************************* 1472*5c51f124SMoriah Waterland * In non-global zone: interrogate zone name and type. 1473*5c51f124SMoriah Waterland * 1474*5c51f124SMoriah Waterland * The parent zone is the zone that the "pkgadd" or "pkgrm" command was 1475*5c51f124SMoriah Waterland * run in. The child zone is the zone that the "pkginstall" or 1476*5c51f124SMoriah Waterland * "pkgremove" command was run in. 1477*5c51f124SMoriah Waterland * ********************************************************************* 1478*5c51f124SMoriah Waterland */ 1479*5c51f124SMoriah Waterland 1480*5c51f124SMoriah Waterland /* 1481*5c51f124SMoriah Waterland * If parent zone name and current zone name defined, and 1482*5c51f124SMoriah Waterland * both zone names are the same, since pkgcond is running 1483*5c51f124SMoriah Waterland * inside of a non-global zone, this is how the scratch 1484*5c51f124SMoriah Waterland * zone is implemented, so target is a non-global zone 1485*5c51f124SMoriah Waterland */ 1486*5c51f124SMoriah Waterland 1487*5c51f124SMoriah Waterland if ((a_gdt->gd_parentZoneName != NULL) && 1488*5c51f124SMoriah Waterland (a_gdt->gd_currentZoneName != NULL) && 1489*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_parentZoneName, 1490*5c51f124SMoriah Waterland a_gdt->gd_currentZoneName) == 0)) { 1491*5c51f124SMoriah Waterland /* parent and current zone name identical: non-gz */ 1492*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_PARENT_CHILD_SAMEZONE, 1493*5c51f124SMoriah Waterland rootPath, a_gdt->gd_parentZoneName); 1494*5c51f124SMoriah Waterland return (R_SUCCESS); 1495*5c51f124SMoriah Waterland } 1496*5c51f124SMoriah Waterland 1497*5c51f124SMoriah Waterland /* 1498*5c51f124SMoriah Waterland * In non-global zone if inherited FS's exits 1499*5c51f124SMoriah Waterland * or zone specific read only FS's exist 1500*5c51f124SMoriah Waterland * or it is in a mounted state. 1501*5c51f124SMoriah Waterland */ 1502*5c51f124SMoriah Waterland 1503*5c51f124SMoriah Waterland if (a_gdt->gd_inheritedFileSystems != NULL || 1504*5c51f124SMoriah Waterland a_gdt->gd_srFsMountedRO || a_gdt->inMountedState) { 1505*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath); 1506*5c51f124SMoriah Waterland return (R_SUCCESS); 1507*5c51f124SMoriah Waterland } 1508*5c51f124SMoriah Waterland 1509*5c51f124SMoriah Waterland /* 1510*5c51f124SMoriah Waterland * the parent and current zone name are not the same; 1511*5c51f124SMoriah Waterland * interrogate the zone types: the parent must be global 1512*5c51f124SMoriah Waterland * and the current must be non-global, which would be set 1513*5c51f124SMoriah Waterland * when a package command is run in the global zone that in 1514*5c51f124SMoriah Waterland * turn runs a package command within the non-global zone. 1515*5c51f124SMoriah Waterland */ 1516*5c51f124SMoriah Waterland 1517*5c51f124SMoriah Waterland /* if defined, parent zone type must be "global" */ 1518*5c51f124SMoriah Waterland 1519*5c51f124SMoriah Waterland if ((a_gdt->gd_parentZoneType != NULL) && 1520*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_parentZoneType, "nonglobal") == 0)) { 1521*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_PARENT_ZONETYPE, 1522*5c51f124SMoriah Waterland rootPath, "nonglobal"); 1523*5c51f124SMoriah Waterland return (R_FAILURE); 1524*5c51f124SMoriah Waterland } 1525*5c51f124SMoriah Waterland 1526*5c51f124SMoriah Waterland /* if defined, current zone type must be "nonglobal" */ 1527*5c51f124SMoriah Waterland 1528*5c51f124SMoriah Waterland if ((a_gdt->gd_currentZoneType != NULL) && 1529*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_currentZoneType, GLOBAL_ZONENAME) == 0)) { 1530*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_BAD_CURRENT_ZONETYPE, 1531*5c51f124SMoriah Waterland rootPath, GLOBAL_ZONENAME); 1532*5c51f124SMoriah Waterland return (R_FAILURE); 1533*5c51f124SMoriah Waterland } 1534*5c51f124SMoriah Waterland 1535*5c51f124SMoriah Waterland /* 1536*5c51f124SMoriah Waterland * ********************************************************************* 1537*5c51f124SMoriah Waterland * no other tests possible: target is a non-global zone 1538*5c51f124SMoriah Waterland * ********************************************************************* 1539*5c51f124SMoriah Waterland */ 1540*5c51f124SMoriah Waterland 1541*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NGZN_IS_NONGLOBAL_ZONE, rootPath); 1542*5c51f124SMoriah Waterland 1543*5c51f124SMoriah Waterland return (R_SUCCESS); 1544*5c51f124SMoriah Waterland } 1545*5c51f124SMoriah Waterland 1546*5c51f124SMoriah Waterland /* 1547*5c51f124SMoriah Waterland * Name: cmd_is_running_system 1548*5c51f124SMoriah Waterland * Description: determine if target is a global zone 1549*5c51f124SMoriah Waterland * Scope: public 1550*5c51f124SMoriah Waterland * Arguments: argc,argv: 1551*5c51f124SMoriah Waterland * - optional path to target to test 1552*5c51f124SMoriah Waterland * Returns: int 1553*5c51f124SMoriah Waterland * == 0 - success 1554*5c51f124SMoriah Waterland * != 0 - failure 1555*5c51f124SMoriah Waterland * IMPLEMENTATION: 1556*5c51f124SMoriah Waterland * - must not be initial installation to the install root 1557*5c51f124SMoriah Waterland * - must not be installation of a zone 1558*5c51f124SMoriah Waterland * - must not be a diskless client 1559*5c51f124SMoriah Waterland * - $ROOTDIR must be "/" 1560*5c51f124SMoriah Waterland * - zone name must be "global" 1561*5c51f124SMoriah Waterland */ 1562*5c51f124SMoriah Waterland 1563*5c51f124SMoriah Waterland static int 1564*5c51f124SMoriah Waterland cmd_is_running_system(int argc, char **argv, GLOBALDATA_T *a_gdt) 1565*5c51f124SMoriah Waterland { 1566*5c51f124SMoriah Waterland char *rootPath = NULL; 1567*5c51f124SMoriah Waterland int c; 1568*5c51f124SMoriah Waterland int r; 1569*5c51f124SMoriah Waterland static char *cmdName = "is_running_system"; 1570*5c51f124SMoriah Waterland static int recursion = 0; 1571*5c51f124SMoriah Waterland 1572*5c51f124SMoriah Waterland /* process any command line options */ 1573*5c51f124SMoriah Waterland 1574*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1575*5c51f124SMoriah Waterland switch (c) { 1576*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1577*5c51f124SMoriah Waterland break; 1578*5c51f124SMoriah Waterland case '?': 1579*5c51f124SMoriah Waterland default: 1580*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1581*5c51f124SMoriah Waterland return (R_USAGE); 1582*5c51f124SMoriah Waterland } 1583*5c51f124SMoriah Waterland } 1584*5c51f124SMoriah Waterland 1585*5c51f124SMoriah Waterland /* prevent recursion */ 1586*5c51f124SMoriah Waterland 1587*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1588*5c51f124SMoriah Waterland 1589*5c51f124SMoriah Waterland /* a running system cannot be a diskless client */ 1590*5c51f124SMoriah Waterland 1591*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 1592*5c51f124SMoriah Waterland 1593*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 1594*5c51f124SMoriah Waterland 1595*5c51f124SMoriah Waterland recursion--; 1596*5c51f124SMoriah Waterland 1597*5c51f124SMoriah Waterland switch (r) { 1598*5c51f124SMoriah Waterland case R_SUCCESS: 1599*5c51f124SMoriah Waterland return (R_FAILURE); 1600*5c51f124SMoriah Waterland case R_FAILURE: 1601*5c51f124SMoriah Waterland break; 1602*5c51f124SMoriah Waterland case R_USAGE: 1603*5c51f124SMoriah Waterland case R_ERROR: 1604*5c51f124SMoriah Waterland default: 1605*5c51f124SMoriah Waterland return (r); 1606*5c51f124SMoriah Waterland } 1607*5c51f124SMoriah Waterland } 1608*5c51f124SMoriah Waterland 1609*5c51f124SMoriah Waterland /* normalize argc/argv */ 1610*5c51f124SMoriah Waterland 1611*5c51f124SMoriah Waterland argc -= optind; 1612*5c51f124SMoriah Waterland argv += optind; 1613*5c51f124SMoriah Waterland 1614*5c51f124SMoriah Waterland /* error if more than one argument */ 1615*5c51f124SMoriah Waterland 1616*5c51f124SMoriah Waterland if (argc > 1) { 1617*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1618*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1619*5c51f124SMoriah Waterland return (R_USAGE); 1620*5c51f124SMoriah Waterland } 1621*5c51f124SMoriah Waterland 1622*5c51f124SMoriah Waterland /* process root path if first argument present */ 1623*5c51f124SMoriah Waterland 1624*5c51f124SMoriah Waterland if (argc == 1) { 1625*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1626*5c51f124SMoriah Waterland return (R_ERROR); 1627*5c51f124SMoriah Waterland } 1628*5c51f124SMoriah Waterland } 1629*5c51f124SMoriah Waterland 1630*5c51f124SMoriah Waterland /* get current root path */ 1631*5c51f124SMoriah Waterland 1632*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1633*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1634*5c51f124SMoriah Waterland return (r); 1635*5c51f124SMoriah Waterland } 1636*5c51f124SMoriah Waterland 1637*5c51f124SMoriah Waterland /* start of command debugging information */ 1638*5c51f124SMoriah Waterland 1639*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1640*5c51f124SMoriah Waterland 1641*5c51f124SMoriah Waterland /* if root path is "/" then check zone name */ 1642*5c51f124SMoriah Waterland 1643*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") != 0) { 1644*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IRST_ROOTPATH_BAD, rootPath, "/"); 1645*5c51f124SMoriah Waterland return (R_FAILURE); 1646*5c51f124SMoriah Waterland } 1647*5c51f124SMoriah Waterland 1648*5c51f124SMoriah Waterland /* zone name must be global */ 1649*5c51f124SMoriah Waterland 1650*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { 1651*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_BAD, rootPath, 1652*5c51f124SMoriah Waterland GLOBAL_ZONENAME); 1653*5c51f124SMoriah Waterland return (R_FAILURE); 1654*5c51f124SMoriah Waterland } 1655*5c51f124SMoriah Waterland 1656*5c51f124SMoriah Waterland /* must not be initial installation to the install root */ 1657*5c51f124SMoriah Waterland 1658*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 1659*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 1660*5c51f124SMoriah Waterland /* initial install: install root cannot be the running system */ 1661*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IRST_INITIAL_INSTALL, rootPath); 1662*5c51f124SMoriah Waterland return (R_FAILURE); 1663*5c51f124SMoriah Waterland } 1664*5c51f124SMoriah Waterland 1665*5c51f124SMoriah Waterland /* must not be installation of a zone */ 1666*5c51f124SMoriah Waterland 1667*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 1668*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 1669*5c51f124SMoriah Waterland /* initial zone install: no path can be running system */ 1670*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IRST_ZONE_INSTALL, rootPath); 1671*5c51f124SMoriah Waterland return (R_FAILURE); 1672*5c51f124SMoriah Waterland } 1673*5c51f124SMoriah Waterland 1674*5c51f124SMoriah Waterland /* target is a running system */ 1675*5c51f124SMoriah Waterland 1676*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IRST_PATH_IS_RUNNING_SYSTEM, rootPath); 1677*5c51f124SMoriah Waterland 1678*5c51f124SMoriah Waterland return (R_SUCCESS); 1679*5c51f124SMoriah Waterland } 1680*5c51f124SMoriah Waterland 1681*5c51f124SMoriah Waterland /* 1682*5c51f124SMoriah Waterland * Name: cmd_can_add_driver 1683*5c51f124SMoriah Waterland * Description: determine if target is a global zone 1684*5c51f124SMoriah Waterland * Scope: public 1685*5c51f124SMoriah Waterland * Arguments: argc,argv: 1686*5c51f124SMoriah Waterland * - optional path to target to test 1687*5c51f124SMoriah Waterland * Returns: int 1688*5c51f124SMoriah Waterland * == 0 - success 1689*5c51f124SMoriah Waterland * != 0 - failure 1690*5c51f124SMoriah Waterland * Implementation: 1691*5c51f124SMoriah Waterland * A driver can be added to the system if the components of a Solaris 1692*5c51f124SMoriah Waterland * instance capable of loading drivers is present and it is not the 1693*5c51f124SMoriah Waterland * currently running system. 1694*5c51f124SMoriah Waterland */ 1695*5c51f124SMoriah Waterland 1696*5c51f124SMoriah Waterland static int 1697*5c51f124SMoriah Waterland cmd_can_add_driver(int argc, char **argv, GLOBALDATA_T *a_gdt) 1698*5c51f124SMoriah Waterland { 1699*5c51f124SMoriah Waterland char *rootPath = NULL; 1700*5c51f124SMoriah Waterland int c; 1701*5c51f124SMoriah Waterland int r; 1702*5c51f124SMoriah Waterland static char *cmdName = "can_add_driver"; 1703*5c51f124SMoriah Waterland static int recursion = 0; 1704*5c51f124SMoriah Waterland 1705*5c51f124SMoriah Waterland /* process any command line options */ 1706*5c51f124SMoriah Waterland 1707*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1708*5c51f124SMoriah Waterland switch (c) { 1709*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1710*5c51f124SMoriah Waterland break; 1711*5c51f124SMoriah Waterland case '?': 1712*5c51f124SMoriah Waterland default: 1713*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1714*5c51f124SMoriah Waterland return (R_USAGE); 1715*5c51f124SMoriah Waterland } 1716*5c51f124SMoriah Waterland } 1717*5c51f124SMoriah Waterland 1718*5c51f124SMoriah Waterland /* prevent recursion */ 1719*5c51f124SMoriah Waterland 1720*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1721*5c51f124SMoriah Waterland 1722*5c51f124SMoriah Waterland /* see if this is the current running system */ 1723*5c51f124SMoriah Waterland 1724*5c51f124SMoriah Waterland r = cmd_is_running_system(argc, argv, a_gdt); 1725*5c51f124SMoriah Waterland 1726*5c51f124SMoriah Waterland /* cannot be a diskless client */ 1727*5c51f124SMoriah Waterland 1728*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1729*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 1730*5c51f124SMoriah Waterland } 1731*5c51f124SMoriah Waterland 1732*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 1733*5c51f124SMoriah Waterland 1734*5c51f124SMoriah Waterland recursion--; 1735*5c51f124SMoriah Waterland 1736*5c51f124SMoriah Waterland switch (r) { 1737*5c51f124SMoriah Waterland case R_SUCCESS: 1738*5c51f124SMoriah Waterland /* is a running system */ 1739*5c51f124SMoriah Waterland return (R_FAILURE); 1740*5c51f124SMoriah Waterland case R_FAILURE: 1741*5c51f124SMoriah Waterland /* not a running syste */ 1742*5c51f124SMoriah Waterland break; 1743*5c51f124SMoriah Waterland case R_USAGE: 1744*5c51f124SMoriah Waterland case R_ERROR: 1745*5c51f124SMoriah Waterland default: 1746*5c51f124SMoriah Waterland /* cannot determine if is a running system */ 1747*5c51f124SMoriah Waterland return (r); 1748*5c51f124SMoriah Waterland } 1749*5c51f124SMoriah Waterland } 1750*5c51f124SMoriah Waterland 1751*5c51f124SMoriah Waterland /* normalize argc/argv */ 1752*5c51f124SMoriah Waterland 1753*5c51f124SMoriah Waterland argc -= optind; 1754*5c51f124SMoriah Waterland argv += optind; 1755*5c51f124SMoriah Waterland 1756*5c51f124SMoriah Waterland /* error if more than one argument */ 1757*5c51f124SMoriah Waterland 1758*5c51f124SMoriah Waterland if (argc > 1) { 1759*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1760*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1761*5c51f124SMoriah Waterland return (R_USAGE); 1762*5c51f124SMoriah Waterland } 1763*5c51f124SMoriah Waterland 1764*5c51f124SMoriah Waterland /* process root path if first argument present */ 1765*5c51f124SMoriah Waterland 1766*5c51f124SMoriah Waterland if (argc == 1) { 1767*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1768*5c51f124SMoriah Waterland return (R_ERROR); 1769*5c51f124SMoriah Waterland } 1770*5c51f124SMoriah Waterland } 1771*5c51f124SMoriah Waterland 1772*5c51f124SMoriah Waterland /* get current root path */ 1773*5c51f124SMoriah Waterland 1774*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1775*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1776*5c51f124SMoriah Waterland return (r); 1777*5c51f124SMoriah Waterland } 1778*5c51f124SMoriah Waterland 1779*5c51f124SMoriah Waterland /* start of command debugging information */ 1780*5c51f124SMoriah Waterland 1781*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1782*5c51f124SMoriah Waterland 1783*5c51f124SMoriah Waterland /* /etc must exist and must not be a symbolic link */ 1784*5c51f124SMoriah Waterland 1785*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1786*5c51f124SMoriah Waterland "%s/%s", rootPath, "/etc"); 1787*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1788*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, 1789*5c51f124SMoriah Waterland rootPath, "/etc"); 1790*5c51f124SMoriah Waterland return (R_FAILURE); 1791*5c51f124SMoriah Waterland } 1792*5c51f124SMoriah Waterland 1793*5c51f124SMoriah Waterland /* /platform must exist and must not be a symbolic link */ 1794*5c51f124SMoriah Waterland 1795*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1796*5c51f124SMoriah Waterland "%s/%s", rootPath, "/platform"); 1797*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1798*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, 1799*5c51f124SMoriah Waterland rootPath, "/platform"); 1800*5c51f124SMoriah Waterland return (R_FAILURE); 1801*5c51f124SMoriah Waterland } 1802*5c51f124SMoriah Waterland 1803*5c51f124SMoriah Waterland /* /kernel must exist and must not be a symbolic link */ 1804*5c51f124SMoriah Waterland 1805*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1806*5c51f124SMoriah Waterland "%s/%s", rootPath, "/kernel"); 1807*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1808*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ADDV_PATH_IS_SYMLINK, 1809*5c51f124SMoriah Waterland rootPath, "/kernel"); 1810*5c51f124SMoriah Waterland return (R_FAILURE); 1811*5c51f124SMoriah Waterland } 1812*5c51f124SMoriah Waterland 1813*5c51f124SMoriah Waterland /* can add a driver */ 1814*5c51f124SMoriah Waterland 1815*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ADDV_YES, rootPath); 1816*5c51f124SMoriah Waterland 1817*5c51f124SMoriah Waterland return (R_SUCCESS); 1818*5c51f124SMoriah Waterland } 1819*5c51f124SMoriah Waterland 1820*5c51f124SMoriah Waterland /* 1821*5c51f124SMoriah Waterland * Name: cmd_can_update_driver 1822*5c51f124SMoriah Waterland * Description: determine if target is a global zone 1823*5c51f124SMoriah Waterland * Scope: public 1824*5c51f124SMoriah Waterland * Arguments: argc,argv: 1825*5c51f124SMoriah Waterland * - optional path to target to test 1826*5c51f124SMoriah Waterland * Returns: int 1827*5c51f124SMoriah Waterland * == 0 - success 1828*5c51f124SMoriah Waterland * != 0 - failure 1829*5c51f124SMoriah Waterland * Implementation: 1830*5c51f124SMoriah Waterland * A driver can be added to the system if the components of a Solaris 1831*5c51f124SMoriah Waterland * instance capable of loading drivers is present and it is not the 1832*5c51f124SMoriah Waterland * currently running system. 1833*5c51f124SMoriah Waterland */ 1834*5c51f124SMoriah Waterland 1835*5c51f124SMoriah Waterland static int 1836*5c51f124SMoriah Waterland cmd_can_update_driver(int argc, char **argv, GLOBALDATA_T *a_gdt) 1837*5c51f124SMoriah Waterland { 1838*5c51f124SMoriah Waterland char *rootPath = NULL; 1839*5c51f124SMoriah Waterland int c; 1840*5c51f124SMoriah Waterland int r; 1841*5c51f124SMoriah Waterland static char *cmdName = "can_update_driver"; 1842*5c51f124SMoriah Waterland static int recursion = 0; 1843*5c51f124SMoriah Waterland 1844*5c51f124SMoriah Waterland /* process any command line options */ 1845*5c51f124SMoriah Waterland 1846*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1847*5c51f124SMoriah Waterland switch (c) { 1848*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1849*5c51f124SMoriah Waterland break; 1850*5c51f124SMoriah Waterland case '?': 1851*5c51f124SMoriah Waterland default: 1852*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1853*5c51f124SMoriah Waterland return (R_USAGE); 1854*5c51f124SMoriah Waterland } 1855*5c51f124SMoriah Waterland } 1856*5c51f124SMoriah Waterland 1857*5c51f124SMoriah Waterland /* prevent recursion */ 1858*5c51f124SMoriah Waterland 1859*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1860*5c51f124SMoriah Waterland 1861*5c51f124SMoriah Waterland /* see if this is the current running system */ 1862*5c51f124SMoriah Waterland 1863*5c51f124SMoriah Waterland r = cmd_is_running_system(argc, argv, a_gdt); 1864*5c51f124SMoriah Waterland 1865*5c51f124SMoriah Waterland /* cannot be a diskless client */ 1866*5c51f124SMoriah Waterland 1867*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1868*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 1869*5c51f124SMoriah Waterland } 1870*5c51f124SMoriah Waterland 1871*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 1872*5c51f124SMoriah Waterland 1873*5c51f124SMoriah Waterland recursion--; 1874*5c51f124SMoriah Waterland 1875*5c51f124SMoriah Waterland switch (r) { 1876*5c51f124SMoriah Waterland case R_SUCCESS: 1877*5c51f124SMoriah Waterland /* is a running system */ 1878*5c51f124SMoriah Waterland return (R_FAILURE); 1879*5c51f124SMoriah Waterland case R_FAILURE: 1880*5c51f124SMoriah Waterland /* not a running syste */ 1881*5c51f124SMoriah Waterland break; 1882*5c51f124SMoriah Waterland case R_USAGE: 1883*5c51f124SMoriah Waterland case R_ERROR: 1884*5c51f124SMoriah Waterland default: 1885*5c51f124SMoriah Waterland /* cannot determine if is a running system */ 1886*5c51f124SMoriah Waterland return (r); 1887*5c51f124SMoriah Waterland } 1888*5c51f124SMoriah Waterland } 1889*5c51f124SMoriah Waterland 1890*5c51f124SMoriah Waterland /* normalize argc/argv */ 1891*5c51f124SMoriah Waterland 1892*5c51f124SMoriah Waterland argc -= optind; 1893*5c51f124SMoriah Waterland argv += optind; 1894*5c51f124SMoriah Waterland 1895*5c51f124SMoriah Waterland /* error if more than one argument */ 1896*5c51f124SMoriah Waterland 1897*5c51f124SMoriah Waterland if (argc > 1) { 1898*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 1899*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 1900*5c51f124SMoriah Waterland return (R_USAGE); 1901*5c51f124SMoriah Waterland } 1902*5c51f124SMoriah Waterland 1903*5c51f124SMoriah Waterland /* process root path if first argument present */ 1904*5c51f124SMoriah Waterland 1905*5c51f124SMoriah Waterland if (argc == 1) { 1906*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 1907*5c51f124SMoriah Waterland return (R_ERROR); 1908*5c51f124SMoriah Waterland } 1909*5c51f124SMoriah Waterland } 1910*5c51f124SMoriah Waterland 1911*5c51f124SMoriah Waterland /* get current root path */ 1912*5c51f124SMoriah Waterland 1913*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 1914*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1915*5c51f124SMoriah Waterland return (r); 1916*5c51f124SMoriah Waterland } 1917*5c51f124SMoriah Waterland 1918*5c51f124SMoriah Waterland /* start of command debugging information */ 1919*5c51f124SMoriah Waterland 1920*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 1921*5c51f124SMoriah Waterland 1922*5c51f124SMoriah Waterland /* /etc must exist and must not be a symbolic link */ 1923*5c51f124SMoriah Waterland 1924*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1925*5c51f124SMoriah Waterland "%s/%s", rootPath, "/etc"); 1926*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1927*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, 1928*5c51f124SMoriah Waterland rootPath, "/etc"); 1929*5c51f124SMoriah Waterland return (R_FAILURE); 1930*5c51f124SMoriah Waterland } 1931*5c51f124SMoriah Waterland 1932*5c51f124SMoriah Waterland /* /platform must exist and must not be a symbolic link */ 1933*5c51f124SMoriah Waterland 1934*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1935*5c51f124SMoriah Waterland "%s/%s", rootPath, "/platform"); 1936*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1937*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, 1938*5c51f124SMoriah Waterland rootPath, "/platform"); 1939*5c51f124SMoriah Waterland return (R_FAILURE); 1940*5c51f124SMoriah Waterland } 1941*5c51f124SMoriah Waterland 1942*5c51f124SMoriah Waterland /* /kernel must exist and must not be a symbolic link */ 1943*5c51f124SMoriah Waterland 1944*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 1945*5c51f124SMoriah Waterland "%s/%s", rootPath, "/kernel"); 1946*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 1947*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_UPDV_PATH_IS_SYMLINK, 1948*5c51f124SMoriah Waterland rootPath, "/kernel"); 1949*5c51f124SMoriah Waterland return (R_FAILURE); 1950*5c51f124SMoriah Waterland } 1951*5c51f124SMoriah Waterland 1952*5c51f124SMoriah Waterland /* can update driver */ 1953*5c51f124SMoriah Waterland 1954*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_UPDV_YES, rootPath); 1955*5c51f124SMoriah Waterland 1956*5c51f124SMoriah Waterland return (R_SUCCESS); 1957*5c51f124SMoriah Waterland } 1958*5c51f124SMoriah Waterland 1959*5c51f124SMoriah Waterland /* 1960*5c51f124SMoriah Waterland * Name: cmd_can_remove_driver 1961*5c51f124SMoriah Waterland * Description: determine if target is a global zone 1962*5c51f124SMoriah Waterland * Scope: public 1963*5c51f124SMoriah Waterland * Arguments: argc,argv: 1964*5c51f124SMoriah Waterland * - optional path to target to test 1965*5c51f124SMoriah Waterland * Returns: int 1966*5c51f124SMoriah Waterland * == 0 - success 1967*5c51f124SMoriah Waterland * != 0 - failure 1968*5c51f124SMoriah Waterland * Implementation: 1969*5c51f124SMoriah Waterland * A driver can be added to the system if the components of a Solaris 1970*5c51f124SMoriah Waterland * instance capable of loading drivers is present and it is not the 1971*5c51f124SMoriah Waterland * currently running system. 1972*5c51f124SMoriah Waterland */ 1973*5c51f124SMoriah Waterland 1974*5c51f124SMoriah Waterland static int 1975*5c51f124SMoriah Waterland cmd_can_remove_driver(int argc, char **argv, GLOBALDATA_T *a_gdt) 1976*5c51f124SMoriah Waterland { 1977*5c51f124SMoriah Waterland char *rootPath = NULL; 1978*5c51f124SMoriah Waterland int c; 1979*5c51f124SMoriah Waterland int r; 1980*5c51f124SMoriah Waterland static char *cmdName = "can_remove_driver"; 1981*5c51f124SMoriah Waterland static int recursion = 0; 1982*5c51f124SMoriah Waterland 1983*5c51f124SMoriah Waterland /* process any command line options */ 1984*5c51f124SMoriah Waterland 1985*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 1986*5c51f124SMoriah Waterland switch (c) { 1987*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 1988*5c51f124SMoriah Waterland break; 1989*5c51f124SMoriah Waterland case '?': 1990*5c51f124SMoriah Waterland default: 1991*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 1992*5c51f124SMoriah Waterland return (R_USAGE); 1993*5c51f124SMoriah Waterland } 1994*5c51f124SMoriah Waterland } 1995*5c51f124SMoriah Waterland 1996*5c51f124SMoriah Waterland /* prevent recursion */ 1997*5c51f124SMoriah Waterland 1998*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 1999*5c51f124SMoriah Waterland 2000*5c51f124SMoriah Waterland /* see if this is the current running system */ 2001*5c51f124SMoriah Waterland 2002*5c51f124SMoriah Waterland r = cmd_is_running_system(argc, argv, a_gdt); 2003*5c51f124SMoriah Waterland 2004*5c51f124SMoriah Waterland /* cannot be a diskless client */ 2005*5c51f124SMoriah Waterland 2006*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2007*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 2008*5c51f124SMoriah Waterland } 2009*5c51f124SMoriah Waterland 2010*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 2011*5c51f124SMoriah Waterland 2012*5c51f124SMoriah Waterland recursion--; 2013*5c51f124SMoriah Waterland 2014*5c51f124SMoriah Waterland switch (r) { 2015*5c51f124SMoriah Waterland case R_SUCCESS: 2016*5c51f124SMoriah Waterland /* is a running system */ 2017*5c51f124SMoriah Waterland return (R_FAILURE); 2018*5c51f124SMoriah Waterland case R_FAILURE: 2019*5c51f124SMoriah Waterland /* not a running syste */ 2020*5c51f124SMoriah Waterland break; 2021*5c51f124SMoriah Waterland case R_USAGE: 2022*5c51f124SMoriah Waterland case R_ERROR: 2023*5c51f124SMoriah Waterland default: 2024*5c51f124SMoriah Waterland /* cannot determine if is a running system */ 2025*5c51f124SMoriah Waterland return (r); 2026*5c51f124SMoriah Waterland } 2027*5c51f124SMoriah Waterland } 2028*5c51f124SMoriah Waterland 2029*5c51f124SMoriah Waterland /* normalize argc/argv */ 2030*5c51f124SMoriah Waterland 2031*5c51f124SMoriah Waterland argc -= optind; 2032*5c51f124SMoriah Waterland argv += optind; 2033*5c51f124SMoriah Waterland 2034*5c51f124SMoriah Waterland /* error if more than one argument */ 2035*5c51f124SMoriah Waterland 2036*5c51f124SMoriah Waterland if (argc > 1) { 2037*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2038*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2039*5c51f124SMoriah Waterland return (R_USAGE); 2040*5c51f124SMoriah Waterland } 2041*5c51f124SMoriah Waterland 2042*5c51f124SMoriah Waterland /* process root path if first argument present */ 2043*5c51f124SMoriah Waterland 2044*5c51f124SMoriah Waterland if (argc == 1) { 2045*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2046*5c51f124SMoriah Waterland return (R_ERROR); 2047*5c51f124SMoriah Waterland } 2048*5c51f124SMoriah Waterland } 2049*5c51f124SMoriah Waterland 2050*5c51f124SMoriah Waterland /* get current root path */ 2051*5c51f124SMoriah Waterland 2052*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2053*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2054*5c51f124SMoriah Waterland return (r); 2055*5c51f124SMoriah Waterland } 2056*5c51f124SMoriah Waterland 2057*5c51f124SMoriah Waterland /* start of command debugging information */ 2058*5c51f124SMoriah Waterland 2059*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2060*5c51f124SMoriah Waterland 2061*5c51f124SMoriah Waterland /* /etc must exist and must not be a symbolic link */ 2062*5c51f124SMoriah Waterland 2063*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 2064*5c51f124SMoriah Waterland "%s/%s", rootPath, "/etc"); 2065*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2066*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, 2067*5c51f124SMoriah Waterland rootPath, "/etc"); 2068*5c51f124SMoriah Waterland return (R_FAILURE); 2069*5c51f124SMoriah Waterland } 2070*5c51f124SMoriah Waterland 2071*5c51f124SMoriah Waterland /* /platform must exist and must not be a symbolic link */ 2072*5c51f124SMoriah Waterland 2073*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 2074*5c51f124SMoriah Waterland "%s/%s", rootPath, "/platform"); 2075*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2076*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, 2077*5c51f124SMoriah Waterland rootPath, "/platform"); 2078*5c51f124SMoriah Waterland return (R_FAILURE); 2079*5c51f124SMoriah Waterland } 2080*5c51f124SMoriah Waterland 2081*5c51f124SMoriah Waterland /* /kernel must exist and must not be a symbolic link */ 2082*5c51f124SMoriah Waterland 2083*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_NOT_SYMBOLIC_LINK, 2084*5c51f124SMoriah Waterland "%s/%s", rootPath, "/kernel"); 2085*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2086*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_RMDV_PATH_IS_SYMLINK, 2087*5c51f124SMoriah Waterland rootPath, "/kernel"); 2088*5c51f124SMoriah Waterland return (R_FAILURE); 2089*5c51f124SMoriah Waterland } 2090*5c51f124SMoriah Waterland 2091*5c51f124SMoriah Waterland /* can remove driver */ 2092*5c51f124SMoriah Waterland 2093*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_RMDV_YES, rootPath); 2094*5c51f124SMoriah Waterland 2095*5c51f124SMoriah Waterland return (R_SUCCESS); 2096*5c51f124SMoriah Waterland } 2097*5c51f124SMoriah Waterland 2098*5c51f124SMoriah Waterland /* 2099*5c51f124SMoriah Waterland * Name: cmd_is_path_writable 2100*5c51f124SMoriah Waterland * Description: determine if target path is writable (not inherited) 2101*5c51f124SMoriah Waterland * Scope: public 2102*5c51f124SMoriah Waterland * Arguments: argc,argv: 2103*5c51f124SMoriah Waterland * - optional path to target to test 2104*5c51f124SMoriah Waterland * Returns: int 2105*5c51f124SMoriah Waterland * == 0 - success 2106*5c51f124SMoriah Waterland * != 0 - failure 2107*5c51f124SMoriah Waterland * IMPLEMENTATION: 2108*5c51f124SMoriah Waterland * - path must be found in the file systems configured 2109*5c51f124SMoriah Waterland * - file system type must not be "inherited" 2110*5c51f124SMoriah Waterland * - mount options must not include "read only" 2111*5c51f124SMoriah Waterland */ 2112*5c51f124SMoriah Waterland 2113*5c51f124SMoriah Waterland static int 2114*5c51f124SMoriah Waterland cmd_is_path_writable(int argc, char **argv, GLOBALDATA_T *a_gdt) 2115*5c51f124SMoriah Waterland { 2116*5c51f124SMoriah Waterland FSI_T *list; 2117*5c51f124SMoriah Waterland char *rootPath = NULL; 2118*5c51f124SMoriah Waterland int c; 2119*5c51f124SMoriah Waterland int n; 2120*5c51f124SMoriah Waterland int nn; 2121*5c51f124SMoriah Waterland int r; 2122*5c51f124SMoriah Waterland long listSize; 2123*5c51f124SMoriah Waterland long rootPathLen; 2124*5c51f124SMoriah Waterland static char *cmdName = "is_path_writable"; 2125*5c51f124SMoriah Waterland static int recursion = 0; 2126*5c51f124SMoriah Waterland 2127*5c51f124SMoriah Waterland /* process any command line options */ 2128*5c51f124SMoriah Waterland 2129*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2130*5c51f124SMoriah Waterland switch (c) { 2131*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2132*5c51f124SMoriah Waterland break; 2133*5c51f124SMoriah Waterland case '?': 2134*5c51f124SMoriah Waterland default: 2135*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2136*5c51f124SMoriah Waterland return (R_USAGE); 2137*5c51f124SMoriah Waterland } 2138*5c51f124SMoriah Waterland } 2139*5c51f124SMoriah Waterland 2140*5c51f124SMoriah Waterland /* prevent recursion */ 2141*5c51f124SMoriah Waterland 2142*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 2143*5c51f124SMoriah Waterland recursion--; 2144*5c51f124SMoriah Waterland } 2145*5c51f124SMoriah Waterland 2146*5c51f124SMoriah Waterland /* normalize argc/argv */ 2147*5c51f124SMoriah Waterland 2148*5c51f124SMoriah Waterland argc -= optind; 2149*5c51f124SMoriah Waterland argv += optind; 2150*5c51f124SMoriah Waterland 2151*5c51f124SMoriah Waterland /* error if more than one argument */ 2152*5c51f124SMoriah Waterland 2153*5c51f124SMoriah Waterland if (argc > 1) { 2154*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2155*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2156*5c51f124SMoriah Waterland return (R_USAGE); 2157*5c51f124SMoriah Waterland } 2158*5c51f124SMoriah Waterland 2159*5c51f124SMoriah Waterland /* process root path if first argument present */ 2160*5c51f124SMoriah Waterland 2161*5c51f124SMoriah Waterland if (argc != 1) { 2162*5c51f124SMoriah Waterland (void) usage(ERR_REQUIRED_ROOTPATH_MISSING, cmdName); 2163*5c51f124SMoriah Waterland return (R_USAGE); 2164*5c51f124SMoriah Waterland } 2165*5c51f124SMoriah Waterland 2166*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2167*5c51f124SMoriah Waterland return (R_ERROR); 2168*5c51f124SMoriah Waterland } 2169*5c51f124SMoriah Waterland 2170*5c51f124SMoriah Waterland /* get current root path */ 2171*5c51f124SMoriah Waterland 2172*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2173*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2174*5c51f124SMoriah Waterland return (r); 2175*5c51f124SMoriah Waterland } 2176*5c51f124SMoriah Waterland 2177*5c51f124SMoriah Waterland /* start of command debugging information */ 2178*5c51f124SMoriah Waterland 2179*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2180*5c51f124SMoriah Waterland 2181*5c51f124SMoriah Waterland /* search file system conf for this path */ 2182*5c51f124SMoriah Waterland 2183*5c51f124SMoriah Waterland rootPathLen = strlen(rootPath); 2184*5c51f124SMoriah Waterland list = a_gdt->gd_fileSystemConfig; 2185*5c51f124SMoriah Waterland listSize = a_gdt->gd_fileSystemConfigLen; 2186*5c51f124SMoriah Waterland for (nn = 0, n = 0; n < listSize; n++) { 2187*5c51f124SMoriah Waterland long mplen = strlen(list[n].fsi_mntPoint); 2188*5c51f124SMoriah Waterland if (rootPathLen < mplen) { 2189*5c51f124SMoriah Waterland /* root path is longer than target, ignore */ 2190*5c51f124SMoriah Waterland continue; 2191*5c51f124SMoriah Waterland } 2192*5c51f124SMoriah Waterland if (strncmp(rootPath, list[n].fsi_mntPoint, mplen) == 0) { 2193*5c51f124SMoriah Waterland /* remember last partial match */ 2194*5c51f124SMoriah Waterland nn = n; 2195*5c51f124SMoriah Waterland } 2196*5c51f124SMoriah Waterland } 2197*5c51f124SMoriah Waterland 2198*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_PWRT_INFO, 2199*5c51f124SMoriah Waterland rootPath, list[nn].fsi_mntPoint, list[nn].fsi_fsType, 2200*5c51f124SMoriah Waterland list[nn].fsi_mntOptions); 2201*5c51f124SMoriah Waterland 2202*5c51f124SMoriah Waterland /* 2203*5c51f124SMoriah Waterland * need to determine if the mount point is writeable: 2204*5c51f124SMoriah Waterland * If parent mount point is "inherited" then it is not writeable 2205*5c51f124SMoriah Waterland */ 2206*5c51f124SMoriah Waterland 2207*5c51f124SMoriah Waterland if (strcmp(list[nn].fsi_fsType, FSTYPE_INHERITED) == 0) { 2208*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_PWRT_INHERITED, rootPath, 2209*5c51f124SMoriah Waterland list[nn].fsi_mntOptions); 2210*5c51f124SMoriah Waterland return (R_FAILURE); 2211*5c51f124SMoriah Waterland } 2212*5c51f124SMoriah Waterland 2213*5c51f124SMoriah Waterland /* see if the file system is mounted with the "read only" option */ 2214*5c51f124SMoriah Waterland 2215*5c51f124SMoriah Waterland r = mountOptionPresent(list[nn].fsi_mntOptions, MNTOPT_RO); 2216*5c51f124SMoriah Waterland if (r == R_SUCCESS) { 2217*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_PWRT_READONLY, 2218*5c51f124SMoriah Waterland rootPath, list[nn].fsi_mntOptions); 2219*5c51f124SMoriah Waterland return (R_FAILURE); 2220*5c51f124SMoriah Waterland } 2221*5c51f124SMoriah Waterland 2222*5c51f124SMoriah Waterland /* target path is writable */ 2223*5c51f124SMoriah Waterland 2224*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_PWRT_IS, rootPath); 2225*5c51f124SMoriah Waterland 2226*5c51f124SMoriah Waterland return (R_SUCCESS); 2227*5c51f124SMoriah Waterland } 2228*5c51f124SMoriah Waterland 2229*5c51f124SMoriah Waterland /* 2230*5c51f124SMoriah Waterland * Name: cmd_is_alternative_root 2231*5c51f124SMoriah Waterland * Description: determine if target is an alternative root 2232*5c51f124SMoriah Waterland * Scope: public 2233*5c51f124SMoriah Waterland * Arguments: argc,argv: 2234*5c51f124SMoriah Waterland * - optional path to target to test 2235*5c51f124SMoriah Waterland * Returns: int 2236*5c51f124SMoriah Waterland * == 0 - success 2237*5c51f124SMoriah Waterland * != 0 - failure 2238*5c51f124SMoriah Waterland * Implementation: 2239*5c51f124SMoriah Waterland * - success if an initial installation to the install root 2240*5c51f124SMoriah Waterland * (an initial install to $PKG_INSTALL_ROOT means that $PKG_INSTALL_ROOT 2241*5c51f124SMoriah Waterland * points to an alternative root that is under construction) 2242*5c51f124SMoriah Waterland * - must not be installation of a zone 2243*5c51f124SMoriah Waterland * - must not be a boot environment 2244*5c51f124SMoriah Waterland * - must not be a diskless client 2245*5c51f124SMoriah Waterland * - must not be a mounted miniroot 2246*5c51f124SMoriah Waterland * - must not be a netinstall image 2247*5c51f124SMoriah Waterland * - must not be a nonglobal zone 2248*5c51f124SMoriah Waterland * - must not be a running system 2249*5c51f124SMoriah Waterland * - $ROOTDIR must not be "/" 2250*5c51f124SMoriah Waterland * - $ROOTDIR/var must exist 2251*5c51f124SMoriah Waterland */ 2252*5c51f124SMoriah Waterland 2253*5c51f124SMoriah Waterland static int 2254*5c51f124SMoriah Waterland cmd_is_alternative_root(int argc, char **argv, GLOBALDATA_T *a_gdt) 2255*5c51f124SMoriah Waterland { 2256*5c51f124SMoriah Waterland char *rootPath = NULL; 2257*5c51f124SMoriah Waterland int c; 2258*5c51f124SMoriah Waterland int r; 2259*5c51f124SMoriah Waterland static char *cmdName = "is_alternative_root"; 2260*5c51f124SMoriah Waterland static int recursion = 0; 2261*5c51f124SMoriah Waterland 2262*5c51f124SMoriah Waterland /* process any command line options */ 2263*5c51f124SMoriah Waterland 2264*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2265*5c51f124SMoriah Waterland switch (c) { 2266*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2267*5c51f124SMoriah Waterland break; 2268*5c51f124SMoriah Waterland case '?': 2269*5c51f124SMoriah Waterland default: 2270*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2271*5c51f124SMoriah Waterland return (R_USAGE); 2272*5c51f124SMoriah Waterland } 2273*5c51f124SMoriah Waterland } 2274*5c51f124SMoriah Waterland 2275*5c51f124SMoriah Waterland /* prevent recursion */ 2276*5c51f124SMoriah Waterland 2277*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 2278*5c51f124SMoriah Waterland 2279*5c51f124SMoriah Waterland /* 2280*5c51f124SMoriah Waterland * an alternative root cannot be any of the following 2281*5c51f124SMoriah Waterland */ 2282*5c51f124SMoriah Waterland 2283*5c51f124SMoriah Waterland /* cannot be a boot_environment */ 2284*5c51f124SMoriah Waterland 2285*5c51f124SMoriah Waterland r = cmd_is_boot_environment(argc, argv, a_gdt); 2286*5c51f124SMoriah Waterland 2287*5c51f124SMoriah Waterland /* cannot be a diskless_client */ 2288*5c51f124SMoriah Waterland 2289*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2290*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 2291*5c51f124SMoriah Waterland } 2292*5c51f124SMoriah Waterland 2293*5c51f124SMoriah Waterland /* cannot be a mounted_miniroot */ 2294*5c51f124SMoriah Waterland 2295*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2296*5c51f124SMoriah Waterland r = cmd_is_mounted_miniroot(argc, argv, a_gdt); 2297*5c51f124SMoriah Waterland } 2298*5c51f124SMoriah Waterland 2299*5c51f124SMoriah Waterland /* cannot be a netinstall_image */ 2300*5c51f124SMoriah Waterland 2301*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2302*5c51f124SMoriah Waterland r = cmd_is_netinstall_image(argc, argv, a_gdt); 2303*5c51f124SMoriah Waterland } 2304*5c51f124SMoriah Waterland 2305*5c51f124SMoriah Waterland /* cannot be a nonglobal_zone */ 2306*5c51f124SMoriah Waterland 2307*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2308*5c51f124SMoriah Waterland r = cmd_is_nonglobal_zone(argc, argv, a_gdt); 2309*5c51f124SMoriah Waterland } 2310*5c51f124SMoriah Waterland 2311*5c51f124SMoriah Waterland /* cannot be a running_system */ 2312*5c51f124SMoriah Waterland 2313*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2314*5c51f124SMoriah Waterland r = cmd_is_running_system(argc, argv, a_gdt); 2315*5c51f124SMoriah Waterland } 2316*5c51f124SMoriah Waterland 2317*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 2318*5c51f124SMoriah Waterland 2319*5c51f124SMoriah Waterland recursion--; 2320*5c51f124SMoriah Waterland 2321*5c51f124SMoriah Waterland /* return failure if any of the preceeding are true */ 2322*5c51f124SMoriah Waterland 2323*5c51f124SMoriah Waterland switch (r) { 2324*5c51f124SMoriah Waterland case R_SUCCESS: 2325*5c51f124SMoriah Waterland return (R_FAILURE); 2326*5c51f124SMoriah Waterland case R_FAILURE: 2327*5c51f124SMoriah Waterland break; 2328*5c51f124SMoriah Waterland case R_USAGE: 2329*5c51f124SMoriah Waterland case R_ERROR: 2330*5c51f124SMoriah Waterland default: 2331*5c51f124SMoriah Waterland return (r); 2332*5c51f124SMoriah Waterland } 2333*5c51f124SMoriah Waterland } 2334*5c51f124SMoriah Waterland 2335*5c51f124SMoriah Waterland /* normalize argc/argv */ 2336*5c51f124SMoriah Waterland 2337*5c51f124SMoriah Waterland argc -= optind; 2338*5c51f124SMoriah Waterland argv += optind; 2339*5c51f124SMoriah Waterland 2340*5c51f124SMoriah Waterland /* error if more than one argument */ 2341*5c51f124SMoriah Waterland 2342*5c51f124SMoriah Waterland if (argc > 1) { 2343*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2344*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2345*5c51f124SMoriah Waterland return (R_USAGE); 2346*5c51f124SMoriah Waterland } 2347*5c51f124SMoriah Waterland 2348*5c51f124SMoriah Waterland /* process root path if first argument present */ 2349*5c51f124SMoriah Waterland 2350*5c51f124SMoriah Waterland if (argc == 1) { 2351*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2352*5c51f124SMoriah Waterland return (R_ERROR); 2353*5c51f124SMoriah Waterland } 2354*5c51f124SMoriah Waterland } 2355*5c51f124SMoriah Waterland 2356*5c51f124SMoriah Waterland /* get current root path */ 2357*5c51f124SMoriah Waterland 2358*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2359*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2360*5c51f124SMoriah Waterland return (r); 2361*5c51f124SMoriah Waterland } 2362*5c51f124SMoriah Waterland 2363*5c51f124SMoriah Waterland /* start of command debugging information */ 2364*5c51f124SMoriah Waterland 2365*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2366*5c51f124SMoriah Waterland 2367*5c51f124SMoriah Waterland /* return success if initial installation */ 2368*5c51f124SMoriah Waterland 2369*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 2370*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 2371*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IALR_INITIAL_INSTALL, rootPath); 2372*5c51f124SMoriah Waterland return (R_SUCCESS); 2373*5c51f124SMoriah Waterland } 2374*5c51f124SMoriah Waterland 2375*5c51f124SMoriah Waterland /* root path must not be "/" */ 2376*5c51f124SMoriah Waterland 2377*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") == 0) { 2378*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IALR_BAD_ROOTPATH, rootPath, "/"); 2379*5c51f124SMoriah Waterland return (R_FAILURE); 2380*5c51f124SMoriah Waterland } 2381*5c51f124SMoriah Waterland 2382*5c51f124SMoriah Waterland /* /var must exist */ 2383*5c51f124SMoriah Waterland 2384*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS, 2385*5c51f124SMoriah Waterland "%s/%s", rootPath, "/var"); 2386*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2387*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IALR_PATH_DOES_NOT_EXIST, 2388*5c51f124SMoriah Waterland rootPath, "/var"); 2389*5c51f124SMoriah Waterland return (R_FAILURE); 2390*5c51f124SMoriah Waterland } 2391*5c51f124SMoriah Waterland 2392*5c51f124SMoriah Waterland /* must not be installation of a zone */ 2393*5c51f124SMoriah Waterland 2394*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 2395*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 2396*5c51f124SMoriah Waterland /* initial zone install: no path can be alternative root */ 2397*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IALR_ZONE_INSTALL, rootPath); 2398*5c51f124SMoriah Waterland return (R_FAILURE); 2399*5c51f124SMoriah Waterland } 2400*5c51f124SMoriah Waterland 2401*5c51f124SMoriah Waterland /* target is an alternative root */ 2402*5c51f124SMoriah Waterland 2403*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_IALR_IS, rootPath); 2404*5c51f124SMoriah Waterland 2405*5c51f124SMoriah Waterland return (R_SUCCESS); 2406*5c51f124SMoriah Waterland } 2407*5c51f124SMoriah Waterland 2408*5c51f124SMoriah Waterland /* 2409*5c51f124SMoriah Waterland * Name: cmd_is_boot_environment 2410*5c51f124SMoriah Waterland * Description: determine if target is an alternative, inactive boot environment 2411*5c51f124SMoriah Waterland * Scope: public 2412*5c51f124SMoriah Waterland * Arguments: argc,argv: 2413*5c51f124SMoriah Waterland * - optional path to target to test 2414*5c51f124SMoriah Waterland * Returns: int 2415*5c51f124SMoriah Waterland * == 0 - success 2416*5c51f124SMoriah Waterland * != 0 - failure 2417*5c51f124SMoriah Waterland * IMPLEMENTATION: 2418*5c51f124SMoriah Waterland * - must not be initial installation to the install root 2419*5c51f124SMoriah Waterland * - must not be installation of a zone 2420*5c51f124SMoriah Waterland * - must not be a diskless client 2421*5c51f124SMoriah Waterland * - must not be a netinstall image 2422*5c51f124SMoriah Waterland * - must not be a mounted miniroot 2423*5c51f124SMoriah Waterland * - $ROOTDIR must not be "/" 2424*5c51f124SMoriah Waterland * - $ROOTDIR/etc/lutab must exist 2425*5c51f124SMoriah Waterland * - $ROOTDIR/etc/lu must exist and must be a directory 2426*5c51f124SMoriah Waterland */ 2427*5c51f124SMoriah Waterland 2428*5c51f124SMoriah Waterland static int 2429*5c51f124SMoriah Waterland cmd_is_boot_environment(int argc, char **argv, GLOBALDATA_T *a_gdt) 2430*5c51f124SMoriah Waterland { 2431*5c51f124SMoriah Waterland char *rootPath = NULL; 2432*5c51f124SMoriah Waterland int c; 2433*5c51f124SMoriah Waterland int r; 2434*5c51f124SMoriah Waterland static char *cmdName = "is_boot_environment"; 2435*5c51f124SMoriah Waterland static int recursion = 0; 2436*5c51f124SMoriah Waterland 2437*5c51f124SMoriah Waterland /* process any command line options */ 2438*5c51f124SMoriah Waterland 2439*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2440*5c51f124SMoriah Waterland switch (c) { 2441*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2442*5c51f124SMoriah Waterland break; 2443*5c51f124SMoriah Waterland case '?': 2444*5c51f124SMoriah Waterland default: 2445*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2446*5c51f124SMoriah Waterland return (R_USAGE); 2447*5c51f124SMoriah Waterland } 2448*5c51f124SMoriah Waterland } 2449*5c51f124SMoriah Waterland 2450*5c51f124SMoriah Waterland /* prevent recursion */ 2451*5c51f124SMoriah Waterland 2452*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 2453*5c51f124SMoriah Waterland /* 2454*5c51f124SMoriah Waterland * a boot environment cannot be any of the following 2455*5c51f124SMoriah Waterland */ 2456*5c51f124SMoriah Waterland 2457*5c51f124SMoriah Waterland /* cannot be a diskless client */ 2458*5c51f124SMoriah Waterland 2459*5c51f124SMoriah Waterland r = cmd_is_diskless_client(argc, argv, a_gdt); 2460*5c51f124SMoriah Waterland 2461*5c51f124SMoriah Waterland /* cannot be a netinstall_image */ 2462*5c51f124SMoriah Waterland 2463*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2464*5c51f124SMoriah Waterland r = cmd_is_netinstall_image(argc, argv, a_gdt); 2465*5c51f124SMoriah Waterland } 2466*5c51f124SMoriah Waterland 2467*5c51f124SMoriah Waterland /* cannot be a mounted_miniroot */ 2468*5c51f124SMoriah Waterland 2469*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2470*5c51f124SMoriah Waterland r = cmd_is_mounted_miniroot(argc, argv, a_gdt); 2471*5c51f124SMoriah Waterland } 2472*5c51f124SMoriah Waterland 2473*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 2474*5c51f124SMoriah Waterland 2475*5c51f124SMoriah Waterland recursion--; 2476*5c51f124SMoriah Waterland 2477*5c51f124SMoriah Waterland /* return failure if any of the preceeding are true */ 2478*5c51f124SMoriah Waterland 2479*5c51f124SMoriah Waterland switch (r) { 2480*5c51f124SMoriah Waterland case R_SUCCESS: 2481*5c51f124SMoriah Waterland return (R_FAILURE); 2482*5c51f124SMoriah Waterland case R_FAILURE: 2483*5c51f124SMoriah Waterland break; 2484*5c51f124SMoriah Waterland case R_USAGE: 2485*5c51f124SMoriah Waterland case R_ERROR: 2486*5c51f124SMoriah Waterland default: 2487*5c51f124SMoriah Waterland return (r); 2488*5c51f124SMoriah Waterland } 2489*5c51f124SMoriah Waterland } 2490*5c51f124SMoriah Waterland 2491*5c51f124SMoriah Waterland /* normalize argc/argv */ 2492*5c51f124SMoriah Waterland 2493*5c51f124SMoriah Waterland argc -= optind; 2494*5c51f124SMoriah Waterland argv += optind; 2495*5c51f124SMoriah Waterland 2496*5c51f124SMoriah Waterland /* error if more than one argument */ 2497*5c51f124SMoriah Waterland 2498*5c51f124SMoriah Waterland if (argc > 1) { 2499*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2500*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2501*5c51f124SMoriah Waterland return (R_USAGE); 2502*5c51f124SMoriah Waterland } 2503*5c51f124SMoriah Waterland 2504*5c51f124SMoriah Waterland /* process root path if first argument present */ 2505*5c51f124SMoriah Waterland 2506*5c51f124SMoriah Waterland if (argc == 1) { 2507*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2508*5c51f124SMoriah Waterland return (R_ERROR); 2509*5c51f124SMoriah Waterland } 2510*5c51f124SMoriah Waterland } 2511*5c51f124SMoriah Waterland 2512*5c51f124SMoriah Waterland /* get current root path */ 2513*5c51f124SMoriah Waterland 2514*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2515*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2516*5c51f124SMoriah Waterland return (r); 2517*5c51f124SMoriah Waterland } 2518*5c51f124SMoriah Waterland 2519*5c51f124SMoriah Waterland /* start of command debugging information */ 2520*5c51f124SMoriah Waterland 2521*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2522*5c51f124SMoriah Waterland 2523*5c51f124SMoriah Waterland /* root path must not be "/" */ 2524*5c51f124SMoriah Waterland 2525*5c51f124SMoriah Waterland if (strcmp(rootPath, "/") == 0) { 2526*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ROOTPATH, rootPath, "/"); 2527*5c51f124SMoriah Waterland return (R_FAILURE); 2528*5c51f124SMoriah Waterland } 2529*5c51f124SMoriah Waterland 2530*5c51f124SMoriah Waterland /* zone name must be global */ 2531*5c51f124SMoriah Waterland 2532*5c51f124SMoriah Waterland if (strcmp(a_gdt->gd_zoneName, GLOBAL_ZONENAME) != 0) { 2533*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_BAD_ZONE, rootPath, 2534*5c51f124SMoriah Waterland GLOBAL_ZONENAME); 2535*5c51f124SMoriah Waterland return (R_FAILURE); 2536*5c51f124SMoriah Waterland } 2537*5c51f124SMoriah Waterland 2538*5c51f124SMoriah Waterland /* $ROOTDIR/etc/lutab must exist */ 2539*5c51f124SMoriah Waterland 2540*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS, "%s/%s", rootPath, "/etc/lutab"); 2541*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2542*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLUTAB, rootPath, 2543*5c51f124SMoriah Waterland "/etc/lutab"); 2544*5c51f124SMoriah Waterland return (R_FAILURE); 2545*5c51f124SMoriah Waterland } 2546*5c51f124SMoriah Waterland 2547*5c51f124SMoriah Waterland /* $ROOTDIR/etc/lu must exist */ 2548*5c51f124SMoriah Waterland 2549*5c51f124SMoriah Waterland r = testPath(TEST_EXISTS|TEST_IS_DIRECTORY, 2550*5c51f124SMoriah Waterland "%s/%s", rootPath, "/etc/lu"); 2551*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2552*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_NO_ETCLU, rootPath, "/etc/lu"); 2553*5c51f124SMoriah Waterland return (R_FAILURE); 2554*5c51f124SMoriah Waterland } 2555*5c51f124SMoriah Waterland 2556*5c51f124SMoriah Waterland /* must not be initial installation */ 2557*5c51f124SMoriah Waterland 2558*5c51f124SMoriah Waterland if ((a_gdt->gd_initialInstall == B_TRUE) && 2559*5c51f124SMoriah Waterland (strcmp(a_gdt->gd_installRoot, rootPath) == 0)) { 2560*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_INITIAL_INSTALL, rootPath); 2561*5c51f124SMoriah Waterland return (R_FAILURE); 2562*5c51f124SMoriah Waterland } 2563*5c51f124SMoriah Waterland 2564*5c51f124SMoriah Waterland /* must not be installation of a zone */ 2565*5c51f124SMoriah Waterland 2566*5c51f124SMoriah Waterland if ((a_gdt->gd_globalZoneInstall == B_TRUE) || 2567*5c51f124SMoriah Waterland (a_gdt->gd_nonglobalZoneInstall == B_TRUE)) { 2568*5c51f124SMoriah Waterland /* initial zone install: no path can be boot environment */ 2569*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_ZONE_INSTALL, rootPath); 2570*5c51f124SMoriah Waterland return (R_FAILURE); 2571*5c51f124SMoriah Waterland } 2572*5c51f124SMoriah Waterland 2573*5c51f124SMoriah Waterland /* target is a boot environment */ 2574*5c51f124SMoriah Waterland 2575*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_BENV_IS, rootPath); 2576*5c51f124SMoriah Waterland 2577*5c51f124SMoriah Waterland return (R_SUCCESS); 2578*5c51f124SMoriah Waterland } 2579*5c51f124SMoriah Waterland 2580*5c51f124SMoriah Waterland /* 2581*5c51f124SMoriah Waterland * Name: cmd_is_sparse_root_ng_zone 2582*5c51f124SMoriah Waterland * Description: determine if target is a sparse non-global zone 2583*5c51f124SMoriah Waterland * Scope: public 2584*5c51f124SMoriah Waterland * Arguments: argc,argv: 2585*5c51f124SMoriah Waterland * - optional path to target to test 2586*5c51f124SMoriah Waterland * Returns: int 2587*5c51f124SMoriah Waterland * == 0 - success 2588*5c51f124SMoriah Waterland * != 0 - failure 2589*5c51f124SMoriah Waterland * IMPLEMENATION: 2590*5c51f124SMoriah Waterland * - must be a non-global zone 2591*5c51f124SMoriah Waterland * - inherited file systems must be present, and/or 2592*5c51f124SMoriah Waterland * - read-only lofs file systems must be present 2593*5c51f124SMoriah Waterland */ 2594*5c51f124SMoriah Waterland 2595*5c51f124SMoriah Waterland static int 2596*5c51f124SMoriah Waterland cmd_is_sparse_root_ng_zone(int argc, char **argv, GLOBALDATA_T *a_gdt) 2597*5c51f124SMoriah Waterland { 2598*5c51f124SMoriah Waterland char *rootPath = NULL; 2599*5c51f124SMoriah Waterland int c; 2600*5c51f124SMoriah Waterland int r; 2601*5c51f124SMoriah Waterland static char *cmdName = "is_sparse_root_nonglobal_zone"; 2602*5c51f124SMoriah Waterland static int recursion = 0; 2603*5c51f124SMoriah Waterland 2604*5c51f124SMoriah Waterland /* process any command line options */ 2605*5c51f124SMoriah Waterland 2606*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2607*5c51f124SMoriah Waterland switch (c) { 2608*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2609*5c51f124SMoriah Waterland break; 2610*5c51f124SMoriah Waterland case '?': 2611*5c51f124SMoriah Waterland default: 2612*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2613*5c51f124SMoriah Waterland return (R_USAGE); 2614*5c51f124SMoriah Waterland } 2615*5c51f124SMoriah Waterland } 2616*5c51f124SMoriah Waterland 2617*5c51f124SMoriah Waterland /* prevent recursion */ 2618*5c51f124SMoriah Waterland 2619*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 2620*5c51f124SMoriah Waterland 2621*5c51f124SMoriah Waterland /* see if this is a non-global zone */ 2622*5c51f124SMoriah Waterland 2623*5c51f124SMoriah Waterland r = cmd_is_nonglobal_zone(argc, argv, a_gdt); 2624*5c51f124SMoriah Waterland 2625*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 2626*5c51f124SMoriah Waterland 2627*5c51f124SMoriah Waterland recursion--; 2628*5c51f124SMoriah Waterland 2629*5c51f124SMoriah Waterland switch (r) { 2630*5c51f124SMoriah Waterland case R_SUCCESS: 2631*5c51f124SMoriah Waterland /* is a non-global zone */ 2632*5c51f124SMoriah Waterland break; 2633*5c51f124SMoriah Waterland case R_FAILURE: 2634*5c51f124SMoriah Waterland /* not a non-global zone */ 2635*5c51f124SMoriah Waterland return (R_FAILURE); 2636*5c51f124SMoriah Waterland case R_USAGE: 2637*5c51f124SMoriah Waterland case R_ERROR: 2638*5c51f124SMoriah Waterland default: 2639*5c51f124SMoriah Waterland /* cannot determine if non-global zone */ 2640*5c51f124SMoriah Waterland return (r); 2641*5c51f124SMoriah Waterland } 2642*5c51f124SMoriah Waterland } 2643*5c51f124SMoriah Waterland 2644*5c51f124SMoriah Waterland /* normalize argc/argv */ 2645*5c51f124SMoriah Waterland 2646*5c51f124SMoriah Waterland argc -= optind; 2647*5c51f124SMoriah Waterland argv += optind; 2648*5c51f124SMoriah Waterland 2649*5c51f124SMoriah Waterland /* error if more than one argument */ 2650*5c51f124SMoriah Waterland 2651*5c51f124SMoriah Waterland if (argc > 1) { 2652*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2653*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2654*5c51f124SMoriah Waterland return (R_USAGE); 2655*5c51f124SMoriah Waterland } 2656*5c51f124SMoriah Waterland 2657*5c51f124SMoriah Waterland /* process root path if first argument present */ 2658*5c51f124SMoriah Waterland 2659*5c51f124SMoriah Waterland if (argc == 1) { 2660*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2661*5c51f124SMoriah Waterland return (R_ERROR); 2662*5c51f124SMoriah Waterland } 2663*5c51f124SMoriah Waterland } 2664*5c51f124SMoriah Waterland 2665*5c51f124SMoriah Waterland /* get current root path */ 2666*5c51f124SMoriah Waterland 2667*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2668*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2669*5c51f124SMoriah Waterland return (r); 2670*5c51f124SMoriah Waterland } 2671*5c51f124SMoriah Waterland 2672*5c51f124SMoriah Waterland /* start of command debugging information */ 2673*5c51f124SMoriah Waterland 2674*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2675*5c51f124SMoriah Waterland 2676*5c51f124SMoriah Waterland /* 2677*5c51f124SMoriah Waterland * in a non-global zone: 2678*5c51f124SMoriah Waterland * if any file systems are inherited, or if /usr is read only, 2679*5c51f124SMoriah Waterland * then the target is a sparse root non-global zone. 2680*5c51f124SMoriah Waterland */ 2681*5c51f124SMoriah Waterland 2682*5c51f124SMoriah Waterland if ((a_gdt->gd_inheritedFileSystems != (char **)NULL) || 2683*5c51f124SMoriah Waterland (a_gdt->gd_srFsMountedRO == B_TRUE)) { 2684*5c51f124SMoriah Waterland /* no inherited file systems */ 2685*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_SRNG_IS, rootPath); 2686*5c51f124SMoriah Waterland return (R_SUCCESS); 2687*5c51f124SMoriah Waterland } 2688*5c51f124SMoriah Waterland 2689*5c51f124SMoriah Waterland /* target is not a sparse root non-global zone */ 2690*5c51f124SMoriah Waterland 2691*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_SRNG_IS_NOT, rootPath); 2692*5c51f124SMoriah Waterland 2693*5c51f124SMoriah Waterland return (R_FAILURE); 2694*5c51f124SMoriah Waterland 2695*5c51f124SMoriah Waterland } 2696*5c51f124SMoriah Waterland 2697*5c51f124SMoriah Waterland /* 2698*5c51f124SMoriah Waterland * Name: cmd_is_what 2699*5c51f124SMoriah Waterland * Description: determine what the target is 2700*5c51f124SMoriah Waterland * Scope: public 2701*5c51f124SMoriah Waterland * Arguments: argc,argv: 2702*5c51f124SMoriah Waterland * - optional path to target to test 2703*5c51f124SMoriah Waterland * Returns: int 2704*5c51f124SMoriah Waterland * == 0 - success 2705*5c51f124SMoriah Waterland * != 0 - failure 2706*5c51f124SMoriah Waterland */ 2707*5c51f124SMoriah Waterland 2708*5c51f124SMoriah Waterland static int 2709*5c51f124SMoriah Waterland cmd_is_what(int argc, char **argv, GLOBALDATA_T *a_gdt) 2710*5c51f124SMoriah Waterland { 2711*5c51f124SMoriah Waterland char *rootPath = NULL; 2712*5c51f124SMoriah Waterland int c; 2713*5c51f124SMoriah Waterland int cur_cmd; 2714*5c51f124SMoriah Waterland int r; 2715*5c51f124SMoriah Waterland static char *cmdName = "is_what"; 2716*5c51f124SMoriah Waterland 2717*5c51f124SMoriah Waterland /* process any command line options */ 2718*5c51f124SMoriah Waterland 2719*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2720*5c51f124SMoriah Waterland switch (c) { 2721*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2722*5c51f124SMoriah Waterland break; 2723*5c51f124SMoriah Waterland case '?': 2724*5c51f124SMoriah Waterland default: 2725*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2726*5c51f124SMoriah Waterland return (R_USAGE); 2727*5c51f124SMoriah Waterland } 2728*5c51f124SMoriah Waterland } 2729*5c51f124SMoriah Waterland 2730*5c51f124SMoriah Waterland /* normalize argc/argv */ 2731*5c51f124SMoriah Waterland 2732*5c51f124SMoriah Waterland argc -= optind; 2733*5c51f124SMoriah Waterland argv += optind; 2734*5c51f124SMoriah Waterland 2735*5c51f124SMoriah Waterland /* error if more than one argument */ 2736*5c51f124SMoriah Waterland 2737*5c51f124SMoriah Waterland if (argc > 1) { 2738*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2739*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2740*5c51f124SMoriah Waterland return (R_USAGE); 2741*5c51f124SMoriah Waterland } 2742*5c51f124SMoriah Waterland 2743*5c51f124SMoriah Waterland /* process root path if first argument present */ 2744*5c51f124SMoriah Waterland 2745*5c51f124SMoriah Waterland if (argc == 1) { 2746*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2747*5c51f124SMoriah Waterland return (R_ERROR); 2748*5c51f124SMoriah Waterland } 2749*5c51f124SMoriah Waterland } 2750*5c51f124SMoriah Waterland 2751*5c51f124SMoriah Waterland /* get current root path */ 2752*5c51f124SMoriah Waterland 2753*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2754*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2755*5c51f124SMoriah Waterland return (r); 2756*5c51f124SMoriah Waterland } 2757*5c51f124SMoriah Waterland 2758*5c51f124SMoriah Waterland /* 2759*5c51f124SMoriah Waterland * construct the command line for all of the packages 2760*5c51f124SMoriah Waterland */ 2761*5c51f124SMoriah Waterland 2762*5c51f124SMoriah Waterland argc = 0; 2763*5c51f124SMoriah Waterland argv[argc++] = strdup(get_prog_name()); 2764*5c51f124SMoriah Waterland argv[argc++] = strdup(rootPath); 2765*5c51f124SMoriah Waterland 2766*5c51f124SMoriah Waterland /* start of command debugging information */ 2767*5c51f124SMoriah Waterland 2768*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2769*5c51f124SMoriah Waterland 2770*5c51f124SMoriah Waterland /* search for specified subcommand and execute if found */ 2771*5c51f124SMoriah Waterland 2772*5c51f124SMoriah Waterland for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) { 2773*5c51f124SMoriah Waterland int result; 2774*5c51f124SMoriah Waterland 2775*5c51f124SMoriah Waterland /* do not recursively call this function */ 2776*5c51f124SMoriah Waterland 2777*5c51f124SMoriah Waterland if (cmds[cur_cmd].c_func == cmd_is_what) { 2778*5c51f124SMoriah Waterland continue; 2779*5c51f124SMoriah Waterland } 2780*5c51f124SMoriah Waterland 2781*5c51f124SMoriah Waterland /* call subcommand with its own argc/argv */ 2782*5c51f124SMoriah Waterland 2783*5c51f124SMoriah Waterland result = cmds[cur_cmd].c_func(argc, argv, a_gdt); 2784*5c51f124SMoriah Waterland 2785*5c51f124SMoriah Waterland /* process result code and exit */ 2786*5c51f124SMoriah Waterland 2787*5c51f124SMoriah Waterland result = adjustResults(result); 2788*5c51f124SMoriah Waterland log_msg(LOG_MSG_INFO, MSG_IS_WHAT_RESULT, 2789*5c51f124SMoriah Waterland cmds[cur_cmd].c_name, result); 2790*5c51f124SMoriah Waterland } 2791*5c51f124SMoriah Waterland return (R_SUCCESS); 2792*5c51f124SMoriah Waterland } 2793*5c51f124SMoriah Waterland 2794*5c51f124SMoriah Waterland /* 2795*5c51f124SMoriah Waterland * Name: cmd_is_whole_root_ng_zone 2796*5c51f124SMoriah Waterland * Description: determine if target is a global zone 2797*5c51f124SMoriah Waterland * Scope: public 2798*5c51f124SMoriah Waterland * Arguments: argc,argv: 2799*5c51f124SMoriah Waterland * - optional path to target to test 2800*5c51f124SMoriah Waterland * Returns: int 2801*5c51f124SMoriah Waterland * == 0 - success 2802*5c51f124SMoriah Waterland * != 0 - failure 2803*5c51f124SMoriah Waterland * IMPLEMENTATION: 2804*5c51f124SMoriah Waterland * - must be a non-global zone 2805*5c51f124SMoriah Waterland * - no inherited file systems may be present 2806*5c51f124SMoriah Waterland * - no read-only lofs file systems may be present 2807*5c51f124SMoriah Waterland */ 2808*5c51f124SMoriah Waterland 2809*5c51f124SMoriah Waterland static int 2810*5c51f124SMoriah Waterland cmd_is_whole_root_ng_zone(int argc, char **argv, GLOBALDATA_T *a_gdt) 2811*5c51f124SMoriah Waterland { 2812*5c51f124SMoriah Waterland char *rootPath = NULL; 2813*5c51f124SMoriah Waterland int c; 2814*5c51f124SMoriah Waterland int r; 2815*5c51f124SMoriah Waterland static char *cmdName = "is_whole_root_nonglobal_zone"; 2816*5c51f124SMoriah Waterland static int recursion = 0; 2817*5c51f124SMoriah Waterland 2818*5c51f124SMoriah Waterland /* process any command line options */ 2819*5c51f124SMoriah Waterland 2820*5c51f124SMoriah Waterland while ((c = getopt(argc, argv, ":")) != EOF) { 2821*5c51f124SMoriah Waterland switch (c) { 2822*5c51f124SMoriah Waterland case '\0': /* prevent end-of-loop not reached warning */ 2823*5c51f124SMoriah Waterland break; 2824*5c51f124SMoriah Waterland case '?': 2825*5c51f124SMoriah Waterland default: 2826*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, optopt, cmdName); 2827*5c51f124SMoriah Waterland return (R_USAGE); 2828*5c51f124SMoriah Waterland } 2829*5c51f124SMoriah Waterland } 2830*5c51f124SMoriah Waterland 2831*5c51f124SMoriah Waterland /* prevent recursion */ 2832*5c51f124SMoriah Waterland 2833*5c51f124SMoriah Waterland if (recursionCheck(&recursion, cmdName) == B_FALSE) { 2834*5c51f124SMoriah Waterland 2835*5c51f124SMoriah Waterland /* see if this is a non-global zone */ 2836*5c51f124SMoriah Waterland 2837*5c51f124SMoriah Waterland r = cmd_is_nonglobal_zone(argc, argv, a_gdt); 2838*5c51f124SMoriah Waterland 2839*5c51f124SMoriah Waterland /* no need to guard against recursion any more */ 2840*5c51f124SMoriah Waterland 2841*5c51f124SMoriah Waterland recursion--; 2842*5c51f124SMoriah Waterland 2843*5c51f124SMoriah Waterland switch (r) { 2844*5c51f124SMoriah Waterland case R_SUCCESS: 2845*5c51f124SMoriah Waterland /* is a non-global zone */ 2846*5c51f124SMoriah Waterland break; 2847*5c51f124SMoriah Waterland case R_FAILURE: 2848*5c51f124SMoriah Waterland /* not a non-global zone */ 2849*5c51f124SMoriah Waterland return (R_FAILURE); 2850*5c51f124SMoriah Waterland case R_USAGE: 2851*5c51f124SMoriah Waterland case R_ERROR: 2852*5c51f124SMoriah Waterland default: 2853*5c51f124SMoriah Waterland /* cannot determine if non-global zone */ 2854*5c51f124SMoriah Waterland return (r); 2855*5c51f124SMoriah Waterland } 2856*5c51f124SMoriah Waterland } 2857*5c51f124SMoriah Waterland 2858*5c51f124SMoriah Waterland /* normalize argc/argv */ 2859*5c51f124SMoriah Waterland 2860*5c51f124SMoriah Waterland argc -= optind; 2861*5c51f124SMoriah Waterland argv += optind; 2862*5c51f124SMoriah Waterland 2863*5c51f124SMoriah Waterland /* error if more than one argument */ 2864*5c51f124SMoriah Waterland 2865*5c51f124SMoriah Waterland if (argc > 1) { 2866*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_UNRECOGNIZED_OPTION, argv[1]); 2867*5c51f124SMoriah Waterland (void) usage(MSG_IS_INVALID_OPTION, argv[1]); 2868*5c51f124SMoriah Waterland return (R_USAGE); 2869*5c51f124SMoriah Waterland } 2870*5c51f124SMoriah Waterland 2871*5c51f124SMoriah Waterland /* process root path if first argument present */ 2872*5c51f124SMoriah Waterland 2873*5c51f124SMoriah Waterland if (argc == 1) { 2874*5c51f124SMoriah Waterland if (setRootPath(argv[0], "argv[0]", B_TRUE) != R_SUCCESS) { 2875*5c51f124SMoriah Waterland return (R_ERROR); 2876*5c51f124SMoriah Waterland } 2877*5c51f124SMoriah Waterland } 2878*5c51f124SMoriah Waterland 2879*5c51f124SMoriah Waterland /* get current root path */ 2880*5c51f124SMoriah Waterland 2881*5c51f124SMoriah Waterland r = getRootPath(&rootPath); 2882*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 2883*5c51f124SMoriah Waterland return (r); 2884*5c51f124SMoriah Waterland } 2885*5c51f124SMoriah Waterland 2886*5c51f124SMoriah Waterland /* start of command debugging information */ 2887*5c51f124SMoriah Waterland 2888*5c51f124SMoriah Waterland echoDebug(DBG_ROOTPATH_IS, rootPath); 2889*5c51f124SMoriah Waterland 2890*5c51f124SMoriah Waterland /* 2891*5c51f124SMoriah Waterland * in a non-global zone: 2892*5c51f124SMoriah Waterland * if no file systems are inherited, and if /usr is not 2893*5c51f124SMoriah Waterland * read only, then the target is a whole root non-global zone. 2894*5c51f124SMoriah Waterland */ 2895*5c51f124SMoriah Waterland 2896*5c51f124SMoriah Waterland if ((a_gdt->gd_inheritedFileSystems == (char **)NULL) && 2897*5c51f124SMoriah Waterland (a_gdt->gd_srFsMountedRO == B_FALSE)) { 2898*5c51f124SMoriah Waterland /* no inherited file systems */ 2899*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_WRNG_IS, rootPath); 2900*5c51f124SMoriah Waterland return (R_SUCCESS); 2901*5c51f124SMoriah Waterland } 2902*5c51f124SMoriah Waterland 2903*5c51f124SMoriah Waterland /* target is not a whole-root non-global zone */ 2904*5c51f124SMoriah Waterland 2905*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_WRNG_IS_NOT, rootPath); 2906*5c51f124SMoriah Waterland 2907*5c51f124SMoriah Waterland return (R_FAILURE); 2908*5c51f124SMoriah Waterland } 2909*5c51f124SMoriah Waterland 2910*5c51f124SMoriah Waterland /* 2911*5c51f124SMoriah Waterland * ***************************************************************************** 2912*5c51f124SMoriah Waterland * utility support functions 2913*5c51f124SMoriah Waterland * ***************************************************************************** 2914*5c51f124SMoriah Waterland */ 2915*5c51f124SMoriah Waterland 2916*5c51f124SMoriah Waterland /* 2917*5c51f124SMoriah Waterland * Name: getMountOption 2918*5c51f124SMoriah Waterland * Description: return next mount option in a string 2919*5c51f124SMoriah Waterland * Arguments: p - pointer to string containing mount options 2920*5c51f124SMoriah Waterland * Output: none 2921*5c51f124SMoriah Waterland * Returns: char * - pointer to next option in string "p" 2922*5c51f124SMoriah Waterland * Side Effects: advances input "p" and inserts \0 in place of the 2923*5c51f124SMoriah Waterland * option separator found. 2924*5c51f124SMoriah Waterland */ 2925*5c51f124SMoriah Waterland 2926*5c51f124SMoriah Waterland static char * 2927*5c51f124SMoriah Waterland getMountOption(char **p) 2928*5c51f124SMoriah Waterland { 2929*5c51f124SMoriah Waterland char *cp = *p; 2930*5c51f124SMoriah Waterland char *retstr; 2931*5c51f124SMoriah Waterland 2932*5c51f124SMoriah Waterland /* advance past all white space */ 2933*5c51f124SMoriah Waterland 2934*5c51f124SMoriah Waterland while (*cp && isspace(*cp)) 2935*5c51f124SMoriah Waterland cp++; 2936*5c51f124SMoriah Waterland 2937*5c51f124SMoriah Waterland /* remember start of next option */ 2938*5c51f124SMoriah Waterland 2939*5c51f124SMoriah Waterland retstr = cp; 2940*5c51f124SMoriah Waterland 2941*5c51f124SMoriah Waterland /* advance to end of string or option separator */ 2942*5c51f124SMoriah Waterland 2943*5c51f124SMoriah Waterland while (*cp && *cp != ',') 2944*5c51f124SMoriah Waterland cp++; 2945*5c51f124SMoriah Waterland 2946*5c51f124SMoriah Waterland /* replace separator with '\0' if not at end of string */ 2947*5c51f124SMoriah Waterland if (*cp) { 2948*5c51f124SMoriah Waterland *cp = '\0'; 2949*5c51f124SMoriah Waterland cp++; 2950*5c51f124SMoriah Waterland } 2951*5c51f124SMoriah Waterland 2952*5c51f124SMoriah Waterland /* reset caller's pointer and return pointer to option */ 2953*5c51f124SMoriah Waterland 2954*5c51f124SMoriah Waterland *p = cp; 2955*5c51f124SMoriah Waterland return (retstr); 2956*5c51f124SMoriah Waterland } 2957*5c51f124SMoriah Waterland 2958*5c51f124SMoriah Waterland /* 2959*5c51f124SMoriah Waterland * Name: mountOptionPresent 2960*5c51f124SMoriah Waterland * Description: determine if specified mount option is present in list 2961*5c51f124SMoriah Waterland * of mount point options 2962*5c51f124SMoriah Waterland * Arguments: a_mntOptions - pointer to string containing list of mount 2963*5c51f124SMoriah Waterland * point options to search 2964*5c51f124SMoriah Waterland * a_opt - pointer to string containing option to search for 2965*5c51f124SMoriah Waterland * Output: none 2966*5c51f124SMoriah Waterland * Returns: R_SUCCESS - option is present in list of mount point options 2967*5c51f124SMoriah Waterland * R_FAILURE - options is not present 2968*5c51f124SMoriah Waterland * R_ERROR - unable to determine if option is present or not 2969*5c51f124SMoriah Waterland */ 2970*5c51f124SMoriah Waterland 2971*5c51f124SMoriah Waterland static int 2972*5c51f124SMoriah Waterland mountOptionPresent(char *a_mntOptions, char *a_opt) 2973*5c51f124SMoriah Waterland { 2974*5c51f124SMoriah Waterland char tmpopts[MNT_LINE_MAX]; 2975*5c51f124SMoriah Waterland char *f, *opts = tmpopts; 2976*5c51f124SMoriah Waterland 2977*5c51f124SMoriah Waterland /* return false if no mount options present */ 2978*5c51f124SMoriah Waterland 2979*5c51f124SMoriah Waterland if ((a_opt == NULL) || (*a_opt == '\0')) { 2980*5c51f124SMoriah Waterland return (R_FAILURE); 2981*5c51f124SMoriah Waterland } 2982*5c51f124SMoriah Waterland 2983*5c51f124SMoriah Waterland /* return not present if no list of options to search */ 2984*5c51f124SMoriah Waterland 2985*5c51f124SMoriah Waterland if (a_mntOptions == NULL) { 2986*5c51f124SMoriah Waterland return (R_FAILURE); 2987*5c51f124SMoriah Waterland } 2988*5c51f124SMoriah Waterland 2989*5c51f124SMoriah Waterland /* return not present if list of options to search is empty */ 2990*5c51f124SMoriah Waterland 2991*5c51f124SMoriah Waterland if (*a_mntOptions == '\0') { 2992*5c51f124SMoriah Waterland return (R_FAILURE); 2993*5c51f124SMoriah Waterland } 2994*5c51f124SMoriah Waterland 2995*5c51f124SMoriah Waterland /* make local copy of option list to search */ 2996*5c51f124SMoriah Waterland 2997*5c51f124SMoriah Waterland (void) strcpy(opts, a_mntOptions); 2998*5c51f124SMoriah Waterland 2999*5c51f124SMoriah Waterland /* scan each option looking for the specified option */ 3000*5c51f124SMoriah Waterland 3001*5c51f124SMoriah Waterland f = getMountOption(&opts); 3002*5c51f124SMoriah Waterland for (; *f; f = getMountOption(&opts)) { 3003*5c51f124SMoriah Waterland /* return success if option matches target */ 3004*5c51f124SMoriah Waterland if (strncmp(a_opt, f, strlen(a_opt)) == 0) { 3005*5c51f124SMoriah Waterland return (R_SUCCESS); 3006*5c51f124SMoriah Waterland } 3007*5c51f124SMoriah Waterland } 3008*5c51f124SMoriah Waterland 3009*5c51f124SMoriah Waterland /* option not found */ 3010*5c51f124SMoriah Waterland 3011*5c51f124SMoriah Waterland return (R_FAILURE); 3012*5c51f124SMoriah Waterland } 3013*5c51f124SMoriah Waterland 3014*5c51f124SMoriah Waterland /* 3015*5c51f124SMoriah Waterland * Name: sortedInsert 3016*5c51f124SMoriah Waterland * Description: perform an alphabetical sorted insert into a list 3017*5c51f124SMoriah Waterland * Arguments: r_list - pointer to list to insert next entry into 3018*5c51f124SMoriah Waterland * a_listSize - pointer to current list size 3019*5c51f124SMoriah Waterland * a_mntPoint - mount point to insert (is sort key) 3020*5c51f124SMoriah Waterland * a_fsType - file system type for mount point 3021*5c51f124SMoriah Waterland * a_mntOptions - file syste mount options for mount point 3022*5c51f124SMoriah Waterland * Output: None 3023*5c51f124SMoriah Waterland * Returns: None 3024*5c51f124SMoriah Waterland */ 3025*5c51f124SMoriah Waterland 3026*5c51f124SMoriah Waterland static void 3027*5c51f124SMoriah Waterland sortedInsert(FSI_T **r_list, long *a_listSize, char *a_mntPoint, 3028*5c51f124SMoriah Waterland char *a_fsType, char *a_mntOptions) 3029*5c51f124SMoriah Waterland { 3030*5c51f124SMoriah Waterland int listSize; 3031*5c51f124SMoriah Waterland FSI_T *list; 3032*5c51f124SMoriah Waterland int n; 3033*5c51f124SMoriah Waterland 3034*5c51f124SMoriah Waterland /* entry assertions */ 3035*5c51f124SMoriah Waterland 3036*5c51f124SMoriah Waterland assert(a_listSize != (long *)NULL); 3037*5c51f124SMoriah Waterland assert(a_mntPoint != NULL); 3038*5c51f124SMoriah Waterland assert(a_fsType != NULL); 3039*5c51f124SMoriah Waterland assert(a_mntOptions != NULL); 3040*5c51f124SMoriah Waterland 3041*5c51f124SMoriah Waterland /* entry debugging info */ 3042*5c51f124SMoriah Waterland 3043*5c51f124SMoriah Waterland echoDebug(DBG_SINS_ENTRY, a_mntPoint, a_fsType, a_mntOptions); 3044*5c51f124SMoriah Waterland 3045*5c51f124SMoriah Waterland /* localize references to the list and list size */ 3046*5c51f124SMoriah Waterland 3047*5c51f124SMoriah Waterland listSize = *a_listSize; 3048*5c51f124SMoriah Waterland list = *r_list; 3049*5c51f124SMoriah Waterland 3050*5c51f124SMoriah Waterland /* 3051*5c51f124SMoriah Waterland * if list empty insert this entry as the first one in the list 3052*5c51f124SMoriah Waterland */ 3053*5c51f124SMoriah Waterland 3054*5c51f124SMoriah Waterland if (listSize == 0) { 3055*5c51f124SMoriah Waterland /* allocate new entry for list */ 3056*5c51f124SMoriah Waterland listSize++; 3057*5c51f124SMoriah Waterland list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1)); 3058*5c51f124SMoriah Waterland 3059*5c51f124SMoriah Waterland /* first entry is data passed to this function */ 3060*5c51f124SMoriah Waterland list[0].fsi_mntPoint = strdup(a_mntPoint); 3061*5c51f124SMoriah Waterland list[0].fsi_fsType = strdup(a_fsType); 3062*5c51f124SMoriah Waterland list[0].fsi_mntOptions = strdup(a_mntOptions); 3063*5c51f124SMoriah Waterland 3064*5c51f124SMoriah Waterland /* second entry is all NULL - end of entry marker */ 3065*5c51f124SMoriah Waterland list[1].fsi_mntPoint = NULL; 3066*5c51f124SMoriah Waterland list[1].fsi_fsType = NULL; 3067*5c51f124SMoriah Waterland list[1].fsi_mntOptions = NULL; 3068*5c51f124SMoriah Waterland 3069*5c51f124SMoriah Waterland /* restore list and list size references to caller */ 3070*5c51f124SMoriah Waterland *a_listSize = listSize; 3071*5c51f124SMoriah Waterland *r_list = list; 3072*5c51f124SMoriah Waterland 3073*5c51f124SMoriah Waterland return; 3074*5c51f124SMoriah Waterland } 3075*5c51f124SMoriah Waterland 3076*5c51f124SMoriah Waterland /* 3077*5c51f124SMoriah Waterland * list not empty - scan looking for largest match 3078*5c51f124SMoriah Waterland */ 3079*5c51f124SMoriah Waterland 3080*5c51f124SMoriah Waterland for (n = 0; n < listSize; n++) { 3081*5c51f124SMoriah Waterland int c; 3082*5c51f124SMoriah Waterland 3083*5c51f124SMoriah Waterland /* compare target with current list entry */ 3084*5c51f124SMoriah Waterland 3085*5c51f124SMoriah Waterland c = strcmp(list[n].fsi_mntPoint, a_mntPoint); 3086*5c51f124SMoriah Waterland 3087*5c51f124SMoriah Waterland if (c == 0) { 3088*5c51f124SMoriah Waterland char *me; 3089*5c51f124SMoriah Waterland long len; 3090*5c51f124SMoriah Waterland 3091*5c51f124SMoriah Waterland /* entry already in list -- merge entries */ 3092*5c51f124SMoriah Waterland 3093*5c51f124SMoriah Waterland len = strlen(list[n].fsi_mntOptions) + 3094*5c51f124SMoriah Waterland strlen(a_mntOptions) + 2; 3095*5c51f124SMoriah Waterland me = (char *)calloc(1, len); 3096*5c51f124SMoriah Waterland 3097*5c51f124SMoriah Waterland /* merge two mount options lists into one */ 3098*5c51f124SMoriah Waterland 3099*5c51f124SMoriah Waterland (void) strlcat(me, list[n].fsi_mntOptions, len); 3100*5c51f124SMoriah Waterland (void) strlcat(me, ",", len); 3101*5c51f124SMoriah Waterland (void) strlcat(me, a_mntOptions, len); 3102*5c51f124SMoriah Waterland 3103*5c51f124SMoriah Waterland /* free old list, replace with merged one */ 3104*5c51f124SMoriah Waterland 3105*5c51f124SMoriah Waterland free(list[n].fsi_mntOptions); 3106*5c51f124SMoriah Waterland list[n].fsi_mntOptions = me; 3107*5c51f124SMoriah Waterland 3108*5c51f124SMoriah Waterland echoDebug(DBG_SORTEDINS_SKIPPED, 3109*5c51f124SMoriah Waterland n, list[n].fsi_mntPoint, a_fsType, 3110*5c51f124SMoriah Waterland list[n].fsi_fsType, a_mntOptions, 3111*5c51f124SMoriah Waterland list[n].fsi_mntOptions); 3112*5c51f124SMoriah Waterland 3113*5c51f124SMoriah Waterland continue; 3114*5c51f124SMoriah Waterland } else if (c < 0) { 3115*5c51f124SMoriah Waterland /* entry before this one - skip */ 3116*5c51f124SMoriah Waterland continue; 3117*5c51f124SMoriah Waterland } 3118*5c51f124SMoriah Waterland 3119*5c51f124SMoriah Waterland /* 3120*5c51f124SMoriah Waterland * entry after this one - insert new entry 3121*5c51f124SMoriah Waterland */ 3122*5c51f124SMoriah Waterland 3123*5c51f124SMoriah Waterland /* allocate one more entry and make space for new entry */ 3124*5c51f124SMoriah Waterland listSize++; 3125*5c51f124SMoriah Waterland list = (FSI_T *)realloc(list, 3126*5c51f124SMoriah Waterland sizeof (FSI_T)*(listSize+1)); 3127*5c51f124SMoriah Waterland (void) memmove(&(list[n+1]), &(list[n]), 3128*5c51f124SMoriah Waterland sizeof (FSI_T)*(listSize-n)); 3129*5c51f124SMoriah Waterland 3130*5c51f124SMoriah Waterland /* insert this entry into list */ 3131*5c51f124SMoriah Waterland list[n].fsi_mntPoint = strdup(a_mntPoint); 3132*5c51f124SMoriah Waterland list[n].fsi_fsType = strdup(a_fsType); 3133*5c51f124SMoriah Waterland list[n].fsi_mntOptions = strdup(a_mntOptions); 3134*5c51f124SMoriah Waterland 3135*5c51f124SMoriah Waterland /* restore list and list size references to caller */ 3136*5c51f124SMoriah Waterland *a_listSize = listSize; 3137*5c51f124SMoriah Waterland *r_list = list; 3138*5c51f124SMoriah Waterland 3139*5c51f124SMoriah Waterland return; 3140*5c51f124SMoriah Waterland } 3141*5c51f124SMoriah Waterland 3142*5c51f124SMoriah Waterland /* 3143*5c51f124SMoriah Waterland * all entries are before this one - append to end of list 3144*5c51f124SMoriah Waterland */ 3145*5c51f124SMoriah Waterland 3146*5c51f124SMoriah Waterland /* allocate new entry at end of list */ 3147*5c51f124SMoriah Waterland listSize++; 3148*5c51f124SMoriah Waterland list = (FSI_T *)realloc(list, sizeof (FSI_T)*(listSize+1)); 3149*5c51f124SMoriah Waterland 3150*5c51f124SMoriah Waterland /* append this entry to the end of the list */ 3151*5c51f124SMoriah Waterland list[listSize-1].fsi_mntPoint = strdup(a_mntPoint); 3152*5c51f124SMoriah Waterland list[listSize-1].fsi_fsType = strdup(a_fsType); 3153*5c51f124SMoriah Waterland list[listSize-1].fsi_mntOptions = strdup(a_mntOptions); 3154*5c51f124SMoriah Waterland 3155*5c51f124SMoriah Waterland /* restore list and list size references to caller */ 3156*5c51f124SMoriah Waterland *a_listSize = listSize; 3157*5c51f124SMoriah Waterland *r_list = list; 3158*5c51f124SMoriah Waterland } 3159*5c51f124SMoriah Waterland 3160*5c51f124SMoriah Waterland /* 3161*5c51f124SMoriah Waterland * Name: calculateFileSystemConfig 3162*5c51f124SMoriah Waterland * Description: generate sorted list of all mounted file systems 3163*5c51f124SMoriah Waterland * Arguments: a_gdt - global data structure to place sorted entries into 3164*5c51f124SMoriah Waterland * Output: None 3165*5c51f124SMoriah Waterland * Returns: R_SUCCESS - successfully generated mounted file systems list 3166*5c51f124SMoriah Waterland * R_FAILURE - options is not present 3167*5c51f124SMoriah Waterland * R_ERROR - unable to determine if option is present or not 3168*5c51f124SMoriah Waterland */ 3169*5c51f124SMoriah Waterland 3170*5c51f124SMoriah Waterland static int 3171*5c51f124SMoriah Waterland calculateFileSystemConfig(GLOBALDATA_T *a_gdt) 3172*5c51f124SMoriah Waterland { 3173*5c51f124SMoriah Waterland FILE *fp; 3174*5c51f124SMoriah Waterland struct mnttab mntbuf; 3175*5c51f124SMoriah Waterland FSI_T *list; 3176*5c51f124SMoriah Waterland long listSize; 3177*5c51f124SMoriah Waterland boolean_t readOnlyMountFound = B_FALSE; 3178*5c51f124SMoriah Waterland 3179*5c51f124SMoriah Waterland /* entry assetions */ 3180*5c51f124SMoriah Waterland 3181*5c51f124SMoriah Waterland assert(a_gdt != (GLOBALDATA_T *)NULL); 3182*5c51f124SMoriah Waterland 3183*5c51f124SMoriah Waterland /* entry debugging info */ 3184*5c51f124SMoriah Waterland 3185*5c51f124SMoriah Waterland echoDebug(DBG_CALCSCFG_ENTRY); 3186*5c51f124SMoriah Waterland 3187*5c51f124SMoriah Waterland /* allocate a list that has one termination entry */ 3188*5c51f124SMoriah Waterland 3189*5c51f124SMoriah Waterland list = (FSI_T *)calloc(1, sizeof (FSI_T)); 3190*5c51f124SMoriah Waterland list[0].fsi_mntPoint = NULL; 3191*5c51f124SMoriah Waterland list[0].fsi_fsType = NULL; 3192*5c51f124SMoriah Waterland list[0].fsi_mntOptions = NULL; 3193*5c51f124SMoriah Waterland listSize = 0; 3194*5c51f124SMoriah Waterland 3195*5c51f124SMoriah Waterland /* insert entries for all inherited file systems */ 3196*5c51f124SMoriah Waterland 3197*5c51f124SMoriah Waterland if (a_gdt->gd_inheritedFileSystems) { 3198*5c51f124SMoriah Waterland int n; 3199*5c51f124SMoriah Waterland char **ifs = a_gdt->gd_inheritedFileSystems; 3200*5c51f124SMoriah Waterland 3201*5c51f124SMoriah Waterland /* debugging info */ 3202*5c51f124SMoriah Waterland 3203*5c51f124SMoriah Waterland echoDebug(DBG_CALCSCFG_INHERITED); 3204*5c51f124SMoriah Waterland 3205*5c51f124SMoriah Waterland /* insert all inherited file systems */ 3206*5c51f124SMoriah Waterland 3207*5c51f124SMoriah Waterland for (n = 0; ifs[n]; n++) { 3208*5c51f124SMoriah Waterland sortedInsert(&list, &listSize, ifs[n], 3209*5c51f124SMoriah Waterland FSTYPE_INHERITED, MNTOPT_RO); 3210*5c51f124SMoriah Waterland } 3211*5c51f124SMoriah Waterland } 3212*5c51f124SMoriah Waterland 3213*5c51f124SMoriah Waterland /* open the mount table for reading */ 3214*5c51f124SMoriah Waterland 3215*5c51f124SMoriah Waterland fp = fopen(MNTTAB, "r"); 3216*5c51f124SMoriah Waterland if (fp == (FILE *)NULL) { 3217*5c51f124SMoriah Waterland return (R_ERROR); 3218*5c51f124SMoriah Waterland } 3219*5c51f124SMoriah Waterland 3220*5c51f124SMoriah Waterland /* debugging info */ 3221*5c51f124SMoriah Waterland 3222*5c51f124SMoriah Waterland echoDebug(DBG_CALCSCFG_MOUNTED); 3223*5c51f124SMoriah Waterland 3224*5c51f124SMoriah Waterland /* go through all the specials looking for the device */ 3225*5c51f124SMoriah Waterland 3226*5c51f124SMoriah Waterland while (getmntent(fp, &mntbuf) == 0) { 3227*5c51f124SMoriah Waterland if (mntbuf.mnt_mountp[0] == '/') { 3228*5c51f124SMoriah Waterland sortedInsert(&list, &listSize, 3229*5c51f124SMoriah Waterland strdup(mntbuf.mnt_mountp), 3230*5c51f124SMoriah Waterland strdup(mntbuf.mnt_fstype), 3231*5c51f124SMoriah Waterland strdup(mntbuf.mnt_mntopts ? mntbuf.mnt_mntopts : "")); 3232*5c51f124SMoriah Waterland } 3233*5c51f124SMoriah Waterland 3234*5c51f124SMoriah Waterland /* 3235*5c51f124SMoriah Waterland * Set flag if we are in a non-global zone and it is in 3236*5c51f124SMoriah Waterland * the mounted state. 3237*5c51f124SMoriah Waterland */ 3238*5c51f124SMoriah Waterland 3239*5c51f124SMoriah Waterland if (strcmp(mntbuf.mnt_mountp, "/a") == 0 && 3240*5c51f124SMoriah Waterland strcmp(mntbuf.mnt_special, "/a") == 0 && 3241*5c51f124SMoriah Waterland strcmp(mntbuf.mnt_fstype, "lofs") == 0) { 3242*5c51f124SMoriah Waterland a_gdt->inMountedState = B_TRUE; 3243*5c51f124SMoriah Waterland } 3244*5c51f124SMoriah Waterland 3245*5c51f124SMoriah Waterland if (!readOnlyMountFound) { 3246*5c51f124SMoriah Waterland readOnlyMountFound = checkForReadOnlyMount(a_gdt, 3247*5c51f124SMoriah Waterland mntbuf.mnt_mountp, mntbuf.mnt_fstype, 3248*5c51f124SMoriah Waterland mntbuf.mnt_mntopts); 3249*5c51f124SMoriah Waterland } 3250*5c51f124SMoriah Waterland } 3251*5c51f124SMoriah Waterland 3252*5c51f124SMoriah Waterland /* close mount table file */ 3253*5c51f124SMoriah Waterland 3254*5c51f124SMoriah Waterland (void) fclose(fp); 3255*5c51f124SMoriah Waterland 3256*5c51f124SMoriah Waterland /* store list pointers in global data structure */ 3257*5c51f124SMoriah Waterland 3258*5c51f124SMoriah Waterland a_gdt->gd_fileSystemConfig = list; 3259*5c51f124SMoriah Waterland a_gdt->gd_fileSystemConfigLen = listSize; 3260*5c51f124SMoriah Waterland 3261*5c51f124SMoriah Waterland return (R_SUCCESS); 3262*5c51f124SMoriah Waterland } 3263*5c51f124SMoriah Waterland 3264*5c51f124SMoriah Waterland /* 3265*5c51f124SMoriah Waterland * Name: checkForReadOnlyMount 3266*5c51f124SMoriah Waterland * Description: given a mount point, type and options, determine if the 3267*5c51f124SMoriah Waterland * mounted file system is part of a "sparse root" configuration 3268*5c51f124SMoriah Waterland * by checking if the known Zone directories a ro LOFS mounted. 3269*5c51f124SMoriah Waterland * Arguments: a_gdt - global data structure to place sorted entries into 3270*5c51f124SMoriah Waterland * a_mntPoint - pointer to string representing mount point 3271*5c51f124SMoriah Waterland * a_fsType - pointer to string representing file system type 3272*5c51f124SMoriah Waterland * a_mntOptions - pointer to string representing the options 3273*5c51f124SMoriah Waterland * used to mount the file system 3274*5c51f124SMoriah Waterland * Returns: B_TRUE - if sparse root mount is found 3275*5c51f124SMoriah Waterland * B_FLASE - if no sparse root mount's are found 3276*5c51f124SMoriah Waterland * Side Effects: set: 3277*5c51f124SMoriah Waterland * a_gdt->gd_srFsMountedRO = B_TRUE 3278*5c51f124SMoriah Waterland * if the mounted file system is part of a 'sparse root' config 3279*5c51f124SMoriah Waterland */ 3280*5c51f124SMoriah Waterland 3281*5c51f124SMoriah Waterland static boolean_t 3282*5c51f124SMoriah Waterland checkForReadOnlyMount(GLOBALDATA_T *a_gdt, char *a_mntPoint, 3283*5c51f124SMoriah Waterland char *a_fsType, char *a_mntOptions) 3284*5c51f124SMoriah Waterland { 3285*5c51f124SMoriah Waterland /* entry assertions */ 3286*5c51f124SMoriah Waterland int i; 3287*5c51f124SMoriah Waterland char mntPoint[MAXPATHLEN]; 3288*5c51f124SMoriah Waterland char *zDirs[] = { "/usr", "/lib", "/platform", "/sbin", NULL }; 3289*5c51f124SMoriah Waterland char *aZDirs[] = { "/a/usr", "/a/lib", "/a/platform", "/a/sbin", NULL }; 3290*5c51f124SMoriah Waterland 3291*5c51f124SMoriah Waterland assert(a_gdt != (GLOBALDATA_T *)NULL); 3292*5c51f124SMoriah Waterland assert(a_mntPoint != NULL); 3293*5c51f124SMoriah Waterland assert(a_fsType != NULL); 3294*5c51f124SMoriah Waterland 3295*5c51f124SMoriah Waterland /* return if no read-only mount option */ 3296*5c51f124SMoriah Waterland 3297*5c51f124SMoriah Waterland if (mountOptionPresent(a_mntOptions, MNTOPT_RO) != R_SUCCESS) { 3298*5c51f124SMoriah Waterland return (B_FALSE); 3299*5c51f124SMoriah Waterland } 3300*5c51f124SMoriah Waterland 3301*5c51f124SMoriah Waterland /* return if file system is not read-only mounted */ 3302*5c51f124SMoriah Waterland 3303*5c51f124SMoriah Waterland if (strcmp(a_fsType, MNTTYPE_LOFS) != 0) { 3304*5c51f124SMoriah Waterland return (B_FALSE); 3305*5c51f124SMoriah Waterland } 3306*5c51f124SMoriah Waterland 3307*5c51f124SMoriah Waterland /* file system is a read-only lofs mounted. */ 3308*5c51f124SMoriah Waterland 3309*5c51f124SMoriah Waterland /* Check read-only lofs mount's appended to the command line path */ 3310*5c51f124SMoriah Waterland 3311*5c51f124SMoriah Waterland if (a_gdt->gd_cmdline_path != NULL) { 3312*5c51f124SMoriah Waterland if (strncmp(a_mntPoint, a_gdt->gd_cmdline_path, 3313*5c51f124SMoriah Waterland strlen(a_gdt->gd_cmdline_path)) == 0) { 3314*5c51f124SMoriah Waterland for (i = 0; zDirs[i] != NULL; i++) { 3315*5c51f124SMoriah Waterland (void) snprintf(mntPoint, sizeof (mntPoint), 3316*5c51f124SMoriah Waterland "%s%s", a_gdt->gd_cmdline_path, 3317*5c51f124SMoriah Waterland zDirs[i]); 3318*5c51f124SMoriah Waterland if (strcmp(a_mntPoint, mntPoint) == 0) { 3319*5c51f124SMoriah Waterland echoDebug(DBG_CKSR_FSREADONLY, 3320*5c51f124SMoriah Waterland a_mntPoint, a_fsType); 3321*5c51f124SMoriah Waterland a_gdt->gd_srFsMountedRO = B_TRUE; 3322*5c51f124SMoriah Waterland return (B_TRUE); 3323*5c51f124SMoriah Waterland } 3324*5c51f124SMoriah Waterland } 3325*5c51f124SMoriah Waterland } 3326*5c51f124SMoriah Waterland 3327*5c51f124SMoriah Waterland /* Check read-only lofs mount's in the mounted state */ 3328*5c51f124SMoriah Waterland 3329*5c51f124SMoriah Waterland } else if (a_gdt->inMountedState) { 3330*5c51f124SMoriah Waterland for (i = 0; aZDirs[i] != NULL; i++) { 3331*5c51f124SMoriah Waterland if (strncmp(a_mntPoint, aZDirs[i], 3332*5c51f124SMoriah Waterland sizeof (aZDirs[i])) == 0) { 3333*5c51f124SMoriah Waterland echoDebug(DBG_CKSR_FSREADONLY, a_mntPoint, 3334*5c51f124SMoriah Waterland a_fsType); 3335*5c51f124SMoriah Waterland a_gdt->gd_srFsMountedRO = B_TRUE; 3336*5c51f124SMoriah Waterland return (B_TRUE); 3337*5c51f124SMoriah Waterland } 3338*5c51f124SMoriah Waterland } 3339*5c51f124SMoriah Waterland 3340*5c51f124SMoriah Waterland /* Check read-only lofs mount's for live system */ 3341*5c51f124SMoriah Waterland 3342*5c51f124SMoriah Waterland } else { 3343*5c51f124SMoriah Waterland for (i = 0; zDirs[i] != NULL; i++) { 3344*5c51f124SMoriah Waterland if (strncmp(a_mntPoint, zDirs[i], 3345*5c51f124SMoriah Waterland sizeof (zDirs[i])) == 0) { 3346*5c51f124SMoriah Waterland echoDebug(DBG_CKSR_FSREADONLY, a_mntPoint, 3347*5c51f124SMoriah Waterland a_fsType); 3348*5c51f124SMoriah Waterland a_gdt->gd_srFsMountedRO = B_TRUE; 3349*5c51f124SMoriah Waterland return (B_TRUE); 3350*5c51f124SMoriah Waterland } 3351*5c51f124SMoriah Waterland } 3352*5c51f124SMoriah Waterland } 3353*5c51f124SMoriah Waterland 3354*5c51f124SMoriah Waterland return (B_FALSE); 3355*5c51f124SMoriah Waterland } 3356*5c51f124SMoriah Waterland 3357*5c51f124SMoriah Waterland /* 3358*5c51f124SMoriah Waterland * Name: adjustResults 3359*5c51f124SMoriah Waterland * Description: adjust output result code before existing 3360*5c51f124SMoriah Waterland * Arguments: a_result - result code to adjust 3361*5c51f124SMoriah Waterland * Returns: int - adjusted result code 3362*5c51f124SMoriah Waterland */ 3363*5c51f124SMoriah Waterland 3364*5c51f124SMoriah Waterland static int 3365*5c51f124SMoriah Waterland adjustResults(int a_result) 3366*5c51f124SMoriah Waterland { 3367*5c51f124SMoriah Waterland boolean_t negate = getNegateResults(); 3368*5c51f124SMoriah Waterland int realResult; 3369*5c51f124SMoriah Waterland 3370*5c51f124SMoriah Waterland /* adjust code as appropriate */ 3371*5c51f124SMoriah Waterland 3372*5c51f124SMoriah Waterland switch (a_result) { 3373*5c51f124SMoriah Waterland case R_SUCCESS: /* condition satisfied */ 3374*5c51f124SMoriah Waterland realResult = ((negate == B_TRUE) ? 1 : 0); 3375*5c51f124SMoriah Waterland break; 3376*5c51f124SMoriah Waterland case R_FAILURE: /* condition not satisfied */ 3377*5c51f124SMoriah Waterland realResult = ((negate == B_TRUE) ? 0 : 1); 3378*5c51f124SMoriah Waterland break; 3379*5c51f124SMoriah Waterland case R_USAGE: /* usage errors */ 3380*5c51f124SMoriah Waterland realResult = 2; 3381*5c51f124SMoriah Waterland break; 3382*5c51f124SMoriah Waterland case R_ERROR: /* condition could not be determined */ 3383*5c51f124SMoriah Waterland default: 3384*5c51f124SMoriah Waterland realResult = 3; 3385*5c51f124SMoriah Waterland break; 3386*5c51f124SMoriah Waterland } 3387*5c51f124SMoriah Waterland 3388*5c51f124SMoriah Waterland /* debugging output */ 3389*5c51f124SMoriah Waterland 3390*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_ADJUST_RESULTS, a_result, negate, 3391*5c51f124SMoriah Waterland realResult); 3392*5c51f124SMoriah Waterland 3393*5c51f124SMoriah Waterland /* return results */ 3394*5c51f124SMoriah Waterland 3395*5c51f124SMoriah Waterland return (realResult); 3396*5c51f124SMoriah Waterland } 3397*5c51f124SMoriah Waterland 3398*5c51f124SMoriah Waterland /* 3399*5c51f124SMoriah Waterland * Name: setCmdLinePath 3400*5c51f124SMoriah Waterland * Description: set global command line path 3401*5c51f124SMoriah Waterland * Arguments: path - path to set from the command line 3402*5c51f124SMoriah Waterland * args - command line args 3403*5c51f124SMoriah Waterland * num_args - number of command line args 3404*5c51f124SMoriah Waterland * Returns: R_SUCCESS - root path successfully set 3405*5c51f124SMoriah Waterland * R_FAILURE - root path could not be set 3406*5c51f124SMoriah Waterland * R_ERROR - fatal error attempting to set root path 3407*5c51f124SMoriah Waterland */ 3408*5c51f124SMoriah Waterland 3409*5c51f124SMoriah Waterland static void 3410*5c51f124SMoriah Waterland setCmdLinePath(char **path, char **args, int num_args) 3411*5c51f124SMoriah Waterland { 3412*5c51f124SMoriah Waterland char rp[PATH_MAX] = { '\0' }; 3413*5c51f124SMoriah Waterland struct stat statbuf; 3414*5c51f124SMoriah Waterland 3415*5c51f124SMoriah Waterland if (*path != NULL) { 3416*5c51f124SMoriah Waterland return; 3417*5c51f124SMoriah Waterland } 3418*5c51f124SMoriah Waterland 3419*5c51f124SMoriah Waterland /* 3420*5c51f124SMoriah Waterland * If a path "pkgcond is_global_zone [path]" is provided on the 3421*5c51f124SMoriah Waterland * command line it must be the last argument. 3422*5c51f124SMoriah Waterland */ 3423*5c51f124SMoriah Waterland 3424*5c51f124SMoriah Waterland if (realpath(args[num_args - 1], rp) != NULL) { 3425*5c51f124SMoriah Waterland if (stat(rp, &statbuf) == 0) { 3426*5c51f124SMoriah Waterland /* make sure the target is a directory */ 3427*5c51f124SMoriah Waterland if ((statbuf.st_mode & S_IFDIR)) { 3428*5c51f124SMoriah Waterland *path = strdup(rp); 3429*5c51f124SMoriah Waterland } else { 3430*5c51f124SMoriah Waterland *path = NULL; 3431*5c51f124SMoriah Waterland } 3432*5c51f124SMoriah Waterland } 3433*5c51f124SMoriah Waterland } 3434*5c51f124SMoriah Waterland } 3435*5c51f124SMoriah Waterland 3436*5c51f124SMoriah Waterland /* 3437*5c51f124SMoriah Waterland * Name: setRootPath 3438*5c51f124SMoriah Waterland * Description: set global root path returned by getRootPath 3439*5c51f124SMoriah Waterland * Arguments: a_path - root path to set 3440*5c51f124SMoriah Waterland * a_mustExist - B_TRUE if path must exist (else error) 3441*5c51f124SMoriah Waterland * - B_FALSE if path may not exist 3442*5c51f124SMoriah Waterland * Returns: R_SUCCESS - root path successfully set 3443*5c51f124SMoriah Waterland * R_FAILURE - root path could not be set 3444*5c51f124SMoriah Waterland * R_ERROR - fatal error attempting to set root path 3445*5c51f124SMoriah Waterland */ 3446*5c51f124SMoriah Waterland 3447*5c51f124SMoriah Waterland static int 3448*5c51f124SMoriah Waterland setRootPath(char *a_path, char *a_envVar, boolean_t a_mustExist) 3449*5c51f124SMoriah Waterland { 3450*5c51f124SMoriah Waterland char rp[PATH_MAX] = { '\0' }; 3451*5c51f124SMoriah Waterland struct stat statbuf; 3452*5c51f124SMoriah Waterland 3453*5c51f124SMoriah Waterland /* if no data then issue warning and return success */ 3454*5c51f124SMoriah Waterland 3455*5c51f124SMoriah Waterland if ((a_path == NULL) || (*a_path == '\0')) { 3456*5c51f124SMoriah Waterland echoDebug(DBG_NO_DEFAULT_ROOT_PATH_SET); 3457*5c51f124SMoriah Waterland return (R_SUCCESS); 3458*5c51f124SMoriah Waterland } 3459*5c51f124SMoriah Waterland 3460*5c51f124SMoriah Waterland /* path present - resolve to absolute path */ 3461*5c51f124SMoriah Waterland 3462*5c51f124SMoriah Waterland if (realpath(a_path, rp) == NULL) { 3463*5c51f124SMoriah Waterland if (a_mustExist == B_TRUE) { 3464*5c51f124SMoriah Waterland /* must exist ... error */ 3465*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID, 3466*5c51f124SMoriah Waterland a_path, strerror(errno)); 3467*5c51f124SMoriah Waterland return (R_ERROR); 3468*5c51f124SMoriah Waterland } else { 3469*5c51f124SMoriah Waterland /* may not exist - use path as specified */ 3470*5c51f124SMoriah Waterland (void) strcpy(rp, a_path); 3471*5c51f124SMoriah Waterland } 3472*5c51f124SMoriah Waterland } 3473*5c51f124SMoriah Waterland 3474*5c51f124SMoriah Waterland /* debugging output */ 3475*5c51f124SMoriah Waterland 3476*5c51f124SMoriah Waterland echoDebug(DBG_DEFAULT_ROOT_PATH_SET, rp, a_envVar ? a_envVar : ""); 3477*5c51f124SMoriah Waterland 3478*5c51f124SMoriah Waterland /* validate path existence if it must exist */ 3479*5c51f124SMoriah Waterland 3480*5c51f124SMoriah Waterland if (a_mustExist == B_TRUE) { 3481*5c51f124SMoriah Waterland 3482*5c51f124SMoriah Waterland /* get node status */ 3483*5c51f124SMoriah Waterland 3484*5c51f124SMoriah Waterland if (stat(rp, &statbuf) != 0) { 3485*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_INVALID, 3486*5c51f124SMoriah Waterland rp, strerror(errno)); 3487*5c51f124SMoriah Waterland return (R_ERROR); 3488*5c51f124SMoriah Waterland } 3489*5c51f124SMoriah Waterland 3490*5c51f124SMoriah Waterland /* make sure the target is a directory */ 3491*5c51f124SMoriah Waterland 3492*5c51f124SMoriah Waterland if (!(statbuf.st_mode & S_IFDIR)) { 3493*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_DEFAULT_ROOT_NOT_DIR, rp); 3494*5c51f124SMoriah Waterland return (R_ERROR); 3495*5c51f124SMoriah Waterland } 3496*5c51f124SMoriah Waterland } 3497*5c51f124SMoriah Waterland 3498*5c51f124SMoriah Waterland /* target exists and is a directory - set */ 3499*5c51f124SMoriah Waterland 3500*5c51f124SMoriah Waterland echoDebug(DBG_SET_ROOT_PATH_TO, rp); 3501*5c51f124SMoriah Waterland 3502*5c51f124SMoriah Waterland /* store copy of resolved root path */ 3503*5c51f124SMoriah Waterland 3504*5c51f124SMoriah Waterland _rootPath = strdup(rp); 3505*5c51f124SMoriah Waterland 3506*5c51f124SMoriah Waterland /* success! */ 3507*5c51f124SMoriah Waterland 3508*5c51f124SMoriah Waterland return (R_SUCCESS); 3509*5c51f124SMoriah Waterland } 3510*5c51f124SMoriah Waterland 3511*5c51f124SMoriah Waterland /* 3512*5c51f124SMoriah Waterland * Name: testPath 3513*5c51f124SMoriah Waterland * Description: determine if a path meets the specified conditions 3514*5c51f124SMoriah Waterland * Arguments: a_tt - conditions to test path against 3515*5c51f124SMoriah Waterland * a_format - format to use to generate path 3516*5c51f124SMoriah Waterland * arguments following a_format - as needed for a_format 3517*5c51f124SMoriah Waterland * Returns: R_SUCCESS - the path meets all of the specified conditions 3518*5c51f124SMoriah Waterland * R_FAILURE - the path does not meet all of the conditions 3519*5c51f124SMoriah Waterland * R_ERROR - error attempting to test path 3520*5c51f124SMoriah Waterland */ 3521*5c51f124SMoriah Waterland 3522*5c51f124SMoriah Waterland /*PRINTFLIKE2*/ 3523*5c51f124SMoriah Waterland static int 3524*5c51f124SMoriah Waterland testPath(TEST_TYPES a_tt, char *a_format, ...) 3525*5c51f124SMoriah Waterland { 3526*5c51f124SMoriah Waterland char *mbPath; /* copy for the path to be returned */ 3527*5c51f124SMoriah Waterland char bfr[1]; 3528*5c51f124SMoriah Waterland int r; 3529*5c51f124SMoriah Waterland size_t vres = 0; 3530*5c51f124SMoriah Waterland struct stat statbuf; 3531*5c51f124SMoriah Waterland va_list ap; 3532*5c51f124SMoriah Waterland int fd; 3533*5c51f124SMoriah Waterland 3534*5c51f124SMoriah Waterland /* entry assertions */ 3535*5c51f124SMoriah Waterland 3536*5c51f124SMoriah Waterland assert(a_format != NULL); 3537*5c51f124SMoriah Waterland assert(*a_format != '\0'); 3538*5c51f124SMoriah Waterland 3539*5c51f124SMoriah Waterland /* determine size of the message in bytes */ 3540*5c51f124SMoriah Waterland 3541*5c51f124SMoriah Waterland va_start(ap, a_format); 3542*5c51f124SMoriah Waterland vres = vsnprintf(bfr, 1, a_format, ap); 3543*5c51f124SMoriah Waterland va_end(ap); 3544*5c51f124SMoriah Waterland 3545*5c51f124SMoriah Waterland assert(vres > 0); 3546*5c51f124SMoriah Waterland 3547*5c51f124SMoriah Waterland /* allocate storage to hold the message */ 3548*5c51f124SMoriah Waterland 3549*5c51f124SMoriah Waterland mbPath = (char *)calloc(1, vres+2); 3550*5c51f124SMoriah Waterland assert(mbPath != NULL); 3551*5c51f124SMoriah Waterland 3552*5c51f124SMoriah Waterland /* generate the results of the printf conversion */ 3553*5c51f124SMoriah Waterland 3554*5c51f124SMoriah Waterland va_start(ap, a_format); 3555*5c51f124SMoriah Waterland vres = vsnprintf(mbPath, vres+1, a_format, ap); 3556*5c51f124SMoriah Waterland va_end(ap); 3557*5c51f124SMoriah Waterland 3558*5c51f124SMoriah Waterland assert(vres > 0); 3559*5c51f124SMoriah Waterland 3560*5c51f124SMoriah Waterland echoDebug(DBG_TEST_PATH, mbPath, (unsigned long)a_tt); 3561*5c51f124SMoriah Waterland 3562*5c51f124SMoriah Waterland /* 3563*5c51f124SMoriah Waterland * When a path given to open(2) contains symbolic links, the 3564*5c51f124SMoriah Waterland * open system call first resolves all symbolic links and then 3565*5c51f124SMoriah Waterland * opens that final "resolved" path. As a result, it is not 3566*5c51f124SMoriah Waterland * possible to check the result of an fstat(2) against the 3567*5c51f124SMoriah Waterland * file descriptor returned by open(2) for S_IFLNK (a symbolic 3568*5c51f124SMoriah Waterland * link) since all symbolic links are resolved before the 3569*5c51f124SMoriah Waterland * target is opened. 3570*5c51f124SMoriah Waterland * 3571*5c51f124SMoriah Waterland * When testing the target as being (or not being) a symbolic 3572*5c51f124SMoriah Waterland * link, first use lstat(2) against the target to determine 3573*5c51f124SMoriah Waterland * whether or not the specified target itself is (or is not) a 3574*5c51f124SMoriah Waterland * symbolic link. 3575*5c51f124SMoriah Waterland */ 3576*5c51f124SMoriah Waterland 3577*5c51f124SMoriah Waterland if (a_tt & (TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)) { 3578*5c51f124SMoriah Waterland /* 3579*5c51f124SMoriah Waterland * testing target is/is not a symbolic link; use lstat 3580*5c51f124SMoriah Waterland * to determine the status of the target itself rather 3581*5c51f124SMoriah Waterland * than what the target might finally address. 3582*5c51f124SMoriah Waterland */ 3583*5c51f124SMoriah Waterland 3584*5c51f124SMoriah Waterland if (lstat(mbPath, &statbuf) != 0) { 3585*5c51f124SMoriah Waterland echoDebug(DBG_CANNOT_LSTAT_PATH, mbPath, 3586*5c51f124SMoriah Waterland strerror(errno)); 3587*5c51f124SMoriah Waterland free(mbPath); 3588*5c51f124SMoriah Waterland return (R_FAILURE); 3589*5c51f124SMoriah Waterland } 3590*5c51f124SMoriah Waterland 3591*5c51f124SMoriah Waterland /* Is the target required to be a symbolic link? */ 3592*5c51f124SMoriah Waterland 3593*5c51f124SMoriah Waterland if (a_tt & TEST_IS_SYMBOLIC_LINK) { 3594*5c51f124SMoriah Waterland /* target must be a symbolic link */ 3595*5c51f124SMoriah Waterland if (!(statbuf.st_mode & S_IFLNK)) { 3596*5c51f124SMoriah Waterland /* failure: target is not a symbolic link */ 3597*5c51f124SMoriah Waterland echoDebug(DBG_IS_NOT_A_SYMLINK, mbPath); 3598*5c51f124SMoriah Waterland free(mbPath); 3599*5c51f124SMoriah Waterland return (R_FAILURE); 3600*5c51f124SMoriah Waterland } 3601*5c51f124SMoriah Waterland /* success: target is a symbolic link */ 3602*5c51f124SMoriah Waterland echoDebug(DBG_SYMLINK_IS, mbPath); 3603*5c51f124SMoriah Waterland } 3604*5c51f124SMoriah Waterland 3605*5c51f124SMoriah Waterland /* Is the target required to not be a symbolic link? */ 3606*5c51f124SMoriah Waterland 3607*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_SYMBOLIC_LINK) { 3608*5c51f124SMoriah Waterland /* target must not be a symbolic link */ 3609*5c51f124SMoriah Waterland if (statbuf.st_mode & S_IFLNK) { 3610*5c51f124SMoriah Waterland /* failure: target is a symbolic link */ 3611*5c51f124SMoriah Waterland echoDebug(DBG_IS_A_SYMLINK, mbPath); 3612*5c51f124SMoriah Waterland free(mbPath); 3613*5c51f124SMoriah Waterland return (R_FAILURE); 3614*5c51f124SMoriah Waterland } 3615*5c51f124SMoriah Waterland /* success: target is not a symbolic link */ 3616*5c51f124SMoriah Waterland echoDebug(DBG_SYMLINK_NOT, mbPath); 3617*5c51f124SMoriah Waterland } 3618*5c51f124SMoriah Waterland 3619*5c51f124SMoriah Waterland /* 3620*5c51f124SMoriah Waterland * if only testing is/is not a symbolic link, then 3621*5c51f124SMoriah Waterland * no need to open the target: return success. 3622*5c51f124SMoriah Waterland */ 3623*5c51f124SMoriah Waterland 3624*5c51f124SMoriah Waterland if (!(a_tt & 3625*5c51f124SMoriah Waterland (~(TEST_IS_SYMBOLIC_LINK|TEST_NOT_SYMBOLIC_LINK)))) { 3626*5c51f124SMoriah Waterland free(mbPath); 3627*5c51f124SMoriah Waterland return (R_SUCCESS); 3628*5c51f124SMoriah Waterland } 3629*5c51f124SMoriah Waterland } 3630*5c51f124SMoriah Waterland 3631*5c51f124SMoriah Waterland /* resolve path and remove any whitespace */ 3632*5c51f124SMoriah Waterland 3633*5c51f124SMoriah Waterland r = resolvePath(&mbPath); 3634*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 3635*5c51f124SMoriah Waterland echoDebug(DBG_TEST_PATH_NO_RESOLVE, mbPath); 3636*5c51f124SMoriah Waterland free(mbPath); 3637*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_EXISTS) { 3638*5c51f124SMoriah Waterland return (R_SUCCESS); 3639*5c51f124SMoriah Waterland } 3640*5c51f124SMoriah Waterland return (r); 3641*5c51f124SMoriah Waterland } 3642*5c51f124SMoriah Waterland 3643*5c51f124SMoriah Waterland echoDebug(DBG_TEST_PATH_RESOLVE, mbPath); 3644*5c51f124SMoriah Waterland 3645*5c51f124SMoriah Waterland /* open the file - this is the basic existence test */ 3646*5c51f124SMoriah Waterland 3647*5c51f124SMoriah Waterland fd = open(mbPath, O_RDONLY|O_LARGEFILE, 0); 3648*5c51f124SMoriah Waterland 3649*5c51f124SMoriah Waterland /* existence test failed if file cannot be opened */ 3650*5c51f124SMoriah Waterland 3651*5c51f124SMoriah Waterland if (fd < 0) { 3652*5c51f124SMoriah Waterland /* 3653*5c51f124SMoriah Waterland * target could not be opened - if testing for non-existence, 3654*5c51f124SMoriah Waterland * return success, otherwise return failure 3655*5c51f124SMoriah Waterland */ 3656*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_EXISTS) { 3657*5c51f124SMoriah Waterland echoDebug(DBG_CANNOT_ACCESS_PATH_OK, mbPath); 3658*5c51f124SMoriah Waterland free(mbPath); 3659*5c51f124SMoriah Waterland return (R_SUCCESS); 3660*5c51f124SMoriah Waterland } 3661*5c51f124SMoriah Waterland 3662*5c51f124SMoriah Waterland echoDebug(DBG_CANNOT_ACCESS_PATH_BUT_SHOULD, 3663*5c51f124SMoriah Waterland mbPath, strerror(errno)); 3664*5c51f124SMoriah Waterland free(mbPath); 3665*5c51f124SMoriah Waterland 3666*5c51f124SMoriah Waterland return (R_FAILURE); 3667*5c51f124SMoriah Waterland } 3668*5c51f124SMoriah Waterland 3669*5c51f124SMoriah Waterland /* 3670*5c51f124SMoriah Waterland * target successfully opened - if testing for non-existence, 3671*5c51f124SMoriah Waterland * return failure, otherwise continue with specified tests 3672*5c51f124SMoriah Waterland */ 3673*5c51f124SMoriah Waterland 3674*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_EXISTS) { 3675*5c51f124SMoriah Waterland /* testing for non-existence: return failure */ 3676*5c51f124SMoriah Waterland echoDebug(DBG_TEST_EXISTS_SHOULD_NOT, mbPath); 3677*5c51f124SMoriah Waterland free(mbPath); 3678*5c51f124SMoriah Waterland (void) close(fd); 3679*5c51f124SMoriah Waterland return (R_FAILURE); 3680*5c51f124SMoriah Waterland } 3681*5c51f124SMoriah Waterland 3682*5c51f124SMoriah Waterland /* get the file status */ 3683*5c51f124SMoriah Waterland 3684*5c51f124SMoriah Waterland r = fstat(fd, &statbuf); 3685*5c51f124SMoriah Waterland if (r != 0) { 3686*5c51f124SMoriah Waterland echoDebug(DBG_PATH_DOES_NOT_EXIST, mbPath, strerror(errno)); 3687*5c51f124SMoriah Waterland (void) close(fd); 3688*5c51f124SMoriah Waterland free(mbPath); 3689*5c51f124SMoriah Waterland return (R_FAILURE); 3690*5c51f124SMoriah Waterland } 3691*5c51f124SMoriah Waterland 3692*5c51f124SMoriah Waterland /* required to be a directory? */ 3693*5c51f124SMoriah Waterland 3694*5c51f124SMoriah Waterland if (a_tt & TEST_IS_DIRECTORY) { 3695*5c51f124SMoriah Waterland if (!(statbuf.st_mode & S_IFDIR)) { 3696*5c51f124SMoriah Waterland /* is not a directory */ 3697*5c51f124SMoriah Waterland echoDebug(DBG_IS_NOT_A_DIRECTORY, mbPath); 3698*5c51f124SMoriah Waterland free(mbPath); 3699*5c51f124SMoriah Waterland return (R_FAILURE); 3700*5c51f124SMoriah Waterland } 3701*5c51f124SMoriah Waterland /* a directory */ 3702*5c51f124SMoriah Waterland echoDebug(DBG_DIRECTORY_IS, mbPath); 3703*5c51f124SMoriah Waterland } 3704*5c51f124SMoriah Waterland 3705*5c51f124SMoriah Waterland /* required to not be a directory? */ 3706*5c51f124SMoriah Waterland 3707*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_DIRECTORY) { 3708*5c51f124SMoriah Waterland if (statbuf.st_mode & S_IFDIR) { 3709*5c51f124SMoriah Waterland /* is a directory */ 3710*5c51f124SMoriah Waterland echoDebug(DBG_IS_A_DIRECTORY, mbPath); 3711*5c51f124SMoriah Waterland free(mbPath); 3712*5c51f124SMoriah Waterland return (R_FAILURE); 3713*5c51f124SMoriah Waterland } 3714*5c51f124SMoriah Waterland /* not a directory */ 3715*5c51f124SMoriah Waterland echoDebug(DBG_DIRECTORY_NOT, mbPath); 3716*5c51f124SMoriah Waterland } 3717*5c51f124SMoriah Waterland 3718*5c51f124SMoriah Waterland /* required to be a file? */ 3719*5c51f124SMoriah Waterland 3720*5c51f124SMoriah Waterland if (a_tt & TEST_IS_FILE) { 3721*5c51f124SMoriah Waterland if (!(statbuf.st_mode & S_IFREG)) { 3722*5c51f124SMoriah Waterland /* is not a regular file */ 3723*5c51f124SMoriah Waterland echoDebug(DBG_IS_NOT_A_FILE, mbPath); 3724*5c51f124SMoriah Waterland free(mbPath); 3725*5c51f124SMoriah Waterland return (R_FAILURE); 3726*5c51f124SMoriah Waterland } 3727*5c51f124SMoriah Waterland /* a regular file */ 3728*5c51f124SMoriah Waterland echoDebug(DBG_FILE_IS, mbPath); 3729*5c51f124SMoriah Waterland } 3730*5c51f124SMoriah Waterland 3731*5c51f124SMoriah Waterland /* required to not be a file? */ 3732*5c51f124SMoriah Waterland 3733*5c51f124SMoriah Waterland if (a_tt & TEST_NOT_FILE) { 3734*5c51f124SMoriah Waterland if (statbuf.st_mode & S_IFREG) { 3735*5c51f124SMoriah Waterland /* is a regular file */ 3736*5c51f124SMoriah Waterland echoDebug(DBG_IS_A_FILE, mbPath); 3737*5c51f124SMoriah Waterland free(mbPath); 3738*5c51f124SMoriah Waterland return (R_FAILURE); 3739*5c51f124SMoriah Waterland } 3740*5c51f124SMoriah Waterland /* not a regular file */ 3741*5c51f124SMoriah Waterland echoDebug(DBG_FILE_NOT, mbPath); 3742*5c51f124SMoriah Waterland } 3743*5c51f124SMoriah Waterland 3744*5c51f124SMoriah Waterland /* 3745*5c51f124SMoriah Waterland * Find token (global) in file pointed to by mbPath. 3746*5c51f124SMoriah Waterland * token is only compared to first word in mbPath. 3747*5c51f124SMoriah Waterland */ 3748*5c51f124SMoriah Waterland 3749*5c51f124SMoriah Waterland if (a_tt & TEST_GLOBAL_TOKEN_IN_FILE) { 3750*5c51f124SMoriah Waterland if (!(statbuf.st_mode & S_IFREG)) { 3751*5c51f124SMoriah Waterland /* is not a regular file */ 3752*5c51f124SMoriah Waterland echoDebug(DBG_IS_NOT_A_FILE, mbPath); 3753*5c51f124SMoriah Waterland free(mbPath); 3754*5c51f124SMoriah Waterland return (R_FAILURE); 3755*5c51f124SMoriah Waterland } 3756*5c51f124SMoriah Waterland /* If global exists then we're not in a non-global zone */ 3757*5c51f124SMoriah Waterland if (findToken(mbPath, GLOBAL_ZONENAME) == R_SUCCESS) { 3758*5c51f124SMoriah Waterland echoDebug(DBG_TOKEN__EXISTS, GLOBAL_ZONENAME, mbPath); 3759*5c51f124SMoriah Waterland free(mbPath); 3760*5c51f124SMoriah Waterland return (R_FAILURE); 3761*5c51f124SMoriah Waterland } 3762*5c51f124SMoriah Waterland } 3763*5c51f124SMoriah Waterland 3764*5c51f124SMoriah Waterland (void) close(fd); 3765*5c51f124SMoriah Waterland 3766*5c51f124SMoriah Waterland /* success! */ 3767*5c51f124SMoriah Waterland 3768*5c51f124SMoriah Waterland echoDebug(DBG_TESTPATH_OK, mbPath); 3769*5c51f124SMoriah Waterland 3770*5c51f124SMoriah Waterland /* free up temp storage used to hold path to test */ 3771*5c51f124SMoriah Waterland 3772*5c51f124SMoriah Waterland free(mbPath); 3773*5c51f124SMoriah Waterland 3774*5c51f124SMoriah Waterland return (R_SUCCESS); 3775*5c51f124SMoriah Waterland } 3776*5c51f124SMoriah Waterland 3777*5c51f124SMoriah Waterland /* 3778*5c51f124SMoriah Waterland * Name: findToken 3779*5c51f124SMoriah Waterland * Description: Find first token in file. 3780*5c51f124SMoriah Waterland * Arguments: 3781*5c51f124SMoriah Waterland * path - file to search for token 3782*5c51f124SMoriah Waterland * token - string to search for 3783*5c51f124SMoriah Waterland * Returns: 3784*5c51f124SMoriah Waterland * R_SUCCESS - the token exists 3785*5c51f124SMoriah Waterland * R_FAILURE - the token does not exist 3786*5c51f124SMoriah Waterland * R_ERROR - fatal error attempting to find token 3787*5c51f124SMoriah Waterland */ 3788*5c51f124SMoriah Waterland 3789*5c51f124SMoriah Waterland static int 3790*5c51f124SMoriah Waterland findToken(char *path, char *token) 3791*5c51f124SMoriah Waterland { 3792*5c51f124SMoriah Waterland FILE *fp; 3793*5c51f124SMoriah Waterland char *cp; 3794*5c51f124SMoriah Waterland char line[MAXPATHLEN]; 3795*5c51f124SMoriah Waterland 3796*5c51f124SMoriah Waterland if (path == NULL || token == NULL) { 3797*5c51f124SMoriah Waterland return (R_ERROR); 3798*5c51f124SMoriah Waterland } 3799*5c51f124SMoriah Waterland if ((fp = fopen(path, "r")) == NULL) { 3800*5c51f124SMoriah Waterland return (R_ERROR); 3801*5c51f124SMoriah Waterland } 3802*5c51f124SMoriah Waterland 3803*5c51f124SMoriah Waterland while (fgets(line, sizeof (line), fp) != NULL) { 3804*5c51f124SMoriah Waterland for (cp = line; *cp && isspace(*cp); cp++); 3805*5c51f124SMoriah Waterland /* skip comments */ 3806*5c51f124SMoriah Waterland if (*cp == '#') { 3807*5c51f124SMoriah Waterland continue; 3808*5c51f124SMoriah Waterland } 3809*5c51f124SMoriah Waterland if (pkgstrContainsToken(cp, token, ":")) { 3810*5c51f124SMoriah Waterland (void) fclose(fp); 3811*5c51f124SMoriah Waterland return (R_SUCCESS); 3812*5c51f124SMoriah Waterland } 3813*5c51f124SMoriah Waterland } 3814*5c51f124SMoriah Waterland (void) fclose(fp); 3815*5c51f124SMoriah Waterland return (R_FAILURE); 3816*5c51f124SMoriah Waterland } 3817*5c51f124SMoriah Waterland 3818*5c51f124SMoriah Waterland 3819*5c51f124SMoriah Waterland /* 3820*5c51f124SMoriah Waterland * Name: resolvePath 3821*5c51f124SMoriah Waterland * Description: fully resolve a path to an absolute real path 3822*5c51f124SMoriah Waterland * Arguments: r_path - pointer to pointer to malloc()ed storage containing 3823*5c51f124SMoriah Waterland * the path to resolve - this path may be reallocated 3824*5c51f124SMoriah Waterland * as necessary to hold the fully resolved path 3825*5c51f124SMoriah Waterland * Output: r_path - is realloc()ed as necessary 3826*5c51f124SMoriah Waterland * Returns: R_SUCCESS - the path is fully resolved 3827*5c51f124SMoriah Waterland * R_FAILURE - the path could not be resolved 3828*5c51f124SMoriah Waterland * R_ERROR - fatal error attempting to resolve path 3829*5c51f124SMoriah Waterland */ 3830*5c51f124SMoriah Waterland 3831*5c51f124SMoriah Waterland static int 3832*5c51f124SMoriah Waterland resolvePath(char **r_path) 3833*5c51f124SMoriah Waterland { 3834*5c51f124SMoriah Waterland int i; 3835*5c51f124SMoriah Waterland char resolvedPath[MAXPATHLEN+1] = {'\0'}; 3836*5c51f124SMoriah Waterland size_t mbPathlen; /* length of multi-byte path */ 3837*5c51f124SMoriah Waterland size_t wcPathlen; /* length of wide-character path */ 3838*5c51f124SMoriah Waterland wchar_t *wcPath; /* wide-character version of the path */ 3839*5c51f124SMoriah Waterland wchar_t *wptr; /* scratch pointer */ 3840*5c51f124SMoriah Waterland 3841*5c51f124SMoriah Waterland /* entry assertions */ 3842*5c51f124SMoriah Waterland 3843*5c51f124SMoriah Waterland assert(r_path != (char **)NULL); 3844*5c51f124SMoriah Waterland 3845*5c51f124SMoriah Waterland /* return error if the path is completely empty */ 3846*5c51f124SMoriah Waterland 3847*5c51f124SMoriah Waterland if (*r_path == '\0') { 3848*5c51f124SMoriah Waterland return (R_FAILURE); 3849*5c51f124SMoriah Waterland } 3850*5c51f124SMoriah Waterland 3851*5c51f124SMoriah Waterland /* remove all leading whitespace */ 3852*5c51f124SMoriah Waterland 3853*5c51f124SMoriah Waterland removeLeadingWhitespace(r_path); 3854*5c51f124SMoriah Waterland 3855*5c51f124SMoriah Waterland /* 3856*5c51f124SMoriah Waterland * convert to real path: an absolute pathname that names the same file, 3857*5c51f124SMoriah Waterland * whose resolution does not involve ".", "..", or symbolic links. 3858*5c51f124SMoriah Waterland */ 3859*5c51f124SMoriah Waterland 3860*5c51f124SMoriah Waterland if (realpath(*r_path, resolvedPath) != NULL) { 3861*5c51f124SMoriah Waterland free(*r_path); 3862*5c51f124SMoriah Waterland *r_path = strdup(resolvedPath); 3863*5c51f124SMoriah Waterland } 3864*5c51f124SMoriah Waterland 3865*5c51f124SMoriah Waterland /* 3866*5c51f124SMoriah Waterland * convert the multi-byte version of the path to a 3867*5c51f124SMoriah Waterland * wide-character rendering, for doing our figuring. 3868*5c51f124SMoriah Waterland */ 3869*5c51f124SMoriah Waterland 3870*5c51f124SMoriah Waterland mbPathlen = strlen(*r_path); 3871*5c51f124SMoriah Waterland 3872*5c51f124SMoriah Waterland if ((wcPath = (wchar_t *) 3873*5c51f124SMoriah Waterland calloc(1, sizeof (wchar_t)*(mbPathlen+1))) == NULL) { 3874*5c51f124SMoriah Waterland return (R_FAILURE); 3875*5c51f124SMoriah Waterland } 3876*5c51f124SMoriah Waterland 3877*5c51f124SMoriah Waterland /*LINTED*/ 3878*5c51f124SMoriah Waterland if ((wcPathlen = mbstowcs(wcPath, *r_path, mbPathlen)) == -1) { 3879*5c51f124SMoriah Waterland free(wcPath); 3880*5c51f124SMoriah Waterland return (R_FAILURE); 3881*5c51f124SMoriah Waterland } 3882*5c51f124SMoriah Waterland 3883*5c51f124SMoriah Waterland /* 3884*5c51f124SMoriah Waterland * remove duplicate slashes first ("//../" -> "/") 3885*5c51f124SMoriah Waterland */ 3886*5c51f124SMoriah Waterland 3887*5c51f124SMoriah Waterland for (wptr = wcPath, i = 0; i < wcPathlen; i++) { 3888*5c51f124SMoriah Waterland *wptr++ = wcPath[i]; 3889*5c51f124SMoriah Waterland 3890*5c51f124SMoriah Waterland if (wcPath[i] == '/') { 3891*5c51f124SMoriah Waterland i++; 3892*5c51f124SMoriah Waterland 3893*5c51f124SMoriah Waterland while (wcPath[i] == '/') { 3894*5c51f124SMoriah Waterland i++; 3895*5c51f124SMoriah Waterland } 3896*5c51f124SMoriah Waterland 3897*5c51f124SMoriah Waterland i--; 3898*5c51f124SMoriah Waterland } 3899*5c51f124SMoriah Waterland } 3900*5c51f124SMoriah Waterland 3901*5c51f124SMoriah Waterland *wptr = '\0'; 3902*5c51f124SMoriah Waterland 3903*5c51f124SMoriah Waterland /* 3904*5c51f124SMoriah Waterland * now convert back to the multi-byte format. 3905*5c51f124SMoriah Waterland */ 3906*5c51f124SMoriah Waterland 3907*5c51f124SMoriah Waterland /*LINTED*/ 3908*5c51f124SMoriah Waterland if (wcstombs(*r_path, wcPath, mbPathlen) == -1) { 3909*5c51f124SMoriah Waterland free(wcPath); 3910*5c51f124SMoriah Waterland return (R_FAILURE); 3911*5c51f124SMoriah Waterland } 3912*5c51f124SMoriah Waterland 3913*5c51f124SMoriah Waterland /* at this point have a path */ 3914*5c51f124SMoriah Waterland 3915*5c51f124SMoriah Waterland /* free up temporary storage */ 3916*5c51f124SMoriah Waterland 3917*5c51f124SMoriah Waterland free(wcPath); 3918*5c51f124SMoriah Waterland 3919*5c51f124SMoriah Waterland return (R_SUCCESS); 3920*5c51f124SMoriah Waterland } 3921*5c51f124SMoriah Waterland 3922*5c51f124SMoriah Waterland /* 3923*5c51f124SMoriah Waterland * Name: removeLeadingWhitespace 3924*5c51f124SMoriah Waterland * Synopsis: Remove leading whitespace from string 3925*5c51f124SMoriah Waterland * Description: Remove all leading whitespace characters from a string 3926*5c51f124SMoriah Waterland * Arguments: a_str - [RO, *RW] - (char **) 3927*5c51f124SMoriah Waterland * Pointer to handle to string (in allocated storage) to 3928*5c51f124SMoriah Waterland * remove all leading whitespace from 3929*5c51f124SMoriah Waterland * Returns: void 3930*5c51f124SMoriah Waterland * The input string is modified as follows: 3931*5c51f124SMoriah Waterland * == NULL: 3932*5c51f124SMoriah Waterland * - input string was NULL 3933*5c51f124SMoriah Waterland * - input string is all whitespace 3934*5c51f124SMoriah Waterland * != NULL: 3935*5c51f124SMoriah Waterland * - copy of input string with leading 3936*5c51f124SMoriah Waterland * whitespace removed 3937*5c51f124SMoriah Waterland * CAUTION: The input string must be allocated space (via malloc() or 3938*5c51f124SMoriah Waterland * strdup()) - it must not be a static or inline character string 3939*5c51f124SMoriah Waterland * NOTE: The input string a_str will be freed with 'free' 3940*5c51f124SMoriah Waterland * if it is all whitespace, or if it contains any leading 3941*5c51f124SMoriah Waterland * whitespace characters 3942*5c51f124SMoriah Waterland * NOTE: Any string returned is placed in new storage for the 3943*5c51f124SMoriah Waterland * calling method. The caller must use 'free' to dispose 3944*5c51f124SMoriah Waterland * of the storage once the string is no longer needed. 3945*5c51f124SMoriah Waterland * Errors: If the string cannot be created, the process exits 3946*5c51f124SMoriah Waterland */ 3947*5c51f124SMoriah Waterland 3948*5c51f124SMoriah Waterland static void 3949*5c51f124SMoriah Waterland removeLeadingWhitespace(char **a_str) 3950*5c51f124SMoriah Waterland { 3951*5c51f124SMoriah Waterland char *o_str; 3952*5c51f124SMoriah Waterland 3953*5c51f124SMoriah Waterland /* entry assertions */ 3954*5c51f124SMoriah Waterland 3955*5c51f124SMoriah Waterland assert(a_str != (char **)NULL); 3956*5c51f124SMoriah Waterland 3957*5c51f124SMoriah Waterland /* if string is null, just return */ 3958*5c51f124SMoriah Waterland 3959*5c51f124SMoriah Waterland if (*a_str == NULL) { 3960*5c51f124SMoriah Waterland return; 3961*5c51f124SMoriah Waterland } 3962*5c51f124SMoriah Waterland o_str = *a_str; 3963*5c51f124SMoriah Waterland 3964*5c51f124SMoriah Waterland /* if string is empty, deallocate and return NULL */ 3965*5c51f124SMoriah Waterland 3966*5c51f124SMoriah Waterland if (*o_str == '\0') { 3967*5c51f124SMoriah Waterland /* free string */ 3968*5c51f124SMoriah Waterland free(*a_str); 3969*5c51f124SMoriah Waterland *a_str = NULL; 3970*5c51f124SMoriah Waterland return; 3971*5c51f124SMoriah Waterland } 3972*5c51f124SMoriah Waterland 3973*5c51f124SMoriah Waterland /* if first character is not a space, just return */ 3974*5c51f124SMoriah Waterland 3975*5c51f124SMoriah Waterland if (!isspace(*o_str)) { 3976*5c51f124SMoriah Waterland return; 3977*5c51f124SMoriah Waterland } 3978*5c51f124SMoriah Waterland 3979*5c51f124SMoriah Waterland /* advance past all space characters */ 3980*5c51f124SMoriah Waterland 3981*5c51f124SMoriah Waterland while ((*o_str != '\0') && (isspace(*o_str))) { 3982*5c51f124SMoriah Waterland o_str++; 3983*5c51f124SMoriah Waterland } 3984*5c51f124SMoriah Waterland 3985*5c51f124SMoriah Waterland /* if string was all space characters, deallocate and return NULL */ 3986*5c51f124SMoriah Waterland 3987*5c51f124SMoriah Waterland if (*o_str == '\0') { 3988*5c51f124SMoriah Waterland /* free string */ 3989*5c51f124SMoriah Waterland free(*a_str); 3990*5c51f124SMoriah Waterland *a_str = NULL; 3991*5c51f124SMoriah Waterland return; 3992*5c51f124SMoriah Waterland } 3993*5c51f124SMoriah Waterland 3994*5c51f124SMoriah Waterland /* have non-space/null byte, return dup, deallocate original */ 3995*5c51f124SMoriah Waterland 3996*5c51f124SMoriah Waterland o_str = strdup(o_str); 3997*5c51f124SMoriah Waterland free(*a_str); 3998*5c51f124SMoriah Waterland *a_str = o_str; 3999*5c51f124SMoriah Waterland } 4000*5c51f124SMoriah Waterland 4001*5c51f124SMoriah Waterland /* 4002*5c51f124SMoriah Waterland * Name: getZoneName 4003*5c51f124SMoriah Waterland * Description: get the name of the zone this process is running in 4004*5c51f124SMoriah Waterland * Arguments: r_zoneName - pointer to pointer to receive zone name 4005*5c51f124SMoriah Waterland * Output: r_zoneName - a pointer to malloc()ed storage containing 4006*5c51f124SMoriah Waterland * the zone name this process is running in is stored 4007*5c51f124SMoriah Waterland * in the location pointed to by r_zoneName 4008*5c51f124SMoriah Waterland * Returns: R_SUCCESS - the zone name is successfully returned 4009*5c51f124SMoriah Waterland * R_FAILURE - the zone name is not successfully returned 4010*5c51f124SMoriah Waterland * R_ERROR - error attempting to get the zone name 4011*5c51f124SMoriah Waterland */ 4012*5c51f124SMoriah Waterland 4013*5c51f124SMoriah Waterland static int 4014*5c51f124SMoriah Waterland getZoneName(char **r_zoneName) 4015*5c51f124SMoriah Waterland { 4016*5c51f124SMoriah Waterland static char zoneName[ZONENAME_MAX] = { '\0' }; 4017*5c51f124SMoriah Waterland 4018*5c51f124SMoriah Waterland /* if zone name not already present, retrieve and cache name */ 4019*5c51f124SMoriah Waterland 4020*5c51f124SMoriah Waterland if (zoneName[0] == '\0') { 4021*5c51f124SMoriah Waterland if (getzonenamebyid(getzoneid(), zoneName, 4022*5c51f124SMoriah Waterland sizeof (zoneName)) < 0) { 4023*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_CANNOT_GET_ZONENAME); 4024*5c51f124SMoriah Waterland return (R_ERROR); 4025*5c51f124SMoriah Waterland } 4026*5c51f124SMoriah Waterland } 4027*5c51f124SMoriah Waterland 4028*5c51f124SMoriah Waterland /* return cached zone name */ 4029*5c51f124SMoriah Waterland 4030*5c51f124SMoriah Waterland *r_zoneName = zoneName; 4031*5c51f124SMoriah Waterland return (R_SUCCESS); 4032*5c51f124SMoriah Waterland } 4033*5c51f124SMoriah Waterland 4034*5c51f124SMoriah Waterland /* 4035*5c51f124SMoriah Waterland * Name: getRootPath 4036*5c51f124SMoriah Waterland * Description: get the root path being tested by this process 4037*5c51f124SMoriah Waterland * Arguments: r_rootPath - pointer to pointer to receive root path 4038*5c51f124SMoriah Waterland * Output: r_rootPath - a pointer to malloc()ed storage containing 4039*5c51f124SMoriah Waterland * the root path name this process is testing 4040*5c51f124SMoriah Waterland * Returns: R_SUCCESS - the root path is successfully returned 4041*5c51f124SMoriah Waterland * R_FAILURE - the root path is not successfully returned 4042*5c51f124SMoriah Waterland * R_ERROR - error attempting to get the root path 4043*5c51f124SMoriah Waterland */ 4044*5c51f124SMoriah Waterland 4045*5c51f124SMoriah Waterland static int 4046*5c51f124SMoriah Waterland getRootPath(char **r_rootPath) 4047*5c51f124SMoriah Waterland { 4048*5c51f124SMoriah Waterland *r_rootPath = _rootPath; 4049*5c51f124SMoriah Waterland return (R_SUCCESS); 4050*5c51f124SMoriah Waterland } 4051*5c51f124SMoriah Waterland 4052*5c51f124SMoriah Waterland /* 4053*5c51f124SMoriah Waterland * Name: setVerbose 4054*5c51f124SMoriah Waterland * Description: Turns on verbose output 4055*5c51f124SMoriah Waterland * Scope: public 4056*5c51f124SMoriah Waterland * Arguments: verbose = B_TRUE indicates verbose mode 4057*5c51f124SMoriah Waterland * Returns: none 4058*5c51f124SMoriah Waterland */ 4059*5c51f124SMoriah Waterland 4060*5c51f124SMoriah Waterland static void 4061*5c51f124SMoriah Waterland setVerbose(boolean_t setting) 4062*5c51f124SMoriah Waterland { 4063*5c51f124SMoriah Waterland /* set log verbose messages */ 4064*5c51f124SMoriah Waterland 4065*5c51f124SMoriah Waterland log_set_verbose(setting); 4066*5c51f124SMoriah Waterland 4067*5c51f124SMoriah Waterland /* set interactive messages */ 4068*5c51f124SMoriah Waterland 4069*5c51f124SMoriah Waterland echoSetFlag(setting); 4070*5c51f124SMoriah Waterland } 4071*5c51f124SMoriah Waterland 4072*5c51f124SMoriah Waterland /* 4073*5c51f124SMoriah Waterland * Name: negate_results 4074*5c51f124SMoriah Waterland * Description: control negation of results 4075*5c51f124SMoriah Waterland * Scope: public 4076*5c51f124SMoriah Waterland * Arguments: setting 4077*5c51f124SMoriah Waterland * == B_TRUE indicates negated results mode 4078*5c51f124SMoriah Waterland * == B_FALSE indicates non-negated results mode 4079*5c51f124SMoriah Waterland * Returns: none 4080*5c51f124SMoriah Waterland */ 4081*5c51f124SMoriah Waterland 4082*5c51f124SMoriah Waterland static void 4083*5c51f124SMoriah Waterland setNegateResults(boolean_t setting) 4084*5c51f124SMoriah Waterland { 4085*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_SET_NEGATE_RESULTS, 4086*5c51f124SMoriah Waterland _negateResults, setting); 4087*5c51f124SMoriah Waterland 4088*5c51f124SMoriah Waterland _negateResults = setting; 4089*5c51f124SMoriah Waterland } 4090*5c51f124SMoriah Waterland 4091*5c51f124SMoriah Waterland /* 4092*5c51f124SMoriah Waterland * Name: getNegateResults 4093*5c51f124SMoriah Waterland * Description: Returns whether or not to results are negated 4094*5c51f124SMoriah Waterland * Scope: public 4095*5c51f124SMoriah Waterland * Arguments: none 4096*5c51f124SMoriah Waterland * Returns: B_TRUE - results are negated 4097*5c51f124SMoriah Waterland * B_FALSE - results are not negated 4098*5c51f124SMoriah Waterland */ 4099*5c51f124SMoriah Waterland 4100*5c51f124SMoriah Waterland static boolean_t 4101*5c51f124SMoriah Waterland getNegateResults(void) 4102*5c51f124SMoriah Waterland { 4103*5c51f124SMoriah Waterland return (_negateResults); 4104*5c51f124SMoriah Waterland } 4105*5c51f124SMoriah Waterland 4106*5c51f124SMoriah Waterland /* 4107*5c51f124SMoriah Waterland * Name: usage 4108*5c51f124SMoriah Waterland * Description: output usage string 4109*5c51f124SMoriah Waterland * Arguments: a_format - format to use to generate message 4110*5c51f124SMoriah Waterland * arguments following a_format - as needed for a_format 4111*5c51f124SMoriah Waterland * Output: Outputs the usage string to stderr. 4112*5c51f124SMoriah Waterland * Returns: R_ERROR 4113*5c51f124SMoriah Waterland */ 4114*5c51f124SMoriah Waterland 4115*5c51f124SMoriah Waterland static int 4116*5c51f124SMoriah Waterland usage(char *a_format, ...) 4117*5c51f124SMoriah Waterland { 4118*5c51f124SMoriah Waterland int cur_cmd; 4119*5c51f124SMoriah Waterland char cmdlst[LINE_MAX+1] = { '\0' }; 4120*5c51f124SMoriah Waterland char *message; 4121*5c51f124SMoriah Waterland char bfr[1]; 4122*5c51f124SMoriah Waterland char *p = get_prog_name(); 4123*5c51f124SMoriah Waterland size_t vres = 0; 4124*5c51f124SMoriah Waterland va_list ap; 4125*5c51f124SMoriah Waterland 4126*5c51f124SMoriah Waterland /* entry assertions */ 4127*5c51f124SMoriah Waterland 4128*5c51f124SMoriah Waterland assert(a_format != NULL); 4129*5c51f124SMoriah Waterland assert(*a_format != '\0'); 4130*5c51f124SMoriah Waterland 4131*5c51f124SMoriah Waterland /* determine size of the message in bytes */ 4132*5c51f124SMoriah Waterland 4133*5c51f124SMoriah Waterland va_start(ap, a_format); 4134*5c51f124SMoriah Waterland /* LINTED warning: variable format specifier to vsnprintf(); */ 4135*5c51f124SMoriah Waterland vres = vsnprintf(bfr, 1, a_format, ap); 4136*5c51f124SMoriah Waterland va_end(ap); 4137*5c51f124SMoriah Waterland 4138*5c51f124SMoriah Waterland assert(vres > 0); 4139*5c51f124SMoriah Waterland 4140*5c51f124SMoriah Waterland /* allocate storage to hold the message */ 4141*5c51f124SMoriah Waterland 4142*5c51f124SMoriah Waterland message = (char *)calloc(1, vres+2); 4143*5c51f124SMoriah Waterland assert(message != NULL); 4144*5c51f124SMoriah Waterland 4145*5c51f124SMoriah Waterland /* generate the results of the printf conversion */ 4146*5c51f124SMoriah Waterland 4147*5c51f124SMoriah Waterland va_start(ap, a_format); 4148*5c51f124SMoriah Waterland /* LINTED warning: variable format specifier to vsnprintf(); */ 4149*5c51f124SMoriah Waterland vres = vsnprintf(message, vres+1, a_format, ap); 4150*5c51f124SMoriah Waterland va_end(ap); 4151*5c51f124SMoriah Waterland 4152*5c51f124SMoriah Waterland assert(vres > 0); 4153*5c51f124SMoriah Waterland 4154*5c51f124SMoriah Waterland /* generate list of all defined conditions */ 4155*5c51f124SMoriah Waterland 4156*5c51f124SMoriah Waterland for (cur_cmd = 0; cmds[cur_cmd].c_name != NULL; cur_cmd++) { 4157*5c51f124SMoriah Waterland (void) strlcat(cmdlst, "\t", sizeof (cmdlst)); 4158*5c51f124SMoriah Waterland (void) strlcat(cmdlst, cmds[cur_cmd].c_name, sizeof (cmdlst)); 4159*5c51f124SMoriah Waterland if (cmds[cur_cmd].c_args != NULL) { 4160*5c51f124SMoriah Waterland (void) strlcat(cmdlst, cmds[cur_cmd].c_args, 4161*5c51f124SMoriah Waterland sizeof (cmdlst)); 4162*5c51f124SMoriah Waterland } 4163*5c51f124SMoriah Waterland (void) strlcat(cmdlst, "\n", sizeof (cmdlst)); 4164*5c51f124SMoriah Waterland } 4165*5c51f124SMoriah Waterland 4166*5c51f124SMoriah Waterland /* output usage with conditions */ 4167*5c51f124SMoriah Waterland 4168*5c51f124SMoriah Waterland log_msg(LOG_MSG_INFO, MSG_USAGE, message, p ? p : "pkgcond", cmdlst); 4169*5c51f124SMoriah Waterland 4170*5c51f124SMoriah Waterland return (R_ERROR); 4171*5c51f124SMoriah Waterland } 4172*5c51f124SMoriah Waterland 4173*5c51f124SMoriah Waterland /* 4174*5c51f124SMoriah Waterland * Name: parseGlobalData 4175*5c51f124SMoriah Waterland * Description: parse environment global data and store in global data structure 4176*5c51f124SMoriah Waterland * Arguments: a_envVar - pointer to string representing the name of the 4177*5c51f124SMoriah Waterland * environment variable to get and parse 4178*5c51f124SMoriah Waterland * r_gdt - pointer to pointer to global data structure to fill in 4179*5c51f124SMoriah Waterland * using the parsed data from a_envVar 4180*5c51f124SMoriah Waterland * Output: none 4181*5c51f124SMoriah Waterland * Returns: R_SUCCESS - the global data is successfully parsed 4182*5c51f124SMoriah Waterland * R_FAILURE - problem parsing global data 4183*5c51f124SMoriah Waterland * R_ERROR - fatal error attempting to parse global data 4184*5c51f124SMoriah Waterland */ 4185*5c51f124SMoriah Waterland 4186*5c51f124SMoriah Waterland static int 4187*5c51f124SMoriah Waterland parseGlobalData(char *a_envVar, GLOBALDATA_T **r_gdt) 4188*5c51f124SMoriah Waterland { 4189*5c51f124SMoriah Waterland int r; 4190*5c51f124SMoriah Waterland int n; 4191*5c51f124SMoriah Waterland char *a; 4192*5c51f124SMoriah Waterland SML_TAG *tag; 4193*5c51f124SMoriah Waterland SML_TAG *ntag; 4194*5c51f124SMoriah Waterland 4195*5c51f124SMoriah Waterland assert(r_gdt != (GLOBALDATA_T **)NULL); 4196*5c51f124SMoriah Waterland 4197*5c51f124SMoriah Waterland /* 4198*5c51f124SMoriah Waterland * allocate space for global data structure if needed 4199*5c51f124SMoriah Waterland */ 4200*5c51f124SMoriah Waterland 4201*5c51f124SMoriah Waterland if (*r_gdt == (GLOBALDATA_T *)NULL) { 4202*5c51f124SMoriah Waterland *r_gdt = (GLOBALDATA_T *)calloc(1, sizeof (GLOBALDATA_T)); 4203*5c51f124SMoriah Waterland } 4204*5c51f124SMoriah Waterland 4205*5c51f124SMoriah Waterland /* 4206*5c51f124SMoriah Waterland * get initial installation indication: 4207*5c51f124SMoriah Waterland * If the initial install variable is set to "true", then an initial 4208*5c51f124SMoriah Waterland * installation of Solaris is underway. When this condition is true: 4209*5c51f124SMoriah Waterland * - if the path being checked is the package install root, then 4210*5c51f124SMoriah Waterland * the path is considered to be an 'alternative root' which is 4211*5c51f124SMoriah Waterland * currently being installed. 4212*5c51f124SMoriah Waterland * - if the path being checked is not the package install root, then 4213*5c51f124SMoriah Waterland * the path needs to be further analyzed to determine what it may 4214*5c51f124SMoriah Waterland * be referring to. 4215*5c51f124SMoriah Waterland */ 4216*5c51f124SMoriah Waterland 4217*5c51f124SMoriah Waterland a = getenv(ENV_VAR_INITIAL_INSTALL); 4218*5c51f124SMoriah Waterland if ((a != NULL) && (strcasecmp(a, "true") == 0)) { 4219*5c51f124SMoriah Waterland (*r_gdt)->gd_initialInstall = B_TRUE; 4220*5c51f124SMoriah Waterland } 4221*5c51f124SMoriah Waterland 4222*5c51f124SMoriah Waterland /* get current zone name */ 4223*5c51f124SMoriah Waterland 4224*5c51f124SMoriah Waterland r = getZoneName(&(*r_gdt)->gd_zoneName); 4225*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 4226*5c51f124SMoriah Waterland (*r_gdt)->gd_zoneName = ""; 4227*5c51f124SMoriah Waterland } 4228*5c51f124SMoriah Waterland 4229*5c51f124SMoriah Waterland /* 4230*5c51f124SMoriah Waterland * get zone installation status: 4231*5c51f124SMoriah Waterland * - If the package install zone name is not set, then an installation 4232*5c51f124SMoriah Waterland * of a global zone, or of a non-global zone, is not underway. 4233*5c51f124SMoriah Waterland * - If the package install zone name is set to "global", then an 4234*5c51f124SMoriah Waterland * installation of a global zone is underway. In this case, no path 4235*5c51f124SMoriah Waterland * can be a netinstall image, diskless client, mounted miniroot, 4236*5c51f124SMoriah Waterland * non-global zone, the current running system, alternative root, 4237*5c51f124SMoriah Waterland * or alternative boot environment. 4238*5c51f124SMoriah Waterland * - If the package install zone name is set to a value other than 4239*5c51f124SMoriah Waterland * "global", then an installation of a non-global zone with that name 4240*5c51f124SMoriah Waterland * is underway. In this case, no path can be a netinstall image, 4241*5c51f124SMoriah Waterland * diskless client, mounted miniroot, global zone, the current 4242*5c51f124SMoriah Waterland * running system, alternative root, or alternative boot environment. 4243*5c51f124SMoriah Waterland */ 4244*5c51f124SMoriah Waterland 4245*5c51f124SMoriah Waterland a = getenv(ENV_VAR_PKGZONENAME); 4246*5c51f124SMoriah Waterland if ((a == NULL) || (*a == '\0')) { 4247*5c51f124SMoriah Waterland /* not installing a zone */ 4248*5c51f124SMoriah Waterland (*r_gdt)->gd_globalZoneInstall = B_FALSE; 4249*5c51f124SMoriah Waterland (*r_gdt)->gd_nonglobalZoneInstall = B_FALSE; 4250*5c51f124SMoriah Waterland } else if (strcmp(a, GLOBAL_ZONENAME) == 0) { 4251*5c51f124SMoriah Waterland /* installing a global zone */ 4252*5c51f124SMoriah Waterland (*r_gdt)->gd_globalZoneInstall = B_TRUE; 4253*5c51f124SMoriah Waterland (*r_gdt)->gd_nonglobalZoneInstall = B_FALSE; 4254*5c51f124SMoriah Waterland (*r_gdt)->gd_zoneName = a; 4255*5c51f124SMoriah Waterland } else { 4256*5c51f124SMoriah Waterland /* installing a non-global zone by that name */ 4257*5c51f124SMoriah Waterland (*r_gdt)->gd_globalZoneInstall = B_FALSE; 4258*5c51f124SMoriah Waterland (*r_gdt)->gd_nonglobalZoneInstall = B_TRUE; 4259*5c51f124SMoriah Waterland (*r_gdt)->gd_zoneName = a; 4260*5c51f124SMoriah Waterland } 4261*5c51f124SMoriah Waterland 4262*5c51f124SMoriah Waterland /* 4263*5c51f124SMoriah Waterland * get package install root. If it doesn't exist check for 4264*5c51f124SMoriah Waterland * patch install root (ROOTDIR) 4265*5c51f124SMoriah Waterland */ 4266*5c51f124SMoriah Waterland 4267*5c51f124SMoriah Waterland a = getenv(ENV_VAR_PKGROOT); 4268*5c51f124SMoriah Waterland if ((a != NULL) && (*a != '\0')) { 4269*5c51f124SMoriah Waterland (*r_gdt)->gd_installRoot = a; 4270*5c51f124SMoriah Waterland } else { 4271*5c51f124SMoriah Waterland a = getenv(ENV_VAR_PATCHROOT); 4272*5c51f124SMoriah Waterland if ((a != NULL) && (*a != '\0')) { 4273*5c51f124SMoriah Waterland (*r_gdt)->gd_installRoot = a; 4274*5c51f124SMoriah Waterland } else { 4275*5c51f124SMoriah Waterland (*r_gdt)->gd_installRoot = "/"; 4276*5c51f124SMoriah Waterland } 4277*5c51f124SMoriah Waterland } 4278*5c51f124SMoriah Waterland 4279*5c51f124SMoriah Waterland /* 4280*5c51f124SMoriah Waterland * get patch client version: always set if $ROOTDIR != / and 4281*5c51f124SMoriah Waterland * the $ROOTDIR/var/sadm/softinfo/INST_RELEASE file exists. 4282*5c51f124SMoriah Waterland */ 4283*5c51f124SMoriah Waterland 4284*5c51f124SMoriah Waterland a = getenv(ENV_VAR_PATCH_CLIENTVER); 4285*5c51f124SMoriah Waterland (*r_gdt)->gd_patchClientVersion = (a ? a : ""); 4286*5c51f124SMoriah Waterland 4287*5c51f124SMoriah Waterland /* get the global data environment variable */ 4288*5c51f124SMoriah Waterland 4289*5c51f124SMoriah Waterland a = getenv(a_envVar); 4290*5c51f124SMoriah Waterland 4291*5c51f124SMoriah Waterland /* if no data then issue warning and return success */ 4292*5c51f124SMoriah Waterland 4293*5c51f124SMoriah Waterland if ((a == NULL) || (*a_envVar == '\0')) { 4294*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_NO_GLOBAL_DATA_AVAILABLE, a_envVar); 4295*5c51f124SMoriah Waterland return (R_SUCCESS); 4296*5c51f124SMoriah Waterland } 4297*5c51f124SMoriah Waterland 4298*5c51f124SMoriah Waterland /* data present - parse into SML structure */ 4299*5c51f124SMoriah Waterland 4300*5c51f124SMoriah Waterland log_msg(LOG_MSG_DEBUG, DBG_PARSE_GLOBAL, a); 4301*5c51f124SMoriah Waterland 4302*5c51f124SMoriah Waterland r = smlConvertStringToTag(&tag, a); 4303*5c51f124SMoriah Waterland if (r != R_SUCCESS) { 4304*5c51f124SMoriah Waterland log_msg(LOG_MSG_ERR, ERR_CANNOT_PARSE_GLOBAL_DATA, a); 4305*5c51f124SMoriah Waterland return (R_FAILURE); 4306*5c51f124SMoriah Waterland } 4307*5c51f124SMoriah Waterland 4308*5c51f124SMoriah Waterland smlDbgPrintTag(tag, DBG_PARSED_ENVIRONMENT, a_envVar); 4309*5c51f124SMoriah Waterland 4310*5c51f124SMoriah Waterland /* fill in global data structure */ 4311*5c51f124SMoriah Waterland 4312*5c51f124SMoriah Waterland /* find the environment condition information structure */ 4313*5c51f124SMoriah Waterland 4314*5c51f124SMoriah Waterland ntag = smlGetTagByName(tag, 0, TAG_COND_TOPLEVEL); 4315*5c51f124SMoriah Waterland if (ntag == SML_TAG__NULL) { 4316*5c51f124SMoriah Waterland log_msg(LOG_MSG_WRN, WRN_PARSED_DATA_MISSING, 4317*5c51f124SMoriah Waterland TAG_COND_TOPLEVEL); 4318*5c51f124SMoriah Waterland return (R_FAILURE); 4319*5c51f124SMoriah Waterland } 4320*5c51f124SMoriah Waterland 4321*5c51f124SMoriah Waterland /* 4322*5c51f124SMoriah Waterland * data found - extract what we know about 4323*5c51f124SMoriah Waterland */ 4324*5c51f124SMoriah Waterland 4325*5c51f124SMoriah Waterland /* parent zone name */ 4326*5c51f124SMoriah Waterland 4327*5c51f124SMoriah Waterland a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_NAME); 4328*5c51f124SMoriah Waterland (*r_gdt)->gd_parentZoneName = a; 4329*5c51f124SMoriah Waterland 4330*5c51f124SMoriah Waterland /* parent zone type */ 4331*5c51f124SMoriah Waterland 4332*5c51f124SMoriah Waterland a = smlGetParamByTag(ntag, 0, TAG_COND_PARENT_ZONE, TAG_COND_ZONE_TYPE); 4333*5c51f124SMoriah Waterland (*r_gdt)->gd_parentZoneType = a; 4334*5c51f124SMoriah Waterland 4335*5c51f124SMoriah Waterland /* current zone name */ 4336*5c51f124SMoriah Waterland 4337*5c51f124SMoriah Waterland a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE, 4338*5c51f124SMoriah Waterland TAG_COND_ZONE_NAME); 4339*5c51f124SMoriah Waterland (*r_gdt)->gd_currentZoneName = a; 4340*5c51f124SMoriah Waterland 4341*5c51f124SMoriah Waterland /* current zone type */ 4342*5c51f124SMoriah Waterland 4343*5c51f124SMoriah Waterland a = smlGetParamByTag(ntag, 0, TAG_COND_CURRENT_ZONE, 4344*5c51f124SMoriah Waterland TAG_COND_ZONE_TYPE); 4345*5c51f124SMoriah Waterland (*r_gdt)->gd_currentZoneType = a; 4346*5c51f124SMoriah Waterland 4347*5c51f124SMoriah Waterland /* extract any inherited file systems */ 4348*5c51f124SMoriah Waterland 4349*5c51f124SMoriah Waterland for (n = 0; ; n++) { 4350*5c51f124SMoriah Waterland char **ifs; 4351*5c51f124SMoriah Waterland 4352*5c51f124SMoriah Waterland a = smlGetParamByTag(ntag, n, TAG_COND_INHERITED_FS, 4353*5c51f124SMoriah Waterland TAG_COND_FS_NAME); 4354*5c51f124SMoriah Waterland 4355*5c51f124SMoriah Waterland if (a == NULL) { 4356*5c51f124SMoriah Waterland if (n > 0) { 4357*5c51f124SMoriah Waterland /* LINTED warning: variable may be used */ 4358*5c51f124SMoriah Waterland (*r_gdt)->gd_inheritedFileSystems = ifs; 4359*5c51f124SMoriah Waterland } 4360*5c51f124SMoriah Waterland break; 4361*5c51f124SMoriah Waterland } 4362*5c51f124SMoriah Waterland 4363*5c51f124SMoriah Waterland if (n == 0) { 4364*5c51f124SMoriah Waterland ifs = (char **)calloc(1, sizeof (char **)*(n+2)); 4365*5c51f124SMoriah Waterland ifs[n] = a; 4366*5c51f124SMoriah Waterland ifs[n+1] = NULL; 4367*5c51f124SMoriah Waterland } else { 4368*5c51f124SMoriah Waterland ifs = (char **)realloc(ifs, sizeof (char **)*(n+2)); 4369*5c51f124SMoriah Waterland ifs[n] = a; 4370*5c51f124SMoriah Waterland ifs[n+1] = NULL; 4371*5c51f124SMoriah Waterland } 4372*5c51f124SMoriah Waterland } 4373*5c51f124SMoriah Waterland 4374*5c51f124SMoriah Waterland return (R_SUCCESS); 4375*5c51f124SMoriah Waterland } 4376*5c51f124SMoriah Waterland 4377*5c51f124SMoriah Waterland /* 4378*5c51f124SMoriah Waterland * Name: dumpGlobalData 4379*5c51f124SMoriah Waterland * Description: dump global data structure using echoDebug 4380*5c51f124SMoriah Waterland * Arguments: a_gdt - pointer to global data structure to dump 4381*5c51f124SMoriah Waterland * Outputs: echoDebug is called to output global data strucutre information 4382*5c51f124SMoriah Waterland * Returns: void 4383*5c51f124SMoriah Waterland */ 4384*5c51f124SMoriah Waterland 4385*5c51f124SMoriah Waterland static void 4386*5c51f124SMoriah Waterland dumpGlobalData(GLOBALDATA_T *a_gdt) 4387*5c51f124SMoriah Waterland { 4388*5c51f124SMoriah Waterland /* entry assertions */ 4389*5c51f124SMoriah Waterland 4390*5c51f124SMoriah Waterland assert(a_gdt != (GLOBALDATA_T *)NULL); 4391*5c51f124SMoriah Waterland 4392*5c51f124SMoriah Waterland /* debugging enabled, dump the global data structure */ 4393*5c51f124SMoriah Waterland 4394*5c51f124SMoriah Waterland echoDebug(DBG_DUMP_GLOBAL_ENTRY); 4395*5c51f124SMoriah Waterland echoDebug(DBG_DUMP_GLOBAL_PARENT_ZONE, 4396*5c51f124SMoriah Waterland a_gdt->gd_parentZoneName ? a_gdt->gd_parentZoneName : "", 4397*5c51f124SMoriah Waterland a_gdt->gd_parentZoneType ? a_gdt->gd_parentZoneType : ""); 4398*5c51f124SMoriah Waterland echoDebug(DBG_DUMP_GLOBAL_CURRENT_ZONE, 4399*5c51f124SMoriah Waterland a_gdt->gd_currentZoneName ? a_gdt->gd_currentZoneName : "", 4400*5c51f124SMoriah Waterland a_gdt->gd_currentZoneType ? a_gdt->gd_currentZoneType : ""); 4401*5c51f124SMoriah Waterland 4402*5c51f124SMoriah Waterland if (a_gdt->gd_inheritedFileSystems) { 4403*5c51f124SMoriah Waterland int n; 4404*5c51f124SMoriah Waterland char **ifs = a_gdt->gd_inheritedFileSystems; 4405*5c51f124SMoriah Waterland for (n = 0; ifs[n]; n++) { 4406*5c51f124SMoriah Waterland echoDebug(DBG_DUMP_GLOBAL_LINE, n, ifs[n]); 4407*5c51f124SMoriah Waterland } 4408*5c51f124SMoriah Waterland } 4409*5c51f124SMoriah Waterland } 4410*5c51f124SMoriah Waterland 4411*5c51f124SMoriah Waterland /* 4412*5c51f124SMoriah Waterland * Name: recursionCheck 4413*5c51f124SMoriah Waterland * Description: prevent recursive calling of functions 4414*5c51f124SMoriah Waterland * Arguments: r_recursion - pointer to int recursion counter 4415*5c51f124SMoriah Waterland * a_function - pointer to name of function 4416*5c51f124SMoriah Waterland * Returns: B_TRUE - function is recursively called 4417*5c51f124SMoriah Waterland * B_FALSE - function not recursively called 4418*5c51f124SMoriah Waterland */ 4419*5c51f124SMoriah Waterland 4420*5c51f124SMoriah Waterland static boolean_t 4421*5c51f124SMoriah Waterland recursionCheck(int *r_recursion, char *a_function) 4422*5c51f124SMoriah Waterland { 4423*5c51f124SMoriah Waterland /* prevent recursion */ 4424*5c51f124SMoriah Waterland 4425*5c51f124SMoriah Waterland (*r_recursion)++; 4426*5c51f124SMoriah Waterland if (*r_recursion > 1) { 4427*5c51f124SMoriah Waterland echoDebug(DBG_RECURSION, a_function, *r_recursion); 4428*5c51f124SMoriah Waterland (*r_recursion)--; 4429*5c51f124SMoriah Waterland return (B_TRUE); 4430*5c51f124SMoriah Waterland } 4431*5c51f124SMoriah Waterland 4432*5c51f124SMoriah Waterland echoDebug(DBG_NO_RECURSION, a_function); 4433*5c51f124SMoriah Waterland return (B_FALSE); 4434*5c51f124SMoriah Waterland } 4435*5c51f124SMoriah Waterland 4436*5c51f124SMoriah Waterland /* 4437*5c51f124SMoriah Waterland * Name: quit 4438*5c51f124SMoriah Waterland * Description: cleanup and exit 4439*5c51f124SMoriah Waterland * Arguments: a_retcode - the code to use to determine final exit status; 4440*5c51f124SMoriah Waterland * if this is NOT "99" and if a "ckreturnFunc" is 4441*5c51f124SMoriah Waterland * set, then that function is called with a_retcode 4442*5c51f124SMoriah Waterland * to set the final exit status. 4443*5c51f124SMoriah Waterland * Valid values are: 4444*5c51f124SMoriah Waterland * 0 - success 4445*5c51f124SMoriah Waterland * 1 - package operation failed (fatal error) 4446*5c51f124SMoriah Waterland * 2 - non-fatal error (warning) 4447*5c51f124SMoriah Waterland * 3 - user selected quit (operation interrupted) 4448*5c51f124SMoriah Waterland * 4 - admin settings prevented operation 4449*5c51f124SMoriah Waterland * 5 - interaction required and -n (non-interactive) specified 4450*5c51f124SMoriah Waterland * "10" is added to indicate "immediate reboot required" 4451*5c51f124SMoriah Waterland * "20" is be added to indicate "reboot after install required" 4452*5c51f124SMoriah Waterland * 99 - do not interpret the code - just exit "99" 4453*5c51f124SMoriah Waterland * Returns: <<this function does not return - calls exit()>> 4454*5c51f124SMoriah Waterland * NOTE: This is needed because libinst functions can call "quit(99)" 4455*5c51f124SMoriah Waterland * to force an error exit. 4456*5c51f124SMoriah Waterland */ 4457*5c51f124SMoriah Waterland 4458*5c51f124SMoriah Waterland void 4459*5c51f124SMoriah Waterland quit(int a_retcode) 4460*5c51f124SMoriah Waterland { 4461*5c51f124SMoriah Waterland /* process return code if not quit(99) */ 4462*5c51f124SMoriah Waterland 4463*5c51f124SMoriah Waterland if (a_retcode == 99) { 4464*5c51f124SMoriah Waterland exit(0x7f); /* processing error (127) */ 4465*5c51f124SMoriah Waterland } 4466*5c51f124SMoriah Waterland 4467*5c51f124SMoriah Waterland exit(R_FAILURE); 4468*5c51f124SMoriah Waterland } 4469