From fceaa8a4cf346fce39751aa42c076717c44a323c Mon Sep 17 00:00:00 2001 From: Andrea Mazzoleni Date: Tue, 18 Jun 2013 21:06:31 +0200 Subject: [PATCH] Uses a lock file instead than a pid file. It's more appropriate for a not daemon. --- HISTORY | 6 +++--- portable.h | 4 ++-- snapraid.c | 40 ++++++++++++++++++++-------------------- state.c | 12 +++++------- state.h | 2 +- util.c | 40 +++++++++------------------------------- util.h | 12 ++++++------ 7 files changed, 46 insertions(+), 70 deletions(-) diff --git a/HISTORY b/HISTORY index 854673f1..b0ed044b 100644 --- a/HISTORY +++ b/HISTORY @@ -9,9 +9,9 @@ SnapRAID HISTORY * Added RAID5/RAID6 mmx and sse2 implementations with unrolling by 4. They are a little faster than the previous unroll by 2. * Added a hash seed to make harder intentional collision attacks. - * Added a pid file to avoid multiple running instances on the same array. - The file is named as the first content file adding the .pid extension. - There is also the undocumented --test-skip-pid to avoid to check it. + * Added a lock file to avoid multiple running instances on the same array. + The file is named as parity file adding the .lock extension. + There is also the undocumented --test-skip-lock to avoid to check it. 3.1 2013/5 ========== diff --git a/portable.h b/portable.h index a976f3bc..ab6d9d16 100644 --- a/portable.h +++ b/portable.h @@ -125,10 +125,10 @@ #endif /** - * Enable PID file support. + * Enable lock file support. */ #if HAVE_FLOCK && HAVE_FTRUNCATE -#define HAVE_PIDFILE 1 +#define HAVE_LOCKFILE 1 #endif /** diff --git a/snapraid.c b/snapraid.c index 33770852..1b01f3fd 100644 --- a/snapraid.c +++ b/snapraid.c @@ -84,7 +84,7 @@ void usage(void) #define OPT_TEST_SKIP_SEQUENTIAL 263 #define OPT_TEST_FORCE_MURMUR3 264 #define OPT_TEST_FORCE_SPOOKY2 265 -#define OPT_TEST_SKIP_PID 266 +#define OPT_TEST_SKIP_LOCK 266 #if HAVE_GETOPT_LONG struct option long_options[] = { @@ -139,8 +139,8 @@ struct option long_options[] = { /* Force Spooky2 hash */ { "test-force-spooky2", 0, 0, OPT_TEST_FORCE_SPOOKY2 }, - /* Skip the use of pid file */ - { "test-skip-pid", 0, 0, OPT_TEST_SKIP_PID }, + /* Skip the use of lock file */ + { "test-skip-lock", 0, 0, OPT_TEST_SKIP_LOCK }, { 0, 0, 0, 0 } }; @@ -188,7 +188,7 @@ int main(int argc, char* argv[]) int test_skip_device; int test_force_murmur3; int test_force_spooky2; - int test_skip_pid; + int test_skip_lock; const char* conf; struct snapraid_state state; int operation; @@ -202,7 +202,7 @@ int main(int argc, char* argv[]) const char* command; const char* import; const char* log; - int pid; + int lock; os_init(); @@ -225,7 +225,7 @@ int main(int argc, char* argv[]) test_skip_device = 0; test_force_murmur3 = 0; test_force_spooky2 = 0; - test_skip_pid = 0; + test_skip_lock = 0; blockstart = 0; blockcount = 0; tommy_list_init(&filterlist_file); @@ -233,7 +233,7 @@ int main(int argc, char* argv[]) filter_missing = 0; import = 0; log = 0; - pid = 0; + lock = 0; opterr = 0; while ((c = @@ -354,8 +354,8 @@ int main(int argc, char* argv[]) case OPT_TEST_FORCE_SPOOKY2 : test_force_spooky2 = 1; break; - case OPT_TEST_SKIP_PID : - test_skip_pid = 1; + case OPT_TEST_SKIP_LOCK : + test_skip_lock = 1; break; default: fprintf(stderr, "Unknown option '%c'\n", (char)c); @@ -445,15 +445,15 @@ int main(int argc, char* argv[]) /* read the configuration file */ state_config(&state, conf, command, verbose, gui, force_zero, force_empty, force_uuid, find_by_name, test_expect_unrecoverable, test_expect_recoverable, test_skip_sign, test_skip_fallocate, test_skip_sequential, test_skip_device, test_force_murmur3, test_force_spooky2); -#if HAVE_PIDFILE - /* create the pid file */ - if (!test_skip_pid) { - pid = pid_lock(state.pidfile); - if (pid == -1) { +#if HAVE_LOCKFILE + /* create the lock file */ + if (!test_skip_lock) { + lock = lock_lock(state.lockfile); + if (lock == -1) { if (errno != EWOULDBLOCK) { - fprintf(stderr, "Error creating the pid file '%s'. %s.\n", state.pidfile, strerror(errno)); + fprintf(stderr, "Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno)); } else { - fprintf(stderr, "The pid file '%s' is already locked!\n", state.pidfile); + fprintf(stderr, "The lock file '%s' is already locked!\n", state.lockfile); fprintf(stderr, "SnapRAID is already in use!\n"); } exit(EXIT_FAILURE); @@ -580,10 +580,10 @@ int main(int argc, char* argv[]) } } -#if HAVE_PIDFILE - if (!test_skip_pid) { - if (pid_unlock(pid, state.pidfile) == -1) { - fprintf(stderr, "Error closing the pid file '%s'. %s.\n", state.pidfile, strerror(errno)); +#if HAVE_LOCKFILE + if (!test_skip_lock) { + if (lock_unlock(lock) == -1) { + fprintf(stderr, "Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno)); exit(EXIT_FAILURE); } } diff --git a/state.c b/state.c index 3a41ecc8..f4a56e58 100644 --- a/state.c +++ b/state.c @@ -45,7 +45,7 @@ void state_init(struct snapraid_state* state) state->qarity_device = 0; state->pool[0] = 0; state->pool_device = 0; - state->pidfile[0] = 0; + state->lockfile[0] = 0; state->level = 1; /* default is the lowest protection */ tommy_list_init(&state->disklist); @@ -359,6 +359,10 @@ void state_config(struct snapraid_state* state, const char* path, const char* co } state->parity_device = st.st_dev; + + /* set lock file */ + pathcpy(state->lockfile, sizeof(state->lockfile), state->parity); + pathcat(state->lockfile, sizeof(state->lockfile), ".lock"); } else if (strcmp(tag, "q-parity") == 0) { char device[PATH_MAX]; char* slash; @@ -463,12 +467,6 @@ void state_config(struct snapraid_state* state, const char* path, const char* co content = content_alloc(buffer, st.st_dev); tommy_list_insert_tail(&state->contentlist, &content->node, content); - - /* if not set pid file, set it as the first content file */ - if (!state->pidfile[0]) { - pathcpy(state->pidfile, sizeof(state->pidfile), buffer); - pathcat(state->pidfile, sizeof(state->pidfile), ".pid"); - } } else if (strcmp(tag, "disk") == 0) { char dir[PATH_MAX]; char device[PATH_MAX]; diff --git a/state.h b/state.h index 34e67f36..079281ac 100644 --- a/state.h +++ b/state.h @@ -50,7 +50,7 @@ struct snapraid_state { uint64_t qarity_device; /**< Device identifier of the qarity. */ char pool[PATH_MAX]; /**< Path of the pool tree. */ uint64_t pool_device; /**< Device identifier of the pool. */ - char pidfile[PATH_MAX]; /**< Path of the pid file to use. */ + char lockfile[PATH_MAX]; /**< Path of the lock file to use. */ unsigned char hashseed[HASH_SIZE]; /**< Hash seed. */ unsigned level; /**< Number of parity levels. 1 for RAID5, 2 for RAID6. */ unsigned hash; /**< Hash kind used. */ diff --git a/util.c b/util.c index 14de2d3c..1dfbf5fe 100644 --- a/util.c +++ b/util.c @@ -867,16 +867,14 @@ void randomize(void* void_ptr, unsigned size) } /****************************************************************************/ -/* pid */ +/* lock */ -#if HAVE_PIDFILE -int pid_lock(const char* file) +#if HAVE_LOCKFILE +int lock_lock(const char* file) { - char buffer[64]; - ssize_t len; int f; - f = open(file, O_CREAT | O_WRONLY, 0600); + f = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0600); if (f == -1) { return -1; } @@ -887,38 +885,18 @@ int pid_lock(const char* file) return -1; } - /* write the pid into the file */ - snprintf(buffer, sizeof(buffer), "%ld", (long)getpid()); - - len = strlen(buffer); - if (write(f, buffer, len) != len) { - close(f); - return -1; - } - - if (ftruncate(f, len) == -1) { - close(f); - return -1; - } - return 0; } #endif -#if HAVE_PIDFILE -int pid_unlock(int f, const char* file) +#if HAVE_LOCKFILE +int lock_unlock(int f) { /* - * Remove file before closing it. - * This opens a race course in case another process already opened it. - * but has not yet failed the next flock() call. - * But removing it after the close, opens a similar race course. - * It seems that deleting a pid file is something just impossible to do it right. + * Intentionally don't remove file the lock file. + * Removing it just introduces race course with other process + * that could have already opened it. */ - if (remove(file) == -1) { - close(f); - return -1; - } if (close(f) == -1) { return -1; diff --git a/util.h b/util.h index e3dd4cc3..b3d1d318 100644 --- a/util.h +++ b/util.h @@ -487,19 +487,19 @@ static inline oathash_t oathashm(oathash_t hash, const unsigned char* value, uns } /****************************************************************************/ -/* pid */ +/* lock */ /** - * Creates and locks the pid file. - * Returns -1 on error, otherwise it's the file handle to pass to pid_unlock(). + * Creates and locks the lock file. + * Returns -1 on error, otherwise it's the file handle to pass to lock_unlock(). */ -int pid_lock(const char* file); +int lock_lock(const char* file); /** - * Unlocks the pid file. + * Unlocks the lock file. * Returns -1 on error. */ -int pid_unlock(int f, const char* file); +int lock_unlock(int f); #endif