mirror of
https://github.com/adulau/aha.git
synced 2024-12-27 11:16:11 +00:00
dlm: detect available userspace daemon
If dlm_controld (the userspace daemon that controls the setup and recovery of the dlm) fails, the kernel should shut down the lockspaces in the kernel rather than leaving them running. This is detected by having dlm_controld hold a misc device open while running, and if the kernel detects a close while the daemon is still needed, it stops the lockspaces in the kernel. Knowing that the userspace daemon isn't running also allows the lockspace create/remove routines to avoid waiting on the daemon for join/leave operations. Signed-off-by: David Teigland <teigland@redhat.com>
This commit is contained in:
parent
0f8e0d9a31
commit
dc68c7ed36
4 changed files with 87 additions and 4 deletions
|
@ -378,6 +378,11 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
|
|||
if (!try_module_get(THIS_MODULE))
|
||||
return -EINVAL;
|
||||
|
||||
if (!dlm_user_daemon_available()) {
|
||||
module_put(THIS_MODULE);
|
||||
return -EUNATCH;
|
||||
}
|
||||
|
||||
error = 0;
|
||||
|
||||
spin_lock(&lslist_lock);
|
||||
|
@ -669,7 +674,7 @@ static int release_lockspace(struct dlm_ls *ls, int force)
|
|||
|
||||
dlm_device_deregister(ls);
|
||||
|
||||
if (force < 3)
|
||||
if (force < 3 && dlm_user_daemon_available())
|
||||
do_uevent(ls, 0);
|
||||
|
||||
dlm_recoverd_stop(ls);
|
||||
|
@ -791,3 +796,20 @@ int dlm_release_lockspace(void *lockspace, int force)
|
|||
return error;
|
||||
}
|
||||
|
||||
void dlm_stop_lockspaces(void)
|
||||
{
|
||||
struct dlm_ls *ls;
|
||||
|
||||
restart:
|
||||
spin_lock(&lslist_lock);
|
||||
list_for_each_entry(ls, &lslist, ls_list) {
|
||||
if (!test_bit(LSFL_RUNNING, &ls->ls_flags))
|
||||
continue;
|
||||
spin_unlock(&lslist_lock);
|
||||
log_error(ls, "no userland control daemon, stopping lockspace");
|
||||
dlm_ls_stop(ls);
|
||||
goto restart;
|
||||
}
|
||||
spin_unlock(&lslist_lock);
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ struct dlm_ls *dlm_find_lockspace_global(uint32_t id);
|
|||
struct dlm_ls *dlm_find_lockspace_local(void *id);
|
||||
struct dlm_ls *dlm_find_lockspace_device(int minor);
|
||||
void dlm_put_lockspace(struct dlm_ls *ls);
|
||||
void dlm_stop_lockspaces(void);
|
||||
|
||||
#endif /* __LOCKSPACE_DOT_H__ */
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
static const char name_prefix[] = "dlm";
|
||||
static const struct file_operations device_fops;
|
||||
static atomic_t dlm_monitor_opened;
|
||||
static int dlm_monitor_unused = 1;
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
|
||||
|
@ -890,6 +892,26 @@ static unsigned int device_poll(struct file *file, poll_table *wait)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int dlm_user_daemon_available(void)
|
||||
{
|
||||
/* dlm_controld hasn't started (or, has started, but not
|
||||
properly populated configfs) */
|
||||
|
||||
if (!dlm_our_nodeid())
|
||||
return 0;
|
||||
|
||||
/* This is to deal with versions of dlm_controld that don't
|
||||
know about the monitor device. We assume that if the
|
||||
dlm_controld was started (above), but the monitor device
|
||||
was never opened, that it's an old version. dlm_controld
|
||||
should open the monitor device before populating configfs. */
|
||||
|
||||
if (dlm_monitor_unused)
|
||||
return 1;
|
||||
|
||||
return atomic_read(&dlm_monitor_opened) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int ctl_device_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
cycle_kernel_lock();
|
||||
|
@ -902,6 +924,20 @@ static int ctl_device_close(struct inode *inode, struct file *file)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int monitor_device_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
atomic_inc(&dlm_monitor_opened);
|
||||
dlm_monitor_unused = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int monitor_device_close(struct inode *inode, struct file *file)
|
||||
{
|
||||
if (atomic_dec_and_test(&dlm_monitor_opened))
|
||||
dlm_stop_lockspaces();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct file_operations device_fops = {
|
||||
.open = device_open,
|
||||
.release = device_close,
|
||||
|
@ -925,19 +961,42 @@ static struct miscdevice ctl_device = {
|
|||
.minor = MISC_DYNAMIC_MINOR,
|
||||
};
|
||||
|
||||
static const struct file_operations monitor_device_fops = {
|
||||
.open = monitor_device_open,
|
||||
.release = monitor_device_close,
|
||||
.owner = THIS_MODULE,
|
||||
};
|
||||
|
||||
static struct miscdevice monitor_device = {
|
||||
.name = "dlm-monitor",
|
||||
.fops = &monitor_device_fops,
|
||||
.minor = MISC_DYNAMIC_MINOR,
|
||||
};
|
||||
|
||||
int __init dlm_user_init(void)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = misc_register(&ctl_device);
|
||||
if (error)
|
||||
log_print("misc_register failed for control device");
|
||||
atomic_set(&dlm_monitor_opened, 0);
|
||||
|
||||
error = misc_register(&ctl_device);
|
||||
if (error) {
|
||||
log_print("misc_register failed for control device");
|
||||
goto out;
|
||||
}
|
||||
|
||||
error = misc_register(&monitor_device);
|
||||
if (error) {
|
||||
log_print("misc_register failed for monitor device");
|
||||
misc_deregister(&ctl_device);
|
||||
}
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
void dlm_user_exit(void)
|
||||
{
|
||||
misc_deregister(&ctl_device);
|
||||
misc_deregister(&monitor_device);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,5 +13,6 @@ void dlm_user_add_ast(struct dlm_lkb *lkb, int type);
|
|||
int dlm_user_init(void);
|
||||
void dlm_user_exit(void);
|
||||
int dlm_device_deregister(struct dlm_ls *ls);
|
||||
int dlm_user_daemon_available(void);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue