From 3484965b89374c5a03547185a81564d8d554c4bd Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Sun, 28 Jun 2026 23:35:44 +0200 Subject: [PATCH] Align data disk UUID validation and write logic with parity splits using content_uuid --- cmdline/elem.c | 2 +- cmdline/elem.h | 2 +- cmdline/state.c | 35 +++++++++++++++++++++++------------ 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/cmdline/elem.c b/cmdline/elem.c index 9e19471f..7e86b99b 100644 --- a/cmdline/elem.c +++ b/cmdline/elem.c @@ -1550,7 +1550,7 @@ struct snapraid_map* map_alloc(const char* name, unsigned position, block_off_t map->position = position; map->total_blocks = total_blocks; map->free_blocks = free_blocks; - pathcpy(map->uuid, sizeof(map->uuid), uuid); + pathcpy(map->content_uuid, sizeof(map->content_uuid), uuid); return map; } diff --git a/cmdline/elem.h b/cmdline/elem.h index 6e1d9f86..10d9d8be 100644 --- a/cmdline/elem.h +++ b/cmdline/elem.h @@ -485,7 +485,7 @@ struct snapraid_disk { */ struct snapraid_map { char name[PATH_MAX]; /**< Name of the disk. */ - char uuid[UUID_MAX]; /**< UUID of the disk. Empty if unknown. They are read from the content file. */ + char content_uuid[UUID_MAX]; /**< UUID of the disk. Empty if unknown. They are read from the content file. */ block_off_t total_blocks; /**< Number of total blocks. */ block_off_t free_blocks; /**< Number of free blocks at last 'sync'. */ unsigned position; /**< Position of the disk in the parity. */ diff --git a/cmdline/state.c b/cmdline/state.c index d3719065..bdecdce3 100644 --- a/cmdline/state.c +++ b/cmdline/state.c @@ -1774,21 +1774,21 @@ static void state_map(struct snapraid_state* state) /* LCOV_EXCL_STOP */ } - if (disk->has_unsupported_uuid) { + if (disk->uuid[0] == 0) { /* if uuid is not available, skip this one */ continue; } /* if the uuid is changed */ - if (strcmp(disk->uuid, map->uuid) != 0) { + if (strcmp(disk->uuid, map->content_uuid) != 0) { /* mark the disk as with an UUID change */ disk->has_different_uuid = 1; /* if the previous uuid is available */ - if (map->uuid[0] != 0) { + if (map->content_uuid[0] != 0) { /* count the number of uuid change */ ++uuid_mismatch; - log_error(ESOFT, "UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, disk->uuid); + log_error(ESOFT, "UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->content_uuid, disk->uuid); } else { /* * No message here, because having a disk without @@ -1797,9 +1797,6 @@ static void state_map(struct snapraid_state* state) disk->had_empty_uuid = 1; } - /* update the uuid in the mapping, */ - pathcpy(map->uuid, sizeof(map->uuid), disk->uuid); - /* write the new state with the new uuid */ state->need_write = 1; } @@ -1810,8 +1807,8 @@ static void state_map(struct snapraid_state* state) if (!state->opt.skip_parity_access) { for (l = 0; l < state->level; ++l) { for (s = 0; s < state->parity[l].split_mac; ++s) { - /* if uuid is not available, just ignore */ if (state->parity[l].split_map[s].uuid[0] == 0) { + /* if uuid is not available, skip this one */ continue; } @@ -3648,12 +3645,26 @@ static void* state_write_thread(void* arg) /* save the mapping only if disk is mapped */ if (disk->mapping_idx != -1) { + const char* uuid; + sputc('M', f); sputbs(map->name, f); sputb32(map->position, f); sputb64(map->total_blocks, f); sputb64(map->free_blocks, f); - sputbs(map->uuid, f); + + /* + * If the probed uuid is empty, but disk access was skipped (globally + * or individually), write the last known uuid. Otherwise, write the + * empty probed uuid. + */ + if (disk->uuid[0] == 0 && (state->opt.skip_disk_access || disk->skip_access)) { + uuid = map->content_uuid; + } else { + uuid = disk->uuid; + } + sputbs(uuid, f); + if (context->first) { log_tag("content_data:%s:%" PRIi64 ":%" PRIi64 "\n", esc_tag(map->name), @@ -3661,7 +3672,7 @@ static void* state_write_thread(void* arg) map->free_blocks * (uint64_t)state->block_size); log_tag("content_data_split:%s:%s\n", esc_tag(map->name), - map->uuid); + uuid); } if (serror(f)) { /* LCOV_EXCL_START */ @@ -5801,8 +5812,8 @@ void generate_configuration(const char* path) struct snapraid_map* map = j->data; struct snapraid_disk* disk; printf("# Set the correct dir for disk '%s'\n", map->name); - if (map->uuid[0]) - printf("# Disk '%s' is the one with id '%s'\n", map->name, map->uuid); + if (map->content_uuid[0]) + printf("# Disk '%s' is the one with id '%s'\n", map->name, map->content_uuid); disk = find_disk_by_name(&state, map->name); if (disk && disk->filelist) { struct snapraid_file* file = disk->filelist->data;