[dm-devel] [PATCH] multipath: handle offlined paths
Christophe Varoqui
christophe.varoqui at gmail.com
Mon Oct 17 22:07:14 UTC 2011
On lun., 2011-10-17 at 16:16 -0500, Benjamin Marzinski wrote:
> The kernel does not allow multipath to load tables containing offline
> devices. Because of this, if you try add a path to a multipath device with
> an offline path, the multipathd will continually, retry and fail to reload
> the table. I've limited the retries to three to avoid livelocking.
>
> Also, if you map included a offline path, multipath was crashing because
> it couldn't get the required sysfs information before calling get_state().
> It now checks for this in multipath, like it does in multipathd
>
> Lastly, multipathd would keep reprinting the last checker message for
> offlined paths, instead of something useful. It now prints a "path offline"
> message.
>
Applied.
Regards,
cvaroqui
> Signed-off-by: Benjamin Marzinski <bmarzins at redhat.com>
> ---
> libmultipath/discovery.c | 9 +++++++--
> multipathd/main.c | 13 ++++++++++---
> 2 files changed, 17 insertions(+), 5 deletions(-)
>
> Index: multipath-tools-111010/libmultipath/discovery.c
> ===================================================================
> --- multipath-tools-111010.orig/libmultipath/discovery.c
> +++ multipath-tools-111010/libmultipath/discovery.c
> @@ -805,8 +805,13 @@ get_state (struct path * pp, int daemon)
> condlog(3, "%s: get_state", pp->dev);
>
> if (!checker_selected(c)) {
> - if (daemon)
> - pathinfo(pp, conf->hwtable, DI_SYSFS);
> + if (daemon || pp->sysdev == NULL) {
> + if (pathinfo(pp, conf->hwtable, DI_SYSFS) != 0) {
> + condlog(3, "%s: couldn't get sysfs pathinfo",
> + pp->dev);
> + return PATH_UNCHECKED;
> + }
> + }
> select_checker(pp);
> if (!checker_selected(c)) {
> condlog(3, "%s: No checker selected", pp->dev);
> Index: multipath-tools-111010/multipathd/main.c
> ===================================================================
> --- multipath-tools-111010.orig/multipathd/main.c
> +++ multipath-tools-111010/multipathd/main.c
> @@ -63,8 +63,13 @@
> #define FILE_NAME_SIZE 256
> #define CMDSIZE 160
>
> -#define LOG_MSG(a,b) \
> - if (strlen(b)) condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b);
> +#define LOG_MSG(a, b) \
> +do { \
> + if (pp->offline) \
> + condlog(a, "%s: %s - path offline", pp->mpp->alias, pp->dev); \
> + else if (strlen(b)) \
> + condlog(a, "%s: %s - %s", pp->mpp->alias, pp->dev, b); \
> +} while(0)
>
> pthread_cond_t exit_cond = PTHREAD_COND_INITIALIZER;
> pthread_mutex_t exit_mutex = PTHREAD_MUTEX_INITIALIZER;
> @@ -365,6 +370,7 @@ ev_add_path (char * devname, struct vect
> struct path * pp;
> char empty_buff[WWID_SIZE] = {0};
> char params[PARAMS_SIZE] = {0};
> + int retries = 3;
> int start_waiter = 0;
>
> if (strstr(devname, "..") != NULL) {
> @@ -478,12 +484,14 @@ rescan:
> /*
> * deal with asynchronous uevents :((
> */
> - if (mpp->action == ACT_RELOAD) {
> + if (mpp->action == ACT_RELOAD && retries-- > 0) {
> condlog(0, "%s: uev_add_path sleep", mpp->alias);
> sleep(1);
> update_mpp_paths(mpp, vecs->pathvec);
> goto rescan;
> }
> + else if (mpp->action == ACT_RELOAD)
> + condlog(0, "%s: giving up reload", mpp->alias);
> else
> goto fail_map;
> }
> @@ -502,8 +510,12 @@ rescan:
> start_waiter_thread(mpp, vecs))
> goto fail_map;
>
> - condlog(2, "%s path added to devmap %s", devname, mpp->alias);
> - return 0;
> + if (retries >= 0) {
> + condlog(2, "%s path added to devmap %s", devname, mpp->alias);
> + return 0;
> + }
> + else
> + return 1;
>
> fail_map:
> remove_map(mpp, vecs, 1);
More information about the dm-devel
mailing list