[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