Adds the new "share" configuration option to allow to share the pool directory in Windows.

This commit is contained in:
Andrea Mazzoleni 2013-12-18 19:26:57 +01:00
parent b10a1c890f
commit 3df99a03ee
12 changed files with 240 additions and 24 deletions

View file

@ -10,6 +10,8 @@ SnapRAID HISTORY
* Allow to run a fix command with disks that doesn't need to be
fixed mounted as read-only.
* Doesn't count empty dirs as files in the diff counters.
* Added a new "share" configuration option to allow to share
in the network the pool directory also in Windows.
* Fixed build problem in OpenBSD due the old assembler.
5.1 2013/12

7
TODO
View file

@ -98,13 +98,6 @@ only if changes are committed after an aborted sync.
- Pooling
* Allow to specify the shared path in Windows to access remote symlinks.
Something like:
share \\SERVER\JBOD\
And then converting all the symbolic links to prepend this path in the link
definition.
Links will appears as \\SERVER\JBOD\DISK_NAME\sub_path_inside_the_disk.
* Add a new "commit" command to move changes from the pool to the array.
It should:
- Move files copied into the pool (that are no links) to the array.

29
pool.c
View file

@ -126,15 +126,24 @@ static int clean_dir(struct snapraid_state* state, const char* dir)
/**
* Creates a link to the specified disk entry.
*/
static void make_link(const char* pool_dir, struct snapraid_disk* disk, const char* sub)
static void make_link(const char* pool_dir, const char* share_dir, struct snapraid_disk* disk, const char* sub)
{
char path[PATH_MAX];
char linkto[PATH_MAX];
char linkto_exported[PATH_MAX];
int ret;
/* make the paths */
/* make the source path */
pathprint(path, sizeof(path), "%s%s", pool_dir, sub);
pathprint(linkto, sizeof(linkto), "%s%s", disk->dir, sub);
/* make the linkto path */
if (share_dir[0] != 0) {
/* with a shared directory, use it */
pathprint(linkto, sizeof(linkto), "%s%s/%s", share_dir, disk->name, sub);
} else {
/* without a share directory, use the local disk paths */
pathprint(linkto, sizeof(linkto), "%s%s", disk->dir, sub);
}
/* create the ancestor directories */
ret = mkancestor(path);
@ -142,8 +151,11 @@ static void make_link(const char* pool_dir, struct snapraid_disk* disk, const ch
exit(EXIT_FAILURE);
}
/* convert back slashes */
pathexport(linkto_exported, sizeof(linkto_exported), linkto);
/* create the symlink */
ret = symlink(linkto, path);
ret = symlink(linkto_exported, path);
if (ret != 0) {
if (errno == EEXIST) {
fprintf(stderr, "WARNING! Duplicate pooling for '%s'\n", path);
@ -163,6 +175,7 @@ void state_pool(struct snapraid_state* state)
{
tommy_node* i;
char pool_dir[PATH_MAX];
char share_dir[PATH_MAX];
unsigned count;
if (state->pool[0] == 0) {
@ -176,6 +189,10 @@ void state_pool(struct snapraid_state* state)
pathprint(pool_dir, sizeof(pool_dir), "%s", state->pool);
pathslash(pool_dir, sizeof(pool_dir));
/* share directory with final slash */
pathprint(share_dir, sizeof(share_dir), "%s", state->share);
pathslash(share_dir, sizeof(share_dir));
/* first clear the previous pool tree */
clean_dir(state, pool_dir);
@ -190,14 +207,14 @@ void state_pool(struct snapraid_state* state)
/* for each file */
for(j=disk->filelist;j!=0;j=j->next) {
struct snapraid_file* file = j->data;
make_link(pool_dir, disk, file->sub);
make_link(pool_dir, share_dir, disk, file->sub);
++count;
}
/* for each link */
for(j=disk->linklist;j!=0;j=j->next) {
struct snapraid_link* link = j->data;
make_link(pool_dir, disk, link->sub);
make_link(pool_dir, share_dir, disk, link->sub);
++count;
}

View file

@ -439,9 +439,61 @@ follow symlinks = yes
.RE
.PP
In Windows the same sharing operation is not so straightforward,
because Windows shares in the network the symbolic links as they are,
and that requires to have modern network clients able to understand
them, that usually doesn\(cqt happen for embedded clients like TVs.
because Windows shares the symbolic links as they are, and that
requires the network clients to resolve them remotely.
.PP
To make it working, besides sharing in the network the pool directory,
you must also share all the disks independently, using as share points
the disk names as defined in the config file. You must also specify in
the \(a"share\(a" option of the configure file, the Windows UNC path that remote
clients needs to use to access such shared disks.
.PP
For example, operating from a server named \(a"darkstar\(a", you can use
the options:
.PP
.RS 4
disk d1 F:\(rsarray\(rs
.PD 0
.PP
.PD
disk d2 G:\(rsarray\(rs
.PD 0
.PP
.PD
disk d3 H:\(rsarray\(rs
.PD 0
.PP
.PD
pool C:\(rspool
.PD 0
.PP
.PD
share \(rs\(rsdarkstar
.PD 0
.PP
.PD
.RE
.PP
and share the following dirs in the network:
.PP
.RS 4
\(rs\(rsdarkstar\(rspool \-> C:\(rspool
\(rs\(rsdarkstar\(rsd1 \-> F:\(rsarray
\(rs\(rsdarkstar\(rsd2 \-> G:\(rsarray
\(rs\(rsdarkstar\(rsd3 \-> H:\(rsarray
.RE
.PP
to allow remote clients to access all the files at \(rs\(rsdarkstar\(rs\(rspool.
.PP
You may also need to configure remote clients, to enable the access at
remote symlinks with the command:
.PP
.RS 4
fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1
.PD 0
.PP
.PD
.RE
.SH COMMANDS
SnapRAID provides a few simple commands that allow to:
.PD 0
@ -913,7 +965,21 @@ is 1073741824 bytes.
.SS pool DIR
Defines the pooling directory where the virtual view of the disk
array is created using the \(a"pool\(a" command.
.PP
The directory must already exist.
.SS share UNC_DIR
Defines the Windows UNC path required to access the disks remotely.
.PP
If this option is specified, the symbolic links created in the pool
directory use this UNC path to access the disks.
Otherwise, the symbolic links will use only local paths, not allowing
to share the pool directory in the network.
.PP
The symbolic links are formed using the specified UNC path, adding the
disk name as specified in the \(a"disk\(a" option, and finally adding the
file dir and name.
.PP
This options is only required for Windows.
.SS Examples
An example of a typical configuration for Unix is:
.PP

View file

@ -75,3 +75,14 @@ exclude \Windows\
# Format: "pool DIR"
#pool C:\pool
# Defines the Windows UNC path required to access disks from the pooling
# directory when shared in the network.
# If present (uncomment to enable), the symbolic links created in the
# pool virtual view, instead of using local paths, are created using the
# specified UNC path, adding the disk names and file path.
# This allows to share the pool directory in the network.
# See the manual page for more details.
#
# Format: "share UNC_DIR"
#share \\server

View file

@ -234,9 +234,37 @@ Getting Started
:follow symlinks = yes
In Windows the same sharing operation is not so straightforward,
because Windows shares in the network the symbolic links as they are,
and that requires to have modern network clients able to understand
them, that usually doesn't happen for embedded clients like TVs.
because Windows shares the symbolic links as they are, and that
requires the network clients to resolve them remotely.
To make it working, besides sharing in the network the pool directory,
you must also share all the disks independently, using as share points
the disk names as defined in the config file. You must also specify in
the "share" option of the configure file, the Windows UNC path that remote
clients needs to use to access such shared disks.
For example, operating from a server named "darkstar", you can use
the options:
:disk d1 F:\array\
:disk d2 G:\array\
:disk d3 H:\array\
:pool C:\pool
:share \\darkstar
and share the following dirs in the network:
\\darkstar\pool -> C:\pool
\\darkstar\d1 -> F:\array
\\darkstar\d2 -> G:\array
\\darkstar\d3 -> H:\array
to allow remote clients to access all the files at \\darkstar\\pool.
You may also need to configure remote clients, to enable the access at
remote symlinks with the command:
:fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1
Commands
SnapRAID provides a few simple commands that allow to:
@ -717,8 +745,23 @@ Configuration
pool DIR
Defines the pooling directory where the virtual view of the disk
array is created using the "pool" command.
The directory must already exist.
share UNC_DIR
Defines the Windows UNC path required to access the disks remotely.
If this option is specified, the symbolic links created in the pool
directory use this UNC path to access the disks.
Otherwise, the symbolic links will use only local paths, not allowing
to share the pool directory in the network.
The symbolic links are formed using the specified UNC path, adding the
disk name as specified in the "disk" option, and finally adding the
file dir and name.
This options is only required for Windows.
Examples
An example of a typical configuration for Unix is:

View file

@ -253,9 +253,37 @@ to your /etc/samba/smb.conf the following options:
follow symlinks = yes
In Windows the same sharing operation is not so straightforward,
because Windows shares in the network the symbolic links as they are,
and that requires to have modern network clients able to understand
them, that usually doesn't happen for embedded clients like TVs.
because Windows shares the symbolic links as they are, and that
requires the network clients to resolve them remotely.
To make it working, besides sharing in the network the pool directory,
you must also share all the disks independently, using as share points
the disk names as defined in the config file. You must also specify in
the "share" option of the configure file, the Windows UNC path that remote
clients needs to use to access such shared disks.
For example, operating from a server named "darkstar", you can use
the options:
disk d1 F:\array\
disk d2 G:\array\
disk d3 H:\array\
pool C:\pool
share \\darkstar
and share the following dirs in the network:
\\darkstar\pool -> C:\pool
\\darkstar\d1 -> F:\array
\\darkstar\d2 -> G:\array
\\darkstar\d3 -> H:\array
to allow remote clients to access all the files at \\darkstar\\pool.
You may also need to configure remote clients, to enable the access at
remote symlinks with the command:
fsutil behavior set SymlinkEvaluation L2L:1 R2R:1 L2R:1 R2L:1
5 COMMANDS
@ -781,8 +809,23 @@ is 1073741824 bytes.
---- 7.8.2 pool DIR ----
Defines the pooling directory where the virtual view of the disk
array is created using the "pool" command.
The directory must already exist.
---- 7.8.3 share UNC_DIR ----
Defines the Windows UNC path required to access the disks remotely.
If this option is specified, the symbolic links created in the pool
directory use this UNC path to access the disks.
Otherwise, the symbolic links will use only local paths, not allowing
to share the pool directory in the network.
The symbolic links are formed using the specified UNC path, adding the
disk name as specified in the "disk" option, and finally adding the
file dir and name.
This options is only required for Windows.
7.9 Examples
------------

19
state.c
View file

@ -83,6 +83,7 @@ void state_init(struct snapraid_state* state)
state->parity_path[l][0] = 0;
state->parity_device[l] = 0;
}
state->share[0] = 0;
state->pool[0] = 0;
state->pool_device = 0;
state->lockfile[0] = 0;
@ -459,6 +460,24 @@ void state_config(struct snapraid_state* state, const char* path, const char* co
/* adjust the level */
if (state->level < l + 1)
state->level = l + 1;
} else if (strcmp(tag, "share") == 0) {
if (*state->share) {
fprintf(stderr, "Multiple 'share' specification in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
ret = sgetlasttok(f, buffer, sizeof(buffer));
if (ret < 0) {
fprintf(stderr, "Invalid 'share' specification in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
if (!*buffer) {
fprintf(stderr, "Empty 'share' specification in '%s' at line %u\n", path, line);
exit(EXIT_FAILURE);
}
pathimport(state->share, sizeof(state->share), buffer);
} else if (strcmp(tag, "pool") == 0) {
struct stat st;

View file

@ -90,6 +90,7 @@ struct snapraid_state {
unsigned raid_mode; /**< Raid mode to use. RAID_MODE_DEFAULT or RAID_MODE_ALTERNATE. */
char parity_path[LEV_MAX][PATH_MAX]; /**< Path of the parity file. One for each parity. */
uint64_t parity_device[LEV_MAX]; /**< Device identifier of the parity. One for each parity. */
char share[PATH_MAX]; /**< Path of the share tree. If !=0 pool links are created in a different way. */
char pool[PATH_MAX]; /**< Path of the pool tree. */
uint64_t pool_device; /**< Device identifier of the pool. */
unsigned char hashseed[HASH_SIZE]; /**< Hash seed. Just after a uint64 to provide a minimal alignment. */

View file

@ -11,5 +11,5 @@ disk disk6 test/disk6/
include *.hidden
exclude *.unrecoverable
pool test/pool
share \\server\jbod

16
util.c
View file

@ -1172,7 +1172,7 @@ void pathimport(char* dst, size_t size, const char* src)
pathcpy(dst, size, src);
#ifdef _WIN32
/* convert all Windows '\' to '/' */
/* convert all Windows '\' to C '/' */
while (*dst) {
if (*dst == '\\')
*dst = '/';
@ -1181,6 +1181,20 @@ void pathimport(char* dst, size_t size, const char* src)
#endif
}
void pathexport(char* dst, size_t size, const char* src)
{
pathcpy(dst, size, src);
#ifdef _WIN32
/* convert all C '/' to Windows '\' */
while (*dst) {
if (*dst == '/')
*dst = '\\';
++dst;
}
#endif
}
void pathprint(char* dst, size_t size, const char* format, ...)
{
size_t len;

7
util.h
View file

@ -410,6 +410,13 @@ void pathcat(char* dst, size_t size, const char* src);
*/
void pathimport(char* dst, size_t size, const char* src);
/**
* Exports a path limiting the size.
* In Windows all the C slashes are converted to the Windows backslash.
* Aborts if too long.
*/
void pathexport(char* dst, size_t size, const char* src);
/**
* Prints a path.
* Aborts if too long.