Changes the way files without read or write permission are handled.

Now we try to continue processing returning a warning where possible.
This commit is contained in:
Andrea Mazzoleni 2011-06-11 09:38:19 +02:00
parent ede528636f
commit f8d2c91a96
6 changed files with 52 additions and 14 deletions

View file

@ -1,6 +1,15 @@
SnapRAID HISTORY
================
1.4 2011/6
==========
* Ignoring in sync System and Hidden files in Windows.
* Files without read permission are ignored in sync.
* If a file is ignored a warning message is printed. You have to exclude it
to remove the warning.
* In fixing, if a file cannot be written for missing permission, an error is
reported only if a write is effectively required.
1.3 2011/5
==========
* Fixed the restore of directory with unicode chars in Windows.

17
check.c
View file

@ -291,9 +291,13 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
if (fix) {
/* if fixing, create the file, open for writing and resize if required */
ret = handle_create(&handle[j], block_file_get(block));
ret = handle_create(&handle[j], block_file_get(block));
if (ret == -1) {
fprintf(stderr, "DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
if (errno == EACCES) {
fprintf(stderr, "WARNING! Please give write permission to the file.\n");
} else {
fprintf(stderr, "DANGER! Without a working data disk, it isn't possible to fix errors on it.\n");
}
fprintf(stderr, "Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
@ -450,7 +454,12 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
ret = handle_write(failed[j].handle, failed[j].block, buffer[failed[j].index], state->block_size);
if (ret == -1) {
fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
if (errno == EACCES) {
fprintf(stderr, "WARNING! Please give write permission to the file.\n");
} else {
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
fprintf(stderr, "WARNING! Without a working data disk, it isn't possible to fix errors on it.\n");
}
fprintf(stderr, "Stopping at block %u\n", i);
++unrecoverable_error;
goto bail;
@ -468,6 +477,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
if (buffer_parity == 0 && parity_f != -1) {
ret = parity_write(state->parity, parity_f, i, buffer[diskmax], state->block_size);
if (ret == -1) {
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
fprintf(stderr, "WARNING! Without a working Parity disk, it isn't possible to fix errors on it.\n");
fprintf(stderr, "Stopping at block %u\n", i);
++unrecoverable_error;
@ -483,6 +493,7 @@ static int state_check_process(struct snapraid_state* state, int fix, int parity
if (buffer_qarity == 0 && qarity_f != -1) {
ret = parity_write(state->qarity, qarity_f, i, buffer[diskmax + 1], state->block_size);
if (ret == -1) {
/* we do not use DANGER because for ENOSPC which is not always correctly reported */
fprintf(stderr, "WARNING! Without a working Q-Parity disk, it isn't possible to fix errors on it.\n");
fprintf(stderr, "Stopping at block %u\n", i);
++unrecoverable_error;

View file

@ -112,6 +112,13 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file)
/* opening in sequential mode in Windows */
handle->f = open(handle->path, O_RDWR | O_CREAT | O_BINARY | O_SEQUENTIAL, 0600);
/* if failed for missing permission */
if (handle->f == -1 && errno == EACCES) {
/* retry without requesting write permission */
handle->f = open(handle->path, O_RDONLY | O_BINARY | O_SEQUENTIAL);
}
if (handle->f == -1) {
/* invalidate for error */
handle->file = 0;
@ -142,6 +149,8 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file)
if (ret != 0) {
if (errno == ENOSPC) {
fprintf(stderr, "Failed to grow file '%s' due lack of space.\n", handle->path);
} else if (errno == EACCES) {
fprintf(stderr, "Failed to grow file '%s' for missing write permission.\n", handle->path);
} else {
fprintf(stderr, "Error growing file '%s'. %s.\n", handle->path, strerror(errno));
}
@ -150,7 +159,11 @@ int handle_create(struct snapraid_handle* handle, struct snapraid_file* file)
} else if (handle->st.st_size > file->size) {
ret = ftruncate(handle->f, file->size);
if (ret != 0) {
fprintf(stderr, "Error truncating file '%s'. %s.\n", handle->path, strerror(errno));
if (errno == EACCES) {
fprintf(stderr, "Failed to truncate file '%s' for missing write permission.\n", handle->path);
} else {
fprintf(stderr, "Error truncating file '%s'. %s.\n", handle->path, strerror(errno));
}
return -1;
}
}

View file

@ -36,8 +36,10 @@ int handle_close_if_different(struct snapraid_handle* handle, struct snapraid_fi
/**
* Creates a file.
* The file is created if missing, and opening with write access.
* The file is created if missing, and opened with write access.
* If the file is larger than expected, the value 1 is returned, and the file is truncated to the correct size.
* If the file cannot be opened for write access, it's opened with read-only access.
* The read-only access works only if the file has already the correct size and doesn't need to be modified.
*/
int handle_create(struct snapraid_handle* handle, struct snapraid_file* file);

View file

@ -82,6 +82,7 @@ int windows_mkdir(const char* file);
/**
* Like the C stat() with inode information.
* It doesn't work for all kind of files and directories. For example "\System Volume Information" cannot be opened.
* Note that instead stat() works for all the files.
*/
#define HAVE_STAT_INODE 1
int stat_inode(const char* file, struct windows_stat* st);

20
scan.c
View file

@ -206,7 +206,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s
d = opendir(dir);
if (!d) {
fprintf(stderr, "Error opening directory '%s'. %s.\n", dir, strerror(errno));
fprintf(stderr, "You can exclude it in the config file with:\n\texclude /%s\n", sub);
fprintf(stderr, "You can exclude it in the config file with:\n\texclude /%s/\n", sub);
exit(EXIT_FAILURE);
}
@ -222,7 +222,7 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s
dd = readdir(d);
if (dd == 0 && errno != 0) {
fprintf(stderr, "Error reading directory '%s'. %s.\n", dir, strerror(errno));
fprintf(stderr, "You can exclude it in the config file with:\n\texclude /%s\n", sub);
fprintf(stderr, "You can exclude it in the config file with:\n\texclude /%s/\n", sub);
exit(EXIT_FAILURE);
}
if (dd == 0 && errno == 0) {
@ -254,13 +254,11 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s
/* check for read permission */
if (access(path_next, R_OK) != 0) {
fprintf(stderr, "You do not have read permissions for file '%s'.\n", path_next);
fprintf(stderr, "Fix the permissions or exclude it in the configuration with:\n\texclude /%s\n", sub_next);
fprintf(stderr, "or exclude the whole directory with:\n\texclude /%s\n", sub);
exit(EXIT_FAILURE);
fprintf(stderr, "warning: Ignoring, for missing read permission, file '%s'\n", path_next);
continue;
}
#if HAVE_STAT_INODE
#if HAVE_STAT_INODE
/* get inode info about the file, Windows needs an additional step */
if (stat_inode(path_next, &st) != 0) {
fprintf(stderr, "Error in stat_inode file '%s'. %s.\n", path_next, strerror(errno));
@ -285,8 +283,12 @@ static void scan_dir(struct snapraid_scan* scan, struct snapraid_state* state, s
}
}
} else {
if (state->verbose) {
printf("warning: Ignored special file '/%s'\n", sub_next);
if (filter_path(&state->filterlist, sub_next, 0) == 0) {
fprintf(stderr, "warning: Ignoring special file '%s'\n", path_next);
} else {
if (state->verbose) {
printf("Excluding special file '/%s'\n", sub_next);
}
}
}
}