[dm-devel] [PATCH] libmultipath: lazy device-mapper initialization
Christophe Varoqui
christophe.varoqui at opensvc.com
Wed Jun 21 10:24:41 UTC 2017
Merged,
Thanks.
On Tue, Jun 6, 2017 at 9:33 PM, Martin Wilck <mwilck at suse.com> wrote:
> The multipath command fails early if libdevmapper and/or the
> dm_multipath driver are not found. But some multipath operations
> don't require device mapper, notably the path checking operations
> called from udev rules during early boot.
>
> This patch delays dm initialization until the first device-mapper
> call, allowing such operations to succeed even if the dm_multipath
> driver is not loaded yet.
>
> This fixes the following problem: during system boot, the dm_multipath
> driver is usually loaded via "ExecStartPre" from the multipathd service
> file. But with commit d7188fcd, this service is started only after
> udev settle and thus the modules are loaded too late for udev
> rule processing, causing "multipath" invocations from udev rules to fail
> and paths to be wrongly classified as non-multipath.
>
> Fixes: d7188fcd "multipathd: start daemon after udev trigger"
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
> libmultipath/devmapper.c | 79 ++++++++++++++++++++++++++++++
> ++++--------------
> libmultipath/devmapper.h | 4 ++-
> libmultipath/waiter.c | 2 +-
> multipath/main.c | 8 ++---
> multipathd/main.c | 4 +--
> 5 files changed, 63 insertions(+), 34 deletions(-)
>
> diff --git a/libmultipath/devmapper.c b/libmultipath/devmapper.c
> index 69b634bf..4319b381 100644
> --- a/libmultipath/devmapper.c
> +++ b/libmultipath/devmapper.c
> @@ -21,6 +21,7 @@
> #include "memory.h"
> #include "devmapper.h"
> #include "sysfs.h"
> +#include "config.h"
>
> #include "log_pthread.h"
> #include <sys/types.h>
> @@ -178,7 +179,7 @@ out:
> }
>
> static int
> -dm_drv_prereq (void)
> +dm_drv_prereq (unsigned int *ver)
> {
> unsigned int minv[3] = {1, 0, 3};
> unsigned int version[3] = {0, 0, 0};
> @@ -193,19 +194,51 @@ dm_drv_prereq (void)
> condlog(3, "DM multipath kernel driver v%u.%u.%u",
> v[0], v[1], v[2]);
>
> - if VERSION_GE(v, minv)
> + if (VERSION_GE(v, minv)) {
> + ver[0] = v[0];
> + ver[1] = v[1];
> + ver[2] = v[2];
> return 0;
> + }
>
> condlog(0, "DM multipath kernel driver must be >= v%u.%u.%u",
> minv[0], minv[1], minv[2]);
> return 1;
> }
>
> -int dm_prereq(void)
> +static int dm_prereq(unsigned int *v)
> {
> if (dm_lib_prereq())
> return 1;
> - return dm_drv_prereq();
> + return dm_drv_prereq(v);
> +}
> +
> +static int libmp_dm_udev_sync = 0;
> +
> +void libmp_udev_set_sync_support(int on)
> +{
> + libmp_dm_udev_sync = !!on;
> +}
> +
> +void libmp_dm_init(void)
> +{
> + struct config *conf;
> +
> + conf = get_multipath_config();
> + dm_init(conf->verbosity);
> + if (dm_prereq(conf->version))
> + exit(1);
> + put_multipath_config(conf);
> + dm_udev_set_sync_support(libmp_dm_udev_sync);
> +}
> +
> +struct dm_task*
> +libmp_dm_task_create(int task)
> +{
> + static pthread_once_t dm_initialized = PTHREAD_ONCE_INIT;
> +
> + pthread_once(&dm_initialized, libmp_dm_init);
> + return dm_task_create(task);
> }
>
> #define do_deferred(x) ((x) == DEFERRED_REMOVE_ON || (x) ==
> DEFERRED_REMOVE_IN_PROGRESS)
> @@ -219,7 +252,7 @@ dm_simplecmd (int task, const char *name, int
> no_flush, int need_sync, uint16_t
> uint32_t cookie = 0;
> struct dm_task *dmt;
>
> - if (!(dmt = dm_task_create (task)))
> + if (!(dmt = libmp_dm_task_create (task)))
> return 0;
>
> if (!dm_task_set_name (dmt, name))
> @@ -274,7 +307,7 @@ dm_addmap (int task, const char *target, struct
> multipath *mpp,
> uint32_t cookie = 0;
> uint16_t udev_flags = DM_UDEV_DISABLE_LIBRARY_FALLBACK |
> ((skip_kpartx == SKIP_KPARTX_ON)? MPATH_UDEV_NO_KPARTX_FLAG : 0);
>
> - if (!(dmt = dm_task_create (task)))
> + if (!(dmt = libmp_dm_task_create (task)))
> return 0;
>
> if (!dm_task_set_name (dmt, mpp->alias))
> @@ -411,7 +444,7 @@ do_get_info(const char *name, struct dm_info *info)
> int r = -1;
> struct dm_task *dmt;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO)))
> return r;
>
> if (!dm_task_set_name(dmt, name))
> @@ -449,7 +482,7 @@ int dm_get_map(const char *name, unsigned long long
> *size, char *outparams)
> char *target_type = NULL;
> char *params = NULL;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
> return 1;
>
> if (!dm_task_set_name(dmt, name))
> @@ -485,7 +518,7 @@ dm_get_prefixed_uuid(const char *name, char *uuid)
> const char *uuidtmp;
> int r = 1;
>
> - dmt = dm_task_create(DM_DEVICE_INFO);
> + dmt = libmp_dm_task_create(DM_DEVICE_INFO);
> if (!dmt)
> return 1;
>
> @@ -548,7 +581,7 @@ int dm_get_status(char *name, char *outstatus)
> char *target_type = NULL;
> char *status = NULL;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
> return 1;
>
> if (!dm_task_set_name(dmt, name))
> @@ -591,7 +624,7 @@ int dm_type(const char *name, char *type)
> char *target_type = NULL;
> char *params;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
> return 0;
>
> if (!dm_task_set_name(dmt, name))
> @@ -627,7 +660,7 @@ int dm_is_mpath(const char *name)
> char *params;
> const char *uuid;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
> return 0;
>
> if (!dm_task_set_name(dmt, name))
> @@ -679,7 +712,7 @@ dm_get_opencount (const char * mapname)
> struct dm_task *dmt;
> struct dm_info info;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_INFO)))
> return 0;
>
> if (!dm_task_set_name(dmt, mapname))
> @@ -837,7 +870,7 @@ int dm_flush_maps (int retries)
> struct dm_names *names;
> unsigned next = 0;
>
> - if (!(dmt = dm_task_create (DM_DEVICE_LIST)))
> + if (!(dmt = libmp_dm_task_create (DM_DEVICE_LIST)))
> return 0;
>
> dm_task_no_open_count(dmt);
> @@ -868,7 +901,7 @@ dm_message(const char * mapname, char * message)
> int r = 1;
> struct dm_task *dmt;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TARGET_MSG)))
> return 1;
>
> if (!dm_task_set_name(dmt, mapname))
> @@ -970,7 +1003,7 @@ dm_get_maps (vector mp)
> if (!mp)
> return 1;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
> return 1;
>
> dm_task_no_open_count(dmt);
> @@ -1056,7 +1089,7 @@ dm_mapname(int major, int minor)
> int r;
> int loop = MAX_WAIT * LOOPS_PER_SEC;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_STATUS)))
> return NULL;
>
> if (!dm_task_set_major(dmt, major) ||
> @@ -1109,7 +1142,7 @@ do_foreach_partmaps (const char * mapname,
> int r = 1;
> char *p;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_LIST)))
> return 1;
>
> dm_task_no_open_count(dmt);
> @@ -1333,7 +1366,7 @@ dm_rename (const char * old, char * new, char
> *delim, int skip_kpartx)
> if (dm_rename_partmaps(old, new, delim))
> return r;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_RENAME)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_RENAME)))
> return r;
>
> if (!dm_task_set_name(dmt, old))
> @@ -1382,7 +1415,7 @@ int dm_reassign_table(const char *name, char *old,
> char *new)
> char *buff;
> void *next = NULL;
>
> - if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_TABLE)))
> return 0;
>
> if (!dm_task_set_name(dmt, name))
> @@ -1392,7 +1425,7 @@ int dm_reassign_table(const char *name, char *old,
> char *new)
>
> if (!dm_task_run(dmt))
> goto out;
> - if (!(reload_dmt = dm_task_create(DM_DEVICE_RELOAD)))
> + if (!(reload_dmt = libmp_dm_task_create(DM_DEVICE_RELOAD)))
> goto out;
> if (!dm_task_set_name(reload_dmt, name))
> goto out_reload;
> @@ -1456,7 +1489,7 @@ int dm_reassign(const char *mapname)
> return 1;
> }
>
> - if (!(dmt = dm_task_create(DM_DEVICE_DEPS))) {
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_DEPS))) {
> condlog(3, "%s: couldn't make dm task", mapname);
> return 0;
> }
> @@ -1514,7 +1547,7 @@ int dm_setgeometry(struct multipath *mpp)
> return 1;
> }
>
> - if (!(dmt = dm_task_create(DM_DEVICE_SET_GEOMETRY)))
> + if (!(dmt = libmp_dm_task_create(DM_DEVICE_SET_GEOMETRY)))
> return 0;
>
> if (!dm_task_set_name(dmt, mpp->alias))
> diff --git a/libmultipath/devmapper.h b/libmultipath/devmapper.h
> index fa739bcc..99a554b5 100644
> --- a/libmultipath/devmapper.h
> +++ b/libmultipath/devmapper.h
> @@ -25,7 +25,9 @@
> #endif
>
> void dm_init(int verbosity);
> -int dm_prereq (void);
> +void libmp_dm_init(void);
> +void libmp_udev_set_sync_support(int on);
> +struct dm_task *libmp_dm_task_create(int task);
> int dm_drv_version (unsigned int * version, char * str);
> int dm_simplecmd_flush (int, const char *, uint16_t);
> int dm_simplecmd_noflush (int, const char *, uint16_t);
> diff --git a/libmultipath/waiter.c b/libmultipath/waiter.c
> index 995ea1ad..cb9708b2 100644
> --- a/libmultipath/waiter.c
> +++ b/libmultipath/waiter.c
> @@ -76,7 +76,7 @@ static int waiteventloop (struct event_thread *waiter)
> if (!waiter->event_nr)
> waiter->event_nr = dm_geteventnr(waiter->mapname);
>
> - if (!(waiter->dmt = dm_task_create(DM_DEVICE_WAITEVENT))) {
> + if (!(waiter->dmt = libmp_dm_task_create(DM_DEVICE_WAITEVENT))) {
> condlog(0, "%s: devmap event #%i dm_task_create error",
> waiter->mapname, waiter->event_nr);
> return 1;
> diff --git a/multipath/main.c b/multipath/main.c
> index 4174d43d..dede017e 100644
> --- a/multipath/main.c
> +++ b/multipath/main.c
> @@ -634,12 +634,6 @@ main (int argc, char *argv[])
> exit(1);
> }
>
> - dm_init(conf->verbosity);
> - if (dm_prereq())
> - exit(1);
> - dm_drv_version(conf->version, TGT_MPATH);
> - dm_udev_set_sync_support(1);
> -
> if (optind < argc) {
> dev = MALLOC(FILE_NAME_SIZE);
>
> @@ -670,6 +664,8 @@ main (int argc, char *argv[])
> conf->max_fds, strerror(errno));
> }
>
> + libmp_udev_set_sync_support(1);
> +
> if (init_checkers(conf->multipath_dir)) {
> condlog(0, "failed to initialize checkers");
> goto out;
> diff --git a/multipathd/main.c b/multipathd/main.c
> index 81c76cab..4be2c579 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -2408,8 +2408,6 @@ child (void * param)
> conf->ignore_new_devs = ignore_new_devs;
> uxsock_timeout = conf->uxsock_timeout;
> rcu_assign_pointer(multipath_conf, conf);
> - dm_init(conf->verbosity);
> - dm_drv_version(conf->version, TGT_MPATH);
> if (init_checkers(conf->multipath_dir)) {
> condlog(0, "failed to initialize checkers");
> goto failed;
> @@ -2458,7 +2456,6 @@ child (void * param)
> setscheduler();
> set_oom_adj();
>
> - dm_udev_set_sync_support(0);
> #ifdef USE_SYSTEMD
> envp = getenv("WATCHDOG_USEC");
> if (envp && sscanf(envp, "%lu", &checkint) == 1) {
> @@ -2700,6 +2697,7 @@ main (int argc, char *argv[])
> pthread_cond_init_mono(&config_cond);
>
> udev = udev_new();
> + libmp_udev_set_sync_support(0);
>
> while ((arg = getopt(argc, argv, ":dsv:k::Bn")) != EOF ) {
> switch(arg) {
> --
> 2.13.0
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/dm-devel/attachments/20170621/aa04c558/attachment.htm>
More information about the dm-devel
mailing list