summaryrefslogtreecommitdiffstats
path: root/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
diff options
context:
space:
mode:
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>2016-06-15 20:29:06 +0200
committerChristian Ehrhardt <christian.ehrhardt@canonical.com>2016-06-15 20:37:12 +0200
commit199e427d5dea3051eec1726eb9c857aa3d5fdde2 (patch)
tree5477b3bd4868676a210bbd3ef67a469d34814e61 /debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
parentb5cdd645c9fc62341d55aebbfc93a1b648415512 (diff)
Merge Ubuntu DPDK packaging as of 15th June 2016
As discussed this shall be our initial baseline. If history is needed for any sort of debugging or analysis it can be found at https://code.launchpad.net/~ubuntu-server/dpdk/+git/dpdk Change-Id: Ie95c7effbbea34d723df14f6451c1f782000cbc1 Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Diffstat (limited to 'debian/patches/ubuntu-fix-vhost-user-socket-permission.patch')
-rw-r--r--debian/patches/ubuntu-fix-vhost-user-socket-permission.patch372
1 files changed, 372 insertions, 0 deletions
diff --git a/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
new file mode 100644
index 00000000..c2a9cdbf
--- /dev/null
+++ b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
@@ -0,0 +1,372 @@
+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
+
+*Update*
+ - with the split libs it now nees to be listed in
+ lib/librte_eal/linuxapp/eal/rte_eal_version.map to work on link steps
+ - please note that upstream gravitates towards not extending but creating a
+ new the API in DPDK as long term solution (will take a while)
+ - also as listed before most affected projects seem to create their own
+ workaround.
+ So over time we have to check when we can drop it at the price of a config
+ transition - likely OVS 2.6 won't need it anymore.
+
+Forwarded: yes
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-18
+
+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 <rte_eal.h>
++
+ #define MAX_VIRTIO_BACKLOG 128
+
+ static void vserver_new_vq_conn(int fd, void *data, int *remove);
+@@ -486,6 +488,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)
+ #include <sys/io.h>
+ #endif
++#include <sys/types.h>
++#include <pwd.h>
++#include <grp.h>
+
+ #include <rte_common.h>
+ #include <rte_debug.h>
+@@ -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 "
+@@ -934,3 +947,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
+@@ -252,6 +252,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
+ ----------------------------
+Index: dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/rte_eal_version.map
++++ dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+@@ -138,6 +138,7 @@ DPDK_2.2 {
+ rte_keepalive_mark_alive;
+ rte_keepalive_register_core;
+ rte_xen_dom0_supported;
++ rte_eal_set_socket_permissions;
+
+ } DPDK_2.1;
+