diff options
-rw-r--r-- | fs/dlm/lockspace.c | 24 | ||||
-rw-r--r-- | fs/dlm/lockspace.h | 1 | ||||
-rw-r--r-- | fs/dlm/user.c | 61 | ||||
-rw-r--r-- | fs/dlm/user.h | 1 |
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 | ||
799 | void 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); | |||
20 | struct dlm_ls *dlm_find_lockspace_local(void *id); | 20 | struct dlm_ls *dlm_find_lockspace_local(void *id); |
21 | struct dlm_ls *dlm_find_lockspace_device(int minor); | 21 | struct dlm_ls *dlm_find_lockspace_device(int minor); |
22 | void dlm_put_lockspace(struct dlm_ls *ls); | 22 | void dlm_put_lockspace(struct dlm_ls *ls); |
23 | void 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 | ||
28 | static const char name_prefix[] = "dlm"; | 28 | static const char name_prefix[] = "dlm"; |
29 | static const struct file_operations device_fops; | 29 | static const struct file_operations device_fops; |
30 | static atomic_t dlm_monitor_opened; | ||
31 | static 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 | ||
895 | int 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 | |||
893 | static int ctl_device_open(struct inode *inode, struct file *file) | 915 | static 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 | ||
927 | static 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 | |||
934 | static 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 | |||
905 | static const struct file_operations device_fops = { | 941 | static 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 | ||
964 | static const struct file_operations monitor_device_fops = { | ||
965 | .open = monitor_device_open, | ||
966 | .release = monitor_device_close, | ||
967 | .owner = THIS_MODULE, | ||
968 | }; | ||
969 | |||
970 | static struct miscdevice monitor_device = { | ||
971 | .name = "dlm-monitor", | ||
972 | .fops = &monitor_device_fops, | ||
973 | .minor = MISC_DYNAMIC_MINOR, | ||
974 | }; | ||
975 | |||
928 | int __init dlm_user_init(void) | 976 | int __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 | ||
939 | void dlm_user_exit(void) | 997 | void 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); | |||
13 | int dlm_user_init(void); | 13 | int dlm_user_init(void); |
14 | void dlm_user_exit(void); | 14 | void dlm_user_exit(void); |
15 | int dlm_device_deregister(struct dlm_ls *ls); | 15 | int dlm_device_deregister(struct dlm_ls *ls); |
16 | int dlm_user_daemon_available(void); | ||
16 | 17 | ||
17 | #endif | 18 | #endif |