summaryrefslogtreecommitdiff
path: root/usr/src/lib/libzonecfg/common/libzonecfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libzonecfg/common/libzonecfg.c')
-rw-r--r--usr/src/lib/libzonecfg/common/libzonecfg.c298
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)
{