diff options
Diffstat (limited to 'usr/src/lib/libzonecfg/common/libzonecfg.c')
-rw-r--r-- | usr/src/lib/libzonecfg/common/libzonecfg.c | 298 |
1 files changed, 29 insertions, 269 deletions
diff --git a/usr/src/lib/libzonecfg/common/libzonecfg.c b/usr/src/lib/libzonecfg/common/libzonecfg.c index 6aef12bbed..569d0f6ba9 100644 --- a/usr/src/lib/libzonecfg/common/libzonecfg.c +++ b/usr/src/lib/libzonecfg/common/libzonecfg.c @@ -70,7 +70,6 @@ #define DTD_ELEM_ATTR (const xmlChar *) "attr" #define DTD_ELEM_COMMENT (const xmlChar *) "comment" #define DTD_ELEM_DEVICE (const xmlChar *) "device" -#define DTD_ELEM_DELETEDDEVICE (const xmlChar *) "deleted-device" #define DTD_ELEM_FS (const xmlChar *) "filesystem" #define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption" #define DTD_ELEM_IPD (const xmlChar *) "inherited-pkg-dir" @@ -2142,9 +2141,8 @@ zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) static int zonecfg_delete_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { - xmlNodePtr newnode, cur = handle->zone_dh_cur; + xmlNodePtr cur = handle->zone_dh_cur; int match_match; - int err; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_DEVICE)) @@ -2154,19 +2152,6 @@ zonecfg_delete_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) tabptr->zone_dev_match); if (match_match) { - /* - * Since we're succesfully deleting (or modifying) - * a device entry, we need to do device node cleanup - * on the next zone bootup, so we leave behind a - * historical record for zoneadmd to consume. - */ - newnode = xmlNewTextChild(handle->zone_dh_top, NULL, - DTD_ELEM_DELETEDDEVICE, NULL); - - if ((err = newprop(newnode, DTD_ATTR_MATCH, - tabptr->zone_dev_match)) != Z_OK) - return (err); - xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); @@ -2193,43 +2178,6 @@ zonecfg_delete_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) } int -zonecfg_clear_deldevs(zone_dochandle_t handle) -{ - xmlNodePtr cur; - int err; - - if ((err = operation_prep(handle)) != Z_OK) - return (err); - - cur = handle->zone_dh_cur; - for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { - if (xmlStrcmp(cur->name, DTD_ELEM_DELETEDDEVICE) != 0) - continue; - - xmlUnlinkNode(cur); - xmlFreeNode(cur); - } - return (Z_OK); -} - -int -zonecfg_has_deldevs(zone_dochandle_t handle) -{ - xmlNodePtr cur; - int err; - - if ((err = operation_prep(handle)) != Z_OK) - return (err); - - cur = handle->zone_dh_cur; - for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { - if (xmlStrcmp(cur->name, DTD_ELEM_DELETEDDEVICE) == 0) - return (Z_OK); - } - return (Z_NO_ENTRY); -} - -int zonecfg_modify_dev( zone_dochandle_t handle, struct zone_devtab *oldtabptr, @@ -2388,54 +2336,6 @@ zonecfg_devperms_apply(zone_dochandle_t hdl, const char *inpath, uid_t owner, } /* - * This is the set of devices which must be present in every zone. Users - * can augment this list with additional device rules in their zone - * configuration, but at present cannot remove any of the this set of - * standard devices. All matching is done by /dev pathname (the "/dev" - * part is implicit. Try to keep rules which match a large number of - * devices (like the pts rule) first. - */ -static const char *standard_devs[] = { - "pts/*", - "ptmx", - "random", - "urandom", - "poll", - "pool", - "kstat", - "zero", - "null", - "crypto", - "cryptoadm", - "ticots", - "ticotsord", - "ticlts", - "lo0", - "lo1", - "lo2", - "lo3", - "sad/user", - "tty", - "logindmux", - "log", - "conslog", - "arp", - "tcp", - "tcp6", - "udp", - "udp6", - "sysevent", -#ifdef __sparc - "openprom", -#endif - "cpu/self/cpuid", - "dtrace/*", - "dtrace/provider/*", - "zfs", - NULL -}; - -/* * This function finds everything mounted under a zone's rootpath. * This returns the number of mounts under rootpath, or -1 on error. * callback is called once per mount found with the first argument @@ -2493,174 +2393,6 @@ out: return (rv); } -/* - * This routine is used to determine if a given device should appear in the - * zone represented by 'handle'. First it consults the list of "standard" - * zone devices. Then it scans the user-supplied device entries. - */ -int -zonecfg_match_dev(zone_dochandle_t handle, const char *devpath, - struct zone_devtab *out_match) -{ - int err; - boolean_t found = B_FALSE; - char match[MAXPATHLEN]; - const char **stdmatch; - xmlNodePtr cur; - - if (handle == NULL || devpath == NULL) - return (Z_INVAL); - - /* - * Check the "standard" devices which we require to be present. - */ - for (stdmatch = &standard_devs[0]; *stdmatch != NULL; stdmatch++) { - /* - * fnmatch gives us simple but powerful shell-style matching. - */ - if (fnmatch(*stdmatch, devpath, FNM_PATHNAME) == 0) { - if (!out_match) - return (Z_OK); - (void) snprintf(out_match->zone_dev_match, - sizeof (out_match->zone_dev_match), - "/dev/%s", *stdmatch); - return (Z_OK); - } - } - - /* - * We got no hits in the set of standard devices. On to the user - * supplied ones. - */ - if ((err = operation_prep(handle)) != Z_OK) { - handle->zone_dh_cur = NULL; - return (err); - } - - cur = handle->zone_dh_cur; - cur = cur->xmlChildrenNode; - if (cur == NULL) - return (Z_NO_ENTRY); - handle->zone_dh_cur = cur; - - for (; cur != NULL; cur = cur->next) { - char *m; - if (xmlStrcmp(cur->name, DTD_ELEM_DEVICE) != 0) - continue; - if ((err = fetchprop(cur, DTD_ATTR_MATCH, match, - sizeof (match))) != Z_OK) { - handle->zone_dh_cur = handle->zone_dh_top; - return (err); - } - m = match; - /* - * fnmatch gives us simple but powerful shell-style matching; - * but first, we need to strip out /dev/ from the matching rule. - */ - if (strncmp(m, "/dev/", 5) == 0) - m += 5; - - if (fnmatch(m, devpath, FNM_PATHNAME) == 0) { - found = B_TRUE; - break; - } - } - - if (!found) - return (Z_NO_ENTRY); - - if (!out_match) - return (Z_OK); - - (void) strlcpy(out_match->zone_dev_match, match, - sizeof (out_match->zone_dev_match)); - return (Z_OK); -} - -/* - * This routine answers the question: do we think <devpath> should be - * deleted during this zone's bootup? - * - * The criteria are: - * - Is there a matching rule for devpath? If yes, then NO. - * - Is this a CHR or BLK device node? If no, then NO. - * - Is there a deleted device entry which matches devpath? Then, YES - * - Else NO - */ -int -zonecfg_should_deldev(zone_dochandle_t handle, const char *devpath, - boolean_t *del) -{ - int err; - char match[MAXPATHLEN]; - xmlNodePtr cur; - struct stat st; - char fullpath[MAXPATHLEN]; - char zonepath[MAXPATHLEN]; - - if (handle == NULL || devpath == NULL || del == NULL) - return (Z_INVAL); - - *del = B_FALSE; - - /* - * If a matching rule exists for this device, then leave it alone. - */ - if (zonecfg_match_dev(handle, devpath, NULL) == Z_OK) - return (Z_OK); - - /* - * lstat it. If it's a regular file, a directory, a link or - * something else miscellaneous, we'll be cautious and not - * touch it. - */ - if ((err = zonecfg_get_zonepath(handle, zonepath, - sizeof (zonepath))) != Z_OK) - return (err); - - (void) snprintf(fullpath, sizeof (fullpath), "%s/dev/%s", zonepath, - devpath); - if (lstat(fullpath, &st) == -1 || - (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))) - return (Z_OK); - - if ((err = operation_prep(handle)) != Z_OK) { - handle->zone_dh_cur = NULL; - return (err); - } - - cur = handle->zone_dh_cur; - cur = cur->xmlChildrenNode; - if (cur == NULL) - return (Z_NO_ENTRY); - handle->zone_dh_cur = cur; - - for (; cur != NULL; cur = cur->next) { - char *m; - if (xmlStrcmp(cur->name, DTD_ELEM_DELETEDDEVICE) != 0) - continue; - if ((err = fetchprop(cur, DTD_ATTR_MATCH, match, - sizeof (match))) != Z_OK) { - handle->zone_dh_cur = handle->zone_dh_top; - return (err); - } - m = match; - /* - * fnmatch gives us simple but powerful shell-style matching; - * but first, we need to strip out /dev/ from the matching rule. - */ - if (strncmp(m, "/dev/", 5) == 0) - m += 5; - - if (fnmatch(m, devpath, FNM_PATHNAME) == 0) { - *del = B_TRUE; - break; - } - } - - return (Z_OK); -} - int zonecfg_lookup_attr(zone_dochandle_t handle, struct zone_attrtab *tabptr) { @@ -3967,6 +3699,34 @@ zone_get_rootpath(char *zone_name, char *rootpath, size_t rp_sz) return (Z_OK); } +/* + * Return the appropriate root for the active /dev. + * For normal zone, the path is $ZONEPATH/root; + * for scratch zone, the dev path is $ZONEPATH/lu. + */ +int +zone_get_devroot(char *zone_name, char *devroot, size_t rp_sz) +{ + int err; + char *suffix; + zone_state_t state; + + /* This function makes sense for non-global zones only. */ + if (strcmp(zone_name, GLOBAL_ZONENAME) == 0) + return (Z_BOGUS_ZONE_NAME); + if ((err = zone_get_zonepath(zone_name, devroot, rp_sz)) != Z_OK) + return (err); + + if (zone_get_state(zone_name, &state) == Z_OK && + state == ZONE_STATE_MOUNTED) + suffix = "/lu"; + else + suffix = "/root"; + if (strlcat(devroot, suffix, rp_sz) >= rp_sz) + return (Z_TOO_BIG); + return (Z_OK); +} + static zone_state_t kernel_state_to_user_state(zoneid_t zoneid, zone_status_t kernel_state) { |