mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-05 03:44:05 +00:00
Add client address to mounted_client item
Add the peername of the client's connected socket to its mounted_client item as it mounts. If the client doesn't recover then fencing can use the IP to find the host to fence. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -327,7 +327,9 @@ struct scoutfs_alloc_root {
|
||||
#define SCOUTFS_ALLOC_OWNER_SRCH 3
|
||||
|
||||
struct scoutfs_mounted_client_btree_val {
|
||||
union scoutfs_inet_addr addr;
|
||||
__u8 flags;
|
||||
__u8 __pad[7];
|
||||
};
|
||||
|
||||
#define SCOUTFS_MOUNTED_CLIENT_QUORUM (1 << 0)
|
||||
|
||||
@@ -100,6 +100,16 @@ static inline void scoutfs_addr_to_sin(struct sockaddr_in *sin,
|
||||
sin->sin_port = cpu_to_be16(le16_to_cpu(addr->v4.port));
|
||||
}
|
||||
|
||||
static inline void scoutfs_sin_to_addr(union scoutfs_inet_addr *addr, struct sockaddr_in *sin)
|
||||
{
|
||||
BUG_ON(sin->sin_family != AF_INET);
|
||||
|
||||
memset(addr, 0, sizeof(union scoutfs_inet_addr));
|
||||
addr->v4.family = cpu_to_le16(SCOUTFS_AF_IPV4);
|
||||
addr->v4.addr = be32_to_le32(sin->sin_addr.s_addr);
|
||||
addr->v4.port = be16_to_le16(sin->sin_port);
|
||||
}
|
||||
|
||||
struct scoutfs_net_connection *
|
||||
scoutfs_net_alloc_conn(struct super_block *sb,
|
||||
scoutfs_net_notify_t notify_up,
|
||||
|
||||
@@ -1453,14 +1453,19 @@ static void init_mounted_client_key(struct scoutfs_key *key, u64 rid)
|
||||
};
|
||||
}
|
||||
|
||||
static bool invalid_mounted_client_item(struct scoutfs_btree_item_ref *iref)
|
||||
{
|
||||
return (iref->val_len != sizeof(struct scoutfs_mounted_client_btree_val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a new mounted client item for a client that is sending us a
|
||||
* greeting that hasn't yet seen a response. The greeting can be
|
||||
* retransmitted to a new server after the previous inserted the item so
|
||||
* it's acceptable to see -EEXIST.
|
||||
*/
|
||||
static int insert_mounted_client(struct super_block *sb, u64 rid,
|
||||
u64 gr_flags)
|
||||
static int insert_mounted_client(struct super_block *sb, u64 rid, u64 gr_flags,
|
||||
struct sockaddr_in *sin)
|
||||
{
|
||||
DECLARE_SERVER_INFO(sb, server);
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
@@ -1469,6 +1474,7 @@ static int insert_mounted_client(struct super_block *sb, u64 rid,
|
||||
int ret;
|
||||
|
||||
init_mounted_client_key(&key, rid);
|
||||
scoutfs_sin_to_addr(&mcv.addr, sin);
|
||||
mcv.flags = 0;
|
||||
if (gr_flags & SCOUTFS_NET_GREETING_FLAG_QUORUM)
|
||||
mcv.flags |= SCOUTFS_MOUNTED_CLIENT_QUORUM;
|
||||
@@ -1484,6 +1490,34 @@ static int insert_mounted_client(struct super_block *sb, u64 rid,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lookup_mounted_client_addr(struct super_block *sb, u64 rid,
|
||||
union scoutfs_inet_addr *addr)
|
||||
{
|
||||
DECLARE_SERVER_INFO(sb, server);
|
||||
struct scoutfs_super_block *super = &SCOUTFS_SB(sb)->super;
|
||||
struct scoutfs_mounted_client_btree_val *mcv;
|
||||
SCOUTFS_BTREE_ITEM_REF(iref);
|
||||
struct scoutfs_key key;
|
||||
int ret;
|
||||
|
||||
init_mounted_client_key(&key, rid);
|
||||
|
||||
mutex_lock(&server->mounted_clients_mutex);
|
||||
ret = scoutfs_btree_lookup(sb, &super->mounted_clients, &key, &iref);
|
||||
if (ret == 0) {
|
||||
if (invalid_mounted_client_item(&iref)) {
|
||||
ret = -EIO;
|
||||
} else {
|
||||
mcv = iref.val;
|
||||
*addr = mcv->addr;
|
||||
}
|
||||
scoutfs_btree_put_iref(&iref);
|
||||
}
|
||||
mutex_unlock(&server->mounted_clients_mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the record of a mounted client. The record can already be
|
||||
* removed if we're processing a farewell on behalf of a client that
|
||||
@@ -1622,8 +1656,8 @@ static int server_greeting(struct super_block *sb,
|
||||
if (ret < 0)
|
||||
goto send_err;
|
||||
|
||||
ret = insert_mounted_client(sb, le64_to_cpu(gr->rid),
|
||||
le64_to_cpu(gr->flags));
|
||||
ret = insert_mounted_client(sb, le64_to_cpu(gr->rid), le64_to_cpu(gr->flags),
|
||||
&conn->peername);
|
||||
|
||||
ret = scoutfs_server_apply_commit(sb, ret);
|
||||
queue_work(server->wq, &server->farewell_work);
|
||||
@@ -1680,11 +1714,6 @@ struct farewell_request {
|
||||
u64 rid;
|
||||
};
|
||||
|
||||
static bool invalid_mounted_client_item(struct scoutfs_btree_item_ref *iref)
|
||||
{
|
||||
return (iref->val_len !=
|
||||
sizeof(struct scoutfs_mounted_client_btree_val));
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim all the resources for a mount which has gone away. It's sent
|
||||
@@ -2040,20 +2069,30 @@ static void fence_pending_recov_worker(struct work_struct *work)
|
||||
struct server_info *server = container_of(work, struct server_info,
|
||||
fence_pending_recov_work);
|
||||
struct super_block *sb = server->sb;
|
||||
union scoutfs_inet_addr addr;
|
||||
u64 rid = 0;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
|
||||
while ((rid = scoutfs_recov_next_pending(sb, rid, SCOUTFS_RECOV_ALL)) > 0) {
|
||||
scoutfs_err(sb, "%lu ms recovery timeout expired for client rid %016llx, fencing",
|
||||
SERVER_RECOV_TIMEOUT_MS, rid);
|
||||
|
||||
ret = scoutfs_fence_start(sb, rid, 0, SCOUTFS_FENCE_CLIENT_RECOVERY);
|
||||
if (ret) {
|
||||
ret = lookup_mounted_client_addr(sb, rid, &addr);
|
||||
if (ret < 0) {
|
||||
scoutfs_err(sb, "client rid addr lookup err %d, shutting down server", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = scoutfs_fence_start(sb, rid, le32_to_be32(addr.v4.addr),
|
||||
SCOUTFS_FENCE_CLIENT_RECOVERY);
|
||||
if (ret < 0) {
|
||||
scoutfs_err(sb, "fence returned err %d, shutting down server", ret);
|
||||
scoutfs_server_abort(sb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
scoutfs_server_abort(sb);
|
||||
}
|
||||
|
||||
static void recovery_timeout(struct super_block *sb)
|
||||
|
||||
@@ -372,9 +372,13 @@ static int print_mounted_client_entry(struct scoutfs_key *key, void *val,
|
||||
unsigned val_len, void *arg)
|
||||
{
|
||||
struct scoutfs_mounted_client_btree_val *mcv = val;
|
||||
struct in_addr in;
|
||||
|
||||
printf(" rid %016llx flags 0x%x\n",
|
||||
le64_to_cpu(key->skmc_rid), mcv->flags);
|
||||
memset(&in, 0, sizeof(in));
|
||||
in.s_addr = htonl(le32_to_cpu(mcv->addr.v4.addr));
|
||||
|
||||
printf(" rid %016llx ipv4_addr %s flags 0x%x\n",
|
||||
le64_to_cpu(key->skmc_rid), inet_ntoa(in), mcv->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user