get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/14959/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 14959,
    "url": "http://patches.dpdk.org/api/patches/14959/?format=api",
    "web_url": "http://patches.dpdk.org/project/dpdk/patch/1469105736-413-1-git-send-email-i.maximets@samsung.com/",
    "project": {
        "id": 1,
        "url": "http://patches.dpdk.org/api/projects/1/?format=api",
        "name": "DPDK",
        "link_name": "dpdk",
        "list_id": "dev.dpdk.org",
        "list_email": "dev@dpdk.org",
        "web_url": "http://core.dpdk.org",
        "scm_url": "git://dpdk.org/dpdk",
        "webscm_url": "http://git.dpdk.org/dpdk",
        "list_archive_url": "https://inbox.dpdk.org/dev",
        "list_archive_url_format": "https://inbox.dpdk.org/dev/{}",
        "commit_url_format": ""
    },
    "msgid": "<1469105736-413-1-git-send-email-i.maximets@samsung.com>",
    "list_archive_url": "https://inbox.dpdk.org/dev/1469105736-413-1-git-send-email-i.maximets@samsung.com",
    "date": "2016-07-21T12:55:36",
    "name": "[dpdk-dev,v3] vhost: fix driver unregister for client mode",
    "commit_ref": null,
    "pull_url": null,
    "state": "accepted",
    "archived": true,
    "hash": "35bb783c2ea640b5ab683507ade6f4baa27246e7",
    "submitter": {
        "id": 323,
        "url": "http://patches.dpdk.org/api/people/323/?format=api",
        "name": "Ilya Maximets",
        "email": "i.maximets@samsung.com"
    },
    "delegate": null,
    "mbox": "http://patches.dpdk.org/project/dpdk/patch/1469105736-413-1-git-send-email-i.maximets@samsung.com/mbox/",
    "series": [],
    "comments": "http://patches.dpdk.org/api/patches/14959/comments/",
    "check": "pending",
    "checks": "http://patches.dpdk.org/api/patches/14959/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<dev-bounces@dpdk.org>",
        "X-Original-To": "patchwork@dpdk.org",
        "Delivered-To": "patchwork@dpdk.org",
        "Received": [
            "from [92.243.14.124] (localhost [IPv6:::1])\n\tby dpdk.org (Postfix) with ESMTP id 060935424;\n\tThu, 21 Jul 2016 14:55:48 +0200 (CEST)",
            "from mailout2.w1.samsung.com (mailout2.w1.samsung.com\n\t[210.118.77.12]) by dpdk.org (Postfix) with ESMTP id CEB042B9D\n\tfor <dev@dpdk.org>; Thu, 21 Jul 2016 14:55:46 +0200 (CEST)",
            "from eucpsbgm1.samsung.com (unknown [203.254.199.244])\n\tby mailout2.w1.samsung.com\n\t(Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5\n\t2014)) with ESMTP id <0OAO00HJX18XG3A0@mailout2.w1.samsung.com> for\n\tdev@dpdk.org; Thu, 21 Jul 2016 13:55:45 +0100 (BST)",
            "from eusync1.samsung.com ( [203.254.199.211])\n\tby eucpsbgm1.samsung.com (EUCPMTA) with SMTP id D0.D2.05254.056C0975;\n\tThu, 21 Jul 2016 13:55:44 +0100 (BST)",
            "from imaximets.rnd.samsung.ru ([106.109.129.180])\n\tby eusync1.samsung.com\n\t(Oracle Communications Messaging Server 7.0.5.31.0 64bit (built May 5\n\t2014)) with ESMTPA id <0OAO008KR18PFQ70@eusync1.samsung.com>; Thu,\n\t21 Jul 2016 13:55:44 +0100 (BST)"
        ],
        "X-AuditID": "cbfec7f4-f796c6d000001486-17-5790c65040c3",
        "From": "Ilya Maximets <i.maximets@samsung.com>",
        "To": "dev@dpdk.org, Huawei Xie <huawei.xie@intel.com>,\n\tYuanhan Liu <yuanhan.liu@linux.intel.com>",
        "Cc": "Dyasly Sergey <s.dyasly@samsung.com>,\n\tHeetae Ahn <heetae82.ahn@samsung.com>,\n\tThomas Monjalon <thomas.monjalon@6wind.com>,\n\tIlya Maximets <i.maximets@samsung.com>",
        "Date": "Thu, 21 Jul 2016 15:55:36 +0300",
        "Message-id": "<1469105736-413-1-git-send-email-i.maximets@samsung.com>",
        "X-Mailer": "git-send-email 2.7.4",
        "In-reply-to": "<1469003563-27340-1-git-send-email-i.maximets@samsung.com>",
        "References": "<1469003563-27340-1-git-send-email-i.maximets@samsung.com>",
        "X-Brightmail-Tracker": "H4sIAAAAAAAAA+NgFprMLMWRmVeSWpSXmKPExsVy+t/xy7oBxyaEG3y+YGPx7tN2Jotpn2+z\n\tW7TPPMtkcaX9J7vF5NlSFl82TWezuD7hAqsDu8fF/juMHr8WLGX1WLznJZPHvJOBHn1bVjEG\n\tsEZx2aSk5mSWpRbp2yVwZbQvPM5e8Ni44ua6kywNjDc0uxg5OSQETCQuXv7GBGGLSVy4t56t\n\ti5GLQ0hgKaPE0R07mSCcViaJGb272EGq2AR0JE6tPsIIYosIJEgc2f+bFaSIWWAVo8T1x5PA\n\tioQFHCQuPVsCZrMIqEo0rrwEVMTBwSvgIrFkjR/ENjmJm+c6mUFsTgF3ie/3j7GB2EICbhKb\n\tjjQyTWDkXcDIsIpRNLU0uaA4KT3XUK84Mbe4NC9dLzk/dxMjJKi+7GBcfMzqEKMAB6MSD2/C\n\tyv5wIdbEsuLK3EOMEhzMSiK84ocmhAvxpiRWVqUW5ccXleakFh9ilOZgURLnnbvrfYiQQHpi\n\tSWp2ampBahFMlomDU6qBUeC3JMdS3ynOQt6PPuoY7n5a/+avBk+zy5q/+aVqqo07ehaKvHio\n\tdvfbZiUt1Y41wcun9q4vdCtsuPqlUG3i1cIZZv19fC+Olsyy/7hyxY5A94dZXuKSRbtEmcW2\n\tmv949e/2inffgg7L8v6K3O52sqN8+8O8DeYqUzOe6TPqO4RwH/zi0uCpqcRSnJFoqMVcVJwI\n\tAIdHM/MmAgAA",
        "Subject": "[dpdk-dev] [PATCH v3] vhost: fix driver unregister for client mode",
        "X-BeenThere": "dev@dpdk.org",
        "X-Mailman-Version": "2.1.15",
        "Precedence": "list",
        "List-Id": "patches and discussions about DPDK <dev.dpdk.org>",
        "List-Unsubscribe": "<http://dpdk.org/ml/options/dev>,\n\t<mailto:dev-request@dpdk.org?subject=unsubscribe>",
        "List-Archive": "<http://dpdk.org/ml/archives/dev/>",
        "List-Post": "<mailto:dev@dpdk.org>",
        "List-Help": "<mailto:dev-request@dpdk.org?subject=help>",
        "List-Subscribe": "<http://dpdk.org/ml/listinfo/dev>,\n\t<mailto:dev-request@dpdk.org?subject=subscribe>",
        "Errors-To": "dev-bounces@dpdk.org",
        "Sender": "\"dev\" <dev-bounces@dpdk.org>"
    },
    "content": "Currently while calling of 'rte_vhost_driver_unregister()' connection\nto QEMU will not be closed. This leads to inability to register driver\nagain and reconnect to same virtual machine.\n\nThis scenario is reproducible with OVS. While executing of the following\ncommand vhost port will be re-created (will be executed\n'rte_vhost_driver_register()' followed by 'rte_vhost_driver_unregister()')\nnetwork will be broken and QEMU possibly will crash:\n\n\tovs-vsctl set Interface vhost1 ofport_request=15\n\nFix this by closing all established connections on driver unregister and\nremoving of pending connections from reconnection list.\n\nFixes: 64ab701c3d1e (\"vhost: add vhost-user client mode\")\n\nSigned-off-by: Ilya Maximets <i.maximets@samsung.com>\n---\n\nVersion 3:\n\t* fixed leak of file descriptors by adding of\n\t  'close(reconn->fd)' to 'vhost_user_remove_reconnect()'\n\nVersion 2:\n\t* style fixes.\n\n lib/librte_vhost/vhost_user/fd_man.c         | 15 ++++++--\n lib/librte_vhost/vhost_user/fd_man.h         |  2 +-\n lib/librte_vhost/vhost_user/vhost-net-user.c | 57 ++++++++++++++++++++++++----\n 3 files changed, 63 insertions(+), 11 deletions(-)",
    "diff": "diff --git a/lib/librte_vhost/vhost_user/fd_man.c b/lib/librte_vhost/vhost_user/fd_man.c\nindex c691339..2d3eeb7 100644\n--- a/lib/librte_vhost/vhost_user/fd_man.c\n+++ b/lib/librte_vhost/vhost_user/fd_man.c\n@@ -132,8 +132,10 @@ fdset_init(struct fdset *pfdset)\n \tif (pfdset == NULL)\n \t\treturn;\n \n-\tfor (i = 0; i < MAX_FDS; i++)\n+\tfor (i = 0; i < MAX_FDS; i++) {\n \t\tpfdset->fd[i].fd = -1;\n+\t\tpfdset->fd[i].dat = NULL;\n+\t}\n \tpfdset->num = 0;\n }\n \n@@ -166,14 +168,16 @@ fdset_add(struct fdset *pfdset, int fd, fd_cb rcb, fd_cb wcb, void *dat)\n \n /**\n  *  Unregister the fd from the fdset.\n+ *  Returns context of a given fd or NULL.\n  */\n-void\n+void *\n fdset_del(struct fdset *pfdset, int fd)\n {\n \tint i;\n+\tvoid *dat = NULL;\n \n \tif (pfdset == NULL || fd == -1)\n-\t\treturn;\n+\t\treturn NULL;\n \n \tdo {\n \t\tpthread_mutex_lock(&pfdset->fd_mutex);\n@@ -181,13 +185,17 @@ fdset_del(struct fdset *pfdset, int fd)\n \t\ti = fdset_find_fd(pfdset, fd);\n \t\tif (i != -1 && pfdset->fd[i].busy == 0) {\n \t\t\t/* busy indicates r/wcb is executing! */\n+\t\t\tdat = pfdset->fd[i].dat;\n \t\t\tpfdset->fd[i].fd = -1;\n \t\t\tpfdset->fd[i].rcb = pfdset->fd[i].wcb = NULL;\n+\t\t\tpfdset->fd[i].dat = NULL;\n \t\t\tpfdset->num--;\n \t\t\ti = -1;\n \t\t}\n \t\tpthread_mutex_unlock(&pfdset->fd_mutex);\n \t} while (i != -1);\n+\n+\treturn dat;\n }\n \n /**\n@@ -203,6 +211,7 @@ fdset_del_slot(struct fdset *pfdset, int index)\n \n \tpfdset->fd[index].fd = -1;\n \tpfdset->fd[index].rcb = pfdset->fd[index].wcb = NULL;\n+\tpfdset->fd[index].dat = NULL;\n \tpfdset->num--;\n \n \tpthread_mutex_unlock(&pfdset->fd_mutex);\ndiff --git a/lib/librte_vhost/vhost_user/fd_man.h b/lib/librte_vhost/vhost_user/fd_man.h\nindex 74ecde2..bd66ed1 100644\n--- a/lib/librte_vhost/vhost_user/fd_man.h\n+++ b/lib/librte_vhost/vhost_user/fd_man.h\n@@ -60,7 +60,7 @@ void fdset_init(struct fdset *pfdset);\n int fdset_add(struct fdset *pfdset, int fd,\n \tfd_cb rcb, fd_cb wcb, void *dat);\n \n-void fdset_del(struct fdset *pfdset, int fd);\n+void *fdset_del(struct fdset *pfdset, int fd);\n \n void fdset_event_dispatch(struct fdset *pfdset);\n \ndiff --git a/lib/librte_vhost/vhost_user/vhost-net-user.c b/lib/librte_vhost/vhost_user/vhost-net-user.c\nindex f0ea3a2..62c5ec3 100644\n--- a/lib/librte_vhost/vhost_user/vhost-net-user.c\n+++ b/lib/librte_vhost/vhost_user/vhost-net-user.c\n@@ -60,6 +60,7 @@\n struct vhost_user_socket {\n \tchar *path;\n \tint listenfd;\n+\tint connfd;\n \tbool is_server;\n \tbool reconnect;\n };\n@@ -277,11 +278,13 @@ vhost_user_add_connection(int fd, struct vhost_user_socket *vsocket)\n \n \tRTE_LOG(INFO, VHOST_CONFIG, \"new device, handle is %d\\n\", vid);\n \n+\tvsocket->connfd = fd;\n \tconn->vsocket = vsocket;\n \tconn->vid = vid;\n \tret = fdset_add(&vhost_user.fdset, fd, vhost_user_msg_handler,\n \t\t\tNULL, conn);\n \tif (ret < 0) {\n+\t\tvsocket->connfd = -1;\n \t\tfree(conn);\n \t\tclose(fd);\n \t\tRTE_LOG(ERR, VHOST_CONFIG,\n@@ -329,6 +332,7 @@ vhost_user_msg_handler(int connfd, void *dat, int *remove)\n \t\t\tRTE_LOG(ERR, VHOST_CONFIG,\n \t\t\t\t\"vhost read incorrect message\\n\");\n \n+\t\tvsocket->connfd = -1;\n \t\tclose(connfd);\n \t\t*remove = 1;\n \t\tfree(conn);\n@@ -635,6 +639,7 @@ rte_vhost_driver_register(const char *path, uint64_t flags)\n \t\tgoto out;\n \tmemset(vsocket, 0, sizeof(struct vhost_user_socket));\n \tvsocket->path = strdup(path);\n+\tvsocket->connfd = -1;\n \n \tif ((flags & RTE_VHOST_USER_CLIENT) != 0) {\n \t\tvsocket->reconnect = !(flags & RTE_VHOST_USER_NO_RECONNECT);\n@@ -664,6 +669,30 @@ out:\n \treturn ret;\n }\n \n+static bool\n+vhost_user_remove_reconnect(struct vhost_user_socket *vsocket)\n+{\n+\tint found = false;\n+\tstruct vhost_user_reconnect *reconn, *next;\n+\n+\tpthread_mutex_lock(&reconn_list.mutex);\n+\n+\tfor (reconn = TAILQ_FIRST(&reconn_list.head);\n+\t     reconn != NULL; reconn = next) {\n+\t\tnext = TAILQ_NEXT(reconn, next);\n+\n+\t\tif (reconn->vsocket == vsocket) {\n+\t\t\tTAILQ_REMOVE(&reconn_list.head, reconn, next);\n+\t\t\tclose(reconn->fd);\n+\t\t\tfree(reconn);\n+\t\t\tfound = true;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\tpthread_mutex_unlock(&reconn_list.mutex);\n+\treturn found;\n+}\n+\n /**\n  * Unregister the specified vhost socket\n  */\n@@ -672,20 +701,34 @@ rte_vhost_driver_unregister(const char *path)\n {\n \tint i;\n \tint count;\n+\tstruct vhost_user_connection *conn;\n \n \tpthread_mutex_lock(&vhost_user.mutex);\n \n \tfor (i = 0; i < vhost_user.vsocket_cnt; i++) {\n-\t\tif (!strcmp(vhost_user.vsockets[i]->path, path)) {\n-\t\t\tif (vhost_user.vsockets[i]->is_server) {\n-\t\t\t\tfdset_del(&vhost_user.fdset,\n-\t\t\t\t\tvhost_user.vsockets[i]->listenfd);\n-\t\t\t\tclose(vhost_user.vsockets[i]->listenfd);\n+\t\tstruct vhost_user_socket *vsocket = vhost_user.vsockets[i];\n+\n+\t\tif (!strcmp(vsocket->path, path)) {\n+\t\t\tif (vsocket->is_server) {\n+\t\t\t\tfdset_del(&vhost_user.fdset, vsocket->listenfd);\n+\t\t\t\tclose(vsocket->listenfd);\n \t\t\t\tunlink(path);\n+\t\t\t} else if (vsocket->reconnect) {\n+\t\t\t\tvhost_user_remove_reconnect(vsocket);\n+\t\t\t}\n+\n+\t\t\tconn = fdset_del(&vhost_user.fdset, vsocket->connfd);\n+\t\t\tif (conn) {\n+\t\t\t\tRTE_LOG(INFO, VHOST_CONFIG,\n+\t\t\t\t\t\"free connfd = %d for device '%s'\\n\",\n+\t\t\t\t\tvsocket->connfd, path);\n+\t\t\t\tclose(vsocket->connfd);\n+\t\t\t\tvhost_destroy_device(conn->vid);\n+\t\t\t\tfree(conn);\n \t\t\t}\n \n-\t\t\tfree(vhost_user.vsockets[i]->path);\n-\t\t\tfree(vhost_user.vsockets[i]);\n+\t\t\tfree(vsocket->path);\n+\t\t\tfree(vsocket);\n \n \t\t\tcount = --vhost_user.vsocket_cnt;\n \t\t\tvhost_user.vsockets[i] = vhost_user.vsockets[count];\n",
    "prefixes": [
        "dpdk-dev",
        "v3"
    ]
}