+module_param(config_on_load, int, 0444);
+MODULE_PARM_DESC(config_on_load, "configure network at module load");
+
+static DEFINE_MUTEX(lnet_config_mutex);
+
+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;
+}
+
+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;
+}
+
+static int
+lnet_dyn_unconfigure_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_del_net(conf->cfg_net);
+ else
+ rc = -EINVAL;
+ mutex_unlock(&lnet_config_mutex);
+
+ return rc;
+}
+
+static int
+lnet_dyn_configure_ni(struct libcfs_ioctl_hdr *hdr)
+{
+ struct lnet_ioctl_config_ni *conf =
+ (struct lnet_ioctl_config_ni *)hdr;
+ int rc = -EINVAL;
+
+ if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf))
+ return rc;
+
+ mutex_lock(&lnet_config_mutex);
+ if (the_lnet.ln_niinit_self) {
+ struct lnet_ioctl_config_lnd_tunables *tun = NULL;
+ struct lnet_nid nid;
+ u32 net_id;
+
+ /* get the tunables if they are available */
+ if (conf->lic_cfg_hdr.ioc_len >=
+ sizeof(*conf) + sizeof(*tun))
+ tun = (struct lnet_ioctl_config_lnd_tunables *) conf->lic_bulk;
+
+ lnet_nid4_to_nid(conf->lic_nid, &nid);
+ net_id = LNET_NID_NET(&nid);
+ rc = lnet_dyn_add_ni(conf, net_id, &LNET_ANY_NID, tun);
+ }
+ mutex_unlock(&lnet_config_mutex);
+
+ return rc;
+}
+
+static int
+lnet_dyn_unconfigure_ni(struct libcfs_ioctl_hdr *hdr)
+{
+ struct lnet_ioctl_config_ni *conf =
+ (struct lnet_ioctl_config_ni *) hdr;
+ struct lnet_nid nid;
+ int rc = -EINVAL;
+
+ if (conf->lic_cfg_hdr.ioc_len < sizeof(*conf) ||
+ !the_lnet.ln_niinit_self)
+ return rc;