Add a proper signal handling

The most common signals are now intercepted with SA_RESTART
to allow a clean interruption.
This commit is contained in:
Andrea Mazzoleni 2015-10-26 19:32:41 +01:00
parent e23397f8de
commit 104c47d106
3 changed files with 41 additions and 18 deletions

2
TODO
View file

@ -43,8 +43,6 @@ The same for directories, when recreating the directory tree.
* If a directory exists with the same name of a parity/content file be more explicative
on the error message. See: https://sourceforge.net/projects/snapraid/forums/forum/1677233/topic/4861034
* Support interrupted operations with EINTR. For remote filesystems it could be relevant.
* Allow to specify more than one disk directories to cover the case of multi partitions.
Different partitions have duplicate inode. The only way to support this is to
add also a kind of device_id, increasing the memory required.

View file

@ -370,14 +370,33 @@ volatile int global_interrupt = 0;
/* LCOV_EXCL_START */
void signal_handler(int signum)
{
switch (signum) {
case SIGINT :
global_interrupt = 1;
break;
}
(void)signum;
/* report the request of interruption */
global_interrupt = 1;
}
/* LCOV_EXCL_STOP */
void signal_init(void)
{
#if HAVE_SIGACTION
struct sigaction sa;
sa.sa_handler = signal_handler;
sigemptyset(&sa.sa_mask);
/* use the SA_RESTART to automatically restart interrupted system calls */
sa.sa_flags = SA_RESTART;
sigaction(SIGHUP, &sa, 0);
sigaction(SIGTERM, &sa, 0);
sigaction(SIGINT, &sa, 0);
sigaction(SIGQUIT, &sa, 0);
#else
signal(SIGINT, signal_handler);
#endif
}
#define OPERATION_DIFF 0
#define OPERATION_SYNC 1
#define OPERATION_CHECK 2
@ -1062,8 +1081,8 @@ int main(int argc, char* argv[])
memory();
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
/* intercept signals while operating */
signal_init();
/* save the new state before the sync */
/* this allow to recover the case of the changes in the array after an aborted sync. */
@ -1124,15 +1143,15 @@ int main(int argc, char* argv[])
memory();
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
/* intercept signals while operating */
signal_init();
state_dry(&state, blockstart, blockcount);
} else if (operation == OPERATION_REHASH) {
state_read(&state);
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
/* intercept signals while operating */
signal_init();
state_rehash(&state);
@ -1144,8 +1163,8 @@ int main(int argc, char* argv[])
memory();
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
/* intercept signals while operating */
signal_init();
ret = state_scrub(&state, percentage, olderthan);
@ -1162,6 +1181,9 @@ int main(int argc, char* argv[])
} else if (operation == OPERATION_REWRITE) {
state_read(&state);
/* intercept signals while operating */
signal_init();
state_write(&state);
memory();
@ -1174,6 +1196,9 @@ int main(int argc, char* argv[])
state_nano(&state);
/* intercept signals while operating */
signal_init();
state_write(&state);
memory();
@ -1225,8 +1250,8 @@ int main(int argc, char* argv[])
memory();
/* intercept Ctrl+C */
signal(SIGINT, &signal_handler);
/* intercept signals while operating */
signal_init();
if (operation == OPERATION_CHECK) {
ret = state_check(&state, 0, blockstart, blockcount);

View file

@ -72,7 +72,7 @@ AC_CHECK_MEMBERS([struct statfs.f_type], [], [], [[
dnl Checks for library functions.
AC_CHECK_FUNCS([memset strchr strerror strrchr mkdir gettimeofday strtoul])
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf])
AC_CHECK_FUNCS([getopt getopt_long snprintf vsnprintf sigaction])
AC_CHECK_FUNCS([ftruncate fallocate fsync access posix_fallocate posix_fadvise])
AC_CHECK_FUNCS([pread pwrite getc_unlocked ferror_unlocked fnmatch])
AC_CHECK_FUNCS([futimes futimens futimesat localtime_r])