Print this page
OS-200 need a better mechanism for storing persistent zone_did
OS-511 make zonecfg device resource extensible, like the net resource
OS-224 add more zonecfg net properties
OS-216 store all net config info on zone

*** 80,96 **** --- 80,99 ---- #define _PATH_TMPFILE "/zonecfg.XXXXXX" #define ZONE_CB_RETRY_COUNT 10 #define ZONE_EVENT_PING_SUBCLASS "ping" #define ZONE_EVENT_PING_PUBLISHER "solaris" + #define DEBUGID_FILE "/etc/zones/did.txt" + /* Hard-code the DTD element/attribute/entity names just once, here. */ #define DTD_ELEM_ATTR (const xmlChar *) "attr" #define DTD_ELEM_COMMENT (const xmlChar *) "comment" #define DTD_ELEM_DEVICE (const xmlChar *) "device" #define DTD_ELEM_FS (const xmlChar *) "filesystem" #define DTD_ELEM_FSOPTION (const xmlChar *) "fsoption" #define DTD_ELEM_NET (const xmlChar *) "network" + #define DTD_ELEM_NETATTR (const xmlChar *) "net-attr" #define DTD_ELEM_RCTL (const xmlChar *) "rctl" #define DTD_ELEM_RCTLVALUE (const xmlChar *) "rctl-value" #define DTD_ELEM_ZONE (const xmlChar *) "zone" #define DTD_ELEM_DATASET (const xmlChar *) "dataset" #define DTD_ELEM_TMPPOOL (const xmlChar *) "tmp_pool"
*** 106,128 **** --- 109,134 ---- #define DTD_ATTR_ALLOWED_ADDRESS (const xmlChar *) "allowed-address" #define DTD_ATTR_AUTOBOOT (const xmlChar *) "autoboot" #define DTD_ATTR_IPTYPE (const xmlChar *) "ip-type" #define DTD_ATTR_DEFROUTER (const xmlChar *) "defrouter" #define DTD_ATTR_DIR (const xmlChar *) "directory" + #define DTD_ATTR_GNIC (const xmlChar *) "global-nic" #define DTD_ATTR_LIMIT (const xmlChar *) "limit" #define DTD_ATTR_LIMITPRIV (const xmlChar *) "limitpriv" #define DTD_ATTR_BOOTARGS (const xmlChar *) "bootargs" #define DTD_ATTR_SCHED (const xmlChar *) "scheduling-class" + #define DTD_ATTR_MAC (const xmlChar *) "mac-addr" #define DTD_ATTR_MATCH (const xmlChar *) "match" #define DTD_ATTR_NAME (const xmlChar *) "name" #define DTD_ATTR_PHYSICAL (const xmlChar *) "physical" #define DTD_ATTR_POOL (const xmlChar *) "pool" #define DTD_ATTR_PRIV (const xmlChar *) "priv" #define DTD_ATTR_RAW (const xmlChar *) "raw" #define DTD_ATTR_SPECIAL (const xmlChar *) "special" #define DTD_ATTR_TYPE (const xmlChar *) "type" #define DTD_ATTR_VALUE (const xmlChar *) "value" + #define DTD_ATTR_VLANID (const xmlChar *) "vlan-id" #define DTD_ATTR_ZONEPATH (const xmlChar *) "zonepath" #define DTD_ATTR_NCPU_MIN (const xmlChar *) "ncpu_min" #define DTD_ATTR_NCPU_MAX (const xmlChar *) "ncpu_max" #define DTD_ATTR_IMPORTANCE (const xmlChar *) "importance" #define DTD_ATTR_PHYSCAP (const xmlChar *) "physcap"
*** 131,140 **** --- 137,147 ---- #define DTD_ATTR_UID (const xmlChar *) "uid" #define DTD_ATTR_GID (const xmlChar *) "gid" #define DTD_ATTR_MODE (const xmlChar *) "mode" #define DTD_ATTR_ACL (const xmlChar *) "acl" #define DTD_ATTR_BRAND (const xmlChar *) "brand" + #define DTD_ATTR_DID (const xmlChar *) "debugid" #define DTD_ATTR_HOSTID (const xmlChar *) "hostid" #define DTD_ATTR_USER (const xmlChar *) "user" #define DTD_ATTR_AUTHS (const xmlChar *) "auths" #define DTD_ATTR_FS_ALLOWED (const xmlChar *) "fs-allowed"
*** 2088,2104 **** * address, and default router information are stored in 'tabptr'. */ int zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur; xmlNodePtr firstmatch; int err; char address[INET6_ADDRSTRLEN]; char physical[LIFNAMSIZ]; size_t addrspec; /* nonzero if tabptr has IP addr */ size_t physspec; /* nonzero if tabptr has interface */ size_t defrouterspec; /* nonzero if tabptr has def. router */ size_t allowed_addrspec; zone_iptype_t iptype; if (tabptr == NULL) --- 2095,2115 ---- * address, and default router information are stored in 'tabptr'. */ int zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur, val; xmlNodePtr firstmatch; int err; char address[INET6_ADDRSTRLEN]; char physical[LIFNAMSIZ]; + char mac[MAXMACADDRLEN]; + char gnic[LIFNAMSIZ]; size_t addrspec; /* nonzero if tabptr has IP addr */ size_t physspec; /* nonzero if tabptr has interface */ + size_t macspec; /* nonzero if tabptr has mac addr */ + size_t gnicspec; /* nonzero if tabptr has gnic */ size_t defrouterspec; /* nonzero if tabptr has def. router */ size_t allowed_addrspec; zone_iptype_t iptype; if (tabptr == NULL)
*** 2106,2126 **** /* * Determine the fields that will be searched. There must be at least * one. * ! * zone_nwif_address, zone_nwif_physical, and zone_nwif_defrouter are * arrays, so no NULL checks are necessary. */ addrspec = strlen(tabptr->zone_nwif_address); physspec = strlen(tabptr->zone_nwif_physical); defrouterspec = strlen(tabptr->zone_nwif_defrouter); allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address); if (addrspec != 0 && allowed_addrspec != 0) return (Z_INVAL); /* can't specify both */ if (addrspec == 0 && physspec == 0 && defrouterspec == 0 && ! allowed_addrspec == 0) return (Z_INSUFFICIENT_SPEC); if ((err = operation_prep(handle)) != Z_OK) return (err); --- 2117,2140 ---- /* * Determine the fields that will be searched. There must be at least * one. * ! * zone_nwif_address, zone_nwif_physical, zone_nwif_defrouter, ! * zone_nwif_mac, zone_nwif_vlan_id and zone_nwif_gnic are * arrays, so no NULL checks are necessary. */ addrspec = strlen(tabptr->zone_nwif_address); physspec = strlen(tabptr->zone_nwif_physical); + macspec = strlen(tabptr->zone_nwif_mac); + gnicspec = strlen(tabptr->zone_nwif_gnic); defrouterspec = strlen(tabptr->zone_nwif_defrouter); allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address); if (addrspec != 0 && allowed_addrspec != 0) return (Z_INVAL); /* can't specify both */ if (addrspec == 0 && physspec == 0 && defrouterspec == 0 && ! allowed_addrspec == 0 && macspec == 0 && gnicspec == 0) return (Z_INSUFFICIENT_SPEC); if ((err = operation_prep(handle)) != Z_OK) return (err);
*** 2143,2152 **** --- 2157,2175 ---- */ if (physspec != 0 && (fetchprop(cur, DTD_ATTR_PHYSICAL, physical, sizeof (physical)) != Z_OK || strcmp(tabptr->zone_nwif_physical, physical) != 0)) continue; + if (iptype == ZS_EXCLUSIVE && macspec != 0 && + (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) != Z_OK || + strcmp(tabptr->zone_nwif_mac, mac) != 0)) + continue; + if (iptype == ZS_EXCLUSIVE && gnicspec != 0 && + (fetchprop(cur, DTD_ATTR_GNIC, gnic, + sizeof (gnic)) != Z_OK || + strcmp(tabptr->zone_nwif_gnic, gnic) != 0)) + continue; if (iptype == ZS_SHARED && addrspec != 0 && (fetchprop(cur, DTD_ATTR_ADDRESS, address, sizeof (address)) != Z_OK || !zonecfg_same_net_address(tabptr->zone_nwif_address, address)))
*** 2185,2194 **** --- 2208,2232 ---- (err = fetchprop(cur, DTD_ATTR_ADDRESS, tabptr->zone_nwif_address, sizeof (tabptr->zone_nwif_address))) != Z_OK) return (err); if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && + (err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) + return (err); + + if (iptype == ZS_EXCLUSIVE && (err = fetchprop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address, sizeof (tabptr->zone_nwif_allowed_address))) != Z_OK) return (err);
*** 2195,2211 **** if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) return (err); return (Z_OK); } static int zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); if (strlen(tabptr->zone_nwif_address) > 0 && (err = newprop(newnode, DTD_ATTR_ADDRESS, --- 2233,2276 ---- if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) return (err); + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; ! struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL); if (strlen(tabptr->zone_nwif_address) > 0 && (err = newprop(newnode, DTD_ATTR_ADDRESS,
*** 2217,2233 **** return (err); if ((err = newprop(newnode, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical)) != Z_OK) return (err); /* ! * Do not add this property when it is not set, for backwards ! * compatibility and because it is optional. */ if ((strlen(tabptr->zone_nwif_defrouter) > 0) && ((err = newprop(newnode, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter)) != Z_OK)) return (err); return (Z_OK); } int zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr) --- 2282,2325 ---- return (err); if ((err = newprop(newnode, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical)) != Z_OK) return (err); /* ! * Do not add these properties when they are not set, for backwards ! * compatibility and because they are optional. */ if ((strlen(tabptr->zone_nwif_defrouter) > 0) && ((err = newprop(newnode, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter)) != Z_OK)) return (err); + if (strlen(tabptr->zone_nwif_mac) > 0 && + (err = newprop(newnode, DTD_ATTR_MAC, + tabptr->zone_nwif_mac)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_vlan_id) > 0 && + (err = newprop(newnode, DTD_ATTR_VLANID, + tabptr->zone_nwif_vlan_id)) != Z_OK) + return (err); + if (strlen(tabptr->zone_nwif_gnic) > 0 && + (err = newprop(newnode, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic)) != Z_OK) + return (err); + + for (valptr = tabptr->zone_nwif_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + return (Z_OK); } int zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
*** 2248,2258 **** static int zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { xmlNodePtr cur = handle->zone_dh_cur; ! boolean_t addr_match, phys_match, allowed_addr_match; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_NET)) continue; --- 2340,2351 ---- static int zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { xmlNodePtr cur = handle->zone_dh_cur; ! boolean_t addr_match, phys_match, allowed_addr_match, mac_match, ! gnic_match; for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if (xmlStrcmp(cur->name, DTD_ELEM_NET)) continue;
*** 2260,2271 **** tabptr->zone_nwif_address); allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address); phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical); ! if (addr_match && allowed_addr_match && phys_match) { xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); } } --- 2353,2369 ---- tabptr->zone_nwif_address); allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS, tabptr->zone_nwif_allowed_address); phys_match = match_prop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical); + mac_match = match_prop(cur, DTD_ATTR_MAC, + tabptr->zone_nwif_mac); + gnic_match = match_prop(cur, DTD_ATTR_GNIC, + tabptr->zone_nwif_gnic); ! if ((addr_match || allowed_addr_match || mac_match || ! gnic_match) && phys_match) { xmlUnlinkNode(cur); xmlFreeNode(cur); return (Z_OK); } }
*** 2310,2319 **** --- 2408,2469 ---- return (err); return (Z_OK); } + void + zonecfg_free_res_attr_list(struct zone_res_attrtab *valtab) + { + if (valtab == NULL) + return; + zonecfg_free_res_attr_list(valtab->zone_res_attr_next); + free(valtab); + } + + int + zonecfg_add_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) + { + struct zone_res_attrtab *last, *old, *new; + + last = *headptr; + for (old = last; old != NULL; old = old->zone_res_attr_next) + last = old; /* walk to the end of the list */ + new = valtabptr; /* alloc'd by caller */ + new->zone_res_attr_next = NULL; + if (last == NULL) + *headptr = new; + else + last->zone_res_attr_next = new; + return (Z_OK); + } + + int + zonecfg_remove_res_attr(struct zone_res_attrtab **headptr, + struct zone_res_attrtab *valtabptr) + { + struct zone_res_attrtab *last, *this, *next; + + last = *headptr; + for (this = last; this != NULL; this = this->zone_res_attr_next) { + if (strcmp(this->zone_res_attr_name, + valtabptr->zone_res_attr_name) == 0 && + strcmp(this->zone_res_attr_value, + valtabptr->zone_res_attr_value) == 0) { + next = this->zone_res_attr_next; + if (this == *headptr) + *headptr = next; + else + last->zone_res_attr_next = next; + free(this); + return (Z_OK); + } else + last = this; + } + return (Z_NO_PROPERTY_ID); + } + /* * Must be a comma-separated list of alpha-numeric file system names. */ static int zonecfg_valid_fs_allowed(const char *fsallowedp)
*** 2459,2469 **** } int zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, firstmatch; int err; char match[MAXPATHLEN]; if (tabptr == NULL) return (Z_INVAL); --- 2609,2619 ---- } int zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, val, firstmatch; int err; char match[MAXPATHLEN]; if (tabptr == NULL) return (Z_INVAL);
*** 2504,2528 **** if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, sizeof (tabptr->zone_dev_match))) != Z_OK) return (err); return (Z_OK); } static int zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); if ((err = newprop(newnode, DTD_ATTR_MATCH, tabptr->zone_dev_match)) != Z_OK) return (err); return (Z_OK); } int zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr) --- 2654,2720 ---- if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match, sizeof (tabptr->zone_dev_match))) != Z_OK) return (err); + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, + valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + return (Z_OK); } static int zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode; ! struct zone_res_attrtab *valptr; int err; newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL); if ((err = newprop(newnode, DTD_ATTR_MATCH, tabptr->zone_dev_match)) != Z_OK) return (err); + for (valptr = tabptr->zone_dev_attrp; valptr != NULL; + valptr = valptr->zone_res_attr_next) { + valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR, + NULL); + err = newprop(valnode, DTD_ATTR_NAME, + valptr->zone_res_attr_name); + if (err != Z_OK) + return (err); + err = newprop(valnode, DTD_ATTR_VALUE, + valptr->zone_res_attr_value); + if (err != Z_OK) + return (err); + } + + return (Z_OK); } int zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr)
*** 4716,4726 **** } int zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur; int err; if (handle == NULL) return (Z_INVAL); --- 4908,4919 ---- } int zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr) { ! xmlNodePtr cur, val; ! struct zone_res_attrtab *valptr; int err; if (handle == NULL) return (Z_INVAL);
*** 4752,4768 **** --- 4945,5002 ---- sizeof (tabptr->zone_nwif_physical))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + if ((err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac, + sizeof (tabptr->zone_nwif_mac))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id, + sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + + if ((err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic, + sizeof (tabptr->zone_nwif_gnic))) != Z_OK) { + handle->zone_dh_cur = handle->zone_dh_top; + return (err); + } + if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER, tabptr->zone_nwif_defrouter, sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + tabptr->zone_nwif_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if (fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK) + break; + if (fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } int
*** 4778,4788 **** } int zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur; int err; if (handle == NULL) return (Z_INVAL); --- 5012,5022 ---- } int zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr) { ! xmlNodePtr cur, val; int err; if (handle == NULL) return (Z_INVAL);
*** 4801,4810 **** --- 5035,5069 ---- sizeof (tabptr->zone_dev_match))) != Z_OK) { handle->zone_dh_cur = handle->zone_dh_top; return (err); } + tabptr->zone_dev_attrp = NULL; + for (val = cur->xmlChildrenNode; val != NULL; val = val->next) { + struct zone_res_attrtab *valptr; + + valptr = (struct zone_res_attrtab *)malloc( + sizeof (struct zone_res_attrtab)); + if (valptr == NULL) + return (Z_NOMEM); + + valptr->zone_res_attr_name[0] = + valptr->zone_res_attr_value[0] = '\0'; + if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr) + != Z_OK) { + free(valptr); + break; + } + + if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name, + sizeof (valptr->zone_res_attr_name)) != Z_OK)) + break; + if ((fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value, + sizeof (valptr->zone_res_attr_value)) != Z_OK)) + break; + } + handle->zone_dh_cur = cur->next; return (Z_OK); } int
*** 5528,5537 **** --- 5787,5954 ---- zonecfg_fini_handle(handle); return (err); } + /* + * Atomically get a new zone_did value. The currently allocated value + * is stored in /etc/zones/did.txt. Lock the file, read the current value, + * increment, save the new value and unlock the file. Return the new value + * or -1 if there was an error. The ID namespace is large enough that we + * don't worry about recycling an ID when a zone is deleted. + */ + static zoneid_t + new_zone_did() + { + int fd; + int len; + int val; + struct flock lck; + char buf[80]; + + if ((fd = open(DEBUGID_FILE, O_RDWR | O_CREAT, + S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { + perror("new_zone_did open failed"); + return (-1); + } + + /* Initialize the lock. */ + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = 0; + + /* Wait until we acquire an exclusive lock on the file. */ + lck.l_type = F_WRLCK; + if (fcntl(fd, F_SETLKW, &lck) == -1) { + perror("new_zone_did lock failed"); + (void) close(fd); + return (-1); + } + + /* Get currently allocated value */ + len = read(fd, buf, sizeof (buf)); + if (len == -1) { + perror("new_zone_did read failed"); + val = -1; + } else { + if (lseek(fd, 0L, SEEK_SET) == -1) { + perror("new_zone_did seek failed"); + val = -1; + } else { + if (len == 0) { + /* Just created the file, initialize at 1 */ + val = 1; + } else { + val = atoi(buf); + val++; + } + + (void) snprintf(buf, sizeof (buf), "%d\n", val); + len = strlen(buf); + + /* Save newly allocated value */ + if (write(fd, buf, len) == -1) { + perror("new_zone_did write failed"); + val = -1; + } + } + } + + /* Release the file lock. */ + lck.l_type = F_UNLCK; + if (fcntl(fd, F_SETLK, &lck) == -1) { + perror("new_zone_did unlock failed"); + val = -1; + } + + if (close(fd) != 0) + perror("new_zone_did close failed"); + + return (val); + } + + /* + * Called by zoneadmd to get the zone's debug ID. + * If the zone doesn't already have an ID, a new one is generated and + * persistently saved onto the zone. Normally either zoneadm or zonecfg + * will assign a new ID for the zone, so zoneadmd should never have to + * generate one, but we also handle that here just to be paranoid. + */ + zoneid_t + zone_get_did(char *zone_name) + { + int res; + zoneid_t new_did; + zone_dochandle_t handle; + char did_str[80]; + + if ((handle = zonecfg_init_handle()) == NULL) + return (getpid()); + + if (zonecfg_get_handle((char *)zone_name, handle) != Z_OK) + return (getpid()); + + res = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + + /* If the zone already has an assigned debug ID, return it. */ + if (res == Z_OK && did_str[0] != '\0') { + zonecfg_fini_handle(handle); + return (atoi(did_str)); + } + + /* + * The zone doesn't have an assigned debug ID yet, generate one and + * save it as part of the zone definition. + */ + if ((new_did = new_zone_did()) == -1) { + /* + * We should really never hit this block of code. + * Generating a new ID failed for some reason. Use the current + * pid as a temporary ID so that the zone can continue to boot + * but we don't persistently save this temporary ID on the zone. + */ + zonecfg_fini_handle(handle); + return (getpid()); + } + + /* Now persistently save this new ID onto the zone. */ + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); + (void) zonecfg_save(handle); + + zonecfg_fini_handle(handle); + return (new_did); + } + + zoneid_t + zonecfg_get_did(zone_dochandle_t handle) + { + char did_str[80]; + int err; + zoneid_t did; + + err = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str)); + if (err == Z_OK && did_str[0] != '\0') + did = atoi(did_str); + else + did = -1; + + return (did); + } + + void + zonecfg_set_did(zone_dochandle_t handle) + { + zoneid_t new_did; + char did_str[80]; + + if ((new_did = new_zone_did()) == -1) + return; + (void) snprintf(did_str, sizeof (did_str), "%d", new_did); + (void) setrootattr(handle, DTD_ATTR_DID, did_str); + } + /* * 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. */