From: Chengyu Zhu <hudson...@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 <hudson...@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