diff mbox

[v2,20/23] multipathd: use foreign API

Message ID 20180305231507.10386-21-mwilck@suse.com (mailing list archive)
State Not Applicable, archived
Delegated to: christophe varoqui
Headers show

Commit Message

Martin Wilck March 5, 2018, 11:15 p.m. UTC
Call into the foreign library code when paths are discovered, uevents
are received, and in the checker loop. Furthermore, use the foreign
code to print information in the "multipathd show paths", "multipathd
show maps", and "multipathd show topology" client commands.

We don't support foreign data in the individual "show map" and "show path"
commands, and neither in the "json" commands. The former is a deliberate
decision, the latter could be added if desired.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---
 multipathd/cli_handlers.c | 39 ++++++++++++++++++++++++++++++++++-----
 multipathd/main.c         | 34 +++++++++++++++++++++++++++++++---
 2 files changed, 65 insertions(+), 8 deletions(-)

Comments

Hannes Reinecke March 6, 2018, 7:15 a.m. UTC | #1
On 03/06/2018 12:15 AM, Martin Wilck wrote:
> Call into the foreign library code when paths are discovered, uevents
> are received, and in the checker loop. Furthermore, use the foreign
> code to print information in the "multipathd show paths", "multipathd
> show maps", and "multipathd show topology" client commands.
> 
> We don't support foreign data in the individual "show map" and "show path"
> commands, and neither in the "json" commands. The former is a deliberate
> decision, the latter could be added if desired.
> 
> Signed-off-by: Martin Wilck <mwilck@suse.com>
> ---
>  multipathd/cli_handlers.c | 39 ++++++++++++++++++++++++++++++++++-----
>  multipathd/main.c         | 34 +++++++++++++++++++++++++++++++---
>  2 files changed, 65 insertions(+), 8 deletions(-)
> 
Reviewed-by: Hannes Reinecke <hare@suse.com>

Cheers,

Hannes
Benjamin Marzinski March 7, 2018, 7:25 p.m. UTC | #2
On Tue, Mar 06, 2018 at 12:15:04AM +0100, Martin Wilck wrote:
> Call into the foreign library code when paths are discovered, uevents
> are received, and in the checker loop. Furthermore, use the foreign
> code to print information in the "multipathd show paths", "multipathd
> show maps", and "multipathd show topology" client commands.
> 
> We don't support foreign data in the individual "show map" and "show path"
> commands, and neither in the "json" commands. The former is a deliberate
> decision, the latter could be added if desired.
> 

Reviewed-by: Benjamin Marzinski <bmarzins@redhat.com>

> Signed-off-by: Martin Wilck <mwilck@suse.com>
> ---
>  multipathd/cli_handlers.c | 39 ++++++++++++++++++++++++++++++++++-----
>  multipathd/main.c         | 34 +++++++++++++++++++++++++++++++---
>  2 files changed, 65 insertions(+), 8 deletions(-)
> 
> diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
> index 78f2a12bc2f8..c0ae54aae841 100644
> --- a/multipathd/cli_handlers.c
> +++ b/multipathd/cli_handlers.c
> @@ -27,6 +27,7 @@
>  #include "main.h"
>  #include "cli.h"
>  #include "uevent.h"
> +#include "foreign.h"
>  
>  int
>  show_paths (char ** r, int * len, struct vectors * vecs, char * style,
> @@ -35,11 +36,13 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style,
>  	int i;
>  	struct path * pp;
>  	char * c;
> -	char * reply;
> +	char * reply, * header;
>  	unsigned int maxlen = INITIAL_REPLY_LEN;
>  	int again = 1;
>  
>  	get_path_layout(vecs->pathvec, 1);
> +	foreign_path_layout();
> +
>  	reply = MALLOC(maxlen);
>  
>  	while (again) {
> @@ -48,18 +51,29 @@ show_paths (char ** r, int * len, struct vectors * vecs, char * style,
>  
>  		c = reply;
>  
> -		if (pretty && VECTOR_SIZE(vecs->pathvec) > 0)
> +		if (pretty)
>  			c += snprint_path_header(c, reply + maxlen - c,
>  						 style);
> +		header = c;
>  
>  		vector_foreach_slot(vecs->pathvec, pp, i)
>  			c += snprint_path(c, reply + maxlen - c,
>  					  style, pp, pretty);
>  
> +		c += snprint_foreign_paths(c, reply + maxlen - c,
> +					   style, pretty);
> +
>  		again = ((c - reply) == (maxlen - 1));
>  
>  		REALLOC_REPLY(reply, again, maxlen);
>  	}
> +
> +	if (pretty && c == header) {
> +		/* No output - clear header */
> +		*reply = '\0';
> +		c = reply;
> +	}
> +
>  	*r = reply;
>  	*len = (int)(c - reply + 1);
>  	return 0;
> @@ -134,6 +148,8 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
>  	int again = 1;
>  
>  	get_path_layout(vecs->pathvec, 0);
> +	foreign_path_layout();
> +
>  	reply = MALLOC(maxlen);
>  
>  	while (again) {
> @@ -150,11 +166,13 @@ show_maps_topology (char ** r, int * len, struct vectors * vecs)
>  			c += snprint_multipath_topology(c, reply + maxlen - c,
>  							mpp, 2);
>  		}
> +		c += snprint_foreign_topology(c, reply + maxlen - c, 2);
>  
>  		again = ((c - reply) == (maxlen - 1));
>  
>  		REALLOC_REPLY(reply, again, maxlen);
>  	}
> +
>  	*r = reply;
>  	*len = (int)(c - reply + 1);
>  	return 0;
> @@ -499,12 +517,14 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
>  {
>  	int i;
>  	struct multipath * mpp;
> -	char * c;
> +	char * c, *header;
>  	char * reply;
>  	unsigned int maxlen = INITIAL_REPLY_LEN;
>  	int again = 1;
>  
>  	get_multipath_layout(vecs->mpvec, 1);
> +	foreign_multipath_layout();
> +
>  	reply = MALLOC(maxlen);
>  
>  	while (again) {
> @@ -512,9 +532,10 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
>  			return 1;
>  
>  		c = reply;
> -		if (pretty && VECTOR_SIZE(vecs->mpvec) > 0)
> +		if (pretty)
>  			c += snprint_multipath_header(c, reply + maxlen - c,
>  						      style);
> +		header = c;
>  
>  		vector_foreach_slot(vecs->mpvec, mpp, i) {
>  			if (update_multipath(vecs, mpp->alias, 0)) {
> @@ -523,12 +544,20 @@ show_maps (char ** r, int *len, struct vectors * vecs, char * style,
>  			}
>  			c += snprint_multipath(c, reply + maxlen - c,
>  					       style, mpp, pretty);
> -		}
>  
> +		}
> +		c += snprint_foreign_multipaths(c, reply + maxlen - c,
> +						style, pretty);
>  		again = ((c - reply) == (maxlen - 1));
>  
>  		REALLOC_REPLY(reply, again, maxlen);
>  	}
> +
> +	if (pretty && c == header) {
> +		/* No output - clear header */
> +		*reply = '\0';
> +		c = reply;
> +	}
>  	*r = reply;
>  	*len = (int)(c - reply + 1);
>  	return 0;
> diff --git a/multipathd/main.c b/multipathd/main.c
> index cb26c58f6ba9..465a1e291226 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -84,6 +84,7 @@ static int use_watchdog;
>  #include "waiter.h"
>  #include "io_err_stat.h"
>  #include "wwids.h"
> +#include "foreign.h"
>  #include "../third-party/valgrind/drd.h"
>  
>  #define FILE_NAME_SIZE 256
> @@ -798,6 +799,8 @@ uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
>  	int ret;
>  
>  	condlog(2, "%s: remove path (uevent)", uev->kernel);
> +	delete_foreign(uev->udev);
> +
>  	pthread_cleanup_push(cleanup_lock, &vecs->lock);
>  	lock(&vecs->lock);
>  	pthread_testcancel();
> @@ -917,12 +920,27 @@ fail:
>  static int
>  uev_update_path (struct uevent *uev, struct vectors * vecs)
>  {
> -	int ro, retval = 0;
> +	int ro, retval = 0, rc;
>  	struct path * pp;
>  	struct config *conf;
>  	int disable_changed_wwids;
>  	int needs_reinit = 0;
>  
> +	switch ((rc = change_foreign(uev->udev))) {
> +	case FOREIGN_OK:
> +		/* known foreign path, ignore event */
> +		return 0;
> +	case FOREIGN_IGNORED:
> +		break;
> +	case FOREIGN_ERR:
> +		condlog(3, "%s: error in change_foreign", __func__);
> +		break;
> +	default:
> +		condlog(1, "%s: return code %d of change_forein is unsupported",
> +			__func__, rc);
> +		break;
> +	}
> +
>  	conf = get_multipath_config();
>  	disable_changed_wwids = conf->disable_changed_wwids;
>  	put_multipath_config(conf);
> @@ -1122,8 +1140,13 @@ uev_trigger (struct uevent * uev, void * trigger_data)
>  	 * are not fully initialised then.
>  	 */
>  	if (!strncmp(uev->kernel, "dm-", 3)) {
> -		if (!uevent_is_mpath(uev))
> +		if (!uevent_is_mpath(uev)) {
> +			if (!strncmp(uev->action, "change", 6))
> +				(void)add_foreign(uev->udev);
> +			else if (!strncmp(uev->action, "remove", 6))
> +				(void)delete_foreign(uev->udev);
>  			goto out;
> +		}
>  		if (!strncmp(uev->action, "change", 6)) {
>  			r = uev_add_map(uev, vecs);
>  
> @@ -1932,7 +1955,7 @@ checkerloop (void *ap)
>  						diff_time.tv_sec);
>  			}
>  		}
> -
> +		check_foreign();
>  		post_config_state(DAEMON_IDLE);
>  		conf = get_multipath_config();
>  		strict_timing = conf->strict_timing;
> @@ -2121,6 +2144,7 @@ reconfigure (struct vectors * vecs)
>  
>  	free_pathvec(vecs->pathvec, FREE_PATHS);
>  	vecs->pathvec = NULL;
> +	delete_all_foreign();
>  
>  	/* Re-read any timezone changes */
>  	tzset();
> @@ -2372,6 +2396,9 @@ child (void * param)
>  		condlog(0, "failed to initialize prioritizers");
>  		goto failed;
>  	}
> +	/* Failing this is non-fatal */
> +
> +	init_foreign(conf->multipath_dir);
>  
>  	setlogmask(LOG_UPTO(conf->verbosity + 3));
>  
> @@ -2529,6 +2556,7 @@ child (void * param)
>  	FREE(vecs);
>  	vecs = NULL;
>  
> +	cleanup_foreign();
>  	cleanup_checkers();
>  	cleanup_prio();
>  
> -- 
> 2.16.1

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

Patch

diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
index 78f2a12bc2f8..c0ae54aae841 100644
--- a/multipathd/cli_handlers.c
+++ b/multipathd/cli_handlers.c
@@ -27,6 +27,7 @@ 
 #include "main.h"
 #include "cli.h"
 #include "uevent.h"
+#include "foreign.h"
 
 int
 show_paths (char ** r, int * len, struct vectors * vecs, char * style,
@@ -35,11 +36,13 @@  show_paths (char ** r, int * len, struct vectors * vecs, char * style,
 	int i;
 	struct path * pp;
 	char * c;
-	char * reply;
+	char * reply, * header;
 	unsigned int maxlen = INITIAL_REPLY_LEN;
 	int again = 1;
 
 	get_path_layout(vecs->pathvec, 1);
+	foreign_path_layout();
+
 	reply = MALLOC(maxlen);
 
 	while (again) {
@@ -48,18 +51,29 @@  show_paths (char ** r, int * len, struct vectors * vecs, char * style,
 
 		c = reply;
 
-		if (pretty && VECTOR_SIZE(vecs->pathvec) > 0)
+		if (pretty)
 			c += snprint_path_header(c, reply + maxlen - c,
 						 style);
+		header = c;
 
 		vector_foreach_slot(vecs->pathvec, pp, i)
 			c += snprint_path(c, reply + maxlen - c,
 					  style, pp, pretty);
 
+		c += snprint_foreign_paths(c, reply + maxlen - c,
+					   style, pretty);
+
 		again = ((c - reply) == (maxlen - 1));
 
 		REALLOC_REPLY(reply, again, maxlen);
 	}
+
+	if (pretty && c == header) {
+		/* No output - clear header */
+		*reply = '\0';
+		c = reply;
+	}
+
 	*r = reply;
 	*len = (int)(c - reply + 1);
 	return 0;
@@ -134,6 +148,8 @@  show_maps_topology (char ** r, int * len, struct vectors * vecs)
 	int again = 1;
 
 	get_path_layout(vecs->pathvec, 0);
+	foreign_path_layout();
+
 	reply = MALLOC(maxlen);
 
 	while (again) {
@@ -150,11 +166,13 @@  show_maps_topology (char ** r, int * len, struct vectors * vecs)
 			c += snprint_multipath_topology(c, reply + maxlen - c,
 							mpp, 2);
 		}
+		c += snprint_foreign_topology(c, reply + maxlen - c, 2);
 
 		again = ((c - reply) == (maxlen - 1));
 
 		REALLOC_REPLY(reply, again, maxlen);
 	}
+
 	*r = reply;
 	*len = (int)(c - reply + 1);
 	return 0;
@@ -499,12 +517,14 @@  show_maps (char ** r, int *len, struct vectors * vecs, char * style,
 {
 	int i;
 	struct multipath * mpp;
-	char * c;
+	char * c, *header;
 	char * reply;
 	unsigned int maxlen = INITIAL_REPLY_LEN;
 	int again = 1;
 
 	get_multipath_layout(vecs->mpvec, 1);
+	foreign_multipath_layout();
+
 	reply = MALLOC(maxlen);
 
 	while (again) {
@@ -512,9 +532,10 @@  show_maps (char ** r, int *len, struct vectors * vecs, char * style,
 			return 1;
 
 		c = reply;
-		if (pretty && VECTOR_SIZE(vecs->mpvec) > 0)
+		if (pretty)
 			c += snprint_multipath_header(c, reply + maxlen - c,
 						      style);
+		header = c;
 
 		vector_foreach_slot(vecs->mpvec, mpp, i) {
 			if (update_multipath(vecs, mpp->alias, 0)) {
@@ -523,12 +544,20 @@  show_maps (char ** r, int *len, struct vectors * vecs, char * style,
 			}
 			c += snprint_multipath(c, reply + maxlen - c,
 					       style, mpp, pretty);
-		}
 
+		}
+		c += snprint_foreign_multipaths(c, reply + maxlen - c,
+						style, pretty);
 		again = ((c - reply) == (maxlen - 1));
 
 		REALLOC_REPLY(reply, again, maxlen);
 	}
+
+	if (pretty && c == header) {
+		/* No output - clear header */
+		*reply = '\0';
+		c = reply;
+	}
 	*r = reply;
 	*len = (int)(c - reply + 1);
 	return 0;
diff --git a/multipathd/main.c b/multipathd/main.c
index cb26c58f6ba9..465a1e291226 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -84,6 +84,7 @@  static int use_watchdog;
 #include "waiter.h"
 #include "io_err_stat.h"
 #include "wwids.h"
+#include "foreign.h"
 #include "../third-party/valgrind/drd.h"
 
 #define FILE_NAME_SIZE 256
@@ -798,6 +799,8 @@  uev_remove_path (struct uevent *uev, struct vectors * vecs, int need_do_map)
 	int ret;
 
 	condlog(2, "%s: remove path (uevent)", uev->kernel);
+	delete_foreign(uev->udev);
+
 	pthread_cleanup_push(cleanup_lock, &vecs->lock);
 	lock(&vecs->lock);
 	pthread_testcancel();
@@ -917,12 +920,27 @@  fail:
 static int
 uev_update_path (struct uevent *uev, struct vectors * vecs)
 {
-	int ro, retval = 0;
+	int ro, retval = 0, rc;
 	struct path * pp;
 	struct config *conf;
 	int disable_changed_wwids;
 	int needs_reinit = 0;
 
+	switch ((rc = change_foreign(uev->udev))) {
+	case FOREIGN_OK:
+		/* known foreign path, ignore event */
+		return 0;
+	case FOREIGN_IGNORED:
+		break;
+	case FOREIGN_ERR:
+		condlog(3, "%s: error in change_foreign", __func__);
+		break;
+	default:
+		condlog(1, "%s: return code %d of change_forein is unsupported",
+			__func__, rc);
+		break;
+	}
+
 	conf = get_multipath_config();
 	disable_changed_wwids = conf->disable_changed_wwids;
 	put_multipath_config(conf);
@@ -1122,8 +1140,13 @@  uev_trigger (struct uevent * uev, void * trigger_data)
 	 * are not fully initialised then.
 	 */
 	if (!strncmp(uev->kernel, "dm-", 3)) {
-		if (!uevent_is_mpath(uev))
+		if (!uevent_is_mpath(uev)) {
+			if (!strncmp(uev->action, "change", 6))
+				(void)add_foreign(uev->udev);
+			else if (!strncmp(uev->action, "remove", 6))
+				(void)delete_foreign(uev->udev);
 			goto out;
+		}
 		if (!strncmp(uev->action, "change", 6)) {
 			r = uev_add_map(uev, vecs);
 
@@ -1932,7 +1955,7 @@  checkerloop (void *ap)
 						diff_time.tv_sec);
 			}
 		}
-
+		check_foreign();
 		post_config_state(DAEMON_IDLE);
 		conf = get_multipath_config();
 		strict_timing = conf->strict_timing;
@@ -2121,6 +2144,7 @@  reconfigure (struct vectors * vecs)
 
 	free_pathvec(vecs->pathvec, FREE_PATHS);
 	vecs->pathvec = NULL;
+	delete_all_foreign();
 
 	/* Re-read any timezone changes */
 	tzset();
@@ -2372,6 +2396,9 @@  child (void * param)
 		condlog(0, "failed to initialize prioritizers");
 		goto failed;
 	}
+	/* Failing this is non-fatal */
+
+	init_foreign(conf->multipath_dir);
 
 	setlogmask(LOG_UPTO(conf->verbosity + 3));
 
@@ -2529,6 +2556,7 @@  child (void * param)
 	FREE(vecs);
 	vecs = NULL;
 
+	cleanup_foreign();
 	cleanup_checkers();
 	cleanup_prio();