[dm-devel] [PATCH 21/21] libmultipath/checkers: cleanup class/instance model
Benjamin Marzinski
bmarzins at redhat.com
Thu Oct 25 21:52:49 UTC 2018
On Fri, Oct 12, 2018 at 12:27:07AM +0200, Martin Wilck wrote:
> The checkers code implicitly uses a sort-of OOP class/instance model,
> but very clumsily. Separate the checker "class" and "instance" cleanly,
> and do a few further cleanups (constifications etc) on the way.
>
Reviewed-by: Benjamin Marzinski <bmarzins at redhat.com>
> Signed-off-by: Martin Wilck <mwilck at suse.com>
> ---
> libmultipath/checkers.c | 137 ++++++++++++++++---------------
> libmultipath/checkers.h | 23 ++----
> libmultipath/checkers/directio.c | 2 +-
> libmultipath/checkers/tur.c | 2 +-
> libmultipath/print.c | 2 +-
> libmultipath/propsel.c | 19 +++--
> 6 files changed, 92 insertions(+), 93 deletions(-)
>
> diff --git a/libmultipath/checkers.c b/libmultipath/checkers.c
> index 19c8ad58..7733471c 100644
> --- a/libmultipath/checkers.c
> +++ b/libmultipath/checkers.c
> @@ -8,6 +8,19 @@
> #include "checkers.h"
> #include "vector.h"
>
> +struct checker_class {
> + struct list_head node;
> + void *handle;
> + int refcount;
> + int sync;
> + char name[CHECKER_NAME_LEN];
> + int (*check)(struct checker *);
> + int (*init)(struct checker *); /* to allocate the context */
> + void (*free)(struct checker *); /* to free the context */
> + const char **msgtable;
> + short msgtable_size;
> +};
> +
> char *checker_state_names[] = {
> "wild",
> "unchecked",
> @@ -23,38 +36,30 @@ char *checker_state_names[] = {
>
> static LIST_HEAD(checkers);
>
> -char * checker_state_name (int i)
> +const char *checker_state_name(int i)
> {
> return checker_state_names[i];
> }
>
> -int init_checkers (char *multipath_dir)
> -{
> - if (!add_checker(multipath_dir, DEFAULT_CHECKER))
> - return 1;
> - return 0;
> -}
> -
> -struct checker * alloc_checker (void)
> +static struct checker_class *alloc_checker_class(void)
> {
> - struct checker *c;
> + struct checker_class *c;
>
> - c = MALLOC(sizeof(struct checker));
> + c = MALLOC(sizeof(struct checker_class));
> if (c) {
> INIT_LIST_HEAD(&c->node);
> c->refcount = 1;
> - c->fd = -1;
> }
> return c;
> }
>
> -void free_checker (struct checker * c)
> +void free_checker_class(struct checker_class *c)
> {
> if (!c)
> return;
> c->refcount--;
> if (c->refcount) {
> - condlog(3, "%s checker refcount %d",
> + condlog(4, "%s checker refcount %d",
> c->name, c->refcount);
> return;
> }
> @@ -71,17 +76,17 @@ void free_checker (struct checker * c)
>
> void cleanup_checkers (void)
> {
> - struct checker * checker_loop;
> - struct checker * checker_temp;
> + struct checker_class *checker_loop;
> + struct checker_class *checker_temp;
>
> list_for_each_entry_safe(checker_loop, checker_temp, &checkers, node) {
> - free_checker(checker_loop);
> + free_checker_class(checker_loop);
> }
> }
>
> -struct checker * checker_lookup (char * name)
> +static struct checker_class *checker_class_lookup(const char *name)
> {
> - struct checker * c;
> + struct checker_class *c;
>
> if (!name || !strlen(name))
> return NULL;
> @@ -92,14 +97,15 @@ struct checker * checker_lookup (char * name)
> return NULL;
> }
>
> -struct checker * add_checker (char *multipath_dir, char * name)
> +static struct checker_class *add_checker_class(const char *multipath_dir,
> + const char *name)
> {
> char libname[LIB_CHECKER_NAMELEN];
> struct stat stbuf;
> - struct checker * c;
> + struct checker_class *c;
> char *errstr;
>
> - c = alloc_checker();
> + c = alloc_checker_class();
> if (!c)
> return NULL;
> snprintf(c->name, CHECKER_NAME_LEN, "%s", name);
> @@ -158,12 +164,11 @@ struct checker * add_checker (char *multipath_dir, char * name)
> c->name, c->msgtable_size);
>
> done:
> - c->fd = -1;
> c->sync = 1;
> list_add(&c->node, &checkers);
> return c;
> out:
> - free_checker(c);
> + free_checker_class(c);
> return NULL;
> }
>
> @@ -176,16 +181,16 @@ void checker_set_fd (struct checker * c, int fd)
>
> void checker_set_sync (struct checker * c)
> {
> - if (!c)
> + if (!c || !c->cls)
> return;
> - c->sync = 1;
> + c->cls->sync = 1;
> }
>
> void checker_set_async (struct checker * c)
> {
> - if (!c)
> + if (!c || !c->cls)
> return;
> - c->sync = 0;
> + c->cls->sync = 0;
> }
>
> void checker_enable (struct checker * c)
> @@ -204,11 +209,11 @@ void checker_disable (struct checker * c)
>
> int checker_init (struct checker * c, void ** mpctxt_addr)
> {
> - if (!c)
> + if (!c || !c->cls)
> return 1;
> c->mpcontext = mpctxt_addr;
> - if (c->init)
> - return c->init(c);
> + if (c->cls->init)
> + return c->cls->init(c);
> return 0;
> }
>
> @@ -220,15 +225,16 @@ void checker_clear (struct checker *c)
>
> void checker_put (struct checker * dst)
> {
> - struct checker * src;
> + struct checker_class *src;
>
> - if (!dst || !strlen(dst->name))
> + if (!dst)
> return;
> - src = checker_lookup(dst->name);
> - if (dst->free)
> - dst->free(dst);
> + src = dst->cls;
> +
> + if (src && src->free)
> + src->free(dst);
> checker_clear(dst);
> - free_checker(src);
> + free_checker_class(src);
> }
>
> int checker_check (struct checker * c, int path_state)
> @@ -243,32 +249,35 @@ int checker_check (struct checker * c, int path_state)
> c->msgid = CHECKER_MSGID_DISABLED;
> return PATH_UNCHECKED;
> }
> - if (!strncmp(c->name, NONE, 4))
> + if (!strncmp(c->cls->name, NONE, 4))
> return path_state;
>
> if (c->fd < 0) {
> c->msgid = CHECKER_MSGID_NO_FD;
> return PATH_WILD;
> }
> - r = c->check(c);
> + r = c->cls->check(c);
>
> return r;
> }
>
> -int checker_selected (struct checker * c)
> +int checker_selected(const struct checker *c)
> {
> if (!c)
> return 0;
> - if (!strncmp(c->name, NONE, 4))
> - return 1;
> - return (c->check) ? 1 : 0;
> + return c->cls != NULL;
> }
>
> const char *checker_name(const struct checker *c)
> {
> - if (!c)
> + if (!c || !c->cls)
> return NULL;
> - return c->name;
> + return c->cls->name;
> +}
> +
> +int checker_is_sync(const struct checker *c)
> +{
> + return c && c->cls && c->cls->sync;
> }
>
> static const char *generic_msg[CHECKER_LAST_GENERIC_MSGID] = {
> @@ -295,8 +304,8 @@ static const char *_checker_message(const struct checker *c)
> return generic_msg[c->msgid];
>
> id = c->msgid - CHECKER_FIRST_MSGID;
> - if (id < c->msgtable_size)
> - return c->msgtable[id];
> + if (id < c->cls->msgtable_size)
> + return c->cls->msgtable[id];
> return NULL;
> }
>
> @@ -309,7 +318,7 @@ const char *checker_message(const struct checker *c)
> *buf = '\0';
> else
> snprintf(buf, sizeof(buf), "%s checker%s",
> - c->name, msg);
> + c->cls->name, msg);
> return buf;
> }
>
> @@ -320,31 +329,29 @@ void checker_clear_message (struct checker *c)
> c->msgid = CHECKER_MSGID_NONE;
> }
>
> -void checker_get (char *multipath_dir, struct checker * dst, char * name)
> +void checker_get(const char *multipath_dir, struct checker *dst,
> + const char *name)
> {
> - struct checker * src = NULL;
> + struct checker_class *src = NULL;
>
> if (!dst)
> return;
>
> if (name && strlen(name)) {
> - src = checker_lookup(name);
> + src = checker_class_lookup(name);
> if (!src)
> - src = add_checker(multipath_dir, name);
> + src = add_checker_class(multipath_dir, name);
> }
> - if (!src) {
> - dst->check = NULL;
> + dst->cls = src;
> + if (!src)
> return;
> - }
> - dst->fd = src->fd;
> - dst->sync = src->sync;
> - strncpy(dst->name, src->name, CHECKER_NAME_LEN);
> - dst->msgid = src->msgid;
> - dst->check = src->check;
> - dst->init = src->init;
> - dst->free = src->free;
> - dst->msgtable = src->msgtable;
> - dst->msgtable_size = src->msgtable_size;
> - dst->handle = NULL;
> +
> src->refcount++;
> }
> +
> +int init_checkers(const char *multipath_dir)
> +{
> + if (!add_checker_class(multipath_dir, DEFAULT_CHECKER))
> + return 1;
> + return 0;
> +}
> diff --git a/libmultipath/checkers.h b/libmultipath/checkers.h
> index 98fec2c4..c46f7ffa 100644
> --- a/libmultipath/checkers.h
> +++ b/libmultipath/checkers.h
> @@ -116,32 +116,22 @@ enum {
> CHECKER_MSGTABLE_SIZE = 100, /* max msg table size for checkers */
> };
>
> +struct checker_class;
> struct checker {
> - struct list_head node;
> - void *handle;
> - int refcount;
> + struct checker_class *cls;
> int fd;
> - int sync;
> unsigned int timeout;
> int disable;
> - char name[CHECKER_NAME_LEN];
> short msgid; /* checker-internal extra status */
> void * context; /* store for persistent data */
> void ** mpcontext; /* store for persistent data shared
> multipath-wide. Use MALLOC if
> you want to stuff data in. */
> - int (*check)(struct checker *);
> - int (*init)(struct checker *); /* to allocate the context */
> - void (*free)(struct checker *); /* to free the context */
> - const char**msgtable;
> - short msgtable_size;
> };
>
> -char * checker_state_name (int);
> -int init_checkers (char *);
> +const char *checker_state_name(int);
> +int init_checkers(const char *);
> void cleanup_checkers (void);
> -struct checker * add_checker (char *, char *);
> -struct checker * checker_lookup (char *);
> int checker_init (struct checker *, void **);
> void checker_clear (struct checker *);
> void checker_put (struct checker *);
> @@ -152,11 +142,12 @@ void checker_set_fd (struct checker *, int);
> void checker_enable (struct checker *);
> void checker_disable (struct checker *);
> int checker_check (struct checker *, int);
> -int checker_selected (struct checker *);
> +int checker_selected(const struct checker *);
> +int checker_is_sync(const struct checker *);
> const char *checker_name (const struct checker *);
> const char *checker_message (const struct checker *);
> void checker_clear_message (struct checker *c);
> -void checker_get (char *, struct checker *, char *);
> +void checker_get(const char *, struct checker *, const char *);
>
> /* Prototypes for symbols exported by path checker dynamic libraries (.so) */
> int libcheck_check(struct checker *);
> diff --git a/libmultipath/checkers/directio.c b/libmultipath/checkers/directio.c
> index c4a0712e..1b00b775 100644
> --- a/libmultipath/checkers/directio.c
> +++ b/libmultipath/checkers/directio.c
> @@ -202,7 +202,7 @@ int libcheck_check (struct checker * c)
> if (!ct)
> return PATH_UNCHECKED;
>
> - ret = check_state(c->fd, ct, c->sync, c->timeout);
> + ret = check_state(c->fd, ct, checker_is_sync(c), c->timeout);
>
> switch (ret)
> {
> diff --git a/libmultipath/checkers/tur.c b/libmultipath/checkers/tur.c
> index 8f4bdc8b..05e7bed6 100644
> --- a/libmultipath/checkers/tur.c
> +++ b/libmultipath/checkers/tur.c
> @@ -323,7 +323,7 @@ int libcheck_check(struct checker * c)
> if (!ct)
> return PATH_UNCHECKED;
>
> - if (c->sync)
> + if (checker_is_sync(c))
> return tur_check(c->fd, c->timeout, &c->msgid);
>
> /*
> diff --git a/libmultipath/print.c b/libmultipath/print.c
> index 7b610b94..fc40b0f0 100644
> --- a/libmultipath/print.c
> +++ b/libmultipath/print.c
> @@ -615,7 +615,7 @@ static int
> snprint_path_checker (char * buff, size_t len, const struct path * pp)
> {
> const struct checker * c = &pp->checker;
> - return snprint_str(buff, len, c->name);
> + return snprint_str(buff, len, checker_name(c));
> }
>
> static int
> diff --git a/libmultipath/propsel.c b/libmultipath/propsel.c
> index fdb5953a..970a3b5c 100644
> --- a/libmultipath/propsel.c
> +++ b/libmultipath/propsel.c
> @@ -479,26 +479,27 @@ check_rdac(struct path * pp)
> int select_checker(struct config *conf, struct path *pp)
> {
> const char *origin;
> - char *checker_name;
> + char *ckr_name;
> struct checker * c = &pp->checker;
>
> if (pp->detect_checker == DETECT_CHECKER_ON) {
> origin = autodetect_origin;
> if (check_rdac(pp)) {
> - checker_name = RDAC;
> + ckr_name = RDAC;
> goto out;
> } else if (pp->tpgs > 0) {
> - checker_name = TUR;
> + ckr_name = TUR;
> goto out;
> }
> }
> - do_set(checker_name, conf->overrides, checker_name, overrides_origin);
> - do_set_from_hwe(checker_name, pp, checker_name, hwe_origin);
> - do_set(checker_name, conf, checker_name, conf_origin);
> - do_default(checker_name, DEFAULT_CHECKER);
> + do_set(checker_name, conf->overrides, ckr_name, overrides_origin);
> + do_set_from_hwe(checker_name, pp, ckr_name, hwe_origin);
> + do_set(checker_name, conf, ckr_name, conf_origin);
> + do_default(ckr_name, DEFAULT_CHECKER);
> out:
> - checker_get(conf->multipath_dir, c, checker_name);
> - condlog(3, "%s: path_checker = %s %s", pp->dev, c->name, origin);
> + checker_get(conf->multipath_dir, c, ckr_name);
> + condlog(3, "%s: path_checker = %s %s", pp->dev,
> + checker_name(c), origin);
> if (conf->checker_timeout) {
> c->timeout = conf->checker_timeout;
> condlog(3, "%s: checker timeout = %u s %s",
> --
> 2.19.0
More information about the dm-devel
mailing list