diff -Nru dpdk-2.2.0/debian/changelog dpdk-2.2.0/debian/changelog --- dpdk-2.2.0/debian/changelog 2016-04-13 12:38:51.000000000 +0200 +++ dpdk-2.2.0/debian/changelog 2016-04-27 10:58:58.000000000 +0200 @@ -1,3 +1,25 @@ +dpdk (2.2.0-0ubuntu8) yakkety; urgency=medium + + * d/p/ubuntu-backport-[36-37] fix virtio issues (LP: #1570195): + - don't let DPDK initialize virtio devices still in use by the kernel + - this avoids conflicts between kernel and dpdk usage of those devices + - an admin now has to unbind/bind devices as on physical hardware + - this is in the dpdk 16.04 release and delta can then be dropped + - d/dpdk-doc.README.Debian update for changes in virtio-pci handling + - d/dpdk.interfaces update for changes in virtio-pci handling + * d/p/ubuntu-backport-38... fix for memory leak (LP: #1570466): + - call vhost_destroy_device on removing vhost user ports to fix memory leak + - this likely is in the dpdk 16.07 release and delta can then be dropped + * d/p/ubuntu-fix-vhost-user-socket-permission.patch fox (LP: #1546565): + - when vhost_user sockets are created they are owner:group of the process + - the DPDK api to create those has no way to specify owner:group + - to fix that without breaking the API and potential workaround code in + consumers of the library like openvswitch 2.6 for example. This patch + adds an EAL commandline option to specify user:group created vhost_user + sockets should have. + + -- Christian Ehrhardt Wed, 27 Apr 2016 10:58:54 +0200 + dpdk (2.2.0-0ubuntu7) xenial; urgency=medium * Increase max_map_count after setting huge pages (LP: #1507921): diff -Nru dpdk-2.2.0/debian/dpdk-doc.README.Debian dpdk-2.2.0/debian/dpdk-doc.README.Debian --- dpdk-2.2.0/debian/dpdk-doc.README.Debian 2016-03-09 09:35:27.000000000 +0100 +++ dpdk-2.2.0/debian/dpdk-doc.README.Debian 2016-04-25 11:35:14.000000000 +0200 @@ -13,11 +13,17 @@ DPDK but if those applications get packaged they should depend on the runtime. -If you are running with virtio-pci network cards ensure that you don't have to -reassign them to dpdk compatible drivers using /etc/dpdk/interfaces. -Instead it is recommended you take care of blacklisting / whitelisting network -cards to prevent DPDK from "stealing" your main connection used to control the -guest. +Since DPDK technically would be able to use all of your compatible card/driver +combination it is required that you take care of blacklisting / whitelisting +network cards to tell dpdk which it has to to initialize (especially true for +virtio-pci as the normal kernel driver is considered compatible). + +If you are working with virtio-pci network cards it isn't a hard requirement to +assign them to a dpdk compatible userspace driver like uio_pci_generic. But you +have to at least unbind them from the default kernel driver (virtio-pci) to +avoid bugs by dpdk and the kernel working on them simultaneously. It is +recommended to reassign them to dpdk compatible drivers using +/etc/dpdk/interfaces (just as you would with any physical card). libdpdk0 contains the shared object needed to run a program in terms of symbol resolution, but none of the other runtime environment pieces. diff -Nru dpdk-2.2.0/debian/dpdk.interfaces dpdk-2.2.0/debian/dpdk.interfaces --- dpdk-2.2.0/debian/dpdk.interfaces 2016-03-09 09:35:27.000000000 +0100 +++ dpdk-2.2.0/debian/dpdk.interfaces 2016-04-25 11:35:14.000000000 +0200 @@ -3,14 +3,11 @@ # Device ID on the specified bus # Driver to bind against (vfio-pci or uio_pci_generic) # -# Note that depending on your network card and what you want to set up also the -# drivers ixgbe or virtio-pci might apply, but these are the default drivers -# and therefore have not to be rebound as dpdk interfaces. -# -# Be aware that those two drivers are part of linux-image-extra- -# package in case you run into missing module issues. +# Be aware that the two dpdk compatible drivers uio_pci_generic and vfio-pci are +# part of linux-image-extra- package. +# This package is not always installed by default - for example in cloud-images. +# So please install it in case you run into missing module issues. # # # pci 0000:04:00.0 vfio-pci # pci 0000:04:00.1 uio_pci_generic -# pci 0000:05:00.0 ixgbe diff -Nru dpdk-2.2.0/debian/patches/series dpdk-2.2.0/debian/patches/series --- dpdk-2.2.0/debian/patches/series 2016-04-13 12:36:57.000000000 +0200 +++ dpdk-2.2.0/debian/patches/series 2016-04-25 11:35:14.000000000 +0200 @@ -38,3 +38,7 @@ ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch ubuntu-backport-34-port-fix-ring-writer-buffer-overflow.patch ubuntu-backport-35-port-fix-burst-size-mask-type.patch +ubuntu-backport-36-pci-identify-devices-not-managed-by-any-kernel-drive.patch +ubuntu-backport-37-pci-ignore-devices-already-managed-in-Linux-when-map.patch +ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch +ubuntu-fix-vhost-user-socket-permission.patch diff -Nru dpdk-2.2.0/debian/patches/ubuntu-backport-36-pci-identify-devices-not-managed-by-any-kernel-drive.patch dpdk-2.2.0/debian/patches/ubuntu-backport-36-pci-identify-devices-not-managed-by-any-kernel-drive.patch --- dpdk-2.2.0/debian/patches/ubuntu-backport-36-pci-identify-devices-not-managed-by-any-kernel-drive.patch 1970-01-01 01:00:00.000000000 +0100 +++ dpdk-2.2.0/debian/patches/ubuntu-backport-36-pci-identify-devices-not-managed-by-any-kernel-drive.patch 2016-04-19 09:52:29.000000000 +0200 @@ -0,0 +1,34 @@ +Description: backport of dpdk 16.04 fix for LP: #1570195 + +Forwarded: n/a (already upstream) +Author: Christian Ehrhardt +Last-Update: 2016-04-19 + +From ee4e23ada8cb0fcb566295756d30bd21e757c783 Mon Sep 17 00:00:00 2001 +From: Huawei Xie +Date: Tue, 8 Mar 2016 23:33:39 +0800 +Subject: [PATCH] pci: identify devices not managed by any kernel driver + +Use RTE_KDRV_NONE to indicate that kernel driver (other than VFIO/UIO) isn't +managing the device. + +Signed-off-by: Huawei Xie +Acked-by: Yuanhan Liu +Acked-by: David Marchand +--- + lib/librte_eal/linuxapp/eal/eal_pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: dpdk/lib/librte_eal/linuxapp/eal/eal_pci.c +=================================================================== +--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_pci.c ++++ dpdk/lib/librte_eal/linuxapp/eal/eal_pci.c +@@ -362,7 +362,7 @@ pci_scan_one(const char *dirname, uint16 + else + dev->kdrv = RTE_KDRV_UNKNOWN; + } else +- dev->kdrv = RTE_KDRV_UNKNOWN; ++ dev->kdrv = RTE_KDRV_NONE; + + /* device is valid, add in list (sorted) */ + if (TAILQ_EMPTY(&pci_device_list)) { diff -Nru dpdk-2.2.0/debian/patches/ubuntu-backport-37-pci-ignore-devices-already-managed-in-Linux-when-map.patch dpdk-2.2.0/debian/patches/ubuntu-backport-37-pci-ignore-devices-already-managed-in-Linux-when-map.patch --- dpdk-2.2.0/debian/patches/ubuntu-backport-37-pci-ignore-devices-already-managed-in-Linux-when-map.patch 1970-01-01 01:00:00.000000000 +0100 +++ dpdk-2.2.0/debian/patches/ubuntu-backport-37-pci-ignore-devices-already-managed-in-Linux-when-map.patch 2016-04-21 08:44:44.000000000 +0200 @@ -0,0 +1,94 @@ +Description: backport of dpdk 16.04 fix for LP: #1570195 + +The whole infrastructure of 756ce64b1ecd eal: "introduce PCI ioport API" was +introduced post DPDK 2.2. + +Old virtio is not using lib/librte_eal/linuxapp/eal/eal_pci.c:pci_map_device +New Code: + vtpci_init + First tries for modern device -> virtio_read_caps -> rte_eal_pci_map_device + This detects and returns with "Not managed by a supported kernel driver" + Then legacy_virtio_resource_init -> rte_eal_pci_ioport_mapi + This is where the original patch added the check + vtpci_init came in c52afa68 "virtio: move left PCI stuff in the right file" + Old code was eth_virtio_dev_init -> virtio_resource_init(pci_dev) + +The logic of the new patch isn't too complex, just the places don't exist +yet. So we add a semantically equivalent check just before virtio_resource_init. + +Additionally I added a message to make it more clear what happened: +EAL: PCI device 0000:00:04.0 on NUMA socket -1 +EAL: probe driver: 1af4:1000 rte_virtio_pmd +=> PMD: device not available (in use by the kernel) +EAL: Error - exiting with code: 1 + Cause: Requested device 0000:00:04.0 cannot be used + +Forwarded: n/a (already upstream) +Author: Christian Ehrhardt +Last-Update: 2016-04-19 + +From b8eb345378bdefc4c976eaaf5abb221e0aca3460 Mon Sep 17 00:00:00 2001 +From: Huawei Xie +Date: Tue, 8 Mar 2016 23:33:42 +0800 +Subject: [PATCH] pci: ignore devices already managed in Linux when mapping x86 + ioport + +call pci_ioport_map (on x86) only if the pci device is not bound +to a kernel driver. + +Signed-off-by: Huawei Xie +Acked-by: Yuanhan Liu +Acked-by: David Marchand +--- + lib/librte_eal/linuxapp/eal/eal_pci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +Index: dpdk/drivers/net/virtio/virtio_ethdev.c +=================================================================== +--- dpdk.orig/drivers/net/virtio/virtio_ethdev.c ++++ dpdk/drivers/net/virtio/virtio_ethdev.c +@@ -1219,6 +1219,34 @@ static int virtio_resource_init(struct r + } + #endif + ++static int virtio_resource_available(struct rte_pci_device *pci_dev) ++{ ++ int ret = -1; ++ ++ /* only use virtio devices if bound on a supported or no driver ++ * backport of b8eb3453 "pci: ignore devices already managed in Linux ++ * when mapping x86" ++ * Fixes (LP #1570195) and avoids various workarounds and warnings ++ * that formerly were needed */ ++ switch (pci_dev->kdrv) { ++#ifdef VFIO_PRESENT ++ case RTE_KDRV_VFIO: ++#endif ++ case RTE_KDRV_IGB_UIO: ++ case RTE_KDRV_UIO_GENERIC: ++ case RTE_KDRV_NONE: ++ ret = 1; ++ break; ++ default: ++ RTE_LOG(ERR, PMD, "device not available for DPDK" ++ " (in use by kernel)\n"); ++ ret = -1; ++ break; ++ } ++ ++ return ret; ++} ++ + /* + * Process Virtio Config changed interrupt and call the callback + * if link state changed. +@@ -1289,6 +1317,9 @@ eth_virtio_dev_init(struct rte_eth_dev * + + pci_dev = eth_dev->pci_dev; + ++ if (virtio_resource_available(pci_dev) < 0) ++ return -1; ++ + if (virtio_resource_init(pci_dev) < 0) + return -1; + diff -Nru dpdk-2.2.0/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch dpdk-2.2.0/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch --- dpdk-2.2.0/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch 1970-01-01 01:00:00.000000000 +0100 +++ dpdk-2.2.0/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch 2016-04-21 10:08:54.000000000 +0200 @@ -0,0 +1,77 @@ +Description: backport of dpdk 16.07 fix for LP: #1570466 + +Backported from this discussion +http://dpdk.org/dev/patchwork/patch/12103/ +Not accepted yet, but likely to be accepted in some form once tested and +confirmed. + +new fix also relies on a lot of new code, vhost_destroy_device looks totally +different from the former destroy_device. +History on todays function content: + 4796ad63 - original code moved from examples to lib + a90ca1a1 - this replaces ops->destroy_device with vhost_destroy_device + 71dc571e - simple check against null pointers + 45ca9c6f - this changed the code from linked list to arrays + New code cleans with: + notify_ops->destroy_device (callback into the parent) + cleanup_device was existing before even in 2.2 code + free_device as well existing before even in 2.2 code + Old code cleans with: + notify_ops->destroy_device - still there + rm_config_ll_entry -> eventually calls cleanup_device and free_device + (just in the more complex linked list way) +So the only adaption for backporting needed is to replace vhost_destroy_device +with ops->destroy_device(ctx) + +Also along the discussion vserver-fh is now initialized with -1 to avoid +accidentially deleting the first connected port if we delete another not yet +connected port. + +Forwarded: yes (based on an upstream discussion) +Author: Christian Ehrhardt +Last-Update: 2016-04-19 + +Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c +=================================================================== +--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c ++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c +@@ -310,6 +310,7 @@ vserver_new_vq_conn(int fd, void *dat, _ + } + + vdev_ctx.fh = fh; ++ vserver->fh = fh; + size = strnlen(vserver->path, PATH_MAX); + ops->set_ifname(vdev_ctx, vserver->path, + size); +@@ -482,6 +483,7 @@ rte_vhost_driver_register(const char *pa + } + + vserver->path = strdup(path); ++ vserver->fh = -1; + + ret = fdset_add(&g_vhost_server.fdset, vserver->listenfd, + vserver_new_vq_conn, NULL, vserver); +@@ -516,6 +518,11 @@ rte_vhost_driver_unregister(const char * + + for (i = 0; i < g_vhost_server.vserver_cnt; i++) { + if (!strcmp(g_vhost_server.server[i]->path, path)) { ++ struct vhost_device_ctx ctx; ++ ++ ctx.fh = g_vhost_server.server[i]->fh; ++ ops->destroy_device(ctx); ++ + fdset_del(&g_vhost_server.fdset, + g_vhost_server.server[i]->listenfd); + +Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h +=================================================================== +--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.h ++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h +@@ -43,6 +43,7 @@ + struct vhost_server { + char *path; /**< The path the uds is bind to. */ + int listenfd; /**< The listener sockfd. */ ++ uint32_t fh; + }; + + /* refer to hw/virtio/vhost-user.c */ diff -Nru dpdk-2.2.0/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch dpdk-2.2.0/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch --- dpdk-2.2.0/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch 1970-01-01 01:00:00.000000000 +0100 +++ dpdk-2.2.0/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch 2016-04-25 11:35:14.000000000 +0200 @@ -0,0 +1,350 @@ +Description: eal: provide option to set vhost_user socket owner/permissions + +The API doesn't hold a way to specify a owner/permission set for vhost_user +created sockets. + +Projects consuming DPDK started to do 'their own workarounds' like openvswitch +https://patchwork.ozlabs.org/patch/559043/ +https://patchwork.ozlabs.org/patch/559045/ +But for this specific example they are blocked/stalled behind a bigger +rework (https://patchwork.ozlabs.org/patch/604898/). + +We need something now for existing code linking against DPDK. That implies to +avoid changing API/ABI. So I created a DPDK EAL commandline option based ideas +in the former patches. + +Fixes LP: #1546565 + +Forwarded: yes +Author: Christian Ehrhardt +Last-Update: 2016-04-24 + +Index: dpdk/lib/librte_eal/common/eal_common_options.c +=================================================================== +--- dpdk.orig/lib/librte_eal/common/eal_common_options.c ++++ dpdk/lib/librte_eal/common/eal_common_options.c +@@ -95,6 +95,8 @@ eal_long_options[] = { + {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM }, + {OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM }, + {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM }, ++ {OPT_VHOST_OWNER, 1, NULL, OPT_VHOST_OWNER_NUM }, ++ {OPT_VHOST_PERM, 1, NULL, OPT_VHOST_PERM_NUM }, + {0, 0, NULL, 0 } + }; + +@@ -153,6 +155,8 @@ eal_reset_internal_config(struct interna + #endif + internal_cfg->vmware_tsc_map = 0; + internal_cfg->create_uio_dev = 0; ++ internal_cfg->vhost_sock_owner = NULL; ++ internal_cfg->vhost_sock_perm = NULL; + } + + static int +Index: dpdk/lib/librte_eal/common/eal_internal_cfg.h +=================================================================== +--- dpdk.orig/lib/librte_eal/common/eal_internal_cfg.h ++++ dpdk/lib/librte_eal/common/eal_internal_cfg.h +@@ -83,6 +83,8 @@ struct internal_config { + volatile enum rte_intr_mode vfio_intr_mode; + const char *hugefile_prefix; /**< the base filename of hugetlbfs files */ + const char *hugepage_dir; /**< specific hugetlbfs directory to use */ ++ const char *vhost_sock_owner; /**< owner:group of vhost_user sockets */ ++ const char *vhost_sock_perm; /**< permissions of vhost_user sockets */ + + unsigned num_hugepage_sizes; /**< how many sizes on this system */ + struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES]; +Index: dpdk/lib/librte_eal/common/eal_options.h +=================================================================== +--- dpdk.orig/lib/librte_eal/common/eal_options.h ++++ dpdk/lib/librte_eal/common/eal_options.h +@@ -83,6 +83,10 @@ enum { + OPT_VMWARE_TSC_MAP_NUM, + #define OPT_XEN_DOM0 "xen-dom0" + OPT_XEN_DOM0_NUM, ++#define OPT_VHOST_OWNER "vhost-owner" ++ OPT_VHOST_OWNER_NUM, ++#define OPT_VHOST_PERM "vhost-perm" ++ OPT_VHOST_PERM_NUM, + OPT_LONG_MAX_NUM + }; + +Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c +=================================================================== +--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c ++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c +@@ -51,6 +51,8 @@ + #include "vhost-net.h" + #include "virtio-net-user.h" + ++#include ++ + #define MAX_VIRTIO_BACKLOG 128 + + static void vserver_new_vq_conn(int fd, void *data, int *remove); +@@ -482,6 +484,8 @@ rte_vhost_driver_register(const char *pa + return -1; + } + ++ rte_eal_set_socket_permissions(path); ++ + vserver->path = strdup(path); + vserver->fh = -1; + +Index: dpdk/lib/librte_eal/linuxapp/eal/eal.c +=================================================================== +--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal.c ++++ dpdk/lib/librte_eal/linuxapp/eal/eal.c +@@ -53,6 +53,9 @@ + #if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) + #include + #endif ++#include ++#include ++#include + + #include + #include +@@ -343,6 +346,8 @@ eal_usage(const char *prgname) + " --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n" + " --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n" + " --"OPT_XEN_DOM0" Support running on Xen dom0 without hugetlbfs\n" ++ " --"OPT_VHOST_OWNER" Create vhost-user sockets with this owner:group\n" ++ " --"OPT_VHOST_PERM" Create vhost-user sockets with these permissions\n" + "\n"); + /* Allow the application to print its usage message too if hook is set */ + if ( rte_application_usage_hook ) { +@@ -618,6 +623,14 @@ eal_parse_args(int argc, char **argv) + internal_config.create_uio_dev = 1; + break; + ++ case OPT_VHOST_OWNER_NUM: ++ internal_config.vhost_sock_owner = optarg; ++ break; ++ ++ case OPT_VHOST_PERM_NUM: ++ internal_config.vhost_sock_perm = optarg; ++ break; ++ + default: + if (opt < OPT_LONG_MIN_NUM && isprint(opt)) { + RTE_LOG(ERR, EAL, "Option %c is not supported " +@@ -932,3 +945,172 @@ rte_eal_check_module(const char *module_ + /* Module has been found */ + return 1; + } ++ ++/* Try to double the size of '*buf', return true ++ * if successful, and '*sizep' will be updated with ++ * the new size. Otherwise, return false. */ ++static int ++enlarge_buffer(char **buf, size_t *sizep) ++{ ++ size_t newsize = *sizep * 2; ++ ++ if (newsize > *sizep) { ++ *buf = realloc(*buf, newsize); ++ *sizep = newsize; ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static int ++get_owners_from_str(const char *user_spec, uid_t *uid, gid_t *gid) ++{ ++ size_t bufsize = 4096; ++ ++ char *pos = strchr(user_spec, ':'); ++ user_spec += strspn(user_spec, " \t\r\n"); ++ size_t len = pos ? (size_t)(pos - user_spec) : strlen(user_spec); ++ ++ char *buf = NULL; ++ struct passwd pwd, *res; ++ int e; ++ ++ buf = malloc(bufsize); ++ char *user_search = NULL; ++ if (len) { ++ user_search = malloc(len + 1); ++ memcpy(user_search, user_spec, len); ++ user_search[len] = '\0'; ++ while ((e = getpwnam_r(user_search, &pwd, buf, bufsize, &res)) == ERANGE) { ++ if (!enlarge_buffer(&buf, &bufsize)) { ++ break; ++ } ++ } ++ ++ if (e != 0) { ++ RTE_LOG(ERR, EAL,"Failed to retrive user %s's uid (%s), aborting.", ++ user_search, strerror(e)); ++ goto release; ++ } ++ if (res == NULL) { ++ RTE_LOG(ERR, EAL,"user %s not found, aborting.", ++ user_search); ++ e = -1; ++ goto release; ++ } ++ } else { ++ /* User name is not specified, use current user. */ ++ while ((e = getpwuid_r(getuid(), &pwd, buf, bufsize, &res)) == ERANGE) { ++ if (!enlarge_buffer(&buf, &bufsize)) { ++ break; ++ } ++ } ++ ++ if (e != 0) { ++ RTE_LOG(ERR, EAL,"Failed to retrive current user's uid " ++ "(%s), aborting.", strerror(e)); ++ goto release; ++ } ++ user_search = strdup(pwd.pw_name); ++ } ++ ++ if (uid) ++ *uid = pwd.pw_uid; ++ ++ free(buf); ++ buf = NULL; ++ ++ if (pos) { ++ char *grpstr = pos + 1; ++ grpstr += strspn(grpstr, " \t\r\n"); ++ ++ if (*grpstr) { ++ struct group grp, *res; ++ ++ bufsize = 4096; ++ buf = malloc(bufsize); ++ while ((e = getgrnam_r(grpstr, &grp, buf, bufsize, &res)) ++ == ERANGE) { ++ if (!enlarge_buffer(&buf, &bufsize)) { ++ break; ++ } ++ } ++ ++ if (e) { ++ RTE_LOG(ERR, EAL,"Failed to get group entry for %s, " ++ "(%s), aborting.", grpstr, ++ strerror(e)); ++ goto release; ++ } ++ if (res == NULL) { ++ RTE_LOG(ERR, EAL,"Group %s not found, aborting.", ++ grpstr); ++ e = -1; ++ goto release; ++ } ++ ++ if (gid) ++ *gid = grp.gr_gid; ++ } ++ } ++ ++ release: ++ free(buf); ++ free(user_search); ++ return e; ++} ++ ++static void ++vhost_set_permissions(const char *vhost_sock_location) ++{ ++ unsigned long int mode = strtoul(internal_config.vhost_sock_perm, NULL, 0); ++ int err = chmod(vhost_sock_location, (mode_t)mode); ++ if (err) { ++ RTE_LOG(ERR, EAL,"vhost-user socket cannot set" ++ " permissions to %s (%s).\n", ++ internal_config.vhost_sock_perm, strerror(err)); ++ return; ++ } ++ RTE_LOG(INFO, EAL,"Socket %s changed permissions" ++ " to %s\n", vhost_sock_location, ++ internal_config.vhost_sock_perm); ++} ++ ++static void ++vhost_set_ownership(const char *vhost_sock_location) ++{ ++ uid_t vhuid=0; ++ gid_t vhgid=0; ++ ++ if (get_owners_from_str(internal_config.vhost_sock_owner, &vhuid, &vhgid)) { ++ RTE_LOG(ERR, EAL,"vhost-user socket unable to get" ++ " specified user/group: %s\n", ++ internal_config.vhost_sock_owner); ++ return; ++ } ++ ++ int err = chown(vhost_sock_location, vhuid, vhgid); ++ if (err) { ++ RTE_LOG(ERR, EAL,"vhost-user socket unable to set" ++ " ownership to %s (%s).\n", ++ internal_config.vhost_sock_owner, strerror(err)); ++ return; ++ } ++ ++ RTE_LOG(INFO, EAL,"Socket %s changed ownership" ++ " to %s.\n", vhost_sock_location, ++ internal_config.vhost_sock_owner); ++} ++ ++void ++rte_eal_set_socket_permissions(const char *path) ++{ ++ if (internal_config.vhost_sock_perm) { ++ vhost_set_permissions(path); ++ } ++ ++ if (internal_config.vhost_sock_owner) { ++ vhost_set_ownership(path); ++ } ++} +Index: dpdk/lib/librte_eal/common/include/rte_eal.h +=================================================================== +--- dpdk.orig/lib/librte_eal/common/include/rte_eal.h ++++ dpdk/lib/librte_eal/common/include/rte_eal.h +@@ -234,6 +234,11 @@ static inline int rte_gettid(void) + return RTE_PER_LCORE(_thread_id); + } + ++/** ++ * Set owner/permissions on sockets if requested on EAL commandline ++ */ ++void rte_eal_set_socket_permissions(const char *); ++ + #ifdef __cplusplus + } + #endif +Index: dpdk/doc/guides/testpmd_app_ug/run_app.rst +=================================================================== +--- dpdk.orig/doc/guides/testpmd_app_ug/run_app.rst ++++ dpdk/doc/guides/testpmd_app_ug/run_app.rst +@@ -156,6 +156,25 @@ See the DPDK Getting Started Guides for + + Use malloc instead of hugetlbfs. + ++* ``--vhost-owner`` ++ ++ When creating vhost_user sockets change owner and group to the specified value. ++ This can be given as ``user:group``, but also only ``user`` or ``:group`` are supported. ++ ++ Examples:: ++ ++ --vhost-owner 'libvirt-qemu:kvm' ++ --vhost-owner 'libvirt-qemu' ++ --vhost-owner ':kvm' ++ ++* ``--vhost-perm`` ++ ++ When creating vhost_user sockets set them up with these permissions. ++ ++ For example:: ++ ++ --vhost-perm '0664' ++ + + Testpmd Command-line Options + ----------------------------