aboutsummaryrefslogtreecommitdiffstats
path: root/fs/dlm
diff options
context:
space:
mode:
Diffstat (limited to 'fs/dlm')
-rw-r--r--fs/dlm/lockspace.c24
-rw-r--r--fs/dlm/lockspace.h1
-rw-r--r--fs/dlm/user.c61
-rw-r--r--fs/dlm/user.h1
4 files changed, 85 insertions, 2 deletions
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 56eae4e4a954..ba672fe0a601 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -378,6 +378,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
378 if (!try_module_get(THIS_MODULE)) 378 if (!try_module_get(THIS_MODULE))
379 return -EINVAL; 379 return -EINVAL;
380 380
381 if (!dlm_user_daemon_available()) {
382 module_put(THIS_MODULE);
383 return -EUNATCH;
384 }
385
381 error = 0; 386 error = 0;
382 387
383 spin_lock(&lslist_lock); 388 spin_lock(&lslist_lock);
@@ -669,7 +674,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
669 674
670 dlm_device_deregister(ls); 675 dlm_device_deregister(ls);
671 676
672 if (force < 3) 677 if (force < 3 && dlm_user_daemon_available())
673 do_uevent(ls, 0); 678 do_uevent(ls, 0);
674 679
675 dlm_recoverd_stop(ls); 680 dlm_recoverd_stop(ls);
@@ -791,3 +796,20 @@ int dlm_release_lockspace(void *lockspace, int force)
791 return error; 796 return error;
792} 797}
793 798
799void dlm_stop_lockspaces(void)
800{
801 struct dlm_ls *ls;
802
803 restart:
804 spin_lock(&lslist_lock);
805 list_for_each_entry(ls, &lslist, ls_list) {
806 if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
807 continue;
808 spin_unlock(&lslist_lock);
809 log_error(ls, "no userland control daemon, stopping lockspace");
810 dlm_ls_stop(ls);
811 goto restart;
812 }
813 spin_unlock(&lslist_lock);
814}
815
diff --git a/fs/dlm/lockspace.h b/fs/dlm/lockspace.h
index 891eabbdd021..f879f87901f8 100644
--- a/fs/dlm/lockspace.h
+++ b/fs/dlm/lockspace.h
@@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id);
20struct dlm_ls *dlm_find_lockspace_local(void *id); 20struct dlm_ls *dlm_find_lockspace_local(void *id);
21struct dlm_ls *dlm_find_lockspace_device(int minor); 21struct dlm_ls *dlm_find_lockspace_device(int minor);
22void dlm_put_lockspace(struct dlm_ls *ls); 22void dlm_put_lockspace(struct dlm_ls *ls);
23void dlm_stop_lockspaces(void);
23 24
24#endif /* __LOCKSPACE_DOT_H__ */ 25#endif /* __LOCKSPACE_DOT_H__ */
25 26
diff --git a/fs/dlm/user.c b/fs/dlm/user.c
index 6542110c0da4..81627b502a56 100644
--- a/fs/dlm/user.c
+++ b/fs/dlm/user.c
@@ -27,6 +27,8 @@
27 27
28static const char name_prefix[] = "dlm"; 28static const char name_prefix[] = "dlm";
29static const struct file_operations device_fops; 29static const struct file_operations device_fops;
30static atomic_t dlm_monitor_opened;
31static int dlm_monitor_unused = 1;
30 32
31#ifdef CONFIG_COMPAT 33#ifdef CONFIG_COMPAT
32 34
@@ -890,6 +892,26 @@ static unsigned int device_poll(struct file *file, poll_table *wait)
890 return 0; 892 return 0;
891} 893}
892 894
895int dlm_user_daemon_available(void)
896{
897 /* dlm_controld hasn't started (or, has started, but not
898 properly populated configfs) */
899
900 if (!dlm_our_nodeid())
901 return 0;
902
903 /* This is to deal with versions of dlm_controld that don't
904 know about the monitor device. We assume that if the
905 dlm_controld was started (above), but the monitor device
906 was never opened, that it's an old version. dlm_controld
907 should open the monitor device before populating configfs. */
908
909 if (dlm_monitor_unused)
910 return 1;
911
912 return atomic_read(&dlm_monitor_opened) ? 1 : 0;
913}
914
893static int ctl_device_open(struct inode *inode, struct file *file) 915static int ctl_device_open(struct inode *inode, struct file *file)
894{ 916{
895 cycle_kernel_lock(); 917 cycle_kernel_lock();
@@ -902,6 +924,20 @@ static int ctl_device_close(struct inode *inode, struct file *file)
902 return 0; 924 return 0;
903} 925}
904 926
927static int monitor_device_open(struct inode *inode, struct file *file)
928{
929 atomic_inc(&dlm_monitor_opened);
930 dlm_monitor_unused = 0;
931 return 0;
932}
933
934static int monitor_device_close(struct inode *inode, struct file *file)
935{
936 if (atomic_dec_and_test(&dlm_monitor_opened))
937 dlm_stop_lockspaces();
938 return 0;
939}
940
905static const struct file_operations device_fops = { 941static const struct file_operations device_fops = {
906 .open = device_open, 942 .open = device_open,
907 .release = device_close, 943 .release = device_close,
@@ -925,19 +961,42 @@ static struct miscdevice ctl_device = {
925 .minor = MISC_DYNAMIC_MINOR, 961 .minor = MISC_DYNAMIC_MINOR,
926}; 962};
927 963
964static const struct file_operations monitor_device_fops = {
965 .open = monitor_device_open,
966 .release = monitor_device_close,
967 .owner = THIS_MODULE,
968};
969
970static struct miscdevice monitor_device = {
971 .name = "dlm-monitor",
972 .fops = &monitor_device_fops,
973 .minor = MISC_DYNAMIC_MINOR,
974};
975
928int __init dlm_user_init(void) 976int __init dlm_user_init(void)
929{ 977{
930 int error; 978 int error;
931 979
980 atomic_set(&dlm_monitor_opened, 0);
981
932 error = misc_register(&ctl_device); 982 error = misc_register(&ctl_device);
933 if (error) 983 if (error) {
934 log_print("misc_register failed for control device"); 984 log_print("misc_register failed for control device");
985 goto out;
986 }
935 987
988 error = misc_register(&monitor_device);
989 if (error) {
990 log_print("misc_register failed for monitor device");
991 misc_deregister(&ctl_device);
992 }
993 out:
936 return error; 994 return error;
937} 995}
938 996
939void dlm_user_exit(void) 997void dlm_user_exit(void)
940{ 998{
941 misc_deregister(&ctl_device); 999 misc_deregister(&ctl_device);
1000 misc_deregister(&monitor_device);
942} 1001}
943 1002
diff --git a/fs/dlm/user.h b/fs/dlm/user.h
index c528b6b2991b..35eb6a13d616 100644
--- a/fs/dlm/user.h
+++ b/fs/dlm/user.h
@@ -13,5 +13,6 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type);
13int dlm_user_init(void); 13int dlm_user_init(void);
14void dlm_user_exit(void); 14void dlm_user_exit(void);
15int dlm_device_deregister(struct dlm_ls *ls); 15int dlm_device_deregister(struct dlm_ls *ls);
16int dlm_user_daemon_available(void);
16 17
17#endif 18#endif