Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libzonecfg/common/libzonecfg.c
          +++ new/usr/src/lib/libzonecfg/common/libzonecfg.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2014 Gary Mills
  24   24   * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  25      - * Copyright 2015 Joyent Inc.
  26   25   * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
       26 + * Copyright 2015 Joyent Inc.
  27   27   */
  28   28  
  29   29  #include <libsysevent.h>
  30   30  #include <pthread.h>
  31   31  #include <stdlib.h>
  32   32  #include <errno.h>
  33   33  #include <fnmatch.h>
  34   34  #include <strings.h>
  35   35  #include <unistd.h>
  36   36  #include <assert.h>
↓ open down ↓ 147 lines elided ↑ open up ↑
 184  184          {ALIAS_MAXSHMIDS, "zone.max-shm-ids", "privileged", "deny", 0},
 185  185          {ALIAS_MAXMSGIDS, "zone.max-msg-ids", "privileged", "deny", 0},
 186  186          {ALIAS_MAXSEMIDS, "zone.max-sem-ids", "privileged", "deny", 0},
 187  187          {ALIAS_MAXLOCKEDMEM, "zone.max-locked-memory", "privileged", "deny", 0},
 188  188          {ALIAS_MAXSWAP, "zone.max-swap", "privileged", "deny", 0},
 189  189          {ALIAS_MAXPHYSMEM, "zone.max-physical-memory", "privileged", "deny",
 190  190              1048576},
 191  191          {ALIAS_SHARES, "zone.cpu-shares", "privileged", "none", 0},
 192  192          {ALIAS_CPUCAP, "zone.cpu-cap", "privileged", "deny", 0},
 193  193          {ALIAS_MAXPROCS, "zone.max-processes", "privileged", "deny", 100},
 194      -        {ALIAS_ZFSPRI, "zone.zfs-io-priority", "privileged", "none", 0},
 195  194          {NULL, NULL, NULL, NULL, 0}
 196  195  };
 197  196  
 198  197  /*
 199  198   * Structure for applying rctls to a running zone.  It allows important
 200  199   * process values to be passed together easily.
 201  200   */
 202  201  typedef struct pr_info_handle {
 203  202          struct ps_prochandle *pr;
 204  203          pid_t pid;
↓ open down ↓ 27 lines elided ↑ open up ↑
 232  231  };
 233  232  
 234  233  /* used to track nested zone-lock operations */
 235  234  static int zone_lock_cnt = 0;
 236  235  
 237  236  /* used to communicate lock status to children */
 238  237  #define LOCK_ENV_VAR    "_ZONEADM_LOCK_HELD"
 239  238  static char zoneadm_lock_held[] = LOCK_ENV_VAR"=1";
 240  239  static char zoneadm_lock_not_held[] = LOCK_ENV_VAR"=0";
 241  240  
 242      -static void zonecfg_notify_delete(const char *);
 243      -
 244  241  char *zonecfg_root = "";
 245  242  
 246  243  /*
 247  244   * For functions which return int, which is most of the functions herein,
 248  245   * the return values should be from the Z_foo set defined in <libzonecfg.h>.
 249  246   * In some instances, we take pains mapping some libc errno values to Z_foo
 250  247   * values from this set.
 251  248   */
 252  249  
 253  250  /*
↓ open down ↓ 169 lines elided ↑ open up ↑
 423  420          if ((err = putzoneent(&ze, PZE_REMOVE)) != Z_OK)
 424  421                  if (!force)
 425  422                          return (err);
 426  423  
 427  424          err = zonecfg_destroy_impl(path);
 428  425  
 429  426          /*
 430  427           * Treat failure to find the XML file silently, since, well, it's
 431  428           * gone, and with the index file cleaned up, we're done.
 432  429           */
 433      -        if (err == Z_OK || err == Z_NO_ZONE) {
 434      -                zonecfg_notify_delete(zonename);
      430 +        if (err == Z_OK || err == Z_NO_ZONE)
 435  431                  return (Z_OK);
 436      -        }
 437  432          return (err);
 438  433  }
 439  434  
 440  435  int
 441  436  zonecfg_destroy_snapshot(const char *zonename)
 442  437  {
 443  438          char path[MAXPATHLEN];
 444  439  
 445  440          if (!snap_file_path(zonename, path, sizeof (path)))
 446  441                  return (Z_MISC_FS);
↓ open down ↓ 676 lines elided ↑ open up ↑
1123 1118   * /etc/zones/index caches a vital piece of information which is also
1124 1119   * in the <zonename>.xml file: the path to the zone.  This is for performance,
1125 1120   * since we need to walk all zonepath's in order to be able to detect conflicts
1126 1121   * (see crosscheck_zonepaths() in the zoneadm command).
1127 1122   *
1128 1123   * An additional complexity is that when doing a rename, we'd like the entire
1129 1124   * index update operation (rename, and potential state changes) to be atomic.
1130 1125   * In general, the operation of this function should succeed or fail as
1131 1126   * a unit.
1132 1127   */
1133      -static int
     1128 +int
1134 1129  zonecfg_refresh_index_file(zone_dochandle_t handle)
1135 1130  {
1136 1131          char name[ZONENAME_MAX], zonepath[MAXPATHLEN];
1137 1132          struct zoneent ze;
1138 1133          int err;
1139 1134          int opcode;
1140 1135          char *zn;
1141 1136  
1142 1137          bzero(&ze, sizeof (ze));
1143 1138          ze.zone_state = -1;     /* Preserve existing state in index */
↓ open down ↓ 1 lines elided ↑ open up ↑
1145 1140          if ((err = zonecfg_get_name(handle, name, sizeof (name))) != Z_OK)
1146 1141                  return (err);
1147 1142          (void) strlcpy(ze.zone_name, name, sizeof (ze.zone_name));
1148 1143  
1149 1144          if ((err = zonecfg_get_zonepath(handle, zonepath,
1150 1145              sizeof (zonepath))) != Z_OK)
1151 1146                  return (err);
1152 1147          (void) strlcpy(ze.zone_path, zonepath + strlen(zonecfg_root),
1153 1148              sizeof (ze.zone_path));
1154 1149  
1155      -        if ((err = zonecfg_get_brand(handle, ze.zone_brand,
1156      -            sizeof (ze.zone_brand))) != 0)
1157      -                return (err);
1158      -
1159      -        if ((err = zonecfg_get_iptype(handle, &ze.zone_iptype)) != Z_OK)
1160      -                return (err);
1161      -
1162      -        ze.zone_did = zonecfg_get_did(handle);
1163      -
1164 1150          if (is_renaming(handle)) {
1165 1151                  opcode = PZE_MODIFY;
1166 1152                  (void) strlcpy(ze.zone_name, handle->zone_dh_delete_name,
1167 1153                      sizeof (ze.zone_name));
1168 1154                  (void) strlcpy(ze.zone_newname, name, sizeof (ze.zone_newname));
1169 1155          } else if (is_new(handle)) {
1170 1156                  FILE *cookie;
1171 1157                  /*
1172 1158                   * Be tolerant of the zone already existing in the index file,
1173 1159                   * since we might be forcibly overwriting an existing
↓ open down ↓ 322 lines elided ↑ open up ↑
1496 1482              ATTACH_FORCED);
1497 1483  
1498 1484          if (forced) {
1499 1485                  (void) rename(detached, attached);
1500 1486          } else {
1501 1487                  (void) unlink(attached);
1502 1488                  (void) unlink(detached);
1503 1489          }
1504 1490  }
1505 1491  
1506      -static void
1507      -zonecfg_notify_conf_change(const char *zname, char *os, char *ns)
1508      -{
1509      -        evchan_t *ze_chan;
1510      -        struct timeval now;
1511      -        uint64_t t;
1512      -        nvlist_t *nvl = NULL;
1513      -
1514      -        if (sysevent_evc_bind(ZONE_EVENT_CHANNEL, &ze_chan, 0) != 0)
1515      -                return;
1516      -
1517      -        /* Current time since Jan 1 1970 but consumers expect NS */
1518      -        gettimeofday(&now, NULL);
1519      -        t = (now.tv_sec * NANOSEC) + (now.tv_usec * 1000);
1520      -
1521      -        if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP) == 0 &&
1522      -            nvlist_add_string(nvl, ZONE_CB_NAME, zname) == 0 &&
1523      -            nvlist_add_string(nvl, ZONE_CB_NEWSTATE, ns) == 0 &&
1524      -            nvlist_add_string(nvl, ZONE_CB_OLDSTATE, os) == 0 &&
1525      -            nvlist_add_int32(nvl, ZONE_CB_ZONEID, -1) == 0 &&
1526      -            nvlist_add_uint64(nvl, ZONE_CB_TIMESTAMP, t) == 0) {
1527      -                (void) sysevent_evc_publish(ze_chan, ZONE_EVENT_STATUS_CLASS,
1528      -                    ZONE_EVENT_STATUS_SUBCLASS, "sun.com", "zonecfg", nvl,
1529      -                    EVCH_SLEEP);
1530      -        }
1531      -
1532      -        nvlist_free(nvl);
1533      -        (void) sysevent_evc_unbind(ze_chan);
1534      -}
1535      -
1536      -void
1537      -zonecfg_notify_create(zone_dochandle_t handle)
1538      -{
1539      -        char zname[ZONENAME_MAX];
1540      -
1541      -        if (zonecfg_check_handle(handle) != Z_OK)
1542      -                return;
1543      -
1544      -        if (zonecfg_get_name(handle, zname, sizeof (zname)) != Z_OK)
1545      -                return;
1546      -
1547      -        zonecfg_notify_conf_change(zname, "", ZONE_STATE_STR_CONFIGURED);
1548      -}
1549      -
1550      -static void
1551      -zonecfg_notify_delete(const char *zname)
1552      -{
1553      -        zonecfg_notify_conf_change(zname, ZONE_STATE_STR_CONFIGURED, "");
1554      -}
1555      -
1556 1492  /*
1557 1493   * Special case: if access(2) fails with ENOENT, then try again using
1558 1494   * ZONE_CONFIG_ROOT instead of config_file_path(zonename).  This is how we
1559 1495   * work around the case of a config file which has not been created yet:
1560 1496   * the user will need access to the directory so use that as a heuristic.
1561 1497   */
1562 1498  
1563 1499  int
1564 1500  zonecfg_access(const char *zonename, int amode)
1565 1501  {
↓ open down ↓ 570 lines elided ↑ open up ↑
2136 2072                  save_errno = errno;
2137 2073                  (void) close(so);
2138 2074                  errno = save_errno;
2139 2075                  return (B_FALSE);
2140 2076          }
2141 2077          (void) close(so);
2142 2078          return (B_TRUE);
2143 2079  }
2144 2080  
2145 2081  /*
2146      - * Turn an addr that looks like f:2:0:44:5:6C into 0f:02:00:44:05:6c
2147      - * We're expecting a dst of at least MAXMACADDRLEN size here.
2148      - */
2149      -static void
2150      -normalize_mac_addr(char *dst, const char *src, int len)
2151      -{
2152      -        char *p, *e, *sep = "";
2153      -        long n;
2154      -        char buf[MAXMACADDRLEN], tmp[4];
2155      -
2156      -        *dst = '\0';
2157      -        (void) strlcpy(buf, src, sizeof (buf));
2158      -        p = strtok(buf, ":");
2159      -        while (p != NULL) {
2160      -                n = strtol(p, &e, 16);
2161      -                if (*e != NULL || n > 0xff)
2162      -                        return;
2163      -                (void) snprintf(tmp, sizeof (tmp), "%s%02x", sep, n);
2164      -                (void) strlcat(dst, tmp, len);
2165      -
2166      -                sep = ":";
2167      -                p = strtok(NULL, ":");
2168      -        }
2169      -}
2170      -
2171      -/*
2172 2082   * Determines whether there is a net resource with the physical interface, IP
2173 2083   * address, and default router specified by 'tabptr' in the zone configuration
2174 2084   * to which 'handle' refers.  'tabptr' must have an interface, an address, a
2175 2085   * default router, or a combination of the three.  This function returns Z_OK
2176 2086   * iff there is exactly one net resource matching the query specified by
2177 2087   * 'tabptr'.  The function returns Z_INSUFFICIENT_SPEC if there are multiple
2178 2088   * matches or 'tabptr' does not specify a physical interface, address, or
2179 2089   * default router.  The function returns Z_NO_RESOURCE_ID if are no matches.
2180 2090   *
2181 2091   * Errors might also be returned if the entry that exactly matches the
↓ open down ↓ 4 lines elided ↑ open up ↑
2186 2096   */
2187 2097  int
2188 2098  zonecfg_lookup_nwif(zone_dochandle_t handle, struct zone_nwiftab *tabptr)
2189 2099  {
2190 2100          xmlNodePtr cur, val;
2191 2101          xmlNodePtr firstmatch;
2192 2102          int err;
2193 2103          char address[INET6_ADDRSTRLEN];
2194 2104          char physical[LIFNAMSIZ];
2195 2105          char mac[MAXMACADDRLEN];
2196      -        char norm_mac[MAXMACADDRLEN];
2197 2106          char gnic[LIFNAMSIZ];
2198 2107          size_t addrspec;                /* nonzero if tabptr has IP addr */
2199 2108          size_t physspec;                /* nonzero if tabptr has interface */
2200 2109          size_t macspec;                 /* nonzero if tabptr has mac addr */
2201 2110          size_t gnicspec;                /* nonzero if tabptr has gnic */
2202 2111          size_t defrouterspec;           /* nonzero if tabptr has def. router */
2203 2112          size_t allowed_addrspec;
2204 2113          zone_iptype_t iptype;
2205 2114  
2206 2115          if (tabptr == NULL)
↓ open down ↓ 36 lines elided ↑ open up ↑
2243 2152                          continue;
2244 2153  
2245 2154                  /*
2246 2155                   * If any relevant fields don't match the query, then skip
2247 2156                   * the current net element.
2248 2157                   */
2249 2158                  if (physspec != 0 && (fetchprop(cur, DTD_ATTR_PHYSICAL,
2250 2159                      physical, sizeof (physical)) != Z_OK ||
2251 2160                      strcmp(tabptr->zone_nwif_physical, physical) != 0))
2252 2161                          continue;
2253      -                if (iptype == ZS_EXCLUSIVE && macspec != 0) {
2254      -                        if (fetchprop(cur, DTD_ATTR_MAC, mac, sizeof (mac)) !=
2255      -                            Z_OK)
2256      -                                continue;
2257      -                        normalize_mac_addr(norm_mac, mac, sizeof (norm_mac));
2258      -                        if (strcmp(tabptr->zone_nwif_mac, norm_mac) != 0)
2259      -                                continue;
2260      -                }
     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;
2261 2166                  if (iptype == ZS_EXCLUSIVE && gnicspec != 0 &&
2262 2167                      (fetchprop(cur, DTD_ATTR_GNIC, gnic,
2263 2168                      sizeof (gnic)) != Z_OK ||
2264 2169                      strcmp(tabptr->zone_nwif_gnic, gnic) != 0))
2265 2170                          continue;
2266 2171                  if (iptype == ZS_SHARED && addrspec != 0 &&
2267 2172                      (fetchprop(cur, DTD_ATTR_ADDRESS, address,
2268 2173                      sizeof (address)) != Z_OK ||
2269 2174                      !zonecfg_same_net_address(tabptr->zone_nwif_address,
2270 2175                      address)))
↓ open down ↓ 177 lines elided ↑ open up ↑
2448 2353                      tabptr->zone_nwif_address);
2449 2354                  allowed_addr_match = match_prop(cur, DTD_ATTR_ALLOWED_ADDRESS,
2450 2355                      tabptr->zone_nwif_allowed_address);
2451 2356                  phys_match = match_prop(cur, DTD_ATTR_PHYSICAL,
2452 2357                      tabptr->zone_nwif_physical);
2453 2358                  mac_match = match_prop(cur, DTD_ATTR_MAC,
2454 2359                      tabptr->zone_nwif_mac);
2455 2360                  gnic_match = match_prop(cur, DTD_ATTR_GNIC,
2456 2361                      tabptr->zone_nwif_gnic);
2457 2362  
2458      -                if (((addr_match && allowed_addr_match) || mac_match ||
     2363 +                if ((addr_match || allowed_addr_match || mac_match ||
2459 2364                      gnic_match) && phys_match) {
2460 2365                          xmlUnlinkNode(cur);
2461 2366                          xmlFreeNode(cur);
2462 2367                          return (Z_OK);
2463 2368                  }
2464 2369          }
2465 2370          return (Z_NO_RESOURCE_ID);
2466 2371  }
2467 2372  
2468 2373  int
↓ open down ↓ 2391 lines elided ↑ open up ↑
4860 4765   * name.  The function returns Z_NO_ENTRY if the pool does not specify a thread
4861 4766   * scheduling class.
4862 4767   */
4863 4768  static int
4864 4769  get_pool_sched_class(char *poolname, char *class, int clsize)
4865 4770  {
4866 4771          int status;
4867 4772          pool_conf_t *poolconf;
4868 4773          pool_t *pool;
4869 4774          pool_elem_t *pe;
4870      -        pool_value_t *pv;
     4775 +        pool_value_t *pv = pool_value_alloc();
4871 4776          const char *sched_str;
4872 4777  
4873 4778          if (pool_get_status(&status) != PO_SUCCESS || status != POOL_ENABLED)
4874 4779                  return (Z_NO_POOL);
4875 4780  
4876 4781          if ((poolconf = pool_conf_alloc()) == NULL)
4877 4782                  return (Z_NO_POOL);
4878 4783  
4879 4784          if (pool_conf_open(poolconf, pool_dynamic_location(), PO_RDONLY) !=
4880 4785              PO_SUCCESS) {
4881 4786                  pool_conf_free(poolconf);
4882 4787                  return (Z_NO_POOL);
4883 4788          }
4884 4789  
4885 4790          if ((pool = pool_get_pool(poolconf, poolname)) == NULL) {
4886 4791                  (void) pool_conf_close(poolconf);
4887 4792                  pool_conf_free(poolconf);
4888 4793                  return (Z_NO_POOL);
4889 4794          }
4890 4795  
4891      -        if ((pv = pool_value_alloc()) == NULL) {
4892      -                (void) pool_conf_close(poolconf);
4893      -                pool_conf_free(poolconf);
4894      -                return (Z_NO_POOL);
4895      -        }
4896      -
4897 4796          pe = pool_to_elem(poolconf, pool);
4898 4797          if (pool_get_property(poolconf, pe, "pool.scheduler", pv) !=
4899 4798              POC_STRING) {
4900 4799                  (void) pool_conf_close(poolconf);
4901      -                pool_value_free(pv);
4902 4800                  pool_conf_free(poolconf);
4903 4801                  return (Z_NO_ENTRY);
4904 4802          }
4905 4803          (void) pool_value_get_string(pv, &sched_str);
4906 4804          (void) pool_conf_close(poolconf);
4907      -        pool_value_free(pv);
4908 4805          pool_conf_free(poolconf);
4909 4806          if (strlcpy(class, sched_str, clsize) >= clsize)
4910 4807                  return (Z_TOO_BIG);
4911 4808          return (Z_OK);
4912 4809  }
4913 4810  
4914 4811  /*
4915 4812   * Get the default scheduling class for the zone.  This will either be the
4916 4813   * class set on the zone's pool or the system default scheduling class.
4917 4814   */
↓ open down ↓ 1249 lines elided ↑ open up ↑
6167 6064                          break;
6168 6065          }
6169 6066          endzoneent(cookie);
6170 6067          return ((found) ? Z_OK : Z_NO_ZONE);
6171 6068  }
6172 6069  
6173 6070  int
6174 6071  zone_set_state(char *zone, zone_state_t state)
6175 6072  {
6176 6073          struct zoneent ze;
6177      -        int res;
6178      -        zone_state_t oldst = (zone_state_t)-1;
6179 6074  
6180 6075          if (state != ZONE_STATE_CONFIGURED && state != ZONE_STATE_INSTALLED &&
6181 6076              state != ZONE_STATE_INCOMPLETE)
6182 6077                  return (Z_INVAL);
6183 6078  
6184      -        (void) zone_get_state(zone, &oldst);
6185      -
6186 6079          bzero(&ze, sizeof (ze));
6187 6080          (void) strlcpy(ze.zone_name, zone, sizeof (ze.zone_name));
6188 6081          ze.zone_state = state;
6189 6082          (void) strlcpy(ze.zone_path, "", sizeof (ze.zone_path));
6190      -        res = putzoneent(&ze, PZE_MODIFY);
6191      -
6192      -        if (res == Z_OK) {
6193      -                zonecfg_notify_conf_change(zone, zone_state_str(oldst),
6194      -                    zone_state_str(state));
6195      -        }
6196      -
6197      -        return (res);
     6083 +        return (putzoneent(&ze, PZE_MODIFY));
6198 6084  }
6199 6085  
6200 6086  /*
6201 6087   * Get id (if any) for specified zone.  There are four possible outcomes:
6202 6088   * - If the string corresponds to the numeric id of an active (booted)
6203 6089   *   zone, sets *zip to the zone id and returns 0.
6204 6090   * - If the string corresponds to the name of an active (booted) zone,
6205 6091   *   sets *zip to the zone id and returns 0.
6206 6092   * - If the string is a name in the configuration but is not booted,
6207 6093   *   sets *zip to ZONE_ID_UNDEFINED and returns 0.
↓ open down ↓ 128 lines elided ↑ open up ↑
6336 6222          endzoneent(fp);
6337 6223          if (ze != NULL) {
6338 6224                  uuid_copy(uuid, ze->zone_uuid);
6339 6225                  free(ze);
6340 6226                  return (Z_OK);
6341 6227          } else {
6342 6228                  return (Z_NO_ZONE);
6343 6229          }
6344 6230  }
6345 6231  
6346      -/*
6347      - * Changes a zone's UUID to the given value. Returns an error if the UUID is
6348      - * malformed or if the zone cannot be located.
6349      - */
6350      -int
6351      -zonecfg_set_uuid(const char *zonename, const char *zonepath,
6352      -    const char *uuid)
6353      -{
6354      -        int err;
6355      -        struct zoneent ze;
6356      -
6357      -        bzero(&ze, sizeof (ze));
6358      -        ze.zone_state = -1;     /* Preserve existing state in index */
6359      -        (void) strlcpy(ze.zone_name, zonename, sizeof (ze.zone_name));
6360      -        (void) strlcpy(ze.zone_path, zonepath, sizeof (ze.zone_path));
6361      -        if (uuid_parse((char *)uuid, ze.zone_uuid) == -1)
6362      -                return (Z_INVALID_PROPERTY);
6363      -
6364      -        if ((err = putzoneent(&ze, PZE_MODIFY)) != Z_OK)
6365      -                return (err);
6366      -
6367      -        return (Z_OK);
6368      -}
6369      -
6370 6232  /*
6371 6233   * File-system convenience functions.
6372 6234   */
6373 6235  boolean_t
6374 6236  zonecfg_valid_fs_type(const char *type)
6375 6237  {
6376 6238          /*
6377 6239           * We already know which FS types don't work.
6378 6240           */
6379 6241          if (strcmp(type, "proc") == 0 ||
↓ open down ↓ 2165 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX