0001
0002
0003
0004
0005
0006
0007
0008
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
0037
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
0065
0066
0067 if (strcmp(stack_name, cluster_stack_name)) {
0068 rc = -EBUSY;
0069 goto out;
0070 }
0071
0072 if (active_stack) {
0073
0074
0075
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
0095 if (!rc)
0096 active_stack->sp_count++;
0097
0098 spin_unlock(&ocfs2_stack_lock);
0099 return rc;
0100 }
0101
0102
0103
0104
0105
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
0114
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
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
0227
0228
0229
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
0289
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
0348 new_conn->cc_version = lproto->lp_max_version;
0349
0350
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
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
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
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
0414
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
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
0443
0444
0445
0446
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
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
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
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
0647
0648
0649
0650
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
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;
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);