Print this page


Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/zoneadmd/vplat.c
          +++ new/usr/src/cmd/zoneadmd/vplat.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  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 (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2016, Joyent Inc.
  25   24   * Copyright (c) 2015 by Delphix. All rights reserved.
       25 + * Copyright 2016, Joyent Inc.
  26   26   */
  27   27  
  28   28  /*
  29   29   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  30   30   */
  31   31  
  32   32  /*
  33   33   * This module contains functions used to bring up and tear down the
  34   34   * Virtual Platform: [un]mounting file-systems, [un]plumbing network
  35   35   * interfaces, [un]configuring devices, establishing resource controls,
↓ open down ↓ 93 lines elided ↑ open up ↑
 129  129  
 130  130  #define V4_ADDR_LEN     32
 131  131  #define V6_ADDR_LEN     128
 132  132  
 133  133  #define RESOURCE_DEFAULT_OPTS \
 134  134          MNTOPT_RO "," MNTOPT_LOFS_NOSUB "," MNTOPT_NODEVICES
 135  135  
 136  136  #define DFSTYPES        "/etc/dfs/fstypes"
 137  137  #define MAXTNZLEN       2048
 138  138  
 139      -/* Number of times to retry unmounting if it fails */
 140      -#define UMOUNT_RETRIES  30
 141      -
 142  139  /* a reasonable estimate for the number of lwps per process */
 143  140  #define LWPS_PER_PROCESS        10
 144  141  
 145  142  /* for routing socket */
 146  143  static int rts_seqno = 0;
 147  144  
 148  145  /* mangled zone name when mounting in an alternate root environment */
 149  146  static char kernzone[ZONENAME_MAX];
 150  147  
 151  148  /* array of cached mount entries for resolve_lofs */
↓ open down ↓ 21 lines elided ↑ open up ↑
 173  170          {"zone.max-shm-ids",    "project.max-shm-ids"},
 174  171          {"zone.max-shm-memory", "project.max-shm-memory"},
 175  172          {NULL,                  NULL}
 176  173  };
 177  174  
 178  175  /* from libsocket, not in any header file */
 179  176  extern int getnetmaskbyaddr(struct in_addr, struct in_addr *);
 180  177  
 181  178  /* from zoneadmd */
 182  179  extern char query_hook[];
 183      -extern char post_statechg_hook[];
 184  180  
 185  181  /*
 186  182   * For each "net" resource configured in zonecfg, we track a zone_addr_list_t
 187  183   * node in a linked list that is sorted by linkid.  The list is constructed as
 188  184   * the xml configuration file is parsed, and the information
 189  185   * contained in each node is added to the kernel before the zone is
 190  186   * booted, to be retrieved and applied from within the exclusive-IP NGZ
 191  187   * on boot.
 192  188   */
 193  189  typedef struct zone_addr_list {
↓ open down ↓ 16 lines elided ↑ open up ↑
 210  206   * Private autofs system call
 211  207   */
 212  208  extern int _autofssys(int, void *);
 213  209  
 214  210  static int
 215  211  autofs_cleanup(zoneid_t zoneid)
 216  212  {
 217  213          /*
 218  214           * Ask autofs to unmount all trigger nodes in the given zone.
 219  215           */
 220      -        return (_autofssys(AUTOFS_UNMOUNTALL, (void *)((uintptr_t)zoneid)));
      216 +        return (_autofssys(AUTOFS_UNMOUNTALL, (void *)zoneid));
 221  217  }
 222  218  
 223  219  static void
 224  220  free_mnttable(struct mnttab *mnt_array, uint_t nelem)
 225  221  {
 226  222          uint_t i;
 227  223  
 228  224          if (mnt_array == NULL)
 229  225                  return;
 230  226          for (i = 0; i < nelem; i++) {
↓ open down ↓ 370 lines elided ↑ open up ↑
 601  597   */
 602  598  static void
 603  599  root_to_lu(zlog_t *zlogp, char *zroot, size_t zrootlen, boolean_t isresolved)
 604  600  {
 605  601          if (!isresolved && zonecfg_in_alt_root())
 606  602                  resolve_lofs(zlogp, zroot, zrootlen);
 607  603          (void) strcpy(strrchr(zroot, '/') + 1, "lu");
 608  604  }
 609  605  
 610  606  /*
 611      - * Perform brand-specific cleanup if we are unable to unmount a FS.
 612      - */
 613      -static void
 614      -brand_umount_cleanup(zlog_t *zlogp, char *path)
 615      -{
 616      -        char cmdbuf[2 * MAXPATHLEN];
 617      -
 618      -        if (post_statechg_hook[0] == '\0')
 619      -                return;
 620      -
 621      -        if (snprintf(cmdbuf, sizeof (cmdbuf), "%s %d %d %s", post_statechg_hook,
 622      -            ZONE_STATE_DOWN, Z_UNMOUNT, path) > sizeof (cmdbuf))
 623      -                return;
 624      -
 625      -        (void) do_subproc(zlogp, cmdbuf, NULL, B_FALSE);
 626      -}
 627      -
 628      -/*
 629  607   * The general strategy for unmounting filesystems is as follows:
 630  608   *
 631  609   * - Remote filesystems may be dead, and attempting to contact them as
 632  610   * part of a regular unmount may hang forever; we want to always try to
 633  611   * forcibly unmount such filesystems and only fall back to regular
 634  612   * unmounts if the filesystem doesn't support forced unmounts.
 635  613   *
 636  614   * - We don't want to unnecessarily corrupt metadata on local
 637  615   * filesystems (ie UFS), so we want to start off with graceful unmounts,
 638  616   * and only escalate to doing forced unmounts if we get stuck.
↓ open down ↓ 12 lines elided ↑ open up ↑
 651  629   * then we bail and are unable to teardown the zone.  If it succeeds,
 652  630   * we're no longer stuck so we continue with our policy of trying
 653  631   * graceful mounts first.
 654  632   *
 655  633   * Zone must be down (ie, no processes or threads active).
 656  634   */
 657  635  static int
 658  636  unmount_filesystems(zlog_t *zlogp, zoneid_t zoneid, boolean_t unmount_cmd)
 659  637  {
 660  638          int error = 0;
 661      -        int fail = 0;
 662  639          FILE *mnttab;
 663  640          struct mnttab *mnts;
 664  641          uint_t nmnt;
 665  642          char zroot[MAXPATHLEN + 1];
 666  643          size_t zrootlen;
 667  644          uint_t oldcount = UINT_MAX;
 668  645          boolean_t stuck = B_FALSE;
 669  646          char **remote_fstypes = NULL;
 670  647  
 671  648          if (zone_get_rootpath(zone_name, zroot, sizeof (zroot)) != Z_OK) {
↓ open down ↓ 67 lines elided ↑ open up ↑
 739  716                                  if (umount2(path, MS_FORCE) == 0)
 740  717                                          unmounted = B_TRUE;
 741  718                          }
 742  719                          /*
 743  720                           * Try forced unmount if we're stuck.
 744  721                           */
 745  722                          if (stuck) {
 746  723                                  if (umount2(path, MS_FORCE) == 0) {
 747  724                                          unmounted = B_TRUE;
 748  725                                          stuck = B_FALSE;
 749      -                                        fail = 0;
 750  726                                  } else {
 751  727                                          /*
 752      -                                         * We may hit a failure here if there
 753      -                                         * is an app in the GZ with an open
 754      -                                         * pipe into the zone (commonly into
 755      -                                         * the zone's /var/run).  This type
 756      -                                         * of app will notice the closed
 757      -                                         * connection and cleanup, but it may
 758      -                                         * take a while and we have no easy
 759      -                                         * way to notice that.  To deal with
 760      -                                         * this case, we will wait and retry
 761      -                                         * a few times before we give up.
      728 +                                         * The first failure indicates a
      729 +                                         * mount we won't be able to get
      730 +                                         * rid of automatically, so we
      731 +                                         * bail.
 762  732                                           */
 763      -                                        fail++;
 764      -                                        if (fail < (UMOUNT_RETRIES - 1)) {
 765      -                                                zerror(zlogp, B_FALSE,
 766      -                                                    "unable to unmount '%s', "
 767      -                                                    "retrying in 2 seconds",
 768      -                                                    path);
 769      -                                                (void) sleep(2);
 770      -                                        } else if (fail > UMOUNT_RETRIES) {
 771      -                                                error++;
 772      -                                                zerror(zlogp, B_FALSE,
 773      -                                                    "unmount of '%s' failed",
 774      -                                                    path);
 775      -                                                free_mnttable(mnts, nmnt);
 776      -                                                goto out;
 777      -                                        } else {
 778      -                                                /* Try the hook 2 times */
 779      -                                                brand_umount_cleanup(zlogp,
 780      -                                                    path);
 781      -                                        }
      733 +                                        error++;
      734 +                                        zerror(zlogp, B_FALSE,
      735 +                                            "unable to unmount '%s'", path);
      736 +                                        free_mnttable(mnts, nmnt);
      737 +                                        goto out;
 782  738                                  }
 783  739                          }
 784  740                          /*
 785  741                           * Try regular unmounts for everything else.
 786  742                           */
 787  743                          if (!unmounted && umount2(path, 0) != 0)
 788  744                                  newcount++;
 789  745                  }
 790  746                  free_mnttable(mnts, nmnt);
 791  747  
↓ open down ↓ 317 lines elided ↑ open up ↑
1109 1065  mount_one_dev_symlink_cb(void *arg, const char *source, const char *target)
1110 1066  {
1111 1067          di_prof_t prof = arg;
1112 1068  
1113 1069          return (di_prof_add_symlink(prof, source, target));
1114 1070  }
1115 1071  
1116 1072  int
1117 1073  vplat_get_iptype(zlog_t *zlogp, zone_iptype_t *iptypep)
1118 1074  {
1119      -        if (zonecfg_get_iptype(snap_hndl, iptypep) != Z_OK) {
     1075 +        zone_dochandle_t handle;
     1076 +
     1077 +        if ((handle = zonecfg_init_handle()) == NULL) {
     1078 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     1079 +                return (-1);
     1080 +        }
     1081 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     1082 +                zerror(zlogp, B_FALSE, "invalid configuration");
     1083 +                zonecfg_fini_handle(handle);
     1084 +                return (-1);
     1085 +        }
     1086 +        if (zonecfg_get_iptype(handle, iptypep) != Z_OK) {
1120 1087                  zerror(zlogp, B_FALSE, "invalid ip-type configuration");
     1088 +                zonecfg_fini_handle(handle);
1121 1089                  return (-1);
1122 1090          }
     1091 +        zonecfg_fini_handle(handle);
1123 1092          return (0);
1124 1093  }
1125 1094  
1126 1095  /*
1127 1096   * Apply the standard lists of devices/symlinks/mappings and the user-specified
1128 1097   * list of devices (via zonecfg) to the /dev filesystem.  The filesystem will
1129 1098   * use these as a profile/filter to determine what exists in /dev.
1130 1099   */
1131 1100  static int
1132 1101  mount_one_dev(zlog_t *zlogp, char *devpath, zone_mnt_t mount_cmd)
1133 1102  {
1134 1103          char                    brand[MAXNAMELEN];
     1104 +        zone_dochandle_t        handle = NULL;
1135 1105          brand_handle_t          bh = NULL;
1136 1106          struct zone_devtab      ztab;
1137 1107          di_prof_t               prof = NULL;
1138 1108          int                     err;
1139 1109          int                     retval = -1;
1140 1110          zone_iptype_t           iptype;
1141      -        const char              *curr_iptype = NULL;
     1111 +        const char              *curr_iptype;
1142 1112  
1143 1113          if (di_prof_init(devpath, &prof)) {
1144 1114                  zerror(zlogp, B_TRUE, "failed to initialize profile");
1145 1115                  goto cleanup;
1146 1116          }
1147 1117  
1148 1118          /*
1149 1119           * Get a handle to the brand info for this zone.
1150 1120           * If we are mounting the zone, then we must always use the default
1151 1121           * brand device mounts.
↓ open down ↓ 14 lines elided ↑ open up ↑
1166 1136                  goto cleanup;
1167 1137          }
1168 1138          switch (iptype) {
1169 1139          case ZS_SHARED:
1170 1140                  curr_iptype = "shared";
1171 1141                  break;
1172 1142          case ZS_EXCLUSIVE:
1173 1143                  curr_iptype = "exclusive";
1174 1144                  break;
1175 1145          }
1176      -        if (curr_iptype == NULL)
1177      -                abort();
1178 1146  
1179 1147          if (brand_platform_iter_devices(bh, zone_name,
1180 1148              mount_one_dev_device_cb, prof, curr_iptype) != 0) {
1181 1149                  zerror(zlogp, B_TRUE, "failed to add standard device");
1182 1150                  goto cleanup;
1183 1151          }
1184 1152  
1185 1153          if (brand_platform_iter_link(bh,
1186 1154              mount_one_dev_symlink_cb, prof) != 0) {
1187 1155                  zerror(zlogp, B_TRUE, "failed to add standard symlink");
1188 1156                  goto cleanup;
1189 1157          }
1190 1158  
1191 1159          /* Add user-specified devices and directories */
1192      -        if ((err = zonecfg_setdevent(snap_hndl)) != 0) {
     1160 +        if ((handle = zonecfg_init_handle()) == NULL) {
     1161 +                zerror(zlogp, B_FALSE, "can't initialize zone handle");
     1162 +                goto cleanup;
     1163 +        }
     1164 +        if ((err = zonecfg_get_handle(zone_name, handle)) != 0) {
     1165 +                zerror(zlogp, B_FALSE, "can't get handle for zone "
     1166 +                    "%s: %s", zone_name, zonecfg_strerror(err));
     1167 +                goto cleanup;
     1168 +        }
     1169 +        if ((err = zonecfg_setdevent(handle)) != 0) {
1193 1170                  zerror(zlogp, B_FALSE, "%s: %s", zone_name,
1194 1171                      zonecfg_strerror(err));
1195 1172                  goto cleanup;
1196 1173          }
1197      -        while (zonecfg_getdevent(snap_hndl, &ztab) == Z_OK) {
     1174 +        while (zonecfg_getdevent(handle, &ztab) == Z_OK) {
1198 1175                  if (di_prof_add_dev(prof, ztab.zone_dev_match)) {
1199 1176                          zerror(zlogp, B_TRUE, "failed to add "
1200 1177                              "user-specified device");
1201 1178                          goto cleanup;
1202 1179                  }
1203 1180          }
1204      -        (void) zonecfg_enddevent(snap_hndl);
     1181 +        (void) zonecfg_enddevent(handle);
1205 1182  
1206 1183          /* Send profile to kernel */
1207 1184          if (di_prof_commit(prof)) {
1208 1185                  zerror(zlogp, B_TRUE, "failed to commit profile");
1209 1186                  goto cleanup;
1210 1187          }
1211 1188  
1212 1189          retval = 0;
1213 1190  
1214 1191  cleanup:
1215 1192          if (bh != NULL)
1216 1193                  brand_close(bh);
     1194 +        if (handle != NULL)
     1195 +                zonecfg_fini_handle(handle);
1217 1196          if (prof)
1218 1197                  di_prof_fini(prof);
1219 1198          return (retval);
1220 1199  }
1221 1200  
1222 1201  static int
1223 1202  mount_one(zlog_t *zlogp, struct zone_fstab *fsptr, const char *rootpath,
1224 1203      zone_mnt_t mount_cmd)
1225 1204  {
1226 1205          char path[MAXPATHLEN];
↓ open down ↓ 473 lines elided ↑ open up ↑
1700 1679  }
1701 1680  
1702 1681  static int
1703 1682  mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd)
1704 1683  {
1705 1684          char rootpath[MAXPATHLEN];
1706 1685          char brand[MAXNAMELEN];
1707 1686          char luroot[MAXPATHLEN];
1708 1687          int i, num_fs = 0;
1709 1688          struct zone_fstab *fs_ptr = NULL;
     1689 +        zone_dochandle_t handle = NULL;
1710 1690          zone_state_t zstate;
1711 1691          brand_handle_t bh;
1712 1692          plat_gmount_cb_data_t cb;
1713 1693  
1714 1694          if (zone_get_state(zone_name, &zstate) != Z_OK ||
1715 1695              (zstate != ZONE_STATE_READY && zstate != ZONE_STATE_MOUNTED)) {
1716 1696                  zerror(zlogp, B_FALSE,
1717 1697                      "zone must be in '%s' or '%s' state to mount file-systems",
1718 1698                      zone_state_str(ZONE_STATE_READY),
1719 1699                      zone_state_str(ZONE_STATE_MOUNTED));
1720 1700                  goto bad;
1721 1701          }
1722 1702  
1723 1703          if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) {
1724 1704                  zerror(zlogp, B_TRUE, "unable to determine zone root");
1725 1705                  goto bad;
1726 1706          }
1727 1707  
1728      -        if (zonecfg_setfsent(snap_hndl) != Z_OK) {
     1708 +        if ((handle = zonecfg_init_handle()) == NULL) {
     1709 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     1710 +                goto bad;
     1711 +        }
     1712 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK ||
     1713 +            zonecfg_setfsent(handle) != Z_OK) {
1729 1714                  zerror(zlogp, B_FALSE, "invalid configuration");
1730 1715                  goto bad;
1731 1716          }
1732 1717  
1733 1718          /*
1734 1719           * If we are mounting the zone, then we must always use the default
1735 1720           * brand global mounts.
1736 1721           */
1737 1722          if (ALT_MOUNT(mount_cmd)) {
1738 1723                  (void) strlcpy(brand, default_brand, sizeof (brand));
1739 1724          } else {
1740 1725                  (void) strlcpy(brand, brand_name, sizeof (brand));
1741 1726          }
1742 1727  
1743 1728          /* Get a handle to the brand info for this zone */
1744 1729          if ((bh = brand_open(brand)) == NULL) {
1745 1730                  zerror(zlogp, B_FALSE, "unable to determine zone brand");
     1731 +                zonecfg_fini_handle(handle);
1746 1732                  return (-1);
1747 1733          }
1748 1734  
1749 1735          /*
1750 1736           * Get the list of global filesystems to mount from the brand
1751 1737           * configuration.
1752 1738           */
1753 1739          cb.pgcd_zlogp = zlogp;
1754 1740          cb.pgcd_fs_tab = &fs_ptr;
1755 1741          cb.pgcd_num_fs = &num_fs;
1756 1742          if (brand_platform_iter_gmounts(bh, zone_name, zonepath,
1757 1743              plat_gmount_cb, &cb) != 0) {
1758 1744                  zerror(zlogp, B_FALSE, "unable to mount filesystems");
1759 1745                  brand_close(bh);
     1746 +                zonecfg_fini_handle(handle);
1760 1747                  return (-1);
1761 1748          }
1762 1749          brand_close(bh);
1763 1750  
1764 1751          /*
1765 1752           * Iterate through the rest of the filesystems. Sort them all,
1766 1753           * then mount them in sorted order. This is to make sure the
1767 1754           * higher level directories (e.g., /usr) get mounted before
1768 1755           * any beneath them (e.g., /usr/local).
1769 1756           */
1770      -        if (mount_filesystems_fsent(snap_hndl, zlogp, &fs_ptr, &num_fs,
     1757 +        if (mount_filesystems_fsent(handle, zlogp, &fs_ptr, &num_fs,
1771 1758              mount_cmd) != 0)
1772 1759                  goto bad;
1773 1760  
     1761 +        zonecfg_fini_handle(handle);
     1762 +        handle = NULL;
     1763 +
1774 1764          /*
1775 1765           * Normally when we mount a zone all the zone filesystems
1776 1766           * get mounted relative to rootpath, which is usually
1777 1767           * <zonepath>/root.  But when mounting a zone for administration
1778 1768           * purposes via the zone "mount" state, build_mounted_pre_var()
1779 1769           * updates rootpath to be <zonepath>/lu/a so we'll mount all
1780 1770           * the zones filesystems there instead.
1781 1771           *
1782 1772           * build_mounted_pre_var() and build_mounted_post_var() will
1783 1773           * also do some extra work to create directories and lofs mount
↓ open down ↓ 75 lines elided ↑ open up ↑
1859 1849                  goto bad;
1860 1850  
1861 1851          free_fs_data(fs_ptr, num_fs);
1862 1852  
1863 1853          /*
1864 1854           * Everything looks fine.
1865 1855           */
1866 1856          return (0);
1867 1857  
1868 1858  bad:
     1859 +        if (handle != NULL)
     1860 +                zonecfg_fini_handle(handle);
1869 1861          free_fs_data(fs_ptr, num_fs);
1870 1862          return (-1);
1871 1863  }
1872 1864  
1873 1865  /* caller makes sure neither parameter is NULL */
1874 1866  static int
1875 1867  addr2netmask(char *prefixstr, int maxprefixlen, uchar_t *maskstr)
1876 1868  {
1877 1869          int prefixlen;
1878 1870  
↓ open down ↓ 335 lines elided ↑ open up ↑
2214 2206           * Finally we set the interface address.
2215 2207           */
2216 2208          laddr = lifr.lifr_addr;
2217 2209          (void) strlcpy(lifr.lifr_name, nwiftabptr->zone_nwif_physical,
2218 2210              sizeof (lifr.lifr_name));
2219 2211          (void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
2220 2212  
2221 2213          if (ioctl(s, SIOCLIFADDIF, (caddr_t)&lifr) < 0) {
2222 2214                  /*
2223 2215                   * Here, we know that the interface can't be brought up.
     2216 +                 * A similar warning message was already printed out to
     2217 +                 * the console by zoneadm(1M) so instead we log the
     2218 +                 * message to syslog and continue.
2224 2219                   */
     2220 +                zerror(&logsys, B_TRUE, "WARNING: skipping network interface "
     2221 +                    "'%s' which may not be present/plumbed in the "
     2222 +                    "global zone.", lifr.lifr_name);
2225 2223                  (void) close(s);
2226 2224                  return (Z_OK);
2227 2225          }
2228 2226  
2229 2227          /* Preserve literal IPv4 address for later potential printing. */
2230 2228          if (af == AF_INET)
2231 2229                  (void) inet_ntop(AF_INET, &in4, addrstr4, INET_ADDRSTRLEN);
2232 2230  
2233 2231          lifr.lifr_zoneid = zone_id;
2234 2232          if (ioctl(s, SIOCSLIFZONE, (caddr_t)&lifr) < 0) {
↓ open down ↓ 192 lines elided ↑ open up ↑
2427 2425   * Sets up network interfaces based on information from the zone configuration.
2428 2426   * IPv4 and IPv6 loopback interfaces are set up "for free", modeling the global
2429 2427   * system.
2430 2428   *
2431 2429   * If anything goes wrong, we log a general error message, attempt to tear down
2432 2430   * whatever we set up, and return an error.
2433 2431   */
2434 2432  static int
2435 2433  configure_shared_network_interfaces(zlog_t *zlogp)
2436 2434  {
     2435 +        zone_dochandle_t handle;
2437 2436          struct zone_nwiftab nwiftab, loopback_iftab;
2438 2437          zoneid_t zoneid;
2439 2438  
2440 2439          if ((zoneid = getzoneidbyname(zone_name)) == ZONE_ID_UNDEFINED) {
2441 2440                  zerror(zlogp, B_TRUE, "unable to get zoneid");
2442 2441                  return (-1);
2443 2442          }
2444 2443  
2445      -        if (zonecfg_setnwifent(snap_hndl) == Z_OK) {
     2444 +        if ((handle = zonecfg_init_handle()) == NULL) {
     2445 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     2446 +                return (-1);
     2447 +        }
     2448 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     2449 +                zerror(zlogp, B_FALSE, "invalid configuration");
     2450 +                zonecfg_fini_handle(handle);
     2451 +                return (-1);
     2452 +        }
     2453 +        if (zonecfg_setnwifent(handle) == Z_OK) {
2446 2454                  for (;;) {
2447      -                        if (zonecfg_getnwifent(snap_hndl, &nwiftab) != Z_OK)
     2455 +                        if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK)
2448 2456                                  break;
2449      -                        nwifent_free_attrs(&nwiftab);
2450 2457                          if (configure_one_interface(zlogp, zoneid, &nwiftab) !=
2451 2458                              Z_OK) {
2452      -                                (void) zonecfg_endnwifent(snap_hndl);
     2459 +                                (void) zonecfg_endnwifent(handle);
     2460 +                                zonecfg_fini_handle(handle);
2453 2461                                  return (-1);
2454 2462                          }
2455 2463                  }
2456      -                (void) zonecfg_endnwifent(snap_hndl);
     2464 +                (void) zonecfg_endnwifent(handle);
2457 2465          }
     2466 +        zonecfg_fini_handle(handle);
2458 2467          if (is_system_labeled()) {
2459 2468                  /*
2460 2469                   * Labeled zones share the loopback interface
2461 2470                   * so it is not plumbed for shared stack instances.
2462 2471                   */
2463 2472                  return (0);
2464 2473          }
2465 2474          (void) strlcpy(loopback_iftab.zone_nwif_physical, "lo0",
2466 2475              sizeof (loopback_iftab.zone_nwif_physical));
2467 2476          (void) strlcpy(loopback_iftab.zone_nwif_address, "127.0.0.1",
↓ open down ↓ 426 lines elided ↑ open up ↑
2894 2903          zone_addr_list_t *ptr, *new;
2895 2904  
2896 2905          for (ptr = zalist; ptr != NULL; ) {
2897 2906                  new = ptr;
2898 2907                  ptr = ptr->za_next;
2899 2908                  free(new);
2900 2909          }
2901 2910  }
2902 2911  
2903 2912  /*
     2913 + * For IP networking, we need to use the illumos-native device tree.  For most
     2914 + * zones, this is $ZONEROOT/dev.  For LX ones, it's $ZONEROOT/native/dev.
     2915 + * Return the appropriate post-$ZONEROOT path.
     2916 + */
     2917 +static char *
     2918 +get_brand_dev(void)
     2919 +{
     2920 +        static char *lxpath = "/native/dev";
     2921 +        /* Cheesy hard-coding of strlen("/native") */
     2922 +        char *default_path = lxpath + 7;
     2923 +
     2924 +        /* LX zones are the exception... */
     2925 +        if (strcmp(brand_name, "lx") == 0)
     2926 +                return (lxpath);
     2927 +
     2928 +        return (default_path);
     2929 +}
     2930 +
     2931 +/*
2904 2932   * Add the kernel access control information for the interface names.
2905 2933   * If anything goes wrong, we log a general error message, attempt to tear down
2906 2934   * whatever we set up, and return an error.
2907 2935   */
2908 2936  static int
2909 2937  configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid)
2910 2938  {
     2939 +        zone_dochandle_t handle;
2911 2940          struct zone_nwiftab nwiftab;
2912 2941          char rootpath[MAXPATHLEN];
2913 2942          char path[MAXPATHLEN];
2914 2943          datalink_id_t linkid;
2915 2944          di_prof_t prof = NULL;
2916 2945          boolean_t added = B_FALSE;
2917 2946          zone_addr_list_t *zalist = NULL, *new;
2918 2947  
2919      -        if (zonecfg_setnwifent(snap_hndl) != Z_OK)
     2948 +        if ((handle = zonecfg_init_handle()) == NULL) {
     2949 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     2950 +                return (-1);
     2951 +        }
     2952 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     2953 +                zerror(zlogp, B_FALSE, "invalid configuration");
     2954 +                zonecfg_fini_handle(handle);
     2955 +                return (-1);
     2956 +        }
     2957 +
     2958 +        if (zonecfg_setnwifent(handle) != Z_OK) {
     2959 +                zonecfg_fini_handle(handle);
2920 2960                  return (0);
     2961 +        }
2921 2962  
2922 2963          for (;;) {
2923      -                if (zonecfg_getnwifent(snap_hndl, &nwiftab) != Z_OK)
     2964 +                if (zonecfg_getnwifent(handle, &nwiftab) != Z_OK)
2924 2965                          break;
2925 2966  
2926      -                nwifent_free_attrs(&nwiftab);
2927 2967                  if (prof == NULL) {
2928 2968                          if (zone_get_devroot(zone_name, rootpath,
2929 2969                              sizeof (rootpath)) != Z_OK) {
2930      -                                (void) zonecfg_endnwifent(snap_hndl);
     2970 +                                (void) zonecfg_endnwifent(handle);
     2971 +                                zonecfg_fini_handle(handle);
2931 2972                                  zerror(zlogp, B_TRUE,
2932 2973                                      "unable to determine dev root");
2933 2974                                  return (-1);
2934 2975                          }
2935 2976                          (void) snprintf(path, sizeof (path), "%s%s", rootpath,
2936      -                            "/dev");
     2977 +                            get_brand_dev());
2937 2978                          if (di_prof_init(path, &prof) != 0) {
2938      -                                (void) zonecfg_endnwifent(snap_hndl);
     2979 +                                (void) zonecfg_endnwifent(handle);
     2980 +                                zonecfg_fini_handle(handle);
2939 2981                                  zerror(zlogp, B_TRUE,
2940 2982                                      "failed to initialize profile");
2941 2983                                  return (-1);
2942 2984                          }
2943 2985                  }
2944 2986  
2945 2987                  /*
2946 2988                   * Create the /dev entry for backward compatibility.
2947 2989                   * Only create the /dev entry if it's not in use.
2948 2990                   * Note that the zone still boots when the assigned
↓ open down ↓ 3 lines elided ↑ open up ↑
2952 2994                   * vanity named aggregations).  The /dev entry is not
2953 2995                   * created in that case.  The /dev/net entry is always
2954 2996                   * accessible.
2955 2997                   */
2956 2998                  if (dladm_name2info(dld_handle, nwiftab.zone_nwif_physical,
2957 2999                      &linkid, NULL, NULL, NULL) == DLADM_STATUS_OK &&
2958 3000                      add_datalink(zlogp, zone_name, linkid,
2959 3001                      nwiftab.zone_nwif_physical) == 0) {
2960 3002                          added = B_TRUE;
2961 3003                  } else {
2962      -                        /*
2963      -                         * Failed to add network device, but the brand hook
2964      -                         * might be doing this for us, so keep silent.
2965      -                         */
2966      -                        continue;
     3004 +                        (void) zonecfg_endnwifent(handle);
     3005 +                        zonecfg_fini_handle(handle);
     3006 +                        zerror(zlogp, B_TRUE, "failed to add network device");
     3007 +                        return (-1);
2967 3008                  }
2968 3009                  /* set up the new IP interface, and add them all later */
2969 3010                  new = malloc(sizeof (*new));
2970 3011                  if (new == NULL) {
2971 3012                          zerror(zlogp, B_TRUE, "no memory for %s",
2972 3013                              nwiftab.zone_nwif_physical);
     3014 +                        zonecfg_fini_handle(handle);
2973 3015                          free_ip_interface(zalist);
2974 3016                  }
2975 3017                  bzero(new, sizeof (*new));
2976 3018                  new->za_nwiftab = nwiftab;
2977 3019                  new->za_linkid = linkid;
2978 3020                  zalist = add_ip_interface(zalist, new);
2979 3021          }
2980 3022          if (zalist != NULL) {
2981 3023                  if ((errno = add_net(zlogp, zoneid, zalist)) != 0) {
2982      -                        (void) zonecfg_endnwifent(snap_hndl);
     3024 +                        (void) zonecfg_endnwifent(handle);
     3025 +                        zonecfg_fini_handle(handle);
2983 3026                          zerror(zlogp, B_TRUE, "failed to add address");
2984 3027                          free_ip_interface(zalist);
2985 3028                          return (-1);
2986 3029                  }
2987 3030                  free_ip_interface(zalist);
2988 3031          }
2989      -        (void) zonecfg_endnwifent(snap_hndl);
     3032 +        (void) zonecfg_endnwifent(handle);
     3033 +        zonecfg_fini_handle(handle);
2990 3034  
2991 3035          if (prof != NULL && added) {
2992 3036                  if (di_prof_commit(prof) != 0) {
2993 3037                          zerror(zlogp, B_TRUE, "failed to commit profile");
2994 3038                          return (-1);
2995 3039                  }
2996 3040          }
2997 3041          if (prof != NULL)
2998 3042                  di_prof_fini(prof);
2999 3043  
↓ open down ↓ 115 lines elided ↑ open up ↑
3115 3159  
3116 3160          for (i = 0, dllink = dllinks; i < dlnum; i++, dllink++) {
3117 3161                  char dlerr[DLADM_STRSIZE];
3118 3162  
3119 3163                  dlstatus = dladm_set_linkprop(dld_handle, *dllink,
3120 3164                      "protection", NULL, 0, DLADM_OPT_ACTIVE);
3121 3165                  if (dlstatus == DLADM_STATUS_NOTFOUND) {
3122 3166                          /* datalink does not belong to the GZ */
3123 3167                          continue;
3124 3168                  }
3125      -                if (dlstatus != DLADM_STATUS_OK)
     3169 +                if (dlstatus != DLADM_STATUS_OK) {
3126 3170                          zerror(zlogp, B_FALSE,
3127      -                            "clear 'protection' link property: %s",
3128 3171                              dladm_status2str(dlstatus, dlerr));
3129      -
     3172 +                        free(dllinks);
     3173 +                        return (-1);
     3174 +                }
3130 3175                  dlstatus = dladm_set_linkprop(dld_handle, *dllink,
3131 3176                      "allowed-ips", NULL, 0, DLADM_OPT_ACTIVE);
3132      -                if (dlstatus != DLADM_STATUS_OK)
     3177 +                if (dlstatus != DLADM_STATUS_OK) {
3133 3178                          zerror(zlogp, B_FALSE,
3134      -                            "clear 'allowed-ips' link property: %s",
3135 3179                              dladm_status2str(dlstatus, dlerr));
     3180 +                        free(dllinks);
     3181 +                        return (-1);
     3182 +                }
3136 3183          }
3137 3184          free(dllinks);
3138 3185          return (0);
3139 3186  }
3140 3187  
3141 3188  static int
     3189 +unconfigure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid)
     3190 +{
     3191 +        int dlnum = 0;
     3192 +
     3193 +        /*
     3194 +         * The kernel shutdown callback for the dls module should have removed
     3195 +         * all datalinks from this zone.  If any remain, then there's a
     3196 +         * problem.
     3197 +         */
     3198 +        if (zone_list_datalink(zoneid, &dlnum, NULL) != 0) {
     3199 +                zerror(zlogp, B_TRUE, "unable to list network interfaces");
     3200 +                return (-1);
     3201 +        }
     3202 +        if (dlnum != 0) {
     3203 +                zerror(zlogp, B_FALSE,
     3204 +                    "datalinks remain in zone after shutdown");
     3205 +                return (-1);
     3206 +        }
     3207 +        return (0);
     3208 +}
     3209 +
     3210 +static int
3142 3211  tcp_abort_conn(zlog_t *zlogp, zoneid_t zoneid,
3143 3212      const struct sockaddr_storage *local, const struct sockaddr_storage *remote)
3144 3213  {
3145 3214          int fd;
3146 3215          struct strioctl ioc;
3147 3216          tcp_ioc_abort_conn_t conn;
3148 3217          int error;
3149 3218  
3150 3219          conn.ac_local = *local;
3151 3220          conn.ac_remote = *remote;
↓ open down ↓ 61 lines elided ↑ open up ↑
3213 3282  
3214 3283          if ((error = tcp_abort_conn(zlogp, zoneid, &l, &r)) != 0)
3215 3284                  return (error);
3216 3285          return (0);
3217 3286  }
3218 3287  
3219 3288  static int
3220 3289  get_privset(zlog_t *zlogp, priv_set_t *privs, zone_mnt_t mount_cmd)
3221 3290  {
3222 3291          int error = -1;
     3292 +        zone_dochandle_t handle;
3223 3293          char *privname = NULL;
3224 3294  
     3295 +        if ((handle = zonecfg_init_handle()) == NULL) {
     3296 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     3297 +                return (-1);
     3298 +        }
     3299 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     3300 +                zerror(zlogp, B_FALSE, "invalid configuration");
     3301 +                zonecfg_fini_handle(handle);
     3302 +                return (-1);
     3303 +        }
     3304 +
3225 3305          if (ALT_MOUNT(mount_cmd)) {
3226 3306                  zone_iptype_t   iptype;
3227      -                const char      *curr_iptype = NULL;
     3307 +                const char      *curr_iptype;
3228 3308  
3229      -                if (zonecfg_get_iptype(snap_hndl, &iptype) != Z_OK) {
     3309 +                if (zonecfg_get_iptype(handle, &iptype) != Z_OK) {
3230 3310                          zerror(zlogp, B_TRUE, "unable to determine ip-type");
     3311 +                        zonecfg_fini_handle(handle);
3231 3312                          return (-1);
3232 3313                  }
3233 3314  
3234 3315                  switch (iptype) {
3235 3316                  case ZS_SHARED:
3236 3317                          curr_iptype = "shared";
3237 3318                          break;
3238 3319                  case ZS_EXCLUSIVE:
3239 3320                          curr_iptype = "exclusive";
3240 3321                          break;
3241 3322                  }
3242 3323  
3243      -                if (zonecfg_default_privset(privs, curr_iptype) == Z_OK)
     3324 +                if (zonecfg_default_privset(privs, curr_iptype) == Z_OK) {
     3325 +                        zonecfg_fini_handle(handle);
3244 3326                          return (0);
3245      -
     3327 +                }
3246 3328                  zerror(zlogp, B_FALSE,
3247 3329                      "failed to determine the zone's default privilege set");
     3330 +                zonecfg_fini_handle(handle);
3248 3331                  return (-1);
3249 3332          }
3250 3333  
3251      -        switch (zonecfg_get_privset(snap_hndl, privs, &privname)) {
     3334 +        switch (zonecfg_get_privset(handle, privs, &privname)) {
3252 3335          case Z_OK:
3253 3336                  error = 0;
3254 3337                  break;
3255 3338          case Z_PRIV_PROHIBITED:
3256 3339                  zerror(zlogp, B_FALSE, "privilege \"%s\" is not permitted "
3257 3340                      "within the zone's privilege set", privname);
3258 3341                  break;
3259 3342          case Z_PRIV_REQUIRED:
3260 3343                  zerror(zlogp, B_FALSE, "required privilege \"%s\" is missing "
3261 3344                      "from the zone's privilege set", privname);
↓ open down ↓ 2 lines elided ↑ open up ↑
3264 3347                  zerror(zlogp, B_FALSE, "unknown privilege \"%s\" specified "
3265 3348                      "in the zone's privilege set", privname);
3266 3349                  break;
3267 3350          default:
3268 3351                  zerror(zlogp, B_FALSE, "failed to determine the zone's "
3269 3352                      "privilege set");
3270 3353                  break;
3271 3354          }
3272 3355  
3273 3356          free(privname);
     3357 +        zonecfg_fini_handle(handle);
3274 3358          return (error);
3275 3359  }
3276 3360  
3277 3361  static char *
3278 3362  zone_proj_rctl(const char *name)
3279 3363  {
3280 3364          int i;
3281 3365  
3282 3366          for (i = 0; zone_proj_rctl_map[i].zpr_zone_rctl != NULL; i++) {
3283 3367                  if (strcmp(name, zone_proj_rctl_map[i].zpr_zone_rctl) == 0) {
↓ open down ↓ 5 lines elided ↑ open up ↑
3289 3373  
3290 3374  static int
3291 3375  get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep)
3292 3376  {
3293 3377          nvlist_t *nvl = NULL;
3294 3378          char *nvl_packed = NULL;
3295 3379          size_t nvl_size = 0;
3296 3380          nvlist_t **nvlv = NULL;
3297 3381          int rctlcount = 0;
3298 3382          int error = -1;
     3383 +        zone_dochandle_t handle;
3299 3384          struct zone_rctltab rctltab;
3300 3385          rctlblk_t *rctlblk = NULL;
3301 3386          uint64_t maxlwps;
3302 3387          uint64_t maxprocs;
3303 3388          int rproc, rlwp;
3304 3389  
3305 3390          *bufp = NULL;
3306 3391          *bufsizep = 0;
3307 3392  
     3393 +        if ((handle = zonecfg_init_handle()) == NULL) {
     3394 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     3395 +                return (-1);
     3396 +        }
     3397 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     3398 +                zerror(zlogp, B_FALSE, "invalid configuration");
     3399 +                zonecfg_fini_handle(handle);
     3400 +                return (-1);
     3401 +        }
     3402 +
3308 3403          rctltab.zone_rctl_valptr = NULL;
3309 3404          if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
3310 3405                  zerror(zlogp, B_TRUE, "%s failed", "nvlist_alloc");
3311 3406                  goto out;
3312 3407          }
3313 3408  
3314 3409          /*
3315 3410           * Allow the administrator to control both the maximum number of
3316 3411           * process table slots, and the maximum number of lwps, with a single
3317 3412           * max-processes or max-lwps property. If only the max-processes
↓ open down ↓ 12 lines elided ↑ open up ↑
3330 3425          } else if (rlwp == Z_OK && rproc == Z_NO_ENTRY) {
3331 3426                  /* no scaling for max-proc value */
3332 3427                  if (zonecfg_set_aliased_rctl(snap_hndl, ALIAS_MAXPROCS,
3333 3428                      maxlwps) != Z_OK) {
3334 3429                          zerror(zlogp, B_FALSE,
3335 3430                              "unable to set max-processes alias");
3336 3431                          goto out;
3337 3432                  }
3338 3433          }
3339 3434  
3340      -        if (zonecfg_setrctlent(snap_hndl) != Z_OK) {
     3435 +        if (zonecfg_setrctlent(handle) != Z_OK) {
3341 3436                  zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setrctlent");
3342 3437                  goto out;
3343 3438          }
3344 3439  
3345 3440          if ((rctlblk = malloc(rctlblk_size())) == NULL) {
3346 3441                  zerror(zlogp, B_TRUE, "memory allocation failed");
3347 3442                  goto out;
3348 3443          }
3349      -        while (zonecfg_getrctlent(snap_hndl, &rctltab) == Z_OK) {
     3444 +        while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
3350 3445                  struct zone_rctlvaltab *rctlval;
3351 3446                  uint_t i, count;
3352 3447                  const char *name = rctltab.zone_rctl_name;
3353 3448                  char *proj_nm;
3354 3449  
3355 3450                  /* zoneadm should have already warned about unknown rctls. */
3356 3451                  if (!zonecfg_is_rctl(name)) {
3357 3452                          zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3358 3453                          rctltab.zone_rctl_valptr = NULL;
3359 3454                          continue;
↓ open down ↓ 82 lines elided ↑ open up ↑
3442 3537                          zerror(zlogp, B_FALSE, "%s failed",
3443 3538                              "nvlist_add_nvlist_array");
3444 3539                          goto out;
3445 3540                  }
3446 3541                  for (i = 0; i < count; i++)
3447 3542                          nvlist_free(nvlv[i]);
3448 3543                  free(nvlv);
3449 3544                  nvlv = NULL;
3450 3545                  rctlcount++;
3451 3546          }
3452      -        (void) zonecfg_endrctlent(snap_hndl);
     3547 +        (void) zonecfg_endrctlent(handle);
3453 3548  
3454 3549          if (rctlcount == 0) {
3455 3550                  error = 0;
3456 3551                  goto out;
3457 3552          }
3458 3553          if (nvlist_pack(nvl, &nvl_packed, &nvl_size, NV_ENCODE_NATIVE, 0)
3459 3554              != 0) {
3460 3555                  zerror(zlogp, B_FALSE, "%s failed", "nvlist_pack");
3461 3556                  goto out;
3462 3557          }
↓ open down ↓ 3 lines elided ↑ open up ↑
3466 3561          *bufsizep = nvl_size;
3467 3562  
3468 3563  out:
3469 3564          free(rctlblk);
3470 3565          zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3471 3566          if (error && nvl_packed != NULL)
3472 3567                  free(nvl_packed);
3473 3568          nvlist_free(nvl);
3474 3569          if (nvlv != NULL)
3475 3570                  free(nvlv);
     3571 +        if (handle != NULL)
     3572 +                zonecfg_fini_handle(handle);
3476 3573          return (error);
3477 3574  }
3478 3575  
3479 3576  static int
3480 3577  get_implicit_datasets(zlog_t *zlogp, char **retstr)
3481 3578  {
3482 3579          char cmdbuf[2 * MAXPATHLEN];
3483 3580  
3484 3581          if (query_hook[0] == '\0')
3485 3582                  return (0);
3486 3583  
3487 3584          if (snprintf(cmdbuf, sizeof (cmdbuf), "%s datasets", query_hook)
3488 3585              > sizeof (cmdbuf))
3489 3586                  return (-1);
3490 3587  
3491      -        if (do_subproc(zlogp, cmdbuf, retstr, B_FALSE) != 0)
     3588 +        if (do_subproc(zlogp, cmdbuf, retstr) != 0)
3492 3589                  return (-1);
3493 3590  
3494 3591          return (0);
3495 3592  }
3496 3593  
3497 3594  static int
3498 3595  get_datasets(zlog_t *zlogp, char **bufp, size_t *bufsizep)
3499 3596  {
     3597 +        zone_dochandle_t handle;
3500 3598          struct zone_dstab dstab;
3501 3599          size_t total, offset, len;
3502 3600          int error = -1;
3503 3601          char *str = NULL;
3504 3602          char *implicit_datasets = NULL;
3505 3603          int implicit_len = 0;
3506 3604  
3507 3605          *bufp = NULL;
3508 3606          *bufsizep = 0;
3509 3607  
     3608 +        if ((handle = zonecfg_init_handle()) == NULL) {
     3609 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     3610 +                return (-1);
     3611 +        }
     3612 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
     3613 +                zerror(zlogp, B_FALSE, "invalid configuration");
     3614 +                zonecfg_fini_handle(handle);
     3615 +                return (-1);
     3616 +        }
     3617 +
3510 3618          if (get_implicit_datasets(zlogp, &implicit_datasets) != 0) {
3511 3619                  zerror(zlogp, B_FALSE, "getting implicit datasets failed");
3512 3620                  goto out;
3513 3621          }
3514 3622  
3515      -        if (zonecfg_setdsent(snap_hndl) != Z_OK) {
     3623 +        if (zonecfg_setdsent(handle) != Z_OK) {
3516 3624                  zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent");
3517 3625                  goto out;
3518 3626          }
3519 3627  
3520 3628          total = 0;
3521      -        while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK)
     3629 +        while (zonecfg_getdsent(handle, &dstab) == Z_OK)
3522 3630                  total += strlen(dstab.zone_dataset_name) + 1;
3523      -        (void) zonecfg_enddsent(snap_hndl);
     3631 +        (void) zonecfg_enddsent(handle);
3524 3632  
3525 3633          if (implicit_datasets != NULL)
3526 3634                  implicit_len = strlen(implicit_datasets);
3527 3635          if (implicit_len > 0)
3528 3636                  total += implicit_len + 1;
3529 3637  
3530 3638          if (total == 0) {
3531 3639                  error = 0;
3532 3640                  goto out;
3533 3641          }
3534 3642  
3535 3643          if ((str = malloc(total)) == NULL) {
3536 3644                  zerror(zlogp, B_TRUE, "memory allocation failed");
3537 3645                  goto out;
3538 3646          }
3539 3647  
3540      -        if (zonecfg_setdsent(snap_hndl) != Z_OK) {
     3648 +        if (zonecfg_setdsent(handle) != Z_OK) {
3541 3649                  zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setdsent");
3542 3650                  goto out;
3543 3651          }
3544 3652          offset = 0;
3545      -        while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK) {
     3653 +        while (zonecfg_getdsent(handle, &dstab) == Z_OK) {
3546 3654                  len = strlen(dstab.zone_dataset_name);
3547 3655                  (void) strlcpy(str + offset, dstab.zone_dataset_name,
3548 3656                      total - offset);
3549 3657                  offset += len;
3550 3658                  if (offset < total - 1)
3551 3659                          str[offset++] = ',';
3552 3660          }
3553      -        (void) zonecfg_enddsent(snap_hndl);
     3661 +        (void) zonecfg_enddsent(handle);
3554 3662  
3555 3663          if (implicit_len > 0)
3556 3664                  (void) strlcpy(str + offset, implicit_datasets, total - offset);
3557 3665  
3558 3666          error = 0;
3559 3667          *bufp = str;
3560 3668          *bufsizep = total;
3561 3669  
3562 3670  out:
3563 3671          if (error != 0 && str != NULL)
3564 3672                  free(str);
     3673 +        if (handle != NULL)
     3674 +                zonecfg_fini_handle(handle);
3565 3675          if (implicit_datasets != NULL)
3566 3676                  free(implicit_datasets);
3567 3677  
3568 3678          return (error);
3569 3679  }
3570 3680  
3571 3681  static int
3572 3682  validate_datasets(zlog_t *zlogp)
3573 3683  {
     3684 +        zone_dochandle_t handle;
3574 3685          struct zone_dstab dstab;
3575 3686          zfs_handle_t *zhp;
3576 3687          libzfs_handle_t *hdl;
3577 3688  
3578      -        if (zonecfg_setdsent(snap_hndl) != Z_OK) {
     3689 +        if ((handle = zonecfg_init_handle()) == NULL) {
     3690 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     3691 +                return (-1);
     3692 +        }
     3693 +        if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
3579 3694                  zerror(zlogp, B_FALSE, "invalid configuration");
     3695 +                zonecfg_fini_handle(handle);
3580 3696                  return (-1);
3581 3697          }
3582 3698  
     3699 +        if (zonecfg_setdsent(handle) != Z_OK) {
     3700 +                zerror(zlogp, B_FALSE, "invalid configuration");
     3701 +                zonecfg_fini_handle(handle);
     3702 +                return (-1);
     3703 +        }
     3704 +
3583 3705          if ((hdl = libzfs_init()) == NULL) {
3584 3706                  zerror(zlogp, B_FALSE, "opening ZFS library");
     3707 +                zonecfg_fini_handle(handle);
3585 3708                  return (-1);
3586 3709          }
3587 3710  
3588      -        while (zonecfg_getdsent(snap_hndl, &dstab) == Z_OK) {
     3711 +        while (zonecfg_getdsent(handle, &dstab) == Z_OK) {
3589 3712  
3590 3713                  if ((zhp = zfs_open(hdl, dstab.zone_dataset_name,
3591 3714                      ZFS_TYPE_FILESYSTEM)) == NULL) {
3592 3715                          zerror(zlogp, B_FALSE, "cannot open ZFS dataset '%s'",
3593 3716                              dstab.zone_dataset_name);
     3717 +                        zonecfg_fini_handle(handle);
3594 3718                          libzfs_fini(hdl);
3595 3719                          return (-1);
3596 3720                  }
3597 3721  
3598 3722                  /*
3599 3723                   * Automatically set the 'zoned' property.  We check the value
3600 3724                   * first because we'll get EPERM if it is already set.
3601 3725                   */
3602 3726                  if (!zfs_prop_get_int(zhp, ZFS_PROP_ZONED) &&
3603 3727                      zfs_prop_set(zhp, zfs_prop_to_name(ZFS_PROP_ZONED),
3604 3728                      "on") != 0) {
3605 3729                          zerror(zlogp, B_FALSE, "cannot set 'zoned' "
3606 3730                              "property for ZFS dataset '%s'\n",
3607 3731                              dstab.zone_dataset_name);
     3732 +                        zonecfg_fini_handle(handle);
3608 3733                          zfs_close(zhp);
3609 3734                          libzfs_fini(hdl);
3610 3735                          return (-1);
3611 3736                  }
3612 3737  
3613 3738                  zfs_close(zhp);
3614 3739          }
3615      -        (void) zonecfg_enddsent(snap_hndl);
     3740 +        (void) zonecfg_enddsent(handle);
3616 3741  
     3742 +        zonecfg_fini_handle(handle);
3617 3743          libzfs_fini(hdl);
3618 3744  
3619 3745          return (0);
3620 3746  }
3621 3747  
3622 3748  /*
3623 3749   * Return true if the path is its own zfs file system.  We determine this
3624 3750   * by stat-ing the path to see if it is zfs and stat-ing the parent to see
3625 3751   * if it is a different fs.
3626 3752   */
↓ open down ↓ 716 lines elided ↑ open up ↑
4343 4469  
4344 4470  /*
4345 4471   * Set pool info for the zone's resource management configuration.
4346 4472   */
4347 4473  static int
4348 4474  setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid)
4349 4475  {
4350 4476          int res;
4351 4477          uint64_t tmp;
4352 4478          char sched[MAXNAMELEN];
     4479 +        zone_dochandle_t handle = NULL;
4353 4480          char pool_err[128];
4354 4481  
     4482 +        if ((handle = zonecfg_init_handle()) == NULL) {
     4483 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     4484 +                return (Z_BAD_HANDLE);
     4485 +        }
     4486 +
     4487 +        if ((res = zonecfg_get_snapshot_handle(zone_name, handle)) != Z_OK) {
     4488 +                zerror(zlogp, B_FALSE, "invalid configuration");
     4489 +                zonecfg_fini_handle(handle);
     4490 +                return (res);
     4491 +        }
     4492 +
4355 4493          /* Get the scheduling class set in the zone configuration. */
4356      -        if (zonecfg_get_sched_class(snap_hndl, sched, sizeof (sched)) == Z_OK &&
     4494 +        if (zonecfg_get_sched_class(handle, sched, sizeof (sched)) == Z_OK &&
4357 4495              strlen(sched) > 0) {
4358 4496                  if (zone_setattr(zoneid, ZONE_ATTR_SCHED_CLASS, sched,
4359 4497                      strlen(sched)) == -1)
4360 4498                          zerror(zlogp, B_TRUE, "WARNING: unable to set the "
4361 4499                              "default scheduling class");
4362 4500  
4363 4501                  if (strcmp(sched, "FX") == 0) {
4364 4502                          /*
4365 4503                           * When FX is specified then by default all processes
4366 4504                           * will start at the lowest priority level (0) and
↓ open down ↓ 24 lines elided ↑ open up ↑
4391 4529              == Z_OK) {
4392 4530                  /*
4393 4531                   * If the zone has the zone.cpu-shares rctl set then we want to
4394 4532                   * use the Fair Share Scheduler (FSS) for processes in the
4395 4533                   * zone.  Check what scheduling class the zone would be running
4396 4534                   * in by default so we can print a warning and modify the class
4397 4535                   * if we wouldn't be using FSS.
4398 4536                   */
4399 4537                  char class_name[PC_CLNMSZ];
4400 4538  
4401      -                if (zonecfg_get_dflt_sched_class(snap_hndl, class_name,
     4539 +                if (zonecfg_get_dflt_sched_class(handle, class_name,
4402 4540                      sizeof (class_name)) != Z_OK) {
4403 4541                          zerror(zlogp, B_FALSE, "WARNING: unable to determine "
4404 4542                              "the zone's scheduling class");
4405 4543  
4406 4544                  } else if (strcmp("FSS", class_name) != 0) {
4407 4545                          zerror(zlogp, B_FALSE, "WARNING: The zone.cpu-shares "
4408 4546                              "rctl is set but\nFSS is not the default "
4409 4547                              "scheduling class for\nthis zone.  FSS will be "
4410 4548                              "used for processes\nin the zone but to get the "
4411 4549                              "full benefit of FSS,\nit should be the default "
↓ open down ↓ 12 lines elided ↑ open up ↑
4424 4562           * well as persistent pools.  In all cases we call the functions
4425 4563           * unconditionally.  Within each funtion the code will check if the
4426 4564           * zone is actually configured for a temporary pool or persistent pool
4427 4565           * and just return if there is nothing to do.
4428 4566           *
4429 4567           * If we are rebooting we want to attempt to reuse any temporary pool
4430 4568           * that was previously set up.  zonecfg_bind_tmp_pool() will do the
4431 4569           * right thing in all cases (reuse or create) based on the current
4432 4570           * zonecfg.
4433 4571           */
4434      -        if ((res = zonecfg_bind_tmp_pool(snap_hndl, zoneid, pool_err,
     4572 +        if ((res = zonecfg_bind_tmp_pool(handle, zoneid, pool_err,
4435 4573              sizeof (pool_err))) != Z_OK) {
4436 4574                  if (res == Z_POOL || res == Z_POOL_CREATE || res == Z_POOL_BIND)
4437 4575                          zerror(zlogp, B_FALSE, "%s: %s\ndedicated-cpu setting "
4438 4576                              "cannot be instantiated", zonecfg_strerror(res),
4439 4577                              pool_err);
4440 4578                  else
4441 4579                          zerror(zlogp, B_FALSE, "could not bind zone to "
4442 4580                              "temporary pool: %s", zonecfg_strerror(res));
     4581 +                zonecfg_fini_handle(handle);
4443 4582                  return (Z_POOL_BIND);
4444 4583          }
4445 4584  
4446 4585          /*
4447 4586           * Check if we need to warn about poold not being enabled.
4448 4587           */
4449      -        if (zonecfg_warn_poold(snap_hndl)) {
     4588 +        if (zonecfg_warn_poold(handle)) {
4450 4589                  zerror(zlogp, B_FALSE, "WARNING: A range of dedicated-cpus has "
4451 4590                      "been specified\nbut the dynamic pool service is not "
4452 4591                      "enabled.\nThe system will not dynamically adjust the\n"
4453 4592                      "processor allocation within the specified range\n"
4454 4593                      "until svc:/system/pools/dynamic is enabled.\n"
4455 4594                      "See poold(1M).");
4456 4595          }
4457 4596  
4458 4597          /* The following is a warning, not an error. */
4459      -        if ((res = zonecfg_bind_pool(snap_hndl, zoneid, pool_err,
     4598 +        if ((res = zonecfg_bind_pool(handle, zoneid, pool_err,
4460 4599              sizeof (pool_err))) != Z_OK) {
4461 4600                  if (res == Z_POOL_BIND)
4462 4601                          zerror(zlogp, B_FALSE, "WARNING: unable to bind to "
4463 4602                              "pool '%s'; using default pool.", pool_err);
4464 4603                  else if (res == Z_POOL)
4465 4604                          zerror(zlogp, B_FALSE, "WARNING: %s: %s",
4466 4605                              zonecfg_strerror(res), pool_err);
4467 4606                  else
4468 4607                          zerror(zlogp, B_FALSE, "WARNING: %s",
4469 4608                              zonecfg_strerror(res));
4470 4609          }
4471 4610  
4472 4611          /* Update saved pool name in case it has changed */
4473      -        (void) zonecfg_get_poolname(snap_hndl, zone_name, pool_name,
     4612 +        (void) zonecfg_get_poolname(handle, zone_name, pool_name,
4474 4613              sizeof (pool_name));
4475 4614  
     4615 +        zonecfg_fini_handle(handle);
4476 4616          return (Z_OK);
4477 4617  }
4478 4618  
4479 4619  static void
4480 4620  report_prop_err(zlog_t *zlogp, const char *name, const char *value, int res)
4481 4621  {
4482 4622          switch (res) {
4483 4623          case Z_TOO_BIG:
4484 4624                  zerror(zlogp, B_FALSE, "%s property value is too large.", name);
4485 4625                  break;
↓ open down ↓ 80 lines elided ↑ open up ↑
4566 4706          if (zone_setattr(zoneid, ZONE_ATTR_FS_ALLOWED, fsallowedp, len) != 0) {
4567 4707                  zerror(zlogp, B_TRUE,
4568 4708                      "fs-allowed couldn't be set: %s: %d", fsallowedp, res);
4569 4709                  return (Z_SYSTEM);
4570 4710          }
4571 4711  
4572 4712          return (Z_OK);
4573 4713  }
4574 4714  
4575 4715  static int
4576      -setup_zone_attrs(zlog_t *zlogp, zoneid_t zoneid)
     4716 +setup_zone_attrs(zlog_t *zlogp, char *zone_namep, zoneid_t zoneid)
4577 4717  {
     4718 +        zone_dochandle_t handle;
4578 4719          int res = Z_OK;
4579 4720  
4580      -        if ((res = setup_zone_hostid(snap_hndl, zlogp, zoneid)) != Z_OK)
     4721 +        if ((handle = zonecfg_init_handle()) == NULL) {
     4722 +                zerror(zlogp, B_TRUE, "getting zone configuration handle");
     4723 +                return (Z_BAD_HANDLE);
     4724 +        }
     4725 +        if ((res = zonecfg_get_snapshot_handle(zone_namep, handle)) != Z_OK) {
     4726 +                zerror(zlogp, B_FALSE, "invalid configuration");
4581 4727                  goto out;
     4728 +        }
4582 4729  
4583      -        if ((res = setup_zone_fs_allowed(snap_hndl, zlogp, zoneid)) != Z_OK)
     4730 +        if ((res = setup_zone_hostid(handle, zlogp, zoneid)) != Z_OK)
4584 4731                  goto out;
4585 4732  
     4733 +        if ((res = setup_zone_fs_allowed(handle, zlogp, zoneid)) != Z_OK)
     4734 +                goto out;
     4735 +
4586 4736  out:
     4737 +        zonecfg_fini_handle(handle);
4587 4738          return (res);
4588 4739  }
4589 4740  
4590      -/*
4591      - * The zone_did is a persistent debug ID.  Each zone should have a unique ID
4592      - * in the kernel.  This is used for things like DTrace which want to monitor
4593      - * zones across reboots.  They can't use the zoneid since that changes on
4594      - * each boot.
4595      - */
4596 4741  zoneid_t
4597      -vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zone_did)
     4742 +vplat_create(zlog_t *zlogp, zone_mnt_t mount_cmd)
4598 4743  {
4599 4744          zoneid_t rval = -1;
4600 4745          priv_set_t *privs;
4601 4746          char rootpath[MAXPATHLEN];
4602 4747          char *rctlbuf = NULL;
4603 4748          size_t rctlbufsz = 0;
4604 4749          char *zfsbuf = NULL;
4605 4750          size_t zfsbufsz = 0;
4606 4751          zoneid_t zoneid = -1;
4607 4752          int xerr;
4608 4753          char *kzone;
4609 4754          FILE *fp = NULL;
4610 4755          tsol_zcent_t *zcent = NULL;
4611 4756          int match = 0;
4612 4757          int doi = 0;
4613      -        int flags = -1;
     4758 +        int flags;
4614 4759          zone_iptype_t iptype;
4615 4760  
4616 4761          if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) {
4617 4762                  zerror(zlogp, B_TRUE, "unable to determine zone root");
4618 4763                  return (-1);
4619 4764          }
4620 4765          if (zonecfg_in_alt_root())
4621 4766                  resolve_lofs(zlogp, rootpath, sizeof (rootpath));
4622 4767  
4623 4768          if (vplat_get_iptype(zlogp, &iptype) < 0) {
↓ open down ↓ 1 lines elided ↑ open up ↑
4625 4770                  return (-1);
4626 4771          }
4627 4772          switch (iptype) {
4628 4773          case ZS_SHARED:
4629 4774                  flags = 0;
4630 4775                  break;
4631 4776          case ZS_EXCLUSIVE:
4632 4777                  flags = ZCF_NET_EXCL;
4633 4778                  break;
4634 4779          }
4635      -        if (flags == -1)
4636      -                abort();
4637 4780  
4638 4781          if ((privs = priv_allocset()) == NULL) {
4639 4782                  zerror(zlogp, B_TRUE, "%s failed", "priv_allocset");
4640 4783                  return (-1);
4641 4784          }
4642 4785          priv_emptyset(privs);
4643 4786          if (get_privset(zlogp, privs, mount_cmd) != 0)
4644 4787                  goto error;
4645 4788  
4646 4789          if (mount_cmd == Z_MNT_BOOT &&
↓ open down ↓ 83 lines elided ↑ open up ↑
4730 4873                          /* This is just an arbitrary name; note "." usage */
4731 4874                          (void) snprintf(kernzone, sizeof (kernzone),
4732 4875                              "SUNWlu.%08lX%08lX", random(), random());
4733 4876                  }
4734 4877                  kzone = kernzone;
4735 4878          }
4736 4879  
4737 4880          xerr = 0;
4738 4881          if ((zoneid = zone_create(kzone, rootpath, privs, rctlbuf,
4739 4882              rctlbufsz, zfsbuf, zfsbufsz, &xerr, match, doi, zlabel,
4740      -            flags, zone_did)) == -1) {
     4883 +            flags)) == -1) {
4741 4884                  if (xerr == ZE_AREMOUNTS) {
4742 4885                          if (zonecfg_find_mounts(rootpath, NULL, NULL) < 1) {
4743 4886                                  zerror(zlogp, B_FALSE,
4744 4887                                      "An unknown file-system is mounted on "
4745 4888                                      "a subdirectory of %s", rootpath);
4746 4889                          } else {
4747 4890  
4748 4891                                  zerror(zlogp, B_FALSE,
4749 4892                                      "These file-systems are mounted on "
4750 4893                                      "subdirectories of %s:", rootpath);
↓ open down ↓ 25 lines elided ↑ open up ↑
4776 4919  
4777 4920          /*
4778 4921           * The following actions are not performed when merely mounting a zone
4779 4922           * for administrative use.
4780 4923           */
4781 4924          if (mount_cmd == Z_MNT_BOOT) {
4782 4925                  brand_handle_t bh;
4783 4926                  struct brand_attr attr;
4784 4927                  char modname[MAXPATHLEN];
4785 4928  
4786      -                if (setup_zone_attrs(zlogp, zoneid) != Z_OK)
     4929 +                if (setup_zone_attrs(zlogp, zone_name, zoneid) != Z_OK)
4787 4930                          goto error;
4788 4931  
4789 4932                  if ((bh = brand_open(brand_name)) == NULL) {
4790 4933                          zerror(zlogp, B_FALSE,
4791 4934                              "unable to determine brand name");
4792 4935                          goto error;
4793 4936                  }
4794 4937  
4795 4938                  if (!is_system_labeled() &&
4796 4939                      (strcmp(brand_name, LABELED_BRAND_NAME) == 0)) {
↓ open down ↓ 37 lines elided ↑ open up ↑
4834 4977          rval = zoneid;
4835 4978          zoneid = -1;
4836 4979  
4837 4980  error:
4838 4981          if (zoneid != -1) {
4839 4982                  (void) zone_shutdown(zoneid);
4840 4983                  (void) zone_destroy(zoneid);
4841 4984          }
4842 4985          if (rctlbuf != NULL)
4843 4986                  free(rctlbuf);
4844      -        if (zfsbuf != NULL)
4845      -                free(zfsbuf);
4846 4987          priv_freeset(privs);
4847 4988          if (fp != NULL)
4848 4989                  zonecfg_close_scratch(fp);
4849 4990          lofs_discard_mnttab();
4850 4991          if (zcent != NULL)
4851 4992                  tsol_freezcent(zcent);
4852 4993          return (rval);
4853 4994  }
4854 4995  
4855 4996  /*
↓ open down ↓ 118 lines elided ↑ open up ↑
4974 5115                          }
4975 5116                          break;
4976 5117                  case ZS_EXCLUSIVE:
4977 5118                          if (configure_exclusive_network_interfaces(zlogp,
4978 5119                              zoneid) !=
4979 5120                              0) {
4980 5121                                  lofs_discard_mnttab();
4981 5122                                  return (-1);
4982 5123                          }
4983 5124                          break;
4984      -                default:
4985      -                        abort();
4986 5125                  }
4987 5126          }
4988 5127  
4989 5128          write_index_file(zoneid);
4990 5129  
4991 5130          lofs_discard_mnttab();
4992 5131          return (0);
4993 5132  }
4994 5133  
4995 5134  static int
↓ open down ↓ 55 lines elided ↑ open up ↑
5051 5190                  else
5052 5191                          retv = 0;
5053 5192                  zonecfg_close_scratch(fp);
5054 5193                  return (retv);
5055 5194          } else {
5056 5195                  return (0);
5057 5196          }
5058 5197  }
5059 5198  
5060 5199  int
5061      -vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting,
5062      -    boolean_t debug)
     5200 +vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting)
5063 5201  {
5064 5202          char *kzone;
5065 5203          zoneid_t zoneid;
5066 5204          int res;
5067 5205          char pool_err[128];
5068 5206          char cmdbuf[MAXPATHLEN];
5069 5207          brand_handle_t bh = NULL;
5070 5208          dladm_status_t status;
5071 5209          char errmsg[DLADM_STRSIZE];
5072 5210          ushort_t flags;
↓ open down ↓ 17 lines elided ↑ open up ↑
5090 5228          }
5091 5229  
5092 5230          if ((zoneid = getzoneidbyname(kzone)) == ZONE_ID_UNDEFINED) {
5093 5231                  if (!bringup_failure_recovery)
5094 5232                          zerror(zlogp, B_TRUE, "unable to get zoneid");
5095 5233                  if (unmount_cmd)
5096 5234                          (void) lu_root_teardown(zlogp);
5097 5235                  goto error;
5098 5236          }
5099 5237  
5100      -        if (remove_datalink_pool(zlogp, zoneid) != 0)
     5238 +        if (remove_datalink_pool(zlogp, zoneid) != 0) {
5101 5239                  zerror(zlogp, B_FALSE, "unable clear datalink pool property");
     5240 +                goto error;
     5241 +        }
5102 5242  
5103      -        if (remove_datalink_protect(zlogp, zoneid) != 0)
     5243 +        if (remove_datalink_protect(zlogp, zoneid) != 0) {
5104 5244                  zerror(zlogp, B_FALSE,
5105 5245                      "unable clear datalink protect property");
     5246 +                goto error;
     5247 +        }
5106 5248  
5107 5249          /*
5108 5250           * The datalinks assigned to the zone will be removed from the NGZ as
5109 5251           * part of zone_shutdown() so that we need to remove protect/pool etc.
5110 5252           * before zone_shutdown(). Even if the shutdown itself fails, the zone
5111 5253           * will not be able to violate any constraints applied because the
5112 5254           * datalinks are no longer available to the zone.
5113 5255           */
5114 5256          if (zone_shutdown(zoneid) != 0) {
5115 5257                  zerror(zlogp, B_TRUE, "unable to shutdown zone");
↓ open down ↓ 13 lines elided ↑ open up ↑
5129 5271          if (brand_get_halt(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
5130 5272              sizeof (cmdbuf) - EXEC_LEN) < 0) {
5131 5273                  brand_close(bh);
5132 5274                  zerror(zlogp, B_FALSE, "unable to determine branded zone's "
5133 5275                      "halt callback.");
5134 5276                  goto error;
5135 5277          }
5136 5278          brand_close(bh);
5137 5279  
5138 5280          if ((strlen(cmdbuf) > EXEC_LEN) &&
5139      -            (do_subproc(zlogp, cmdbuf, NULL, debug) != Z_OK)) {
     5281 +            (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) {
5140 5282                  zerror(zlogp, B_FALSE, "%s failed", cmdbuf);
5141 5283                  goto error;
5142 5284          }
5143 5285  
5144 5286          if (!unmount_cmd) {
5145 5287                  zone_iptype_t iptype;
5146 5288  
5147 5289                  if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &flags,
5148 5290                      sizeof (flags)) < 0) {
5149 5291                          if (vplat_get_iptype(zlogp, &iptype) < 0) {
↓ open down ↓ 11 lines elided ↑ open up ↑
5161 5303                  switch (iptype) {
5162 5304                  case ZS_SHARED:
5163 5305                          if (unconfigure_shared_network_interfaces(zlogp,
5164 5306                              zoneid) != 0) {
5165 5307                                  zerror(zlogp, B_FALSE, "unable to unconfigure "
5166 5308                                      "network interfaces in zone");
5167 5309                                  goto error;
5168 5310                          }
5169 5311                          break;
5170 5312                  case ZS_EXCLUSIVE:
     5313 +                        if (unconfigure_exclusive_network_interfaces(zlogp,
     5314 +                            zoneid) != 0) {
     5315 +                                zerror(zlogp, B_FALSE, "unable to unconfigure "
     5316 +                                    "network interfaces in zone");
     5317 +                                goto error;
     5318 +                        }
5171 5319                          status = dladm_zone_halt(dld_handle, zoneid);
5172 5320                          if (status != DLADM_STATUS_OK) {
5173 5321                                  zerror(zlogp, B_FALSE, "unable to notify "
5174 5322                                      "dlmgmtd of zone halt: %s",
5175 5323                                      dladm_status2str(status, errmsg));
5176 5324                          }
5177 5325                          break;
5178 5326                  }
5179 5327          }
5180 5328  
↓ open down ↓ 16 lines elided ↑ open up ↑
5197 5345           * modified to no longer use a temporary pool.  In that case we need
5198 5346           * to destroy the temporary pool now.  This case looks like the case
5199 5347           * where we never had a temporary pool configured but
5200 5348           * zonecfg_destroy_tmp_pool will do the right thing either way.
5201 5349           */
5202 5350          if (!unmount_cmd) {
5203 5351                  boolean_t destroy_tmp_pool = B_TRUE;
5204 5352  
5205 5353                  if (rebooting) {
5206 5354                          struct zone_psettab pset_tab;
     5355 +                        zone_dochandle_t handle;
5207 5356  
5208      -                        if (zonecfg_lookup_pset(snap_hndl, &pset_tab) == Z_OK)
     5357 +                        if ((handle = zonecfg_init_handle()) != NULL &&
     5358 +                            zonecfg_get_handle(zone_name, handle) == Z_OK &&
     5359 +                            zonecfg_lookup_pset(handle, &pset_tab) == Z_OK)
5209 5360                                  destroy_tmp_pool = B_FALSE;
     5361 +
     5362 +                        zonecfg_fini_handle(handle);
5210 5363                  }
5211 5364  
5212 5365                  if (destroy_tmp_pool) {
5213 5366                          if ((res = zonecfg_destroy_tmp_pool(zone_name, pool_err,
5214 5367                              sizeof (pool_err))) != Z_OK) {
5215 5368                                  if (res == Z_POOL)
5216 5369                                          zerror(zlogp, B_FALSE, pool_err);
5217 5370                          }
5218 5371                  }
5219 5372          }
↓ open down ↓ 22 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX