mirror of
https://github.com/amadvance/snapraid.git
synced 2026-10-25 18:40:19 -04:00
Allow to specify multiple content files.
This commit is contained in:
parent
045602581e
commit
99420cffab
10 changed files with 232 additions and 107 deletions
5
HISTORY
5
HISTORY
|
|
@ -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
15
elem.c
|
|
@ -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
18
elem.h
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
|||
69
snapraid.1
69
snapraid.1
|
|
@ -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".
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
61
snapraid.d
61
snapraid.d
|
|
@ -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".
|
||||
|
|
|
|||
61
snapraid.txt
61
snapraid.txt
|
|
@ -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
84
state.c
|
|
@ -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);
|
||||
|
|
|
|||
2
state.h
2
state.h
|
|
@ -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. */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue