Allow to specify multiple content files.

This commit is contained in:
Andrea Mazzoleni 2011-04-25 13:43:51 +02:00
parent 045602581e
commit 99420cffab
10 changed files with 232 additions and 107 deletions

View file

@ -4,10 +4,11 @@ SnapRAID HISTORY
1.1 2011/5
==========
* Added RAID6 support.
* The default checksum is Murmur3 hash.
* Allow to specify multiple content files.
* Changed the default checksum to Murmur3 hash. It's a lot faster than MD5.
MD5 is still supported for backward compatibility.
* The check command returns with an error code if any kind of error is present.
Previously it was only if unrecoverable error was present.
Previously it was only if unrecoverable errors were present.
1.0 2011/4
==========

15
elem.c
View file

@ -23,6 +23,21 @@
/****************************************************************************/
/* snapraid */
struct snapraid_content* content_alloc(const char* path)
{
struct snapraid_content* content;
content = malloc_nofail(sizeof(struct snapraid_content));
pathcpy(content->content, sizeof(content->content), path);
return content;
}
void content_free(struct snapraid_content* content)
{
free(content);
}
struct snapraid_filter* filter_alloc(const char* pattern)
{
struct snapraid_filter* filter;

18
elem.h
View file

@ -44,6 +44,14 @@ typedef uint32_t block_off_t;
*/
typedef int64_t data_off_t;
/**
* Content file specification.
*/
struct snapraid_content {
char content[PATH_MAX]; /**< Path of the content file. */
tommy_node node; /**< Next node in the list. */
};
/**
* Filter for paths.
*/
@ -99,6 +107,16 @@ struct snapraid_disk {
tommy_array blockarr; /**< Block array of the disk. */
};
/**
* Allocates a content.
*/
struct snapraid_content* content_alloc(const char* path);
/**
* Deallocates a content.
*/
void content_free(struct snapraid_content* content);
/**
* Allocates an exclusion.
*/

View file

@ -109,21 +109,23 @@ hard\(hylinks, symbolic\(hylinks are not saved.
.PD
.SH GETTING STARTED
To use SnapRAID you need first select one disk of your disk array
to dedicate at the parity information. With parity you will be able
to recover from a single disk failure.
to dedicate at the \(a"parity\(a" information. With parity you will be able
to recover from a single disk failure, like RAID5.
.PP
If you want to recover from two disk failures you must reserve
another disk for the q\(hyparity information.
If you want to recover from two disk failures, like RAID6, you must
reserve another disk for the \(a"q\(hyparity\(a" information
.PP
For both disks, you have to pick the biggest disks in the array,
as the redundancy information may grow in size as the biggest data
disk in the array.
.PP
This disk will be dedicated to store the parity and q\(hyparity.
You should not store other data on it, with the exception of
the content metadata information.
This disk will be dedicated to store the \(a"parity\(a" and \(a"q\(hyparity\(a"
files.
You should not store other data on them, with the exception of
a copy the \(a"content\(a" file, that contains the list of all the files
stored in your array with all the checksums to verify their integrity.
.PP
For example, suppose that you are interested only at the parity level
For example, suppose that you are interested only at one parity level
of protection, and that all your disks are present in:
.PP
.RS 4
@ -215,7 +217,7 @@ will start where interrupted.
.PP
When this command completes, your data is SAFE.
.PP
At this point you can start using your data as you like, and periodically
At this point you can start using your array as you like, and periodically
update the redundancy information running the \(a"sync\(a" command.
.PP
To check the integrity of your data you can use the \(a"check\(a" command:
@ -244,7 +246,14 @@ in \(a"sync\(a".
.PP
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.
deleted directory, simply running the fix command like.
.PP
.RS 4
snapraid fix \(hyf JUST_DELETED_DIR/
.PD 0
.PP
.PD
.RE
.SH COMMANDS
SnapRAID provides three simple commands that allow to:
.PD 0
@ -341,6 +350,8 @@ it should contains the following options:
.TP
.B parity FILE
Defines the file to use to store the parity information.
The parity enables the protection from a single disk
failure, like RAID5.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the parity disk reserved for only this file, ensures that
@ -349,8 +360,8 @@ This option is mandatory and it can be used only one time.
.TP
.B q\(hyparity FILE
Defines the file to use to store the q\(hyparity information.
This option is optional, and if present it enables the protection
from two disk failures.
If present, the q\(hyparity enables the protection from two disk
failures, like RAID6.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the q\(hyparity disk reserved for only this file, ensures that
@ -360,9 +371,13 @@ This option is optional and it can be used only one time.
.B content FILE
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 is mandatory and it can be used only one time.
It can be placed in the same disk of the parity and q\(hyaparity file,
or better in another disk, but NOT in a data disk of the array.
This option is mandatory and it can be used more time to save
more copies of the same files.
It\(cqs suggested to store at least one copy for each parity disk.
One more doesn\(cqt hurt, just in case you lose all the parity disks,
and you still need to check the data integrity.
.TP
.B disk NAME DIR
Defines the name and the mount point of the disks of the array.
@ -370,6 +385,8 @@ NAME is used to identify the disk, and it must be unique.
DIR is the mount point of the disk in the file\(hysystem.
You can change the mount point as you like, as far you
keep the NAME fixed.
The specification order is also important, if you change it,
you will invalidate the q\(hyparity file.
You should use one option for each disk of the array.
.TP
.B exclude PATTERN
@ -426,6 +443,10 @@ content /mnt/diskpar/content
.PD 0
.PP
.PD
content /var/snapraid/content
.PD 0
.PP
.PD
disk d1 /mnt/disk1/
.PD 0
.PP
@ -531,11 +552,12 @@ snapraid \(hyf \(a"*.mp3\(a" check
.PD
.RE
.SH CONTENT
SnapRAID creates a metadata content file describing the content of
your disk array.
SnapRAID stores the list of your files in the content file.
.PP
It\(cqs a text file, listing all the files in your disk array. You do not
need to understand its format, but it\(cqs described here for documentation.
It\(cqs a text file, listing all the files present in your disk array,
with all the checksums to verify their integrity.
You do not need to understand its format, but it\(cqs described here
for documentation.
.PP
This file is read and written by the \(a"sync\(a" command, and only read by
\(a"fix\(a" and \(a"check\(a".
@ -570,12 +592,13 @@ The HASH may be missing if not yet computed.
This field is used only when you interrupt manually the \(a"sync\(a"
command.
.SH PARITY
SnapRAID creates the parity and q\(hyparity files containing the redundancy
information of your disk array.
SnapRAID stores the redundancy information of your array in the parity
and q\(hyparity files.
.PP
They are binary files, containing the computed redundancy of all the
blocks defined in the \(a"content\(a" file. You do not need to understand its
format, but it\(cqs described here for documentation.
blocks defined in the \(a"content\(a" file.
You do not need to understand its format, but it\(cqs described here
for documentation.
.PP
These files are read and written by the \(a"sync\(a" and \(a"fix\(a" commands, and
only read by \(a"check\(a".

View file

@ -1,17 +1,28 @@
# Configuration for snapraid
# Example configuration for snapraid
# Defines the file to use as parity storage
# It must be in an different disk than the data disks
# Defines the file to use as Parity storage
# It must NOT be in a data disk
# Format: "parity FILE_PATH"
parity /mnt/diskpar/parity
# Defines the file to use as Q-Parity storage
# If specified, it enables a double failures protection like RAID6
# It must NOT be in a data disk
# Format: "q-parity FILE_PATH"
#q-parity /mnt/diskqar/q-parity
# Defines the file to use as content list
# You can use multiple specification to store more copies of the file
# It's suggested to have at least N+1 copies of the file, where N is the number of parity files.
# It must NOT be in a data disk
# It can be in the disks used for parity storage
# Format: "content FILE_PATH"
# It must be in an different disk than the data disks
# It can be in the same disk used for parity storage
content /mnt/diskpar/content
#content /mnt/diskqar/content
content /var/snapraid/content
# Defines the data disks to use
# The order is relevant for parity, do not change it
# Format: "disk DISK_NAME DISK_MOUNT_POINT"
disk d1 /mnt/disk1/
disk d2 /mnt/disk2/
@ -27,7 +38,7 @@ exclude tmp/
exclude /lost+found/
# Defines the block size in kibi bytes (1024 bytes).
# Format: "block_size SIZE_IN_KiB"
# Default value is 256 -> 256 kibi bytes -> 262144 bytes
# Format: "block_size SIZE_IN_KiB"
block_size 256

View file

@ -74,21 +74,23 @@ Limitations
Getting Started
To use SnapRAID you need first select one disk of your disk array
to dedicate at the parity information. With parity you will be able
to recover from a single disk failure.
to dedicate at the "parity" information. With parity you will be able
to recover from a single disk failure, like RAID5.
If you want to recover from two disk failures you must reserve
another disk for the q-parity information.
If you want to recover from two disk failures, like RAID6, you must
reserve another disk for the "q-parity" information
For both disks, you have to pick the biggest disks in the array,
as the redundancy information may grow in size as the biggest data
disk in the array.
This disk will be dedicated to store the parity and q-parity.
You should not store other data on it, with the exception of
the content metadata information.
This disk will be dedicated to store the "parity" and "q-parity"
files.
You should not store other data on them, with the exception of
a copy the "content" file, that contains the list of all the files
stored in your array with all the checksums to verify their integrity.
For example, suppose that you are interested only at the parity level
For example, suppose that you are interested only at one parity level
of protection, and that all your disks are present in:
:/mnt/diskpar <- selected disk for parity
@ -127,7 +129,7 @@ Getting Started
When this command completes, your data is SAFE.
At this point you can start using your data as you like, and periodically
At this point you can start using your array as you like, and periodically
update the redundancy information running the "sync" command.
To check the integrity of your data you can use the "check" command:
@ -146,7 +148,9 @@ Getting Started
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.
deleted directory, simply running the fix command like.
:snapraid fix -f JUST_DELETED_DIR/
Commands
SnapRAID provides three simple commands that allow to:
@ -241,6 +245,8 @@ Configuration
=parity FILE
Defines the file to use to store the parity information.
The parity enables the protection from a single disk
failure, like RAID5.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the parity disk reserved for only this file, ensures that
@ -249,8 +255,8 @@ Configuration
=q-parity FILE
Defines the file to use to store the q-parity information.
This option is optional, and if present it enables the protection
from two disk failures.
If present, the q-parity enables the protection from two disk
failures, like RAID6.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the q-parity disk reserved for only this file, ensures that
@ -260,9 +266,13 @@ Configuration
=content FILE
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 is mandatory and it can be used only one time.
It can be placed in the same disk of the parity and q-aparity file,
or better in another disk, but NOT in a data disk of the array.
This option is mandatory and it can be used more time to save
more copies of the same files.
It's suggested to store at least one copy for each parity disk.
One more doesn't hurt, just in case you lose all the parity disks,
and you still need to check the data integrity.
=disk NAME DIR
Defines the name and the mount point of the disks of the array.
@ -270,6 +280,8 @@ Configuration
DIR is the mount point of the disk in the file-system.
You can change the mount point as you like, as far you
keep the NAME fixed.
The specification order is also important, if you change it,
you will invalidate the q-parity file.
You should use one option for each disk of the array.
=exclude PATTERN
@ -308,6 +320,7 @@ Configuration
:parity /mnt/diskpar/parity
:content /mnt/diskpar/content
:content /var/snapraid/content
:disk d1 /mnt/disk1/
:disk d2 /mnt/disk2/
:disk d3 /mnt/disk3/
@ -360,11 +373,12 @@ Pattern
:snapraid -f "*.mp3" check
Content
SnapRAID creates a metadata content file describing the content of
your disk array.
SnapRAID stores the list of your files in the content file.
It's a text file, listing all the files in your disk array. You do not
need to understand its format, but it's described here for documentation.
It's a text file, listing all the files present in your disk array,
with all the checksums to verify their integrity.
You do not need to understand its format, but it's described here
for documentation.
This file is read and written by the "sync" command, and only read by
"fix" and "check".
@ -400,12 +414,13 @@ Content
command.
Parity
SnapRAID creates the parity and q-parity files containing the redundancy
information of your disk array.
SnapRAID stores the redundancy information of your array in the parity
and q-parity files.
They are binary files, containing the computed redundancy of all the
blocks defined in the "content" file. You do not need to understand its
format, but it's described here for documentation.
blocks defined in the "content" file.
You do not need to understand its format, but it's described here
for documentation.
These files are read and written by the "sync" and "fix" commands, and
only read by "check".

View file

@ -87,21 +87,23 @@ Other limitations are:
=================
To use SnapRAID you need first select one disk of your disk array
to dedicate at the parity information. With parity you will be able
to recover from a single disk failure.
to dedicate at the "parity" information. With parity you will be able
to recover from a single disk failure, like RAID5.
If you want to recover from two disk failures you must reserve
another disk for the q-parity information.
If you want to recover from two disk failures, like RAID6, you must
reserve another disk for the "q-parity" information
For both disks, you have to pick the biggest disks in the array,
as the redundancy information may grow in size as the biggest data
disk in the array.
This disk will be dedicated to store the parity and q-parity.
You should not store other data on it, with the exception of
the content metadata information.
This disk will be dedicated to store the "parity" and "q-parity"
files.
You should not store other data on them, with the exception of
a copy the "content" file, that contains the list of all the files
stored in your array with all the checksums to verify their integrity.
For example, suppose that you are interested only at the parity level
For example, suppose that you are interested only at one parity level
of protection, and that all your disks are present in:
/mnt/diskpar <- selected disk for parity
@ -140,7 +142,7 @@ will start where interrupted.
When this command completes, your data is SAFE.
At this point you can start using your data as you like, and periodically
At this point you can start using your array as you like, and periodically
update the redundancy information running the "sync" command.
To check the integrity of your data you can use the "check" command:
@ -159,7 +161,9 @@ in "sync".
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.
deleted directory, simply running the fix command like.
snapraid fix -f JUST_DELETED_DIR/
5 COMMANDS
@ -263,6 +267,8 @@ it should contains the following options:
parity FILE
Defines the file to use to store the parity information.
The parity enables the protection from a single disk
failure, like RAID5.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the parity disk reserved for only this file, ensures that
@ -271,8 +277,8 @@ it should contains the following options:
q-parity FILE
Defines the file to use to store the q-parity information.
This option is optional, and if present it enables the protection
from two disk failures.
If present, the q-parity enables the protection from two disk
failures, like RAID6.
It must be placed in a disk dedicated for this purpose with
as much free space as the biggest disk in the array.
Leaving the q-parity disk reserved for only this file, ensures that
@ -282,9 +288,13 @@ it should contains the following options:
content FILE
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 is mandatory and it can be used only one time.
It can be placed in the same disk of the parity and q-aparity file,
or better in another disk, but NOT in a data disk of the array.
This option is mandatory and it can be used more time to save
more copies of the same files.
It's suggested to store at least one copy for each parity disk.
One more doesn't hurt, just in case you lose all the parity disks,
and you still need to check the data integrity.
disk NAME DIR
Defines the name and the mount point of the disks of the array.
@ -292,6 +302,8 @@ it should contains the following options:
DIR is the mount point of the disk in the file-system.
You can change the mount point as you like, as far you
keep the NAME fixed.
The specification order is also important, if you change it,
you will invalidate the q-parity file.
You should use one option for each disk of the array.
exclude PATTERN
@ -330,6 +342,7 @@ An example of a typical configuration is:
parity /mnt/diskpar/parity
content /mnt/diskpar/content
content /var/snapraid/content
disk d1 /mnt/disk1/
disk d2 /mnt/disk2/
disk d3 /mnt/disk3/
@ -388,11 +401,12 @@ For example, in the command line:
9 CONTENT
=========
SnapRAID creates a metadata content file describing the content of
your disk array.
SnapRAID stores the list of your files in the content file.
It's a text file, listing all the files in your disk array. You do not
need to understand its format, but it's described here for documentation.
It's a text file, listing all the files present in your disk array,
with all the checksums to verify their integrity.
You do not need to understand its format, but it's described here
for documentation.
This file is read and written by the "sync" command, and only read by
"fix" and "check".
@ -431,12 +445,13 @@ is described here.
10 PARITY
=========
SnapRAID creates the parity and q-parity files containing the redundancy
information of your disk array.
SnapRAID stores the redundancy information of your array in the parity
and q-parity files.
They are binary files, containing the computed redundancy of all the
blocks defined in the "content" file. You do not need to understand its
format, but it's described here for documentation.
blocks defined in the "content" file.
You do not need to understand its format, but it's described here
for documentation.
These files are read and written by the "sync" and "fix" commands, and
only read by "check".

84
state.c
View file

@ -35,13 +35,13 @@ void state_init(struct snapraid_state* state)
state->expect_recoverable = 0;
state->need_write = 0;
state->block_size = 256 * 1024; /* default 256 KiB */
state->content[0] = 0;
state->parity[0] = 0;
state->qarity[0] = 0;
state->level = 1; /* default is the lowest protection */
state->hash = HASH_MURMUR3; /* default is the fastest */
tommy_array_init(&state->diskarr);
tommy_list_init(&state->excludelist);
tommy_list_init(&state->contentlist);
}
void state_done(struct snapraid_state* state)
@ -51,6 +51,7 @@ void state_done(struct snapraid_state* state)
for(i=0;i<tommy_array_size(&state->diskarr);++i)
disk_free(tommy_array_get(&state->diskarr, i));
tommy_array_done(&state->diskarr);
tommy_list_foreach(&state->contentlist, (tommy_foreach_func*)content_free);
tommy_list_foreach(&state->excludelist, (tommy_foreach_func*)filter_free);
}
@ -58,6 +59,7 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
{
FILE* f;
unsigned line;
unsigned content_count;
state->verbose = verbose;
state->force_zero = force_zero;
@ -78,6 +80,7 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
}
line = 0;
content_count = 0;
while (1) {
char buffer[TEXT_LINE_MAX];
char* tag;
@ -139,11 +142,9 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
pathcpy(state->qarity, sizeof(state->qarity), s);
state->level = 2;
} else if (strcmp(tag, "content") == 0) {
if (*state->content) {
fprintf(stderr, "Multiple 'content' specification in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
pathcpy(state->content, sizeof(state->content), s);
struct snapraid_content* content = content_alloc(s);
tommy_list_insert_tail(&state->contentlist, &content->node, content);
++content_count;
} else if (strcmp(tag, "disk") == 0) {
char* name = s;
s = strtoken(s);
@ -163,12 +164,16 @@ void state_config(struct snapraid_state* state, const char* path, int verbose, i
fclose(f);
if (!state->parity) {
fprintf(stderr, "No 'parity' specification in '%s' at line %u\n", path, line);
if (state->parity[0] == 0) {
fprintf(stderr, "No 'parity' specification in '%s'\n", path);
exit(EXIT_FAILURE);
}
if (!state->content) {
fprintf(stderr, "No 'content' specification in '%s' at line %u\n", path, line);
if (content_count == 0) {
fprintf(stderr, "No 'content' specification in '%s'\n", path);
exit(EXIT_FAILURE);
}
if (state->qarity[0] != 0 && content_count < 2) {
fprintf(stderr, "With 'q-parity' you must have at least two 'content' specifications in '%s'\n", path);
exit(EXIT_FAILURE);
}
}
@ -183,12 +188,14 @@ void state_read(struct snapraid_state* state)
unsigned line;
unsigned count_file;
unsigned count_block;
struct snapraid_content* content;
count_file = 0;
count_block = 0;
pathcpy(path, sizeof(path), state->content);
f = fopen(state->content, "rt");
content = tommy_list_head(&state->contentlist)->data;
pathcpy(path, sizeof(path), content->content);
f = fopen(path, "rt");
if (!f) {
/* if not found, assume empty */
if (errno == ENOENT)
@ -198,7 +205,7 @@ void state_read(struct snapraid_state* state)
exit(EXIT_FAILURE);
}
printf("Loading state...\n");
printf("Loading state from %s...\n", path);
/* start with a MD5 default. */
/* it's for compatibility with version 1.0 where MD5 was implicit. */
@ -425,36 +432,36 @@ void state_read(struct snapraid_state* state)
}
}
void state_write(struct snapraid_state* state)
static void state_write_one(struct snapraid_state* state, const char* path, unsigned* out_count_file, unsigned* out_count_block)
{
FILE* f;
char path[PATH_MAX];
unsigned i;
char tmp[PATH_MAX];
unsigned count_file;
unsigned count_block;
unsigned i;
int ret;
count_file = 0;
count_block = 0;
printf("Saving state...\n");
printf("Saving state to %s...\n", path);
pathprint(path, sizeof(path), "%s.tmp", state->content);
f = fopen(path, "wt");
pathprint(tmp, sizeof(tmp), "%s.tmp", path);
f = fopen(tmp, "wt");
if (!f) {
fprintf(stderr, "Error opening for writing the content file '%s'\n", path);
fprintf(stderr, "Error opening for writing the content file '%s'\n", tmp);
exit(EXIT_FAILURE);
}
ret = fprintf(f, "blksize %u\n", state->block_size);
if (ret < 0) {
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
ret = fprintf(f, "checksum %s\n", state->hash == HASH_MD5 ? "md5" : "murmur3");
if (ret < 0) {
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
@ -477,7 +484,7 @@ void state_write(struct snapraid_state* state)
ret = fprintf(f,"file %s %llu %llu %llu %s\n", disk->name, size, mtime, inode, file->sub);
if (ret < 0) {
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
@ -501,7 +508,7 @@ void state_write(struct snapraid_state* state)
ret = fprintf(f, "%s %u\n", tag, block->parity_pos);
}
if (ret < 0) {
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in fprintf(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
@ -516,27 +523,46 @@ void state_write(struct snapraid_state* state)
/* than even in a system crash event we have one valid copy of the file. */
if (fflush(f) != 0) {
fprintf(stderr, "Error writing the content file '%s', in fflush(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s', in fflush(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
#if HAVE_FSYNC
if (fsync(fileno(f)) != 0) {
fprintf(stderr, "Error writing the content file '%s' in fsync(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in fsync(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
#endif
if (fclose(f) != 0) {
fprintf(stderr, "Error writing the content file '%s' in close(). %s.\n", path, strerror(errno));
fprintf(stderr, "Error writing the content file '%s' in close(). %s.\n", tmp, strerror(errno));
exit(EXIT_FAILURE);
}
if (rename(path, state->content) != 0) {
fprintf(stderr, "Error renaming the content file '%s' to '%s' in rename(). %s.\n", path, state->content, strerror(errno));
if (rename(tmp, path) != 0) {
fprintf(stderr, "Error renaming the content file '%s' to '%s' in rename(). %s.\n", tmp, path, strerror(errno));
exit(EXIT_FAILURE);
}
if (out_count_file)
*out_count_file = count_file;
if (out_count_block)
*out_count_block = count_block;
}
void state_write(struct snapraid_state* state)
{
unsigned count_file;
unsigned count_block;
tommy_node* node;
node = tommy_list_head(&state->contentlist);
while (node) {
struct snapraid_content* content = node->data;
state_write_one(state, content->content, &count_file, &count_block);
node = node->next;
}
if (state->verbose) {
printf("\tfile %u\n", count_file);
printf("\tblock %u\n", count_block);

View file

@ -37,11 +37,11 @@ struct snapraid_state {
int expect_recoverable; /**< Expect presence of recoverable error in checking. */
int need_write; /**< If the state is changed. */
uint32_t block_size; /**< Block size in bytes. */
char content[PATH_MAX]; /**< Path of the content file. */
char parity[PATH_MAX]; /**< Path of the parity file. */
char qarity[PATH_MAX]; /**< Path of the qarity file. */
unsigned level; /**< Number of parity levels. 1 for RAID5, 2 for RAID6. */
unsigned hash; /**< Hash kind used. */
tommy_list contentlist; /**< List of content files. */
tommy_array diskarr; /**< Disk array. */
tommy_list excludelist; /**< List of exclusion. */
};

View file

@ -2,6 +2,7 @@ block_size 1
parity test/parity
q-parity test/q-parity
content test/content
content test/q-content
disk d1 test/disk1/
disk d2 test/disk2/
disk d3 test/disk3/