diff mbox

[10/12] libmultipath: filter uevents before proccessing

Message ID 1482825809-9528-11-git-send-email-tang.junhui@zte.com.cn (mailing list archive)
State Not Applicable, archived
Delegated to: christophe varoqui
Headers show

Commit Message

tang.junhui@zte.com.cn Dec. 27, 2016, 8:03 a.m. UTC
From: tang.junhui <tang.junhui@zte.com.cn>

Before merging uevents, these uevents are going to be filtered:
Change or addition uevent of a removed path (it indicate by an
deletion uevent occurred later).

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

Comments

Benjamin Marzinski Jan. 4, 2017, 1:21 a.m. UTC | #1
On Tue, Dec 27, 2016 at 04:03:27PM +0800, tang.junhui@zte.com.cn wrote:
> From: tang.junhui <tang.junhui@zte.com.cn>
> 
> Before merging uevents, these uevents are going to be filtered:
> Change or addition uevent of a removed path (it indicate by an
> deletion uevent occurred later).
> 

I think it's safe to remove add and change uevents if they are followed
by a remove event, regardless of whether or not they have a wwid, as
long as the kernel name is the same.  We only get the remove event when
the device is gone. Processing the add and change events will never get
us anything in these cases, because there is no device to act on.

-Ben

> Change-Id: If00c2c2e23ea466c1d4643c541ed2d8f9a0c8dea
> Signed-off-by: tang.junhui <tang.junhui@zte.com.cn>
> ---
>  libmultipath/uevent.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)
> 
> diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
> index 114068c..424f272 100644
> --- a/libmultipath/uevent.c
> +++ b/libmultipath/uevent.c
> @@ -140,6 +140,28 @@ uevent_can_discard(char *devpath, char *kernel)
>  }
>  
>  bool
> +uevent_can_filter(struct uevent *earlier, struct uevent *later)
> +{
> +
> +	/*
> +	 * filter earlier uvents if path has removed later, eg:
> +	 * "add path3 |chang path3 |add path2 |remove path3"
> +	 * can filter as:
> +	 * "add path2 |remove path3"
> +	 * uevent "add path3" and "chang path3" are filtered out
> +	 */
> +	if (earlier->wwid && later->wwid &&
> +		!strcmp(earlier->wwid, later->wwid) &&
> +		strncmp(later->kernel, "dm-", 3) &&
> +		!strcmp(later->action, "remove") &&
> +		!strcmp(earlier->kernel, later->kernel)) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +bool
>  merge_need_stop(struct uevent *earlier, struct uevent *later)
>  {
>  	/*
> @@ -196,6 +218,38 @@ uevent_can_merge(struct uevent *earlier, struct uevent *later)
>  }
>  
>  void
> +uevent_filter(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:
> +		/*
> +		 * filter unnessary earlier uevents by the later uevent
> +		 */
> +		if (uevent_can_filter(earlier, later)) {
> +			condlog(2, "uevent: %s-%s-%s has removed by uevent: %s-%s-%s, filtered",
> +				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_del_init(&temp->node);
> +			if (temp->udev)
> +				udev_device_unref(temp->udev);
> +			FREE(temp);
> +
> +			if (earlier ==  list_entry(tmpq, typeof(struct uevent), node))
> +				break;
> +			else
> +				goto next_earlier_node;
> +		}
> +	}
> +}
> +
> +void
>  uevent_merge(struct uevent *later, struct list_head *tmpq)
>  {
>  	struct uevent *earlier, *temp;
> @@ -232,6 +286,7 @@ merge_uevq(struct list_head *tmpq)
>  	struct uevent *later;
>  
>  	list_for_each_entry_reverse(later, tmpq, node) {
> +		uevent_filter(later, tmpq);
>  		uevent_merge(later, tmpq);
>  	}
>  }
> -- 
> 2.8.1.windows.1
> 

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel
tang.junhui@zte.com.cn Jan. 4, 2017, 2:03 a.m. UTC | #2
Hello Ben,

I add wwid judgment for safe.
I think twice, and as you say, it is safe enough without
this judgment, I will delete these wwid judgment.

Tanks
Tang Junhui



发件人:         "Benjamin Marzinski" <bmarzins@redhat.com>
收件人:         tang.junhui@zte.com.cn, 
抄送:   tang.wenjun3@zte.com.cn, zhang.kai16@zte.com.cn, 
dm-devel@redhat.com, bart.vanassche@sandisk.com, mwilck@suse.com
日期:   2017/01/04 09:28
主题:   Re: [dm-devel] [PATCH 10/12] libmultipath: filter uevents before 
proccessing
发件人: dm-devel-bounces@redhat.com



On Tue, Dec 27, 2016 at 04:03:27PM +0800, tang.junhui@zte.com.cn wrote:
> From: tang.junhui <tang.junhui@zte.com.cn>

> 

> Before merging uevents, these uevents are going to be filtered:

> Change or addition uevent of a removed path (it indicate by an

> deletion uevent occurred later).

> 


I think it's safe to remove add and change uevents if they are followed
by a remove event, regardless of whether or not they have a wwid, as
long as the kernel name is the same.  We only get the remove event when
the device is gone. Processing the add and change events will never get
us anything in these cases, because there is no device to act on.

-Ben

> Change-Id: If00c2c2e23ea466c1d4643c541ed2d8f9a0c8dea

> Signed-off-by: tang.junhui <tang.junhui@zte.com.cn>

> ---

>  libmultipath/uevent.c | 55 

+++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 55 insertions(+)

> 

> diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c

> index 114068c..424f272 100644

> --- a/libmultipath/uevent.c

> +++ b/libmultipath/uevent.c

> @@ -140,6 +140,28 @@ uevent_can_discard(char *devpath, char *kernel)

>  }

> 

>  bool

> +uevent_can_filter(struct uevent *earlier, struct uevent *later)

> +{

> +

> +              /*

> +               * filter earlier uvents if path has removed later, eg:

> +               * "add path3 |chang path3 |add path2 |remove path3"

> +               * can filter as:

> +               * "add path2 |remove path3"

> +               * uevent "add path3" and "chang path3" are filtered out

> +               */

> +              if (earlier->wwid && later->wwid &&

> +                              !strcmp(earlier->wwid, later->wwid) &&

> +                              strncmp(later->kernel, "dm-", 3) &&

> +                              !strcmp(later->action, "remove") &&

> +                              !strcmp(earlier->kernel, later->kernel)) 

{
> +                              return true;

> +              }

> +

> +              return false;

> +}

> +

> +bool

>  merge_need_stop(struct uevent *earlier, struct uevent *later)

>  {

>                /*

> @@ -196,6 +218,38 @@ uevent_can_merge(struct uevent *earlier, struct 

uevent *later)
>  }

> 

>  void

> +uevent_filter(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:

> +                              /*

> +                               * filter unnessary earlier uevents by 

the later uevent
> +                               */

> +                              if (uevent_can_filter(earlier, later)) {

> +                                              condlog(2, "uevent: 

%s-%s-%s has removed by uevent: %s-%s-%s, filtered",
> + 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_del_init(&temp->node);

> +                                              if (temp->udev)

> + udev_device_unref(temp->udev);

> +                                              FREE(temp);

> +

> +                                              if (earlier == 

list_entry(tmpq, typeof(struct uevent), node))
> +                                                              break;

> +                                              else

> +                                                              goto 

next_earlier_node;
> +                              }

> +              }

> +}

> +

> +void

>  uevent_merge(struct uevent *later, struct list_head *tmpq)

>  {

>                struct uevent *earlier, *temp;

> @@ -232,6 +286,7 @@ merge_uevq(struct list_head *tmpq)

>                struct uevent *later;

> 

>                list_for_each_entry_reverse(later, tmpq, node) {

> +                              uevent_filter(later, tmpq);

>                                uevent_merge(later, tmpq);

>                }

>  }

> -- 

> 2.8.1.windows.1

> 


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

Patch

diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c
index 114068c..424f272 100644
--- a/libmultipath/uevent.c
+++ b/libmultipath/uevent.c
@@ -140,6 +140,28 @@  uevent_can_discard(char *devpath, char *kernel)
 }
 
 bool
+uevent_can_filter(struct uevent *earlier, struct uevent *later)
+{
+
+	/*
+	 * filter earlier uvents if path has removed later, eg:
+	 * "add path3 |chang path3 |add path2 |remove path3"
+	 * can filter as:
+	 * "add path2 |remove path3"
+	 * uevent "add path3" and "chang path3" are filtered out
+	 */
+	if (earlier->wwid && later->wwid &&
+		!strcmp(earlier->wwid, later->wwid) &&
+		strncmp(later->kernel, "dm-", 3) &&
+		!strcmp(later->action, "remove") &&
+		!strcmp(earlier->kernel, later->kernel)) {
+		return true;
+	}
+
+	return false;
+}
+
+bool
 merge_need_stop(struct uevent *earlier, struct uevent *later)
 {
 	/*
@@ -196,6 +218,38 @@  uevent_can_merge(struct uevent *earlier, struct uevent *later)
 }
 
 void
+uevent_filter(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:
+		/*
+		 * filter unnessary earlier uevents by the later uevent
+		 */
+		if (uevent_can_filter(earlier, later)) {
+			condlog(2, "uevent: %s-%s-%s has removed by uevent: %s-%s-%s, filtered",
+				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_del_init(&temp->node);
+			if (temp->udev)
+				udev_device_unref(temp->udev);
+			FREE(temp);
+
+			if (earlier ==  list_entry(tmpq, typeof(struct uevent), node))
+				break;
+			else
+				goto next_earlier_node;
+		}
+	}
+}
+
+void
 uevent_merge(struct uevent *later, struct list_head *tmpq)
 {
 	struct uevent *earlier, *temp;
@@ -232,6 +286,7 @@  merge_uevq(struct list_head *tmpq)
 	struct uevent *later;
 
 	list_for_each_entry_reverse(later, tmpq, node) {
+		uevent_filter(later, tmpq);
 		uevent_merge(later, tmpq);
 	}
 }