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 "../../include/linux/lnet/lib-lnet.h" 39 40static int config_on_load; 41module_param(config_on_load, int, 0444); 42MODULE_PARM_DESC(config_on_load, "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 118 mutex_init(&lnet_config_mutex); 119 120 rc = LNetInit(); 121 if (rc != 0) { 122 CERROR("LNetInit: error %d\n", rc); 123 return rc; 124 } 125 126 rc = libcfs_register_ioctl(&lnet_ioctl_handler); 127 LASSERT(rc == 0); 128 129 if (config_on_load) { 130 /* Have to schedule a separate thread to avoid deadlocking 131 * in modload */ 132 (void) kthread_run(lnet_configure, NULL, "lnet_initd"); 133 } 134 135 return 0; 136} 137 138void 139fini_lnet(void) 140{ 141 int rc; 142 143 rc = libcfs_deregister_ioctl(&lnet_ioctl_handler); 144 LASSERT(rc == 0); 145 146 LNetFini(); 147} 148 149MODULE_AUTHOR("Peter J. Braam <braam@clusterfs.com>"); 150MODULE_DESCRIPTION("Portals v3.1"); 151MODULE_LICENSE("GPL"); 152MODULE_VERSION("1.0.0"); 153 154module_init(init_lnet); 155module_exit(fini_lnet); 156