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:
Zach Brown
2019-05-28 16:16:51 -07:00
committed by Zach Brown
parent 2cc4f89ad5
commit 4df35efbc0
4 changed files with 104 additions and 0 deletions

View File

@@ -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;
}
}

View File

@@ -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

View File

@@ -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) ?:

View File

@@ -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;