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 <bmarz...@redhat.com>

> Signed-off-by: Martin Wilck <mwi...@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

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to