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

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzonecfg/common/libzonecfg.c
          +++ new/usr/src/lib/libzonecfg/common/libzonecfg.c
↓ open down ↓ 74 lines elided ↑ open up ↑
  75   75  #include <libbrand.h>
  76   76  
  77   77  #include <libzonecfg.h>
  78   78  #include "zonecfg_impl.h"
  79   79  
  80   80  #define _PATH_TMPFILE   "/zonecfg.XXXXXX"
  81   81  #define ZONE_CB_RETRY_COUNT             10
  82   82  #define ZONE_EVENT_PING_SUBCLASS        "ping"
  83   83  #define ZONE_EVENT_PING_PUBLISHER       "solaris"
  84   84  
       85 +#define DEBUGID_FILE    "/etc/zones/did.txt"
       86 +
  85   87  /* Hard-code the DTD element/attribute/entity names just once, here. */
  86   88  #define DTD_ELEM_ATTR           (const xmlChar *) "attr"
  87   89  #define DTD_ELEM_COMMENT        (const xmlChar *) "comment"
  88   90  #define DTD_ELEM_DEVICE         (const xmlChar *) "device"
  89   91  #define DTD_ELEM_FS             (const xmlChar *) "filesystem"
  90   92  #define DTD_ELEM_FSOPTION       (const xmlChar *) "fsoption"
  91   93  #define DTD_ELEM_NET            (const xmlChar *) "network"
       94 +#define DTD_ELEM_NETATTR        (const xmlChar *) "net-attr"
  92   95  #define DTD_ELEM_RCTL           (const xmlChar *) "rctl"
  93   96  #define DTD_ELEM_RCTLVALUE      (const xmlChar *) "rctl-value"
  94   97  #define DTD_ELEM_ZONE           (const xmlChar *) "zone"
  95   98  #define DTD_ELEM_DATASET        (const xmlChar *) "dataset"
  96   99  #define DTD_ELEM_TMPPOOL        (const xmlChar *) "tmp_pool"
  97  100  #define DTD_ELEM_PSET           (const xmlChar *) "pset"
  98  101  #define DTD_ELEM_MCAP           (const xmlChar *) "mcap"
  99  102  #define DTD_ELEM_PACKAGE        (const xmlChar *) "package"
 100  103  #define DTD_ELEM_OBSOLETES      (const xmlChar *) "obsoletes"
 101  104  #define DTD_ELEM_DEV_PERM       (const xmlChar *) "dev-perm"
 102  105  #define DTD_ELEM_ADMIN          (const xmlChar *) "admin"
 103  106  
 104  107  #define DTD_ATTR_ACTION         (const xmlChar *) "action"
 105  108  #define DTD_ATTR_ADDRESS        (const xmlChar *) "address"
 106  109  #define DTD_ATTR_ALLOWED_ADDRESS        (const xmlChar *) "allowed-address"
 107  110  #define DTD_ATTR_AUTOBOOT       (const xmlChar *) "autoboot"
 108  111  #define DTD_ATTR_IPTYPE         (const xmlChar *) "ip-type"
 109  112  #define DTD_ATTR_DEFROUTER      (const xmlChar *) "defrouter"
 110  113  #define DTD_ATTR_DIR            (const xmlChar *) "directory"
      114 +#define DTD_ATTR_GNIC           (const xmlChar *) "global-nic"
 111  115  #define DTD_ATTR_LIMIT          (const xmlChar *) "limit"
 112  116  #define DTD_ATTR_LIMITPRIV      (const xmlChar *) "limitpriv"
 113  117  #define DTD_ATTR_BOOTARGS       (const xmlChar *) "bootargs"
 114  118  #define DTD_ATTR_SCHED          (const xmlChar *) "scheduling-class"
      119 +#define DTD_ATTR_MAC            (const xmlChar *) "mac-addr"
 115  120  #define DTD_ATTR_MATCH          (const xmlChar *) "match"
 116  121  #define DTD_ATTR_NAME           (const xmlChar *) "name"
 117  122  #define DTD_ATTR_PHYSICAL       (const xmlChar *) "physical"
 118  123  #define DTD_ATTR_POOL           (const xmlChar *) "pool"
 119  124  #define DTD_ATTR_PRIV           (const xmlChar *) "priv"
 120  125  #define DTD_ATTR_RAW            (const xmlChar *) "raw"
 121  126  #define DTD_ATTR_SPECIAL        (const xmlChar *) "special"
 122  127  #define DTD_ATTR_TYPE           (const xmlChar *) "type"
 123  128  #define DTD_ATTR_VALUE          (const xmlChar *) "value"
      129 +#define DTD_ATTR_VLANID         (const xmlChar *) "vlan-id"
 124  130  #define DTD_ATTR_ZONEPATH       (const xmlChar *) "zonepath"
 125  131  #define DTD_ATTR_NCPU_MIN       (const xmlChar *) "ncpu_min"
 126  132  #define DTD_ATTR_NCPU_MAX       (const xmlChar *) "ncpu_max"
 127  133  #define DTD_ATTR_IMPORTANCE     (const xmlChar *) "importance"
 128  134  #define DTD_ATTR_PHYSCAP        (const xmlChar *) "physcap"
 129  135  #define DTD_ATTR_VERSION        (const xmlChar *) "version"
 130  136  #define DTD_ATTR_ID             (const xmlChar *) "id"
 131  137  #define DTD_ATTR_UID            (const xmlChar *) "uid"
 132  138  #define DTD_ATTR_GID            (const xmlChar *) "gid"
 133  139  #define DTD_ATTR_MODE           (const xmlChar *) "mode"
 134  140  #define DTD_ATTR_ACL            (const xmlChar *) "acl"
 135  141  #define DTD_ATTR_BRAND          (const xmlChar *) "brand"
      142 +#define DTD_ATTR_DID            (const xmlChar *) "debugid"
 136  143  #define DTD_ATTR_HOSTID         (const xmlChar *) "hostid"
 137  144  #define DTD_ATTR_USER           (const xmlChar *) "user"
 138  145  #define DTD_ATTR_AUTHS          (const xmlChar *) "auths"
 139  146  #define DTD_ATTR_FS_ALLOWED     (const xmlChar *) "fs-allowed"
 140  147  
 141  148  #define DTD_ENTITY_BOOLEAN      "boolean"
 142  149  #define DTD_ENTITY_DEVPATH      "devpath"
 143  150  #define DTD_ENTITY_DRIVER       "driver"
 144  151  #define DTD_ENTITY_DRVMIN       "drv_min"
 145  152  #define DTD_ENTITY_FALSE        "false"
↓ open down ↓ 1937 lines elided ↑ open up ↑
2083 2090   *
2084 2091   * Errors might also be returned if the entry that exactly matches the
2085 2092   * query lacks critical network resource information.
2086 2093   *
2087 2094   * If there is a single match, then the matching entry's physical interface, IP
2088 2095   * address, and default router information are stored in 'tabptr'.
2089 2096   */
2090 2097  int
2091 2098  zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
2092 2099  {
2093      -        xmlNodePtr cur;
     2100 +        xmlNodePtr cur, val;
2094 2101          xmlNodePtr firstmatch;
2095 2102          int err;
2096 2103          char address[INET6_ADDRSTRLEN];
2097 2104          char physical[LIFNAMSIZ];
     2105 +        char mac[MAXMACADDRLEN];
     2106 +        char gnic[LIFNAMSIZ];
2098 2107          size_t addrspec;                /* nonzero if tabptr has IP addr */
2099 2108          size_t physspec;                /* nonzero if tabptr has interface */
     2109 +        size_t macspec;                 /* nonzero if tabptr has mac addr */
     2110 +        size_t gnicspec;                /* nonzero if tabptr has gnic */
2100 2111          size_t defrouterspec;           /* nonzero if tabptr has def. router */
2101 2112          size_t allowed_addrspec;
2102 2113          zone_iptype_t iptype;
2103 2114  
2104 2115          if (tabptr == NULL)
2105 2116                  return (Z_INVAL);
2106 2117  
2107 2118          /*
2108 2119           * Determine the fields that will be searched.  There must be at least
2109 2120           * one.
2110 2121           *
2111      -         * zone_nwif_address, zone_nwif_physical, and zone_nwif_defrouter are
     2122 +         * zone_nwif_address, zone_nwif_physical, zone_nwif_defrouter,
     2123 +         * zone_nwif_mac, zone_nwif_vlan_id and zone_nwif_gnic  are
2112 2124           * arrays, so no NULL checks are necessary.
2113 2125           */
2114 2126          addrspec = strlen(tabptr->zone_nwif_address);
2115 2127          physspec = strlen(tabptr->zone_nwif_physical);
     2128 +        macspec = strlen(tabptr->zone_nwif_mac);
     2129 +        gnicspec = strlen(tabptr->zone_nwif_gnic);
2116 2130          defrouterspec = strlen(tabptr->zone_nwif_defrouter);
2117 2131          allowed_addrspec = strlen(tabptr->zone_nwif_allowed_address);
2118 2132          if (addrspec != 0 && allowed_addrspec != 0)
2119 2133                  return (Z_INVAL); /* can't specify both */
2120 2134          if (addrspec == 0 && physspec == 0 && defrouterspec == 0 &&
2121      -            allowed_addrspec == 0)
     2135 +            allowed_addrspec == 0 && macspec == 0 && gnicspec == 0)
2122 2136                  return (Z_INSUFFICIENT_SPEC);
2123 2137  
2124 2138          if ((err = operation_prep(handle)) != Z_OK)
2125 2139                  return (err);
2126 2140  
2127 2141          if ((err = zonecfg_get_iptype(handle, &iptype)) != Z_OK)
2128 2142                  return (err);
2129 2143          /*
2130 2144           * Iterate over the configuration's elements and look for net elements
2131 2145           * that match the query.
↓ open down ↓ 6 lines elided ↑ open up ↑
2138 2152                          continue;
2139 2153  
2140 2154                  /*
2141 2155                   * If any relevant fields don't match the query, then skip
2142 2156                   * the current net element.
2143 2157                   */
2144 2158                  if (physspec != 0 && (fetchprop(cur, DTD_ATTR_PHYSICAL,
2145 2159                      physical, sizeof (physical)) != Z_OK ||
2146 2160                      strcmp(tabptr->zone_nwif_physical, physical) != 0))
2147 2161                          continue;
     2162 +                if (iptype == ZS_EXCLUSIVE && macspec != 0 &&
     2163 +                    (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) != Z_OK ||
     2164 +                    strcmp(tabptr->zone_nwif_mac, mac) != 0))
     2165 +                        continue;
     2166 +                if (iptype == ZS_EXCLUSIVE && gnicspec != 0 &&
     2167 +                    (fetchprop(cur, DTD_ATTR_GNIC, gnic,
     2168 +                    sizeof (gnic)) != Z_OK ||
     2169 +                    strcmp(tabptr->zone_nwif_gnic, gnic) != 0))
     2170 +                        continue;
2148 2171                  if (iptype == ZS_SHARED && addrspec != 0 &&
2149 2172                      (fetchprop(cur, DTD_ATTR_ADDRESS, address,
2150 2173                      sizeof (address)) != Z_OK ||
2151 2174                      !zonecfg_same_net_address(tabptr->zone_nwif_address,
2152 2175                      address)))
2153 2176                          continue;
2154 2177                  if (iptype == ZS_EXCLUSIVE && allowed_addrspec != 0 &&
2155 2178                      (fetchprop(cur, DTD_ATTR_ALLOWED_ADDRESS, address,
2156 2179                      sizeof (address)) != Z_OK ||
2157 2180                      !zonecfg_same_net_address(tabptr->zone_nwif_allowed_address,
↓ open down ↓ 22 lines elided ↑ open up ↑
2180 2203          if ((err = fetchprop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical,
2181 2204              sizeof (tabptr->zone_nwif_physical))) != Z_OK)
2182 2205                  return (err);
2183 2206  
2184 2207          if (iptype == ZS_SHARED &&
2185 2208              (err = fetchprop(cur, DTD_ATTR_ADDRESS, tabptr->zone_nwif_address,
2186 2209              sizeof (tabptr->zone_nwif_address))) != Z_OK)
2187 2210                  return (err);
2188 2211  
2189 2212          if (iptype == ZS_EXCLUSIVE &&
     2213 +            (err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac,
     2214 +            sizeof (tabptr->zone_nwif_mac))) != Z_OK)
     2215 +                return (err);
     2216 +
     2217 +        if (iptype == ZS_EXCLUSIVE &&
     2218 +            (err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id,
     2219 +            sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK)
     2220 +                return (err);
     2221 +
     2222 +        if (iptype == ZS_EXCLUSIVE &&
     2223 +            (err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic,
     2224 +            sizeof (tabptr->zone_nwif_gnic))) != Z_OK)
     2225 +                return (err);
     2226 +
     2227 +        if (iptype == ZS_EXCLUSIVE &&
2190 2228              (err = fetchprop(cur, DTD_ATTR_ALLOWED_ADDRESS,
2191 2229              tabptr->zone_nwif_allowed_address,
2192 2230              sizeof (tabptr->zone_nwif_allowed_address))) != Z_OK)
2193 2231                  return (err);
2194 2232  
2195 2233          if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER,
2196 2234              tabptr->zone_nwif_defrouter,
2197 2235              sizeof (tabptr->zone_nwif_defrouter))) != Z_OK)
2198 2236                  return (err);
2199 2237  
     2238 +        tabptr->zone_nwif_attrp = NULL;
     2239 +        for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
     2240 +                struct zone_res_attrtab *valptr;
     2241 +
     2242 +                valptr = (struct zone_res_attrtab *)malloc(
     2243 +                    sizeof (struct zone_res_attrtab));
     2244 +                if (valptr == NULL)
     2245 +                        return (Z_NOMEM);
     2246 +
     2247 +                valptr->zone_res_attr_name[0] =
     2248 +                    valptr->zone_res_attr_value[0] = '\0';
     2249 +                if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr)
     2250 +                    != Z_OK) {
     2251 +                        free(valptr);
     2252 +                        break;
     2253 +                }
     2254 +
     2255 +                if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name,
     2256 +                    sizeof (valptr->zone_res_attr_name)) != Z_OK))
     2257 +                        break;
     2258 +                if ((fetchprop(val, DTD_ATTR_VALUE,
     2259 +                    valptr->zone_res_attr_value,
     2260 +                    sizeof (valptr->zone_res_attr_value)) != Z_OK))
     2261 +                        break;
     2262 +        }
     2263 +
2200 2264          return (Z_OK);
2201 2265  }
2202 2266  
2203 2267  static int
2204 2268  zonecfg_add_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
2205 2269  {
2206      -        xmlNodePtr newnode, cur = handle->zone_dh_cur;
     2270 +        xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode;
     2271 +        struct zone_res_attrtab *valptr;
2207 2272          int err;
2208 2273  
2209 2274          newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_NET, NULL);
2210 2275          if (strlen(tabptr->zone_nwif_address) > 0 &&
2211 2276              (err = newprop(newnode, DTD_ATTR_ADDRESS,
2212 2277              tabptr->zone_nwif_address)) != Z_OK)
2213 2278                  return (err);
2214 2279          if (strlen(tabptr->zone_nwif_allowed_address) > 0 &&
2215 2280              (err = newprop(newnode, DTD_ATTR_ALLOWED_ADDRESS,
2216 2281              tabptr->zone_nwif_allowed_address)) != Z_OK)
2217 2282                  return (err);
2218 2283          if ((err = newprop(newnode, DTD_ATTR_PHYSICAL,
2219 2284              tabptr->zone_nwif_physical)) != Z_OK)
2220 2285                  return (err);
2221 2286          /*
2222      -         * Do not add this property when it is not set, for backwards
2223      -         * compatibility and because it is optional.
     2287 +         * Do not add these properties when they are not set, for backwards
     2288 +         * compatibility and because they are optional.
2224 2289           */
2225 2290          if ((strlen(tabptr->zone_nwif_defrouter) > 0) &&
2226 2291              ((err = newprop(newnode, DTD_ATTR_DEFROUTER,
2227 2292              tabptr->zone_nwif_defrouter)) != Z_OK))
2228 2293                  return (err);
     2294 +        if (strlen(tabptr->zone_nwif_mac) > 0 &&
     2295 +            (err = newprop(newnode, DTD_ATTR_MAC,
     2296 +            tabptr->zone_nwif_mac)) != Z_OK)
     2297 +                return (err);
     2298 +        if (strlen(tabptr->zone_nwif_vlan_id) > 0 &&
     2299 +            (err = newprop(newnode, DTD_ATTR_VLANID,
     2300 +            tabptr->zone_nwif_vlan_id)) != Z_OK)
     2301 +                return (err);
     2302 +        if (strlen(tabptr->zone_nwif_gnic) > 0 &&
     2303 +            (err = newprop(newnode, DTD_ATTR_GNIC,
     2304 +            tabptr->zone_nwif_gnic)) != Z_OK)
     2305 +                return (err);
     2306 +
     2307 +        for (valptr = tabptr->zone_nwif_attrp; valptr != NULL;
     2308 +            valptr = valptr->zone_res_attr_next) {
     2309 +                valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR,
     2310 +                    NULL);
     2311 +                err = newprop(valnode, DTD_ATTR_NAME,
     2312 +                    valptr->zone_res_attr_name);
     2313 +                if (err != Z_OK)
     2314 +                        return (err);
     2315 +                err = newprop(valnode, DTD_ATTR_VALUE,
     2316 +                    valptr->zone_res_attr_value);
     2317 +                if (err != Z_OK)
     2318 +                        return (err);
     2319 +        }
     2320 +
2229 2321          return (Z_OK);
2230 2322  }
2231 2323  
2232 2324  int
2233 2325  zonecfg_add_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
2234 2326  {
2235 2327          int err;
2236 2328  
2237 2329          if (tabptr == NULL)
2238 2330                  return (Z_INVAL);
↓ open down ↓ 4 lines elided ↑ open up ↑
2243 2335          if ((err = zonecfg_add_nwif_core(handle, tabptr)) != Z_OK)
2244 2336                  return (err);
2245 2337  
2246 2338          return (Z_OK);
2247 2339  }
2248 2340  
2249 2341  static int
2250 2342  zonecfg_delete_nwif_core(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
2251 2343  {
2252 2344          xmlNodePtr cur = handle->zone_dh_cur;
2253      -        boolean_t addr_match, phys_match, allowed_addr_match;
     2345 +        boolean_t addr_match, phys_match, allowed_addr_match, mac_match,
     2346 +            gnic_match;
2254 2347  
2255 2348          for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) {
2256 2349                  if (xmlStrcmp(cur->name, DTD_ELEM_NET))
2257 2350                          continue;
2258 2351  
2259 2352                  addr_match = match_prop(cur, DTD_ATTR_ADDRESS,
2260 2353                      tabptr->zone_nwif_address);
2261 2354                  allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS,
2262 2355                      tabptr->zone_nwif_allowed_address);
2263 2356                  phys_match = match_prop(cur, DTD_ATTR_PHYSICAL,
2264 2357                      tabptr->zone_nwif_physical);
     2358 +                mac_match = match_prop(cur, DTD_ATTR_MAC,
     2359 +                    tabptr->zone_nwif_mac);
     2360 +                gnic_match = match_prop(cur, DTD_ATTR_GNIC,
     2361 +                    tabptr->zone_nwif_gnic);
2265 2362  
2266      -                if (addr_match && allowed_addr_match && phys_match) {
     2363 +                if ((addr_match || allowed_addr_match || mac_match ||
     2364 +                    gnic_match) && phys_match) {
2267 2365                          xmlUnlinkNode(cur);
2268 2366                          xmlFreeNode(cur);
2269 2367                          return (Z_OK);
2270 2368                  }
2271 2369          }
2272 2370          return (Z_NO_RESOURCE_ID);
2273 2371  }
2274 2372  
2275 2373  int
2276 2374  zonecfg_delete_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
↓ open down ↓ 28 lines elided ↑ open up ↑
2305 2403  
2306 2404          if ((err = zonecfg_delete_nwif_core(handle, oldtabptr)) != Z_OK)
2307 2405                  return (err);
2308 2406  
2309 2407          if ((err = zonecfg_add_nwif_core(handle, newtabptr)) != Z_OK)
2310 2408                  return (err);
2311 2409  
2312 2410          return (Z_OK);
2313 2411  }
2314 2412  
     2413 +void
     2414 +zonecfg_free_res_attr_list(struct zone_res_attrtab *valtab)
     2415 +{
     2416 +        if (valtab == NULL)
     2417 +                return;
     2418 +        zonecfg_free_res_attr_list(valtab->zone_res_attr_next);
     2419 +        free(valtab);
     2420 +}
     2421 +
     2422 +int
     2423 +zonecfg_add_res_attr(struct zone_res_attrtab **headptr,
     2424 +    struct zone_res_attrtab *valtabptr)
     2425 +{
     2426 +        struct zone_res_attrtab *last, *old, *new;
     2427 +
     2428 +        last = *headptr;
     2429 +        for (old = last; old != NULL; old = old->zone_res_attr_next)
     2430 +                last = old;     /* walk to the end of the list */
     2431 +        new = valtabptr;        /* alloc'd by caller */
     2432 +        new->zone_res_attr_next = NULL;
     2433 +        if (last == NULL)
     2434 +                *headptr = new;
     2435 +        else
     2436 +                last->zone_res_attr_next = new;
     2437 +        return (Z_OK);
     2438 +}
     2439 +
     2440 +int
     2441 +zonecfg_remove_res_attr(struct zone_res_attrtab **headptr,
     2442 +    struct zone_res_attrtab *valtabptr)
     2443 +{
     2444 +        struct zone_res_attrtab *last, *this, *next;
     2445 +
     2446 +        last = *headptr;
     2447 +        for (this = last; this != NULL; this = this->zone_res_attr_next) {
     2448 +                if (strcmp(this->zone_res_attr_name,
     2449 +                    valtabptr->zone_res_attr_name) == 0 &&
     2450 +                    strcmp(this->zone_res_attr_value,
     2451 +                    valtabptr->zone_res_attr_value) == 0) {
     2452 +                        next = this->zone_res_attr_next;
     2453 +                        if (this == *headptr)
     2454 +                                *headptr = next;
     2455 +                        else
     2456 +                                last->zone_res_attr_next = next;
     2457 +                        free(this);
     2458 +                        return (Z_OK);
     2459 +                } else
     2460 +                        last = this;
     2461 +        }
     2462 +        return (Z_NO_PROPERTY_ID);
     2463 +}
     2464 +
2315 2465  /*
2316 2466   * Must be a comma-separated list of alpha-numeric file system names.
2317 2467   */
2318 2468  static int
2319 2469  zonecfg_valid_fs_allowed(const char *fsallowedp)
2320 2470  {
2321 2471          char tmp[ZONE_FS_ALLOWED_MAX];
2322 2472          char *cp = tmp;
2323 2473          char *p;
2324 2474  
↓ open down ↓ 129 lines elided ↑ open up ↑
2454 2604           * hostid.
2455 2605           */
2456 2606          if (hostidp == NULL || (err = zonecfg_valid_hostid(hostidp)) == Z_OK)
2457 2607                  return (setrootattr(handle, DTD_ATTR_HOSTID, hostidp));
2458 2608          return (err);
2459 2609  }
2460 2610  
2461 2611  int
2462 2612  zonecfg_lookup_dev(zone_dochandle_t handle, struct zone_devtab *tabptr)
2463 2613  {
2464      -        xmlNodePtr cur, firstmatch;
     2614 +        xmlNodePtr cur, val, firstmatch;
2465 2615          int err;
2466 2616          char match[MAXPATHLEN];
2467 2617  
2468 2618          if (tabptr == NULL)
2469 2619                  return (Z_INVAL);
2470 2620  
2471 2621          if ((err = operation_prep(handle)) != Z_OK)
2472 2622                  return (err);
2473 2623  
2474 2624          cur = handle->zone_dh_cur;
↓ open down ↓ 24 lines elided ↑ open up ↑
2499 2649          }
2500 2650          if (firstmatch == NULL)
2501 2651                  return (Z_NO_RESOURCE_ID);
2502 2652  
2503 2653          cur = firstmatch;
2504 2654  
2505 2655          if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match,
2506 2656              sizeof (tabptr->zone_dev_match))) != Z_OK)
2507 2657                  return (err);
2508 2658  
     2659 +        tabptr->zone_dev_attrp = NULL;
     2660 +        for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
     2661 +                struct zone_res_attrtab *valptr;
     2662 +
     2663 +                valptr = (struct zone_res_attrtab *)malloc(
     2664 +                    sizeof (struct zone_res_attrtab));
     2665 +                if (valptr == NULL)
     2666 +                        return (Z_NOMEM);
     2667 +
     2668 +                valptr->zone_res_attr_name[0] =
     2669 +                    valptr->zone_res_attr_value[0] = '\0';
     2670 +                if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr)
     2671 +                    != Z_OK) {
     2672 +                        free(valptr);
     2673 +                        break;
     2674 +                }
     2675 +
     2676 +                if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name,
     2677 +                    sizeof (valptr->zone_res_attr_name)) != Z_OK))
     2678 +                        break;
     2679 +                if ((fetchprop(val, DTD_ATTR_VALUE,
     2680 +                    valptr->zone_res_attr_value,
     2681 +                    sizeof (valptr->zone_res_attr_value)) != Z_OK))
     2682 +                        break;
     2683 +        }
     2684 +
2509 2685          return (Z_OK);
2510 2686  }
2511 2687  
2512 2688  static int
2513 2689  zonecfg_add_dev_core(zone_dochandle_t handle, struct zone_devtab *tabptr)
2514 2690  {
2515      -        xmlNodePtr newnode, cur = handle->zone_dh_cur;
     2691 +        xmlNodePtr newnode, cur = handle->zone_dh_cur, valnode;
     2692 +        struct zone_res_attrtab *valptr;
2516 2693          int err;
2517 2694  
2518 2695          newnode = xmlNewTextChild(cur, NULL, DTD_ELEM_DEVICE, NULL);
2519 2696  
2520 2697          if ((err = newprop(newnode, DTD_ATTR_MATCH,
2521 2698              tabptr->zone_dev_match)) != Z_OK)
2522 2699                  return (err);
2523 2700  
     2701 +        for (valptr = tabptr->zone_dev_attrp; valptr != NULL;
     2702 +            valptr = valptr->zone_res_attr_next) {
     2703 +                valnode = xmlNewTextChild(newnode, NULL, DTD_ELEM_NETATTR,
     2704 +                    NULL);
     2705 +                err = newprop(valnode, DTD_ATTR_NAME,
     2706 +                    valptr->zone_res_attr_name);
     2707 +                if (err != Z_OK)
     2708 +                        return (err);
     2709 +                err = newprop(valnode, DTD_ATTR_VALUE,
     2710 +                    valptr->zone_res_attr_value);
     2711 +                if (err != Z_OK)
     2712 +                        return (err);
     2713 +        }
     2714 +
     2715 +
2524 2716          return (Z_OK);
2525 2717  }
2526 2718  
2527 2719  int
2528 2720  zonecfg_add_dev(zone_dochandle_t handle, struct zone_devtab *tabptr)
2529 2721  {
2530 2722          int err;
2531 2723  
2532 2724          if (tabptr == NULL)
2533 2725                  return (Z_INVAL);
↓ open down ↓ 2177 lines elided ↑ open up ↑
4711 4903  
4712 4904  int
4713 4905  zonecfg_setnwifent(zone_dochandle_t handle)
4714 4906  {
4715 4907          return (zonecfg_setent(handle));
4716 4908  }
4717 4909  
4718 4910  int
4719 4911  zonecfg_getnwifent(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
4720 4912  {
4721      -        xmlNodePtr cur;
     4913 +        xmlNodePtr cur, val;
     4914 +        struct zone_res_attrtab *valptr;
4722 4915          int err;
4723 4916  
4724 4917          if (handle == NULL)
4725 4918                  return (Z_INVAL);
4726 4919  
4727 4920          if ((cur = handle->zone_dh_cur) == NULL)
4728 4921                  return (Z_NO_ENTRY);
4729 4922  
4730 4923          for (; cur != NULL; cur = cur->next)
4731 4924                  if (!xmlStrcmp(cur->name, DTD_ELEM_NET))
↓ open down ↓ 15 lines elided ↑ open up ↑
4747 4940                  handle->zone_dh_cur = handle->zone_dh_top;
4748 4941                  return (err);
4749 4942          }
4750 4943  
4751 4944          if ((err = fetchprop(cur, DTD_ATTR_PHYSICAL, tabptr->zone_nwif_physical,
4752 4945              sizeof (tabptr->zone_nwif_physical))) != Z_OK) {
4753 4946                  handle->zone_dh_cur = handle->zone_dh_top;
4754 4947                  return (err);
4755 4948          }
4756 4949  
     4950 +        if ((err = fetchprop(cur, DTD_ATTR_MAC, tabptr->zone_nwif_mac,
     4951 +            sizeof (tabptr->zone_nwif_mac))) != Z_OK) {
     4952 +                handle->zone_dh_cur = handle->zone_dh_top;
     4953 +                return (err);
     4954 +        }
     4955 +
     4956 +        if ((err = fetchprop(cur, DTD_ATTR_VLANID, tabptr->zone_nwif_vlan_id,
     4957 +            sizeof (tabptr->zone_nwif_vlan_id))) != Z_OK) {
     4958 +                handle->zone_dh_cur = handle->zone_dh_top;
     4959 +                return (err);
     4960 +        }
     4961 +
     4962 +        if ((err = fetchprop(cur, DTD_ATTR_GNIC, tabptr->zone_nwif_gnic,
     4963 +            sizeof (tabptr->zone_nwif_gnic))) != Z_OK) {
     4964 +                handle->zone_dh_cur = handle->zone_dh_top;
     4965 +                return (err);
     4966 +        }
     4967 +
4757 4968          if ((err = fetchprop(cur, DTD_ATTR_DEFROUTER,
4758 4969              tabptr->zone_nwif_defrouter,
4759 4970              sizeof (tabptr->zone_nwif_defrouter))) != Z_OK) {
4760 4971                  handle->zone_dh_cur = handle->zone_dh_top;
4761 4972                  return (err);
4762 4973          }
4763 4974  
     4975 +        tabptr->zone_nwif_attrp = NULL;
     4976 +        for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
     4977 +                valptr = (struct zone_res_attrtab *)malloc(
     4978 +                    sizeof (struct zone_res_attrtab));
     4979 +                if (valptr == NULL)
     4980 +                        return (Z_NOMEM);
     4981 +
     4982 +                valptr->zone_res_attr_name[0] =
     4983 +                    valptr->zone_res_attr_value[0] = '\0';
     4984 +                if (zonecfg_add_res_attr(&(tabptr->zone_nwif_attrp), valptr)
     4985 +                    != Z_OK) {
     4986 +                        free(valptr);
     4987 +                        break;
     4988 +                }
     4989 +
     4990 +                if (fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name,
     4991 +                    sizeof (valptr->zone_res_attr_name)) != Z_OK)
     4992 +                        break;
     4993 +                if (fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value,
     4994 +                    sizeof (valptr->zone_res_attr_value)) != Z_OK)
     4995 +                        break;
     4996 +        }
     4997 +
4764 4998          handle->zone_dh_cur = cur->next;
4765 4999          return (Z_OK);
4766 5000  }
4767 5001  
4768 5002  int
4769 5003  zonecfg_endnwifent(zone_dochandle_t handle)
4770 5004  {
4771 5005          return (zonecfg_endent(handle));
4772 5006  }
4773 5007  
4774 5008  int
4775 5009  zonecfg_setdevent(zone_dochandle_t handle)
4776 5010  {
4777 5011          return (zonecfg_setent(handle));
4778 5012  }
4779 5013  
4780 5014  int
4781 5015  zonecfg_getdevent(zone_dochandle_t handle, struct zone_devtab *tabptr)
4782 5016  {
4783      -        xmlNodePtr cur;
     5017 +        xmlNodePtr cur, val;
4784 5018          int err;
4785 5019  
4786 5020          if (handle == NULL)
4787 5021                  return (Z_INVAL);
4788 5022  
4789 5023          if ((cur = handle->zone_dh_cur) == NULL)
4790 5024                  return (Z_NO_ENTRY);
4791 5025  
4792 5026          for (; cur != NULL; cur = cur->next)
4793 5027                  if (!xmlStrcmp(cur->name, DTD_ELEM_DEVICE))
↓ open down ↓ 2 lines elided ↑ open up ↑
4796 5030                  handle->zone_dh_cur = handle->zone_dh_top;
4797 5031                  return (Z_NO_ENTRY);
4798 5032          }
4799 5033  
4800 5034          if ((err = fetchprop(cur, DTD_ATTR_MATCH, tabptr->zone_dev_match,
4801 5035              sizeof (tabptr->zone_dev_match))) != Z_OK) {
4802 5036                  handle->zone_dh_cur = handle->zone_dh_top;
4803 5037                  return (err);
4804 5038          }
4805 5039  
     5040 +        tabptr->zone_dev_attrp = NULL;
     5041 +        for (val = cur->xmlChildrenNode; val != NULL; val = val->next) {
     5042 +                struct zone_res_attrtab *valptr;
     5043 +
     5044 +                valptr = (struct zone_res_attrtab *)malloc(
     5045 +                    sizeof (struct zone_res_attrtab));
     5046 +                if (valptr == NULL)
     5047 +                        return (Z_NOMEM);
     5048 +
     5049 +                valptr->zone_res_attr_name[0] =
     5050 +                    valptr->zone_res_attr_value[0] = '\0';
     5051 +                if (zonecfg_add_res_attr(&(tabptr->zone_dev_attrp), valptr)
     5052 +                    != Z_OK) {
     5053 +                        free(valptr);
     5054 +                        break;
     5055 +                }
     5056 +
     5057 +                if ((fetchprop(val, DTD_ATTR_NAME, valptr->zone_res_attr_name,
     5058 +                    sizeof (valptr->zone_res_attr_name)) != Z_OK))
     5059 +                        break;
     5060 +                if ((fetchprop(val, DTD_ATTR_VALUE, valptr->zone_res_attr_value,
     5061 +                    sizeof (valptr->zone_res_attr_value)) != Z_OK))
     5062 +                        break;
     5063 +        }
     5064 +
4806 5065          handle->zone_dh_cur = cur->next;
4807 5066          return (Z_OK);
4808 5067  }
4809 5068  
4810 5069  int
4811 5070  zonecfg_enddevent(zone_dochandle_t handle)
4812 5071  {
4813 5072          return (zonecfg_endent(handle));
4814 5073  }
4815 5074  
↓ open down ↓ 707 lines elided ↑ open up ↑
5523 5782                  return (Z_NOMEM);
5524 5783  
5525 5784          err = zonecfg_get_handle((char *)zone_name, handle);
5526 5785          if (err == Z_OK)
5527 5786                  err = zonecfg_get_brand(handle, brandname, rp_sz);
5528 5787  
5529 5788          zonecfg_fini_handle(handle);
5530 5789          return (err);
5531 5790  }
5532 5791  
     5792 +/*
     5793 + * Atomically get a new zone_did value.  The currently allocated value
     5794 + * is stored in /etc/zones/did.txt.  Lock the file, read the current value,
     5795 + * increment, save the new value and unlock the file.  Return the new value
     5796 + * or -1 if there was an error.  The ID namespace is large enough that we
     5797 + * don't worry about recycling an ID when a zone is deleted.
     5798 + */
     5799 +static zoneid_t
     5800 +new_zone_did()
     5801 +{
     5802 +        int fd;
     5803 +        int len;
     5804 +        int val;
     5805 +        struct flock lck;
     5806 +        char buf[80];
     5807 +
     5808 +        if ((fd = open(DEBUGID_FILE, O_RDWR | O_CREAT,
     5809 +            S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
     5810 +                perror("new_zone_did open failed");
     5811 +                return (-1);
     5812 +        }
     5813 +
     5814 +        /* Initialize the lock. */
     5815 +        lck.l_whence = SEEK_SET;
     5816 +        lck.l_start = 0;
     5817 +        lck.l_len = 0;
     5818 +
     5819 +        /* Wait until we acquire an exclusive lock on the file. */
     5820 +        lck.l_type = F_WRLCK;
     5821 +        if (fcntl(fd, F_SETLKW, &lck) == -1) {
     5822 +                perror("new_zone_did lock failed");
     5823 +                (void) close(fd);
     5824 +                return (-1);
     5825 +        }
     5826 +
     5827 +        /* Get currently allocated value */
     5828 +        len = read(fd, buf, sizeof (buf));
     5829 +        if (len == -1) {
     5830 +                perror("new_zone_did read failed");
     5831 +                val = -1;
     5832 +        } else {
     5833 +                if (lseek(fd, 0L, SEEK_SET) == -1) {
     5834 +                        perror("new_zone_did seek failed");
     5835 +                        val = -1;
     5836 +                } else {
     5837 +                        if (len == 0) {
     5838 +                                /* Just created the file, initialize at 1 */
     5839 +                                val = 1;
     5840 +                        } else {
     5841 +                                val = atoi(buf);
     5842 +                                val++;
     5843 +                        }
     5844 +
     5845 +                        (void) snprintf(buf, sizeof (buf), "%d\n", val);
     5846 +                        len = strlen(buf);
     5847 +
     5848 +                        /* Save newly allocated value */
     5849 +                        if (write(fd, buf, len) == -1) {
     5850 +                                perror("new_zone_did write failed");
     5851 +                                val = -1;
     5852 +                        }
     5853 +                }
     5854 +        }
     5855 +
     5856 +        /* Release the file lock. */
     5857 +        lck.l_type = F_UNLCK;
     5858 +        if (fcntl(fd, F_SETLK, &lck) == -1) {
     5859 +                perror("new_zone_did unlock failed");
     5860 +                val = -1;
     5861 +        }
     5862 +
     5863 +        if (close(fd) != 0)
     5864 +                perror("new_zone_did close failed");
     5865 +
     5866 +        return (val);
     5867 +}
     5868 +
     5869 +/*
     5870 + * Called by zoneadmd to get the zone's debug ID.
     5871 + * If the zone doesn't already have an ID, a new one is generated and
     5872 + * persistently saved onto the zone.  Normally either zoneadm or zonecfg
     5873 + * will assign a new ID for the zone, so zoneadmd should never have to
     5874 + * generate one, but we also handle that here just to be paranoid.
     5875 + */
     5876 +zoneid_t
     5877 +zone_get_did(char *zone_name)
     5878 +{
     5879 +        int res;
     5880 +        zoneid_t new_did;
     5881 +        zone_dochandle_t handle;
     5882 +        char did_str[80];
     5883 +
     5884 +        if ((handle = zonecfg_init_handle()) == NULL)
     5885 +                return (getpid());
     5886 +
     5887 +        if (zonecfg_get_handle((char *)zone_name, handle) != Z_OK)
     5888 +                return (getpid());
     5889 +
     5890 +        res = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str));
     5891 +
     5892 +        /* If the zone already has an assigned debug ID, return it. */
     5893 +        if (res == Z_OK && did_str[0] != '\0') {
     5894 +                zonecfg_fini_handle(handle);
     5895 +                return (atoi(did_str));
     5896 +        }
     5897 +
     5898 +        /*
     5899 +         * The zone doesn't have an assigned debug ID yet, generate one and
     5900 +         * save it as part of the zone definition.
     5901 +         */
     5902 +        if ((new_did = new_zone_did()) == -1) {
     5903 +                /*
     5904 +                 * We should really never hit this block of code.
     5905 +                 * Generating a new ID failed for some reason.  Use the current
     5906 +                 * pid as a temporary ID so that the zone can continue to boot
     5907 +                 * but we don't persistently save this temporary ID on the zone.
     5908 +                 */
     5909 +                zonecfg_fini_handle(handle);
     5910 +                return (getpid());
     5911 +        }
     5912 +
     5913 +        /* Now persistently save this new ID onto the zone. */
     5914 +        (void) snprintf(did_str, sizeof (did_str), "%d", new_did);
     5915 +        (void) setrootattr(handle, DTD_ATTR_DID, did_str);
     5916 +        (void) zonecfg_save(handle);
     5917 +
     5918 +        zonecfg_fini_handle(handle);
     5919 +        return (new_did);
     5920 +}
     5921 +
     5922 +zoneid_t
     5923 +zonecfg_get_did(zone_dochandle_t handle)
     5924 +{
     5925 +        char did_str[80];
     5926 +        int err;
     5927 +        zoneid_t did;
     5928 +
     5929 +        err = getrootattr(handle, DTD_ATTR_DID, did_str, sizeof (did_str));
     5930 +        if (err == Z_OK && did_str[0] != '\0')
     5931 +                did = atoi(did_str);
     5932 +        else
     5933 +                did = -1;
     5934 +
     5935 +        return (did);
     5936 +}
     5937 +
     5938 +void
     5939 +zonecfg_set_did(zone_dochandle_t handle)
     5940 +{
     5941 +        zoneid_t new_did;
     5942 +        char did_str[80];
     5943 +
     5944 +        if ((new_did = new_zone_did()) == -1)
     5945 +                return;
     5946 +        (void) snprintf(did_str, sizeof (did_str), "%d", new_did);
     5947 +        (void) setrootattr(handle, DTD_ATTR_DID, did_str);
     5948 +}
     5949 +
5533 5950  /*
5534 5951   * Return the appropriate root for the active /dev.
5535 5952   * For normal zone, the path is $ZONEPATH/root;
5536 5953   * for scratch zone, the dev path is $ZONEPATH/lu.
5537 5954   */
5538 5955  int
5539 5956  zone_get_devroot(char *zone_name, char *devroot, size_t rp_sz)
5540 5957  {
5541 5958          int err;
5542 5959          char *suffix;
↓ open down ↓ 2447 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX