Print this page
Forgot to merge in unlink of ZONE_LOCK in dlmgmtd.
dlmgmt mismerge
Mismerge dlmgmt_door.c
OS-3342 dlmgmtd needs to be mindful of lock ordering
OS-2608 dlmgmtd needs to record zone identifiers
OS-3492 zone_free asserts to its destruction when dlmgmtd has fallen
OS-3494 zoneadmd tears down networking too soon when boot fails
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>

@@ -56,12 +56,17 @@
 #include <sys/sysevent/eventdefs.h>
 #include <zone.h>
 #include <libsysevent.h>
 #include <libdlmgmt.h>
 #include <librcm.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
 #include "dlmgmt_impl.h"
 
+
 typedef void dlmgmt_door_handler_t(void *, void *, size_t *, zoneid_t,
     ucred_t *);
 
 typedef struct dlmgmt_door_info_s {
         uint_t                  di_cmd;

@@ -377,10 +382,15 @@
         }
 
         if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0)
                 goto done;
 
+        if (linkp->ll_tomb == B_TRUE) {
+                err = EINPROGRESS;
+                goto done;
+        }
+
         if (((linkp->ll_flags & flags) & DLMGMT_ACTIVE) != 0) {
                 if ((err = dlmgmt_delete_db_entry(linkp, DLMGMT_ACTIVE)) != 0)
                         goto done;
                 dflags |= DLMGMT_ACTIVE;
         }

@@ -646,10 +656,16 @@
         }
 
         if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0)
                 goto done;
 
+        if (linkp->ll_tomb == B_TRUE) {
+                err = EBUSY;
+                goto done;
+        }
+
+
         if (link_by_name(remapid->ld_link, linkp->ll_zoneid) != NULL) {
                 err = EEXIST;
                 goto done;
         }
 

@@ -707,10 +723,15 @@
         }
 
         if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0)
                 goto done;
 
+        if (linkp->ll_tomb == B_TRUE) {
+                err = EBUSY;
+                goto done;
+        }
+
         if (linkp->ll_flags & DLMGMT_ACTIVE) {
                 err = EINVAL;
                 goto done;
         }
 

@@ -1214,10 +1235,15 @@
         }
 
         if ((err = dlmgmt_checkprivs(linkp->ll_class, cred)) != 0)
                 goto done;
 
+        if (linkp->ll_tomb == B_TRUE) {
+                err = EBUSY;
+                goto done;
+        }
+
         /* We can only assign an active link to a zone. */
         if (!(linkp->ll_flags & DLMGMT_ACTIVE)) {
                 err = EINVAL;
                 goto done;
         }

@@ -1307,20 +1333,41 @@
     ucred_t *cred)
 {
         int                     err = 0;
         dlmgmt_door_zonehalt_t  *zonehalt = argp;
         dlmgmt_zonehalt_retval_t *retvalp = retp;
+        static char my_pid[10];
 
+        if (my_pid[0] == NULL)
+                (void) snprintf(my_pid, sizeof (my_pid), "%d\n", getpid());
+
         if ((err = dlmgmt_checkprivs(0, cred)) == 0) {
                 if (zoneid != GLOBAL_ZONEID) {
                         err = EACCES;
                 } else if (zonehalt->ld_zoneid == GLOBAL_ZONEID) {
                         err = EINVAL;
                 } else {
+                        /*
+                         * dls and mac don't honor the locking rules defined in
+                         * mac. In order to try and make that case less likely
+                         * to happen, we try to serialize some of the zone
+                         * activity here between dlmgmtd and the brands on
+                         * /etc/dladm/zone.lck
+                         */
+                        int fd;
+
+                        while ((fd = open(ZONE_LOCK, O_WRONLY |
+                            O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
+                        (void) sleep(1);
+                        (void) write(fd, my_pid, sizeof (my_pid));
+                        (void) close(fd);
+
                         dlmgmt_table_lock(B_TRUE);
                         dlmgmt_db_fini(zonehalt->ld_zoneid);
                         dlmgmt_table_unlock();
+
+                        (void) unlink(ZONE_LOCK);
                 }
         }
         retvalp->lr_err = err;
 }