Imported Upstream version 11.3
This commit is contained in:
@@ -889,7 +889,7 @@ void io_init(struct snapraid_io* io, struct snapraid_state* state,
|
||||
allocated += state->block_size * buffer_max;
|
||||
}
|
||||
|
||||
msg_progress("Using %u MiB of memory for %u blocks of IO cache.\n", (unsigned)(allocated / MEBI), io->io_max);
|
||||
msg_progress("Using %u MiB of memory for %u cached blocks.\n", (unsigned)(allocated / MEBI), io->io_max);
|
||||
|
||||
if (parity_writer) {
|
||||
io->reader_max = handle_max;
|
||||
|
||||
@@ -74,7 +74,7 @@ void state_list(struct snapraid_state* state)
|
||||
if (tm) {
|
||||
printf("%04u/%02u/%02u %02u:%02u", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min);
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(":%02u.%03u", tm->tm_sec, file->mtime_nsec / 1000000);
|
||||
printf(":%02u.%09u", tm->tm_sec, file->mtime_nsec);
|
||||
printf(" ");
|
||||
}
|
||||
printf("%s\n", fmt_term(disk, file->sub, esc_buffer));
|
||||
@@ -105,7 +105,7 @@ void state_list(struct snapraid_state* state)
|
||||
printf("%12s ", type);
|
||||
printf(" ");
|
||||
if (msg_level >= MSG_VERBOSE)
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
printf("%s -> %s\n", fmt_term(disk, slink->sub, esc_buffer), fmt_term(disk, slink->linkto, esc_buffer_alt));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,6 +694,7 @@ static void windows_errno(DWORD error)
|
||||
errno = EPERM;
|
||||
break;
|
||||
case ERROR_IO_DEVICE : /* in ReadFile() and WriteFile() */
|
||||
case ERROR_CRC : /* in ReadFile() */
|
||||
errno = EIO;
|
||||
break;
|
||||
default :
|
||||
|
||||
@@ -41,6 +41,7 @@ void test(void)
|
||||
s = sopen_multi_write(STREAM_MAX);
|
||||
for (i = 0; i < STREAM_MAX; ++i) {
|
||||
snprintf(file, sizeof(file), "stream%u.bin", i);
|
||||
remove(file);
|
||||
if (sopen_multi_file(s, i, file) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
@@ -136,25 +136,29 @@ void MurmurHash3_x86_128(const void* data, size_t size, const uint8_t* seed, voi
|
||||
uint32_t k4 = 0;
|
||||
|
||||
switch (size_remainder) {
|
||||
case 15 : k4 ^= (uint32_t)tail[14] << 16;
|
||||
case 14 : k4 ^= (uint32_t)tail[13] << 8;
|
||||
case 13 : k4 ^= (uint32_t)tail[12] << 0;
|
||||
case 15 : k4 ^= (uint32_t)tail[14] << 16; /* fallthrough */
|
||||
case 14 : k4 ^= (uint32_t)tail[13] << 8; /* fallthrough */
|
||||
case 13 : k4 ^= (uint32_t)tail[12] << 0; /* fallthrough */
|
||||
k4 *= c4; k4 = util_rotl32(k4, 18); k4 *= c1; h4 ^= k4;
|
||||
case 12 : k3 ^= (uint32_t)tail[11] << 24;
|
||||
case 11 : k3 ^= (uint32_t)tail[10] << 16;
|
||||
case 10 : k3 ^= (uint32_t)tail[ 9] << 8;
|
||||
case 9 : k3 ^= (uint32_t)tail[ 8] << 0;
|
||||
/* fallthrough */
|
||||
case 12 : k3 ^= (uint32_t)tail[11] << 24; /* fallthrough */
|
||||
case 11 : k3 ^= (uint32_t)tail[10] << 16; /* fallthrough */
|
||||
case 10 : k3 ^= (uint32_t)tail[ 9] << 8; /* fallthrough */
|
||||
case 9 : k3 ^= (uint32_t)tail[ 8] << 0; /* fallthrough */
|
||||
k3 *= c3; k3 = util_rotl32(k3, 17); k3 *= c4; h3 ^= k3;
|
||||
case 8 : k2 ^= (uint32_t)tail[ 7] << 24;
|
||||
case 7 : k2 ^= (uint32_t)tail[ 6] << 16;
|
||||
case 6 : k2 ^= (uint32_t)tail[ 5] << 8;
|
||||
case 5 : k2 ^= (uint32_t)tail[ 4] << 0;
|
||||
/* fallthrough */
|
||||
case 8 : k2 ^= (uint32_t)tail[ 7] << 24; /* fallthrough */
|
||||
case 7 : k2 ^= (uint32_t)tail[ 6] << 16; /* fallthrough */
|
||||
case 6 : k2 ^= (uint32_t)tail[ 5] << 8; /* fallthrough */
|
||||
case 5 : k2 ^= (uint32_t)tail[ 4] << 0; /* fallthrough */
|
||||
k2 *= c2; k2 = util_rotl32(k2, 16); k2 *= c3; h2 ^= k2;
|
||||
case 4 : k1 ^= (uint32_t)tail[ 3] << 24;
|
||||
case 3 : k1 ^= (uint32_t)tail[ 2] << 16;
|
||||
case 2 : k1 ^= (uint32_t)tail[ 1] << 8;
|
||||
case 1 : k1 ^= (uint32_t)tail[ 0] << 0;
|
||||
/* fallthrough */
|
||||
case 4 : k1 ^= (uint32_t)tail[ 3] << 24; /* fallthrough */
|
||||
case 3 : k1 ^= (uint32_t)tail[ 2] << 16; /* fallthrough */
|
||||
case 2 : k1 ^= (uint32_t)tail[ 1] << 8; /* fallthrough */
|
||||
case 1 : k1 ^= (uint32_t)tail[ 0] << 0; /* fallthrough */
|
||||
k1 *= c1; k1 = util_rotl32(k1, 15); k1 *= c2; h1 ^= k1;
|
||||
/* fallthrough */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ void memory(void)
|
||||
log_tag("memory:link:%" PRIu64 "\n", (uint64_t)(sizeof(struct snapraid_link)));
|
||||
log_tag("memory:dir:%" PRIu64 "\n", (uint64_t)(sizeof(struct snapraid_dir)));
|
||||
|
||||
msg_progress("Using %u MiB of memory for the FileSystem.\n", (unsigned)(malloc_counter_get() / MEBI));
|
||||
msg_progress("Using %u MiB of memory for the file-system.\n", (unsigned)(malloc_counter_get() / MEBI));
|
||||
}
|
||||
|
||||
void test(int argc, char* argv[])
|
||||
@@ -1091,7 +1091,7 @@ int main(int argc, char* argv[])
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
/* follow */
|
||||
/* fallthrough */
|
||||
case OPERATION_SPINUP :
|
||||
case OPERATION_SPINDOWN :
|
||||
if (!tommy_list_empty(&filterlist_file)) {
|
||||
|
||||
103
cmdline/state.c
103
cmdline/state.c
@@ -2872,6 +2872,7 @@ struct state_write_thread_context {
|
||||
/* input */
|
||||
block_off_t blockmax;
|
||||
time_t info_oldest;
|
||||
time_t info_now;
|
||||
int info_has_rehash;
|
||||
STREAM* f;
|
||||
/* output */
|
||||
@@ -2888,6 +2889,7 @@ static void* state_write_thread(void* arg)
|
||||
struct snapraid_state* state = context->state;
|
||||
block_off_t blockmax = context->blockmax;
|
||||
time_t info_oldest = context->info_oldest;
|
||||
time_t info_now = context->info_now;
|
||||
int info_has_rehash = context->info_has_rehash;
|
||||
STREAM* f = context->f;
|
||||
uint32_t crc;
|
||||
@@ -3278,7 +3280,18 @@ static void* state_write_thread(void* arg)
|
||||
flag |= 8;
|
||||
sputb32(flag, f);
|
||||
|
||||
t = info_get_time(info) - info_oldest;
|
||||
t = info_get_time(info);
|
||||
|
||||
/* truncate any time that is in the future */
|
||||
if (t > info_now)
|
||||
t = info_now;
|
||||
|
||||
/* the oldest info is computed only on required blocks, so it may not be the absolute oldest */
|
||||
if (t < info_oldest)
|
||||
t = 0;
|
||||
else
|
||||
t -= info_oldest;
|
||||
|
||||
sputb32(t, f);
|
||||
} else {
|
||||
/* write a special 0 flag to mark missing info */
|
||||
@@ -3353,6 +3366,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
tommy_node* i;
|
||||
block_off_t blockmax;
|
||||
time_t info_oldest;
|
||||
time_t info_now;
|
||||
int info_has_rehash;
|
||||
int mapping_idx;
|
||||
block_off_t idx;
|
||||
@@ -3371,6 +3385,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
/* clear the info for unused blocks */
|
||||
/* and get some other info */
|
||||
info_oldest = 0; /* oldest time in info */
|
||||
info_now = time(0); /* get the present time */
|
||||
info_has_rehash = 0; /* if there is a rehash info */
|
||||
for (idx = 0; idx < blockmax; ++idx) {
|
||||
/* if the position is used */
|
||||
@@ -3434,10 +3449,21 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
msg_progress("Saving state to %s...\n", content->content);
|
||||
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
/* ensure to delete a previous stale file */
|
||||
if (remove(tmp) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing the stale content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
f = sopen_write(tmp);
|
||||
if (f == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error opening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@@ -3450,6 +3476,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
context->state = state;
|
||||
context->blockmax = blockmax;
|
||||
context->info_oldest = info_oldest;
|
||||
context->info_now = info_now;
|
||||
context->info_has_rehash = info_has_rehash;
|
||||
context->f = f;
|
||||
|
||||
@@ -3562,12 +3589,24 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
struct snapraid_content* content = i->data;
|
||||
char tmp[PATH_MAX];
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
/* ensure to delete a previous stale file */
|
||||
if (remove(tmp) != 0) {
|
||||
if (errno != ENOENT) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error removing the stale content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
if (sopen_multi_file(f, k, tmp) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error opening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
++k;
|
||||
i = i->next;
|
||||
}
|
||||
@@ -3579,6 +3618,7 @@ static void state_write_content(struct snapraid_state* state, uint32_t* out_crc)
|
||||
context->state = state;
|
||||
context->blockmax = blockmax;
|
||||
context->info_oldest = info_oldest;
|
||||
context->info_now = info_now;
|
||||
context->info_has_rehash = info_has_rehash;
|
||||
context->f = f;
|
||||
|
||||
@@ -3851,11 +3891,10 @@ static void state_verify_content(struct snapraid_state* state, uint32_t crc)
|
||||
msg_progress("Verifying %s...\n", content->content);
|
||||
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
|
||||
f = sopen_read(tmp);
|
||||
if (f == 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error reopening the content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
log_fatal("Error reopening the temporary content file '%s'. %s.\n", tmp, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
@@ -3924,6 +3963,59 @@ static void state_rename_content(struct snapraid_state* state)
|
||||
{
|
||||
tommy_node* i;
|
||||
|
||||
#if defined(_linux) /* this sequence is linux specific */
|
||||
i = tommy_list_head(&state->contentlist);
|
||||
while (i) {
|
||||
struct snapraid_content* content = i->data;
|
||||
char tmp[PATH_MAX];
|
||||
char dir[PATH_MAX];
|
||||
char* slash;
|
||||
int handle;
|
||||
|
||||
pathcpy(dir, sizeof(dir), content->content);
|
||||
|
||||
slash = strrchr(tmp, '/');
|
||||
if (slash)
|
||||
*slash = 0;
|
||||
else
|
||||
pathcpy(dir, sizeof(dir), ".");
|
||||
|
||||
/* open the directory to get the handle */
|
||||
handle = open(dir, O_RDONLY | O_DIRECTORY);
|
||||
if (handle < 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error opening the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* now rename the just written copy with the correct name */
|
||||
pathprint(tmp, sizeof(tmp), "%s.tmp", content->content);
|
||||
if (rename(tmp, content->content) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error renaming the content file '%s' to '%s'. %s.\n", tmp, content->content, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* sync the directory */
|
||||
if (fsync(handle) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error syncing the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (close(handle) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_fatal("Error closing the directory '%s'. %s.\n", dir, strerror(errno));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
i = i->next;
|
||||
}
|
||||
#else
|
||||
i = tommy_list_head(&state->contentlist);
|
||||
while (i) {
|
||||
struct snapraid_content* content = i->data;
|
||||
@@ -3940,6 +4032,7 @@ static void state_rename_content(struct snapraid_state* state)
|
||||
|
||||
i = i->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void state_write(struct snapraid_state* state)
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
unsigned day_ago(time_t ref, time_t now)
|
||||
{
|
||||
/* in case some dates is in the future */
|
||||
if (now < ref)
|
||||
return 0;
|
||||
|
||||
return (now - ref) / (24 * 3600);
|
||||
}
|
||||
|
||||
@@ -458,6 +462,10 @@ int state_status(struct snapraid_state* state)
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (newest > now) {
|
||||
printf("WARNING! You have scrub dates in the future! The next sync/scrub will truncate them!\n");
|
||||
}
|
||||
|
||||
if (unsynced_blocks) {
|
||||
printf("WARNING! The array is NOT fully synced.\n");
|
||||
printf("You have a sync in progress at %u%%.\n", (blockmax - unsynced_blocks) * 100 / blockmax);
|
||||
|
||||
@@ -112,7 +112,8 @@ int sopen_multi_file(STREAM* s, unsigned i, const char* file)
|
||||
|
||||
pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
|
||||
|
||||
f = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
/* O_EXCL to be resilent ensure to always create a new file and not use a stale link to the original file */
|
||||
f = open(file, O_WRONLY | O_CREAT | O_EXCL | O_BINARY | O_SEQUENTIAL, 0600);
|
||||
if (f == -1) {
|
||||
/* LCOV_EXCL_START */
|
||||
return -1;
|
||||
|
||||
@@ -299,6 +299,8 @@ void pathslash(char* dst, size_t size);
|
||||
|
||||
/**
|
||||
* Cut everything after the latest slash.
|
||||
*
|
||||
* If the string doesn't contain any slash, it returns the empty string.
|
||||
*/
|
||||
void pathcut(char* dst);
|
||||
|
||||
|
||||
@@ -1536,7 +1536,7 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t
|
||||
data_off_t out_size;
|
||||
parity_size(&parity_handle[l], &out_size);
|
||||
parity_overflow(state, out_size);
|
||||
log_fatal("WARNING! Without an unsable %s file, it isn't possible to sync.\n", lev_name(l));
|
||||
log_fatal("WARNING! Without an usable %s file, it isn't possible to sync.\n", lev_name(l));
|
||||
exit(EXIT_FAILURE);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
@@ -917,18 +917,20 @@ static int devtree(const char* name, const char* custom, dev_t device, devinfo_t
|
||||
|
||||
while ((dd = readdir(d)) != 0) {
|
||||
if (dd->d_name[0] != '.') {
|
||||
dev_t subdev;
|
||||
|
||||
/* for each slave, expand the full potential tree */
|
||||
pathprint(path, sizeof(path), "/sys/dev/block/%u:%u/slaves/%s/dev", major(device), minor(device), dd->d_name);
|
||||
|
||||
device = devread(path);
|
||||
if (!device) {
|
||||
subdev = devread(path);
|
||||
if (!subdev) {
|
||||
/* LCOV_EXCL_START */
|
||||
closedir(d);
|
||||
return -1;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
if (devtree(name, custom, device, parent, list) != 0) {
|
||||
if (devtree(name, custom, subdev, parent, list) != 0) {
|
||||
/* LCOV_EXCL_START */
|
||||
closedir(d);
|
||||
return -1;
|
||||
@@ -1072,8 +1074,8 @@ static int devscan(tommy_list* list)
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devsmart(dev_t device, const char* name, const char* custom, uint64_t* smart, char* serial, char* vendor, char* model)
|
||||
{
|
||||
char cmd[128];
|
||||
char file[128];
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
FILE* f;
|
||||
int ret;
|
||||
|
||||
@@ -1086,7 +1088,7 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t
|
||||
|
||||
/* if there is a custom command */
|
||||
if (custom[0]) {
|
||||
char option[128];
|
||||
char option[PATH_MAX];
|
||||
snprintf(option, sizeof(option), custom, file);
|
||||
snprintf(cmd, sizeof(cmd), "smartctl -a %s", option);
|
||||
} else {
|
||||
@@ -1140,8 +1142,8 @@ static int devsmart(dev_t device, const char* name, const char* custom, uint64_t
|
||||
#if HAVE_LINUX_DEVICE
|
||||
static int devdown(dev_t device, const char* name, const char* custom)
|
||||
{
|
||||
char cmd[128];
|
||||
char file[128];
|
||||
char cmd[PATH_MAX + 64];
|
||||
char file[PATH_MAX];
|
||||
FILE* f;
|
||||
int ret;
|
||||
|
||||
@@ -1154,7 +1156,7 @@ static int devdown(dev_t device, const char* name, const char* custom)
|
||||
|
||||
/* if there is a custom command */
|
||||
if (custom[0]) {
|
||||
char option[128];
|
||||
char option[PATH_MAX];
|
||||
snprintf(option, sizeof(option), custom, file);
|
||||
snprintf(cmd, sizeof(cmd), "smartctl -s standby,now %s", option);
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user