summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2015-03-23 18:22:22 +0000
committerRobert Mustacchi <rm@joyent.com>2015-03-23 18:58:56 +0000
commit43489f9fd43ea92de4a6795588b0ab45ceb4668e (patch)
tree719946e86c35e994310ee9d5cedfb1603a22e724 /usr/src
parent6e09664c777b4c9bb52577dfab3a1552c2b6b72e (diff)
downloadillumos-joyent-43489f9fd43ea92de4a6795588b0ab45ceb4668e.tar.gz
OS-4080 launching a second varpd confuses the world
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/lib/varpd/libvarpd/common/libvarpd_overlay.c2
-rw-r--r--usr/src/uts/common/io/overlay/overlay_target.c24
2 files changed, 24 insertions, 2 deletions
diff --git a/usr/src/lib/varpd/libvarpd/common/libvarpd_overlay.c b/usr/src/lib/varpd/libvarpd/common/libvarpd_overlay.c
index 4213694c8a..c7c69da7be 100644
--- a/usr/src/lib/varpd/libvarpd/common/libvarpd_overlay.c
+++ b/usr/src/lib/varpd/libvarpd/common/libvarpd_overlay.c
@@ -36,7 +36,7 @@
int
libvarpd_overlay_init(varpd_impl_t *vip)
{
- vip->vdi_overlayfd = open(OVERLAY_PATH, O_RDWR);
+ vip->vdi_overlayfd = open(OVERLAY_PATH, O_RDWR | O_EXCL);
if (vip->vdi_overlayfd == -1)
return (errno);
return (0);
diff --git a/usr/src/uts/common/io/overlay/overlay_target.c b/usr/src/uts/common/io/overlay/overlay_target.c
index 9d3e4eb200..c2da20c883 100644
--- a/usr/src/uts/common/io/overlay/overlay_target.c
+++ b/usr/src/uts/common/io/overlay/overlay_target.c
@@ -59,6 +59,7 @@
typedef struct overlay_target_hdl {
minor_t oth_minor; /* RO */
zoneid_t oth_zoneid; /* RO */
+ int oth_oflags; /* RO */
list_node_t oth_link; /* overlay_target_lock */
kmutex_t oth_lock;
list_t oth_outstanding; /* oth_lock */
@@ -92,6 +93,7 @@ static list_t overlay_thdl_list;
static kmutex_t overlay_target_lock;
static kcondvar_t overlay_target_condvar;
static list_t overlay_target_list;
+static boolean_t overlay_target_excl;
/*
* Outstanding data per hash table entry.
@@ -1519,7 +1521,11 @@ overlay_target_open(dev_t *devp, int flags, int otype, cred_t *credp)
if (otype & OTYP_BLK)
return (EINVAL);
- if (flags & ~(FREAD | FWRITE))
+ if (flags & ~(FREAD | FWRITE | FEXCL))
+ return (EINVAL);
+
+ if ((flags & FWRITE) &&
+ !(flags & FEXCL))
return (EINVAL);
if (!(flags & FREAD) && !(flags & FWRITE))
@@ -1538,12 +1544,24 @@ overlay_target_open(dev_t *devp, int flags, int otype, cred_t *credp)
VERIFY(thdl != NULL);
thdl->oth_minor = mid;
thdl->oth_zoneid = crgetzoneid(credp);
+ thdl->oth_oflags = flags;
mutex_init(&thdl->oth_lock, NULL, MUTEX_DRIVER, NULL);
list_create(&thdl->oth_outstanding, sizeof (overlay_target_entry_t),
offsetof(overlay_target_entry_t, ote_qlink));
*devp = makedevice(getmajor(*devp), mid);
mutex_enter(&overlay_target_lock);
+ if ((flags & FEXCL) && overlay_target_excl == B_TRUE) {
+ mutex_exit(&overlay_target_lock);
+ list_destroy(&thdl->oth_outstanding);
+ mutex_destroy(&thdl->oth_lock);
+ ddi_soft_state_free(overlay_thdl_state, mid);
+ id_free(overlay_thdl_idspace, mid);
+ return (EEXIST);
+ } else if ((flags & FEXCL) != 0) {
+ VERIFY(overlay_target_excl == B_FALSE);
+ overlay_target_excl = B_TRUE;
+ }
list_insert_tail(&overlay_thdl_list, thdl);
mutex_exit(&overlay_target_lock);
@@ -1628,6 +1646,10 @@ overlay_target_close(dev_t dev, int flags, int otype, cred_t *credp)
list_insert_tail(&overlay_target_list, entry);
cv_signal(&overlay_target_condvar);
mutex_exit(&thdl->oth_lock);
+ if ((thdl->oth_oflags & FEXCL) != 0) {
+ VERIFY(overlay_target_excl == B_TRUE);
+ overlay_target_excl = B_FALSE;
+ }
mutex_exit(&overlay_target_lock);
list_destroy(&thdl->oth_outstanding);