e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * CDDL HEADER START
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The contents of this file are subject to the terms of the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Common Development and Distribution License (the "License").
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * You may not use this file except in compliance with the License.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * or http://www.opensolaris.org/os/licensing.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * See the License for the specific language governing permissions
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * and limitations under the License.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * When distributing Covered Code, include this CDDL HEADER in each
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * If applicable, add the following below this CDDL HEADER, with the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * fields enclosed by brackets "[]" replaced with your own identifying
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * information: Portions Copyright [yyyy] [name of copyright owner]
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * CDDL HEADER END
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * s10_support is a small cli utility used to perform some brand-specific
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * tasks when verifying a zone. This utility is not intended to be called
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * by users - it is intended to be invoked by the zones utilities.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <ctype.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <errno.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <fcntl.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <libgen.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <limits.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <s10_brand.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <stdarg.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <stdio.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <stdlib.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <string.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <strings.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <stropts.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <sys/stat.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <sys/types.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <sys/utsname.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <sys/varargs.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <unistd.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <libintl.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <locale.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <dirent.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <sys/systeminfo.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#include <libzonecfg.h>
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic void s10_err(char *msg, ...) __NORETURN;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic void usage(void) __NORETURN;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * XXX This is a temporary flag for the initial release to enable the
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * use of features which are not yet tested or fully implemented.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic boolean_t override = B_FALSE;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic char *bname = NULL;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv/*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * DELETE_LIST_PATH represents the path to a solaris10-branded zone's "delete
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * list", which is generated by patchrm when it needs to remove files after
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * the zone reboots. See set_zone_emul_bitmap() below for additional details.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv#define DELETE_LIST_PATH "/var/sadm/patch/.delete_list"
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#define PKGINFO_RD_LEN 128
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#define PATCHLIST "PATCHLIST="
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#if !defined(TEXT_DOMAIN) /* should be defined by cc -D */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek#endif
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*PRINTFLIKE1*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic void
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_err(char *msg, ...)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char buf[1024];
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek va_list ap;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek va_start(ap, msg);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) vsnprintf(buf, sizeof (buf), msg, ap);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek va_end(ap);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* This needs go to stdout so the msgs show up through zoneadm. */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) printf("Error: %s\n", buf);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek exit(1);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic int
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_verify(char *xmlfile)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek zone_dochandle_t handle;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek struct zone_devtab devtab;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((handle = zonecfg_init_handle()) == NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("internal libzonecfg.so.1 error"), 0);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (zonecfg_get_xml_handle(xmlfile, handle) != Z_OK) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek zonecfg_fini_handle(handle);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Check to see whether the zone has any unsupported devices
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * configured.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The audio framework has changed in Solaris Next as compared to
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * S10. Data indicates the less than 1/10 of 1 percent of zones
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * are using /dev/sound. Given the low usage vs. the effort to
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * provide emulation, /dev/sound is currently disallowed. We can
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * revisit this if there is enough demand.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (zonecfg_setdevent(handle) != Z_OK) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek zonecfg_fini_handle(handle);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (zonecfg_getdevent(handle, &devtab) == Z_OK) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strncmp(devtab.zone_dev_match, "/dev/sound", 10) == 0 &&
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek !override) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek zonecfg_fini_handle(handle);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("solaris10 zones do not currently "
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "support /dev/sound"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) zonecfg_enddevent(handle);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek zonecfg_fini_handle(handle);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (0);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Read an entry from a pkginfo file. Some of these lines can
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * either be arbitrarily long or be continued by a backslash at the end of
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * the line. This function coalesces lines that are longer than the read
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * buffer, and lines that are continued, into one buffer which is returned.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * The caller must free this memory. NULL is returned when we hit EOF or
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * if we run out of memory (errno is set to ENOMEM).
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic char *
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekread_pkg_data(FILE *fp)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *start;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *inp;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *p;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek int char_cnt = 0;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek errno = 0;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((start = (char *)malloc(PKGINFO_RD_LEN)) == NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek errno = ENOMEM;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (NULL);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek inp = start;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek while ((p = fgets(inp, PKGINFO_RD_LEN, fp)) != NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek int len;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek len = strlen(inp);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (inp[len - 1] == '\n' &&
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (len == 1 || inp[len - 2] != '\\')) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char_cnt = len;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek break;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (inp[len - 1] == '\n' && inp[len - 2] == '\\')
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char_cnt += len - 2;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek else
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char_cnt += PKGINFO_RD_LEN - 1;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((p = realloc(start, char_cnt + PKGINFO_RD_LEN)) == NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek errno = ENOMEM;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek break;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek start = p;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek inp = start + char_cnt;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (errno == ENOMEM || (p == NULL && char_cnt == 0)) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek free(start);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek start = NULL;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (start);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Read the SUNWcakr pkginfo file and get the PATCHLIST for the pkg.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic int
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinekget_ku_patchlist(char *zonepath, char **patchlist)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char pkginfo[MAXPATHLEN];
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek FILE *fp;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *buf;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek int err = 0;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (snprintf(pkginfo, sizeof (pkginfo),
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "%s/root/var/sadm/pkg/SUNWcakr/pkginfo", zonepath)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek >= sizeof (pkginfo))
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("error formating pkg path"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((fp = fopen(pkginfo, "r")) == NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (errno);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek while ((buf = read_pkg_data(fp)) != NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strncmp(buf, PATCHLIST, sizeof (PATCHLIST) - 1) == 0) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek int len;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* remove trailing newline */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek len = strlen(buf);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek buf[len - 1] = '\0';
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((*patchlist =
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek strdup(buf + sizeof (PATCHLIST) - 1)) == NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek err = ENOMEM;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek free(buf);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek break;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek free(buf);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) fclose(fp);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (err);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Verify that we have the minimum KU needed.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Note that KU patches are accumulative so future KUs will still deliver
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * 141444 or 141445.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic boolean_t
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekhave_valid_ku(char *zonename)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *p;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *lastp;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *pstr;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *patchlist = NULL;
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek char zonepath[MAXPATHLEN];
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek char sanity_skip[MAXPATHLEN];
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek struct stat64 buf;
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa boolean_t is_xpv = B_FALSE;
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa char platform[80];
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa char *xpv_vers = "142910";
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek char *vers_table[] = {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "141444-09",
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa "141445-09"};
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK)
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek s10_err(gettext("error getting zone's path"));
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek /*
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek * If the zone was installed to bypass sanity checking for internal
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek * testing purposes, just return success.
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek */
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (snprintf(sanity_skip, sizeof (sanity_skip), "%s/root/.sanity_skip",
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek zonepath) >= sizeof (sanity_skip))
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek s10_err(gettext("error formating file path"));
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (stat64(sanity_skip, &buf) == 0)
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek return (B_TRUE);
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (get_ku_patchlist(zonepath, &patchlist) != 0 || patchlist == NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (B_FALSE);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa /*
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * Check if we're running on the i86xpv platform. If so, the zone
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * needs a different ku patch to work properly.
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa */
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) != -1 &&
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa strcmp(platform, "i86xpv") == 0)
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa is_xpv = B_TRUE;
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek pstr = patchlist;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek while ((p = strtok_r(pstr, " ", &lastp)) != NULL) {
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (is_xpv) {
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (strncmp(p, xpv_vers, 6) == 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (B_TRUE);
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa } else {
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (strcmp(p, vers_table[0]) == 0 ||
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa strcmp(p, vers_table[1]) == 0)
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa return (B_TRUE);
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek pstr = NULL;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (is_xpv)
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa s10_err(gettext("the zone must have patch 142910 installed "
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa "when running in a paravirtualized domain"));
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (B_FALSE);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv/*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Convert the specified file basename into an unsigned integer. If the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * basename contains characters that cannot be converted into digits or the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * basename isn't NULL or newline-terminated, then this function returns
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * the unsigned equivalent of -1.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjvstatic unsigned int
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjvbasename_to_uint(const char *basenamep)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv{
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv char *filename_endptr;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv unsigned int bit_index;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv errno = 0;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bit_index = (unsigned int)strtoul(basenamep, &filename_endptr, 10);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (errno != 0 || (*filename_endptr != '\n' &&
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv *filename_endptr != '\0') || filename_endptr == basenamep)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv return ((unsigned int)-1);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv return (bit_index);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv}
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek/*
ad601a0502a167436cd68b185fff0eb78c34777bjv * Determine which features/behaviors should be emulated and construct a bitmap
ad601a0502a167436cd68b185fff0eb78c34777bjv * representing the results. Associate the bitmap with the zone so that
ad601a0502a167436cd68b185fff0eb78c34777bjv * the brand's emulation library will be able to retrieve the bitmap and
ad601a0502a167436cd68b185fff0eb78c34777bjv * determine how the zone's process' behaviors should be emulated.
ad601a0502a167436cd68b185fff0eb78c34777bjv *
ad601a0502a167436cd68b185fff0eb78c34777bjv * This function does not return if an error occurs.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
ad601a0502a167436cd68b185fff0eb78c34777bjvstatic void
ad601a0502a167436cd68b185fff0eb78c34777bjvset_zone_emul_bitmap(char *zonename)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv char zoneroot[MAXPATHLEN];
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv char path[MAXPATHLEN];
ad601a0502a167436cd68b185fff0eb78c34777bjv DIR *req_emulation_dirp;
ad601a0502a167436cd68b185fff0eb78c34777bjv struct dirent *emul_feature_filep;
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_emul_bitmap_t bitmap;
ad601a0502a167436cd68b185fff0eb78c34777bjv unsigned int bit_index;
ad601a0502a167436cd68b185fff0eb78c34777bjv zoneid_t zoneid;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv FILE *delete_listp;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * If the Solaris 10 directory containing emulation feature files
ad601a0502a167436cd68b185fff0eb78c34777bjv * doesn't exist in the zone, then assume that it only needs the
ad601a0502a167436cd68b185fff0eb78c34777bjv * most basic emulation and, therefore, doesn't need a bitmap.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (zone_get_rootpath(zonename, zoneroot, sizeof (zoneroot)) != Z_OK)
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_err(gettext("error getting zone's path"));
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (snprintf(path, sizeof (path), "%s" S10_REQ_EMULATION_DIR,
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv zoneroot) >= sizeof (path))
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("zone's emulation versioning directory's path "
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv "%s" S10_REQ_EMULATION_DIR " is too long"), zoneroot);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if ((req_emulation_dirp = opendir(path)) == NULL)
ad601a0502a167436cd68b185fff0eb78c34777bjv return;
ad601a0502a167436cd68b185fff0eb78c34777bjv bzero(bitmap, sizeof (bitmap));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * Iterate over the contents of the directory and determine which
ad601a0502a167436cd68b185fff0eb78c34777bjv * features the brand should emulate for this zone.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
ad601a0502a167436cd68b185fff0eb78c34777bjv while ((emul_feature_filep = readdir(req_emulation_dirp)) != NULL) {
ad601a0502a167436cd68b185fff0eb78c34777bjv if (strcmp(emul_feature_filep->d_name, ".") == 0 ||
ad601a0502a167436cd68b185fff0eb78c34777bjv strcmp(emul_feature_filep->d_name, "..") == 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek continue;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * Convert the file's name to an unsigned integer. Ignore
ad601a0502a167436cd68b185fff0eb78c34777bjv * files whose names aren't unsigned integers.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bit_index = basename_to_uint(emul_feature_filep->d_name);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (bit_index == (unsigned int)-1)
ad601a0502a167436cd68b185fff0eb78c34777bjv continue;
ad601a0502a167436cd68b185fff0eb78c34777bjv
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * Determine if the brand can emulate the feature specified
ad601a0502a167436cd68b185fff0eb78c34777bjv * by bit_index.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
ad601a0502a167436cd68b185fff0eb78c34777bjv if (bit_index >= S10_NUM_EMUL_FEATURES) {
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * The zone requires emulation that the brand can't
ad601a0502a167436cd68b185fff0eb78c34777bjv * provide. Notify the user by displaying an error
ad601a0502a167436cd68b185fff0eb78c34777bjv * message.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_err(gettext("The zone's version of Solaris 10 is "
ad601a0502a167436cd68b185fff0eb78c34777bjv "incompatible with the\ncurrent version of the "
ad601a0502a167436cd68b185fff0eb78c34777bjv "solaris10 brand.\nPlease update your Solaris "
ad601a0502a167436cd68b185fff0eb78c34777bjv "system to the latest release."));
ad601a0502a167436cd68b185fff0eb78c34777bjv } else {
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * Set the feature's flag in the bitmap.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
ad601a0502a167436cd68b185fff0eb78c34777bjv bitmap[(bit_index >> 3)] |= (1 << (bit_index & 0x7));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek }
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv (void) closedir(req_emulation_dirp);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv /*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * The zone's administrator might have removed a patch that delivered
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * an emulation feature file the last time the zone ran. If so, then
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * the zone's patch utilities won't delete the file until the zone's
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * svc:/system/patch-finish:delete SMF service runs. This is
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * problematic because the zone will be using system libraries whose
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * ioctl structures and syscall invocations will differ from those
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * expected by the emulation library. For example, if an administrator
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * removes a patch that affects the formats of MNTFS ioctls, then the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * administrator's zone will use a version of libc.so.1 that issues
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * MNTFS ioctls that use older structure versions than the zone's
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * emulation library will expect.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv *
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Fortunately, the patchrm utility creates a hidden file,
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * /var/sadm/patch/.delete_list, which lists all files that
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * svc:/system/patch-finish:delete will delete. We'll determine whether
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * this file exists in the zone and disable the emulation bits
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * associated with the emulation feature files that will be deleted.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv *
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * NOTE: The patch tools lofs mount backup copies of critical system
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * libraries, such as /lib/libc.so.1, over their replacements whenever
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * administrators add or remove DAP patches. Consequently, there isn't
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * a window of vulnerability between patch addition or removal and
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * zone reboot. The aforementioned problem only occurs after a zone
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * reboots.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (snprintf(path, sizeof (path), "%s" DELETE_LIST_PATH, zoneroot) >=
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv sizeof (path))
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("zone's delete list's path %s" DELETE_LIST_PATH
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv " is too long"), zoneroot);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if ((delete_listp = fopen(path, "r")) != NULL) {
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv while (fgets(path, sizeof (path), delete_listp) != NULL) {
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv char *const basenamep = path +
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv sizeof (S10_REQ_EMULATION_DIR);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv /*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Make sure that the file is in the directory
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * containing emulation feature files. If it is,
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * then basenamep should refer to the basename of
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * the file.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (strncmp(path, S10_REQ_EMULATION_DIR,
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv sizeof (S10_REQ_EMULATION_DIR) - 1) != 0)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv continue;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (*(basenamep - 1) != '/')
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv continue;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv /*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Convert the file's basename into a bit index in
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * the emulation bitmap. If the file's basename isn't
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * integral, then skip the file. Otherwise, clear the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * corresponding bit in the bitmap.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bit_index = basename_to_uint(basenamep);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (bit_index == (unsigned int)-1)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv continue;
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (bit_index < S10_NUM_EMUL_FEATURES)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bitmap[(bit_index >> 3)] &=
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv ~(1 << (bit_index & 0x7));
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv }
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (ferror(delete_listp) != 0 || feof(delete_listp) == 0)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("The program encountered an error while"
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv " reading from %s" DELETE_LIST_PATH "."), zoneroot);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv (void) fclose(delete_listp);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv } else if (errno != ENOENT) {
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv /*
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * The delete list exists but couldn't be opened. Warn the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * administrator.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv */
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("Unable to open %s" DELETE_LIST_PATH ": %s"),
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv zoneroot, strerror(errno));
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv }
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ad601a0502a167436cd68b185fff0eb78c34777bjv /*
ad601a0502a167436cd68b185fff0eb78c34777bjv * We're done scanning files. Set the zone's emulation bitmap.
ad601a0502a167436cd68b185fff0eb78c34777bjv */
ad601a0502a167436cd68b185fff0eb78c34777bjv if ((zoneid = getzoneidbyname(zonename)) < 0)
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_err(gettext("unable to get zoneid"));
ad601a0502a167436cd68b185fff0eb78c34777bjv if (zone_setattr(zoneid, S10_EMUL_BITMAP, bitmap, sizeof (bitmap)) != 0)
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_err(gettext("error setting zone's emulation bitmap"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic int
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelineks10_boot(char *zonename)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (!have_valid_ku(zonename))
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("The installed version of Solaris 10 is "
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "not supported"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
ad601a0502a167436cd68b185fff0eb78c34777bjv set_zone_emul_bitmap(zonename);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (0);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekstatic void
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekusage()
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) fprintf(stderr, gettext(
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "usage:\t%s verify <xml file>\n"
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "\t%s boot\n"),
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek bname, bname);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek exit(1);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekint
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinekmain(int argc, char *argv[])
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek{
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) setlocale(LC_ALL, "");
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) textdomain(TEXT_DOMAIN);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek bname = basename(argv[0]);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (argc != 3)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek usage();
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * XXX This is a temporary env variable for the initial release to
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * enable the use of features which are not yet tested or fully
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * implemented.
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (getenv("S10BRAND_TEST") != NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek override = B_TRUE;
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strcmp(argv[1], "verify") == 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (s10_verify(argv[2]));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strcmp(argv[1], "boot") == 0)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek return (s10_boot(argv[2]));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek usage();
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek}