From 52eb4675d35636dd5bf4d8ce4e53b75cefde978c Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Tue, 3 Dec 2013 18:40:19 +0100 Subject: [PATCH] Fixes a crash if a file is deleted during a sync/scrub. --- HISTORY | 3 ++- dry.c | 4 ++-- scrub.c | 10 +++++++--- sync.c | 16 ++++++++++------ 4 files changed, 21 insertions(+), 12 deletions(-) diff --git a/HISTORY b/HISTORY index 81b0d8cc..51f76c7a 100644 --- a/HISTORY +++ b/HISTORY @@ -3,7 +3,8 @@ SnapRAID HISTORY 5.1 2013/12 (BETA) ================== - * Fixed the -C, --gen-conf command. + * Fixed a crash if a file is deleted during a sync/scrub. + * Fixed a crash in the -C, --gen-conf command. * Prints the files with duplicate physical offset if the -v, --verbose option is specified. diff --git a/dry.c b/dry.c index efa498dd..9746c975 100644 --- a/dry.c +++ b/dry.c @@ -71,7 +71,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit /* close the old one, if any */ ret = handle_close(&handle[j]); if (ret == -1) { - fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to rehash.\n"); + fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to dry.\n"); printf("Stopping at block %u\n", i); ++error; goto bail; @@ -80,7 +80,7 @@ static int state_dry_process(struct snapraid_state* state, struct snapraid_parit /* open the file only for reading */ ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stdlog); if (ret == -1) { - fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to rehash.\n"); + fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to dry.\n"); printf("Stopping at block %u\n", i); ++error; goto bail; diff --git a/scrub.c b/scrub.c index 7f267bb2..991e579e 100644 --- a/scrub.c +++ b/scrub.c @@ -216,12 +216,14 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par } /* if the file is different than the current one, close it */ - if (handle[j].file != block_file_get(block)) { + if (handle[j].file != 0 && handle[j].file != block_file_get(block)) { + /* keep a pointer at the file we are going to close for error reporting */ + struct snapraid_file* file = handle[j].file; ret = handle_close(&handle[j]); if (ret == -1) { /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ - fprintf(stdlog, "error:%u:%s:%s: Close error. %s\n", i, handle[j].disk->name, handle[j].file->sub, strerror(errno)); + fprintf(stdlog, "error:%u:%s:%s: Close error. %s\n", i, handle[j].disk->name, file->sub, strerror(errno)); fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to scrub.\n"); printf("Stopping at block %u\n", i); ++error; @@ -231,7 +233,9 @@ static int state_scrub_process(struct snapraid_state* state, struct snapraid_par ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stderr); if (ret == -1) { - fprintf(stdlog, "error:%u:%s:%s: Open error. %s\n", i, handle[j].disk->name, handle[j].file->sub, strerror(errno)); + /* file we have tried to open for error reporting */ + struct snapraid_file* file = block_file_get(block); + fprintf(stdlog, "error:%u:%s:%s: Open error. %s\n", i, handle[j].disk->name, file->sub, strerror(errno)); ++error; error_on_this_block = 1; continue; diff --git a/sync.c b/sync.c index e66fe373..02cbae20 100644 --- a/sync.c +++ b/sync.c @@ -232,12 +232,14 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari } /* if the file is different than the current one, close it */ - if (handle[j].file != block_file_get(block)) { + if (handle[j].file != 0 && handle[j].file != block_file_get(block)) { + /* keep a pointer at the file we are going to close for error reporting */ + struct snapraid_file* file = handle[j].file; ret = handle_close(&handle[j]); if (ret == -1) { /* This one is really an unexpected error, because we are only reading */ /* and closing a descriptor should never fail */ - fprintf(stdlog, "error:%u:%s:%s: Close error. %s\n", i, handle[j].disk->name, handle[j].file->sub, strerror(errno)); + fprintf(stdlog, "error:%u:%s:%s: Close error. %s\n", i, handle[j].disk->name, file->sub, strerror(errno)); fprintf(stderr, "DANGER! Unexpected close error in a data disk, it isn't possible to sync.\n"); fprintf(stderr, "Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", handle[j].disk->dir, handle[j].path); printf("Stopping at block %u\n", i); @@ -248,8 +250,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari ret = handle_open(&handle[j], block_file_get(block), state->opt.skip_sequential, stderr); if (ret == -1) { + /* file we have tried to open for error reporting */ + struct snapraid_file* file = block_file_get(block); if (errno == ENOENT) { - fprintf(stdlog, "error:%u:%s:%s: Open missing error\n", i, handle[j].disk->name, handle[j].file->sub); + fprintf(stdlog, "error:%u:%s:%s: Open missing error\n", i, handle[j].disk->name, file->sub); fprintf(stderr, "Missing file '%s'.\n", handle[j].path); fprintf(stderr, "WARNING! You cannot modify data disk during a sync.\n"); fprintf(stderr, "Rerun the sync command when finished.\n"); @@ -261,7 +265,7 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari error_on_this_block = 1; continue; } else if (errno == EACCES) { - fprintf(stdlog, "error:%u:%s:%s: Open access error\n", i, handle[j].disk->name, handle[j].file->sub); + fprintf(stdlog, "error:%u:%s:%s: Open access error\n", i, handle[j].disk->name, file->sub); fprintf(stderr, "No access at file '%s'.\n", handle[j].path); fprintf(stderr, "WARNING! Please fix the access permission in the data disk.\n"); fprintf(stderr, "Rerun the sync command when finished.\n"); @@ -272,10 +276,10 @@ static int state_sync_process(struct snapraid_state* state, struct snapraid_pari error_on_this_block = 1; continue; } else { - fprintf(stdlog, "error:%u:%s:%s: Open error. %s\n", i, handle[j].disk->name, handle[j].file->sub, strerror(errno)); + fprintf(stdlog, "error:%u:%s:%s: Open error. %s\n", i, handle[j].disk->name, file->sub, strerror(errno)); fprintf(stderr, "DANGER! Unexpected open error in a data disk, it isn't possible to sync.\n"); fprintf(stderr, "Ensure that disk '%s' is sane and that file '%s' can be accessed.\n", handle[j].disk->dir, handle[j].path); - printf("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", handle[j].file->sub); + printf("Stopping to allow recovery. Try with 'snapraid check -f %s'\n", file->sub); } ++error;