[PATCH v1] erofs-utils:mount: add OCI recovery support for NBD reattach
ChengyuZhu6
hudson at cyzhu.com
Tue Sep 9 17:09:09 AEST 2025
From: Chengyu Zhu <hudsonzhu at tencent.com>
This commit implements recovery support for OCI-based NBD mounts,
allowing the system to properly reattach NBD devices after
NBD disconnection.
Signed-off-by: Chengyu Zhu <hudsonzhu at tencent.com>
---
mount/main.c | 100 ++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 75 insertions(+), 25 deletions(-)
diff --git a/mount/main.c b/mount/main.c
index c52ac3b..37e9f6d 100644
--- a/mount/main.c
+++ b/mount/main.c
@@ -401,12 +401,14 @@ out_closefd:
return err;
}
-static char *erofsmount_write_recovery_info(const char *source)
+static char *erofsmount_write_recovery_info(struct erofs_nbd_source *source)
{
char recp[] = "/var/run/erofs/mountnbd_XXXXXX";
char *realp;
int fd, err;
FILE *f;
+ char *content = NULL;
+ int ret;
fd = mkstemp(recp);
if (fd < 0 && errno == ENOENT) {
@@ -424,15 +426,32 @@ static char *erofsmount_write_recovery_info(const char *source)
return ERR_PTR(-errno);
}
- realp = realpath(source, NULL);
- if (!realp) {
- fclose(f);
- return ERR_PTR(-errno);
+ if (source->type == EROFSNBD_SOURCE_OCI) {
+ ret = asprintf(&content, "%s %s %s %s %d",
+ source->ocicfg.image_ref ?: "",
+ source->ocicfg.platform ?: "",
+ source->ocicfg.username ?: "",
+ source->ocicfg.password ?: "",
+ source->ocicfg.layer_index);
+ if (ret < 0) {
+ fclose(f);
+ return ERR_PTR(-ENOMEM);
+ }
+ err = fprintf(f, "OCI_LAYER %s\n", content) < 0;
+ free(content);
+ } else {
+ realp = realpath(source->device_path, NULL);
+ if (!realp) {
+ fclose(f);
+ return ERR_PTR(-errno);
+ }
+
+ /* TYPE<LOCAL> <SOURCE PATH>\n(more..) */
+ err = fprintf(f, "LOCAL %s\n", realp) < 0;
+ free(realp);
}
- /* TYPE<LOCAL> <SOURCE PATH>\n(more..) */
- err = fprintf(f, "LOCAL %s\n", realp) < 0;
+
fclose(f);
- free(realp);
if (err)
return ERR_PTR(-ENOMEM);
return strdup(recp) ?: ERR_PTR(-ENOMEM);
@@ -491,15 +510,10 @@ static int erofsmount_startnbd_nl(pid_t *pid, struct erofs_nbd_source *source)
exit(EXIT_FAILURE);
ctx.vd.fd = err;
}
-
- if (source->type == EROFSNBD_SOURCE_LOCAL) {
- recp = erofsmount_write_recovery_info(source->device_path);
- if (IS_ERR(recp)) {
- erofs_io_close(&ctx.vd);
- exit(EXIT_FAILURE);
- }
- } else {
- recp = NULL;
+ recp = erofsmount_write_recovery_info(source);
+ if (IS_ERR(recp)) {
+ erofs_io_close(&ctx.vd);
+ exit(EXIT_FAILURE);
}
num = -1;
@@ -595,19 +609,55 @@ static int erofsmount_reattach(const char *target)
*(source++) = '\0';
}
- if (strcmp(line, "LOCAL")) {
+ if (!strcmp(line, "LOCAL")) {
+ err = open(source, O_RDONLY);
+ if (err < 0) {
+ err = -errno;
+ goto err_line;
+ }
+ ctx.vd.fd = err;
+ } else if (!strcmp(line, "OCI_LAYER")) {
+ struct ocierofs_config oci_cfg = {};
+ char *platform, *username, *password, *layer_str;
+ int layer_index;
+
+ platform = strchr(source, ' ');
+ if (platform) {
+ *platform++ = '\0';
+ oci_cfg.image_ref = source;
+ oci_cfg.platform = platform;
+ } else {
+ oci_cfg.image_ref = source;
+ }
+
+ username = strchr(platform ?: source, ' ');
+ if (username) {
+ *username++ = '\0';
+ oci_cfg.username = username;
+ }
+
+ password = strchr(username ?: (platform ?: source), ' ');
+ if (password) {
+ *password++ = '\0';
+ oci_cfg.password = password;
+ }
+
+ layer_str = strchr(password ?: (username ?: (platform ?: source)), ' ');
+ if (layer_str) {
+ *layer_str++ = '\0';
+ layer_index = atoi(layer_str);
+ oci_cfg.layer_index = layer_index;
+ }
+
+ err = ocierofs_io_open(&ctx.vd, &oci_cfg);
+ if (err < 0)
+ goto err_line;
+ } else {
err = -EOPNOTSUPP;
erofs_err("unsupported source type %s recorded in recovery file", line);
goto err_line;
}
- err = open(source, O_RDONLY);
- if (err < 0) {
- err = -errno;
- goto err_line;
- }
- ctx.vd.fd = err;
-
err = erofs_nbd_nl_reconnect(nbdnum, identifier);
if (err >= 0) {
ctx.sk.fd = err;
--
2.51.0
More information about the Linux-erofs
mailing list