summaryrefslogtreecommitdiff
path: root/usr/src/cmd/dlmgmtd
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2011-04-12 15:46:06 -0700
committerJerry Jelinek <jerry.jelinek@joyent.com>2011-04-12 15:46:06 -0700
commit3925eabb01912ea68ad1a482e7750865d7d8941d (patch)
tree9cfc270832b0bdf4f3ecc948e674e195ca2a5c27 /usr/src/cmd/dlmgmtd
parent16e1bf65c89fb01d6f0a244c67de0e7e90736f17 (diff)
downloadillumos-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.c37
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_impl.h3
-rw-r--r--usr/src/cmd/dlmgmtd/dlmgmt_main.c2
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.