mirror of
https://github.com/versity/scoutfs.git
synced 2026-02-07 19:20:44 +00:00
scoutfs: show quorum state in sysfs
Add some sysfs files which show quorum state. We store the state in quorum_info off the super which is updates as we participate in elections. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
#include "quorum.h"
|
||||
#include "server.h"
|
||||
#include "net.h"
|
||||
#include "sysfs.h"
|
||||
#include "scoutfs_trace.h"
|
||||
|
||||
/*
|
||||
@@ -63,6 +64,19 @@
|
||||
* - add config rotation (write new config, reclaim stale slots)
|
||||
*/
|
||||
|
||||
struct quorum_info {
|
||||
struct scoutfs_sysfs_attrs ssa;
|
||||
|
||||
bool is_leader;
|
||||
struct sockaddr_in conf_addr;
|
||||
u16 conf_port;
|
||||
};
|
||||
|
||||
#define DECLARE_QUORUM_INFO(sb, name) \
|
||||
struct quorum_info *name = SCOUTFS_SB(sb)->quorum_info
|
||||
#define DECLARE_QUORUM_INFO_KOBJ(kobj, name) \
|
||||
DECLARE_QUORUM_INFO(SCOUTFS_SYSFS_ATTRS_SB(kobj), name)
|
||||
|
||||
static void addr_to_sin(struct sockaddr_in *sin, struct scoutfs_inet_addr *addr)
|
||||
{
|
||||
sin->sin_family = AF_INET;
|
||||
@@ -527,6 +541,7 @@ int scoutfs_quorum_election(struct super_block *sb, char *our_name,
|
||||
bool unmounting, u64 our_umb,
|
||||
struct scoutfs_quorum_elected_info *qei)
|
||||
{
|
||||
DECLARE_QUORUM_INFO(sb, qinf);
|
||||
struct scoutfs_super_block *super = NULL;
|
||||
struct scoutfs_quorum_config *conf;
|
||||
struct scoutfs_quorum_slot *slot;
|
||||
@@ -566,6 +581,16 @@ int scoutfs_quorum_election(struct super_block *sb, char *our_name,
|
||||
goto out;
|
||||
conf = &super->quorum_config;
|
||||
|
||||
/* update sysfs with most recently seen config */
|
||||
if (our_slot >= 0) {
|
||||
slot = &conf->slots[our_slot];
|
||||
addr_to_sin(&qinf->conf_addr, &slot->addr);
|
||||
qinf->conf_port = le16_to_cpu(slot->addr.port);
|
||||
} else {
|
||||
memset(&qinf->conf_addr, 0, sizeof(qinf->conf_addr));
|
||||
qinf->conf_port = 0;
|
||||
}
|
||||
|
||||
majority = scoutfs_quorum_majority(sb, conf);
|
||||
|
||||
readahead_quorum_blocks(sb);
|
||||
@@ -623,6 +648,7 @@ int scoutfs_quorum_election(struct super_block *sb, char *our_name,
|
||||
elected_nr);
|
||||
if (ret == 0) {
|
||||
qei->run_server = true;
|
||||
qinf->is_leader = true;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -739,8 +765,10 @@ int scoutfs_quorum_clear_elected(struct super_block *sb,
|
||||
struct scoutfs_quorum_elected_info *qei)
|
||||
{
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
DECLARE_QUORUM_INFO(sb, qinf);
|
||||
|
||||
qei->flags &= ~SCOUTFS_QUORUM_BLOCK_FLAG_ELECTED;
|
||||
qinf->is_leader = false;
|
||||
|
||||
return write_quorum_block(sb, super->hdr.fsid, qei->config_gen,
|
||||
qei->config_slot, qei->write_nr,
|
||||
@@ -807,3 +835,73 @@ bool scoutfs_quorum_voting_member(struct super_block *sb,
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static ssize_t is_leader_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
DECLARE_QUORUM_INFO_KOBJ(kobj, qinf);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u", !!qinf->is_leader);
|
||||
}
|
||||
SCOUTFS_ATTR_RO(is_leader);
|
||||
|
||||
static ssize_t ipv4_addr_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
DECLARE_QUORUM_INFO_KOBJ(kobj, qinf);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%pIS", &qinf->conf_addr);
|
||||
}
|
||||
SCOUTFS_ATTR_RO(ipv4_addr);
|
||||
|
||||
static ssize_t ipv4_port_show(struct kobject *kobj,
|
||||
struct kobj_attribute *attr, char *buf)
|
||||
{
|
||||
DECLARE_QUORUM_INFO_KOBJ(kobj, qinf);
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%u", qinf->conf_port);
|
||||
}
|
||||
SCOUTFS_ATTR_RO(ipv4_port);
|
||||
|
||||
static struct attribute *quorum_attrs[] = {
|
||||
SCOUTFS_ATTR_PTR(is_leader),
|
||||
SCOUTFS_ATTR_PTR(ipv4_addr),
|
||||
SCOUTFS_ATTR_PTR(ipv4_port),
|
||||
NULL,
|
||||
};
|
||||
|
||||
int scoutfs_quorum_setup(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct quorum_info *qinf;
|
||||
int ret;
|
||||
|
||||
qinf = kzalloc(sizeof(struct quorum_info), GFP_KERNEL);
|
||||
if (!qinf) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
scoutfs_sysfs_init_attrs(sb, &qinf->ssa);
|
||||
|
||||
sbi->quorum_info = qinf;
|
||||
|
||||
ret = scoutfs_sysfs_create_attrs(sb, &qinf->ssa, quorum_attrs,
|
||||
"quorum");
|
||||
out:
|
||||
if (ret)
|
||||
scoutfs_quorum_destroy(sb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void scoutfs_quorum_destroy(struct super_block *sb)
|
||||
{
|
||||
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
|
||||
struct quorum_info *qinf = SCOUTFS_SB(sb)->quorum_info;
|
||||
|
||||
if (qinf) {
|
||||
scoutfs_sysfs_destroy_attrs(sb, &qinf->ssa);
|
||||
kfree(qinf);
|
||||
sbi->quorum_info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,4 +27,6 @@ bool scoutfs_quorum_voting_member(struct super_block *sb,
|
||||
struct scoutfs_quorum_config *conf,
|
||||
char *name);
|
||||
|
||||
int scoutfs_quorum_setup(struct super_block *sb);
|
||||
void scoutfs_quorum_destroy(struct super_block *sb);
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,7 @@
|
||||
#include "server.h"
|
||||
#include "options.h"
|
||||
#include "sysfs.h"
|
||||
#include "quorum.h"
|
||||
#include "scoutfs_trace.h"
|
||||
|
||||
static struct dentry *scoutfs_debugfs_root;
|
||||
@@ -161,6 +162,7 @@ static void scoutfs_put_super(struct super_block *sb)
|
||||
|
||||
scoutfs_shutdown_trans(sb);
|
||||
scoutfs_client_destroy(sb);
|
||||
scoutfs_quorum_destroy(sb);
|
||||
scoutfs_inode_destroy(sb);
|
||||
|
||||
/* the server locks the listen address and compacts */
|
||||
@@ -371,6 +373,7 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent)
|
||||
scoutfs_setup_trans(sb) ?:
|
||||
scoutfs_lock_setup(sb) ?:
|
||||
scoutfs_net_setup(sb) ?:
|
||||
scoutfs_quorum_setup(sb) ?:
|
||||
scoutfs_server_setup(sb) ?:
|
||||
scoutfs_client_setup(sb) ?:
|
||||
scoutfs_client_wait_node_id(sb) ?:
|
||||
|
||||
@@ -46,6 +46,7 @@ struct scoutfs_sb_info {
|
||||
struct inode_sb_info *inode_sb_info;
|
||||
struct btree_info *btree_info;
|
||||
struct net_info *net_info;
|
||||
struct quorum_info *quorum_info;
|
||||
|
||||
wait_queue_head_t trans_hold_wq;
|
||||
struct task_struct *trans_task;
|
||||
|
||||
Reference in New Issue
Block a user