Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * stackglue.c
0004  *
0005  * Code which implements an OCFS2 specific interface to underlying
0006  * cluster stacks.
0007  *
0008  * Copyright (C) 2007, 2009 Oracle.  All rights reserved.
0009  */
0010 
0011 #include <linux/list.h>
0012 #include <linux/spinlock.h>
0013 #include <linux/module.h>
0014 #include <linux/slab.h>
0015 #include <linux/kmod.h>
0016 #include <linux/fs.h>
0017 #include <linux/kobject.h>
0018 #include <linux/sysfs.h>
0019 #include <linux/sysctl.h>
0020 
0021 #include "ocfs2_fs.h"
0022 
0023 #include "stackglue.h"
0024 
0025 #define OCFS2_STACK_PLUGIN_O2CB     "o2cb"
0026 #define OCFS2_STACK_PLUGIN_USER     "user"
0027 #define OCFS2_MAX_HB_CTL_PATH       256
0028 
0029 static struct ocfs2_protocol_version locking_max_version;
0030 static DEFINE_SPINLOCK(ocfs2_stack_lock);
0031 static LIST_HEAD(ocfs2_stack_list);
0032 static char cluster_stack_name[OCFS2_STACK_LABEL_LEN + 1];
0033 static char ocfs2_hb_ctl_path[OCFS2_MAX_HB_CTL_PATH] = "/sbin/ocfs2_hb_ctl";
0034 
0035 /*
0036  * The stack currently in use.  If not null, active_stack->sp_count > 0,
0037  * the module is pinned, and the locking protocol cannot be changed.
0038  */
0039 static struct ocfs2_stack_plugin *active_stack;
0040 
0041 static struct ocfs2_stack_plugin *ocfs2_stack_lookup(const char *name)
0042 {
0043     struct ocfs2_stack_plugin *p;
0044 
0045     assert_spin_locked(&ocfs2_stack_lock);
0046 
0047     list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
0048         if (!strcmp(p->sp_name, name))
0049             return p;
0050     }
0051 
0052     return NULL;
0053 }
0054 
0055 static int ocfs2_stack_driver_request(const char *stack_name,
0056                       const char *plugin_name)
0057 {
0058     int rc;
0059     struct ocfs2_stack_plugin *p;
0060 
0061     spin_lock(&ocfs2_stack_lock);
0062 
0063     /*
0064      * If the stack passed by the filesystem isn't the selected one,
0065      * we can't continue.
0066      */
0067     if (strcmp(stack_name, cluster_stack_name)) {
0068         rc = -EBUSY;
0069         goto out;
0070     }
0071 
0072     if (active_stack) {
0073         /*
0074          * If the active stack isn't the one we want, it cannot
0075          * be selected right now.
0076          */
0077         if (!strcmp(active_stack->sp_name, plugin_name))
0078             rc = 0;
0079         else
0080             rc = -EBUSY;
0081         goto out;
0082     }
0083 
0084     p = ocfs2_stack_lookup(plugin_name);
0085     if (!p || !try_module_get(p->sp_owner)) {
0086         rc = -ENOENT;
0087         goto out;
0088     }
0089 
0090     active_stack = p;
0091     rc = 0;
0092 
0093 out:
0094     /* If we found it, pin it */
0095     if (!rc)
0096         active_stack->sp_count++;
0097 
0098     spin_unlock(&ocfs2_stack_lock);
0099     return rc;
0100 }
0101 
0102 /*
0103  * This function looks up the appropriate stack and makes it active.  If
0104  * there is no stack, it tries to load it.  It will fail if the stack still
0105  * cannot be found.  It will also fail if a different stack is in use.
0106  */
0107 static int ocfs2_stack_driver_get(const char *stack_name)
0108 {
0109     int rc;
0110     char *plugin_name = OCFS2_STACK_PLUGIN_O2CB;
0111 
0112     /*
0113      * Classic stack does not pass in a stack name.  This is
0114      * compatible with older tools as well.
0115      */
0116     if (!stack_name || !*stack_name)
0117         stack_name = OCFS2_STACK_PLUGIN_O2CB;
0118 
0119     if (strlen(stack_name) != OCFS2_STACK_LABEL_LEN) {
0120         printk(KERN_ERR
0121                "ocfs2 passed an invalid cluster stack label: \"%s\"\n",
0122                stack_name);
0123         return -EINVAL;
0124     }
0125 
0126     /* Anything that isn't the classic stack is a user stack */
0127     if (strcmp(stack_name, OCFS2_STACK_PLUGIN_O2CB))
0128         plugin_name = OCFS2_STACK_PLUGIN_USER;
0129 
0130     rc = ocfs2_stack_driver_request(stack_name, plugin_name);
0131     if (rc == -ENOENT) {
0132         request_module("ocfs2_stack_%s", plugin_name);
0133         rc = ocfs2_stack_driver_request(stack_name, plugin_name);
0134     }
0135 
0136     if (rc == -ENOENT) {
0137         printk(KERN_ERR
0138                "ocfs2: Cluster stack driver \"%s\" cannot be found\n",
0139                plugin_name);
0140     } else if (rc == -EBUSY) {
0141         printk(KERN_ERR
0142                "ocfs2: A different cluster stack is in use\n");
0143     }
0144 
0145     return rc;
0146 }
0147 
0148 static void ocfs2_stack_driver_put(void)
0149 {
0150     spin_lock(&ocfs2_stack_lock);
0151     BUG_ON(active_stack == NULL);
0152     BUG_ON(active_stack->sp_count == 0);
0153 
0154     active_stack->sp_count--;
0155     if (!active_stack->sp_count) {
0156         module_put(active_stack->sp_owner);
0157         active_stack = NULL;
0158     }
0159     spin_unlock(&ocfs2_stack_lock);
0160 }
0161 
0162 int ocfs2_stack_glue_register(struct ocfs2_stack_plugin *plugin)
0163 {
0164     int rc;
0165 
0166     spin_lock(&ocfs2_stack_lock);
0167     if (!ocfs2_stack_lookup(plugin->sp_name)) {
0168         plugin->sp_count = 0;
0169         plugin->sp_max_proto = locking_max_version;
0170         list_add(&plugin->sp_list, &ocfs2_stack_list);
0171         printk(KERN_INFO "ocfs2: Registered cluster interface %s\n",
0172                plugin->sp_name);
0173         rc = 0;
0174     } else {
0175         printk(KERN_ERR "ocfs2: Stack \"%s\" already registered\n",
0176                plugin->sp_name);
0177         rc = -EEXIST;
0178     }
0179     spin_unlock(&ocfs2_stack_lock);
0180 
0181     return rc;
0182 }
0183 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_register);
0184 
0185 void ocfs2_stack_glue_unregister(struct ocfs2_stack_plugin *plugin)
0186 {
0187     struct ocfs2_stack_plugin *p;
0188 
0189     spin_lock(&ocfs2_stack_lock);
0190     p = ocfs2_stack_lookup(plugin->sp_name);
0191     if (p) {
0192         BUG_ON(p != plugin);
0193         BUG_ON(plugin == active_stack);
0194         BUG_ON(plugin->sp_count != 0);
0195         list_del_init(&plugin->sp_list);
0196         printk(KERN_INFO "ocfs2: Unregistered cluster interface %s\n",
0197                plugin->sp_name);
0198     } else {
0199         printk(KERN_ERR "Stack \"%s\" is not registered\n",
0200                plugin->sp_name);
0201     }
0202     spin_unlock(&ocfs2_stack_lock);
0203 }
0204 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_unregister);
0205 
0206 void ocfs2_stack_glue_set_max_proto_version(struct ocfs2_protocol_version *max_proto)
0207 {
0208     struct ocfs2_stack_plugin *p;
0209 
0210     spin_lock(&ocfs2_stack_lock);
0211     if (memcmp(max_proto, &locking_max_version,
0212            sizeof(struct ocfs2_protocol_version))) {
0213         BUG_ON(locking_max_version.pv_major != 0);
0214 
0215         locking_max_version = *max_proto;
0216         list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
0217             p->sp_max_proto = locking_max_version;
0218         }
0219     }
0220     spin_unlock(&ocfs2_stack_lock);
0221 }
0222 EXPORT_SYMBOL_GPL(ocfs2_stack_glue_set_max_proto_version);
0223 
0224 
0225 /*
0226  * The ocfs2_dlm_lock() and ocfs2_dlm_unlock() functions take no argument
0227  * for the ast and bast functions.  They will pass the lksb to the ast
0228  * and bast.  The caller can wrap the lksb with their own structure to
0229  * get more information.
0230  */
0231 int ocfs2_dlm_lock(struct ocfs2_cluster_connection *conn,
0232            int mode,
0233            struct ocfs2_dlm_lksb *lksb,
0234            u32 flags,
0235            void *name,
0236            unsigned int namelen)
0237 {
0238     if (!lksb->lksb_conn)
0239         lksb->lksb_conn = conn;
0240     else
0241         BUG_ON(lksb->lksb_conn != conn);
0242     return active_stack->sp_ops->dlm_lock(conn, mode, lksb, flags,
0243                           name, namelen);
0244 }
0245 EXPORT_SYMBOL_GPL(ocfs2_dlm_lock);
0246 
0247 int ocfs2_dlm_unlock(struct ocfs2_cluster_connection *conn,
0248              struct ocfs2_dlm_lksb *lksb,
0249              u32 flags)
0250 {
0251     BUG_ON(lksb->lksb_conn == NULL);
0252 
0253     return active_stack->sp_ops->dlm_unlock(conn, lksb, flags);
0254 }
0255 EXPORT_SYMBOL_GPL(ocfs2_dlm_unlock);
0256 
0257 int ocfs2_dlm_lock_status(struct ocfs2_dlm_lksb *lksb)
0258 {
0259     return active_stack->sp_ops->lock_status(lksb);
0260 }
0261 EXPORT_SYMBOL_GPL(ocfs2_dlm_lock_status);
0262 
0263 int ocfs2_dlm_lvb_valid(struct ocfs2_dlm_lksb *lksb)
0264 {
0265     return active_stack->sp_ops->lvb_valid(lksb);
0266 }
0267 EXPORT_SYMBOL_GPL(ocfs2_dlm_lvb_valid);
0268 
0269 void *ocfs2_dlm_lvb(struct ocfs2_dlm_lksb *lksb)
0270 {
0271     return active_stack->sp_ops->lock_lvb(lksb);
0272 }
0273 EXPORT_SYMBOL_GPL(ocfs2_dlm_lvb);
0274 
0275 void ocfs2_dlm_dump_lksb(struct ocfs2_dlm_lksb *lksb)
0276 {
0277     active_stack->sp_ops->dump_lksb(lksb);
0278 }
0279 EXPORT_SYMBOL_GPL(ocfs2_dlm_dump_lksb);
0280 
0281 int ocfs2_stack_supports_plocks(void)
0282 {
0283     return active_stack && active_stack->sp_ops->plock;
0284 }
0285 EXPORT_SYMBOL_GPL(ocfs2_stack_supports_plocks);
0286 
0287 /*
0288  * ocfs2_plock() can only be safely called if
0289  * ocfs2_stack_supports_plocks() returned true
0290  */
0291 int ocfs2_plock(struct ocfs2_cluster_connection *conn, u64 ino,
0292         struct file *file, int cmd, struct file_lock *fl)
0293 {
0294     WARN_ON_ONCE(active_stack->sp_ops->plock == NULL);
0295     if (active_stack->sp_ops->plock)
0296         return active_stack->sp_ops->plock(conn, ino, file, cmd, fl);
0297     return -EOPNOTSUPP;
0298 }
0299 EXPORT_SYMBOL_GPL(ocfs2_plock);
0300 
0301 int ocfs2_cluster_connect(const char *stack_name,
0302               const char *cluster_name,
0303               int cluster_name_len,
0304               const char *group,
0305               int grouplen,
0306               struct ocfs2_locking_protocol *lproto,
0307               void (*recovery_handler)(int node_num,
0308                            void *recovery_data),
0309               void *recovery_data,
0310               struct ocfs2_cluster_connection **conn)
0311 {
0312     int rc = 0;
0313     struct ocfs2_cluster_connection *new_conn;
0314 
0315     BUG_ON(group == NULL);
0316     BUG_ON(conn == NULL);
0317     BUG_ON(recovery_handler == NULL);
0318 
0319     if (grouplen > GROUP_NAME_MAX) {
0320         rc = -EINVAL;
0321         goto out;
0322     }
0323 
0324     if (memcmp(&lproto->lp_max_version, &locking_max_version,
0325            sizeof(struct ocfs2_protocol_version))) {
0326         rc = -EINVAL;
0327         goto out;
0328     }
0329 
0330     new_conn = kzalloc(sizeof(struct ocfs2_cluster_connection),
0331                GFP_KERNEL);
0332     if (!new_conn) {
0333         rc = -ENOMEM;
0334         goto out;
0335     }
0336 
0337     strlcpy(new_conn->cc_name, group, GROUP_NAME_MAX + 1);
0338     new_conn->cc_namelen = grouplen;
0339     if (cluster_name_len)
0340         strlcpy(new_conn->cc_cluster_name, cluster_name,
0341             CLUSTER_NAME_MAX + 1);
0342     new_conn->cc_cluster_name_len = cluster_name_len;
0343     new_conn->cc_recovery_handler = recovery_handler;
0344     new_conn->cc_recovery_data = recovery_data;
0345 
0346     new_conn->cc_proto = lproto;
0347     /* Start the new connection at our maximum compatibility level */
0348     new_conn->cc_version = lproto->lp_max_version;
0349 
0350     /* This will pin the stack driver if successful */
0351     rc = ocfs2_stack_driver_get(stack_name);
0352     if (rc)
0353         goto out_free;
0354 
0355     rc = active_stack->sp_ops->connect(new_conn);
0356     if (rc) {
0357         ocfs2_stack_driver_put();
0358         goto out_free;
0359     }
0360 
0361     *conn = new_conn;
0362 
0363 out_free:
0364     if (rc)
0365         kfree(new_conn);
0366 
0367 out:
0368     return rc;
0369 }
0370 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect);
0371 
0372 /* The caller will ensure all nodes have the same cluster stack */
0373 int ocfs2_cluster_connect_agnostic(const char *group,
0374                    int grouplen,
0375                    struct ocfs2_locking_protocol *lproto,
0376                    void (*recovery_handler)(int node_num,
0377                                 void *recovery_data),
0378                    void *recovery_data,
0379                    struct ocfs2_cluster_connection **conn)
0380 {
0381     char *stack_name = NULL;
0382 
0383     if (cluster_stack_name[0])
0384         stack_name = cluster_stack_name;
0385     return ocfs2_cluster_connect(stack_name, NULL, 0, group, grouplen,
0386                      lproto, recovery_handler, recovery_data,
0387                      conn);
0388 }
0389 EXPORT_SYMBOL_GPL(ocfs2_cluster_connect_agnostic);
0390 
0391 /* If hangup_pending is 0, the stack driver will be dropped */
0392 int ocfs2_cluster_disconnect(struct ocfs2_cluster_connection *conn,
0393                  int hangup_pending)
0394 {
0395     int ret;
0396 
0397     BUG_ON(conn == NULL);
0398 
0399     ret = active_stack->sp_ops->disconnect(conn);
0400 
0401     /* XXX Should we free it anyway? */
0402     if (!ret) {
0403         kfree(conn);
0404         if (!hangup_pending)
0405             ocfs2_stack_driver_put();
0406     }
0407 
0408     return ret;
0409 }
0410 EXPORT_SYMBOL_GPL(ocfs2_cluster_disconnect);
0411 
0412 /*
0413  * Leave the group for this filesystem.  This is executed by a userspace
0414  * program (stored in ocfs2_hb_ctl_path).
0415  */
0416 static void ocfs2_leave_group(const char *group)
0417 {
0418     int ret;
0419     char *argv[5], *envp[3];
0420 
0421     argv[0] = ocfs2_hb_ctl_path;
0422     argv[1] = "-K";
0423     argv[2] = "-u";
0424     argv[3] = (char *)group;
0425     argv[4] = NULL;
0426 
0427     /* minimal command environment taken from cpu_run_sbin_hotplug */
0428     envp[0] = "HOME=/";
0429     envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
0430     envp[2] = NULL;
0431 
0432     ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
0433     if (ret < 0) {
0434         printk(KERN_ERR
0435                "ocfs2: Error %d running user helper "
0436                "\"%s %s %s %s\"\n",
0437                ret, argv[0], argv[1], argv[2], argv[3]);
0438     }
0439 }
0440 
0441 /*
0442  * Hangup is a required post-umount.  ocfs2-tools software expects the
0443  * filesystem to call "ocfs2_hb_ctl" during unmount.  This happens
0444  * regardless of whether the DLM got started, so we can't do it
0445  * in ocfs2_cluster_disconnect().  The ocfs2_leave_group() function does
0446  * the actual work.
0447  */
0448 void ocfs2_cluster_hangup(const char *group, int grouplen)
0449 {
0450     BUG_ON(group == NULL);
0451     BUG_ON(group[grouplen] != '\0');
0452 
0453     ocfs2_leave_group(group);
0454 
0455     /* cluster_disconnect() was called with hangup_pending==1 */
0456     ocfs2_stack_driver_put();
0457 }
0458 EXPORT_SYMBOL_GPL(ocfs2_cluster_hangup);
0459 
0460 int ocfs2_cluster_this_node(struct ocfs2_cluster_connection *conn,
0461                 unsigned int *node)
0462 {
0463     return active_stack->sp_ops->this_node(conn, node);
0464 }
0465 EXPORT_SYMBOL_GPL(ocfs2_cluster_this_node);
0466 
0467 
0468 /*
0469  * Sysfs bits
0470  */
0471 
0472 static ssize_t ocfs2_max_locking_protocol_show(struct kobject *kobj,
0473                            struct kobj_attribute *attr,
0474                            char *buf)
0475 {
0476     ssize_t ret = 0;
0477 
0478     spin_lock(&ocfs2_stack_lock);
0479     if (locking_max_version.pv_major)
0480         ret = snprintf(buf, PAGE_SIZE, "%u.%u\n",
0481                    locking_max_version.pv_major,
0482                    locking_max_version.pv_minor);
0483     spin_unlock(&ocfs2_stack_lock);
0484 
0485     return ret;
0486 }
0487 
0488 static struct kobj_attribute ocfs2_attr_max_locking_protocol =
0489     __ATTR(max_locking_protocol, S_IRUGO,
0490            ocfs2_max_locking_protocol_show, NULL);
0491 
0492 static ssize_t ocfs2_loaded_cluster_plugins_show(struct kobject *kobj,
0493                          struct kobj_attribute *attr,
0494                          char *buf)
0495 {
0496     ssize_t ret = 0, total = 0, remain = PAGE_SIZE;
0497     struct ocfs2_stack_plugin *p;
0498 
0499     spin_lock(&ocfs2_stack_lock);
0500     list_for_each_entry(p, &ocfs2_stack_list, sp_list) {
0501         ret = snprintf(buf, remain, "%s\n",
0502                    p->sp_name);
0503         if (ret >= remain) {
0504             /* snprintf() didn't fit */
0505             total = -E2BIG;
0506             break;
0507         }
0508         total += ret;
0509         remain -= ret;
0510     }
0511     spin_unlock(&ocfs2_stack_lock);
0512 
0513     return total;
0514 }
0515 
0516 static struct kobj_attribute ocfs2_attr_loaded_cluster_plugins =
0517     __ATTR(loaded_cluster_plugins, S_IRUGO,
0518            ocfs2_loaded_cluster_plugins_show, NULL);
0519 
0520 static ssize_t ocfs2_active_cluster_plugin_show(struct kobject *kobj,
0521                         struct kobj_attribute *attr,
0522                         char *buf)
0523 {
0524     ssize_t ret = 0;
0525 
0526     spin_lock(&ocfs2_stack_lock);
0527     if (active_stack) {
0528         ret = snprintf(buf, PAGE_SIZE, "%s\n",
0529                    active_stack->sp_name);
0530         if (ret >= PAGE_SIZE)
0531             ret = -E2BIG;
0532     }
0533     spin_unlock(&ocfs2_stack_lock);
0534 
0535     return ret;
0536 }
0537 
0538 static struct kobj_attribute ocfs2_attr_active_cluster_plugin =
0539     __ATTR(active_cluster_plugin, S_IRUGO,
0540            ocfs2_active_cluster_plugin_show, NULL);
0541 
0542 static ssize_t ocfs2_cluster_stack_show(struct kobject *kobj,
0543                     struct kobj_attribute *attr,
0544                     char *buf)
0545 {
0546     ssize_t ret;
0547     spin_lock(&ocfs2_stack_lock);
0548     ret = snprintf(buf, PAGE_SIZE, "%s\n", cluster_stack_name);
0549     spin_unlock(&ocfs2_stack_lock);
0550 
0551     return ret;
0552 }
0553 
0554 static ssize_t ocfs2_cluster_stack_store(struct kobject *kobj,
0555                      struct kobj_attribute *attr,
0556                      const char *buf, size_t count)
0557 {
0558     size_t len = count;
0559     ssize_t ret;
0560 
0561     if (len == 0)
0562         return len;
0563 
0564     if (buf[len - 1] == '\n')
0565         len--;
0566 
0567     if ((len != OCFS2_STACK_LABEL_LEN) ||
0568         (strnlen(buf, len) != len))
0569         return -EINVAL;
0570 
0571     spin_lock(&ocfs2_stack_lock);
0572     if (active_stack) {
0573         if (!strncmp(buf, cluster_stack_name, len))
0574             ret = count;
0575         else
0576             ret = -EBUSY;
0577     } else {
0578         memcpy(cluster_stack_name, buf, len);
0579         ret = count;
0580     }
0581     spin_unlock(&ocfs2_stack_lock);
0582 
0583     return ret;
0584 }
0585 
0586 
0587 static struct kobj_attribute ocfs2_attr_cluster_stack =
0588     __ATTR(cluster_stack, S_IRUGO | S_IWUSR,
0589            ocfs2_cluster_stack_show,
0590            ocfs2_cluster_stack_store);
0591 
0592 
0593 
0594 static ssize_t ocfs2_dlm_recover_show(struct kobject *kobj,
0595                     struct kobj_attribute *attr,
0596                     char *buf)
0597 {
0598     return snprintf(buf, PAGE_SIZE, "1\n");
0599 }
0600 
0601 static struct kobj_attribute ocfs2_attr_dlm_recover_support =
0602     __ATTR(dlm_recover_callback_support, S_IRUGO,
0603            ocfs2_dlm_recover_show, NULL);
0604 
0605 static struct attribute *ocfs2_attrs[] = {
0606     &ocfs2_attr_max_locking_protocol.attr,
0607     &ocfs2_attr_loaded_cluster_plugins.attr,
0608     &ocfs2_attr_active_cluster_plugin.attr,
0609     &ocfs2_attr_cluster_stack.attr,
0610     &ocfs2_attr_dlm_recover_support.attr,
0611     NULL,
0612 };
0613 
0614 static const struct attribute_group ocfs2_attr_group = {
0615     .attrs = ocfs2_attrs,
0616 };
0617 
0618 struct kset *ocfs2_kset;
0619 EXPORT_SYMBOL_GPL(ocfs2_kset);
0620 
0621 static void ocfs2_sysfs_exit(void)
0622 {
0623     kset_unregister(ocfs2_kset);
0624 }
0625 
0626 static int ocfs2_sysfs_init(void)
0627 {
0628     int ret;
0629 
0630     ocfs2_kset = kset_create_and_add("ocfs2", NULL, fs_kobj);
0631     if (!ocfs2_kset)
0632         return -ENOMEM;
0633 
0634     ret = sysfs_create_group(&ocfs2_kset->kobj, &ocfs2_attr_group);
0635     if (ret)
0636         goto error;
0637 
0638     return 0;
0639 
0640 error:
0641     kset_unregister(ocfs2_kset);
0642     return ret;
0643 }
0644 
0645 /*
0646  * Sysctl bits
0647  *
0648  * The sysctl lives at /proc/sys/fs/ocfs2/nm/hb_ctl_path.  The 'nm' doesn't
0649  * make as much sense in a multiple cluster stack world, but it's safer
0650  * and easier to preserve the name.
0651  */
0652 
0653 static struct ctl_table ocfs2_nm_table[] = {
0654     {
0655         .procname   = "hb_ctl_path",
0656         .data       = ocfs2_hb_ctl_path,
0657         .maxlen     = OCFS2_MAX_HB_CTL_PATH,
0658         .mode       = 0644,
0659         .proc_handler   = proc_dostring,
0660     },
0661     { }
0662 };
0663 
0664 static struct ctl_table_header *ocfs2_table_header;
0665 
0666 /*
0667  * Initialization
0668  */
0669 
0670 static int __init ocfs2_stack_glue_init(void)
0671 {
0672     strcpy(cluster_stack_name, OCFS2_STACK_PLUGIN_O2CB);
0673 
0674     ocfs2_table_header = register_sysctl("fs/ocfs2/nm", ocfs2_nm_table);
0675     if (!ocfs2_table_header) {
0676         printk(KERN_ERR
0677                "ocfs2 stack glue: unable to register sysctl\n");
0678         return -ENOMEM; /* or something. */
0679     }
0680 
0681     return ocfs2_sysfs_init();
0682 }
0683 
0684 static void __exit ocfs2_stack_glue_exit(void)
0685 {
0686     memset(&locking_max_version, 0,
0687            sizeof(struct ocfs2_protocol_version));
0688     ocfs2_sysfs_exit();
0689     if (ocfs2_table_header)
0690         unregister_sysctl_table(ocfs2_table_header);
0691 }
0692 
0693 MODULE_AUTHOR("Oracle");
0694 MODULE_DESCRIPTION("ocfs2 cluster stack glue layer");
0695 MODULE_LICENSE("GPL");
0696 module_init(ocfs2_stack_glue_init);
0697 module_exit(ocfs2_stack_glue_exit);