From: Alexander Boyko Date: Mon, 7 May 2018 13:56:51 +0000 (-0400) Subject: LU-6399 lnet: socket cleanup X-Git-Tag: 2.11.53~94 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=e37335b2d8c2dc74badea8978ab3f46a63621265;hp=4813eee9b06f6ceb4f39cce42d904ec1516a824a LU-6399 lnet: socket cleanup The ioctl request was designed to get all needed information through socket from usermode. But the same patterns with tricks was used at kernel by lib-socket.. The patch changes this behavior from socket to kernel socket. For libcfs_sock_ioctl tricks with usermode call removed, kernel_sock_ioctl is used instead. But this call handle SIOCGIFADDR and SIOCGIFNETMASK. For SIOCGIFFLAGS we take device flag directly. Function libcfs_ipif_enumerate() which are used SIOCGIFCONF command totally rewriten to get device names without ioctl requests. Signed-off-by: Alexander Boyko Change-Id: Idf0da800a49dbefa419fc5fecaa9ee1bd4d85327 Reviewed-on: https://review.whamcloud.com/14179 Tested-by: Jenkins Reviewed-by: James Simmons Tested-by: Maloo Reviewed-by: Doug Oucharek Reviewed-by: Oleg Drokin --- diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index ba6a0dd..4774cac 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -239,30 +239,6 @@ i_uid_read, [ ]) # LIBCFS_I_UID_READ # -# LIBCFS_SOCK_ALLOC_FILE -# -# FC18 3.7.2-201 unexport sock_map_fd() change to -# use sock_alloc_file(). -# upstream commit 56b31d1c9f1e6a3ad92e7bfe252721e05d92b285 -# -AC_DEFUN([LIBCFS_SOCK_ALLOC_FILE], [ -LB_CHECK_EXPORT([sock_alloc_file], [net/socket.c], [ - LB_CHECK_COMPILE([if 'sock_alloc_file' takes 3 arguments], - sock_alloc_file_3args, [ - #include - ],[ - sock_alloc_file(NULL, 0, NULL); - ],[ - AC_DEFINE(HAVE_SOCK_ALLOC_FILE_3ARGS, 1, - [sock_alloc_file takes 3 arguments]) - ],[ - AC_DEFINE(HAVE_SOCK_ALLOC_FILE, 1, - [sock_alloc_file is exported]) - ]) -]) -]) # LIBCFS_SOCK_ALLOC_FILE - -# # LIBCFS_HAVE_CRC32 # AC_DEFUN([LIBCFS_HAVE_CRC32], [ @@ -929,8 +905,6 @@ LIBCFS_REINIT_COMPLETION # 3.5 LIBCFS_PROCESS_NAMESPACE LIBCFS_I_UID_READ -# 3.7 -LIBCFS_SOCK_ALLOC_FILE # 3.8 LIBCFS_HAVE_CRC32 LIBCFS_ENABLE_CRC32_ACCEL diff --git a/lnet/lnet/lib-socket.c b/lnet/lnet/lib-socket.c index 0f1778d..4c081fe 100644 --- a/lnet/lnet/lib-socket.c +++ b/lnet/lnet/lib-socket.c @@ -44,25 +44,10 @@ #include static int -kernel_sock_unlocked_ioctl(struct file *filp, int cmd, unsigned long arg) -{ - mm_segment_t oldfs = get_fs(); - int err; - - set_fs(KERNEL_DS); - err = filp->f_op->unlocked_ioctl(filp, cmd, arg); - set_fs(oldfs); - - return err; -} - -static int lnet_sock_ioctl(int cmd, unsigned long arg) { - struct file *sock_filp; - struct socket *sock; - int fd = -1; - int rc; + struct socket *sock; + int rc; #ifdef HAVE_SOCK_CREATE_KERN_USE_NET rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock); @@ -74,33 +59,24 @@ lnet_sock_ioctl(int cmd, unsigned long arg) return rc; } -#if !defined(HAVE_SOCK_ALLOC_FILE) && !defined(HAVE_SOCK_ALLOC_FILE_3ARGS) - fd = sock_map_fd(sock, 0); - if (fd < 0) { - rc = fd; - sock_release(sock); - goto out; - } - sock_filp = fget(fd); -#else -# ifdef HAVE_SOCK_ALLOC_FILE_3ARGS - sock_filp = sock_alloc_file(sock, 0, NULL); -# else - sock_filp = sock_alloc_file(sock, 0); -# endif -#endif - if (IS_ERR(sock_filp)) { - rc = PTR_ERR(sock_filp); - sock_release(sock); - goto out; + if (cmd == SIOCGIFFLAGS) { + /* This cmd is used only to get IFF_UP flag */ + struct ifreq *ifr = (struct ifreq *) arg; + struct net_device *dev; + + dev = dev_get_by_name(sock_net(sock->sk), ifr->ifr_name); + if (dev) { + ifr->ifr_flags = dev->flags; + dev_put(dev); + rc = 0; + } else { + rc = -ENODEV; + } + } else { + rc = kernel_sock_ioctl(sock, cmd, arg); } + sock_release(sock); - rc = kernel_sock_unlocked_ioctl(sock_filp, cmd, arg); - - fput(sock_filp); -out: - if (fd >= 0) - sys_close(fd); return rc; } @@ -189,93 +165,73 @@ int lnet_ipif_enumerate(char ***namesp) { /* Allocate and fill in 'names', returning # interfaces/error */ - char **names; - int toobig; - int nalloc; - int nfound; - struct ifreq *ifr; - struct ifconf ifc; - int rc; - int nob; - int i; + struct net_device *dev; + struct socket *sock; + char **names; + int toobig; + int nalloc; + int nfound; + int rc; + int nob; + int i; nalloc = 16; /* first guess at max interfaces */ toobig = 0; - for (;;) { - if (nalloc * sizeof(*ifr) > PAGE_SIZE) { - toobig = 1; - nalloc = PAGE_SIZE / sizeof(*ifr); - CWARN("Too many interfaces: only enumerating " - "first %d\n", nalloc); - } - - LIBCFS_ALLOC(ifr, nalloc * sizeof(*ifr)); - if (ifr == NULL) { - CERROR("ENOMEM enumerating up to %d interfaces\n", - nalloc); - rc = -ENOMEM; - goto out0; - } - - ifc.ifc_buf = (char *)ifr; - ifc.ifc_len = nalloc * sizeof(*ifr); - - rc = lnet_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc); - if (rc < 0) { - CERROR("Error %d enumerating interfaces\n", rc); - goto out1; - } + nfound = 0; - LASSERT(rc == 0); - - nfound = ifc.ifc_len/sizeof(*ifr); - LASSERT(nfound <= nalloc); - - if (nfound < nalloc || toobig) - break; - - LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); - nalloc *= 2; +#ifdef HAVE_SOCK_CREATE_KERN_USE_NET + rc = sock_create_kern(&init_net, PF_INET, SOCK_STREAM, 0, &sock); +#else + rc = sock_create_kern(PF_INET, SOCK_STREAM, 0, &sock); +#endif + if (rc) { + CERROR("Can't create socket: %d\n", rc); + return rc; } + for_each_netdev(sock_net(sock->sk), dev) + nfound++; + if (nfound == 0) - goto out1; + goto out_release_sock; LIBCFS_ALLOC(names, nfound * sizeof(*names)); if (names == NULL) { rc = -ENOMEM; - goto out1; + goto out_release_sock; } - for (i = 0; i < nfound; i++) { - nob = strnlen(ifr[i].ifr_name, IFNAMSIZ); + i = 0; + for_each_netdev(sock_net(sock->sk), dev) { + nob = strnlen(dev->name, IFNAMSIZ); + CERROR("netdev %s\n", dev->name); if (nob == IFNAMSIZ) { /* no space for terminating NULL */ CERROR("interface name %.*s too long (%d max)\n", - nob, ifr[i].ifr_name, IFNAMSIZ); + nob, dev->name, IFNAMSIZ); rc = -ENAMETOOLONG; - goto out2; + goto out_free_names; } LIBCFS_ALLOC(names[i], IFNAMSIZ); - if (names[i] == NULL) { + if (!names[i]) { rc = -ENOMEM; - goto out2; + goto out_free_names; } - memcpy(names[i], ifr[i].ifr_name, nob); + memcpy(names[i], dev->name, nob); names[i][nob] = 0; + i++; } *namesp = names; - rc = nfound; + rc = i; - out2: +out_free_names: if (rc < 0) lnet_ipif_free_enumeration(names, nfound); - out1: - LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); - out0: +out_release_sock: + sock_release(sock); return rc; } EXPORT_SYMBOL(lnet_ipif_enumerate);