Print this page
OS-3342+co
OS-722
OS-478 -- lint
OS-375-1
OS-328 dlmgmtd/mac_link_flow_add() deadlock
OS-249

*** 19,28 **** --- 19,29 ---- * CDDL HEADER END */ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ /* * Main door handler functions used by dlmgmtd to process the different door * call requests. Door call requests can come from the user-land applications,
*** 56,65 **** --- 57,70 ---- #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 *);
*** 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; }
*** 437,446 **** --- 447,460 ---- dlmgmt_door_getlinkid_t *getlinkid = argp; dlmgmt_getlinkid_retval_t *retvalp = retp; dlmgmt_link_t *linkp; int err = 0; + /* Enable the global zone to lookup links it has given away. */ + if (zoneid == GLOBAL_ZONEID && getlinkid->ld_zoneid != -1) + zoneid = getlinkid->ld_zoneid; + /* * Hold the reader lock to access the link */ dlmgmt_table_lock(B_FALSE);
*** 646,655 **** --- 660,675 ---- } 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 **** --- 727,741 ---- } 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 **** --- 1239,1253 ---- } 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; }
*** 1243,1253 **** err = errno; dlmgmt_log(LOG_WARNING, "unable to remove link %d from " "zone %d: %s", linkid, oldzoneid, strerror(err)); goto done; } ! avl_remove(&dlmgmt_loan_avl, linkp); linkp->ll_onloan = B_FALSE; } if (newzoneid != GLOBAL_ZONEID) { if (zone_add_datalink(newzoneid, linkid) != 0) { err = errno; --- 1273,1295 ---- err = errno; dlmgmt_log(LOG_WARNING, "unable to remove link %d from " "zone %d: %s", linkid, oldzoneid, strerror(err)); goto done; } ! ! if (newzoneid == GLOBAL_ZONEID && linkp->ll_onloan) { ! /* ! * We can only reassign a loaned VNIC back to the ! * global zone when the zone is shutting down, since ! * otherwise the VNIC is in use by the zone and will be ! * busy. Leave the VNIC assigned to the zone so we can ! * still see it and delete it when dlmgmt_zonehalt() ! * runs. ! */ ! goto done; ! } ! linkp->ll_onloan = B_FALSE; } if (newzoneid != GLOBAL_ZONEID) { if (zone_add_datalink(newzoneid, linkid) != 0) { err = errno;
*** 1254,1264 **** dlmgmt_log(LOG_WARNING, "unable to add link %d to zone " "%d: %s", linkid, newzoneid, strerror(err)); (void) zone_add_datalink(oldzoneid, linkid); goto done; } - avl_add(&dlmgmt_loan_avl, linkp); linkp->ll_onloan = B_TRUE; } avl_remove(&dlmgmt_name_avl, linkp); linkp->ll_zoneid = newzoneid; --- 1296,1305 ----
*** 1307,1326 **** --- 1348,1388 ---- 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; }