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

@@ -20,10 +20,11 @@
  */
 
 /*
  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2014 Joyent, Inc.  All rights reserved.
  */
 
 /*
  * The dlmgmtd daemon is started by the datalink-management SMF service.
  * This daemon is used to manage <link name, linkid> mapping and the

@@ -123,19 +124,28 @@
         }
         (void) dlmgmt_set_doorfd(B_FALSE);
         dlmgmt_door_fd = -1;
 }
 
-int
+static int
 dlmgmt_door_attach(zoneid_t zoneid, char *rootdir)
 {
         int     fd;
         int     err = 0;
         char    doorpath[MAXPATHLEN];
+        struct stat statbuf;
 
-        (void) snprintf(doorpath, sizeof (doorpath), "%s%s", rootdir,
-            DLMGMT_DOOR);
+        /* Handle running in a non-native branded zone (i.e. has /native) */
+        (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
+            rootdir, DLMGMT_TMPFS_DIR);
+        if (stat(doorpath, &statbuf) == 0) {
+                (void) snprintf(doorpath, sizeof (doorpath), "%s/native%s",
+                    rootdir, DLMGMT_DOOR);
+        } else {
+                (void) snprintf(doorpath, sizeof (doorpath), "%s%s",
+                    rootdir, DLMGMT_DOOR);
+        }
 
         /*
          * Create the door file for dlmgmtd.
          */
         if ((fd = open(doorpath, O_CREAT|O_RDONLY, 0644)) == -1) {

@@ -190,22 +200,30 @@
          * Create the DLMGMT_TMPFS_DIR directory.
          */
         (void) snprintf(tmpfsdir, sizeof (tmpfsdir), "%s%s", rootdir,
             DLMGMT_TMPFS_DIR);
         if (stat(tmpfsdir, &statbuf) < 0) {
+                if (mkdir(tmpfsdir, (mode_t)0755) < 0) {
+                        /*
+                         * Handle running in a non-native branded zone
+                         * (i.e. has /native)
+                         */
+                        (void) snprintf(tmpfsdir, sizeof (tmpfsdir),
+                            "%s/native%s", rootdir, DLMGMT_TMPFS_DIR);
                 if (mkdir(tmpfsdir, (mode_t)0755) < 0)
                         return (errno);
+                }
         } else if ((statbuf.st_mode & S_IFMT) != S_IFDIR) {
                 return (ENOTDIR);
         }
 
         if ((chmod(tmpfsdir, 0755) < 0) ||
             (chown(tmpfsdir, UID_DLADM, GID_NETADM) < 0)) {
                 return (EPERM);
         }
 
-        if ((err = dlmgmt_db_init(zoneid)) != 0)
+        if ((err = dlmgmt_db_init(zoneid, rootdir)) != 0)
                 return (err);
         return (dlmgmt_door_attach(zoneid, rootdir));
 }
 
 /*

@@ -212,11 +230,11 @@
  * Initialize each running zone.
  */
 static int
 dlmgmt_allzones_init(void)
 {
-        int             err, i;
+        int             i;
         zoneid_t        *zids = NULL;
         uint_t          nzids, nzids_saved;
 
         if (zone_list(NULL, &nzids) != 0)
                 return (errno);

@@ -233,15 +251,41 @@
                 free(zids);
                 goto again;
         }
 
         for (i = 0; i < nzids; i++) {
-                if ((err = dlmgmt_zone_init(zids[i])) != 0)
+                int res;
+                zone_status_t status;
+
+                /*
+                 * Skip over zones that have gone away or are going down
+                 * since we got the list.  Process all zones in the list,
+                 * logging errors for any that failed.
+                 */
+                if (zone_getattr(zids[i], ZONE_ATTR_STATUS, &status,
+                    sizeof (status)) < 0)
+                        continue;
+                switch (status) {
+                        case ZONE_IS_SHUTTING_DOWN:
+                        case ZONE_IS_EMPTY:
+                        case ZONE_IS_DOWN:
+                        case ZONE_IS_DYING:
+                        case ZONE_IS_DEAD:
+                                /* FALLTHRU */
+                                continue;
+                        default:
                         break;
         }
+                if ((res = dlmgmt_zone_init(zids[i])) != 0) {
+                        (void) fprintf(stderr, "zone (%ld) init error %s",
+                            zids[i], strerror(res));
+                        dlmgmt_log(LOG_ERR, "zone (%d) init error %s",
+                            zids[i], strerror(res));
+                }
+        }
         free(zids);
-        return (err);
+        return (0);
 }
 
 static int
 dlmgmt_init(void)
 {

@@ -260,10 +304,12 @@
                 dlmgmt_log(LOG_ERR, "signal() for SIGTERM/INT failed: %s",
                     strerror(err));
                 return (err);
         }
 
+        (void) unlink(ZONE_LOCK);
+
         /*
          * First derive the name of the cache file from the FMRI name. This
          * cache name is used to keep active datalink configuration.
          */
         if (debug) {