1*e71ca95cSGerald Jelinek /* 2*e71ca95cSGerald Jelinek * CDDL HEADER START 3*e71ca95cSGerald Jelinek * 4*e71ca95cSGerald Jelinek * The contents of this file are subject to the terms of the 5*e71ca95cSGerald Jelinek * Common Development and Distribution License (the "License"). 6*e71ca95cSGerald Jelinek * You may not use this file except in compliance with the License. 7*e71ca95cSGerald Jelinek * 8*e71ca95cSGerald Jelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*e71ca95cSGerald Jelinek * or http://www.opensolaris.org/os/licensing. 10*e71ca95cSGerald Jelinek * See the License for the specific language governing permissions 11*e71ca95cSGerald Jelinek * and limitations under the License. 12*e71ca95cSGerald Jelinek * 13*e71ca95cSGerald Jelinek * When distributing Covered Code, include this CDDL HEADER in each 14*e71ca95cSGerald Jelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*e71ca95cSGerald Jelinek * If applicable, add the following below this CDDL HEADER, with the 16*e71ca95cSGerald Jelinek * fields enclosed by brackets "[]" replaced with your own identifying 17*e71ca95cSGerald Jelinek * information: Portions Copyright [yyyy] [name of copyright owner] 18*e71ca95cSGerald Jelinek * 19*e71ca95cSGerald Jelinek * CDDL HEADER END 20*e71ca95cSGerald Jelinek */ 21*e71ca95cSGerald Jelinek /* 22*e71ca95cSGerald Jelinek * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23*e71ca95cSGerald Jelinek * Use is subject to license terms. 24*e71ca95cSGerald Jelinek */ 25*e71ca95cSGerald Jelinek 26*e71ca95cSGerald Jelinek /* 27*e71ca95cSGerald Jelinek * s10_support is a small cli utility used to perform some brand-specific 28*e71ca95cSGerald Jelinek * tasks when verifying a zone. This utility is not intended to be called 29*e71ca95cSGerald Jelinek * by users - it is intended to be invoked by the zones utilities. 30*e71ca95cSGerald Jelinek */ 31*e71ca95cSGerald Jelinek 32*e71ca95cSGerald Jelinek #include <ctype.h> 33*e71ca95cSGerald Jelinek #include <errno.h> 34*e71ca95cSGerald Jelinek #include <fcntl.h> 35*e71ca95cSGerald Jelinek #include <libgen.h> 36*e71ca95cSGerald Jelinek #include <limits.h> 37*e71ca95cSGerald Jelinek #include <s10_brand.h> 38*e71ca95cSGerald Jelinek #include <stdarg.h> 39*e71ca95cSGerald Jelinek #include <stdio.h> 40*e71ca95cSGerald Jelinek #include <stdlib.h> 41*e71ca95cSGerald Jelinek #include <string.h> 42*e71ca95cSGerald Jelinek #include <strings.h> 43*e71ca95cSGerald Jelinek #include <stropts.h> 44*e71ca95cSGerald Jelinek #include <sys/stat.h> 45*e71ca95cSGerald Jelinek #include <sys/types.h> 46*e71ca95cSGerald Jelinek #include <sys/utsname.h> 47*e71ca95cSGerald Jelinek #include <sys/varargs.h> 48*e71ca95cSGerald Jelinek #include <unistd.h> 49*e71ca95cSGerald Jelinek #include <libintl.h> 50*e71ca95cSGerald Jelinek #include <locale.h> 51*e71ca95cSGerald Jelinek #include <dirent.h> 52*e71ca95cSGerald Jelinek #include <sys/systeminfo.h> 53*e71ca95cSGerald Jelinek 54*e71ca95cSGerald Jelinek #include <libzonecfg.h> 55*e71ca95cSGerald Jelinek 56*e71ca95cSGerald Jelinek static void s10_err(char *msg, ...) __NORETURN; 57*e71ca95cSGerald Jelinek static void usage(void) __NORETURN; 58*e71ca95cSGerald Jelinek 59*e71ca95cSGerald Jelinek /* 60*e71ca95cSGerald Jelinek * XXX This is a temporary flag for the initial release to enable the 61*e71ca95cSGerald Jelinek * use of features which are not yet tested or fully implemented. 62*e71ca95cSGerald Jelinek */ 63*e71ca95cSGerald Jelinek static boolean_t override = B_FALSE; 64*e71ca95cSGerald Jelinek 65*e71ca95cSGerald Jelinek static char *bname = NULL; 66*e71ca95cSGerald Jelinek 67*e71ca95cSGerald Jelinek #define PKGINFO_RD_LEN 128 68*e71ca95cSGerald Jelinek #define PATCHLIST "PATCHLIST=" 69*e71ca95cSGerald Jelinek 70*e71ca95cSGerald Jelinek #if !defined(TEXT_DOMAIN) /* should be defined by cc -D */ 71*e71ca95cSGerald Jelinek #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */ 72*e71ca95cSGerald Jelinek #endif 73*e71ca95cSGerald Jelinek 74*e71ca95cSGerald Jelinek /*PRINTFLIKE1*/ 75*e71ca95cSGerald Jelinek static void 76*e71ca95cSGerald Jelinek s10_err(char *msg, ...) 77*e71ca95cSGerald Jelinek { 78*e71ca95cSGerald Jelinek char buf[1024]; 79*e71ca95cSGerald Jelinek va_list ap; 80*e71ca95cSGerald Jelinek 81*e71ca95cSGerald Jelinek va_start(ap, msg); 82*e71ca95cSGerald Jelinek (void) vsnprintf(buf, sizeof (buf), msg, ap); 83*e71ca95cSGerald Jelinek va_end(ap); 84*e71ca95cSGerald Jelinek 85*e71ca95cSGerald Jelinek /* This needs go to stdout so the msgs show up through zoneadm. */ 86*e71ca95cSGerald Jelinek (void) printf("Error: %s\n", buf); 87*e71ca95cSGerald Jelinek 88*e71ca95cSGerald Jelinek exit(1); 89*e71ca95cSGerald Jelinek /*NOTREACHED*/ 90*e71ca95cSGerald Jelinek } 91*e71ca95cSGerald Jelinek 92*e71ca95cSGerald Jelinek static int 93*e71ca95cSGerald Jelinek s10_verify(char *xmlfile) 94*e71ca95cSGerald Jelinek { 95*e71ca95cSGerald Jelinek zone_dochandle_t handle; 96*e71ca95cSGerald Jelinek struct zone_fstab fstab; 97*e71ca95cSGerald Jelinek struct zone_devtab devtab; 98*e71ca95cSGerald Jelinek zone_iptype_t iptype; 99*e71ca95cSGerald Jelinek struct zone_dstab dstab; 100*e71ca95cSGerald Jelinek 101*e71ca95cSGerald Jelinek if ((handle = zonecfg_init_handle()) == NULL) 102*e71ca95cSGerald Jelinek s10_err(gettext("internal libzonecfg.so.1 error"), 0); 103*e71ca95cSGerald Jelinek 104*e71ca95cSGerald Jelinek if (zonecfg_get_xml_handle(xmlfile, handle) != Z_OK) { 105*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 106*e71ca95cSGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file")); 107*e71ca95cSGerald Jelinek } 108*e71ca95cSGerald Jelinek 109*e71ca95cSGerald Jelinek /* 110*e71ca95cSGerald Jelinek * Check to see whether the zone has any inherit-pkg-dirs 111*e71ca95cSGerald Jelinek * configured. 112*e71ca95cSGerald Jelinek */ 113*e71ca95cSGerald Jelinek if (zonecfg_setipdent(handle) != Z_OK) { 114*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 115*e71ca95cSGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file")); 116*e71ca95cSGerald Jelinek } 117*e71ca95cSGerald Jelinek if (zonecfg_getipdent(handle, &fstab) == Z_OK) { 118*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 119*e71ca95cSGerald Jelinek s10_err(gettext("solaris10 zones do not support " 120*e71ca95cSGerald Jelinek "inherit-pkg-dirs")); 121*e71ca95cSGerald Jelinek } 122*e71ca95cSGerald Jelinek (void) zonecfg_endipdent(handle); 123*e71ca95cSGerald Jelinek 124*e71ca95cSGerald Jelinek /* 125*e71ca95cSGerald Jelinek * Check to see whether the zone has any unsupported devices 126*e71ca95cSGerald Jelinek * configured. 127*e71ca95cSGerald Jelinek * 128*e71ca95cSGerald Jelinek * The audio framework has changed in Solaris Next as compared to 129*e71ca95cSGerald Jelinek * S10. Data indicates the less than 1/10 of 1 percent of zones 130*e71ca95cSGerald Jelinek * are using /dev/sound. Given the low usage vs. the effort to 131*e71ca95cSGerald Jelinek * provide emulation, /dev/sound is currently disallowed. We can 132*e71ca95cSGerald Jelinek * revisit this if there is enough demand. 133*e71ca95cSGerald Jelinek */ 134*e71ca95cSGerald Jelinek if (zonecfg_setdevent(handle) != Z_OK) { 135*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 136*e71ca95cSGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file")); 137*e71ca95cSGerald Jelinek } 138*e71ca95cSGerald Jelinek if (zonecfg_getdevent(handle, &devtab) == Z_OK) { 139*e71ca95cSGerald Jelinek if (strncmp(devtab.zone_dev_match, "/dev/sound", 10) == 0 && 140*e71ca95cSGerald Jelinek !override) { 141*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 142*e71ca95cSGerald Jelinek s10_err(gettext("solaris10 zones do not currently " 143*e71ca95cSGerald Jelinek "support /dev/sound")); 144*e71ca95cSGerald Jelinek } 145*e71ca95cSGerald Jelinek } 146*e71ca95cSGerald Jelinek (void) zonecfg_enddevent(handle); 147*e71ca95cSGerald Jelinek 148*e71ca95cSGerald Jelinek /* 149*e71ca95cSGerald Jelinek * Check to see whether the zone has any experimental features 150*e71ca95cSGerald Jelinek * configured. 151*e71ca95cSGerald Jelinek */ 152*e71ca95cSGerald Jelinek if (zonecfg_get_iptype(handle, &iptype) == Z_OK && 153*e71ca95cSGerald Jelinek iptype == ZS_EXCLUSIVE && !override) { 154*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 155*e71ca95cSGerald Jelinek s10_err(gettext("solaris10 zones do not currently support " 156*e71ca95cSGerald Jelinek "exclusive ip-type stacks")); 157*e71ca95cSGerald Jelinek } 158*e71ca95cSGerald Jelinek 159*e71ca95cSGerald Jelinek if (zonecfg_setdsent(handle) != Z_OK) { 160*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 161*e71ca95cSGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file")); 162*e71ca95cSGerald Jelinek } 163*e71ca95cSGerald Jelinek if (zonecfg_getdsent(handle, &dstab) == Z_OK && !override) { 164*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 165*e71ca95cSGerald Jelinek s10_err(gettext("solaris10 zones do not currently support " 166*e71ca95cSGerald Jelinek "delegated datasets")); 167*e71ca95cSGerald Jelinek } 168*e71ca95cSGerald Jelinek (void) zonecfg_enddsent(handle); 169*e71ca95cSGerald Jelinek 170*e71ca95cSGerald Jelinek zonecfg_fini_handle(handle); 171*e71ca95cSGerald Jelinek return (0); 172*e71ca95cSGerald Jelinek } 173*e71ca95cSGerald Jelinek 174*e71ca95cSGerald Jelinek /* 175*e71ca95cSGerald Jelinek * Read an entry from a pkginfo file. Some of these lines can 176*e71ca95cSGerald Jelinek * either be arbitrarily long or be continued by a backslash at the end of 177*e71ca95cSGerald Jelinek * the line. This function coalesces lines that are longer than the read 178*e71ca95cSGerald Jelinek * buffer, and lines that are continued, into one buffer which is returned. 179*e71ca95cSGerald Jelinek * The caller must free this memory. NULL is returned when we hit EOF or 180*e71ca95cSGerald Jelinek * if we run out of memory (errno is set to ENOMEM). 181*e71ca95cSGerald Jelinek */ 182*e71ca95cSGerald Jelinek static char * 183*e71ca95cSGerald Jelinek read_pkg_data(FILE *fp) 184*e71ca95cSGerald Jelinek { 185*e71ca95cSGerald Jelinek char *start; 186*e71ca95cSGerald Jelinek char *inp; 187*e71ca95cSGerald Jelinek char *p; 188*e71ca95cSGerald Jelinek int char_cnt = 0; 189*e71ca95cSGerald Jelinek 190*e71ca95cSGerald Jelinek errno = 0; 191*e71ca95cSGerald Jelinek if ((start = (char *)malloc(PKGINFO_RD_LEN)) == NULL) { 192*e71ca95cSGerald Jelinek errno = ENOMEM; 193*e71ca95cSGerald Jelinek return (NULL); 194*e71ca95cSGerald Jelinek } 195*e71ca95cSGerald Jelinek 196*e71ca95cSGerald Jelinek inp = start; 197*e71ca95cSGerald Jelinek while ((p = fgets(inp, PKGINFO_RD_LEN, fp)) != NULL) { 198*e71ca95cSGerald Jelinek int len; 199*e71ca95cSGerald Jelinek 200*e71ca95cSGerald Jelinek len = strlen(inp); 201*e71ca95cSGerald Jelinek if (inp[len - 1] == '\n' && 202*e71ca95cSGerald Jelinek (len == 1 || inp[len - 2] != '\\')) { 203*e71ca95cSGerald Jelinek char_cnt = len; 204*e71ca95cSGerald Jelinek break; 205*e71ca95cSGerald Jelinek } 206*e71ca95cSGerald Jelinek 207*e71ca95cSGerald Jelinek if (inp[len - 1] == '\n' && inp[len - 2] == '\\') 208*e71ca95cSGerald Jelinek char_cnt += len - 2; 209*e71ca95cSGerald Jelinek else 210*e71ca95cSGerald Jelinek char_cnt += PKGINFO_RD_LEN - 1; 211*e71ca95cSGerald Jelinek 212*e71ca95cSGerald Jelinek if ((p = realloc(start, char_cnt + PKGINFO_RD_LEN)) == NULL) { 213*e71ca95cSGerald Jelinek errno = ENOMEM; 214*e71ca95cSGerald Jelinek break; 215*e71ca95cSGerald Jelinek } 216*e71ca95cSGerald Jelinek 217*e71ca95cSGerald Jelinek start = p; 218*e71ca95cSGerald Jelinek inp = start + char_cnt; 219*e71ca95cSGerald Jelinek } 220*e71ca95cSGerald Jelinek 221*e71ca95cSGerald Jelinek if (errno == ENOMEM || (p == NULL && char_cnt == 0)) { 222*e71ca95cSGerald Jelinek free(start); 223*e71ca95cSGerald Jelinek start = NULL; 224*e71ca95cSGerald Jelinek } 225*e71ca95cSGerald Jelinek 226*e71ca95cSGerald Jelinek return (start); 227*e71ca95cSGerald Jelinek } 228*e71ca95cSGerald Jelinek 229*e71ca95cSGerald Jelinek /* 230*e71ca95cSGerald Jelinek * Read the SUNWcakr pkginfo file and get the PATCHLIST for the pkg. 231*e71ca95cSGerald Jelinek */ 232*e71ca95cSGerald Jelinek static int 233*e71ca95cSGerald Jelinek get_ku_patchlist(char *zonename, char **patchlist) 234*e71ca95cSGerald Jelinek { 235*e71ca95cSGerald Jelinek char zonepath[MAXPATHLEN]; 236*e71ca95cSGerald Jelinek char pkginfo[MAXPATHLEN]; 237*e71ca95cSGerald Jelinek FILE *fp; 238*e71ca95cSGerald Jelinek char *buf; 239*e71ca95cSGerald Jelinek int err = 0; 240*e71ca95cSGerald Jelinek 241*e71ca95cSGerald Jelinek if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK) 242*e71ca95cSGerald Jelinek s10_err(gettext("error getting zone's path")); 243*e71ca95cSGerald Jelinek 244*e71ca95cSGerald Jelinek if (snprintf(pkginfo, sizeof (pkginfo), 245*e71ca95cSGerald Jelinek "%s/root/var/sadm/pkg/SUNWcakr/pkginfo", zonepath) 246*e71ca95cSGerald Jelinek >= sizeof (pkginfo)) 247*e71ca95cSGerald Jelinek s10_err(gettext("error formating pkg path")); 248*e71ca95cSGerald Jelinek 249*e71ca95cSGerald Jelinek if ((fp = fopen(pkginfo, "r")) == NULL) 250*e71ca95cSGerald Jelinek return (errno); 251*e71ca95cSGerald Jelinek 252*e71ca95cSGerald Jelinek while ((buf = read_pkg_data(fp)) != NULL) { 253*e71ca95cSGerald Jelinek if (strncmp(buf, PATCHLIST, sizeof (PATCHLIST) - 1) == 0) { 254*e71ca95cSGerald Jelinek int len; 255*e71ca95cSGerald Jelinek 256*e71ca95cSGerald Jelinek /* remove trailing newline */ 257*e71ca95cSGerald Jelinek len = strlen(buf); 258*e71ca95cSGerald Jelinek buf[len - 1] = '\0'; 259*e71ca95cSGerald Jelinek 260*e71ca95cSGerald Jelinek if ((*patchlist = 261*e71ca95cSGerald Jelinek strdup(buf + sizeof (PATCHLIST) - 1)) == NULL) 262*e71ca95cSGerald Jelinek err = ENOMEM; 263*e71ca95cSGerald Jelinek 264*e71ca95cSGerald Jelinek free(buf); 265*e71ca95cSGerald Jelinek break; 266*e71ca95cSGerald Jelinek } 267*e71ca95cSGerald Jelinek 268*e71ca95cSGerald Jelinek free(buf); 269*e71ca95cSGerald Jelinek } 270*e71ca95cSGerald Jelinek (void) fclose(fp); 271*e71ca95cSGerald Jelinek 272*e71ca95cSGerald Jelinek return (err); 273*e71ca95cSGerald Jelinek } 274*e71ca95cSGerald Jelinek 275*e71ca95cSGerald Jelinek /* 276*e71ca95cSGerald Jelinek * Verify that we have the minimum KU needed. 277*e71ca95cSGerald Jelinek * Note that KU patches are accumulative so future KUs will still deliver 278*e71ca95cSGerald Jelinek * 141444 or 141445. 279*e71ca95cSGerald Jelinek */ 280*e71ca95cSGerald Jelinek static boolean_t 281*e71ca95cSGerald Jelinek have_valid_ku(char *zonename) 282*e71ca95cSGerald Jelinek { 283*e71ca95cSGerald Jelinek char *p; 284*e71ca95cSGerald Jelinek char *lastp; 285*e71ca95cSGerald Jelinek char *pstr; 286*e71ca95cSGerald Jelinek char *patchlist = NULL; 287*e71ca95cSGerald Jelinek int i; 288*e71ca95cSGerald Jelinek char *vers_table[] = { 289*e71ca95cSGerald Jelinek "141444-09", 290*e71ca95cSGerald Jelinek "141445-09", 291*e71ca95cSGerald Jelinek NULL}; 292*e71ca95cSGerald Jelinek 293*e71ca95cSGerald Jelinek if (get_ku_patchlist(zonename, &patchlist) != 0 || patchlist == NULL) 294*e71ca95cSGerald Jelinek return (B_FALSE); 295*e71ca95cSGerald Jelinek 296*e71ca95cSGerald Jelinek pstr = patchlist; 297*e71ca95cSGerald Jelinek while ((p = strtok_r(pstr, " ", &lastp)) != NULL) { 298*e71ca95cSGerald Jelinek for (i = 0; vers_table[i] != NULL; i++) 299*e71ca95cSGerald Jelinek if (strcmp(p, vers_table[i]) == 0) 300*e71ca95cSGerald Jelinek return (B_TRUE); 301*e71ca95cSGerald Jelinek 302*e71ca95cSGerald Jelinek pstr = NULL; 303*e71ca95cSGerald Jelinek } 304*e71ca95cSGerald Jelinek 305*e71ca95cSGerald Jelinek return (B_FALSE); 306*e71ca95cSGerald Jelinek } 307*e71ca95cSGerald Jelinek 308*e71ca95cSGerald Jelinek /* 309*e71ca95cSGerald Jelinek * Get the emulation version from the /usr/lib/brand/solaris10/version file 310*e71ca95cSGerald Jelinek * in either the global zone or the non-global zone. 311*e71ca95cSGerald Jelinek */ 312*e71ca95cSGerald Jelinek static int 313*e71ca95cSGerald Jelinek get_emul_version_number(char *verspath) 314*e71ca95cSGerald Jelinek { 315*e71ca95cSGerald Jelinek int vers = 0; 316*e71ca95cSGerald Jelinek FILE *fp; 317*e71ca95cSGerald Jelinek char buf[LINE_MAX]; 318*e71ca95cSGerald Jelinek 319*e71ca95cSGerald Jelinek /* If the file doesn't exist, assume version 0 */ 320*e71ca95cSGerald Jelinek if ((fp = fopen(verspath, "r")) == NULL) 321*e71ca95cSGerald Jelinek return (vers); 322*e71ca95cSGerald Jelinek 323*e71ca95cSGerald Jelinek while (fgets(buf, sizeof (buf), fp) != NULL) { 324*e71ca95cSGerald Jelinek if (buf[0] == '#') 325*e71ca95cSGerald Jelinek continue; 326*e71ca95cSGerald Jelinek 327*e71ca95cSGerald Jelinek errno = 0; 328*e71ca95cSGerald Jelinek vers = strtol(buf, (char **)NULL, 10); 329*e71ca95cSGerald Jelinek if (errno != 0) { 330*e71ca95cSGerald Jelinek (void) fclose(fp); 331*e71ca95cSGerald Jelinek s10_err(gettext("error reading minimum version")); 332*e71ca95cSGerald Jelinek } 333*e71ca95cSGerald Jelinek } 334*e71ca95cSGerald Jelinek 335*e71ca95cSGerald Jelinek (void) fclose(fp); 336*e71ca95cSGerald Jelinek 337*e71ca95cSGerald Jelinek return (vers); 338*e71ca95cSGerald Jelinek } 339*e71ca95cSGerald Jelinek 340*e71ca95cSGerald Jelinek /* 341*e71ca95cSGerald Jelinek * Get the current emulation version that is implemented. 342*e71ca95cSGerald Jelinek */ 343*e71ca95cSGerald Jelinek static int 344*e71ca95cSGerald Jelinek get_current_emul_version() 345*e71ca95cSGerald Jelinek { 346*e71ca95cSGerald Jelinek return (get_emul_version_number("/usr/lib/brand/solaris10/version")); 347*e71ca95cSGerald Jelinek } 348*e71ca95cSGerald Jelinek 349*e71ca95cSGerald Jelinek /* 350*e71ca95cSGerald Jelinek * Get the emulation version that the S10 image requires. This 351*e71ca95cSGerald Jelinek * reads the optional /usr/lib/brand/solaris10/version file that might 352*e71ca95cSGerald Jelinek * exist on Solaris 10. That file specifies the minimal solaris10 brand 353*e71ca95cSGerald Jelinek * emulation version that the specific release of S10 requires. If no 354*e71ca95cSGerald Jelinek * minimal version is specified, the initial emulation remains compatible. 355*e71ca95cSGerald Jelinek * 356*e71ca95cSGerald Jelinek * If a new KU patch is created which needs different handling by the 357*e71ca95cSGerald Jelinek * emulation, then the S10 /usr/lib/brand/solaris10/version file should be 358*e71ca95cSGerald Jelinek * updated to specify a new version. 359*e71ca95cSGerald Jelinek */ 360*e71ca95cSGerald Jelinek static int 361*e71ca95cSGerald Jelinek get_image_emul_rqd_version(char *zonename) 362*e71ca95cSGerald Jelinek { 363*e71ca95cSGerald Jelinek char zonepath[MAXPATHLEN]; 364*e71ca95cSGerald Jelinek char verspath[MAXPATHLEN]; 365*e71ca95cSGerald Jelinek 366*e71ca95cSGerald Jelinek if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK) 367*e71ca95cSGerald Jelinek s10_err(gettext("error getting zone's path")); 368*e71ca95cSGerald Jelinek 369*e71ca95cSGerald Jelinek if (snprintf(verspath, sizeof (verspath), 370*e71ca95cSGerald Jelinek "%s/root/usr/lib/brand/solaris10/version", 371*e71ca95cSGerald Jelinek zonepath) >= sizeof (verspath)) 372*e71ca95cSGerald Jelinek s10_err(gettext("error formating version path")); 373*e71ca95cSGerald Jelinek 374*e71ca95cSGerald Jelinek return (get_emul_version_number(verspath)); 375*e71ca95cSGerald Jelinek } 376*e71ca95cSGerald Jelinek 377*e71ca95cSGerald Jelinek static void 378*e71ca95cSGerald Jelinek fail_xvm() 379*e71ca95cSGerald Jelinek { 380*e71ca95cSGerald Jelinek char buf[80]; 381*e71ca95cSGerald Jelinek 382*e71ca95cSGerald Jelinek if (sysinfo(SI_PLATFORM, buf, sizeof (buf)) != -1 && 383*e71ca95cSGerald Jelinek strcmp(buf, "i86xpv") == 0 && !override) 384*e71ca95cSGerald Jelinek s10_err(gettext("running the solaris10 brand " 385*e71ca95cSGerald Jelinek "in a paravirtualized\ndomain is currently not supported")); 386*e71ca95cSGerald Jelinek } 387*e71ca95cSGerald Jelinek 388*e71ca95cSGerald Jelinek static int 389*e71ca95cSGerald Jelinek s10_boot(char *zonename) 390*e71ca95cSGerald Jelinek { 391*e71ca95cSGerald Jelinek zoneid_t zoneid; 392*e71ca95cSGerald Jelinek int emul_vers; 393*e71ca95cSGerald Jelinek int rqd_emul_vers; 394*e71ca95cSGerald Jelinek 395*e71ca95cSGerald Jelinek if (!have_valid_ku(zonename)) 396*e71ca95cSGerald Jelinek s10_err(gettext("The installed version of Solaris 10 is " 397*e71ca95cSGerald Jelinek "not supported")); 398*e71ca95cSGerald Jelinek 399*e71ca95cSGerald Jelinek emul_vers = get_current_emul_version(); 400*e71ca95cSGerald Jelinek rqd_emul_vers = get_image_emul_rqd_version(zonename); 401*e71ca95cSGerald Jelinek 402*e71ca95cSGerald Jelinek if (rqd_emul_vers > emul_vers) 403*e71ca95cSGerald Jelinek s10_err(gettext("The zone's version of Solaris 10 is " 404*e71ca95cSGerald Jelinek "incompatible with the current version of the solaris10 " 405*e71ca95cSGerald Jelinek "brand.")); 406*e71ca95cSGerald Jelinek 407*e71ca95cSGerald Jelinek if ((zoneid = getzoneidbyname(zonename)) < 0) 408*e71ca95cSGerald Jelinek s10_err(gettext("unable to get zoneid")); 409*e71ca95cSGerald Jelinek 410*e71ca95cSGerald Jelinek if (zone_setattr(zoneid, S10_EMUL_VERSION_NUM, &rqd_emul_vers, 411*e71ca95cSGerald Jelinek sizeof (int)) == -1) 412*e71ca95cSGerald Jelinek s10_err(gettext("error setting zone's emulation version " 413*e71ca95cSGerald Jelinek "property")); 414*e71ca95cSGerald Jelinek 415*e71ca95cSGerald Jelinek fail_xvm(); 416*e71ca95cSGerald Jelinek 417*e71ca95cSGerald Jelinek return (0); 418*e71ca95cSGerald Jelinek } 419*e71ca95cSGerald Jelinek 420*e71ca95cSGerald Jelinek static void 421*e71ca95cSGerald Jelinek usage() 422*e71ca95cSGerald Jelinek { 423*e71ca95cSGerald Jelinek (void) fprintf(stderr, gettext( 424*e71ca95cSGerald Jelinek "usage:\t%s verify <xml file>\n" 425*e71ca95cSGerald Jelinek "\t%s boot\n"), 426*e71ca95cSGerald Jelinek bname, bname); 427*e71ca95cSGerald Jelinek exit(1); 428*e71ca95cSGerald Jelinek } 429*e71ca95cSGerald Jelinek 430*e71ca95cSGerald Jelinek int 431*e71ca95cSGerald Jelinek main(int argc, char *argv[]) 432*e71ca95cSGerald Jelinek { 433*e71ca95cSGerald Jelinek (void) setlocale(LC_ALL, ""); 434*e71ca95cSGerald Jelinek (void) textdomain(TEXT_DOMAIN); 435*e71ca95cSGerald Jelinek 436*e71ca95cSGerald Jelinek bname = basename(argv[0]); 437*e71ca95cSGerald Jelinek 438*e71ca95cSGerald Jelinek if (argc != 3) 439*e71ca95cSGerald Jelinek usage(); 440*e71ca95cSGerald Jelinek 441*e71ca95cSGerald Jelinek /* 442*e71ca95cSGerald Jelinek * XXX This is a temporary env variable for the initial release to 443*e71ca95cSGerald Jelinek * enable the use of features which are not yet tested or fully 444*e71ca95cSGerald Jelinek * implemented. 445*e71ca95cSGerald Jelinek */ 446*e71ca95cSGerald Jelinek if (getenv("S10BRAND_TEST") != NULL) 447*e71ca95cSGerald Jelinek override = B_TRUE; 448*e71ca95cSGerald Jelinek 449*e71ca95cSGerald Jelinek if (strcmp(argv[1], "verify") == 0) 450*e71ca95cSGerald Jelinek return (s10_verify(argv[2])); 451*e71ca95cSGerald Jelinek 452*e71ca95cSGerald Jelinek if (strcmp(argv[1], "boot") == 0) 453*e71ca95cSGerald Jelinek return (s10_boot(argv[2])); 454*e71ca95cSGerald Jelinek 455*e71ca95cSGerald Jelinek usage(); 456*e71ca95cSGerald Jelinek /*NOTREACHED*/ 457*e71ca95cSGerald Jelinek } 458