e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * CDDL HEADER START
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 * 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 * 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 * CDDL HEADER END
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
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 Jelinekstatic void s10_err(char *msg, ...) __NORETURN;
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.
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.
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/*PRINTFLIKE1*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek (void) vsnprintf(buf, sizeof (buf), msg, ap);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* This needs go to stdout so the msgs show up through zoneadm. */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /*NOTREACHED*/
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((handle = zonecfg_init_handle()) == NULL)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("internal libzonecfg.so.1 error"), 0);
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (zonecfg_get_xml_handle(xmlfile, handle) != Z_OK) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("zonecfg provided an invalid XML file"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Check to see whether the zone has any unsupported devices
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * configured.
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 s10_err(gettext("zonecfg provided an invalid XML file"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (zonecfg_getdevent(handle, &devtab) == Z_OK) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strncmp(devtab.zone_dev_match, "/dev/sound", 10) == 0 &&
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("solaris10 zones do not currently "
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "support /dev/sound"));
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 if ((start = (char *)malloc(PKGINFO_RD_LEN)) == NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek while ((p = fgets(inp, PKGINFO_RD_LEN, fp)) != NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (inp[len - 1] == '\n' && inp[len - 2] == '\\')
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if ((p = realloc(start, char_cnt + PKGINFO_RD_LEN)) == NULL) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (errno == ENOMEM || (p == NULL && char_cnt == 0)) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek * Read the SUNWcakr pkginfo file and get the PATCHLIST for the pkg.
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinekget_ku_patchlist(char *zonepath, char **patchlist)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "%s/root/var/sadm/pkg/SUNWcakr/pkginfo", zonepath)
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("error formating pkg path"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek if (strncmp(buf, PATCHLIST, sizeof (PATCHLIST) - 1) == 0) {
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek /* remove trailing newline */
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek strdup(buf + sizeof (PATCHLIST) - 1)) == NULL)
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.
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa "141445-09"};
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (zone_get_zonepath(zonename, zonepath, sizeof (zonepath)) != Z_OK)
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek s10_err(gettext("error getting zone's path"));
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek * If the zone was installed to bypass sanity checking for internal
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek * testing purposes, just return success.
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (snprintf(sanity_skip, sizeof (sanity_skip), "%s/root/.sanity_skip",
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek s10_err(gettext("error formating file path"));
1c604ca783a40b93271e2765bd14a3060c14429bGerald Jelinek if (get_ku_patchlist(zonepath, &patchlist) != 0 || patchlist == NULL)
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * Check if we're running on the i86xpv platform. If so, the zone
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa * needs a different ku patch to work properly.
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa if (sysinfo(SI_PLATFORM, platform, sizeof (platform)) != -1 &&
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek while ((p = strtok_r(pstr, " ", &lastp)) != NULL) {
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa s10_err(gettext("the zone must have patch 142910 installed "
ab5dfd5e82c7de6e8a7172573741f3c5890a82fa "when running in a paravirtualized domain"));
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.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjvstatic unsigned int
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bit_index = (unsigned int)strtoul(basenamep, &filename_endptr, 10);
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv *filename_endptr != '\0') || filename_endptr == basenamep)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv return ((unsigned int)-1);
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 * This function does not return if an error occurs.
ad601a0502a167436cd68b185fff0eb78c34777bjvstatic void
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.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (zone_get_rootpath(zonename, zoneroot, sizeof (zoneroot)) != Z_OK)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv if (snprintf(path, sizeof (path), "%s" S10_REQ_EMULATION_DIR,
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("zone's emulation versioning directory's path "
ad601a0502a167436cd68b185fff0eb78c34777bjv * Iterate over the contents of the directory and determine which
ad601a0502a167436cd68b185fff0eb78c34777bjv * features the brand should emulate for this zone.
ad601a0502a167436cd68b185fff0eb78c34777bjv while ((emul_feature_filep = readdir(req_emulation_dirp)) != NULL) {
ad601a0502a167436cd68b185fff0eb78c34777bjv * Convert the file's name to an unsigned integer. Ignore
ad601a0502a167436cd68b185fff0eb78c34777bjv * files whose names aren't unsigned integers.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv bit_index = basename_to_uint(emul_feature_filep->d_name);
ad601a0502a167436cd68b185fff0eb78c34777bjv * Determine if the brand can emulate the feature specified
ad601a0502a167436cd68b185fff0eb78c34777bjv * by bit_index.
ad601a0502a167436cd68b185fff0eb78c34777bjv * The zone requires emulation that the brand can't
ad601a0502a167436cd68b185fff0eb78c34777bjv * provide. Notify the user by displaying an error
ad601a0502a167436cd68b185fff0eb78c34777bjv * message.
ad601a0502a167436cd68b185fff0eb78c34777bjv "incompatible with the\ncurrent version of the "
ad601a0502a167436cd68b185fff0eb78c34777bjv "solaris10 brand.\nPlease update your Solaris "
ad601a0502a167436cd68b185fff0eb78c34777bjv "system to the latest release."));
ad601a0502a167436cd68b185fff0eb78c34777bjv * Set the feature's flag in the bitmap.
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 * 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 * 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 if (snprintf(path, sizeof (path), "%s" DELETE_LIST_PATH, zoneroot) >=
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("zone's delete list's path %s" DELETE_LIST_PATH
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv while (fgets(path, sizeof (path), delete_listp) != NULL) {
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 * 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 if (ferror(delete_listp) != 0 || feof(delete_listp) == 0)
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * The delete list exists but couldn't be opened. Warn the
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv * administrator.
98f4f4f656cf8a11e7013e69b0cc54f82fa9b79bjv s10_err(gettext("Unable to open %s" DELETE_LIST_PATH ": %s"),
ad601a0502a167436cd68b185fff0eb78c34777bjv * We're done scanning files. Set the zone's emulation bitmap.
ad601a0502a167436cd68b185fff0eb78c34777bjv if (zone_setattr(zoneid, S10_EMUL_BITMAP, bitmap, sizeof (bitmap)) != 0)
ad601a0502a167436cd68b185fff0eb78c34777bjv s10_err(gettext("error setting zone's emulation bitmap"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek s10_err(gettext("The installed version of Solaris 10 is "
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "not supported"));
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "usage:\t%s verify <xml file>\n"
e71ca95ca6de23d33b54cb55cefdef30bc7c969bGerald Jelinek "\t%s boot\n"),
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 /*NOTREACHED*/