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; }