+/*
+ * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * Copyright (c) 2012, 2017, Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ * Lustre is a trademark of Sun Microsystems, Inc.
+ */
+
+#define DEBUG_SUBSYSTEM S_LNET
+
+#include <lnet/lib-lnet.h>
+#include <uapi/linux/lnet/lnet-dlc.h>
+
+static int config_on_load = 0;
+module_param(config_on_load, int, 0444);
+MODULE_PARM_DESC(config_on_load, "configure network at module load");
+
+static DEFINE_MUTEX(lnet_config_mutex);
+
+static int
+lnet_configure(void *arg)
+{
+ /* 'arg' only there so I can be passed to cfs_create_thread() */
+ int rc = 0;
+
+ mutex_lock(&lnet_config_mutex);
+
+ if (!the_lnet.ln_niinit_self) {
+ rc = try_module_get(THIS_MODULE);
+
+ if (rc != 1)
+ goto out;
+
+ rc = LNetNIInit(LNET_PID_LUSTRE);
+ if (rc >= 0) {
+ the_lnet.ln_niinit_self = 1;
+ rc = 0;
+ } else {
+ module_put(THIS_MODULE);
+ }
+ }
+
+out:
+ mutex_unlock(&lnet_config_mutex);
+ return rc;
+}
+
+static int
+lnet_unconfigure (void)
+{
+ int refcount;
+
+ mutex_lock(&lnet_config_mutex);
+
+ if (the_lnet.ln_niinit_self) {
+ the_lnet.ln_niinit_self = 0;
+ LNetNIFini();
+ module_put(THIS_MODULE);
+ }
+
+ mutex_lock(&the_lnet.ln_api_mutex);
+ refcount = the_lnet.ln_refcount;
+ mutex_unlock(&the_lnet.ln_api_mutex);
+
+ mutex_unlock(&lnet_config_mutex);
+
+ return (refcount == 0) ? 0 : -EBUSY;
+}
+
+static int
+lnet_dyn_configure_net(struct libcfs_ioctl_hdr *hdr)
+{
+ struct lnet_ioctl_config_data *conf =
+ (struct lnet_ioctl_config_data *)hdr;
+ int rc;
+
+ if (conf->cfg_hdr.ioc_len < sizeof(*conf))
+ return -EINVAL;
+
+ mutex_lock(&lnet_config_mutex);
+ if (the_lnet.ln_niinit_self)
+ rc = lnet_dyn_add_net(conf);
+ else
+ rc = -EINVAL;
+ mutex_unlock(&lnet_config_mutex);
+
+ return rc;
+}