6bd70aba5a
This saves the journal recovery result and makes it visible through sysfs. User space needs to know if the node actually recovered the journal or tried and gave up. Signed-off-by: David Teigland <teigland@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
226 lines
5.3 KiB
C
226 lines
5.3 KiB
C
/*
|
|
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
|
|
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
|
|
*
|
|
* This copyrighted material is made available to anyone wishing to use,
|
|
* modify, copy, or redistribute it subject to the terms and conditions
|
|
* of the GNU General Public License v.2.
|
|
*/
|
|
|
|
#include <linux/ctype.h>
|
|
#include <linux/stat.h>
|
|
|
|
#include "lock_dlm.h"
|
|
|
|
extern struct lm_lockops gdlm_ops;
|
|
|
|
static ssize_t proto_name_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%s\n", gdlm_ops.lm_proto_name);
|
|
}
|
|
|
|
static ssize_t block_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
ssize_t ret;
|
|
int val = 0;
|
|
|
|
if (test_bit(DFL_BLOCK_LOCKS, &ls->flags))
|
|
val = 1;
|
|
ret = sprintf(buf, "%d\n", val);
|
|
return ret;
|
|
}
|
|
|
|
static ssize_t block_store(struct gdlm_ls *ls, const char *buf, size_t len)
|
|
{
|
|
ssize_t ret = len;
|
|
int val;
|
|
|
|
val = simple_strtol(buf, NULL, 0);
|
|
|
|
if (val == 1)
|
|
set_bit(DFL_BLOCK_LOCKS, &ls->flags);
|
|
else if (val == 0) {
|
|
clear_bit(DFL_BLOCK_LOCKS, &ls->flags);
|
|
gdlm_submit_delayed(ls);
|
|
} else
|
|
ret = -EINVAL;
|
|
return ret;
|
|
}
|
|
|
|
static ssize_t withdraw_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
ssize_t ret;
|
|
int val = 0;
|
|
|
|
if (test_bit(DFL_WITHDRAW, &ls->flags))
|
|
val = 1;
|
|
ret = sprintf(buf, "%d\n", val);
|
|
return ret;
|
|
}
|
|
|
|
static ssize_t withdraw_store(struct gdlm_ls *ls, const char *buf, size_t len)
|
|
{
|
|
ssize_t ret = len;
|
|
int val;
|
|
|
|
val = simple_strtol(buf, NULL, 0);
|
|
|
|
if (val == 1)
|
|
set_bit(DFL_WITHDRAW, &ls->flags);
|
|
else
|
|
ret = -EINVAL;
|
|
wake_up(&ls->wait_control);
|
|
return ret;
|
|
}
|
|
|
|
static ssize_t id_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%u\n", ls->id);
|
|
}
|
|
|
|
static ssize_t jid_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->jid);
|
|
}
|
|
|
|
static ssize_t first_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->first);
|
|
}
|
|
|
|
static ssize_t first_done_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->first_done);
|
|
}
|
|
|
|
static ssize_t recover_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->recover_jid);
|
|
}
|
|
|
|
static ssize_t recover_store(struct gdlm_ls *ls, const char *buf, size_t len)
|
|
{
|
|
ls->recover_jid = simple_strtol(buf, NULL, 0);
|
|
ls->fscb(ls->fsdata, LM_CB_NEED_RECOVERY, &ls->recover_jid);
|
|
return len;
|
|
}
|
|
|
|
static ssize_t recover_done_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->recover_jid_done);
|
|
}
|
|
|
|
static ssize_t recover_status_show(struct gdlm_ls *ls, char *buf)
|
|
{
|
|
return sprintf(buf, "%d\n", ls->recover_jid_status);
|
|
}
|
|
|
|
struct gdlm_attr {
|
|
struct attribute attr;
|
|
ssize_t (*show)(struct gdlm_ls *, char *);
|
|
ssize_t (*store)(struct gdlm_ls *, const char *, size_t);
|
|
};
|
|
|
|
#define GDLM_ATTR(_name,_mode,_show,_store) \
|
|
static struct gdlm_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
|
|
|
|
GDLM_ATTR(proto_name, 0444, proto_name_show, NULL);
|
|
GDLM_ATTR(block, 0644, block_show, block_store);
|
|
GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store);
|
|
GDLM_ATTR(id, 0444, id_show, NULL);
|
|
GDLM_ATTR(jid, 0444, jid_show, NULL);
|
|
GDLM_ATTR(first, 0444, first_show, NULL);
|
|
GDLM_ATTR(first_done, 0444, first_done_show, NULL);
|
|
GDLM_ATTR(recover, 0644, recover_show, recover_store);
|
|
GDLM_ATTR(recover_done, 0444, recover_done_show, NULL);
|
|
GDLM_ATTR(recover_status, 0444, recover_status_show, NULL);
|
|
|
|
static struct attribute *gdlm_attrs[] = {
|
|
&gdlm_attr_proto_name.attr,
|
|
&gdlm_attr_block.attr,
|
|
&gdlm_attr_withdraw.attr,
|
|
&gdlm_attr_id.attr,
|
|
&gdlm_attr_jid.attr,
|
|
&gdlm_attr_first.attr,
|
|
&gdlm_attr_first_done.attr,
|
|
&gdlm_attr_recover.attr,
|
|
&gdlm_attr_recover_done.attr,
|
|
&gdlm_attr_recover_status.attr,
|
|
NULL,
|
|
};
|
|
|
|
static ssize_t gdlm_attr_show(struct kobject *kobj, struct attribute *attr,
|
|
char *buf)
|
|
{
|
|
struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
|
|
struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
|
|
return a->show ? a->show(ls, buf) : 0;
|
|
}
|
|
|
|
static ssize_t gdlm_attr_store(struct kobject *kobj, struct attribute *attr,
|
|
const char *buf, size_t len)
|
|
{
|
|
struct gdlm_ls *ls = container_of(kobj, struct gdlm_ls, kobj);
|
|
struct gdlm_attr *a = container_of(attr, struct gdlm_attr, attr);
|
|
return a->store ? a->store(ls, buf, len) : len;
|
|
}
|
|
|
|
static struct sysfs_ops gdlm_attr_ops = {
|
|
.show = gdlm_attr_show,
|
|
.store = gdlm_attr_store,
|
|
};
|
|
|
|
static struct kobj_type gdlm_ktype = {
|
|
.default_attrs = gdlm_attrs,
|
|
.sysfs_ops = &gdlm_attr_ops,
|
|
};
|
|
|
|
static struct kset gdlm_kset = {
|
|
.subsys = &kernel_subsys,
|
|
.kobj = {.name = "lock_dlm",},
|
|
.ktype = &gdlm_ktype,
|
|
};
|
|
|
|
int gdlm_kobject_setup(struct gdlm_ls *ls, struct kobject *fskobj)
|
|
{
|
|
int error;
|
|
|
|
error = kobject_set_name(&ls->kobj, "%s", "lock_module");
|
|
if (error) {
|
|
log_error("can't set kobj name %d", error);
|
|
return error;
|
|
}
|
|
|
|
ls->kobj.kset = &gdlm_kset;
|
|
ls->kobj.ktype = &gdlm_ktype;
|
|
ls->kobj.parent = fskobj;
|
|
|
|
error = kobject_register(&ls->kobj);
|
|
if (error)
|
|
log_error("can't register kobj %d", error);
|
|
|
|
return error;
|
|
}
|
|
|
|
void gdlm_kobject_release(struct gdlm_ls *ls)
|
|
{
|
|
kobject_unregister(&ls->kobj);
|
|
}
|
|
|
|
int gdlm_sysfs_init(void)
|
|
{
|
|
int error;
|
|
|
|
error = kset_register(&gdlm_kset);
|
|
if (error)
|
|
printk("lock_dlm: cannot register kset %d\n", error);
|
|
|
|
return error;
|
|
}
|
|
|
|
void gdlm_sysfs_exit(void)
|
|
{
|
|
kset_unregister(&gdlm_kset);
|
|
}
|
|
|