⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 linux-tcpip.c

📁 非常经典的一个分布式系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- * vim:expandtab:shiftwidth=8:tabstop=8: * * Copyright (C) 2005 Cluster File Systems, Inc. * *   This file is part of Lustre, http://www.lustre.org. * *   Lustre is free software; you can redistribute it and/or *   modify it under the terms of version 2 of the GNU General Public *   License as published by the Free Software Foundation. * *   Lustre is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with Lustre; if not, write to the Free Software *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#define DEBUG_SUBSYSTEM S_LNET#include <libcfs/kp30.h>#include <libcfs/libcfs.h>#include <linux/if.h>#include <linux/in.h>#include <linux/file.h>/* For sys_open & sys_close */#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)#include <linux/syscalls.h>#else#include <linux/fs.h>#endifintlibcfs_sock_ioctl(int cmd, unsigned long arg){        mm_segment_t   oldmm = get_fs();        struct socket  *sock;        int             fd;        int             rc;        struct file     *sock_filp;        rc = sock_create (PF_INET, SOCK_STREAM, 0, &sock);        if (rc != 0) {                CERROR ("Can't create socket: %d\n", rc);                return rc;        }        fd = sock_map_fd(sock);        if (fd < 0) {                rc = fd;                sock_release(sock);                goto out;        }        sock_filp = fget(fd);        if (!sock_filp) {                rc = -ENOMEM;                goto out_fd;        }        set_fs(KERNEL_DS);#ifdef HAVE_UNLOCKED_IOCTL        if (sock_filp->f_op->unlocked_ioctl)                rc = sock_filp->f_op->unlocked_ioctl(sock_filp, cmd, arg);        else#endif             {                lock_kernel();                rc =sock_filp->f_op->ioctl(sock_filp->f_dentry->d_inode,                                           sock_filp, cmd, arg);                unlock_kernel();             }        set_fs(oldmm);        fput(sock_filp); out_fd:        sys_close(fd); out:        return rc;}intlibcfs_ipif_query (char *name, int *up, __u32 *ip, __u32 *mask){        struct ifreq   ifr;        int            nob;        int            rc;        __u32          val;        nob = strnlen(name, IFNAMSIZ);        if (nob == IFNAMSIZ) {                CERROR("Interface name %s too long\n", name);                return -EINVAL;        }        CLASSERT (sizeof(ifr.ifr_name) >= IFNAMSIZ);        strcpy(ifr.ifr_name, name);        rc = libcfs_sock_ioctl(SIOCGIFFLAGS, (unsigned long)&ifr);        if (rc != 0) {                CERROR("Can't get flags for interface %s\n", name);                return rc;        }        if ((ifr.ifr_flags & IFF_UP) == 0) {                CDEBUG(D_NET, "Interface %s down\n", name);                *up = 0;                *ip = *mask = 0;                return 0;        }        *up = 1;        strcpy(ifr.ifr_name, name);        ifr.ifr_addr.sa_family = AF_INET;        rc = libcfs_sock_ioctl(SIOCGIFADDR, (unsigned long)&ifr);        if (rc != 0) {                CERROR("Can't get IP address for interface %s\n", name);                return rc;        }        val = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;        *ip = ntohl(val);        strcpy(ifr.ifr_name, name);        ifr.ifr_addr.sa_family = AF_INET;        rc = libcfs_sock_ioctl(SIOCGIFNETMASK, (unsigned long)&ifr);        if (rc != 0) {                CERROR("Can't get netmask for interface %s\n", name);                return rc;        }        val = ((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr.s_addr;        *mask = ntohl(val);        return 0;}EXPORT_SYMBOL(libcfs_ipif_query);intlibcfs_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;        nalloc = 16;        /* first guess at max interfaces */        toobig = 0;        for (;;) {                if (nalloc * sizeof(*ifr) > CFS_PAGE_SIZE) {                        toobig = 1;                        nalloc = CFS_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 = libcfs_sock_ioctl(SIOCGIFCONF, (unsigned long)&ifc);                if (rc < 0) {                        CERROR ("Error %d enumerating interfaces\n", rc);                        goto out1;                }                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;        }        if (nfound == 0)                goto out1;        LIBCFS_ALLOC(names, nfound * sizeof(*names));        if (names == NULL) {                rc = -ENOMEM;                goto out1;        }        /* NULL out all names[i] */        memset (names, 0, nfound * sizeof(*names));        for (i = 0; i < nfound; i++) {                nob = strnlen (ifr[i].ifr_name, IFNAMSIZ);                if (nob == IFNAMSIZ) {                        /* no space for terminating NULL */                        CERROR("interface name %.*s too long (%d max)\n",                               nob, ifr[i].ifr_name, IFNAMSIZ);                        rc = -ENAMETOOLONG;                        goto out2;                }                LIBCFS_ALLOC(names[i], IFNAMSIZ);                if (names[i] == NULL) {                        rc = -ENOMEM;                        goto out2;                }                memcpy(names[i], ifr[i].ifr_name, nob);                names[i][nob] = 0;        }        *namesp = names;        rc = nfound; out2:        if (rc < 0)                libcfs_ipif_free_enumeration(names, nfound); out1:        LIBCFS_FREE(ifr, nalloc * sizeof(*ifr)); out0:        return rc;}EXPORT_SYMBOL(libcfs_ipif_enumerate);voidlibcfs_ipif_free_enumeration (char **names, int n){        int      i;        LASSERT (n > 0);        for (i = 0; i < n && names[i] != NULL; i++)                LIBCFS_FREE(names[i], IFNAMSIZ);        LIBCFS_FREE(names, n * sizeof(*names));}EXPORT_SYMBOL(libcfs_ipif_free_enumeration);intlibcfs_sock_write (struct socket *sock, void *buffer, int nob, int timeout){        int            rc;        mm_segment_t   oldmm = get_fs();        long           ticks = timeout * HZ;        unsigned long  then;        struct timeval tv;        LASSERT (nob > 0);        /* Caller may pass a zero timeout if she thinks the socket buffer is         * empty enough to take the whole message immediately */        for (;;) {                struct iovec  iov = {                        .iov_base = buffer,                        .iov_len  = nob                };                struct msghdr msg = {                        .msg_name       = NULL,                        .msg_namelen    = 0,                        .msg_iov        = &iov,                        .msg_iovlen     = 1,                        .msg_control    = NULL,                        .msg_controllen = 0,                        .msg_flags      = (timeout == 0) ? MSG_DONTWAIT : 0                };                if (timeout != 0) {                        /* Set send timeout to remaining time */                        tv = (struct timeval) {                                .tv_sec = ticks / HZ,                                .tv_usec = ((ticks % HZ) * 1000000) / HZ                        };                        set_fs(KERNEL_DS);                        rc = sock_setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO,                                             (char *)&tv, sizeof(tv));                        set_fs(oldmm);                        if (rc != 0) {                                CERROR("Can't set socket send timeout "                                       "%ld.%06d: %d\n",                                       (long)tv.tv_sec, (int)tv.tv_usec, rc);                                return rc;                        }                }                set_fs (KERNEL_DS);                then = jiffies;                rc = sock_sendmsg (sock, &msg, iov.iov_len);                ticks -= jiffies - then;                set_fs (oldmm);                if (rc == nob)                        return 0;                if (rc < 0)                        return rc;                if (rc == 0) {                        CERROR ("Unexpected zero rc\n");                        return (-ECONNABORTED);                }                if (ticks <= 0)                        return -EAGAIN;                buffer = ((char *)buffer) + rc;                nob -= rc;        }        return (0);}EXPORT_SYMBOL(libcfs_sock_write);intlibcfs_sock_read (struct socket *sock, void *buffer, int nob, int timeout){        int            rc;        mm_segment_t   oldmm = get_fs();        long           ticks = timeout * HZ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -