Whamcloud - gitweb
LU-9859 lnet: move ioctl device to lnet 33/50833/10
authorMr NeilBrown <neilb@suse.de>
Tue, 24 Nov 2020 00:42:44 +0000 (11:42 +1100)
committerOleg Drokin <green@whamcloud.com>
Wed, 19 Jul 2023 16:42:58 +0000 (16:42 +0000)
The misc device "/dev/lnet" is currently managed in libcfs code,
despite that fact that it is named "lnet" and almost all ioctl
handlers are in lnet code.

So move the management of the device to lnet code, leaving just
the minimal amount in libcfs:
case IOC_LIBCFS_CLEAR_DEBUG:
case IOC_LIBCFS_MARK_DEBUG:

Also rename various parts of the interface from libcfs_ioctl* to
lnet_ioctl*.
ioctl names, data structures, and include files are left unchanged for
now.

Note that the return value from LNetCtl() was previously passed
through notifier_from_errno() and notifier_to_errno().  This had the
effect of turning any positive value to zero.  We need to preserve
that and not return positive results.  PING would return a positive
result.  lnd->lnd_ctl probably doesn't, but due to the difficulty of
auditing, it is safer to always force the result to non-positive.

Test-Parameters: trivial
Signed-off-by: Mr NeilBrown <neilb@suse.de>
Change-Id: I9cf158f1f9d8b03687d85ba40bd88f1f0ab8e4b8
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/50833
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Chris Horn <chris.horn@hpe.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
libcfs/include/libcfs/libcfs.h
libcfs/include/libcfs/util/ioctl.h
libcfs/libcfs/module.c
libcfs/libcfs/util/l_ioctl.c
lnet/include/lnet/lib-lnet.h
lnet/include/uapi/linux/lnet/libcfs_ioctl.h
lnet/lnet/api-ni.c
lnet/lnet/module.c
lnet/selftest/console.c

index 030ea1b..e12fe6a 100644 (file)
 
 typedef s32 timeout_t;
 
-extern struct blocking_notifier_head libcfs_ioctl_list;
-static inline int notifier_from_ioctl_errno(int err)
-{
-       if (err == -EINVAL)
-               return NOTIFY_OK;
-       return notifier_from_errno(err) | NOTIFY_STOP_MASK;
-}
-
-int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data);
+int libcfs_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data);
 
 extern struct workqueue_struct *cfs_rehash_wq;
 
index a59e2c9..c99fda6 100644 (file)
 #define LIBCFS_IOC_INIT(data)                                  \
 do {                                                           \
        memset(&(data), 0, sizeof(data));                       \
-       (data).ioc_hdr.ioc_version = LIBCFS_IOCTL_VERSION;      \
+       (data).ioc_hdr.ioc_version = LNET_IOCTL_VERSION;        \
        (data).ioc_hdr.ioc_len = sizeof(data);                  \
 } while (0)
 
 #define LIBCFS_IOC_INIT_V2(data, hdr)                  \
 do {                                                   \
        memset(&(data), 0, sizeof(data));               \
-       (data).hdr.ioc_version = LIBCFS_IOCTL_VERSION2; \
+       (data).hdr.ioc_version = LNET_IOCTL_VERSION2;   \
        (data).hdr.ioc_len = sizeof(data);              \
 } while (0)
 
index e764c9f..33bba9c 100644 (file)
@@ -28,7 +28,6 @@
 /*
  * This file is part of Lustre, http://www.lustre.org/
  */
-#include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
@@ -63,152 +62,8 @@ struct lnet_debugfs_symlink_def {
 
 static struct dentry *lnet_debugfs_root;
 
-BLOCKING_NOTIFIER_HEAD(libcfs_ioctl_list);
-EXPORT_SYMBOL(libcfs_ioctl_list);
-
-static inline size_t libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
+int libcfs_ioctl(unsigned int cmd, struct libcfs_ioctl_data *data)
 {
-       size_t len = sizeof(*data);
-
-       len += (data->ioc_inllen1 + 7) & ~7;
-       len += (data->ioc_inllen2 + 7) & ~7;
-       return len;
-}
-
-static bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
-{
-       const int maxlen = 1 << 30;
-       if (data->ioc_hdr.ioc_len > maxlen)
-               return true;
-
-       if (data->ioc_inllen1 > maxlen)
-               return true;
-
-       if (data->ioc_inllen2 > maxlen)
-               return true;
-
-       if (data->ioc_inlbuf1 && !data->ioc_inllen1)
-               return true;
-
-       if (data->ioc_inlbuf2 && !data->ioc_inllen2)
-               return true;
-
-       if (data->ioc_pbuf1 && !data->ioc_plen1)
-               return true;
-
-       if (data->ioc_pbuf2 && !data->ioc_plen2)
-               return true;
-
-       if (data->ioc_plen1 && !data->ioc_pbuf1)
-               return true;
-
-       if (data->ioc_plen2 && !data->ioc_pbuf2)
-               return true;
-
-       if (libcfs_ioctl_packlen(data) != data->ioc_hdr.ioc_len)
-               return true;
-
-       if (data->ioc_inllen1 &&
-               data->ioc_bulk[((data->ioc_inllen1 + 7) & ~7) +
-                              data->ioc_inllen2 - 1] != '\0')
-               return true;
-
-       return false;
-}
-
-int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data)
-{
-       ENTRY;
-
-       if (libcfs_ioctl_is_invalid(data)) {
-               CERROR("libcfs ioctl: parameter not correctly formatted\n");
-               RETURN(-EINVAL);
-       }
-
-       if (data->ioc_inllen1 != 0)
-               data->ioc_inlbuf1 = &data->ioc_bulk[0];
-
-       if (data->ioc_inllen2 != 0)
-               data->ioc_inlbuf2 = &data->ioc_bulk[0] +
-                                   round_up(data->ioc_inllen1, 8);
-
-       RETURN(0);
-}
-
-int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
-                        struct libcfs_ioctl_hdr __user *uhdr)
-{
-       struct libcfs_ioctl_hdr hdr;
-       int err;
-
-       ENTRY;
-       if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
-               RETURN(-EFAULT);
-
-       if (hdr.ioc_version != LIBCFS_IOCTL_VERSION &&
-           hdr.ioc_version != LIBCFS_IOCTL_VERSION2) {
-               CERROR("libcfs ioctl: version mismatch expected %#x, got %#x\n",
-                      LIBCFS_IOCTL_VERSION, hdr.ioc_version);
-               RETURN(-EINVAL);
-       }
-
-       if (hdr.ioc_len < sizeof(struct libcfs_ioctl_hdr)) {
-               CERROR("libcfs ioctl: user buffer too small for ioctl\n");
-               RETURN(-EINVAL);
-       }
-
-       if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) {
-               CERROR("libcfs ioctl: user buffer is too large %d/%d\n",
-                      hdr.ioc_len, LIBCFS_IOC_DATA_MAX);
-               RETURN(-EINVAL);
-       }
-
-       LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len);
-       if (*hdr_pp == NULL)
-               RETURN(-ENOMEM);
-
-       if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len))
-               GOTO(free, err = -EFAULT);
-
-       if ((*hdr_pp)->ioc_version != hdr.ioc_version ||
-               (*hdr_pp)->ioc_len != hdr.ioc_len) {
-               GOTO(free, err = -EINVAL);
-       }
-
-       RETURN(0);
-
-free:
-       LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
-       RETURN(err);
-}
-
-static int libcfs_ioctl(unsigned long cmd, void __user *uparam)
-{
-       struct libcfs_ioctl_data *data = NULL;
-       struct libcfs_ioctl_hdr  *hdr;
-       int                       err;
-       ENTRY;
-
-       /* 'cmd' and permissions get checked in our arch-specific caller */
-       err = libcfs_ioctl_getdata(&hdr, uparam);
-       if (err != 0) {
-               CDEBUG_LIMIT(D_ERROR,
-                            "libcfs ioctl: data header error %d\n", err);
-               RETURN(err);
-       }
-
-       if (hdr->ioc_version == LIBCFS_IOCTL_VERSION) {
-               /* The libcfs_ioctl_data_adjust() function performs adjustment
-                * operations on the libcfs_ioctl_data structure to make
-                * it usable by the code.  This doesn't need to be called
-                * for new data structures added. */
-               data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
-               err = libcfs_ioctl_data_adjust(data);
-               if (err != 0)
-                       GOTO(out, err);
-       }
-
-       CDEBUG(D_IOCTL, "libcfs ioctl cmd %lu\n", cmd);
        switch (cmd) {
        case IOC_LIBCFS_CLEAR_DEBUG:
                libcfs_debug_clear_buffer();
@@ -217,55 +72,17 @@ static int libcfs_ioctl(unsigned long cmd, void __user *uparam)
                if (data == NULL ||
                    data->ioc_inlbuf1 == NULL ||
                    data->ioc_inlbuf1[data->ioc_inllen1 - 1] != '\0')
-                       GOTO(out, err = -EINVAL);
+                       return -EINVAL;
 
                libcfs_debug_mark_buffer(data->ioc_inlbuf1);
                break;
 
        default:
-               err = blocking_notifier_call_chain(&libcfs_ioctl_list,
-                                                  cmd, hdr);
-               if (!(err & NOTIFY_STOP_MASK))
-                       /* No-one claimed the ioctl */
-                       err = -EINVAL;
-               else
-                       err = notifier_to_errno(err);
-               if (copy_to_user(uparam, hdr, hdr->ioc_len) && !err)
-                       err = -EFAULT;
-               break;
-       }
-out:
-       LIBCFS_FREE(hdr, hdr->ioc_len);
-       RETURN(err);
-}
-
-static long
-libcfs_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
-{
-       if (!capable(CAP_SYS_ADMIN))
-               return -EACCES;
-
-       if (_IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
-           _IOC_NR(cmd) < IOC_LIBCFS_MIN_NR  ||
-           _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR) {
-               CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
-                      _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
                return -EINVAL;
        }
-
-       return libcfs_ioctl(cmd, (void __user *)arg);
+       return 0;
 }
-
-static const struct file_operations libcfs_fops = {
-       .owner                  = THIS_MODULE,
-       .unlocked_ioctl         = libcfs_psdev_ioctl,
-};
-
-static struct miscdevice libcfs_dev = {
-       .minor                  = MISC_DYNAMIC_MINOR,
-       .name                   = "lnet",
-       .fops                   = &libcfs_fops,
-};
+EXPORT_SYMBOL(libcfs_ioctl);
 
 static int proc_dobitmasks(struct ctl_table *table, int write,
                           void __user *buffer, size_t *lenp, loff_t *ppos)
@@ -864,24 +681,18 @@ static int __init libcfs_init(void)
        if (rc != 0)
                goto cleanup_debug;
 
-       rc = misc_register(&libcfs_dev);
-       if (rc) {
-               CERROR("misc_register: error %d\n", rc);
-               goto cleanup_cpu;
-       }
-
        cfs_rehash_wq = alloc_workqueue("cfs_rh", WQ_SYSFS, 4);
        if (!cfs_rehash_wq) {
                rc = -ENOMEM;
                CERROR("libcfs: failed to start rehash workqueue: rc = %d\n",
                       rc);
-               goto cleanup_deregister;
+               goto cleanup_cpu;
        }
 
        rc = cfs_crypto_register();
        if (rc) {
                CERROR("cfs_crypto_regster: error %d\n", rc);
-               goto cleanup_deregister;
+               goto cleanup_cpu;
        }
 
        lnet_insert_debugfs(lnet_table, THIS_MODULE, &debugfs_state);
@@ -898,8 +709,6 @@ static int __init libcfs_init(void)
        return 0;
 cleanup_crypto:
        cfs_crypto_unregister();
-cleanup_deregister:
-       misc_deregister(&libcfs_dev);
 cleanup_cpu:
        cfs_cpu_fini();
 cleanup_debug:
@@ -929,8 +738,6 @@ static void __exit libcfs_exit(void)
 
        cfs_crypto_unregister();
 
-       misc_deregister(&libcfs_dev);
-
        cfs_cpu_fini();
 
        /* the below message is checked in test-framework.sh check_mem_leak() */
index 15e3d33..27c3db9 100644 (file)
@@ -139,7 +139,7 @@ int libcfs_ioctl_pack(struct libcfs_ioctl_data *data, char **pbuf, int max)
        struct libcfs_ioctl_data *overlay;
 
        data->ioc_hdr.ioc_len = libcfs_ioctl_packlen(data);
-       data->ioc_hdr.ioc_version = LIBCFS_IOCTL_VERSION;
+       data->ioc_hdr.ioc_version = LNET_IOCTL_VERSION;
 
        if (*pbuf && libcfs_ioctl_packlen(data) > max)
                return 1;
index e4224b0..9e36659 100644 (file)
@@ -649,8 +649,6 @@ struct lnet_ni *lnet_get_next_ni_locked(struct lnet_net *mynet,
 struct lnet_ni *lnet_get_ni_idx_locked(int idx);
 int lnet_get_net_healthv_locked(struct lnet_net *net);
 
-extern int libcfs_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
-                               struct libcfs_ioctl_hdr __user *uparam);
 extern int lnet_get_peer_list(__u32 *countp, __u32 *sizep,
                              struct lnet_process_id __user *ids);
 extern void lnet_peer_ni_set_healthv(lnet_nid_t nid, int value, bool all);
@@ -1308,4 +1306,13 @@ lnet_set_route_aliveness(struct lnet_route *route, bool alive)
                       alive ? "up" : "down");
 }
 void lnet_update_ping_buffer(void);
+
+extern struct blocking_notifier_head lnet_ioctl_list;
+static inline int notifier_from_ioctl_errno(int err)
+{
+       if (err == -EINVAL)
+               return NOTIFY_OK;
+       return notifier_from_errno(err) | NOTIFY_STOP_MASK;
+}
+
 #endif
index 7927cc8..c2eff75 100644 (file)
@@ -46,8 +46,8 @@
 #define __user
 #endif
 
-#define LIBCFS_IOCTL_VERSION 0x0001000a
-#define LIBCFS_IOCTL_VERSION2 0x0001000b
+#define LNET_IOCTL_VERSION 0x0001000a
+#define LNET_IOCTL_VERSION2 0x0001000b
 
 struct libcfs_ioctl_hdr {
        __u32 ioc_len;
@@ -157,6 +157,4 @@ struct libcfs_ioctl_data {
 #define IOC_LIBCFS_SET_PEER               _IOWR(IOC_LIBCFS_TYPE, 112, IOCTL_CONFIG_SIZE)
 #define IOC_LIBCFS_MAX_NR                                        112
 
-extern int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data);
-
 #endif /* __UAPI_LIBCFS_IOCTL_H__ */
index 76dcd73..ae59d5f 100644 (file)
@@ -4542,6 +4542,7 @@ LNetCtl(unsigned int cmd, void *arg)
                if (rc < 0)
                        goto report_ping_err;
                count = rc;
+               rc = 0;
 
                for (i = 0; i < count; i++) {
                        struct lnet_processid *result;
@@ -4703,7 +4704,7 @@ report_ping_err:
                        rc = ni->ni_net->net_lnd->lnd_ctl(ni, cmd, arg);
 
                lnet_ni_decref(ni);
-               return rc;
+               return rc <= 0 ? rc : 0;
        }
        /* not reached */
 }
index 178a954..aac5522 100644 (file)
@@ -31,6 +31,7 @@
 
 #define DEBUG_SUBSYSTEM S_LNET
 
+#include <linux/miscdevice.h>
 #include <lnet/lib-lnet.h>
 #include <uapi/linux/lnet/lnet-dlc.h>
 
@@ -182,10 +183,8 @@ lnet_dyn_unconfigure_ni(struct libcfs_ioctl_hdr *hdr)
 }
 
 static int
-lnet_ioctl(struct notifier_block *nb,
-          unsigned long cmd, void *vdata)
+lnet_ioctl(unsigned int cmd, struct libcfs_ioctl_hdr *hdr)
 {
-       struct libcfs_ioctl_hdr *hdr = vdata;
        int rc;
 
        switch (cmd) {
@@ -233,11 +232,198 @@ lnet_ioctl(struct notifier_block *nb,
                }
                break;
        }
-       return notifier_from_ioctl_errno(rc);
+       return rc;
+}
+BLOCKING_NOTIFIER_HEAD(lnet_ioctl_list);
+EXPORT_SYMBOL(lnet_ioctl_list);
+
+static inline size_t lnet_ioctl_packlen(struct libcfs_ioctl_data *data)
+{
+       size_t len = sizeof(*data);
+
+       len += (data->ioc_inllen1 + 7) & ~7;
+       len += (data->ioc_inllen2 + 7) & ~7;
+       return len;
 }
 
-static struct notifier_block lnet_ioctl_handler = {
-       .notifier_call = lnet_ioctl,
+static bool lnet_ioctl_is_invalid(struct libcfs_ioctl_data *data)
+{
+       const int maxlen = 1 << 30;
+
+       if (data->ioc_hdr.ioc_len > maxlen)
+               return true;
+
+       if (data->ioc_inllen1 > maxlen)
+               return true;
+
+       if (data->ioc_inllen2 > maxlen)
+               return true;
+
+       if (data->ioc_inlbuf1 && !data->ioc_inllen1)
+               return true;
+
+       if (data->ioc_inlbuf2 && !data->ioc_inllen2)
+               return true;
+
+       if (data->ioc_pbuf1 && !data->ioc_plen1)
+               return true;
+
+       if (data->ioc_pbuf2 && !data->ioc_plen2)
+               return true;
+
+       if (data->ioc_plen1 && !data->ioc_pbuf1)
+               return true;
+
+       if (data->ioc_plen2 && !data->ioc_pbuf2)
+               return true;
+
+       if (lnet_ioctl_packlen(data) != data->ioc_hdr.ioc_len)
+               return true;
+
+       if (data->ioc_inllen1 &&
+               data->ioc_bulk[((data->ioc_inllen1 + 7) & ~7) +
+                              data->ioc_inllen2 - 1] != '\0')
+               return true;
+
+       return false;
+}
+
+static int lnet_ioctl_data_adjust(struct libcfs_ioctl_data *data)
+{
+       ENTRY;
+
+       if (lnet_ioctl_is_invalid(data)) {
+               CERROR("lnet ioctl: parameter not correctly formatted\n");
+               RETURN(-EINVAL);
+       }
+
+       if (data->ioc_inllen1 != 0)
+               data->ioc_inlbuf1 = &data->ioc_bulk[0];
+
+       if (data->ioc_inllen2 != 0)
+               data->ioc_inlbuf2 = (&data->ioc_bulk[0] +
+                                    round_up(data->ioc_inllen1, 8));
+
+       RETURN(0);
+}
+
+static int lnet_ioctl_getdata(struct libcfs_ioctl_hdr **hdr_pp,
+                             struct libcfs_ioctl_hdr __user *uhdr)
+{
+       struct libcfs_ioctl_hdr hdr;
+       int err;
+
+       ENTRY;
+       if (copy_from_user(&hdr, uhdr, sizeof(hdr)))
+               RETURN(-EFAULT);
+
+       if (hdr.ioc_version != LNET_IOCTL_VERSION &&
+           hdr.ioc_version != LNET_IOCTL_VERSION2) {
+               CERROR("lnet ioctl: version mismatch expected %#x, got %#x\n",
+                      LNET_IOCTL_VERSION, hdr.ioc_version);
+               RETURN(-EINVAL);
+       }
+
+       if (hdr.ioc_len < sizeof(struct libcfs_ioctl_hdr)) {
+               CERROR("lnet ioctl: user buffer too small for ioctl\n");
+               RETURN(-EINVAL);
+       }
+
+       if (hdr.ioc_len > LIBCFS_IOC_DATA_MAX) {
+               CERROR("lnet ioctl: user buffer is too large %d/%d\n",
+                      hdr.ioc_len, LIBCFS_IOC_DATA_MAX);
+               RETURN(-EINVAL);
+       }
+
+       LIBCFS_ALLOC(*hdr_pp, hdr.ioc_len);
+       if (*hdr_pp == NULL)
+               RETURN(-ENOMEM);
+
+       if (copy_from_user(*hdr_pp, uhdr, hdr.ioc_len))
+               GOTO(free, err = -EFAULT);
+
+       if ((*hdr_pp)->ioc_version != hdr.ioc_version ||
+               (*hdr_pp)->ioc_len != hdr.ioc_len) {
+               GOTO(free, err = -EINVAL);
+       }
+
+       RETURN(0);
+
+free:
+       LIBCFS_FREE(*hdr_pp, hdr.ioc_len);
+       RETURN(err);
+}
+
+static long
+lnet_psdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+       struct libcfs_ioctl_data *data = NULL;
+       struct libcfs_ioctl_hdr  *hdr;
+       int                       err;
+       void __user              *uparam = (void __user *)arg;
+
+       ENTRY;
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       if (_IOC_TYPE(cmd) != IOC_LIBCFS_TYPE ||
+           _IOC_NR(cmd) < IOC_LIBCFS_MIN_NR  ||
+           _IOC_NR(cmd) > IOC_LIBCFS_MAX_NR) {
+               CDEBUG(D_IOCTL, "invalid ioctl ( type %d, nr %d, size %d )\n",
+                      _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
+               return -EINVAL;
+       }
+
+       /* 'cmd' and permissions get checked in our arch-specific caller */
+       err = lnet_ioctl_getdata(&hdr, uparam);
+       if (err != 0) {
+               CDEBUG_LIMIT(D_ERROR,
+                            "lnet ioctl: data header error %d\n", err);
+               RETURN(err);
+       }
+
+       if (hdr->ioc_version == LNET_IOCTL_VERSION) {
+               /* The lnet_ioctl_data_adjust() function performs adjustment
+                * operations on the libcfs_ioctl_data structure to make
+                * it usable by the code.  This doesn't need to be called
+                * for new data structures added.
+                */
+               data = container_of(hdr, struct libcfs_ioctl_data, ioc_hdr);
+               err = lnet_ioctl_data_adjust(data);
+               if (err != 0)
+                       GOTO(out, err);
+       }
+
+       CDEBUG(D_IOCTL, "lnet ioctl cmd %u\n", cmd);
+
+       err = libcfs_ioctl(cmd, data);
+       if (err == -EINVAL)
+               err = lnet_ioctl(cmd, hdr);
+       if (err == -EINVAL) {
+               err = blocking_notifier_call_chain(&lnet_ioctl_list,
+                                                  cmd, hdr);
+               if (!(err & NOTIFY_STOP_MASK))
+                       /* No-one claimed the ioctl */
+                       err = -EINVAL;
+               else
+                       err = notifier_to_errno(err);
+       }
+       if (copy_to_user(uparam, hdr, hdr->ioc_len) && !err)
+               err = -EFAULT;
+out:
+       LIBCFS_FREE(hdr, hdr->ioc_len);
+       RETURN(err);
+}
+
+static const struct file_operations lnet_fops = {
+       .owner                  = THIS_MODULE,
+       .unlocked_ioctl         = lnet_psdev_ioctl,
+};
+
+static struct miscdevice lnet_dev = {
+       .minor                  = MISC_DYNAMIC_MINOR,
+       .name                   = "lnet",
+       .fops                   = &lnet_fops,
 };
 
 static int __init lnet_init(void)
@@ -247,7 +433,13 @@ static int __init lnet_init(void)
 
        rc = lnet_lib_init();
        if (rc != 0) {
-               CERROR("lnet_lib_init: error %d\n", rc);
+               CERROR("lnet_lib_init: rc = %d\n", rc);
+               RETURN(rc);
+       }
+
+       rc = misc_register(&lnet_dev);
+       if (rc) {
+               CERROR("misc_register: rc = %d\n", rc);
                RETURN(rc);
        }
 
@@ -255,10 +447,6 @@ static int __init lnet_init(void)
            dead_router_check_interval != INT_MIN)
                LCONSOLE_WARN("live_router_check_interval and dead_router_check_interval have been deprecated. Use alive_router_check_interval instead. Ignoring these deprecated parameters.\n");
 
-       rc = blocking_notifier_chain_register(&libcfs_ioctl_list,
-                                             &lnet_ioctl_handler);
-       LASSERT(rc == 0);
-
        if (config_on_load) {
                /* Have to schedule a separate thread to avoid deadlocking
                 * in modload */
@@ -270,11 +458,7 @@ static int __init lnet_init(void)
 
 static void __exit lnet_exit(void)
 {
-       int rc;
-
-       rc = blocking_notifier_chain_unregister(&libcfs_ioctl_list,
-                                               &lnet_ioctl_handler);
-       LASSERT(rc == 0);
+       misc_deregister(&lnet_dev);
 
        lnet_router_exit();
        lnet_lib_exit();
index 583536a..50ee1dd 100644 (file)
@@ -1997,7 +1997,7 @@ lstcon_console_init(void)
        if (rc < 0)
                goto out;
 
-       rc = blocking_notifier_chain_register(&libcfs_ioctl_list,
+       rc = blocking_notifier_chain_register(&lnet_ioctl_list,
                                              &lstcon_ioctl_handler);
        if (rc < 0) {
                lstcon_fini_netlink();
@@ -2023,7 +2023,7 @@ lstcon_console_fini(void)
 {
        int i;
 
-       blocking_notifier_chain_unregister(&libcfs_ioctl_list,
+       blocking_notifier_chain_unregister(&lnet_ioctl_list,
                                           &lstcon_ioctl_handler);
        lstcon_fini_netlink();