[PATCH 2/4] erofs-utils: lib: nbd: add support for the netlink reconnection
Gao Xiang
hsiangkao at linux.alibaba.com
Wed Sep 3 01:06:08 AEST 2025
In order to support NBD failover.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/backends/nbd.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++
lib/liberofs_nbd.h | 4 ++
2 files changed, 97 insertions(+)
diff --git a/lib/backends/nbd.c b/lib/backends/nbd.c
index 7058a81..9b56a56 100644
--- a/lib/backends/nbd.c
+++ b/lib/backends/nbd.c
@@ -174,6 +174,26 @@ err_out:
return err;
}
+char *erofs_nbd_get_identifier(int nbdnum)
+{
+ char s[32], *line = NULL;
+ size_t n;
+ FILE *f;
+ int err;
+
+ (void)snprintf(s, sizeof(s), "/sys/block/nbd%d/backend", nbdnum);
+ f = fopen(s, "r");
+ if (!f)
+ return ERR_PTR(-errno);
+
+ if (getline(&line, &n, f) < 0)
+ err = -errno;
+ else
+ err = 0;
+ fclose(f);
+ return err ? ERR_PTR(err) : line;
+}
+
#if defined(HAVE_NETLINK_GENL_GENL_H) && defined(HAVE_LIBNL_GENL_3)
enum {
NBD_ATTR_UNSPEC,
@@ -209,6 +229,7 @@ enum {
NBD_CMD_UNSPEC,
NBD_CMD_CONNECT,
NBD_CMD_DISCONNECT,
+ NBD_CMD_RECONFIGURE,
__NBD_CMD_MAX,
};
@@ -312,6 +333,7 @@ int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
NLA_PUT_U64(msg, NBD_ATTR_SIZE_BYTES, blocks << blkbits);
NLA_PUT_U64(msg, NBD_ATTR_SERVER_FLAGS, NBD_FLAG_READ_ONLY);
NLA_PUT_U64(msg, NBD_ATTR_TIMEOUT, 0);
+ NLA_PUT_U64(msg, NBD_ATTR_DEAD_CONN_TIMEOUT, EROFS_NBD_DEAD_CONN_TIMEOUT);
if (identifier)
NLA_PUT_STRING(msg, NBD_ATTR_BACKEND_IDENTIFIER, identifier);
@@ -339,6 +361,72 @@ int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
return cbctx.errcode;
return sv[0];
+nla_put_failure:
+ nla_nest_cancel(msg, sock_opt);
+ nla_nest_cancel(msg, sock_attr);
+err_nlm_free:
+ nlmsg_free(msg);
+err_nls_free:
+ nl_socket_free(socket);
+err_out:
+ close(sv[0]);
+ close(sv[1]);
+ return err;
+}
+
+int erofs_nbd_nl_reconnect(int index, const char *identifier)
+{
+ struct nlattr *sock_attr, *sock_opt;
+ struct nl_sock *socket;
+ struct nl_msg *msg;
+ int sv[2], err;
+ int driver_id;
+
+ err = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
+ if (err < 0)
+ return -errno;
+
+ socket = erofs_nbd_get_nl_sock(&driver_id);
+ if (IS_ERR(socket)) {
+ err = PTR_ERR(socket);
+ goto err_out;
+ }
+
+ msg = nlmsg_alloc();
+ if (!msg) {
+ erofs_err("Couldn't allocate netlink message");
+ err = -ENOMEM;
+ goto err_nls_free;
+ }
+
+ genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, 0,
+ NBD_CMD_RECONFIGURE, 0);
+ NLA_PUT_U32(msg, NBD_ATTR_INDEX, index);
+ if (identifier)
+ NLA_PUT_STRING(msg, NBD_ATTR_BACKEND_IDENTIFIER, identifier);
+
+ err = -EINVAL;
+ sock_attr = nla_nest_start(msg, NBD_ATTR_SOCKETS);
+ if (!sock_attr) {
+ erofs_err("Couldn't nest the sockets for our connection");
+ goto err_nlm_free;
+ }
+
+ sock_opt = nla_nest_start(msg, NBD_SOCK_ITEM);
+ if (!sock_attr) {
+ nla_nest_cancel(msg, sock_attr);
+ goto err_nlm_free;
+ }
+ NLA_PUT_U32(msg, NBD_SOCK_FD, sv[1]);
+ nla_nest_end(msg, sock_opt);
+ nla_nest_end(msg, sock_attr);
+
+ err = nl_send_sync(socket, msg);
+ if (err)
+ goto err_out;
+ nl_socket_free(socket);
+ return sv[0];
+
nla_put_failure:
nla_nest_cancel(msg, sock_opt);
nla_nest_cancel(msg, sock_attr);
@@ -357,6 +445,11 @@ int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
{
return -EOPNOTSUPP;
}
+
+int erofs_nbd_nl_reconnect(int index, const char *identifier)
+{
+ return -EOPNOTSUPP;
+}
#endif
int erofs_nbd_do_it(int nbdfd)
diff --git a/lib/liberofs_nbd.h b/lib/liberofs_nbd.h
index 89c4cf2..03886de 100644
--- a/lib/liberofs_nbd.h
+++ b/lib/liberofs_nbd.h
@@ -31,6 +31,9 @@ struct erofs_nbd_request {
u32 len;
} __packed;
+/* 30-day timeout for NBD recovery */
+#define EROFS_NBD_DEAD_CONN_TIMEOUT (3600 * 24 * 30)
+
long erofs_nbd_in_service(int nbdnum);
int erofs_nbd_devscan(void);
int erofs_nbd_connect(int nbdfd, int blkbits, u64 blocks);
@@ -41,4 +44,5 @@ int erofs_nbd_disconnect(int nbdfd);
int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
const char *identifier);
+int erofs_nbd_nl_reconnect(int index, const char *identifier);
#endif
--
2.43.5
More information about the Linux-erofs
mailing list