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,67 ****
--- 56,72 ----
  #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,386 ****
--- 382,396 ----
          }
  
          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,655 ****
--- 656,671 ----
          }
  
          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,716 ****
--- 723,737 ----
          }
  
          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,1223 ****
--- 1235,1249 ----
          }
  
          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,1326 ****
--- 1333,1373 ----
      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;
  }