<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:\5B8B\4F53;
        panose-1:2 1 6 0 3 1 1 1 1 1;}
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
        {font-family:"\@\5B8B\4F53";
        panose-1:2 1 6 0 3 1 1 1 1 1;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        text-align:justify;
        text-justify:inter-ideograph;
        font-size:10.5pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 90.0pt 72.0pt 90.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span style="color:#1F497D">Hello<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">I find an issue when use  dmsetup in the situation udev event timeout.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Dmsetup use the dm_udev_wait function sync with udev event.When use the dmsetup generate a new dm-disk, if the raw disk is abnormal(for example ,a ipsan disk hung IO request), the udevd daemon handle the dm-disk
 udev event maybe timeout, and will not notify the dmsetup  by semaphore. And because the  dm_udev_wait use the semop to sync with udevd, if udevd event timeout, the dmsetup will hung forever even when the raw disk be recovery.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">I wonder if we could use the semtimedop instead semop to add the timeout in function  dm_udev_wait. If the udevd daemon timeout when handle the dm event, the dm_udev_wait could timeout too, and the dmsetup could
 return error.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">This is my patch base lvm2-2.02.115-3:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">From 6961f824abe8eb15f8328f2f4bd39f4cdbf65d4f Mon Sep 17 00:00:00 2001<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">From: fengtiantian <<a href="mailto:fengtiantian@huawei.com">fengtiantian@huawei.com</a>><o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Date: Mon, 23 Oct 2017 19:29:55 +0800<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">Subject: [PATCH] add timeout when fail to wait udev<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">libdm/libdm-common.c |  7 ++++++-<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">tools/dmsetup.c      | 20 ++++++++++++++++----<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">2 files changed, 22 insertions(+), 5 deletions(-)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">index bd51645..ede2fea 100644<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">--- a/libdm/libdm-common.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+++ b/libdm/libdm-common.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -59,6 +59,8 @@ union semun<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">#endif<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">#endif<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+#define UDEV_SEM_TIMEOUT 300<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static char _sysfs_dir[PATH_MAX] = "/sys/";<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static char _path0[PATH_MAX];           /* path buffer, safe 4kB on stack */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -2476,6 +2478,9 @@ static int _udev_wait(uint32_t cookie)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        int semid;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        struct sembuf sb = {0, 0, 0};<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       struct timespec timeout;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       timeout.tv_sec = UDEV_SEM_TIMEOUT;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       timeout.tv_nsec = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (!cookie || !dm_udev_get_sync_support())<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                return 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -2496,7 +2501,7 @@ static int _udev_wait(uint32_t cookie)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                             cookie, semid);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">repeat_wait:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-       if (semop(semid, &sb, 1) < 0) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       if (semtimedop(semid, &sb, 1,&timeout) < 0) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                if (errno == EINTR)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                        goto repeat_wait;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                else if (errno == EIDRM)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">diff --git a/tools/dmsetup.c b/tools/dmsetup.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">index 4202dbb..0840031 100644<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">--- a/tools/dmsetup.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+++ b/tools/dmsetup.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -619,6 +619,7 @@ static int _load(CMD_ARGS)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static int _create(CMD_ARGS)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        int r = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       int udev_wait_r = 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        struct dm_task *dmt;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        const char *file = NULL;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        uint32_t cookie = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -695,18 +696,22 @@ static int _create(CMD_ARGS)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">       out:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (!_udev_cookie)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-               (void) dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               udev_wait_r = dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (r && _switches[VERBOSE_ARG])<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                r = _display_info(dmt);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        dm_task_destroy(dmt);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       if(!udev_wait_r)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               return 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        return r;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">static int _do_rename(const char *name, const char *new_name, const char *new_uuid) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        int r = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       int udev_wait_r = 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        struct dm_task *dmt;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        uint32_t cookie = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        uint16_t udev_flags = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -751,10 +756,13 @@ static int _do_rename(const char *name, const char *new_name, const char *new_uu<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">       out:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (!_udev_cookie)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-               (void) dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               udev_wait_r =  dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        dm_task_destroy(dmt);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       if (!udev_wait_r)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               return 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        return r;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -1267,7 +1275,8 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        int udev_wait_flag = task == DM_DEVICE_RESUME ||<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                             task == DM_DEVICE_REMOVE;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        int r = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       int udev_wait_r = 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        struct dm_task *dmt;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (!(dmt = dm_task_create(task)))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">@@ -1326,13 +1335,16 @@ static int _simple(int task, const char *name, uint32_t event_nr, int display)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">       out:<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (!_udev_cookie && udev_wait_flag)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">-               (void) dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               udev_wait_r = dm_udev_wait(cookie);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        if (r && display && _switches[VERBOSE_ARG])<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">                r = _display_info(dmt);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        dm_task_destroy(dmt);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+       if(!udev_wait_r)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+               return 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">        return r;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D"><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">--<o:p></o:p></span></p>
<p class="MsoNormal"><span style="color:#1F497D">1.8.3.1<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-size:11.0pt"><o:p> </o:p></span></p>
</div>
</body>
</html>