All of lore.kernel.org
 help / color / mirror / Atom feed
From: tang.junhui@zte.com.cn
To: christophe.varoqui@opensvc.com, hare@suse.de,
	bmarzins@redhat.com, mwilck@suse.com, bart.vanassche@sandisk.com
Cc: zhang.kai16@zte.com.cn, dm-devel@redhat.com,
	tang.junhui@zte.com.cn, tang.wenjun3@zte.com.cn
Subject: [PATCH 09/12] multipathd: merge uevents before proccessing
Date: Tue, 27 Dec 2016 16:03:26 +0800	[thread overview]
Message-ID: <1482825809-9528-10-git-send-email-tang.junhui@zte.com.cn> (raw)
In-Reply-To: <1482825809-9528-1-git-send-email-tang.junhui@zte.com.cn>

From: tang.junhui <tang.junhui@zte.com.cn>

These uevents are going to be merged:
1) uevents come from paths and
2) uevents type is same and
3) uevents type is addition or deletion and
4) uevents wwid is same.

Change-Id: I05ee057391c092aa0c5f989b7a4f9cb550bb4d98
Signed-off-by: tang.junhui <tang.junhui@zte.com.cn>
---
 libmultipath/uevent.c | 125 +++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 114 insertions(+), 11 deletions(-)

diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
index b0b05e9..114068c 100644
--- a/libmultipath/uevent.c
+++ b/libmultipath/uevent.c
@@ -85,6 +85,20 @@ struct uevent * alloc_uevent (void)
 	return uev;
 }
 
+void
+uevq_cleanup(struct list_head *tmpq)
+{
+	struct uevent *uev, *tmp;
+
+	list_for_each_entry_safe(uev, tmp, tmpq, node) {
+		list_del_init(&uev->node);
+
+		if (uev->udev)
+			udev_device_unref(uev->udev);
+		FREE(uev);
+	}
+}
+
 bool
 uevent_can_discard(char *devpath, char *kernel)
 {
@@ -125,6 +139,103 @@ uevent_can_discard(char *devpath, char *kernel)
 	return false;
 }
 
+bool
+merge_need_stop(struct uevent *earlier, struct uevent *later)
+{
+	/*
+	 * dm uevent do not try to merge with left uevents
+	 */
+	if (!strncmp(later->kernel, "dm-", 3))
+		return true;
+
+	/*
+	 * we can not make a jugement without wwid,
+	 * so it is sensible to stop merging
+	 */
+	if (!earlier->wwid || !later->wwid)
+		return true;
+	/*
+	 * uevents merging stoped
+	 * when we meet an opposite action uevent from the same LUN to AVOID
+	 * "add path1 |remove path1 |add path2 |remove path2 |add path3"
+	 * to merge as "remove path1, path2" and "add path1, path2, path3"
+	 * OR
+	 * "remove path1 |add path1 |remove path2 |add path2 |remove path3"
+	 * to merge as "add path1, path2" and "remove path1, path2, path3"
+	 * SO
+	 * when we meet a non-change uevent from the same LUN
+	 * with the same wwid and different action
+	 * it would be better to stop merging.
+	 */
+	if (!strcmp(earlier->wwid, later->wwid) &&
+	    strcmp(earlier->action, later->action) &&
+	    strcmp(earlier->action, "change") &&
+	    strcmp(later->action, "change"))
+		return true;
+
+	return false;
+}
+
+bool
+uevent_can_merge(struct uevent *earlier, struct uevent *later)
+{
+	/* merge paths uevents
+	 * whose wwids exsit and are same
+	 * and actions are same,
+	 * and actions are addition or deletion
+	 */
+	if (earlier->wwid && later->wwid &&
+	    !strcmp(earlier->wwid, later->wwid) &&
+	    !strcmp(earlier->action, later->action) &&
+	    strncmp(earlier->action, "change", 6) &&
+	    strncmp(earlier->kernel, "dm-", 3)) {
+		return true;
+	}
+
+	return false;
+}
+
+void
+uevent_merge(struct uevent *later, struct list_head *tmpq)
+{
+	struct uevent *earlier, *temp;
+	/*
+	 * compare the uevent with earlier uevents
+	 */
+	list_for_some_entry_reverse(earlier, &later->node, tmpq, node) {
+next_earlier_node:
+		if (merge_need_stop(earlier, later))
+			break;
+		/*
+		 * try to merge earlier uevents to the later uevent
+		 */
+		if (uevent_can_merge(earlier, later)) {
+			condlog(3, "merged uevent: %s-%s-%s with uevent: %s-%s-%s",
+				earlier->action, earlier->kernel, earlier->wwid,
+				later->action, later->kernel, later->wwid);
+			temp = earlier;
+
+			earlier = list_entry(earlier->node.prev, typeof(struct uevent), node);
+			list_move(&temp->node, &later->merge_node);
+
+			if (earlier ==  list_entry(tmpq, typeof(struct uevent), node))
+				break;
+			else
+				goto next_earlier_node;
+		}
+	}
+}
+
+void
+merge_uevq(struct list_head *tmpq)
+{
+	struct uevent *later;
+
+	list_for_each_entry_reverse(later, tmpq, node) {
+		uevent_merge(later, tmpq);
+	}
+}
+
 void
 service_uevq(struct list_head *tmpq)
 {
@@ -136,6 +247,8 @@ service_uevq(struct list_head *tmpq)
 		if (my_uev_trigger && my_uev_trigger(uev, my_trigger_data))
 			condlog(0, "uevent trigger error");
 
+		uevq_cleanup(&uev->merge_node);
+
 		if (uev->udev)
 			udev_device_unref(uev->udev);
 		FREE(uev);
@@ -150,17 +263,6 @@ static void uevent_cleanup(void *arg)
 	udev_unref(udev);
 }
 
-void
-uevq_cleanup(struct list_head *tmpq)
-{
-	struct uevent *uev, *tmp;
-
-	list_for_each_entry_safe(uev, tmp, tmpq, node) {
-		list_del_init(&uev->node);
-		FREE(uev);
-	}
-}
-
 /*
  * Service the uevent queue.
  */
@@ -189,6 +291,7 @@ int uevent_dispatch(int (*uev_trigger)(struct uevent *, void * trigger_data),
 		pthread_mutex_unlock(uevq_lockp);
 		if (!my_uev_trigger)
 			break;
+		merge_uevq(&uevq_tmp);
 		service_uevq(&uevq_tmp);
 	}
 	condlog(3, "Terminating uev service queue");
-- 
2.8.1.windows.1

  parent reply	other threads:[~2016-12-27  8:03 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-12-27  8:03 [PATCH 00/12] multipath-tools: improve processing efficiency for addition and deletion of multipath devices tang.junhui
2016-12-27  8:03 ` [PATCH 01/12] libmultipath: add wwid for "struct uevent" to record wwid of uevent tang.junhui
2017-01-03 22:02   ` Benjamin Marzinski
2017-01-04  6:56     ` tang.junhui
2017-01-04 18:14       ` Benjamin Marzinski
2017-01-04 20:33         ` Martin Wilck
2017-01-05  3:00           ` Benjamin Marzinski
2017-01-05  3:10         ` tang.junhui
2017-01-05 17:36           ` Benjamin Marzinski
2017-01-06  0:59             ` tang.junhui
2017-01-06 16:02               ` Benjamin Marzinski
2017-01-09  7:22                 ` tang.junhui
2016-12-27  8:03 ` [PATCH 02/12] libmultipath: add merge_node for "struct uevent" to record nodes of merged uevents tang.junhui
2016-12-27  8:03 ` [PATCH 03/12] libmultipath: add two list iteration macros tang.junhui
2016-12-27  8:03 ` [PATCH 04/12] multipathd: add need_do_map to indicate whether need calling domap() in ev_add_path() tang.junhui
2016-12-27  8:03 ` [PATCH 05/12] multipathd: add need_do_map to indicate whether need calling domap() in ev_remove_path() tang.junhui
2016-12-27  8:03 ` [PATCH 06/12] multipathd: move uev_discard() to uevent.c and change its name to uevent_can_discard() tang.junhui
2016-12-27  8:03 ` [PATCH 07/12] multipathd: move calling filter_devnode() from uev_trigger() " tang.junhui
2016-12-27  8:03 ` [PATCH 08/12] libmultipath: wait one seconds for more uevents in uevent_listen() in uevents burst situations tang.junhui
2016-12-28 20:25   ` Martin Wilck
2016-12-29  0:48     ` tang.junhui
2017-01-03 22:31   ` Benjamin Marzinski
2017-01-04  7:32     ` tang.junhui
2016-12-27  8:03 ` tang.junhui [this message]
2017-01-04  0:30   ` [PATCH 09/12] multipathd: merge uevents before proccessing Benjamin Marzinski
2017-01-04  3:29     ` tang.junhui
2016-12-27  8:03 ` [PATCH 10/12] libmultipath: filter " tang.junhui
2017-01-04  1:21   ` Benjamin Marzinski
2017-01-04  2:03     ` tang.junhui
2016-12-27  8:03 ` [PATCH 11/12] multipathd: proccess merged uevents tang.junhui
2017-01-04  1:03   ` Benjamin Marzinski
2017-01-04  1:54     ` tang.junhui
2016-12-27  8:03 ` [PATCH 12/12] libmultipath: use existing wwid when wwid has already been existed in uevent tang.junhui

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1482825809-9528-10-git-send-email-tang.junhui@zte.com.cn \
    --to=tang.junhui@zte.com.cn \
    --cc=bart.vanassche@sandisk.com \
    --cc=bmarzins@redhat.com \
    --cc=christophe.varoqui@opensvc.com \
    --cc=dm-devel@redhat.com \
    --cc=hare@suse.de \
    --cc=mwilck@suse.com \
    --cc=tang.wenjun3@zte.com.cn \
    --cc=zhang.kai16@zte.com.cn \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.