diff --git a/Makefile.am b/Makefile.am index f635cb77..aa9b0d03 100644 --- a/Makefile.am +++ b/Makefile.am @@ -19,8 +19,9 @@ snapraid_SOURCES = \ raid.c \ selftest.c \ speed.c \ + import.c \ mingw.c \ - os.c + unix.c noinst_HEADERS = \ portable.h \ @@ -45,8 +46,9 @@ noinst_HEADERS = \ cpu.h \ raid.h \ tables.h \ + import.h \ mingw.h \ - os.h + unix.h mktest_SOURCES = \ mktest.c \ @@ -209,6 +211,16 @@ endif $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check 2>> test.log $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf check + echo --- Delete files from three disks and fix with import in RAID6 + rm -r test/disk1/_a + rm -r test/disk1/_b + rm -r test/disk2/_a + rm -r test/disk2/_b + mv test/disk3/_a test/_a + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self --test-expect-unrecoverable -c $(srcdir)/test-raid6.conf fix 2>> test.log + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -i test/_a -c $(srcdir)/test-raid6.conf fix 2>> test.log + rm -r test/_a + $(TESTENV) ./snapraid$(EXEEXT) $(CHECKFLAGS) --test-skip-self -c $(srcdir)/test-raid6.conf sync echo --- Abort sync late with additions, delete them and recover with RAID6 echo --- This triggers the recoving with q using p to check the validity cp -pR test/disk1/_a test/disk1/_c diff --git a/configure.ac b/configure.ac index 8b810e7b..0dd23e5f 100644 --- a/configure.ac +++ b/configure.ac @@ -93,7 +93,7 @@ AC_ARG_ENABLE([debug], [AS_HELP_STRING([--enable-debug],[enable debugging])], [ TESTENV="" - CFLAGS="-O0 -g" + CFLAGS="-O0 -g -Wall -Wextra" ], []) diff --git a/mingw.c b/mingw.c index 94c291cb..447a77cf 100644 --- a/mingw.c +++ b/mingw.c @@ -41,6 +41,44 @@ typedef struct _FILE_ATTRIBUTE_TAG_INFO { #define IO_REPARSE_TAG_SYMLINK (0xA000000C) #endif +/* For SetThreadExecutionState */ +#define WIN32_ES_SYSTEM_REQUIRED 0x00000001L +#define WIN32_ES_DISPLAY_REQUIRED 0x00000002L +#define WIN32_ES_USER_PRESENT 0x00000004L +#define WIN32_ES_AWAYMODE_REQUIRED 0x00000040L +#define WIN32_ES_CONTINUOUS 0x80000000L + +void os_init(void) +{ + HMODULE kernel32 = GetModuleHandle("KERNEL32.DLL"); + WORD (WINAPI* WIN32_SetThreadExecutionState)(DWORD); + + if (kernel32) { + WIN32_SetThreadExecutionState = (void*)GetProcAddress(kernel32, "SetThreadExecutionState"); + if (WIN32_SetThreadExecutionState) { + /* set the thread execution level to avoid sleep */ + if (WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS | WIN32_ES_SYSTEM_REQUIRED | WIN32_ES_AWAYMODE_REQUIRED) == 0) { + /* retry with the XP variant */ + WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS | WIN32_ES_SYSTEM_REQUIRED); + } + } + } +} + +void os_done(void) +{ + HMODULE kernel32 = GetModuleHandle("KERNEL32.DLL"); + WORD (WINAPI* WIN32_SetThreadExecutionState)(DWORD); + + if (kernel32) { + WIN32_SetThreadExecutionState = (void*)GetProcAddress(kernel32, "SetThreadExecutionState"); + if (WIN32_SetThreadExecutionState) { + /* restore the normal execution level */ + WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS); + } + } +} + /** * Number of conversion buffers. */ diff --git a/os.c b/os.c deleted file mode 100644 index 6a042943..00000000 --- a/os.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2011 Andrea Mazzoleni - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include "portable.h" - -#include "os.h" - -/****************************************************************************/ -/* os */ - -#ifdef __MINGW32__ -#define WIN32_ES_SYSTEM_REQUIRED 0x00000001L -#define WIN32_ES_DISPLAY_REQUIRED 0x00000002L -#define WIN32_ES_USER_PRESENT 0x00000004L -#define WIN32_ES_AWAYMODE_REQUIRED 0x00000040L -#define WIN32_ES_CONTINUOUS 0x80000000L -#endif - -void os_init(void) -{ -#ifdef __MINGW32__ - HMODULE kernel32 = GetModuleHandle("KERNEL32.DLL"); - WORD (WINAPI* WIN32_SetThreadExecutionState)(DWORD); - - if (kernel32) { - WIN32_SetThreadExecutionState = (void*)GetProcAddress(kernel32, "SetThreadExecutionState"); - if (WIN32_SetThreadExecutionState) { - /* set the thread execution level to avoid sleep */ - if (WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS | WIN32_ES_SYSTEM_REQUIRED | WIN32_ES_AWAYMODE_REQUIRED) == 0) { - /* retry with the XP variant */ - WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS | WIN32_ES_SYSTEM_REQUIRED); - } - } - } -#endif -} - -void os_done(void) -{ -#ifdef __MINGW32__ - HMODULE kernel32 = GetModuleHandle("KERNEL32.DLL"); - WORD (WINAPI* WIN32_SetThreadExecutionState)(DWORD); - - if (kernel32) { - WIN32_SetThreadExecutionState = (void*)GetProcAddress(kernel32, "SetThreadExecutionState"); - if (WIN32_SetThreadExecutionState) { - /* restore the normal execution level */ - WIN32_SetThreadExecutionState(WIN32_ES_CONTINUOUS); - } - } -#endif -} - diff --git a/os.h b/os.h deleted file mode 100644 index 87bd730f..00000000 --- a/os.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2011 Andrea Mazzoleni - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef __OS_H -#define __OS_H - -/****************************************************************************/ -/* os */ - -void os_init(void); -void os_done(void); - -#endif - diff --git a/portable.h b/portable.h index 256ffbd3..01f2216a 100644 --- a/portable.h +++ b/portable.h @@ -111,79 +111,13 @@ #define SWITCH_GETOPT_LONG(a,b) b #endif -#ifdef __MINGW32__ /* Specific for MingW */ +/** + * Includes specific support for Windows or Linux. + */ +#ifdef __MINGW32__ #include "mingw.h" - -/* We have nano second support */ -#define STAT_NSEC(st) (st)->st_mtimensec - -#else /* Specific for Unix */ - -#define O_BINARY 0 /**< Not used in Unix. */ -#define O_SEQUENTIAL 0 /**< In Unix posix_fadvise() shall be used. */ - -/* Check if we have nanoseconds support */ -#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC -#define STAT_NSEC(st) (st)->st_mtim.tv_nsec /* Linux */ -#elif HAVE_STRUCT_STAT_ST_MTIMENSEC -#define STAT_NSEC(st) (st)->st_mtimensec /* NetBSD */ -#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC -#define STAT_NSEC(st) (st)->st_mtimespec.tv_nsec /* FreeBSD, Mac OS X */ #else -/** - * If nanoseconds are not supported, we report the special FILE_MTIME_NSEC_INVALID value, - * to mark that it's undefined. - * This result in not having it saved into the content file as a dummy 0. - */ -#define STAT_NSEC(st) -1 -#endif - -#ifdef O_NOATIME -/** - * Open a file with the O_NOATIME flag to avoid to update the acces time. - */ -static inline int open_noatime(const char* file, int flags) -{ - int f = open(file, flags | O_NOATIME); - if (f == -1 && errno == EPERM) - f = open(file, flags); - return f; -} -#else -#define open_noatime open -#endif - -/** - * Check if the specified file is hidden. - */ -static inline int dirent_hidden(struct dirent* dd) -{ - return dd->d_name[0] == '.'; -} - -/** - * Return a description of the file type. - */ -static inline const char* stat_desc(struct stat* st) -{ - if (S_ISREG(st->st_mode)) - return "regular"; - if (S_ISDIR(st->st_mode)) - return "directory"; - if (S_ISCHR(st->st_mode)) - return "character"; - if (S_ISBLK(st->st_mode)) - return "block-device"; - if (S_ISFIFO(st->st_mode)) - return "fifo"; - if (S_ISLNK(st->st_mode)) - return "link"; - if (S_ISLNK(st->st_mode)) - return "symbolic-link"; - if (S_ISSOCK(st->st_mode)) - return "socket"; - return "unknown"; -} +#include "unix.h" #endif /** @@ -194,5 +128,15 @@ static inline int hardlink(const char* a, const char* b) return link(a, b); } +/** + * Initializes the system. + */ +void os_init(void); + +/** + * Deintialize the system. + */ +void os_done(void); + #endif diff --git a/unix.c b/unix.c new file mode 100644 index 00000000..ef7838ec --- /dev/null +++ b/unix.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2011 Andrea Mazzoleni + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "portable.h" + +int open_noatime(const char* file, int flags) +{ +#ifdef O_NOATIME + int f = open(file, flags | O_NOATIME); + + /* only root is allowed to use O_NOATIME, in case retry without it */ + if (f == -1 && errno == EPERM) + f = open(file, flags); + return f; +#else + return open(file, flags); +#endif +} + +int dirent_hidden(struct dirent* dd) +{ + return dd->d_name[0] == '.'; +} + +const char* stat_desc(struct stat* st) +{ + if (S_ISREG(st->st_mode)) + return "regular"; + if (S_ISDIR(st->st_mode)) + return "directory"; + if (S_ISCHR(st->st_mode)) + return "character"; + if (S_ISBLK(st->st_mode)) + return "block-device"; + if (S_ISFIFO(st->st_mode)) + return "fifo"; + if (S_ISLNK(st->st_mode)) + return "link"; + if (S_ISLNK(st->st_mode)) + return "symbolic-link"; + if (S_ISSOCK(st->st_mode)) + return "socket"; + return "unknown"; +} + +void os_init(void) +{ +} + +void os_done(void) +{ +} + diff --git a/unix.h b/unix.h new file mode 100644 index 00000000..47b95084 --- /dev/null +++ b/unix.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2011 Andrea Mazzoleni + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __UNIX_H +#define __UNIX_H + +#define O_BINARY 0 /**< Not used in Unix. */ +#define O_SEQUENTIAL 0 /**< In Unix posix_fadvise() shall be used. */ + +/* Check if we have nanoseconds support */ +#if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC +#define STAT_NSEC(st) (st)->st_mtim.tv_nsec /* Linux */ +#elif HAVE_STRUCT_STAT_ST_MTIMENSEC +#define STAT_NSEC(st) (st)->st_mtimensec /* NetBSD */ +#elif HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC +#define STAT_NSEC(st) (st)->st_mtimespec.tv_nsec /* FreeBSD, Mac OS X */ +#else +/** + * If nanoseconds are not supported, we report the special FILE_MTIME_NSEC_INVALID value, + * to mark that it's undefined. + * This result in not having it saved into the content file as a dummy 0. + */ +#define STAT_NSEC(st) -1 +#endif + +/** + * Open a file with the O_NOATIME flag to avoid to update the acces time. + */ +int open_noatime(const char* file, int flags); + +/** + * Check if the specified file is hidden. + */ +int dirent_hidden(struct dirent* dd); + +/** + * Return a description of the file type. + */ +const char* stat_desc(struct stat* st); + +#endif +