[PATCH 1/1] erofs-utils: mount: auto-detect platform for OCI recovery files

Chengyu hudson at cyzhu.com
Fri Feb 27 14:34:44 AEDT 2026


From: Chengyu Zhu <hudsonzhu at tencent.com>

erofsmount_write_recovery_oci() writes source->ocicfg.platform into
recovery files directly, but it could be NULL when not explicitly
configured, causing reattach failures.

Fix this by falling back to ocierofs_get_platform_spec().  Also
refactor it to return a compile-time string literal instead of
asprintf(), eliminating the need for callers to free() the result.

Signed-off-by: Chengyu Zhu <hudsonzhu at tencent.com>
---
 lib/liberofs_oci.h |  1 +
 lib/remotes/oci.c  | 55 +++++++++++++++-------------------------------
 mount/main.c       | 11 +++++++---
 3 files changed, 27 insertions(+), 40 deletions(-)

diff --git a/lib/liberofs_oci.h b/lib/liberofs_oci.h
index 9e0571f..2243c82 100644
--- a/lib/liberofs_oci.h
+++ b/lib/liberofs_oci.h
@@ -80,6 +80,7 @@ int ocierofs_io_open(struct erofs_vfile *vf, const struct ocierofs_config *cfg);
 
 char *ocierofs_encode_userpass(const char *username, const char *password);
 int ocierofs_decode_userpass(const char *b64, char **out_user, char **out_pass);
+const char *ocierofs_get_platform_spec(void);
 
 #ifdef __cplusplus
 }
diff --git a/lib/remotes/oci.c b/lib/remotes/oci.c
index e5b2f7c..47e8b27 100644
--- a/lib/remotes/oci.c
+++ b/lib/remotes/oci.c
@@ -1109,54 +1109,38 @@ static int ocierofs_parse_ref(struct ocierofs_ctx *ctx, const char *ref_str)
 	return 0;
 }
 
-static char *ocierofs_get_platform_spec(void)
+const char *ocierofs_get_platform_spec(void)
 {
-	const char *os = NULL, *arch = NULL, *variant = NULL;
-	char *platform;
-
 #if defined(__linux__)
-	os = "linux";
+#define EROFS_OCI_OS "linux"
 #elif defined(__APPLE__)
-	os = "darwin";
+#define EROFS_OCI_OS "darwin"
 #elif defined(_WIN32)
-	os = "windows";
+#define EROFS_OCI_OS "windows"
 #elif defined(__FreeBSD__)
-	os = "freebsd";
+#define EROFS_OCI_OS "freebsd"
 #endif
 
 #if defined(__x86_64__) || defined(__amd64__)
-	arch = "amd64";
+	return EROFS_OCI_OS "/amd64";
 #elif defined(__aarch64__) || defined(__arm64__)
-	arch = "arm64";
-	variant = "v8";
+	return EROFS_OCI_OS "/arm64/v8";
 #elif defined(__i386__)
-	arch = "386";
+	return EROFS_OCI_OS "/386";
 #elif defined(__arm__)
-	arch = "arm";
-	variant = "v7";
+	return EROFS_OCI_OS "/arm/v7";
 #elif defined(__riscv) && (__riscv_xlen == 64)
-	arch = "riscv64";
+	return EROFS_OCI_OS "/riscv64";
+#elif defined(__ppc64__) && defined(__BYTE_ORDER__) && \
+	  (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+	return EROFS_OCI_OS "/ppc64le";
 #elif defined(__ppc64__)
-#if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
-	arch = "ppc64le";
-#else
-	arch = "ppc64";
-#endif
+	return EROFS_OCI_OS "/ppc64";
 #elif defined(__s390x__)
-	arch = "s390x";
+	return EROFS_OCI_OS "/s390x";
+#else
+	return NULL;
 #endif
-
-	if (!os || !arch)
-		return NULL;
-
-	if (variant) {
-		if (asprintf(&platform, "%s/%s/%s", os, arch, variant) < 0)
-			return NULL;
-	} else {
-		if (asprintf(&platform, "%s/%s", os, arch) < 0)
-			return NULL;
-	}
-	return platform;
 }
 
 /**
@@ -1187,10 +1171,7 @@ static int ocierofs_init(struct ocierofs_ctx *ctx, const struct ocierofs_config
 		ctx->blob_digest = NULL;
 	ctx->registry = strdup("registry-1.docker.io");
 	ctx->tag = strdup("latest");
-	if (config->platform)
-		ctx->platform = strdup(config->platform);
-	else
-		ctx->platform = ocierofs_get_platform_spec();
+	ctx->platform = strdup(config->platform ?: ocierofs_get_platform_spec());
 	if (!ctx->registry || !ctx->tag || !ctx->platform)
 		return -ENOMEM;
 
diff --git a/mount/main.c b/mount/main.c
index 3530b2c..b04be5d 100644
--- a/mount/main.c
+++ b/mount/main.c
@@ -717,6 +717,7 @@ out_closefd:
 static int erofsmount_write_recovery_oci(FILE *f, struct erofs_nbd_source *source)
 {
 	char *b64cred = NULL;
+	const char *platform;
 	int ret;
 
 	if (source->ocicfg.username || source->ocicfg.password) {
@@ -726,11 +727,15 @@ static int erofsmount_write_recovery_oci(FILE *f, struct erofs_nbd_source *sourc
 			return PTR_ERR(b64cred);
 	}
 
+	platform = source->ocicfg.platform;
+	if (!platform || !*platform)
+		platform = ocierofs_get_platform_spec();
+
 	if ((source->ocicfg.tarindex_path || source->ocicfg.zinfo_path) &&
 	    source->ocicfg.blob_digest && *source->ocicfg.blob_digest) {
 		ret = fprintf(f, "TARINDEX_OCI_BLOB %s %s %s %s %s %s\n",
 			      source->ocicfg.image_ref ?: "",
-			      source->ocicfg.platform ?: "",
+			      platform ?: "",
 			      source->ocicfg.blob_digest,
 			      b64cred ?: "",
 			      source->ocicfg.tarindex_path ?: "",
@@ -742,7 +747,7 @@ static int erofsmount_write_recovery_oci(FILE *f, struct erofs_nbd_source *sourc
 	if (source->ocicfg.blob_digest && *source->ocicfg.blob_digest) {
 		ret = fprintf(f, "OCI_NATIVE_BLOB %s %s %s %s\n",
 			      source->ocicfg.image_ref ?: "",
-			      source->ocicfg.platform ?: "",
+			      platform ?: "",
 			      source->ocicfg.blob_digest,
 			      b64cred ?: "");
 		free(b64cred);
@@ -752,7 +757,7 @@ static int erofsmount_write_recovery_oci(FILE *f, struct erofs_nbd_source *sourc
 	if (source->ocicfg.layer_index >= 0) {
 		ret = fprintf(f, "OCI_LAYER %s %s %d %s\n",
 			      source->ocicfg.image_ref ?: "",
-			      source->ocicfg.platform ?: "",
+			      platform ?: "",
 			      source->ocicfg.layer_index,
 			      b64cred ?: "");
 		free(b64cred);
-- 
2.47.1



More information about the Linux-erofs mailing list