From 7a21d264c7c74cf939f57fa93d1622af29a3b560 Mon Sep 17 00:00:00 2001 From: Evgeny Sinelnikov Date: Mon, 29 Mar 2021 06:05:48 +0400 Subject: [PATCH] cdrom.c, tools.{h.c}: Add support 'fuid' automatic mode option for method cdrom The installed system can have several devices with the same structure. The automatic 'fuid' option can be used to detach one from the other to find the partition where our stage2 image is stored, launched from stage1 (in this case propagator). This option works automatically with the cdrom method: - automatic=method:cdrom,fuid:PATH_TO_UNIQ_UID_FILENAME --- cdrom.c | 25 +++++++++++++++++++++++-- tools.c | 13 +++++++++++++ tools.h | 1 + 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/cdrom.c b/cdrom.c index 5e118ea..9864b73 100644 --- a/cdrom.c +++ b/cdrom.c @@ -35,6 +35,7 @@ #include "probing.h" #include "log.h" #include "mount.h" +#include "automatic.h" #include "cdrom.h" #include "init.h" @@ -88,6 +89,26 @@ done: return rc; } +/* test_that_cd_with_file_uid() returns 0 on success, using in automatic mode */ +static int test_that_cd_with_file_uid(const char * dev_name, const char * dev_model) +{ + const char *uid_file = get_auto_value("fuid"); + char *uid_file_path = get_uid_file_path(NULL, uid_file); + int rc; + + if (uid_file_path != NULL && access(uid_file_path, R_OK)) { + log_message("skip device /dev/%s %s without uid file %s", dev_name, dev_model, uid_file); + rc = -1; + goto done; + } + + rc = test_that_cd(1); + +done: + if (uid_file_path != NULL) + free(uid_file_path); + return rc; +} static enum return_type try_with_device(char * dev_name, char * dev_model); @@ -186,7 +207,7 @@ int try_automatic(char ** medias, char ** medias_models) wait_message("Trying to access media in drive %s", *model); if (mount_that_cd_device(*ptr) != -1) { - if (!test_that_cd(1)) { + if (!test_that_cd_with_file_uid(*ptr, *model)) { remove_wait_message(); return i; } @@ -271,7 +292,7 @@ enum return_type cdrom_prepare(void) log_message("mount device /dev/%s %s failed", medias[i], medias_models[i]); } if (automatic_result != RETURN_OK) - return automatic_result; + break; } ptr = medias; diff --git a/tools.c b/tools.c index c8e7f7b..bbe6289 100644 --- a/tools.c +++ b/tools.c @@ -414,6 +414,19 @@ char * get_ramdisk_path(const char *mount_path) return strdup(img_name); } +char * get_uid_file_path(const char *mount_path, const char *uid_file) +{ + char file_name[500]; + + /* return NULL for empty file uid */ + if (!uid_file || uid_file[0] == '\0') + return NULL; + /* FIXME */ + strcpy(file_name, mount_path ? mount_path : IMAGE_LOCATION "/"); + strcat(file_name, uid_file); + return strdup(file_name); +} + /* This function is used to protect against stage2 (aka ramdisk) spoofing */ enum return_type verify_ramdisk_digest(const char *filename, const char *sha256_hash) { diff --git a/tools.h b/tools.h index f54919f..19b095d 100644 --- a/tools.h +++ b/tools.h @@ -45,6 +45,7 @@ char ** list_directory(char * direct); int string_array_length(char ** a); int do_losetup(char * device, char * target); char * get_ramdisk_path(const char *); +char * get_uid_file_path(const char *, const char *); enum return_type verify_ramdisk_digest(const char *filename, const char *sha256_hash); int splash_verbose(); int update_splash(char * state);