Store UUIDs in the disk element

This commit is contained in:
Andrea Mazzoleni 2015-12-28 12:09:13 +01:00
parent c80fd07058
commit 801d01c55b
3 changed files with 32 additions and 24 deletions

View file

@ -725,13 +725,14 @@ int dir_name_compare(const void* void_arg, const void* void_data)
return strcmp(arg, dir->sub);
}
struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip)
struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip)
{
struct snapraid_disk* disk;
disk = malloc_nofail(sizeof(struct snapraid_disk));
pathcpy(disk->name, sizeof(disk->name), name);
pathimport(disk->dir, sizeof(disk->dir), dir);
pathcpy(disk->uuid, sizeof(disk->uuid), uuid);
/* ensure that the dir terminate with "/" if it isn't empty */
pathslash(disk->dir, sizeof(disk->dir));
@ -745,7 +746,7 @@ struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev
disk->has_volatile_inodes = 0;
disk->has_unreliable_physical = 0;
disk->has_different_uuid = 0;
disk->has_unsupported_uuid = 0;
disk->has_unsupported_uuid = *uuid == 0; /* empty UUID means unsupported */
disk->had_empty_uuid = 0;
disk->mapping_idx = -1;
disk->skip_access = skip;

View file

@ -31,6 +31,11 @@
/****************************************************************************/
/* snapraid */
/**
* Max UUID length.
*/
#define UUID_MAX 128
/**
* Invalid position.
*/
@ -320,6 +325,8 @@ struct snapraid_disk {
char name[PATH_MAX]; /**< Name of the disk. */
char dir[PATH_MAX]; /**< Mount point of the disk. It always terminates with /. */
char smartctl[PATH_MAX]; /**< Custom command for smartctl. Empty means auto. */
char uuid[UUID_MAX]; /**< UUID of the disk. */
uint64_t device; /**< Device identifier. */
uint64_t tick; /**< Usage time of the disk. */
block_off_t total_blocks; /**< Number of total blocks. */
@ -378,11 +385,6 @@ struct snapraid_disk {
tommy_node node;
};
/**
* Max UUID length.
*/
#define UUID_MAX 128
/**
* Disk mapping.
*/
@ -866,7 +868,7 @@ static inline tommy_uint32_t dir_name_hash(const char* name)
/**
* Allocate a disk.
*/
struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip);
struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, const char* uuid, int skip);
/**
* Deallocate a disk.

View file

@ -785,6 +785,7 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
} else if (strcmp(tag, "disk") == 0) {
char dir[PATH_MAX];
char device[PATH_MAX];
char uuid[UUID_MAX];
struct snapraid_disk* disk;
uint64_t dev;
int skip_access;
@ -844,11 +845,23 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
if (stat(device, &st) == 0) {
dev = st.st_dev;
/* read the uuid, if unsupported use an empty one */
if (devuuid(dev, uuid, sizeof(uuid)) != 0) {
*uuid = 0;
}
/* fake a different UUID when testing */
if (state->opt.fake_uuid) {
snprintf(uuid, sizeof(uuid), "fake-uuid-%d", state->opt.fake_uuid);
--state->opt.fake_uuid;
}
} else {
/* if the disk can be skipped */
if (state->opt.force_device) {
/* use a fake device, and mark the disk to be skipped */
dev = 0;
*uuid = 0;
skip_access = 1;
log_fatal("DANGER! Skipping unaccessible data disk '%s'...\n", buffer);
} else {
@ -866,9 +879,10 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
} else {
/* use a fake device */
dev = 0;
*uuid = 0;
}
disk = disk_alloc(buffer, dir, dev, skip_access);
disk = disk_alloc(buffer, dir, dev, uuid, skip_access);
tommy_list_insert_tail(&state->disklist, &disk->node, disk);
} else if (strcmp(tag, "smartctl") == 0) {
@ -1155,7 +1169,7 @@ static struct snapraid_disk* find_disk(struct snapraid_state* state, const char*
/* without a configuration file, add disks automatically */
struct snapraid_disk* disk;
disk = disk_alloc(name, "DUMMY/", -1, 0);
disk = disk_alloc(name, "DUMMY/", -1, "", 0);
tommy_list_insert_tail(&state->disklist, &disk->node, disk);
@ -1255,8 +1269,6 @@ static void state_map(struct snapraid_state* state)
for (i = state->maplist; i != 0; i = i->next) {
struct snapraid_map* map = i->data;
struct snapraid_disk* disk;
char uuid[UUID_MAX];
int ret;
disk = find_disk(state, map->name);
if (disk == 0) {
@ -1266,20 +1278,13 @@ static void state_map(struct snapraid_state* state)
/* LCOV_EXCL_STOP */
}
ret = devuuid(disk->device, uuid, sizeof(uuid));
if (ret != 0) {
/* uuid not available, just ignore but marks the disk with unsupported UUID */
disk->has_unsupported_uuid = 1;
if (disk->has_unsupported_uuid) {
/* if uuid is not available, skip this one */
continue;
}
if (state->opt.fake_uuid) {
snprintf(uuid, sizeof(uuid), "fake-uuid-%d", state->opt.fake_uuid);
--state->opt.fake_uuid;
}
/* if the uuid is changed */
if (strcmp(uuid, map->uuid) != 0) {
if (strcmp(disk->uuid, map->uuid) != 0) {
/* mark the disk as with an UUID change */
disk->has_different_uuid = 1;
@ -1287,7 +1292,7 @@ static void state_map(struct snapraid_state* state)
if (map->uuid[0] != 0) {
/* count the number of uuid change */
++uuid_mismatch;
log_fatal("UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, uuid);
log_fatal("UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, disk->uuid);
} else {
/* no message here, because having a disk without */
/* UUID is the normal state of an empty disk */
@ -1295,7 +1300,7 @@ static void state_map(struct snapraid_state* state)
}
/* update the uuid in the mapping, */
pathcpy(map->uuid, sizeof(map->uuid), uuid);
pathcpy(map->uuid, sizeof(map->uuid), disk->uuid);
/* write the new state with the new uuid */
state->need_write = 1;