Print this page
OS-5330 zoneadm mounting an lx or joyent branded zone fails
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
(NOTE: Manual port, because of divergence from SmartOS.)
Network interfaces need to configure in /native/dev for LX.
Mismerged snap_hndl (should be handle) blocked lipkg zone boot
(NOTE:  There are other instances of snap_hndl we pulled in from
        illumos-joyent that may need to be nuked too.)
OS-1571 Placate gcc -Wparentheses
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-5292 zoneadmd should infer zone.max-processes
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4915 want FX high priority zone configuration option
OS-4925 ps pri shows misleading value for zone in RT scheduling class
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
OS-4254 libbrand token substitution incomplete for mount entries
OS-3776 project rctls should be in sync with zone rctls
OS-3524 in order to support interaction with docker containers, need to be able to connect to stdio for init from GZ
OS-3525 in order to support 'docker logs' need to be able to get stdio from zone to log file
OS-399 zone phys. mem. cap should be a rctl and have associated kstat

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 (c) 2013, Joyent Inc. All rights reserved.
  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      -#define ALT_MOUNT(mount_cmd)    ((mount_cmd) != Z_MNT_BOOT)
 140      -
 141  139  /* a reasonable estimate for the number of lwps per process */
 142  140  #define LWPS_PER_PROCESS        10
 143  141  
 144  142  /* for routing socket */
 145  143  static int rts_seqno = 0;
 146  144  
 147  145  /* mangled zone name when mounting in an alternate root environment */
 148  146  static char kernzone[ZONENAME_MAX];
 149  147  
 150  148  /* array of cached mount entries for resolve_lofs */
↓ open down ↓ 3 lines elided ↑ open up ↑
 154  152  static tsol_zcent_t *get_zone_label(zlog_t *, priv_set_t *);
 155  153  static int tsol_mounts(zlog_t *, char *, char *);
 156  154  static void tsol_unmounts(zlog_t *, char *);
 157  155  
 158  156  static m_label_t *zlabel = NULL;
 159  157  static m_label_t *zid_label = NULL;
 160  158  static priv_set_t *zprivs = NULL;
 161  159  
 162  160  static const char *DFLT_FS_ALLOWED = "hsfs,smbfs,nfs,nfs3,nfs4,nfsdyn";
 163  161  
      162 +typedef struct zone_proj_rctl_map {
      163 +        char *zpr_zone_rctl;
      164 +        char *zpr_project_rctl;
      165 +} zone_proj_rctl_map_t;
      166 +
      167 +static zone_proj_rctl_map_t zone_proj_rctl_map[] = {
      168 +        {"zone.max-msg-ids",    "project.max-msg-ids"},
      169 +        {"zone.max-sem-ids",    "project.max-sem-ids"},
      170 +        {"zone.max-shm-ids",    "project.max-shm-ids"},
      171 +        {"zone.max-shm-memory", "project.max-shm-memory"},
      172 +        {NULL,                  NULL}
      173 +};
      174 +
 164  175  /* from libsocket, not in any header file */
 165  176  extern int getnetmaskbyaddr(struct in_addr, struct in_addr *);
 166  177  
 167  178  /* from zoneadmd */
 168  179  extern char query_hook[];
 169  180  
 170  181  /*
 171  182   * For each "net" resource configured in zonecfg, we track a zone_addr_list_t
 172  183   * node in a linked list that is sorted by linkid.  The list is constructed as
 173  184   * the xml configuration file is parsed, and the information
↓ open down ↓ 969 lines elided ↑ open up ↑
1143 1154              mount_one_dev_symlink_cb, prof) != 0) {
1144 1155                  zerror(zlogp, B_TRUE, "failed to add standard symlink");
1145 1156                  goto cleanup;
1146 1157          }
1147 1158  
1148 1159          /* Add user-specified devices and directories */
1149 1160          if ((handle = zonecfg_init_handle()) == NULL) {
1150 1161                  zerror(zlogp, B_FALSE, "can't initialize zone handle");
1151 1162                  goto cleanup;
1152 1163          }
1153      -        if (err = zonecfg_get_handle(zone_name, handle)) {
     1164 +        if ((err = zonecfg_get_handle(zone_name, handle)) != 0) {
1154 1165                  zerror(zlogp, B_FALSE, "can't get handle for zone "
1155 1166                      "%s: %s", zone_name, zonecfg_strerror(err));
1156 1167                  goto cleanup;
1157 1168          }
1158      -        if (err = zonecfg_setdevent(handle)) {
     1169 +        if ((err = zonecfg_setdevent(handle)) != 0) {
1159 1170                  zerror(zlogp, B_FALSE, "%s: %s", zone_name,
1160 1171                      zonecfg_strerror(err));
1161 1172                  goto cleanup;
1162 1173          }
1163 1174          while (zonecfg_getdevent(handle, &ztab) == Z_OK) {
1164 1175                  if (di_prof_add_dev(prof, ztab.zone_dev_match)) {
1165 1176                          zerror(zlogp, B_TRUE, "failed to add "
1166 1177                              "user-specified device");
1167 1178                          goto cleanup;
1168 1179                  }
↓ open down ↓ 495 lines elided ↑ open up ↑
1664 1675                      sizeof (fsp->zone_fs_special));
1665 1676          }
1666 1677          (void) zonecfg_endfsent(handle);
1667 1678          return (0);
1668 1679  }
1669 1680  
1670 1681  static int
1671 1682  mount_filesystems(zlog_t *zlogp, zone_mnt_t mount_cmd)
1672 1683  {
1673 1684          char rootpath[MAXPATHLEN];
1674      -        char zonepath[MAXPATHLEN];
1675 1685          char brand[MAXNAMELEN];
1676 1686          char luroot[MAXPATHLEN];
1677 1687          int i, num_fs = 0;
1678 1688          struct zone_fstab *fs_ptr = NULL;
1679 1689          zone_dochandle_t handle = NULL;
1680 1690          zone_state_t zstate;
1681 1691          brand_handle_t bh;
1682 1692          plat_gmount_cb_data_t cb;
1683 1693  
1684 1694          if (zone_get_state(zone_name, &zstate) != Z_OK ||
1685 1695              (zstate != ZONE_STATE_READY && zstate != ZONE_STATE_MOUNTED)) {
1686 1696                  zerror(zlogp, B_FALSE,
1687 1697                      "zone must be in '%s' or '%s' state to mount file-systems",
1688 1698                      zone_state_str(ZONE_STATE_READY),
1689 1699                      zone_state_str(ZONE_STATE_MOUNTED));
1690 1700                  goto bad;
1691 1701          }
1692 1702  
1693      -        if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) {
1694      -                zerror(zlogp, B_TRUE, "unable to determine zone path");
1695      -                goto bad;
1696      -        }
1697      -
1698 1703          if (zone_get_rootpath(zone_name, rootpath, sizeof (rootpath)) != Z_OK) {
1699 1704                  zerror(zlogp, B_TRUE, "unable to determine zone root");
1700 1705                  goto bad;
1701 1706          }
1702 1707  
1703 1708          if ((handle = zonecfg_init_handle()) == NULL) {
1704 1709                  zerror(zlogp, B_TRUE, "getting zone configuration handle");
1705 1710                  goto bad;
1706 1711          }
1707 1712          if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK ||
↓ open down ↓ 80 lines elided ↑ open up ↑
1788 1793           *   3) Set up the rest of the scratch zone environment
1789 1794           *      (build_mounted_post_var()).
1790 1795           */
1791 1796          if (ALT_MOUNT(mount_cmd) && !build_mounted_pre_var(zlogp,
1792 1797              rootpath, sizeof (rootpath), zonepath, luroot, sizeof (luroot)))
1793 1798                  goto bad;
1794 1799  
1795 1800          qsort(fs_ptr, num_fs, sizeof (*fs_ptr), fs_compare);
1796 1801  
1797 1802          for (i = 0; i < num_fs; i++) {
1798      -                if (ALT_MOUNT(mount_cmd) &&
1799      -                    strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) {
1800      -                        size_t slen = strlen(rootpath) - 2;
     1803 +                if (ALT_MOUNT(mount_cmd)) {
     1804 +                        if (strcmp(fs_ptr[i].zone_fs_dir, "/dev") == 0) {
     1805 +                                size_t slen = strlen(rootpath) - 2;
1801 1806  
1802      -                        /*
1803      -                         * By default we'll try to mount /dev as /a/dev
1804      -                         * but /dev is special and always goes at the top
1805      -                         * so strip the trailing '/a' from the rootpath.
1806      -                         */
1807      -                        assert(strcmp(&rootpath[slen], "/a") == 0);
1808      -                        rootpath[slen] = '\0';
1809      -                        if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd)
1810      -                            != 0)
1811      -                                goto bad;
1812      -                        rootpath[slen] = '/';
1813      -                        continue;
     1807 +                                /*
     1808 +                                 * By default we'll try to mount /dev
     1809 +                                 * as /a/dev but /dev is special and
     1810 +                                 * always goes at the top so strip the
     1811 +                                 * trailing '/a' from the rootpath.
     1812 +                                 */
     1813 +                                assert(strcmp(&rootpath[slen], "/a") == 0);
     1814 +                                rootpath[slen] = '\0';
     1815 +                                if (mount_one(zlogp, &fs_ptr[i], rootpath,
     1816 +                                    mount_cmd) != 0)
     1817 +                                        goto bad;
     1818 +                                rootpath[slen] = '/';
     1819 +                                continue;
     1820 +                        } else if (strcmp(brand_name, default_brand) != 0) {
     1821 +                                /*
     1822 +                                 * If mounting non-native brand, skip
     1823 +                                 * mounting global mounts and
     1824 +                                 * filesystem entries since they are
     1825 +                                 * only needed for native pkg upgrade
     1826 +                                 * tools.
     1827 +                                 *
     1828 +                                 * The only exception right now is
     1829 +                                 * /dev (handled above), which is
     1830 +                                 * needed in the luroot in order to
     1831 +                                 * zlogin -S into the zone.
     1832 +                                 */
     1833 +                                continue;
     1834 +                        }
1814 1835                  }
     1836 +
1815 1837                  if (mount_one(zlogp, &fs_ptr[i], rootpath, mount_cmd) != 0)
1816 1838                          goto bad;
1817 1839          }
1818 1840          if (ALT_MOUNT(mount_cmd) &&
1819 1841              !build_mounted_post_var(zlogp, mount_cmd, rootpath, luroot))
1820 1842                  goto bad;
1821 1843  
1822 1844          /*
1823 1845           * For Trusted Extensions cross-mount each lower level /export/home
1824 1846           */
↓ open down ↓ 1056 lines elided ↑ open up ↑
2881 2903          zone_addr_list_t *ptr, *new;
2882 2904  
2883 2905          for (ptr = zalist; ptr != NULL; ) {
2884 2906                  new = ptr;
2885 2907                  ptr = ptr->za_next;
2886 2908                  free(new);
2887 2909          }
2888 2910  }
2889 2911  
2890 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 +/*
2891 2932   * Add the kernel access control information for the interface names.
2892 2933   * If anything goes wrong, we log a general error message, attempt to tear down
2893 2934   * whatever we set up, and return an error.
2894 2935   */
2895 2936  static int
2896 2937  configure_exclusive_network_interfaces(zlog_t *zlogp, zoneid_t zoneid)
2897 2938  {
2898 2939          zone_dochandle_t handle;
2899 2940          struct zone_nwiftab nwiftab;
2900 2941          char rootpath[MAXPATHLEN];
↓ open down ↓ 25 lines elided ↑ open up ↑
2926 2967                  if (prof == NULL) {
2927 2968                          if (zone_get_devroot(zone_name, rootpath,
2928 2969                              sizeof (rootpath)) != Z_OK) {
2929 2970                                  (void) zonecfg_endnwifent(handle);
2930 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 2979                                  (void) zonecfg_endnwifent(handle);
2939 2980                                  zonecfg_fini_handle(handle);
2940 2981                                  zerror(zlogp, B_TRUE,
2941 2982                                      "failed to initialize profile");
2942 2983                                  return (-1);
2943 2984                          }
2944 2985                  }
2945 2986  
2946 2987                  /*
↓ open down ↓ 363 lines elided ↑ open up ↑
3310 3351                  zerror(zlogp, B_FALSE, "failed to determine the zone's "
3311 3352                      "privilege set");
3312 3353                  break;
3313 3354          }
3314 3355  
3315 3356          free(privname);
3316 3357          zonecfg_fini_handle(handle);
3317 3358          return (error);
3318 3359  }
3319 3360  
     3361 +static char *
     3362 +zone_proj_rctl(const char *name)
     3363 +{
     3364 +        int i;
     3365 +
     3366 +        for (i = 0; zone_proj_rctl_map[i].zpr_zone_rctl != NULL; i++) {
     3367 +                if (strcmp(name, zone_proj_rctl_map[i].zpr_zone_rctl) == 0) {
     3368 +                        return (zone_proj_rctl_map[i].zpr_project_rctl);
     3369 +                }
     3370 +        }
     3371 +        return (NULL);
     3372 +}
     3373 +
3320 3374  static int
3321 3375  get_rctls(zlog_t *zlogp, char **bufp, size_t *bufsizep)
3322 3376  {
3323 3377          nvlist_t *nvl = NULL;
3324 3378          char *nvl_packed = NULL;
3325 3379          size_t nvl_size = 0;
3326 3380          nvlist_t **nvlv = NULL;
3327 3381          int rctlcount = 0;
3328 3382          int error = -1;
3329 3383          zone_dochandle_t handle;
3330 3384          struct zone_rctltab rctltab;
3331 3385          rctlblk_t *rctlblk = NULL;
3332 3386          uint64_t maxlwps;
3333 3387          uint64_t maxprocs;
     3388 +        int rproc, rlwp;
3334 3389  
3335 3390          *bufp = NULL;
3336 3391          *bufsizep = 0;
3337 3392  
3338 3393          if ((handle = zonecfg_init_handle()) == NULL) {
3339 3394                  zerror(zlogp, B_TRUE, "getting zone configuration handle");
3340 3395                  return (-1);
3341 3396          }
3342 3397          if (zonecfg_get_snapshot_handle(zone_name, handle) != Z_OK) {
3343 3398                  zerror(zlogp, B_FALSE, "invalid configuration");
↓ open down ↓ 2 lines elided ↑ open up ↑
3346 3401          }
3347 3402  
3348 3403          rctltab.zone_rctl_valptr = NULL;
3349 3404          if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
3350 3405                  zerror(zlogp, B_TRUE, "%s failed", "nvlist_alloc");
3351 3406                  goto out;
3352 3407          }
3353 3408  
3354 3409          /*
3355 3410           * Allow the administrator to control both the maximum number of
3356      -         * process table slots and the maximum number of lwps with just the
3357      -         * max-processes property.  If only the max-processes property is set,
3358      -         * we add a max-lwps property with a limit derived from max-processes.
     3411 +         * process table slots, and the maximum number of lwps, with a single
     3412 +         * max-processes or max-lwps property. If only the max-processes
     3413 +         * property is set, we add a max-lwps property with a limit derived
     3414 +         * from max-processes. If only the max-lwps property is set, we add a
     3415 +         * max-processes property with the same limit as max-lwps.
3359 3416           */
3360      -        if (zonecfg_get_aliased_rctl(handle, ALIAS_MAXPROCS, &maxprocs)
3361      -            == Z_OK &&
3362      -            zonecfg_get_aliased_rctl(handle, ALIAS_MAXLWPS, &maxlwps)
3363      -            == Z_NO_ENTRY) {
3364      -                if (zonecfg_set_aliased_rctl(handle, ALIAS_MAXLWPS,
     3417 +        rproc = zonecfg_get_aliased_rctl(snap_hndl, ALIAS_MAXPROCS, &maxprocs);
     3418 +        rlwp = zonecfg_get_aliased_rctl(snap_hndl, ALIAS_MAXLWPS, &maxlwps);
     3419 +        if (rproc == Z_OK && rlwp == Z_NO_ENTRY) {
     3420 +                if (zonecfg_set_aliased_rctl(snap_hndl, ALIAS_MAXLWPS,
3365 3421                      maxprocs * LWPS_PER_PROCESS) != Z_OK) {
3366 3422                          zerror(zlogp, B_FALSE, "unable to set max-lwps alias");
3367 3423                          goto out;
3368 3424                  }
     3425 +        } else if (rlwp == Z_OK && rproc == Z_NO_ENTRY) {
     3426 +                /* no scaling for max-proc value */
     3427 +                if (zonecfg_set_aliased_rctl(snap_hndl, ALIAS_MAXPROCS,
     3428 +                    maxlwps) != Z_OK) {
     3429 +                        zerror(zlogp, B_FALSE,
     3430 +                            "unable to set max-processes alias");
     3431 +                        goto out;
     3432 +                }
3369 3433          }
3370 3434  
3371 3435          if (zonecfg_setrctlent(handle) != Z_OK) {
3372 3436                  zerror(zlogp, B_FALSE, "%s failed", "zonecfg_setrctlent");
3373 3437                  goto out;
3374 3438          }
3375 3439  
3376 3440          if ((rctlblk = malloc(rctlblk_size())) == NULL) {
3377 3441                  zerror(zlogp, B_TRUE, "memory allocation failed");
3378 3442                  goto out;
3379 3443          }
3380 3444          while (zonecfg_getrctlent(handle, &rctltab) == Z_OK) {
3381 3445                  struct zone_rctlvaltab *rctlval;
3382 3446                  uint_t i, count;
3383 3447                  const char *name = rctltab.zone_rctl_name;
     3448 +                char *proj_nm;
3384 3449  
3385 3450                  /* zoneadm should have already warned about unknown rctls. */
3386 3451                  if (!zonecfg_is_rctl(name)) {
3387 3452                          zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3388 3453                          rctltab.zone_rctl_valptr = NULL;
3389 3454                          continue;
3390 3455                  }
3391 3456                  count = 0;
3392 3457                  for (rctlval = rctltab.zone_rctl_valptr; rctlval != NULL;
3393 3458                      rctlval = rctlval->zone_rctlval_next) {
↓ open down ↓ 46 lines elided ↑ open up ↑
3440 3505                          if (nvlist_add_uint64(nvlv[i], "action",
3441 3506                              (uint_t)rctlblk_get_local_action(rctlblk, NULL))
3442 3507                              != 0) {
3443 3508                                  zerror(zlogp, B_FALSE, "%s failed",
3444 3509                                      "nvlist_add_uint64");
3445 3510                                  goto out;
3446 3511                          }
3447 3512                  }
3448 3513                  zonecfg_free_rctl_value_list(rctltab.zone_rctl_valptr);
3449 3514                  rctltab.zone_rctl_valptr = NULL;
     3515 +
     3516 +                /*
     3517 +                 * With no action on our part we will start zsched with the
     3518 +                 * project rctl values for our (zoneadmd) current project. For
     3519 +                 * brands running a variant of Illumos, that's not a problem
     3520 +                 * since they will setup their own projects, but for a
     3521 +                 * non-native brand like lx, where there are no projects, we
     3522 +                 * want to start things up with the same project rctls as the
     3523 +                 * corresponding zone rctls, since nothing within the zone will
     3524 +                 * ever change the project rctls.
     3525 +                 */
     3526 +                if ((proj_nm = zone_proj_rctl(name)) != NULL) {
     3527 +                        if (nvlist_add_nvlist_array(nvl, proj_nm, nvlv, count)
     3528 +                            != 0) {
     3529 +                                zerror(zlogp, B_FALSE,
     3530 +                                    "nvlist_add_nvlist_arrays failed");
     3531 +                                goto out;
     3532 +                        }
     3533 +                }
     3534 +
3450 3535                  if (nvlist_add_nvlist_array(nvl, (char *)name, nvlv, count)
3451 3536                      != 0) {
3452 3537                          zerror(zlogp, B_FALSE, "%s failed",
3453 3538                              "nvlist_add_nvlist_array");
3454 3539                          goto out;
3455 3540                  }
3456 3541                  for (i = 0; i < count; i++)
3457 3542                          nvlist_free(nvlv[i]);
3458 3543                  free(nvlv);
3459 3544                  nvlv = NULL;
↓ open down ↓ 241 lines elided ↑ open up ↑
3701 3786   * Otherwise if there's no label on the dataset, create one here.
3702 3787   */
3703 3788  
3704 3789  static int
3705 3790  validate_rootds_label(zlog_t *zlogp, char *rootpath, m_label_t *zone_sl)
3706 3791  {
3707 3792          int             error = -1;
3708 3793          zfs_handle_t    *zhp;
3709 3794          libzfs_handle_t *hdl;
3710 3795          m_label_t       ds_sl;
3711      -        char            zonepath[MAXPATHLEN];
3712 3796          char            ds_hexsl[MAXNAMELEN];
3713 3797  
3714 3798          if (!is_system_labeled())
3715 3799                  return (0);
3716 3800  
3717      -        if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) {
3718      -                zerror(zlogp, B_TRUE, "unable to determine zone path");
3719      -                return (-1);
3720      -        }
3721      -
3722 3801          if (!is_zonepath_zfs(zonepath))
3723 3802                  return (0);
3724 3803  
3725 3804          if ((hdl = libzfs_init()) == NULL) {
3726 3805                  zerror(zlogp, B_FALSE, "opening ZFS library");
3727 3806                  return (-1);
3728 3807          }
3729 3808  
3730 3809          if ((zhp = zfs_path_to_zhandle(hdl, rootpath,
3731 3810              ZFS_TYPE_FILESYSTEM)) == NULL) {
↓ open down ↓ 650 lines elided ↑ open up ↑
4382 4461                          zerror(zlogp, B_FALSE,
4383 4462                              "zone root %s is reachable through %s",
4384 4463                              rootpath, mnp->mnt_mountp);
4385 4464                          return (B_TRUE);
4386 4465                  }
4387 4466          }
4388 4467          return (B_FALSE);
4389 4468  }
4390 4469  
4391 4470  /*
4392      - * Set memory cap and pool info for the zone's resource management
4393      - * configuration.
     4471 + * Set pool info for the zone's resource management configuration.
4394 4472   */
4395 4473  static int
4396 4474  setup_zone_rm(zlog_t *zlogp, char *zone_name, zoneid_t zoneid)
4397 4475  {
4398 4476          int res;
4399 4477          uint64_t tmp;
4400      -        struct zone_mcaptab mcap;
4401 4478          char sched[MAXNAMELEN];
4402 4479          zone_dochandle_t handle = NULL;
4403 4480          char pool_err[128];
4404 4481  
4405 4482          if ((handle = zonecfg_init_handle()) == NULL) {
4406 4483                  zerror(zlogp, B_TRUE, "getting zone configuration handle");
4407 4484                  return (Z_BAD_HANDLE);
4408 4485          }
4409 4486  
4410 4487          if ((res = zonecfg_get_snapshot_handle(zone_name, handle)) != Z_OK) {
4411 4488                  zerror(zlogp, B_FALSE, "invalid configuration");
4412 4489                  zonecfg_fini_handle(handle);
4413 4490                  return (res);
4414 4491          }
4415 4492  
4416      -        /*
4417      -         * If a memory cap is configured, set the cap in the kernel using
4418      -         * zone_setattr() and make sure the rcapd SMF service is enabled.
4419      -         */
4420      -        if (zonecfg_getmcapent(handle, &mcap) == Z_OK) {
4421      -                uint64_t num;
4422      -                char smf_err[128];
4423      -
4424      -                num = (uint64_t)strtoull(mcap.zone_physmem_cap, NULL, 10);
4425      -                if (zone_setattr(zoneid, ZONE_ATTR_PHYS_MCAP, &num, 0) == -1) {
4426      -                        zerror(zlogp, B_TRUE, "could not set zone memory cap");
4427      -                        zonecfg_fini_handle(handle);
4428      -                        return (Z_INVAL);
4429      -                }
4430      -
4431      -                if (zonecfg_enable_rcapd(smf_err, sizeof (smf_err)) != Z_OK) {
4432      -                        zerror(zlogp, B_FALSE, "enabling system/rcap service "
4433      -                            "failed: %s", smf_err);
4434      -                        zonecfg_fini_handle(handle);
4435      -                        return (Z_INVAL);
4436      -                }
4437      -        }
4438      -
4439 4493          /* Get the scheduling class set in the zone configuration. */
4440 4494          if (zonecfg_get_sched_class(handle, sched, sizeof (sched)) == Z_OK &&
4441 4495              strlen(sched) > 0) {
4442 4496                  if (zone_setattr(zoneid, ZONE_ATTR_SCHED_CLASS, sched,
4443 4497                      strlen(sched)) == -1)
4444 4498                          zerror(zlogp, B_TRUE, "WARNING: unable to set the "
4445 4499                              "default scheduling class");
4446 4500  
4447      -        } else if (zonecfg_get_aliased_rctl(handle, ALIAS_SHARES, &tmp)
     4501 +                if (strcmp(sched, "FX") == 0) {
     4502 +                        /*
     4503 +                         * When FX is specified then by default all processes
     4504 +                         * will start at the lowest priority level (0) and
     4505 +                         * stay there. We support an optional attr which
     4506 +                         * indicates that all the processes should be "high
     4507 +                         * priority". We set this on the zone so that starting
     4508 +                         * init will set the priority high.
     4509 +                         */
     4510 +                        struct zone_attrtab a;
     4511 +
     4512 +                        bzero(&a, sizeof (a));
     4513 +                        (void) strlcpy(a.zone_attr_name, "fixed-hi-prio",
     4514 +                            sizeof (a.zone_attr_name));
     4515 +
     4516 +                        if (zonecfg_lookup_attr(snap_hndl, &a) == Z_OK &&
     4517 +                            strcmp(a.zone_attr_value, "true") == 0) {
     4518 +                                boolean_t hi = B_TRUE;
     4519 +
     4520 +                                if (zone_setattr(zoneid,
     4521 +                                    ZONE_ATTR_SCHED_FIXEDHI, (void *)hi,
     4522 +                                    sizeof (hi)) == -1)
     4523 +                                        zerror(zlogp, B_TRUE, "WARNING: unable "
     4524 +                                            "to set high priority");
     4525 +                        }
     4526 +                }
     4527 +
     4528 +        } else if (zonecfg_get_aliased_rctl(snap_hndl, ALIAS_SHARES, &tmp)
4448 4529              == Z_OK) {
4449 4530                  /*
4450 4531                   * If the zone has the zone.cpu-shares rctl set then we want to
4451 4532                   * use the Fair Share Scheduler (FSS) for processes in the
4452 4533                   * zone.  Check what scheduling class the zone would be running
4453 4534                   * in by default so we can print a warning and modify the class
4454 4535                   * if we wouldn't be using FSS.
4455 4536                   */
4456 4537                  char class_name[PC_CLNMSZ];
4457 4538  
↓ open down ↓ 526 lines elided ↑ open up ↑
4984 5065                              uuidstr);
4985 5066                          (void) fclose(zet);
4986 5067                  }
4987 5068          }
4988 5069          _exit(0);
4989 5070  }
4990 5071  
4991 5072  int
4992 5073  vplat_bringup(zlog_t *zlogp, zone_mnt_t mount_cmd, zoneid_t zoneid)
4993 5074  {
4994      -        char zonepath[MAXPATHLEN];
     5075 +        char zpath[MAXPATHLEN];
4995 5076  
4996 5077          if (mount_cmd == Z_MNT_BOOT && validate_datasets(zlogp) != 0) {
4997 5078                  lofs_discard_mnttab();
4998 5079                  return (-1);
4999 5080          }
5000 5081  
5001 5082          /*
5002 5083           * Before we try to mount filesystems we need to create the
5003 5084           * attribute backing store for /dev
5004 5085           */
5005      -        if (zone_get_zonepath(zone_name, zonepath, sizeof (zonepath)) != Z_OK) {
5006      -                lofs_discard_mnttab();
5007      -                return (-1);
5008      -        }
5009      -        resolve_lofs(zlogp, zonepath, sizeof (zonepath));
     5086 +        (void) strlcpy(zpath, zonepath, sizeof (zpath));
     5087 +        resolve_lofs(zlogp, zpath, sizeof (zpath));
5010 5088  
5011 5089          /* Make /dev directory owned by root, grouped sys */
5012      -        if (make_one_dir(zlogp, zonepath, "/dev", DEFAULT_DIR_MODE,
5013      -            0, 3) != 0) {
     5090 +        if (make_one_dir(zlogp, zpath, "/dev", DEFAULT_DIR_MODE, 0, 3) != 0) {
5014 5091                  lofs_discard_mnttab();
5015 5092                  return (-1);
5016 5093          }
5017 5094  
5018 5095          if (mount_filesystems(zlogp, mount_cmd) != 0) {
5019 5096                  lofs_discard_mnttab();
5020 5097                  return (-1);
5021 5098          }
5022 5099  
5023 5100          if (mount_cmd == Z_MNT_BOOT) {
↓ open down ↓ 95 lines elided ↑ open up ↑
5119 5196          }
5120 5197  }
5121 5198  
5122 5199  int
5123 5200  vplat_teardown(zlog_t *zlogp, boolean_t unmount_cmd, boolean_t rebooting)
5124 5201  {
5125 5202          char *kzone;
5126 5203          zoneid_t zoneid;
5127 5204          int res;
5128 5205          char pool_err[128];
5129      -        char zpath[MAXPATHLEN];
5130 5206          char cmdbuf[MAXPATHLEN];
5131 5207          brand_handle_t bh = NULL;
5132 5208          dladm_status_t status;
5133 5209          char errmsg[DLADM_STRSIZE];
5134 5210          ushort_t flags;
5135 5211  
5136 5212          kzone = zone_name;
5137 5213          if (zonecfg_in_alt_root()) {
5138 5214                  FILE *fp;
5139 5215  
↓ open down ↓ 35 lines elided ↑ open up ↑
5175 5251           * part of zone_shutdown() so that we need to remove protect/pool etc.
5176 5252           * before zone_shutdown(). Even if the shutdown itself fails, the zone
5177 5253           * will not be able to violate any constraints applied because the
5178 5254           * datalinks are no longer available to the zone.
5179 5255           */
5180 5256          if (zone_shutdown(zoneid) != 0) {
5181 5257                  zerror(zlogp, B_TRUE, "unable to shutdown zone");
5182 5258                  goto error;
5183 5259          }
5184 5260  
5185      -        /* Get the zonepath of this zone */
5186      -        if (zone_get_zonepath(zone_name, zpath, sizeof (zpath)) != Z_OK) {
5187      -                zerror(zlogp, B_FALSE, "unable to determine zone path");
5188      -                goto error;
5189      -        }
5190      -
5191 5261          /* Get a handle to the brand info for this zone */
5192 5262          if ((bh = brand_open(brand_name)) == NULL) {
5193 5263                  zerror(zlogp, B_FALSE, "unable to determine zone brand");
5194 5264                  return (-1);
5195 5265          }
5196 5266          /*
5197 5267           * If there is a brand 'halt' callback, execute it now to give the
5198 5268           * brand a chance to cleanup any custom configuration.
5199 5269           */
5200 5270          (void) strcpy(cmdbuf, EXEC_PREFIX);
5201      -        if (brand_get_halt(bh, zone_name, zpath, cmdbuf + EXEC_LEN,
     5271 +        if (brand_get_halt(bh, zone_name, zonepath, cmdbuf + EXEC_LEN,
5202 5272              sizeof (cmdbuf) - EXEC_LEN) < 0) {
5203 5273                  brand_close(bh);
5204 5274                  zerror(zlogp, B_FALSE, "unable to determine branded zone's "
5205 5275                      "halt callback.");
5206 5276                  goto error;
5207 5277          }
5208 5278          brand_close(bh);
5209 5279  
5210 5280          if ((strlen(cmdbuf) > EXEC_LEN) &&
5211 5281              (do_subproc(zlogp, cmdbuf, NULL) != Z_OK)) {
↓ open down ↓ 113 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX