Adds UUID to check to detect disk misplacement.

This commit is contained in:
Andrea Mazzoleni 2013-03-03 22:39:46 +01:00
parent 8810d7b05d
commit 768113c670
15 changed files with 272 additions and 34 deletions

View file

@ -19,6 +19,8 @@ SnapRAID HISTORY
exclusion rules.
* In 'check' and 'fix', if verbose is enabled, prints the result for each
processed file.
* Added an UUID check to detect when a disk is replaced, and to prevent
unwanted disk swaps.
2.1 2013/1
==========

7
TODO
View file

@ -28,6 +28,13 @@ on the error message. See: https://sourceforge.net/projects/snapraid/forums/foru
* In Windows to use FILE_FLAG_BACKUP_SEMANTICS we should also get privileges.
See http://www.codeproject.com/Articles/21202/Reparse-Points-in-Vista.
Altought it doesn't seem necessary when used in CreateFile to just open directory.
Anyway, see this snipset found with google:
DWORD access = 0;
DWORD share = FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE;
CreateFile(path1,access,share,NULL,OPEN_EXISTING,
(GetFileAttributes(path1)&FILE_ATTRIBUTE_DIRECTORY)?FILE_FLAG_BACKUP_SEMANTICS:0,NULL);
It seems to use it *exclusively* for directory.
Is it possible that the need of lstat_ex depends on that ?
* In Windows we must be case insensitive, at least for ASCII<128 comparison. For other UTF-8 chars
is too complex.

View file

@ -49,7 +49,7 @@ AC_SYS_LARGEFILE
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf])
AC_CHECK_FUNCS([ftruncate fallocate fsync access posix_fallocate posix_fadvise pread pwrite getc_unlocked ferror_unlocked fnmatch])
AC_CHECK_FUNCS([futimes futimens futimesat])
AC_CHECK_FUNCS([futimes futimens futimesat fstatat])
dnl Checks for architecture
AC_C_BIGENDIAN

3
elem.c
View file

@ -496,12 +496,13 @@ void disk_free(struct snapraid_disk* disk)
free(disk);
}
struct snapraid_map* map_alloc(const char* name, unsigned position)
struct snapraid_map* map_alloc(const char* name, unsigned position, const char* uuid)
{
struct snapraid_map* map;
map = malloc_nofail(sizeof(struct snapraid_map));
pathcpy(map->name, sizeof(map->name), name);
pathcpy(map->uuid, sizeof(map->uuid), uuid);
map->position = position;
return map;

9
elem.h
View file

@ -252,12 +252,18 @@ struct snapraid_disk {
tommy_node node;
};
/**
* Max UUID length.
*/
#define UUID_MAX 128
/**
* Disk mapping.
*/
struct snapraid_map {
char name[PATH_MAX]; /**< Name of the disk. */
unsigned position; /**< Position of the disk in the parity. */
char uuid[UUID_MAX]; /**< UUID of the disk. Empty if unknown. */
/* nodes for data structures */
tommy_node node;
@ -617,8 +623,9 @@ static inline struct snapraid_block* disk_block_get(struct snapraid_disk* disk,
/**
* Allocates a disk mapping.
* Uses uuid="" if not available.
*/
struct snapraid_map* map_alloc(const char* name, unsigned position);
struct snapraid_map* map_alloc(const char* name, unsigned position, const char* uuid);
/**
* Deallocates a disk mapping.

View file

@ -1029,5 +1029,13 @@ int windows_readlink(const char* file, char* buffer, size_t size)
return len;
}
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
{
/* just use the volume serial number returned in the device parameter */
snprintf(uuid, uuid_size, "%08x", (unsigned)device);
return 0;
}
#endif

View file

@ -128,6 +128,12 @@ static inline int hardlink(const char* a, const char* b)
return link(a, b);
}
/**
* Get the device UUID.
* Returns 0 on success.
*/
int devuuid(uint64_t device, char* uuid, size_t size);
/**
* Initializes the system.
*/

13
scan.c
View file

@ -385,8 +385,10 @@ static void scan_file(struct snapraid_scan* scan, struct snapraid_state* state,
/* otherwise it could be a deleted and recreated file */
if (strcmp(file->sub, sub) == 0) {
if (!state->force_zero) {
fprintf(stderr, "The file '%s%s' has now zero size!\n", disk->dir, sub);
fprintf(stderr, "If you really want to sync, use 'snapraid --force-zero sync'\n");
fprintf(stderr, "The file '%s%s' has unexpected zero size! If this an expected state\n", disk->dir, sub);
fprintf(stderr, "you can '%s' anyway usinge 'snapraid --force-zero %s'\n", state->command, state->command);
fprintf(stderr, "Instead, it's possible that after a kernel crash this file was lost,\n");
fprintf(stderr, "and you can use 'snapraid --filter %s fix' to recover it.\n", sub);
exit(EXIT_FAILURE);
}
}
@ -851,8 +853,11 @@ void state_scan(struct snapraid_state* state, int output)
}
if (has_empty) {
fprintf(stderr, " are now missing or rewritten!\n");
fprintf(stderr, "This happens with an empty disk or when all the files are recreated after a 'fix' command.\n");
fprintf(stderr, "If you really want to sync, use 'snapraid --force-empty sync'.\n");
fprintf(stderr, "This happens when deleting all the files from a disk,\n");
fprintf(stderr, "or when all the files are recreated after a 'fix' command,\n");
fprintf(stderr, "or manually copied. If this is really what you are doing, \n");
fprintf(stderr, "you can '%s' anyway, using 'snapraid --force-empty %s'.\n", state->command, state->command);
fprintf(stderr, "Instead, it's possible that you have some disks not mounted.\n");
exit(EXIT_FAILURE);
}
}

View file

@ -18,7 +18,7 @@ snapraid [\(hyc, \(hy\(hyconf CONFIG]
.PD 0
.PP
.PD
[\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty]
[\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty] [\(hyU, \(hy\(hyforce\(hyuuid]
.PD 0
.PP
.PD
@ -506,6 +506,16 @@ This allows to easily detect when a data file\(hysystem is not
mounted.
This option can be used only with the \(a"sync\(a" command.
.TP
.B \(hyU, \(hy\(hyforce\(hyuuid
Forces the insecure operation of syncing, checking and fixing
with disks that have changed the UUID.
If SnapRAID detects that a disk has changed UUID,
it stops proceeding unless you specify this option.
This allows to detect when your disks are mounted in the
wrong mount points.
This option can be used only with the \(a"sync\(a", \(a"check\(a" or
\(a"fix\(a" command.
.TP
.B \(hys, \(hy\(hystart BLKSTART
Starts the processing from the specified
block number. It could be useful to easy retry to check
@ -919,7 +929,7 @@ disk d1 /mnt/new_spare_disk/
Run the fix command, storing the log in an external file with:
.PP
.RS 4
snapraid \(hyd NAME fix 2>fix.log
snapraid \(hyd NAME \(hyl fix.log fix
.PD 0
.PP
.PD
@ -929,6 +939,12 @@ Where NAME is the name of the disk, like \(a"d1\(a" as in our previous example.
.PP
This command will take a long time.
.PP
If the command doesn\(cqt start complaining that the failed and replaced
disk has changed UUID, just add the \(cq\(hyU\(cq option.
But ensure that the failed disk is the only one with the UUID changed.
.PP
You can also add the \(cq\(hyv\(cq option to see on the console the fixed files.
.PP
Take care that you need also few gigabytes free to store the fix.log file.
Run it from a disk with some free space.
.PP
@ -946,8 +962,8 @@ If you are satisfied of the recovering, you can now proceed further,
but take care that after synching you will no more able to retry the
\(a"fix\(a" command!
.SS STEP 3 \(hy> Check
As paranoid check, you can now run a whole \(a"check\(a" command to ensure that
everything is OK.
As paranoid but recommended check, you can now run a \(a"check\(a" command to ensure
that everything is OK on the disk.
.PP
.RS 4
snapraid \(hyd NAME \(hya check
@ -994,8 +1010,9 @@ defined in the configuration file.
.SS checksum CHECKSUM
Defines the checksum kind used. It can be only \(a"murmur3\(a".
From SnapRAID 2.0 the old \(a"md5\(a" checksum is not supported anymore.
.SS map NAME INDEX
.SS map NAME INDEX [UUID]
Defines the position INDEX of the disk NAME in the parity computation.
The disk UUID is also present if supported for the platform.
.SS sign SIGN
Signature checksum of the content file to ensure that it doesn\(cqt get
corrupted. If you want to modify the content file manually, you have

View file

@ -66,6 +66,7 @@ void usage(void)
printf(" " SWITCH_GETOPT_LONG("-N, --find-by-name ", "-N") " Find the files by name instead than by inode\n");
printf(" " SWITCH_GETOPT_LONG("-Z, --force-zero ", "-Z") " Force synching of files that get zero size\n");
printf(" " SWITCH_GETOPT_LONG("-E, --force-empty ", "-E") " Force synching of disks that get empty\n");
printf(" " SWITCH_GETOPT_LONG("-U, --force-uuid ", "-U") " Force commands on disks with uuid changed\n");
printf(" " SWITCH_GETOPT_LONG("-s, --start BLKSTART ", "-s") " Start from the specified block number\n");
printf(" " SWITCH_GETOPT_LONG("-t, --count BLKCOUNT ", "-t") " Count of block to process\n");
printf(" " SWITCH_GETOPT_LONG("-v, --verbose ", "-v") " Verbose\n");
@ -94,6 +95,7 @@ struct option long_options[] = {
{ "log", 1, 0, 'l' },
{ "force-zero", 0, 0, 'Z' },
{ "force-empty", 0, 0, 'E' },
{ "force-uuid", 0, 0, 'U' },
{ "find-by-name", 0, 0, 'N' },
{ "audit-only", 0, 0, 'a' },
{ "speed-test", 0, 0, 'T' },
@ -101,7 +103,7 @@ struct option long_options[] = {
{ "gui", 0, 0, 'G' }, /* undocumented GUI interface command */
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'V' },
/* The following are test specific options, DO NOT USE! */
/* After syncing, do not write the new content file */
@ -128,7 +130,7 @@ struct option long_options[] = {
};
#endif
#define OPTIONS "c:f:d:ms:t:i:l:ZENaTvhVG"
#define OPTIONS "c:f:d:ms:t:i:l:ZEUNaTvhVG"
volatile int global_interrupt = 0;
@ -156,6 +158,7 @@ int main(int argc, char* argv[])
int gui;
int force_zero;
int force_empty;
int force_uuid;
int find_by_name;
int audit_only;
int test_kill_after_sync;
@ -187,6 +190,7 @@ int main(int argc, char* argv[])
gui = 0;
force_zero = 0;
force_empty = 0;
force_uuid = 0;
find_by_name = 0;
audit_only = 0;
test_kill_after_sync = 0;
@ -269,6 +273,9 @@ int main(int argc, char* argv[])
case 'E' :
force_empty = 1;
break;
case 'U' :
force_uuid = 1;
break;
case 'N' :
find_by_name = 1;
break;
@ -402,7 +409,7 @@ int main(int argc, char* argv[])
state_init(&state);
state_config(&state, conf, verbose, gui, force_zero, force_empty, find_by_name, test_expect_unrecoverable, test_expect_recoverable, test_skip_sign, test_skip_fallocate, test_skip_device);
state_config(&state, conf, command, verbose, gui, force_zero, force_empty, force_uuid, find_by_name, test_expect_unrecoverable, test_expect_recoverable, test_skip_sign, test_skip_fallocate, test_skip_device);
if (import != 0) {
printf("%s\n", import);

View file

@ -6,7 +6,7 @@ Synopsis
: [-f, --filter PATTERN] [-d, --filter-disk NAME] [-m, --filter-missing]
: [-a, --audit-only] [-i, --import DIR]
: [-N, --find-by-name]
: [-Z, --force-zero] [-E, --force-empty]
: [-Z, --force-zero] [-E, --force-empty] [-U, --force-uuid]
: [-s, --start BLKSTART] [-t, --count BLKCOUNT]
: [-v, --verbose] [-l, --log FILE]
: sync|pool|diff|dup|check|fix
@ -363,6 +363,16 @@ Options
mounted.
This option can be used only with the "sync" command.
-U, --force-uuid
Forces the insecure operation of syncing, checking and fixing
with disks that have changed the UUID.
If SnapRAID detects that a disk has changed UUID,
it stops proceeding unless you specify this option.
This allows to detect when your disks are mounted in the
wrong mount points.
This option can be used only with the "sync", "check" or
"fix" command.
-s, --start BLKSTART
Starts the processing from the specified
block number. It could be useful to easy retry to check
@ -645,12 +655,18 @@ Recovering
STEP 2 -> Fix
Run the fix command, storing the log in an external file with:
:snapraid -d NAME fix 2>fix.log
:snapraid -d NAME -l fix.log fix
Where NAME is the name of the disk, like "d1" as in our previous example.
This command will take a long time.
If the command doesn't start complaining that the failed and replaced
disk has changed UUID, just add the '-U' option.
But ensure that the failed disk is the only one with the UUID changed.
You can also add the '-v' option to see on the console the fixed files.
Take care that you need also few gigabytes free to store the fix.log file.
Run it from a disk with some free space.
@ -669,8 +685,8 @@ Recovering
"fix" command!
STEP 3 -> Check
As paranoid check, you can now run a whole "check" command to ensure that
everything is OK.
As paranoid but recommended check, you can now run a "check" command to ensure
that everything is OK on the disk.
:snapraid -d NAME -a check
@ -712,8 +728,9 @@ Content
Defines the checksum kind used. It can be only "murmur3".
From SnapRAID 2.0 the old "md5" checksum is not supported anymore.
map NAME INDEX
map NAME INDEX [UUID]
Defines the position INDEX of the disk NAME in the parity computation.
The disk UUID is also present if supported for the platform.
sign SIGN
Signature checksum of the content file to ensure that it doesn't get

View file

@ -10,7 +10,7 @@ snapraid [-c, --conf CONFIG]
[-f, --filter PATTERN] [-d, --filter-disk NAME] [-m, --filter-missing]
[-a, --audit-only] [-i, --import DIR]
[-N, --find-by-name]
[-Z, --force-zero] [-E, --force-empty]
[-Z, --force-zero] [-E, --force-empty] [-U, --force-uuid]
[-s, --start BLKSTART] [-t, --count BLKCOUNT]
[-v, --verbose] [-l, --log FILE]
sync|pool|diff|dup|check|fix
@ -398,6 +398,16 @@ SnapRAID provides the following options:
mounted.
This option can be used only with the "sync" command.
-U, --force-uuid
Forces the insecure operation of syncing, checking and fixing
with disks that have changed the UUID.
If SnapRAID detects that a disk has changed UUID,
it stops proceeding unless you specify this option.
This allows to detect when your disks are mounted in the
wrong mount points.
This option can be used only with the "sync", "check" or
"fix" command.
-s, --start BLKSTART
Starts the processing from the specified
block number. It could be useful to easy retry to check
@ -709,12 +719,18 @@ to:
Run the fix command, storing the log in an external file with:
snapraid -d NAME fix 2>fix.log
snapraid -d NAME -l fix.log fix
Where NAME is the name of the disk, like "d1" as in our previous example.
This command will take a long time.
If the command doesn't start complaining that the failed and replaced
disk has changed UUID, just add the '-U' option.
But ensure that the failed disk is the only one with the UUID changed.
You can also add the '-v' option to see on the console the fixed files.
Take care that you need also few gigabytes free to store the fix.log file.
Run it from a disk with some free space.
@ -735,8 +751,8 @@ but take care that after synching you will no more able to retry the
9.3 STEP 3 -> Check
-------------------
As paranoid check, you can now run a whole "check" command to ensure that
everything is OK.
As paranoid but recommended check, you can now run a "check" command to ensure
that everything is OK on the disk.
snapraid -d NAME -a check
@ -787,10 +803,11 @@ defined in the configuration file.
Defines the checksum kind used. It can be only "murmur3".
From SnapRAID 2.0 the old "md5" checksum is not supported anymore.
10.3 map NAME INDEX
-------------------
10.3 map NAME INDEX [UUID]
--------------------------
Defines the position INDEX of the disk NAME in the parity computation.
The disk UUID is also present if supported for the platform.
10.4 sign SIGN
--------------

86
state.c
View file

@ -217,10 +217,9 @@ static void state_config_check(struct snapraid_state* state, const char* path, i
exit(EXIT_FAILURE);
}
}
}
void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_device)
void state_config(struct snapraid_state* state, const char* path, const char* command, int verbose, int gui, int force_zero, int force_empty, int force_uuid, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_device)
{
STREAM* f;
unsigned line;
@ -229,12 +228,14 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
state->gui = gui;
state->force_zero = force_zero;
state->force_empty = force_empty;
state->force_uuid = force_uuid;
state->filter_hidden = 0;
state->find_by_name = find_by_name;
state->expect_unrecoverable = expect_unrecoverable;
state->expect_recoverable = expect_recoverable;
state->skip_sign = skip_sign;
state->skip_fallocate = skip_fallocate;
state->command = command;
if (state->gui) {
fprintf(stdlog, "version:%s\n", PACKAGE_VERSION);
@ -611,6 +612,7 @@ static void state_map(struct snapraid_state* state)
{
unsigned hole;
tommy_node* i;
unsigned uuid_mismatch;
/* removes all the mapping without a disk */
/* this happens when a disk is removed from the configuration file */
@ -675,10 +677,64 @@ static void state_map(struct snapraid_state* state)
}
/* insert the new mapping */
map = map_alloc(disk->name, hole);
map = map_alloc(disk->name, hole, "");
tommy_list_insert_tail(&state->maplist, &map->node, map);
}
/* checks if mapping match the disk uuid */
uuid_mismatch = 0;
for(i=state->maplist;i!=0;i=i->next) {
struct snapraid_map* map = i->data;
struct snapraid_disk* disk;
tommy_node* j;
char uuid[UUID_MAX];
int ret;
for(j=state->disklist;j!=0;j=j->next) {
disk = j->data;
if (strcmp(disk->name, map->name) == 0) {
/* disk found */
break;
}
}
if (j==0) {
fprintf(stderr, "Internal incosistency for mapping '%s'\n", map->name);
exit(EXIT_FAILURE);
}
ret = devuuid(disk->device, uuid, sizeof(uuid));
if (ret != 0) {
/* uuid not available, just ignore */
continue;
}
if (map->uuid[0] != 0) {
if (strcmp(uuid, map->uuid) != 0) {
++uuid_mismatch;
fprintf(stderr, "UUID change for disk '%s' from '%s' to '%s'\n", disk->name, map->uuid, uuid);
}
}
if (strcmp(uuid, map->uuid) != 0) {
/* rewrite if the uuid changes */
state->need_write = 1;
}
/* update the uuid in the mapping, */
/* even if it's already present because it may be changed */
pathcpy(map->uuid, sizeof(map->uuid), uuid);
}
if (!state->force_uuid && uuid_mismatch > 0) {
fprintf(stderr, "Some disks have UUID changed from the latest 'sync'.\n");
fprintf(stderr, "If this happens because you really replaced them,\n");
fprintf(stderr, "you can '%s' anyway, using 'snapraid --force-uuid %s'.\n", state->command, state->command);
fprintf(stderr, "Instead, it's possible that you messed up the disk mount points,\n");
fprintf(stderr, "and you have to restore the mount points at the state of the latest sync.\n");
exit(EXIT_FAILURE);
}
}
/**
@ -1356,6 +1412,7 @@ void state_read(struct snapraid_state* state)
}
} else if (strcmp(tag, "map") == 0) {
struct snapraid_map* map;
char uuid[UUID_MAX];
uint32_t v_pos;
hash = oathash8(hash, 'm');
@ -1380,7 +1437,21 @@ void state_read(struct snapraid_state* state)
}
hash = oathash32(hash, v_pos);
map = map_alloc(buffer, v_pos);
c = sgetc(f);
if (c != ' ') {
sungetc(c, f);
uuid[0] = 0;
} else {
/* read the uuid */
ret = sgettok(f, uuid, sizeof(uuid));
if (ret < 0) {
fprintf(stderr, "Invalid 'map' specification in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
hash = oathashs(hash, uuid);
}
map = map_alloc(buffer, v_pos, uuid);
tommy_list_insert_tail(&state->maplist, &map->node, map);
} else if (strcmp(tag, "sign") == 0) {
@ -1553,6 +1624,13 @@ void state_write(struct snapraid_state* state)
sputc(' ', f);
sputu32(map->position, f);
hash = oathash32(hash, map->position);
/* if there is an uuid, print it */
if (map->uuid[0]) {
sputc(' ', f);
sputs(map->uuid, f);
hash = oathashs(hash, map->uuid);
}
sputeol(f);
if (serror(f)) {
fprintf(stderr, "Error writing the content file '%s'. %s.\n", serrorfile(f), strerror(errno));

View file

@ -29,8 +29,9 @@ extern volatile int global_interrupt;
struct snapraid_state {
int verbose; /**< Verbose output. */
int gui; /**< Gui output. */
int force_zero; /**< Forced dangerous operations of synching file now with zero size. */
int force_empty; /**< Forced dangerous operations of synching disk now empty. */
int force_zero; /**< Forced dangerous operations of synching files now with zero size. */
int force_empty; /**< Forced dangerous operations of synching disks now empty. */
int force_uuid; /**< Forced dangerous operations of synching disks with uuid changed. */
int filter_hidden; /**< Filter out hidden files. */
int find_by_name; /**< Forced dangerous operations of synching a rewritten disk. */
uint64_t autosave; /**< Autosave after the specified amount of data. 0 to disable. */
@ -48,6 +49,7 @@ struct snapraid_state {
uint64_t pool_device; /**< Device identifier of the pool. */
unsigned level; /**< Number of parity levels. 1 for RAID5, 2 for RAID6. */
unsigned hash; /**< Hash kind used. */
const char* command; /**< Command running. */
tommy_list contentlist; /**< List of content files. */
tommy_list disklist; /**< List of all the disks. */
tommy_list maplist; /**< List of all the disk mappings. */
@ -74,7 +76,7 @@ void state_done(struct snapraid_state* state);
/**
* Reads the configuration file.
*/
void state_config(struct snapraid_state* state, const char* path, int verbose, int gui, int force_zero, int force_empty, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_device);
void state_config(struct snapraid_state* state, const char* path, const char* command, int verbose, int gui, int force_zero, int force_empty, int force_uuid, int find_by_name, int expect_unrecoverable, int expect_recoverable, int skip_sign, int skip_fallocate, int skip_device);
/**
* Reads the state.

66
unix.c
View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011 Andrea Mazzoleni
* Copyright (C) 2013 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -59,6 +59,70 @@ const char* stat_desc(struct stat* st)
return "unknown";
}
#if HAVE_FSTATAT
/**
* This function get the UUID using the /dev/disk/by-uuid/ links.
* Comparing with the libblkid library, it works also from not root processes.
*/
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
{
int ret;
DIR* d;
struct stat st;
/* scan the UUID directory searching for the device */
d = opendir("/dev/disk/by-uuid");
if (!d) {
/* directory missing?, likely we are not in Linux */
return -1;
}
while (1) {
struct dirent* dd;
dd = readdir(d);
if (dd == 0) {
/* not found or generic error */
goto bail;
}
/* skip "." and ".." files, UUIDs never start with '.' */
if (dd->d_name[0] == '.') {
continue;
}
ret = fstatat(dirfd(d), dd->d_name, &st, 0);
if (ret != 0) {
/* generic error, ignore and continue the search */
continue;
}
/* if it matches, we have the uuid */
if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
snprintf(uuid, uuid_size, "%s", dd->d_name);
break;
}
}
closedir(d);
return 0;
bail:
closedir(d);
return -1;
}
#else
int devuuid(uint64_t device, char* uuid, size_t uuid_size)
{
(void)device;
(void)uuid;
(void)uuid_size;
/* not supported */
return -1;
}
#endif
void os_init(void)
{
}