Imported Upstream version 11.3

This commit is contained in:
Mario Fetka
2019-01-07 14:41:48 +01:00
parent 8d2a0b593e
commit c540e24217
31 changed files with 408 additions and 217 deletions

View File

@@ -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;

View File

@@ -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));
}
}

View File

@@ -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 :

View File

@@ -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);

View File

@@ -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 */
}
}

View File

@@ -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)) {

View File

@@ -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)

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 */
}

View File

@@ -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 {