Print this page
OS-3007 dlmgmtd needs to work with non-native zones
OS-1572
OS-375 i_dls_mgmt_upcall()/dlmgmt_zfop() deadlock in dlmgmtd
OS-375-1
OS-327

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/dlmgmtd/dlmgmt_main.c
          +++ new/usr/src/cmd/dlmgmtd/dlmgmt_main.c
↓ open down ↓ 14 lines elided ↑ open up ↑
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
       25 + * Copyright 2014 Joyent, Inc.  All rights reserved.
  25   26   */
  26   27  
  27   28  /*
  28   29   * The dlmgmtd daemon is started by the datalink-management SMF service.
  29   30   * This daemon is used to manage <link name, linkid> mapping and the
  30   31   * persistent datalink configuration.
  31   32   *
  32   33   * Today, the <link name, linkid> mapping and the persistent configuration
  33   34   * of datalinks is kept in /etc/dladm/datalink.conf, and the daemon keeps
  34   35   * a copy of the datalinks in the memory (see dlmgmt_id_avl and
↓ open down ↓ 83 lines elided ↑ open up ↑
 118  119                  return;
 119  120  
 120  121          if (door_revoke(dlmgmt_door_fd) == -1) {
 121  122                  dlmgmt_log(LOG_WARNING, "door_revoke(%s) failed: %s",
 122  123                      DLMGMT_DOOR, strerror(errno));
 123  124          }
 124  125          (void) dlmgmt_set_doorfd(B_FALSE);
 125  126          dlmgmt_door_fd = -1;
 126  127  }
 127  128  
 128      -int
      129 +static int
 129  130  dlmgmt_door_attach(zoneid_t zoneid, char *rootdir)
 130  131  {
 131  132          int     fd;
 132  133          int     err = 0;
 133  134          char    doorpath[MAXPATHLEN];
      135 +        struct stat statbuf;
 134  136  
 135      -        (void) snprintf(doorpath, sizeof (doorpath), "%s%s", rootdir,
 136      -            DLMGMT_DOOR);
      137 +        /* Handle running in a non-native branded zone (i.e. has /native) */
      138 +        (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
      139 +            rootdir, DLMGMT_TMPFS_DIR);
      140 +        if (stat(doorpath, &statbuf) == 0) {
      141 +                (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
      142 +                    rootdir, DLMGMT_DOOR);
      143 +        } else {
      144 +                (void) snprintf(doorpath, sizeof (doorpath), "%s%s",
      145 +                    rootdir, DLMGMT_DOOR);
      146 +        }
 137  147  
 138  148          /*
 139  149           * Create the door file for dlmgmtd.
 140  150           */
 141  151          if ((fd = open(doorpath, O_CREAT|O_RDONLY, 0644)) == -1) {
 142  152                  err = errno;
 143  153                  dlmgmt_log(LOG_ERR, "open(%s) failed: %s", doorpath,
 144  154                      strerror(err));
 145  155                  return (err);
 146  156          }
↓ open down ↓ 38 lines elided ↑ open up ↑
 185  195              sizeof (rootdir)) < 0) {
 186  196                  return (errno);
 187  197          }
 188  198  
 189  199          /*
 190  200           * Create the DLMGMT_TMPFS_DIR directory.
 191  201           */
 192  202          (void) snprintf(tmpfsdir, sizeof (tmpfsdir), "%s%s", rootdir,
 193  203              DLMGMT_TMPFS_DIR);
 194  204          if (stat(tmpfsdir, &statbuf) < 0) {
 195      -                if (mkdir(tmpfsdir, (mode_t)0755) < 0)
 196      -                        return (errno);
      205 +                if (mkdir(tmpfsdir, (mode_t)0755) < 0) {
      206 +                        /*
      207 +                         * Handle running in a non-native branded zone
      208 +                         * (i.e. has /native)
      209 +                         */
      210 +                        (void) snprintf(tmpfsdir, sizeof (tmpfsdir),
      211 +                            "%s/native%s", rootdir, DLMGMT_TMPFS_DIR);
      212 +                        if (mkdir(tmpfsdir, (mode_t)0755) < 0)
      213 +                                return (errno);
      214 +                }
 197  215          } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
 198  216                  return (ENOTDIR);
 199  217          }
 200  218  
 201  219          if ((chmod(tmpfsdir, 0755) < 0) ||
 202  220              (chown(tmpfsdir, UID_DLADM, GID_NETADM) < 0)) {
 203  221                  return (EPERM);
 204  222          }
 205  223  
 206      -        if ((err = dlmgmt_db_init(zoneid)) != 0)
      224 +        if ((err = dlmgmt_db_init(zoneid, rootdir)) != 0)
 207  225                  return (err);
 208  226          return (dlmgmt_door_attach(zoneid, rootdir));
 209  227  }
 210  228  
 211  229  /*
 212  230   * Initialize each running zone.
 213  231   */
 214  232  static int
 215  233  dlmgmt_allzones_init(void)
 216  234  {
 217      -        int             err, i;
      235 +        int             i;
 218  236          zoneid_t        *zids = NULL;
 219  237          uint_t          nzids, nzids_saved;
 220  238  
 221  239          if (zone_list(NULL, &nzids) != 0)
 222  240                  return (errno);
 223  241  again:
 224  242          nzids *= 2;
 225  243          if ((zids = malloc(nzids * sizeof (zoneid_t))) == NULL)
 226  244                  return (errno);
 227  245          nzids_saved = nzids;
 228  246          if (zone_list(zids, &nzids) != 0) {
 229  247                  free(zids);
 230  248                  return (errno);
 231  249          }
 232  250          if (nzids > nzids_saved) {
 233  251                  free(zids);
 234  252                  goto again;
 235  253          }
 236  254  
 237  255          for (i = 0; i < nzids; i++) {
 238      -                if ((err = dlmgmt_zone_init(zids[i])) != 0)
 239      -                        break;
      256 +                int res;
      257 +                zone_status_t status;
      258 +
      259 +                /*
      260 +                 * Skip over zones that have gone away or are going down
      261 +                 * since we got the list.  Process all zones in the list,
      262 +                 * logging errors for any that failed.
      263 +                 */
      264 +                if (zone_getattr(zids[i], ZONE_ATTR_STATUS, &status,
      265 +                    sizeof (status)) < 0)
      266 +                        continue;
      267 +                switch (status) {
      268 +                        case ZONE_IS_SHUTTING_DOWN:
      269 +                        case ZONE_IS_EMPTY:
      270 +                        case ZONE_IS_DOWN:
      271 +                        case ZONE_IS_DYING:
      272 +                        case ZONE_IS_DEAD:
      273 +                                /* FALLTHRU */
      274 +                                continue;
      275 +                        default:
      276 +                                break;
      277 +                }
      278 +                if ((res = dlmgmt_zone_init(zids[i])) != 0) {
      279 +                        (void) fprintf(stderr, "zone (%ld) init error %s",
      280 +                            zids[i], strerror(res));
      281 +                        dlmgmt_log(LOG_ERR, "zone (%d) init error %s",
      282 +                            zids[i], strerror(res));
      283 +                }
 240  284          }
 241  285          free(zids);
 242      -        return (err);
      286 +        return (0);
 243  287  }
 244  288  
 245  289  static int
 246  290  dlmgmt_init(void)
 247  291  {
 248  292          int     err;
 249  293          char    *fmri, *c;
 250  294          char    filename[MAXPATHLEN];
 251  295  
 252  296          if (dladm_open(&dld_handle) != DLADM_STATUS_OK) {
↓ open down ↓ 2 lines elided ↑ open up ↑
 255  299          }
 256  300  
 257  301          if (signal(SIGTERM, dlmgmtd_exit) == SIG_ERR ||
 258  302              signal(SIGINT, dlmgmtd_exit) == SIG_ERR) {
 259  303                  err = errno;
 260  304                  dlmgmt_log(LOG_ERR, "signal() for SIGTERM/INT failed: %s",
 261  305                      strerror(err));
 262  306                  return (err);
 263  307          }
 264  308  
      309 +        (void) unlink(ZONE_LOCK);
      310 +
 265  311          /*
 266  312           * First derive the name of the cache file from the FMRI name. This
 267  313           * cache name is used to keep active datalink configuration.
 268  314           */
 269  315          if (debug) {
 270  316                  (void) snprintf(cachefile, MAXPATHLEN, "%s/%s%s",
 271  317                      DLMGMT_TMPFS_DIR, progname, ".debug.cache");
 272  318          } else {
 273  319                  if ((fmri = getenv("SMF_FMRI")) == NULL) {
 274  320                          dlmgmt_log(LOG_ERR, "dlmgmtd is an smf(5) managed "
↓ open down ↓ 272 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX