mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Adds the -t option to limit the number of blocks processed.
More tests with incomplete sync.
This commit is contained in:
parent
25841deb04
commit
87bb5c7a66
9 changed files with 93 additions and 557 deletions
11
Makefile.am
11
Makefile.am
|
|
@ -82,6 +82,17 @@ check-local:
|
|||
$(TESTENV) ./mktest$(EXEEXT) generate 3 3 100 4000
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Delete some files and create some new, sync and check in multiple steps
|
||||
rm test/disk1/4*
|
||||
rm test/disk2/5*
|
||||
rm test/disk2/6*
|
||||
$(TESTENV) ./mktest$(EXEEXT) generate 4 3 100 4000
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf -t 7 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf -t 11 sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf sync
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check
|
||||
echo --- Delete some files, fix and check
|
||||
rm test/disk1/1*
|
||||
$(TESTENV) ./snapraid$(EXEEXT) -c $(srcdir)/test.conf check 2>/dev/null
|
||||
|
|
|
|||
23
check.c
23
check.c
|
|
@ -66,6 +66,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
struct snapraid_block* failed_block;
|
||||
struct snapraid_handle* failed_handle;
|
||||
int one_hash;
|
||||
int all_parity;
|
||||
|
||||
/* for each disk */
|
||||
one_hash = 0;
|
||||
|
|
@ -73,6 +74,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
struct snapraid_block* block = disk_block_get(handle[j].disk, i);
|
||||
if (block && bit_has(block->flag, BLOCK_HAS_HASH)) {
|
||||
one_hash = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -83,10 +85,12 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
/* start with 0 */
|
||||
memset(xor_buffer, 0, state->block_size);
|
||||
|
||||
/* for each disk, process the block */
|
||||
failed = 0;
|
||||
failed_block = 0;
|
||||
all_parity = 1; /* if all hashed block have parity computed */
|
||||
failed = 0; /* number of failed block */
|
||||
failed_block = 0; /* last failed block */
|
||||
failed_handle = 0;
|
||||
|
||||
/* for each disk, process the block */
|
||||
for(j=0;j<diskmax;++j) {
|
||||
int read_size;
|
||||
struct md5_t md5;
|
||||
|
|
@ -103,6 +107,10 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
if (!bit_has(block->flag, BLOCK_HAS_HASH))
|
||||
continue;
|
||||
|
||||
/* keep track if at least one hashed block has no parity */
|
||||
if (!bit_has(block->flag, BLOCK_HAS_PARITY))
|
||||
all_parity = 0;
|
||||
|
||||
ret = handle_close_if_different(&handle[j], block->file);
|
||||
if (ret == -1) {
|
||||
fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
|
||||
|
|
@ -170,7 +178,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
|
|||
count_size += read_size;
|
||||
}
|
||||
|
||||
if (parity_f == -1) {
|
||||
if (parity_f == -1 || !all_parity) {
|
||||
/* all the cases with no parity file */
|
||||
if (failed != 0) {
|
||||
fprintf(stderr, "%u: UNRECOVERABLE errors for this block\n", i);
|
||||
|
|
@ -320,7 +328,7 @@ bail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart)
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
block_off_t blockmax;
|
||||
|
|
@ -342,6 +350,11 @@ void state_check(struct snapraid_state* state, int fix, block_off_t blockstart)
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
pathcpy(path, sizeof(path), state->parity);
|
||||
if (fix) {
|
||||
/* if fixing, create the file and open for writing */
|
||||
|
|
|
|||
20
snapraid.1
20
snapraid.1
|
|
@ -2,13 +2,17 @@
|
|||
.SH NAME
|
||||
snapraid \(hy SnapRAID Backup For Disk Arrays
|
||||
.SH SYNOPSIS
|
||||
snapraid [\(hyc, \(hy\(hyconf CONFIG] [\(hys, \(hy\(hystart BLOCK]
|
||||
snapraid [\(hyc, \(hy\(hyconf CONFIG]
|
||||
.PD 0
|
||||
.PP
|
||||
.PD
|
||||
[\(hyZ, \(hy\(hyforce\(hyzero] [\(hyE, \(hy\(hyforce\(hyempty]
|
||||
.PD 0
|
||||
.PP
|
||||
.PD
|
||||
[\(hys, \(hy\(hystart BLKSTART] [\(hyt, \(hy\(hycount BLKCOUNT]
|
||||
.PD 0
|
||||
.PP
|
||||
.PD
|
||||
[\(hyv, \(hy\(hyverbose]
|
||||
.PD 0
|
||||
|
|
@ -237,11 +241,6 @@ Selects the configuration file. If not specified is assumed
|
|||
the file \(cq/etc/snapraid.conf\(cq in Unix, and \(cqsnapraid.conf\(cq
|
||||
in Windows.
|
||||
.TP
|
||||
.B \(hys, \(hy\(hystart BLOCK
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check or
|
||||
fix some specific block, in case of a damaged disk.
|
||||
.TP
|
||||
.B \(hyZ, \(hy\(hyforce\(hyzero
|
||||
Forces the insecure operation of syncing a file with zero
|
||||
size that before was not empty.
|
||||
|
|
@ -258,6 +257,15 @@ unless you specify this option.
|
|||
This allows to easily detect when a data file\(hysystem is not
|
||||
mounted.
|
||||
.TP
|
||||
.B \(hys, \(hy\(hystart BLKSTART
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check
|
||||
or fix some specific block, in case of a damaged disk.
|
||||
.TP
|
||||
.B \(hyt, \(hy\(hycount BLKCOUNT
|
||||
Process only the specified number of blocks.
|
||||
It\(cqs present mainly for testing.
|
||||
.TP
|
||||
.B \(hyv, \(hy\(hyverbose
|
||||
Prints more information in the processing.
|
||||
.TP
|
||||
|
|
|
|||
30
snapraid.c
30
snapraid.c
|
|
@ -43,19 +43,21 @@ void usage(void) {
|
|||
printf("Usage: " PACKAGE " [options]\n");
|
||||
printf("\n");
|
||||
printf("Options:\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-s, --start BLK ", "-s") " Start from the specified block number\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("-v, --verbose ", "-v") " Verbose\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-h, --help ", "-h") " Help\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-V, --version ", "-V") " Version\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-c, --conf FILE ", "-c") " Configuration file (default " CONF ")\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("-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("-v, --verbose ", "-v") " Verbose\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-h, --help ", "-h") " Help\n");
|
||||
printf(" " SWITCH_GETOPT_LONG("-V, --version ", "-V") " Version\n");
|
||||
}
|
||||
|
||||
#if HAVE_GETOPT_LONG
|
||||
struct option long_options[] = {
|
||||
{ "conf", 1, 0, 'c' },
|
||||
{ "start", 1, 0, 's' },
|
||||
{ "count", 1, 0, 't' },
|
||||
{ "force-zero", 0, 0, 'Z' },
|
||||
{ "force-empty", 0, 0, 'E' },
|
||||
{ "verbose", 0, 0, 'v' },
|
||||
|
|
@ -65,7 +67,7 @@ struct option long_options[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#define OPTIONS "c:s:ZEvhV"
|
||||
#define OPTIONS "c:s:t:ZEvhV"
|
||||
|
||||
volatile int global_interrupt = 0;
|
||||
|
||||
|
|
@ -92,6 +94,7 @@ int main(int argc, char* argv[])
|
|||
struct snapraid_state state;
|
||||
int operation;
|
||||
block_off_t blockstart;
|
||||
block_off_t blockcount;
|
||||
int ret;
|
||||
|
||||
/* intercept Ctrl+C */
|
||||
|
|
@ -103,6 +106,7 @@ int main(int argc, char* argv[])
|
|||
force_zero = 0;
|
||||
force_empty = 0;
|
||||
blockstart = 0;
|
||||
blockcount = 0;
|
||||
|
||||
opterr = 0;
|
||||
while ((c =
|
||||
|
|
@ -122,6 +126,12 @@ int main(int argc, char* argv[])
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 't' :
|
||||
if (stru32(optarg, &blockcount) != 0) {
|
||||
fprintf(stderr, "Invalid count number '%s'\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'Z' :
|
||||
force_zero = 1;
|
||||
break;
|
||||
|
|
@ -168,7 +178,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
state_scan(&state);
|
||||
|
||||
ret = state_sync(&state, blockstart);
|
||||
ret = state_sync(&state, blockstart, blockcount);
|
||||
|
||||
/* save the new state if required */
|
||||
if (state.need_write)
|
||||
|
|
@ -180,7 +190,7 @@ int main(int argc, char* argv[])
|
|||
} else {
|
||||
state_read(&state);
|
||||
|
||||
state_check(&state, operation == OPERATION_FIX, blockstart);
|
||||
state_check(&state, operation == OPERATION_FIX, blockstart, blockcount);
|
||||
}
|
||||
|
||||
state_done(&state);
|
||||
|
|
|
|||
17
snapraid.d
17
snapraid.d
|
|
@ -2,8 +2,9 @@ Name{number}
|
|||
snapraid - SnapRAID Backup For Disk Arrays
|
||||
|
||||
Synopsis
|
||||
:snapraid [-c, --conf CONFIG] [-s, --start BLOCK]
|
||||
:snapraid [-c, --conf CONFIG]
|
||||
: [-Z, --force-zero] [-E, --force-empty]
|
||||
: [-s, --start BLKSTART] [-t, --count BLKCOUNT]
|
||||
: [-v, --verbose]
|
||||
: COMMAND
|
||||
|
||||
|
|
@ -155,11 +156,6 @@ Options
|
|||
the file '/etc/snapraid.conf' in Unix, and 'snapraid.conf'
|
||||
in Windows.
|
||||
|
||||
-s, --start BLOCK
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check or
|
||||
fix some specific block, in case of a damaged disk.
|
||||
|
||||
-Z, --force-zero
|
||||
Forces the insecure operation of syncing a file with zero
|
||||
size that before was not empty.
|
||||
|
|
@ -176,6 +172,15 @@ Options
|
|||
This allows to easily detect when a data file-system is not
|
||||
mounted.
|
||||
|
||||
-s, --start BLKSTART
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check
|
||||
or fix some specific block, in case of a damaged disk.
|
||||
|
||||
-t, --count BLKCOUNT
|
||||
Process only the specified number of blocks.
|
||||
It's present mainly for testing.
|
||||
|
||||
-v, --verbose
|
||||
Prints more information in the processing.
|
||||
|
||||
|
|
|
|||
521
snapraid.html
521
snapraid.html
|
|
@ -1,521 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>SnapRAID Backup For Disk Arrays</title>
|
||||
</head>
|
||||
<body>
|
||||
<center><h2>SnapRAID Backup For Disk Arrays</h2></center>
|
||||
<h2><a name="1">1</a>
|
||||
Synopsis
|
||||
</h2>
|
||||
<pre>
|
||||
snapraid [-c, --conf CONFIG] [-s, --start BLOCK]
|
||||
[-Z, --force-zero] [-E, --force-empty]
|
||||
[-v, --verbose]
|
||||
COMMAND
|
||||
</pre>
|
||||
<p>
|
||||
<pre>
|
||||
snapraid [-V, --version] [-h, --help]
|
||||
</pre>
|
||||
<h2><a name="2">2</a>
|
||||
Description
|
||||
</h2>
|
||||
SnapRAID is a backup program for a disk array using redundancy.
|
||||
<p>
|
||||
SnapRAID uses a disk of the array to store redundancy information,
|
||||
and it allows to recover from a disk failure.
|
||||
<p>
|
||||
SnapRAID is mainly targeted for a home media center, where you have
|
||||
a lot of big files that rarely change.
|
||||
<p>
|
||||
The main features of SnapRAID are:
|
||||
<ul>
|
||||
<li>
|
||||
You can start using SnapRAID with already filled disks.
|
||||
</li>
|
||||
<li>
|
||||
The disks of the array can have different sizes.
|
||||
</li>
|
||||
<li>
|
||||
You can add more disks at the array at any time.
|
||||
</li>
|
||||
<li>
|
||||
If you accidentally delete some files in a disk, you can
|
||||
recover them.
|
||||
</li>
|
||||
<li>
|
||||
If more than one disk fails, you lose the data only on the
|
||||
failed disks. All the data in the other disks is safe.
|
||||
</li>
|
||||
<li>
|
||||
It doesn't lock-in your data. You can stop using SnapRAID at any
|
||||
time without the need to reformat or move data.
|
||||
</li>
|
||||
<li>
|
||||
All your data is hashed to ensure data integrity.
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
The official site of SnapRAID is:
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
<a href="http://snapraid.sourceforge.net">http://snapraid.sourceforge.net</a>
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<h2><a name="3">3</a>
|
||||
Limitations
|
||||
</h2>
|
||||
SnapRAID is in between a RAID and a backup program trying to get the best
|
||||
benefits of them. Altought it also has some limitations that you should
|
||||
consider before using it.
|
||||
<p>
|
||||
The main one, is that if a disk fail, and you haven't recently synched,
|
||||
you may not able to do a complete recover.
|
||||
More specifically, you may be unable to recover up to the size of the
|
||||
amount of the changed or deleted files, from the last sync operation.
|
||||
This happens even if the files changed or deleted are not in the
|
||||
failed disk.
|
||||
New added files don't prevent the recovering of the already existing
|
||||
files. You may only lose the just added files, if they were on the failed
|
||||
disk.
|
||||
<p>
|
||||
This is the reason because SnapRAID is better suited for data that
|
||||
rarely change.
|
||||
<p>
|
||||
Other limitations are:
|
||||
* You have different filesystems for each disk.
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
Using a RAID you have only a big filesystem.
|
||||
</td></tr></table>
|
||||
<ul>
|
||||
<li>
|
||||
It doesn't stripe data.
|
||||
With RAID you get a speed boost with striping.
|
||||
</li>
|
||||
<li>
|
||||
It doesn't support realtime recovery.
|
||||
With RAID you do not have to stop working when a disk fails.
|
||||
</li>
|
||||
<li>
|
||||
It's able to recover damages only from a single disk.
|
||||
With a Backup you are able to recover from a complete
|
||||
failure of the whole disk array.
|
||||
</li>
|
||||
</ul>
|
||||
<h2><a name="4">4</a>
|
||||
Getting Started
|
||||
</h2>
|
||||
To use SnapRAID you need first select one disk of your disk array
|
||||
to dedicate at the redundancy information.
|
||||
<p>
|
||||
You have to pick the biggest disk in the array, as the redundancy
|
||||
information may grow in size as the biggest data disk in the array.
|
||||
<p>
|
||||
This disk will be dedicated to this pourpuse only and you should
|
||||
not store other data on it.
|
||||
<p>
|
||||
Suppose now that you have mounted all your disks in the mount points:
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
/mnt/diskpar <- selected disk for parity
|
||||
/mnt/disk1
|
||||
/mnt/disk2
|
||||
/mnt/disk3
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
you have to create the configuration file /etc/snapraid.conf with
|
||||
the following content:
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
parity /mnt/diskpar/parity
|
||||
content /mnt/diskpar/content
|
||||
disk d1 /mnt/disk1/
|
||||
disk d2 /mnt/disk2/
|
||||
disk d3 /mnt/disk3/
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
At this point you are ready to start the "sync" command to build the
|
||||
redundancy information.
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
snapraid sync
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
This process maty take some hours the first time, depending on the size
|
||||
of the data already present in the disks. If the disks are empty
|
||||
the process is immediate.
|
||||
<p>
|
||||
You can stop it at any time pressing Ctrl+C, and at the next run it
|
||||
will start where interrupted.
|
||||
<p>
|
||||
When this command completes, your data is SAFE.
|
||||
<p>
|
||||
At this point you can start using your data as you like, and peridiocally
|
||||
update the redundancy information running the "sync" command.
|
||||
<p>
|
||||
To check the integrity of your data you can use the "check" command:
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
snapraid check
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
If will read all your data, to check if it's correct.
|
||||
<p>
|
||||
If an error is found, you can use the "fix" command to fix it.
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
snapraid fix
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
Note that the fix command will revert your data at the state of the
|
||||
last "sync" command executed. It works like a snapshot was taken
|
||||
in "sync".
|
||||
<p>
|
||||
In this regard snapraid is more like a backup program than a RAID
|
||||
system. For example, you can use it to recover from an accidentally
|
||||
deleted directory, simply running the fix command.
|
||||
<h2><a name="5">5</a>
|
||||
Commands
|
||||
</h2>
|
||||
SnapRAID provides three simple commands that allow to:
|
||||
<ul>
|
||||
<li>
|
||||
Make a backup/snapshot -> "sync"
|
||||
</li>
|
||||
<li>
|
||||
Check for integrity -> "check"
|
||||
</li>
|
||||
<li>
|
||||
Restore the last backup/snapshot -> "fix".
|
||||
</li>
|
||||
</ul>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
sync
|
||||
</strong></td></tr><tr><td>
|
||||
Updates the redundancy information. All the modified files
|
||||
in the disk array are read, and the redundancy data is
|
||||
updated.
|
||||
You can stop this process at any time pressing Ctrl+C,
|
||||
without losing the work already done.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
check
|
||||
</strong></td></tr><tr><td>
|
||||
Checks all the files the redundancy data. All the files
|
||||
are hashed and compared with the snapshot saved in the
|
||||
previous "sync" command.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
fix
|
||||
</strong></td></tr><tr><td>
|
||||
Checks and fix all the files. It's like "check" but it
|
||||
also tries to fix problems reverting the state of the
|
||||
disk array at the previous "sync" command.
|
||||
</td></tr>
|
||||
</table>
|
||||
<h2><a name="6">6</a>
|
||||
Options
|
||||
</h2>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-c, --conf CONFIG
|
||||
</strong></td></tr><tr><td>
|
||||
Selects the configuration file. If not specified is assumed
|
||||
the file `/etc/snapraid.conf'.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-s, --start BLOCK
|
||||
</strong></td></tr><tr><td>
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check or
|
||||
fix some specific block, in case of a damaged disk.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-Z, --force-zero
|
||||
</strong></td></tr><tr><td>
|
||||
Forces the insecure operation of synching a file with zero
|
||||
size that before was not empty.
|
||||
If SnapRAID detects such condition, it stops proceeding
|
||||
unless you specify this option.
|
||||
This allows to easily detect when after a system crash,
|
||||
some accessed files were zeroed.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-E, --force-empty
|
||||
</strong></td></tr><tr><td>
|
||||
Forces the insecure operation of synching an empty disk
|
||||
that before was not empty.
|
||||
If SnapRAID detects such condition, it stops proceeding
|
||||
unless you specify this option.
|
||||
This allows to easily detect when a data filesystem is not
|
||||
mounted.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-v, --verbose
|
||||
</strong></td></tr><tr><td>
|
||||
Prints more information in the processing.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-h, --help
|
||||
</strong></td></tr><tr><td>
|
||||
Prints a short help screen.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
-V, --version
|
||||
</strong></td></tr><tr><td>
|
||||
Prints the program version.
|
||||
</td></tr>
|
||||
</table>
|
||||
<h2><a name="7">7</a>
|
||||
Configuration
|
||||
</h2>
|
||||
SnapRAID requires a configuration file to know where your disk array
|
||||
is located, and where storing the redundancy information.
|
||||
<p>
|
||||
This configuration file is located in /etc/snapraid.conf and
|
||||
it should contains the following options:
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
parity FILE
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the file to use to store the redundancy information.
|
||||
It must be placed in a disk dedicated for this porpose with
|
||||
as much free space as the biggest disk in the array.
|
||||
Leaving the parity disk reserved for only this file, ensures that
|
||||
it doesn't get fragmented, improving the performance.
|
||||
This option can be used only one time.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
content FILE
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the file to use to store the content of the redundancy
|
||||
organization.
|
||||
It can be placed in the same disk of the parity file, or better
|
||||
in another disk, but NOT in a data disk of the array.
|
||||
This option can be used only one time.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
disk NAME DIR
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the name and the mount point of the disks of the array.
|
||||
NAME is used to identify the disk, and it must be unique.
|
||||
DIR is the mount point of the disk in the filesystem.
|
||||
You can change the mount point as you like, as far you
|
||||
keep the NAME fixed.
|
||||
You should use one option for each disk of the array.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
exclude PATTERN
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the file or directory patterns to exclude from the sync
|
||||
process. See the PATTERN section for more details in the
|
||||
pattern specifications.
|
||||
This option can be used many times.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
block_size SIZE_IN_KIBIBYTES
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the basic block size in kibi bytes of
|
||||
the redundancy blocks. Where one kibi bytes is 1024 bytes.
|
||||
The default is 256 and it should work for most conditions.
|
||||
You increase this value if you do not have enough memory
|
||||
to run SnapRAID.
|
||||
It requires to run something about TS*24/BS bytes, where TS
|
||||
is the total size in bytes of your disk array, and BS is the
|
||||
block size in bytes.
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
For example with 6 disk of 2 TiB and a block size of 256 KiB
|
||||
(1 KiB = 1024 Bytes) you have:
|
||||
</td></tr></table>
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
memory = (6 * 2 * 2^40) * 24 / (256 * 2^10) = 1.1 GiB
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
You should instead decrease this value if you have a lot of
|
||||
small files in the disk array. For each file, even if of few
|
||||
bytes, a whole block is always allocated, so you may have a lot
|
||||
of unused space.
|
||||
</td></tr></table>
|
||||
<p>
|
||||
An example of a typical configuration is:
|
||||
<p>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
parity /mnt/diskpar/parity
|
||||
content /mnt/diskpar/content
|
||||
disk d1 /mnt/disk1/
|
||||
disk d2 /mnt/disk2/
|
||||
disk d3 /mnt/disk3/
|
||||
exclude *.bak
|
||||
exclude /lost+found/
|
||||
exclude tmp/
|
||||
block_size 256
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<h2><a name="8">8</a>
|
||||
Pattern
|
||||
</h2>
|
||||
Patterns are used to define the files and directories to exclude
|
||||
from the redundancy process.
|
||||
<p>
|
||||
It makes sense to exclude any file not worth to be saved or that
|
||||
changes often.
|
||||
<p>
|
||||
There are four different types of patterns:
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
FILE
|
||||
</strong></td></tr><tr><td>
|
||||
Excludes any file named as FILE. You can use any globbing
|
||||
character like * and ?.
|
||||
This pattern is applied only to files and not to directories.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
DIR/
|
||||
</strong></td></tr><tr><td>
|
||||
Excludes any directory named DIR. You can use any globbing
|
||||
character like * and ?.
|
||||
This pattern is applied only to directories and not to files.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
/PATH/FILE
|
||||
</strong></td></tr><tr><td>
|
||||
Excludes the exact specified file path. You can use any
|
||||
globbing character like * and ? but they never matches a
|
||||
directory slash.
|
||||
This pattern is applied only to files and not to directories.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
/PATH/DIR/
|
||||
</strong></td></tr><tr><td>
|
||||
Excludes the exact specified directory path. You can use any
|
||||
globbing character like * and ? but they never matches a
|
||||
directory slash.
|
||||
This pattern is applied only to directories and not to files.
|
||||
</td></tr>
|
||||
</table>
|
||||
<p>
|
||||
For example:
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2"><tr><td width="5%"></td><td width="95%">
|
||||
<pre>
|
||||
# Excludes any file named "*.bak"
|
||||
exclude *.bak
|
||||
# Excludes the root directory "/lost+found"
|
||||
exclude /lost+found/
|
||||
# Excludes any directory named "tmp"
|
||||
exclude tmp/
|
||||
</pre>
|
||||
</td></tr></table>
|
||||
<h2><a name="9">9</a>
|
||||
Content
|
||||
</h2>
|
||||
SnapRAID creates a content file describing the content of your disk array.
|
||||
<p>
|
||||
You should never change it manually, altought the format of this file is
|
||||
described here.
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
blk_size SIZE
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the size of the block in bytes. It must match the size
|
||||
defined in the configuration file.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
file DISK SIZE TIME INODE PATH
|
||||
</strong></td></tr><tr><td>
|
||||
Defines a file in the specified DISK.
|
||||
The INODE number is used to identify the file in the "sync"
|
||||
command, allowing to rename or move the file in disk without
|
||||
the need to recompute the parity for it.
|
||||
The SIZE and TIME information are used to identify if the file
|
||||
changed from the last "sync" command, and if there is the need
|
||||
to recompute the parity.
|
||||
The PATH information is used in the "check" and "fix" commands
|
||||
to identify the file.
|
||||
</td></tr>
|
||||
</table>
|
||||
<table width="100%" border="0" cellspacing="0" cellpadding="2">
|
||||
<tr valign="top" align="left"><td><strong>
|
||||
blk BLOCK HASH
|
||||
</strong></td></tr><tr><td>
|
||||
Defines the ordered parity block list used by the last defined file.
|
||||
BLOCK is the block position in the "parity" file.
|
||||
0 for the first block, 1 for the second one and so on.
|
||||
HASH is the md5 of the block. In the last block of the file,
|
||||
the HASH is the hash of only the used part of the block.
|
||||
</td></tr>
|
||||
</table>
|
||||
<h2><a name="10">10</a>
|
||||
Parity
|
||||
</h2>
|
||||
SnapRAID creates a parity file containing the parity information of your disk array.
|
||||
<p>
|
||||
It's a binary file, containing the parity information of all the blocks defined
|
||||
in the "content" file.
|
||||
<p>
|
||||
For all the blocks at a given position, the parity information is computed with
|
||||
the XOR operator applied to all the blocks.
|
||||
<p>
|
||||
When a file block is shorter than the default block size, for example because it's
|
||||
the last block of a file, it's assumed filled with 0 at the end in the XOR operation.
|
||||
<h2><a name="11">11</a>
|
||||
Copyright
|
||||
</h2>
|
||||
This file is Copyright (C) 2011 Andrea Mazzoleni
|
||||
<h2><a name="12">12</a>
|
||||
See Also
|
||||
</h2>
|
||||
rsync(1)
|
||||
</body>
|
||||
</html>
|
||||
17
snapraid.txt
17
snapraid.txt
|
|
@ -6,8 +6,9 @@
|
|||
1 SYNOPSIS
|
||||
==========
|
||||
|
||||
snapraid [-c, --conf CONFIG] [-s, --start BLOCK]
|
||||
snapraid [-c, --conf CONFIG]
|
||||
[-Z, --force-zero] [-E, --force-empty]
|
||||
[-s, --start BLKSTART] [-t, --count BLKCOUNT]
|
||||
[-v, --verbose]
|
||||
COMMAND
|
||||
|
||||
|
|
@ -174,11 +175,6 @@ SnapRAID provides three simple commands that allow to:
|
|||
the file '/etc/snapraid.conf' in Unix, and 'snapraid.conf'
|
||||
in Windows.
|
||||
|
||||
-s, --start BLOCK
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check or
|
||||
fix some specific block, in case of a damaged disk.
|
||||
|
||||
-Z, --force-zero
|
||||
Forces the insecure operation of syncing a file with zero
|
||||
size that before was not empty.
|
||||
|
|
@ -195,6 +191,15 @@ SnapRAID provides three simple commands that allow to:
|
|||
This allows to easily detect when a data file-system is not
|
||||
mounted.
|
||||
|
||||
-s, --start BLKSTART
|
||||
Starts the processing from the specified
|
||||
block number. It could be useful to easy retry to check
|
||||
or fix some specific block, in case of a damaged disk.
|
||||
|
||||
-t, --count BLKCOUNT
|
||||
Process only the specified number of blocks.
|
||||
It's present mainly for testing.
|
||||
|
||||
-v, --verbose
|
||||
Prints more information in the processing.
|
||||
|
||||
|
|
|
|||
4
state.h
4
state.h
|
|
@ -71,12 +71,12 @@ void state_scan(struct snapraid_state* state);
|
|||
/**
|
||||
* Syncs the parity data.
|
||||
*/
|
||||
int state_sync(struct snapraid_state* state, block_off_t blockstart);
|
||||
int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount);
|
||||
|
||||
/**
|
||||
* Checks (and fixes) all the files and the parity data.
|
||||
*/
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart);
|
||||
void state_check(struct snapraid_state* state, int fix, block_off_t blockstart, block_off_t blockcount);
|
||||
|
||||
/**
|
||||
* Writes the progress.
|
||||
|
|
|
|||
7
sync.c
7
sync.c
|
|
@ -217,7 +217,7 @@ bail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int state_sync(struct snapraid_state* state, block_off_t blockstart)
|
||||
int state_sync(struct snapraid_state* state, block_off_t blockstart, block_off_t blockcount)
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
block_off_t blockmax;
|
||||
|
|
@ -236,6 +236,11 @@ int state_sync(struct snapraid_state* state, block_off_t blockstart)
|
|||
fprintf(stderr, "Error in the starting block %u. It's bigger than the parity size %u.\n", blockstart, blockmax);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* adjust the number of block to process */
|
||||
if (blockcount != 0 && blockstart + blockcount < blockmax) {
|
||||
blockmax = blockstart + blockcount;
|
||||
}
|
||||
|
||||
pathcpy(path, sizeof(path), state->parity);
|
||||
f = parity_create(path, size);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue