diff options
| author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-04-12 15:46:06 -0700 |
|---|---|---|
| committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2011-04-12 15:46:06 -0700 |
| commit | 3925eabb01912ea68ad1a482e7750865d7d8941d (patch) | |
| tree | 9cfc270832b0bdf4f3ecc948e674e195ca2a5c27 /usr/src/cmd/dlmgmtd | |
| parent | 16e1bf65c89fb01d6f0a244c67de0e7e90736f17 (diff) | |
| download | illumos-joyent-3925eabb01912ea68ad1a482e7750865d7d8941d.tar.gz | |
OS-375 i_dls_mgmt_upcall()/dlmgmt_zfop() deadlock in dlmgmtd
OS-376 vnic_dev_create()/dlmgmt_table_lock()/vnic_dev_delete() deadlock
OS-378 dlmgmt_zonehalt()/dlmgmt_upcall_getattr() deadlock
Diffstat (limited to 'usr/src/cmd/dlmgmtd')
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_door.c | 37 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_impl.h | 3 | ||||
| -rw-r--r-- | usr/src/cmd/dlmgmtd/dlmgmt_main.c | 2 |
3 files changed, 23 insertions, 19 deletions
diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_door.c b/usr/src/cmd/dlmgmtd/dlmgmt_door.c index e3e7fccd84..acb44870a8 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_door.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_door.c @@ -59,7 +59,9 @@ #include <libsysevent.h> #include <libdlmgmt.h> #include <librcm.h> -#include <thread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> #include "dlmgmt_impl.h" typedef void dlmgmt_door_handler_t(void *, void *, size_t *, zoneid_t, @@ -1318,14 +1320,6 @@ done: retvalp->lr_err = err; } -static void -do_zonehalt(void *zid) -{ - dlmgmt_table_lock(B_TRUE); - dlmgmt_db_fini((zoneid_t)zid); - dlmgmt_table_unlock(); -} - /* ARGSUSED */ static void dlmgmt_zonehalt(void *argp, void *retp, size_t *sz, zoneid_t zoneid, @@ -1350,17 +1344,22 @@ dlmgmt_zonehalt(void *argp, void *retp, size_t *sz, zoneid_t zoneid, * dls_devnet_destroy calls mac_perim_enter_by_mh * which could lead to deadlock if another process is * holding the mac perimeter then made an upcall to - * dlmgmtd. To avoid this, we run the dlmgmt_db_fini - * in a thread so that we can continue to service - * upcalls in parallel with cleaning up zones. + * dlmgmtd. To try to avoid this, we serialize zone + * activity on the /etc/dladm/zone.lck file. */ - err = thr_create(NULL, 0, - (void *(*)(void *))do_zonehalt, - (void *)(zonehalt->ld_zoneid), THR_DAEMON, NULL); - if (err != 0) - dlmgmt_log(LOG_ERR, "unable to create thread " - "to clean up zone %d: %s", - zonehalt->ld_zoneid, strerror(err)); + int fd; + + while ((fd = open(ZONE_LOCK, + O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) + < 0) + sleep(1); + close(fd); + + dlmgmt_table_lock(B_TRUE); + dlmgmt_db_fini(zonehalt->ld_zoneid); + dlmgmt_table_unlock(); + + (void) unlink(ZONE_LOCK); } } retvalp->lr_err = err; diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h index cdfd0d8a4d..780a18ce5a 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_impl.h +++ b/usr/src/cmd/dlmgmtd/dlmgmt_impl.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, Joyent Inc. All rights reserved. */ /* @@ -84,6 +85,8 @@ typedef struct dlmgmt_dlconf_s { avl_node_t ld_node; } dlmgmt_dlconf_t; +#define ZONE_LOCK "/etc/dladm/zone.lck" + extern boolean_t debug; extern const char *progname; extern char cachefile[]; diff --git a/usr/src/cmd/dlmgmtd/dlmgmt_main.c b/usr/src/cmd/dlmgmtd/dlmgmt_main.c index 75e620a36b..7a26440a3f 100644 --- a/usr/src/cmd/dlmgmtd/dlmgmt_main.c +++ b/usr/src/cmd/dlmgmtd/dlmgmt_main.c @@ -287,6 +287,8 @@ dlmgmt_init(void) 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. |
