linux/drivers/staging/lustre/lnet/lnet/module.c
<<
>>
Prefs
   1/*
   2 * GPL HEADER START
   3 *
   4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License version 2 only,
   8 * as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope that it will be useful, but
  11 * WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 * General Public License version 2 for more details (a copy is included
  14 * in the LICENSE file that accompanied this code).
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * version 2 along with this program; If not, see
  18 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
  19 *
  20 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  21 * CA 95054 USA or visit www.sun.com if you need additional information or
  22 * have any questions.
  23 *
  24 * GPL HEADER END
  25 */
  26/*
  27 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  28 * Use is subject to license terms.
  29 *
  30 * Copyright (c) 2012, Intel Corporation.
  31 */
  32/*
  33 * This file is part of Lustre, http://www.lustre.org/
  34 * Lustre is a trademark of Sun Microsystems, Inc.
  35 */
  36
  37#define DEBUG_SUBSYSTEM S_LNET
  38#include <linux/lnet/lib-lnet.h>
  39
  40static int config_on_load = 0;
  41CFS_MODULE_PARM(config_on_load, "i", int, 0444,
  42                "configure network at module load");
  43
  44static struct mutex lnet_config_mutex;
  45
  46int
  47lnet_configure (void *arg)
  48{
  49        /* 'arg' only there so I can be passed to cfs_create_thread() */
  50        int    rc = 0;
  51
  52        LNET_MUTEX_LOCK(&lnet_config_mutex);
  53
  54        if (!the_lnet.ln_niinit_self) {
  55                rc = LNetNIInit(LUSTRE_SRV_LNET_PID);
  56                if (rc >= 0) {
  57                        the_lnet.ln_niinit_self = 1;
  58                        rc = 0;
  59                }
  60        }
  61
  62        LNET_MUTEX_UNLOCK(&lnet_config_mutex);
  63        return rc;
  64}
  65
  66int
  67lnet_unconfigure (void)
  68{
  69        int   refcount;
  70
  71        LNET_MUTEX_LOCK(&lnet_config_mutex);
  72
  73        if (the_lnet.ln_niinit_self) {
  74                the_lnet.ln_niinit_self = 0;
  75                LNetNIFini();
  76        }
  77
  78        LNET_MUTEX_LOCK(&the_lnet.ln_api_mutex);
  79        refcount = the_lnet.ln_refcount;
  80        LNET_MUTEX_UNLOCK(&the_lnet.ln_api_mutex);
  81
  82        LNET_MUTEX_UNLOCK(&lnet_config_mutex);
  83        return (refcount == 0) ? 0 : -EBUSY;
  84}
  85
  86int
  87lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
  88{
  89        int   rc;
  90
  91        switch (cmd) {
  92        case IOC_LIBCFS_CONFIGURE:
  93                return lnet_configure(NULL);
  94
  95        case IOC_LIBCFS_UNCONFIGURE:
  96                return lnet_unconfigure();
  97
  98        default:
  99                /* Passing LNET_PID_ANY only gives me a ref if the net is up
 100                 * already; I'll need it to ensure the net can't go down while
 101                 * I'm called into it */
 102                rc = LNetNIInit(LNET_PID_ANY);
 103                if (rc >= 0) {
 104                        rc = LNetCtl(cmd, data);
 105                        LNetNIFini();
 106                }
 107                return rc;
 108        }
 109}
 110
 111DECLARE_IOCTL_HANDLER(lnet_ioctl_handler, lnet_ioctl);
 112
 113int
 114init_lnet(void)
 115{
 116        int               rc;
 117        ENTRY;
 118
 119        mutex_init(&lnet_config_mutex);
 120
 121        rc = LNetInit();
 122        if (rc != 0) {
 123                CERROR("LNetInit: error %d\n", rc);
 124                RETURN(rc);
 125        }
 126
 127        rc = libcfs_register_ioctl(&lnet_ioctl_handler);
 128        LASSERT (rc == 0);
 129
 130        if (config_on_load) {
 131                /* Have to schedule a separate thread to avoid deadlocking
 132                 * in modload */
 133                (void) kthread_run(lnet_configure, NULL, "lnet_initd");
 134        }
 135
 136        RETURN(0);
 137}
 138
 139void
 140fini_lnet(void)
 141{
 142        int rc;
 143
 144        rc = libcfs_deregister_ioctl(&lnet_ioctl_handler);
 145        LASSERT (rc == 0);
 146
 147        LNetFini();
 148}
 149
 150MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>");
 151MODULE_DESCRIPTION("Portals v3.1");
 152MODULE_LICENSE("GPL");
 153
 154cfs_module(lnet, "1.0.0", init_lnet, fini_lnet);
 155