From 12b30c198e1c28f7d99f6905b41912f23784b5d0 Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Tue, 9 Feb 2016 23:12:33 +0100 Subject: [PATCH] Use a thread-safe esc() function with a local buffer --- cmdline/check.c | 89 +++++++++++++++++++++++++---------------------- cmdline/device.c | 3 +- cmdline/dry.c | 16 +++++---- cmdline/dup.c | 4 ++- cmdline/list.c | 6 ++-- cmdline/parity.c | 3 +- cmdline/scan.c | 28 ++++++++------- cmdline/scrub.c | 18 +++++----- cmdline/support.c | 24 ++----------- cmdline/support.h | 6 +++- cmdline/sync.c | 53 +++++++++++++++------------- cmdline/touch.c | 3 +- 12 files changed, 131 insertions(+), 122 deletions(-) diff --git a/cmdline/check.c b/cmdline/check.c index 1e5bf7e5..7c960e77 100644 --- a/cmdline/check.c +++ b/cmdline/check.c @@ -292,6 +292,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign int n; int something_to_recover; int something_unsynced; + char esc_buffer[ESC_MAX]; error = 0; @@ -337,7 +338,7 @@ static int repair(struct snapraid_state* state, int rehash, unsigned pos, unsign struct snapraid_file* file = failed[j].file; block_off_t file_pos = failed[j].file_pos; - log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub), file_pos); + log_tag("entry:%u:%s:%s:%s:%s:%s:%u:\n", j, desc, hash, data, disk->name, esc(file->sub, esc_buffer), file_pos); } else { log_tag("entry:%u:%s:%s:%s:\n", j, desc, hash, data); } @@ -597,6 +598,8 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s { unsigned j; int ret; + char esc_buffer[ESC_MAX]; + char esc_buffer_alt[ESC_MAX]; /* if we are processing only bad blocks, we don't have to do any post-processing */ /* as we don't have any guarantee to process the last block of the fixed files */ @@ -660,7 +663,7 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s ret = handle_close(&handle[j]); if (ret != 0) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); return -1; /* LCOV_EXCL_STOP */ @@ -676,7 +679,7 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s /* LCOV_EXCL_STOP */ } - log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("unrecoverable %s\n", path); /* and do not set the time if damaged */ @@ -696,7 +699,7 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s ret = handle_close(&handle[j]); if (ret != 0) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); return -1; /* LCOV_EXCL_STOP */ @@ -707,14 +710,14 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s ret = handle_open(&handle[j], file, state->file_mode, log_error, 0); if (ret != 0) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Without a working data disk, it isn't possible to fix errors on it.\n"); return -1; /* LCOV_EXCL_STOP */ } } - log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("recovered %s\n", path); inode = handle[j].st.st_ino; @@ -747,26 +750,26 @@ static int file_post(struct snapraid_state* state, int fix, unsigned i, struct s /* LCOV_EXCL_STOP */ } } else { - log_tag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc(file->sub), esc(collide_file->sub)); + log_tag("collision:%s:%s:%s: Not setting modification time to avoid inode collision\n", disk->name, esc(file->sub, esc_buffer), esc(collide_file->sub, esc_buffer_alt)); } } else { /* we are not fixing, but only checking */ /* print just the final status */ if (file_flag_has(file, FILE_IS_DAMAGED)) { if (state->opt.auditonly) { - log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:damaged:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("damaged %s\n", path); } else { - log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:unrecoverable:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("unrecoverable %s\n", path); } } else if (file_flag_has(file, FILE_IS_FIXED)) { - log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:recoverable:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("recoverable %s\n", path); } else { /* we don't use msg_verbose() because it also goes into the log */ if (msg_level >= MSG_VERBOSE) { - log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:correct:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("correct %s\n", path); } } @@ -782,7 +785,7 @@ close_and_continue: ret = handle_close(&handle[j]); if (ret != 0) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); return -1; /* LCOV_EXCL_STOP */ @@ -861,6 +864,8 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna struct failed_struct* failed; unsigned* failed_map; unsigned l; + char esc_buffer[ESC_MAX]; + char esc_buffer_alt[ESC_MAX]; handle = handle_mapping(state, &diskmax); @@ -1003,7 +1008,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna ret = handle_close(&handle[j]); if (ret == -1) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(handle[j].file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); log_fatal("Stopping at block %u\n", i); ++unrecoverable_error; @@ -1053,7 +1058,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna failed[failed_count].handle = &handle[j]; ++failed_count; - log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub), file_pos); + log_tag("error:%u:%s:%s: Open error at position %u\n", i, disk->name, esc(file->sub, esc_buffer), file_pos); ++error; /* mark the file as missing, to avoid to retry to open it again */ @@ -1086,7 +1091,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna && handle[j].st.st_size > file->size ) { log_error("File '%s' is larger than expected.\n", handle[j].path); - log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub)); + log_tag("error:%u:%s:%s: Size error\n", i, disk->name, esc(file->sub, esc_buffer)); ++error; if (fix) { @@ -1100,7 +1105,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* LCOV_EXCL_STOP */ } - log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub)); + log_tag("fixed:%u:%s:%s: Fixed size\n", i, disk->name, esc(file->sub, esc_buffer)); ++recovered_error; } } @@ -1126,7 +1131,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna failed[failed_count].handle = &handle[j]; ++failed_count; - log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub), file_pos); + log_tag("error:%u:%s:%s: Read error at position %u\n", i, disk->name, esc(file->sub, esc_buffer), file_pos); ++error; continue; } @@ -1175,7 +1180,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna failed[failed_count].handle = &handle[j]; ++failed_count; - log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub), file_pos, diff); + log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", i, disk->name, esc(file->sub, esc_buffer), file_pos, diff); ++error; continue; } @@ -1237,7 +1242,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* print a list of all the errors in files */ for (j = 0; j < failed_count; ++j) { if (failed[j].is_bad) - log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); + log_tag("unrecoverable:%u:%s:%s: Unrecoverable error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub, esc_buffer), failed[j].file_pos); } /* keep track of damaged files */ @@ -1255,7 +1260,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna for (j = 0; j < failed_count; ++j) { if (failed[j].is_bad && failed[j].is_outofdate) { ++partial_recover_error; - log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); + log_tag("unrecoverable:%u:%s:%s: Unrecoverable unsynced error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub, esc_buffer), failed[j].file_pos); } } if (partial_recover_error != 0) { @@ -1323,7 +1328,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* note that it could be also marked as damaged in other iterations */ file_flag_set(failed[j].file, FILE_IS_FIXED); - log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub), failed[j].file_pos); + log_tag("fixed:%u:%s:%s: Fixed data error at position %u\n", i, failed[j].disk->name, esc(failed[j].file->sub, esc_buffer), failed[j].file_pos); ++recovered_error; } @@ -1432,17 +1437,17 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna unsuccesful = 1; log_error("Error stating empty file '%s'. %s.\n", path, strerror(errno)); - log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub)); + log_tag("error:%s:%s: Empty file stat error\n", disk->name, esc(file->sub, esc_buffer)); ++error; } else if (!S_ISREG(st.st_mode)) { unsuccesful = 1; - log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub)); + log_tag("error:%s:%s: Empty file error for not regular file\n", disk->name, esc(file->sub, esc_buffer)); ++error; } else if (st.st_size != 0) { unsuccesful = 1; - log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub), st.st_size); + log_tag("error:%s:%s: Empty file error for size '%" PRIu64 "'\n", disk->name, esc(file->sub, esc_buffer), st.st_size); ++error; } @@ -1503,10 +1508,10 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* LCOV_EXCL_STOP */ } - log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub)); + log_tag("fixed:%s:%s: Fixed empty file\n", disk->name, esc(file->sub, esc_buffer)); ++recovered_error; - log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub)); + log_tag("status:recovered:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); msg_info("recovered %s%s\n", disk->dir, file->sub); } } @@ -1540,12 +1545,12 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna unsuccesful = 1; log_error("Error stating hardlink '%s'. %s.\n", path, strerror(errno)); - log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("hardlink_error:%s:%s:%s: Hardlink stat error\n", disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); ++error; } else if (!S_ISREG(st.st_mode)) { unsuccesful = 1; - log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("hardlink_error:%s:%s:%s: Hardlink error for not regular file\n", disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); ++error; } @@ -1570,18 +1575,18 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna } log_error("Error stating hardlink-to '%s'. %s.\n", pathto, strerror(errno)); - log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("hardlink_error:%s:%s:%s: Hardlink to stat error\n", disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); ++error; } else if (!S_ISREG(stto.st_mode)) { unsuccesful = 1; - log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("hardlink_error:%s:%s:%s: Hardlink-to error for not regular file\n", disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); ++error; } else if (!unsuccesful && st.st_ino != stto.st_ino) { unsuccesful = 1; log_error("Mismatch hardlink '%s' and '%s'. Different inode.\n", path, pathto); - log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("hardlink_error:%s:%s:%s: Hardlink mismatch for different inode\n", disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); ++error; } } else { @@ -1592,13 +1597,13 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna unsuccesful = 1; log_error("Error reading symlink '%s'. %s.\n", path, strerror(errno)); - log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub)); + log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub, esc_buffer)); ++error; } else if (ret >= PATH_MAX) { unsuccesful = 1; log_error("Error reading symlink '%s'. Symlink too long.\n", path); - log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub)); + log_tag("symlink_error:%s:%s: Symlink read error\n", disk->name, esc(slink->sub, esc_buffer)); ++error; } else { linkto[ret] = 0; @@ -1606,7 +1611,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna if (strcmp(linkto, slink->linkto) != 0) { unsuccesful = 1; - log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub), linkto, slink->linkto); + log_tag("symlink_error:%s:%s: Symlink data error '%s' instead of '%s'\n", disk->name, esc(slink->sub, esc_buffer), linkto, slink->linkto); ++error; } } @@ -1654,7 +1659,7 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* LCOV_EXCL_STOP */ } - log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc(slink->sub)); + log_tag("hardlink_fixed:%s:%s: Fixed hardlink error\n", disk->name, esc(slink->sub, esc_buffer)); ++recovered_error; } else { ret = symlink(slink->linkto, path); @@ -1673,11 +1678,11 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* LCOV_EXCL_STOP */ } - log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc(slink->sub)); + log_tag("symlink_fixed:%s:%s: Fixed symlink error\n", disk->name, esc(slink->sub, esc_buffer)); ++recovered_error; } - log_tag("status:recovered:%s:%s\n", disk->name, esc(slink->sub)); + log_tag("status:recovered:%s:%s\n", disk->name, esc(slink->sub, esc_buffer)); msg_info("recovered %s%s\n", disk->dir, slink->sub); } } @@ -1706,12 +1711,12 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna unsuccesful = 1; log_error("Error stating dir '%s'. %s.\n", path, strerror(errno)); - log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc(dir->sub)); + log_tag("dir_error:%s:%s: Dir stat error\n", disk->name, esc(dir->sub, esc_buffer)); ++error; } else if (!S_ISDIR(st.st_mode)) { unsuccesful = 1; - log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc(dir->sub)); + log_tag("dir_error:%s:%s: Dir error for not directory\n", disk->name, esc(dir->sub, esc_buffer)); ++error; } @@ -1744,10 +1749,10 @@ static int state_check_process(struct snapraid_state* state, int fix, struct sna /* LCOV_EXCL_STOP */ } - log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc(dir->sub)); + log_tag("dir_fixed:%s:%s: Fixed dir error\n", disk->name, esc(dir->sub, esc_buffer)); ++recovered_error; - log_tag("status:recovered:%s:%s\n", disk->name, esc(dir->sub)); + log_tag("status:recovered:%s:%s\n", disk->name, esc(dir->sub, esc_buffer)); msg_info("recovered %s%s\n", disk->dir, dir->sub); } } @@ -1763,7 +1768,7 @@ bail: ret = handle_close(&handle[j]); if (ret == -1) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); ++unrecoverable_error; /* continue, as we are already exiting */ diff --git a/cmdline/device.c b/cmdline/device.c index 1d4d572f..bb04089b 100644 --- a/cmdline/device.c +++ b/cmdline/device.c @@ -608,6 +608,7 @@ static void state_smart(unsigned n, tommy_list* low) int make_it_fail = 0; uint64_t mask32 = 0xffffffffU; uint64_t mask16 = 0xffffU; + char esc_buffer[ESC_MAX]; /* compute lengths for padding */ device_pad = 0; @@ -746,7 +747,7 @@ static void state_smart(unsigned n, tommy_list* low) log_tag("smart:%s:%s\n", devinfo->file, devinfo->name); if (devinfo->smart_serial[0]) - log_tag("attr:%s:%s:serial:%s\n", devinfo->file, devinfo->name, esc(devinfo->smart_serial)); + log_tag("attr:%s:%s:serial:%s\n", devinfo->file, devinfo->name, esc(devinfo->smart_serial, esc_buffer)); if (afr != 0) log_tag("attr:%s:%s:afr:%g\n", devinfo->file, devinfo->name, afr); if (devinfo->smart[SMART_SIZE] != SMART_UNASSIGNED) diff --git a/cmdline/dry.c b/cmdline/dry.c index cfe33da5..521703ce 100644 --- a/cmdline/dry.c +++ b/cmdline/dry.c @@ -48,6 +48,7 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task block_off_t blockcur = task->position; unsigned char* buffer = task->buffer; int ret; + char esc_buffer[ESC_MAX]; /* if the disk position is not used */ if (!disk) { @@ -81,7 +82,7 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -89,7 +90,7 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task return; } - log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -103,7 +104,7 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to dry.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -112,7 +113,7 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task /* LCOV_EXCL_STOP */ } - log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } @@ -120,13 +121,13 @@ static void dry_data_reader(struct snapraid_worker* worker, struct snapraid_task task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); if (task->read_size == -1) { if (errno == EIO) { - log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); task->state = TASK_STATE_IOERROR_CONTINUE; return; } - log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } @@ -182,6 +183,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit unsigned l; unsigned* waiting_map; unsigned waiting_mac; + char esc_buffer[ESC_MAX]; handle = handle_mapping(state, &diskmax); @@ -358,7 +360,7 @@ bail: ret = handle_close(&handle[j]); if (ret == -1) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); ++error; /* continue, as we are already exiting */ diff --git a/cmdline/dup.c b/cmdline/dup.c index 1a33055e..b669436f 100644 --- a/cmdline/dup.c +++ b/cmdline/dup.c @@ -92,6 +92,8 @@ void state_dup(struct snapraid_state* state) tommy_node* i; unsigned count; data_off_t size; + char esc_buffer[ESC_MAX]; + char esc_buffer_alt[ESC_MAX]; tommy_hashdyn_init(&hashset); @@ -127,7 +129,7 @@ void state_dup(struct snapraid_state* state) if (found) { ++count; size += found->file->size; - log_tag("dup:%s:%s:%s:%s:%" PRIu64 ": dup\n", disk->name, esc(file->sub), found->disk->name, esc(found->file->sub), found->file->size); + log_tag("dup:%s:%s:%s:%s:%" PRIu64 ": dup\n", disk->name, esc(file->sub, esc_buffer), found->disk->name, esc(found->file->sub, esc_buffer_alt), found->file->size); printf("%12" PRIu64 " %s%s = %s%s\n", file->size, disk->dir, file->sub, found->disk->dir, found->file->sub); hash_free(hash); } else { diff --git a/cmdline/list.c b/cmdline/list.c index 558fdfa6..7616d7c4 100644 --- a/cmdline/list.c +++ b/cmdline/list.c @@ -32,6 +32,8 @@ void state_list(struct snapraid_state* state) unsigned file_count; data_off_t file_size; unsigned link_count; + char esc_buffer[ESC_MAX]; + char esc_buffer_alt[ESC_MAX]; file_count = 0; file_size = 0; @@ -59,7 +61,7 @@ void state_list(struct snapraid_state* state) ++file_count; file_size += file->size; - log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub), file->size, file->mtime_sec, file->mtime_nsec, file->inode); + log_tag("file:%s:%s:%" PRIu64 ":%" PRIi64 ":%u:%" PRIi64 "\n", disk->name, esc(file->sub, esc_buffer), file->size, file->mtime_sec, file->mtime_nsec, file->inode); t = file->mtime_sec; #if HAVE_LOCALTIME_R @@ -98,7 +100,7 @@ void state_list(struct snapraid_state* state) ++link_count; - log_tag("link_%s:%s:%s:%s\n", type, disk->name, esc(slink->sub), esc(slink->linkto)); + log_tag("link_%s:%s:%s:%s\n", type, disk->name, esc(slink->sub, esc_buffer), esc(slink->linkto, esc_buffer_alt)); printf("%12s ", type); printf(" "); diff --git a/cmdline/parity.c b/cmdline/parity.c index 8ef1f54b..12de22c9 100644 --- a/cmdline/parity.c +++ b/cmdline/parity.c @@ -116,6 +116,7 @@ void parity_overflow(struct snapraid_state* state, data_off_t size) tommy_node* i; block_off_t blockalloc; int first = 1; + char esc_buffer[ESC_MAX]; /* don't report if everything is outside or if the file is not accessible */ if (size == 0) { @@ -136,7 +137,7 @@ void parity_overflow(struct snapraid_state* state, data_off_t size) if (file->blockmax > 0) { block_off_t parity_pos = fs_file2par_get(disk, file, file->blockmax - 1); if (parity_pos >= blockalloc) { - log_tag("outofparity:%s:%s\n", disk->name, esc(file->sub)); + log_tag("outofparity:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); if (first) { first = 0; log_fatal("\nYour data requires more parity than the available space.\n"); diff --git a/cmdline/scan.c b/cmdline/scan.c index 40e66d22..881773e4 100644 --- a/cmdline/scan.c +++ b/cmdline/scan.c @@ -88,6 +88,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub, struct snapraid_state* state = scan->state; struct snapraid_disk* disk = scan->disk; struct snapraid_link* slink; + char esc_buffer[ESC_MAX]; /* check if the link already exists */ slink = tommy_hashdyn_search(&disk->linkset, link_name_compare_to_arg, sub, link_name_hash(sub)); @@ -109,7 +110,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub, ++scan->count_equal; if (state->opt.gui) { - log_tag("scan:equal:%s:%s\n", disk->name, esc(slink->sub)); + log_tag("scan:equal:%s:%s\n", disk->name, esc(slink->sub, esc_buffer)); } } else { /* it's an update */ @@ -119,7 +120,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub, ++scan->count_change; - log_tag("scan:update:%s:%s\n", disk->name, esc(slink->sub)); + log_tag("scan:update:%s:%s\n", disk->name, esc(slink->sub, esc_buffer)); if (is_diff) { printf("update %s%s\n", disk->dir, slink->sub); } @@ -136,7 +137,7 @@ static void scan_link(struct snapraid_scan* scan, int is_diff, const char* sub, /* create the new link */ ++scan->count_insert; - log_tag("scan:add:%s:%s\n", disk->name, esc(sub)); + log_tag("scan:add:%s:%s\n", disk->name, esc(sub, esc_buffer)); if (is_diff) { printf("add %s%s\n", disk->dir, sub); } @@ -614,6 +615,8 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, int64_t file_already_present_mtime_sec; int file_already_present_mtime_nsec; int is_file_reported; + char esc_buffer[ESC_MAX]; + char esc_buffer_alt[ESC_MAX]; /* * If the disk has persistent inodes and UUID, try a search on the past inodes, @@ -694,7 +697,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, /* if the path is different, it means a moved file with the same inode */ ++scan->count_move; - log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub), esc(sub)); + log_tag("scan:move:%s:%s:%s\n", disk->name, esc(file->sub, esc_buffer), esc(sub, esc_buffer_alt)); if (is_diff) { printf("move %s%s -> %s%s\n", disk->dir, file->sub, disk->dir, sub); } @@ -715,7 +718,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, ++scan->count_equal; if (state->opt.gui) { - log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); + log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); } } @@ -831,7 +834,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, /* like when restoring a backup that restores also the timestamp */ ++scan->count_restore; - log_tag("scan:restore:%s:%s\n", disk->name, esc(sub)); + log_tag("scan:restore:%s:%s\n", disk->name, esc(sub, esc_buffer)); if (is_diff) { printf("restore %s%s\n", disk->dir, sub); } @@ -854,7 +857,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, ++scan->count_equal; if (state->opt.gui) { - log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub)); + log_tag("scan:equal:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); } } @@ -946,7 +949,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, /* revert old counter and use the copy one */ ++scan->count_copy; - log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub), disk->name, esc(file->sub)); + log_tag("scan:copy:%s:%s:%s:%s\n", other_disk->name, esc(other_file->sub, esc_buffer), disk->name, esc(file->sub, esc_buffer_alt)); if (is_diff) { printf("copy %s%s -> %s%s\n", other_disk->dir, other_file->sub, disk->dir, file->sub); } @@ -966,7 +969,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, if (is_file_already_present) { ++scan->count_change; - log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc(sub), + log_tag("scan:update:%s:%s: %" PRIu64 " %" PRIu64 ".%d -> %" PRIu64 " %" PRIu64 ".%d\n", disk->name, esc(sub, esc_buffer), (uint64_t)file_already_present_size, (uint64_t)file_already_present_mtime_sec, file_already_present_mtime_nsec, (uint64_t)file->size, (uint64_t)file->mtime_sec, file->mtime_nsec ); @@ -977,7 +980,7 @@ static void scan_file(struct snapraid_scan* scan, int is_diff, const char* sub, } else { ++scan->count_insert; - log_tag("scan:add:%s:%s\n", disk->name, esc(sub)); + log_tag("scan:add:%s:%s\n", disk->name, esc(sub, esc_buffer)); if (is_diff) { printf("add %s%s\n", disk->dir, sub); } @@ -1425,6 +1428,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff) fptr* msg; struct snapraid_scan total; int no_difference; + char esc_buffer[ESC_MAX]; tommy_list_init(&scanlist); @@ -1522,7 +1526,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff) if (!file_flag_has(file, FILE_IS_PRESENT)) { ++scan->count_remove; - log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub)); + log_tag("scan:remove:%s:%s\n", disk->name, esc(file->sub, esc_buffer)); if (is_diff) { printf("remove %s%s\n", disk->dir, file->sub); } @@ -1543,7 +1547,7 @@ static int state_diffscan(struct snapraid_state* state, int is_diff) if (!link_flag_has(slink, FILE_IS_PRESENT)) { ++scan->count_remove; - log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub)); + log_tag("scan:remove:%s:%s\n", disk->name, esc(slink->sub, esc_buffer)); if (is_diff) { printf("remove %s%s\n", disk->dir, slink->sub); } diff --git a/cmdline/scrub.c b/cmdline/scrub.c index b85e1097..c5657457 100644 --- a/cmdline/scrub.c +++ b/cmdline/scrub.c @@ -111,6 +111,7 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta block_off_t blockcur = task->position; unsigned char* buffer = task->buffer; int ret; + char esc_buffer[ESC_MAX]; /* if the disk position is not used */ if (!disk) { @@ -144,7 +145,7 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -152,7 +153,7 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta return; } - log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -166,7 +167,7 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to scrub.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -175,7 +176,7 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta /* LCOV_EXCL_STOP */ } - log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } @@ -198,13 +199,13 @@ static void scrub_data_reader(struct snapraid_worker* worker, struct snapraid_ta task->read_size = handle_read(handle, task->file_pos, buffer, state->block_size, log_error, 0); if (task->read_size == -1) { if (errno == EIO) { - log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); task->state = TASK_STATE_IOERROR_CONTINUE; return; } - log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); task->state = TASK_STATE_ERROR_CONTINUE; return; } @@ -266,6 +267,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par unsigned l; unsigned* waiting_map; unsigned waiting_mac; + char esc_buffer[ESC_MAX]; /* maps the disks to handles */ handle = handle_mapping(state, &diskmax); @@ -467,7 +469,7 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par if (memcmp(hash, block->hash, HASH_SIZE) != 0) { unsigned diff = memdiff(hash, block->hash, HASH_SIZE); - log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc(file->sub), file_pos, diff); + log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc(file->sub, esc_buffer), file_pos, diff); /* it's a silent error only if we are dealing with synced files */ if (file_is_unsynced) { @@ -675,7 +677,7 @@ bail: ret = handle_close(&handle[j]); if (ret == -1) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); ++error; /* continue, as we are already exiting */ diff --git a/cmdline/support.c b/cmdline/support.c index a418e073..dc1260ff 100644 --- a/cmdline/support.c +++ b/cmdline/support.c @@ -379,21 +379,6 @@ void printp(double v, size_t pad) printl(buf, pad); } -/** - * Number of buffers for esc(). - */ -#define ESC_MAX 4 - -/** - * Buffer table to allow multiple calls to esc(). - */ -static char esc_table[ESC_MAX][PATH_MAX*2+1]; - -/** - * Next buffer to use. - */ -static unsigned esc_index = 0; - #define ESCAPE(from,to) \ case from : \ if (p == end) \ @@ -404,15 +389,12 @@ static unsigned esc_index = 0; *p++ = to; \ break -const char* esc(const char* str) +const char* esc(const char* str, char* buffer) { - char* begin = esc_table[esc_index]; - char* end = begin + PATH_MAX; + char* begin = buffer; + char* end = begin + ESC_MAX; char* p = begin; - /* next call uses the next buffer */ - esc_index = (esc_index + 1) % ESC_MAX; - /* copy string with escaping */ while (*str) { char c = *str; diff --git a/cmdline/support.h b/cmdline/support.h index 6a3ca997..fc84f5bc 100644 --- a/cmdline/support.h +++ b/cmdline/support.h @@ -213,12 +213,16 @@ void printp(double v, size_t pad); /****************************************************************************/ /* escape */ +#define ESC_MAX (PATH_MAX*2+1) + /** * Escape a string. * + * \param buffer Preallocated buffer of ESC_MAX size. + * * Chars ':', '\n', '\r' and '\' are escaped to '\d', '\\n', '\\r' and '\\'. */ -const char* esc(const char* str); +const char* esc(const char* str, char* buffer); /** * Polish a string. diff --git a/cmdline/sync.c b/cmdline/sync.c index 43f474b4..5a4c750c 100644 --- a/cmdline/sync.c +++ b/cmdline/sync.c @@ -42,6 +42,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta unsigned error; unsigned silent_error; unsigned io_error; + char esc_buffer[ESC_MAX]; /* maps the disks to handles */ handle = handle_mapping(state, &diskmax); @@ -137,7 +138,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close EIO error. %s\n", i, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path); log_fatal("Stopping at block %u\n", i); @@ -145,7 +146,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta goto bail; } - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle[j].path); log_fatal("Stopping at block %u\n", i); @@ -159,7 +160,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EIO error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path); log_fatal("Stopping at block %u\n", i); @@ -169,7 +170,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta } if (errno == ENOENT) { - log_tag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open ENOENT error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_error("Missing file '%s'.\n", handle[j].path); log_error("WARNING! You cannot modify data disk during a sync.\n"); log_error("Rerun the sync command when finished.\n"); @@ -180,7 +181,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta } if (errno == EACCES) { - log_tag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EACCES error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_error("No access at file '%s'.\n", handle[j].path); log_error("WARNING! Please fix the access permission in the data disk.\n"); log_error("Rerun the sync command when finished.\n"); @@ -190,7 +191,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta } /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle[j].path); log_fatal("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub); @@ -205,7 +206,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta || STAT_NSEC(&handle[j].st) != file->mtime_nsec || handle[j].st.st_ino != file->inode ) { - log_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub)); + log_tag("error:%u:%s:%s: Unexpected attribute change\n", i, disk->name, esc(file->sub, esc_buffer)); if (handle[j].st.st_size != file->size) { log_error("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle[j].path, file->size, handle[j].st.st_size); } else if (handle[j].st.st_mtime != file->mtime_sec @@ -226,7 +227,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta if (read_size == -1) { /* LCOV_EXCL_START */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub), file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", i, disk->name, esc(file->sub, esc_buffer), file_pos, strerror(errno)); log_fatal("DANGER! Unexpected input/output read error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be read.\n", disk->dir, handle[j].path); log_fatal("Stopping at block %u\n", i); @@ -234,7 +235,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta goto bail; } - log_tag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub), file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read error at position %u. %s\n", i, disk->name, esc(file->sub, esc_buffer), file_pos, strerror(errno)); log_fatal("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be read.\n", handle[j].path); log_fatal("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub); @@ -261,7 +262,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta if (block_state == BLOCK_STATE_REP) { /* compare the hash */ if (memcmp(hash, block->hash, HASH_SIZE) != 0) { - log_tag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub)); + log_tag("error:%u:%s:%s: Unexpected data change\n", i, disk->name, esc(file->sub, esc_buffer)); log_error("Data change at file '%s' at position '%u'\n", handle[j].path, file_pos); log_error("WARNING! Unexpected data modification of a file without parity!\n"); @@ -317,7 +318,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockmax, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockmax, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle[j].path); log_fatal("Stopping at block %u\n", blockmax); @@ -325,7 +326,7 @@ static int state_hash_process(struct snapraid_state* state, block_off_t blocksta goto bail; } - log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockmax, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle[j].path); log_fatal("Stopping at block %u\n", blockmax); @@ -372,7 +373,7 @@ bail: struct snapraid_disk* disk = handle[j].disk; ret = handle_close(&handle[j]); if (ret == -1) { - log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", i, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); ++error; /* continue, as we are already exiting */ @@ -478,6 +479,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas block_off_t blockcur = task->position; unsigned char* buffer = task->buffer; int ret; + char esc_buffer[ESC_MAX]; /* if the disk position is not used */ if (!disk) { @@ -512,7 +514,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close EIO error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -520,7 +522,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas return; } - log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(report->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected close error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -534,7 +536,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas if (ret == -1) { if (errno == EIO) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EIO error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected input/output open error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", disk->dir, handle->path); log_fatal("Stopping at block %u\n", blockcur); @@ -544,7 +546,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas } if (errno == ENOENT) { - log_tag("error:%u:%s:%s: Open ENOENT error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open ENOENT error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_error("Missing file '%s'.\n", handle->path); log_error("WARNING! You cannot modify data disk during a sync.\n"); log_error("Rerun the sync command when finished.\n"); @@ -555,7 +557,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas } if (errno == EACCES) { - log_tag("error:%u:%s:%s: Open EACCES error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open EACCES error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_error("No access at file '%s'.\n", handle->path); log_error("WARNING! Please fix the access permission in the data disk.\n"); log_error("Rerun the sync command when finished.\n"); @@ -565,7 +567,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas } /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Open error. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), strerror(errno)); log_fatal("WARNING! Unexpected open error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be accessed.\n", handle->path); log_fatal("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", task->file->sub); @@ -580,7 +582,7 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas || STAT_NSEC(&handle->st) != task->file->mtime_nsec || handle->st.st_ino != task->file->inode ) { - log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc(task->file->sub)); + log_tag("error:%u:%s:%s: Unexpected attribute change\n", blockcur, disk->name, esc(task->file->sub, esc_buffer)); if (handle->st.st_size != task->file->size) { log_error("Unexpected size change at file '%s' from %" PRIu64 " to %" PRIu64 ".\n", handle->path, task->file->size, handle->st.st_size); } else if (handle->st.st_mtime != task->file->mtime_sec @@ -601,13 +603,13 @@ static void sync_data_reader(struct snapraid_worker* worker, struct snapraid_tas if (task->read_size == -1) { /* LCOV_EXCL_START */ if (errno == EIO) { - log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read EIO error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_error("Input/Output error in file '%s' at position '%u'\n", handle->path, task->file_pos); task->state = TASK_STATE_IOERROR_CONTINUE; return; } - log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub), task->file_pos, strerror(errno)); + log_tag("error:%u:%s:%s: Read error at position %u. %s\n", blockcur, disk->name, esc(task->file->sub, esc_buffer), task->file_pos, strerror(errno)); log_fatal("WARNING! Unexpected read error in a data disk, it isn't possible to sync.\n"); log_fatal("Ensure that file '%s' can be read.\n", handle->path); log_fatal("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", task->file->sub); @@ -686,6 +688,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari unsigned l; unsigned* waiting_map; unsigned waiting_mac; + char esc_buffer[ESC_MAX]; /* the sync process assumes that all the hashes are correct */ /* including the ones from CHG and DELETED blocks */ @@ -931,7 +934,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari if (memcmp(hash, block->hash, HASH_SIZE) != 0) { /* if the file has invalid parity, it's a REP changed during the sync */ if (block_has_invalid_parity(block)) { - log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc(file->sub)); + log_tag("error:%u:%s:%s: Unexpected data change\n", blockcur, disk->name, esc(file->sub, esc_buffer)); log_error("Data change at file '%s' at position '%u'\n", task->path, file_pos); log_error("WARNING! Unexpected data modification of a file without parity!\n"); @@ -952,7 +955,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari continue; } else { /* otherwise it's a BLK with silent error */ unsigned diff = memdiff(hash, block->hash, HASH_SIZE); - log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc(file->sub), file_pos, diff); + log_tag("error:%u:%s:%s: Data error at position %u, diff bits %u\n", blockcur, disk->name, esc(file->sub, esc_buffer), file_pos, diff); log_error("Data error in file '%s' at position '%u', diff bits %u\n", task->path, file_pos, diff); /* save the failed block for the fix */ @@ -1371,7 +1374,7 @@ bail: ret = handle_close(&handle[j]); if (ret == -1) { /* LCOV_EXCL_START */ - log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(file->sub), strerror(errno)); + log_tag("error:%u:%s:%s: Close error. %s\n", blockcur, disk->name, esc(file->sub, esc_buffer), strerror(errno)); log_fatal("DANGER! Unexpected close error in a data disk.\n"); ++error; /* continue, as we are already exiting */ diff --git a/cmdline/touch.c b/cmdline/touch.c index db7cbbbf..031a197b 100644 --- a/cmdline/touch.c +++ b/cmdline/touch.c @@ -25,6 +25,7 @@ void state_touch(struct snapraid_state* state) { tommy_node* i; + char esc_buffer[ESC_MAX]; msg_progress("Setting sub-second timestamps...\n"); @@ -136,7 +137,7 @@ void state_touch(struct snapraid_state* state) /* state changed, we need to update it */ state->need_write = 1; - log_tag("touch:%s:%s: %" PRIu64 ".%d\n", disk->name, esc(file->sub), (uint64_t)st.st_mtime, (int)STAT_NSEC(&st)); + log_tag("touch:%s:%s: %" PRIu64 ".%d\n", disk->name, esc(file->sub, esc_buffer), (uint64_t)st.st_mtime, (int)STAT_NSEC(&st)); msg_info("touch %s%s\n", disk->dir, file->sub); } }