[PATCH v2] erofs-utils: oci: add support for indexing by layer digest
Gao Xiang
hsiangkao at linux.alibaba.com
Thu Sep 18 12:27:10 AEST 2025
On 2025/9/16 23:34, ChengyuZhu6 wrote:
> From: Chengyu Zhu <hudsonzhu at tencent.com>
>
> Add support for indexing by layer_digest string for more precise
> and reliable OCI layer identification. This change affects both mkfs.erofs
> and mount.erofs tools.
>
> Signed-off-by: Chengyu Zhu <hudsonzhu at tencent.com>
> ---
> lib/liberofs_oci.h | 6 +-
> lib/remotes/oci.c | 89 +++++++++++++++++++------
> mkfs/main.c | 75 +++++++++++++--------
> mount/main.c | 160 +++++++++++++++++++++++++++++++++------------
> 4 files changed, 240 insertions(+), 90 deletions(-)
>
> diff --git a/lib/liberofs_oci.h b/lib/liberofs_oci.h
> index aa41141..621eb2b 100644
> --- a/lib/liberofs_oci.h
> +++ b/lib/liberofs_oci.h
> @@ -21,7 +21,8 @@ struct erofs_importer;
> * @platform: target platform in "os/arch" format (e.g., "linux/amd64")
> * @username: username for authentication (optional)
> * @password: password for authentication (optional)
> - * @layer_index: specific layer to extract (-1 for all layers)
> + * @layer_digest: specific layer digest to extract (NULL for all layers)
> + * @layer_index: specific layer index to extract (negative for all layers)
> *
> * Configuration structure for OCI image parameters including registry
> * location, image identification, platform specification, and authentication
> @@ -32,6 +33,7 @@ struct ocierofs_config {
> char *platform;
> char *username;
> char *password;
> + char *layer_digest;
> int layer_index;
> };
>
> @@ -51,7 +53,7 @@ struct ocierofs_ctx {
> char *tag;
> char *manifest_digest;
> struct ocierofs_layer_info **layers;
> - int layer_index;
> + char *layer_digest;
> int layer_count;
> };
>
> diff --git a/lib/remotes/oci.c b/lib/remotes/oci.c
> index 26aec27..d22aa2e 100644
> --- a/lib/remotes/oci.c
> +++ b/lib/remotes/oci.c
> @@ -898,6 +898,21 @@ static int ocierofs_prepare_auth(struct ocierofs_ctx *ctx,
> return 0;
> }
>
> +static int ocierofs_find_layer_by_digest(struct ocierofs_ctx *ctx, const char *digest)
> +{
> + int i;
> +
> + if (!digest || !ctx->layers)
> + return -1;
It's an internal function, let's not check input argument validity (`digest`).
Or if users misuse an internal function, I'd rather to have a coredump instead
of slient failure.
In principle, `ctx->layers` won't be NULL here too (if ctx->layer_count > 0),
if it really needs to check, I suggest using `DBG_BUGON(!ctx->layers)` or
just get rid of this check.
> +
> + for (i = 0; i < ctx->layer_count; i++) {
DBG_BUGON(!ctx->layers[i]);
DBG_BUGON(!ctx->layers[i]->digest);
if (!strcmp(ctx->layers[i]->digest, digest))
return i;
> + if (ctx->layers[i] && ctx->layers[i]->digest &&
> + !strcmp(ctx->layers[i]->digest, digest))
> + return i;
> + }
> + return -1;
> +}
> +
> static int ocierofs_prepare_layers(struct ocierofs_ctx *ctx,
> const struct ocierofs_config *config)
> {
> @@ -925,16 +940,35 @@ static int ocierofs_prepare_layers(struct ocierofs_ctx *ctx,
> goto out_manifest;
> }
>
> - if (ctx->layer_index >= ctx->layer_count) {
> - erofs_err("layer index %d exceeds available layers (%d)",
> - ctx->layer_index, ctx->layer_count);
> - ret = -EINVAL;
> - goto out_layers;
> + if (config->layer_index >= 0) {
> + if (config->layer_index >= ctx->layer_count) {
> + erofs_err("layer index %d out of range (0..%d)",
> + config->layer_index, ctx->layer_count - 1);
> + ret = -EINVAL;
> + goto out_layers;
> + }
> + if (!ctx->layers[config->layer_index] ||
> + !ctx->layers[config->layer_index]->digest) {
> + ret = -EINVAL;
> + goto out_layers;
> + }
DBG_BUGON(!ctx->layers[config->layer_index]);
DBG_BUGON(!ctx->layers[config->layer_index]->digest);
> + ctx->layer_digest = strdup(ctx->layers[config->layer_index]->digest);
> + if (!ctx->layer_digest) {
> + ret = -ENOMEM;
> + goto out_layers;
> + }
> + } else if (ctx->layer_digest) {
> + if (ocierofs_find_layer_by_digest(ctx, ctx->layer_digest) < 0) {
} else if (ctx->layer_digest &&
ocierofs_find_layer_by_digest(ctx, ctx->layer_digest) < 0) {
erofs_err("layer digest %s not found in image layers",
ctx->layer_digest);
ret = -ENOENT;
goto out_layers;
}
...
> -/* Parse input string in format: "image_ref platform layer [b64cred]" */
> +/* Parse input string in format: "image_ref platform layer [b64cred]"
> + * where layer is one of:
> + * - "digest:<sha256...>" (layer_digest)
> + * - "index:<N>" (layer_index)
> + * - "" (no specific layer)
can we just add another tag for this?
OCI_LAYER and OCI_DIGEST
Thanks,
Gao Xiang
More information about the Linux-erofs
mailing list