All of lore.kernel.org
 help / color / mirror / Atom feed
* [dm-devel] [PATCH] multipathd: fix no checking persistent reservation registration
@ 2021-06-24  8:47 lixiaokeng
  2021-06-24 10:19 ` Martin Wilck
  0 siblings, 1 reply; 3+ messages in thread
From: lixiaokeng @ 2021-06-24  8:47 UTC (permalink / raw)
  To: Christophe Varoqui, Martin Wilck, Benjamin Marzinski,
	dm-devel mailing list
  Cc: linfeilong, liuzhiqiang (I)

If one multipath device has two paths, the first is down (network
failure) and the second is up, then we register a prkey to the
device. The first path will register successfully but the second
won't. Then fix the network. The uev_update_path will race with
check_path. If uev_update_path -> pathinfo is called before
check_path, the state of the first path will be set PATH_UP
without checking persistent reservation registration.

Here we add checking in uev_update_path.

Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
---
 multipathd/main.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/multipathd/main.c b/multipathd/main.c
index 2251e02c..0948bf81 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -1316,6 +1316,7 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
 	struct path * pp;
 	struct config *conf;
 	int needs_reinit = 0;
+	int oldstate;

 	switch ((rc = change_foreign(uev->udev))) {
 	case FOREIGN_OK:
@@ -1366,9 +1367,22 @@ uev_update_path (struct uevent *uev, struct vectors * vecs)
 			pp->udev = udev_device_ref(uev->udev);
 			conf = get_multipath_config();
 			pthread_cleanup_push(put_multipath_config, conf);
+			oldstate = pp->state;
+
 			if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) != PATHINFO_OK)
 				condlog(1, "%s: pathinfo failed after change uevent",
 					uev->kernel);
+
+			if (pp->state != oldstate && (pp->state == PATH_UP || pp->state == PATH_GHOST)) {
+				if (pp->mpp && pp->mpp->prflag) {
+					/*
+					 * Check Persistent Reservation.
+					 */
+					condlog(2, "%s: checking persistent reservation "
+						"registration when update path", pp->dev);
+					mpath_pr_event_handle(pp);
+				}
+			}
 			pthread_cleanup_pop(1);
 		}

-- 

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


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [dm-devel] [PATCH] multipathd: fix no checking persistent reservation registration
  2021-06-24  8:47 [dm-devel] [PATCH] multipathd: fix no checking persistent reservation registration lixiaokeng
@ 2021-06-24 10:19 ` Martin Wilck
  2021-06-24 12:31   ` lixiaokeng
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Wilck @ 2021-06-24 10:19 UTC (permalink / raw)
  To: lixiaokeng, Christophe Varoqui, Benjamin Marzinski,
	dm-devel mailing list
  Cc: linfeilong, liuzhiqiang (I)

On Do, 2021-06-24 at 16:47 +0800, lixiaokeng wrote:
> If one multipath device has two paths, the first is down (network
> failure) and the second is up, then we register a prkey to the
> device. The first path will register successfully but the second
> won't. Then fix the network. The uev_update_path will race with
> check_path. If uev_update_path -> pathinfo is called before
> check_path, the state of the first path will be set PATH_UP
> without checking persistent reservation registration.
> 
> Here we add checking in uev_update_path.
> 
> Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
> ---
>  multipathd/main.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/multipathd/main.c b/multipathd/main.c
> index 2251e02c..0948bf81 100644
> --- a/multipathd/main.c
> +++ b/multipathd/main.c
> @@ -1316,6 +1316,7 @@ uev_update_path (struct uevent *uev, struct
> vectors * vecs)
>         struct path * pp;
>         struct config *conf;
>         int needs_reinit = 0;
> +       int oldstate;
> 
>         switch ((rc = change_foreign(uev->udev))) {
>         case FOREIGN_OK:
> @@ -1366,9 +1367,22 @@ uev_update_path (struct uevent *uev, struct
> vectors * vecs)
>                         pp->udev = udev_device_ref(uev->udev);
>                         conf = get_multipath_config();
>                         pthread_cleanup_push(put_multipath_config,
> conf);
> +                       oldstate = pp->state;
> +
>                         if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) !=
> PATHINFO_OK)
>                                 condlog(1, "%s: pathinfo failed after
> change uevent",
>                                         uev->kernel);
> +
> +                       if (pp->state != oldstate && (pp->state ==
> PATH_UP || pp->state == PATH_GHOST)) {


I don't understand. pathinfo(DI_SYSFS|DI_NOIO) doesn't modify 
pp->state.  So your first condition should always be false.
Am I overlooking something?

Regards
Martin



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


^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [dm-devel] [PATCH] multipathd: fix no checking persistent reservation registration
  2021-06-24 10:19 ` Martin Wilck
@ 2021-06-24 12:31   ` lixiaokeng
  0 siblings, 0 replies; 3+ messages in thread
From: lixiaokeng @ 2021-06-24 12:31 UTC (permalink / raw)
  To: Martin Wilck, Christophe Varoqui, Benjamin Marzinski,
	dm-devel mailing list
  Cc: linfeilong, liuzhiqiang (I)

Hi Martin,

You are right!! This problem was found in 0.7.7. Now I know it
is fixed with commit 9b715bf9 in 0.8.1.
I will use the commit 9b715bf9 to fix it. Thanks for your
review and answer very much.

Regarts
Lixiaokeng

On 2021/6/24 18:19, Martin Wilck wrote:
> On Do, 2021-06-24 at 16:47 +0800, lixiaokeng wrote:
>> If one multipath device has two paths, the first is down (network
>> failure) and the second is up, then we register a prkey to the
>> device. The first path will register successfully but the second
>> won't. Then fix the network. The uev_update_path will race with
>> check_path. If uev_update_path -> pathinfo is called before
>> check_path, the state of the first path will be set PATH_UP
>> without checking persistent reservation registration.
>>
>> Here we add checking in uev_update_path.
>>
>> Signed-off-by: Lixiaokeng <lixiaokeng@huawei.com>
>> ---
>>  multipathd/main.c | 14 ++++++++++++++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/multipathd/main.c b/multipathd/main.c
>> index 2251e02c..0948bf81 100644
>> --- a/multipathd/main.c
>> +++ b/multipathd/main.c
>> @@ -1316,6 +1316,7 @@ uev_update_path (struct uevent *uev, struct
>> vectors * vecs)
>>         struct path * pp;
>>         struct config *conf;
>>         int needs_reinit = 0;
>> +       int oldstate;
>>
>>         switch ((rc = change_foreign(uev->udev))) {
>>         case FOREIGN_OK:
>> @@ -1366,9 +1367,22 @@ uev_update_path (struct uevent *uev, struct
>> vectors * vecs)
>>                         pp->udev = udev_device_ref(uev->udev);
>>                         conf = get_multipath_config();
>>                         pthread_cleanup_push(put_multipath_config,
>> conf);
>> +                       oldstate = pp->state;
>> +
>>                         if (pathinfo(pp, conf, DI_SYSFS|DI_NOIO) !=
>> PATHINFO_OK)
>>                                 condlog(1, "%s: pathinfo failed after
>> change uevent",
>>                                         uev->kernel);
>> +
>> +                       if (pp->state != oldstate && (pp->state ==
>> PATH_UP || pp->state == PATH_GHOST)) {
> 
> 
> I don't understand. pathinfo(DI_SYSFS|DI_NOIO) doesn't modify 
> pp->state.  So your first condition should always be false.
> Am I overlooking something?
> 
> Regards
> Martin
> 
> 
> .
> 


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


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2021-06-24 12:31 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-24  8:47 [dm-devel] [PATCH] multipathd: fix no checking persistent reservation registration lixiaokeng
2021-06-24 10:19 ` Martin Wilck
2021-06-24 12:31   ` lixiaokeng

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.