[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