diff options
author | Toomas Soome <tsoome@me.com> | 2016-09-16 01:57:23 +0300 |
---|---|---|
committer | Dan McDonald <danmcd@omniti.com> | 2016-09-29 21:16:59 -0400 |
commit | 8ae05c101a3c849364fa53a66ec87aa59823326a (patch) | |
tree | f7f795d2fe124c05b3087ade2ec03cab15b0dc64 /usr/src | |
parent | 5cbe397111597bc67a2d5d429b52a503f55a14b3 (diff) | |
download | illumos-gate-8ae05c101a3c849364fa53a66ec87aa59823326a.tar.gz |
7392 remove event channel support from lofi and implement lofi_devlink_cache.
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Approved by: Dan McDonald <danmcd@omniti.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/uts/common/io/lofi.c | 115 | ||||
-rw-r--r-- | usr/src/uts/common/os/log_sysevent.c | 64 | ||||
-rw-r--r-- | usr/src/uts/common/sys/Makefile | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/lofi_impl.h | 41 |
4 files changed, 110 insertions, 111 deletions
diff --git a/usr/src/uts/common/io/lofi.c b/usr/src/uts/common/io/lofi.c index d4b8ed4b1e..c358b0d067 100644 --- a/usr/src/uts/common/io/lofi.c +++ b/usr/src/uts/common/io/lofi.c @@ -128,6 +128,7 @@ #include <sys/debug.h> #include <sys/vnode.h> #include <sys/lofi.h> +#include <sys/lofi_impl.h> /* for cache structure */ #include <sys/fcntl.h> #include <sys/pathname.h> #include <sys/filio.h> @@ -167,12 +168,7 @@ return (EINVAL); \ } -#define DEVFS_CHANNEL "devfsadm_event_channel" #define LOFI_TIMEOUT 30 -static evchan_t *lofi_chan; -static kmutex_t lofi_chan_lock; -static kcondvar_t lofi_chan_cv; -static nvlist_t *lofi_devlink_cache; static void *lofi_statep; static kmutex_t lofi_lock; /* state lock */ @@ -1897,51 +1893,6 @@ err: return (error); } -/*ARGSUSED*/ -static int -lofi_dev_callback(sysevent_t *ev, void *cookie) -{ - nvlist_t *nvlist; - char *class, *driver; - char name[10]; - int32_t instance; - - class = sysevent_get_class_name(ev); - if (strcmp(class, EC_DEV_ADD) && strcmp(class, EC_DEV_REMOVE)) - return (0); - - (void) sysevent_get_attr_list(ev, &nvlist); - driver = fnvlist_lookup_string(nvlist, DEV_DRIVER_NAME); - instance = fnvlist_lookup_int32(nvlist, DEV_INSTANCE); - - if (strcmp(driver, LOFI_DRIVER_NAME) != 0) { - fnvlist_free(nvlist); - return (0); - } - - /* - * insert or remove device info, then announce the change - * via cv_broadcast. - * This allows the MAP/UNMAP to monitor device change. - */ - (void) snprintf(name, sizeof (name), "%d", instance); - if (strcmp(class, EC_DEV_ADD) == 0) { - mutex_enter(&lofi_chan_lock); - fnvlist_add_nvlist(lofi_devlink_cache, name, nvlist); - cv_broadcast(&lofi_chan_cv); - mutex_exit(&lofi_chan_lock); - } else if (strcmp(class, EC_DEV_REMOVE) == 0) { - mutex_enter(&lofi_chan_lock); - /* Can not use fnvlist_remove() as we can get ENOENT. */ - (void) nvlist_remove_all(lofi_devlink_cache, name); - cv_broadcast(&lofi_chan_cv); - mutex_exit(&lofi_chan_lock); - } - - fnvlist_free(nvlist); - return (0); -} - static int lofi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { @@ -1976,23 +1927,6 @@ lofi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) return (DDI_FAILURE); } - rv = sysevent_evc_bind(DEVFS_CHANNEL, &lofi_chan, - EVCH_CREAT | EVCH_HOLD_PEND); - if (rv == 0) { - rv = sysevent_evc_subscribe(lofi_chan, "lofi", - EC_ALL, lofi_dev_callback, NULL, 0); - rv |= sysevent_evc_subscribe(lofi_chan, "disk", - EC_ALL, lofi_dev_callback, NULL, 0); - } else - lofi_chan = NULL; - if (rv != 0) { - if (lofi_chan != NULL) - (void) sysevent_evc_unbind(lofi_chan); - ddi_prop_remove_all(dip); - ddi_remove_minor_node(dip, NULL); - ddi_soft_state_free(lofi_statep, 0); - return (DDI_FAILURE); - } zone_key_create(&lofi_zone_key, NULL, lofi_zone_shutdown, NULL); lsp->ls_dip = dip; @@ -2039,7 +1973,6 @@ lofi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) mutex_exit(&lofi_lock); - (void) sysevent_evc_unbind(lofi_chan); if (zone_key_delete(lofi_zone_key) != 0) cmn_err(CE_WARN, "failed to delete zone key"); @@ -2752,7 +2685,7 @@ lofi_copy_devpath(struct lofi_ioctl *klip) int error; char namebuf[MAXNAMELEN], *str; clock_t ticks; - nvlist_t *nvl; + nvlist_t *nvl = NULL; if (klip->li_labeled == B_TRUE) klip->li_devpath[0] = '\0'; @@ -2766,13 +2699,15 @@ lofi_copy_devpath(struct lofi_ioctl *klip) (void) snprintf(namebuf, sizeof (namebuf), "%d", klip->li_id); ticks = ddi_get_lbolt() + LOFI_TIMEOUT * drv_usectohz(1000000); - nvl = NULL; - - mutex_enter(&lofi_chan_lock); - while (nvlist_lookup_nvlist(lofi_devlink_cache, namebuf, &nvl) != 0) { - error = cv_timedwait(&lofi_chan_cv, &lofi_chan_lock, ticks); + mutex_enter(&lofi_devlink_cache.ln_lock); + error = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data, namebuf, &nvl); + while (error != 0) { + error = cv_timedwait(&lofi_devlink_cache.ln_cv, + &lofi_devlink_cache.ln_lock, ticks); if (error == -1) break; + error = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data, + namebuf, &nvl); } if (nvl != NULL) { @@ -2781,7 +2716,7 @@ lofi_copy_devpath(struct lofi_ioctl *klip) sizeof (klip->li_devpath)); } } - mutex_exit(&lofi_chan_lock); + mutex_exit(&lofi_devlink_cache.ln_lock); } /* @@ -3060,13 +2995,17 @@ out: */ (void) snprintf(name, sizeof (name), "%d", klip->li_id); ticks = ddi_get_lbolt() + LOFI_TIMEOUT * drv_usectohz(1000000); - mutex_enter(&lofi_chan_lock); - while (nvlist_lookup_nvlist(lofi_devlink_cache, name, &nvl) == 0) { - err = cv_timedwait(&lofi_chan_cv, &lofi_chan_lock, ticks); + mutex_enter(&lofi_devlink_cache.ln_lock); + err = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data, name, &nvl); + while (err == 0) { + err = cv_timedwait(&lofi_devlink_cache.ln_cv, + &lofi_devlink_cache.ln_lock, ticks); if (err == -1) break; + err = nvlist_lookup_nvlist(lofi_devlink_cache.ln_data, + name, &nvl); } - mutex_exit(&lofi_chan_lock); + mutex_exit(&lofi_devlink_cache.ln_lock); mutex_exit(&lofi_lock); (void) copy_out_lofi_ioctl(klip, ulip, ioctl_flag); @@ -3589,18 +3528,11 @@ _init(void) } mutex_init(&lofi_lock, NULL, MUTEX_DRIVER, NULL); - mutex_init(&lofi_chan_lock, NULL, MUTEX_DRIVER, NULL); - cv_init(&lofi_chan_cv, NULL, CV_DRIVER, NULL); - error = nvlist_alloc(&lofi_devlink_cache, NV_UNIQUE_NAME, KM_SLEEP); - if (error == 0) - error = mod_install(&modlinkage); + error = mod_install(&modlinkage); + if (error) { id_space_destroy(lofi_id); - if (lofi_devlink_cache != NULL) - nvlist_free(lofi_devlink_cache); - mutex_destroy(&lofi_chan_lock); - cv_destroy(&lofi_chan_cv); mutex_destroy(&lofi_lock); ddi_soft_state_fini((void **)&lofi_statep); list_destroy(&lofi_list); @@ -3627,13 +3559,6 @@ _fini(void) if (error) return (error); - mutex_enter(&lofi_chan_lock); - nvlist_free(lofi_devlink_cache); - lofi_devlink_cache = NULL; - mutex_exit(&lofi_chan_lock); - - mutex_destroy(&lofi_chan_lock); - cv_destroy(&lofi_chan_cv); mutex_destroy(&lofi_lock); id_space_destroy(lofi_id); ddi_soft_state_fini((void **)&lofi_statep); diff --git a/usr/src/uts/common/os/log_sysevent.c b/usr/src/uts/common/os/log_sysevent.c index 9739d4dbdf..0b4fe18af3 100644 --- a/usr/src/uts/common/os/log_sysevent.c +++ b/usr/src/uts/common/os/log_sysevent.c @@ -37,6 +37,7 @@ #include <sys/sysevent_impl.h> #include <sys/sysevent/dev.h> #include <sys/modctl.h> +#include <sys/lofi_impl.h> #include <sys/sysmacros.h> #include <sys/disp.h> #include <sys/autoconf.h> @@ -149,6 +150,9 @@ static kmutex_t event_pause_mutex; static kcondvar_t event_pause_cv; static int event_pause_state = 0; +/* Cached device links for lofi. */ +lofi_nvl_t lofi_devlink_cache; + /*ARGSUSED*/ static void log_event_busy_timeout(void *arg) @@ -438,11 +442,26 @@ log_event_deliver() } /* + * Set up the nvlist based data cache. User by lofi to find + * device name for mapped file. + */ +static void +lofi_nvl_init(lofi_nvl_t *cache) +{ + mutex_init(&cache->ln_lock, NULL, MUTEX_DRIVER, NULL); + cv_init(&cache->ln_cv, NULL, CV_DRIVER, NULL); + (void) nvlist_alloc(&cache->ln_data, NV_UNIQUE_NAME, KM_SLEEP); +} + +/* * log_event_init - Allocate and initialize log_event data structures. */ void log_event_init() { + /* Set up devlink cache for lofi. */ + lofi_nvl_init(&lofi_devlink_cache); + mutex_init(&event_door_mutex, NULL, MUTEX_DEFAULT, NULL); mutex_init(&eventq_head_mutex, NULL, MUTEX_DEFAULT, NULL); @@ -1752,29 +1771,42 @@ log_sysevent(sysevent_t *ev, int flag, sysevent_id_t *eid) static void notify_lofi(sysevent_t *ev) { - static evchan_t *devfs_chan = NULL; nvlist_t *nvlist; - int ret; + char name[10], *class, *driver; + int32_t instance; - if ((strcmp(EC_DEV_ADD, sysevent_get_class_name(ev)) != 0) && - (strcmp(EC_DEV_REMOVE, sysevent_get_class_name(ev)) != 0)) + class = sysevent_get_class_name(ev); + if ((strcmp(EC_DEV_ADD, class) != 0) && + (strcmp(EC_DEV_REMOVE, class) != 0)) { return; - - /* only bind once to avoid bind/unbind storm on busy system */ - if (devfs_chan == NULL) { - if ((ret = sysevent_evc_bind("devfsadm_event_channel", - &devfs_chan, EVCH_CREAT | EVCH_HOLD_PEND)) != 0) { - cmn_err(CE_CONT, "sysevent_evc_bind failed: %d\n", ret); - return; - } } (void) sysevent_get_attr_list(ev, &nvlist); - (void) sysevent_evc_publish(devfs_chan, sysevent_get_class_name(ev), - sysevent_get_subclass_name(ev), "illumos", EC_DEVFS, nvlist, - EVCH_SLEEP); + driver = fnvlist_lookup_string(nvlist, DEV_DRIVER_NAME); + instance = fnvlist_lookup_int32(nvlist, DEV_INSTANCE); + + /* We are only interested about lofi. */ + if (strcmp(driver, "lofi") != 0) { + fnvlist_free(nvlist); + return; + } + + /* + * insert or remove device info, then announce the change + * via cv_broadcast. + */ + (void) snprintf(name, sizeof (name), "%d", instance); + mutex_enter(&lofi_devlink_cache.ln_lock); + if (strcmp(class, EC_DEV_ADD) == 0) { + fnvlist_add_nvlist(lofi_devlink_cache.ln_data, name, nvlist); + } else { + /* Can not use fnvlist_remove() as we can get ENOENT. */ + (void) nvlist_remove_all(lofi_devlink_cache.ln_data, name); + } + cv_broadcast(&lofi_devlink_cache.ln_cv); + mutex_exit(&lofi_devlink_cache.ln_lock); - nvlist_free(nvlist); + fnvlist_free(nvlist); } /* diff --git a/usr/src/uts/common/sys/Makefile b/usr/src/uts/common/sys/Makefile index d5dd20bff9..cb3187ae89 100644 --- a/usr/src/uts/common/sys/Makefile +++ b/usr/src/uts/common/sys/Makefile @@ -352,6 +352,7 @@ CHKHDRS= \ lockfs.h \ lockstat.h \ lofi.h \ + lofi_impl.h \ log.h \ logindmux.h \ logindmux_impl.h \ diff --git a/usr/src/uts/common/sys/lofi_impl.h b/usr/src/uts/common/sys/lofi_impl.h new file mode 100644 index 0000000000..5d2382eb5c --- /dev/null +++ b/usr/src/uts/common/sys/lofi_impl.h @@ -0,0 +1,41 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2016 Toomas Soome <tsoome@me.com> + */ + +#ifndef _SYS_LOFI_IMPL_H +#define _SYS_LOFI_IMPL_H + +/* + * lofi private implementation details. + */ + +#include <sys/nvpair.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* Structure for custom data, maintained as nvlist. */ +typedef struct lofi_nvl { + kmutex_t ln_lock; + kcondvar_t ln_cv; + nvlist_t *ln_data; +} lofi_nvl_t; + +extern lofi_nvl_t lofi_devlink_cache; +#ifdef __cplusplus +} +#endif + +#endif /* _SYS_LOFI_IMPL_H */ |