From c6a0c8078b8be141618fed1011229582f13ec30f Mon Sep 17 00:00:00 2001 From: Tom Grennan Date: Thu, 13 Dec 2007 18:21:38 -0800 Subject: support aufs and unionfs --- src/commit.c | 4 ++-- src/delete.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/commit.c b/src/commit.c index 3fa77c5..d0d2517 100644 --- a/src/commit.c +++ b/src/commit.c @@ -1318,8 +1318,8 @@ static int fin_commit(boolean ok) static char format4[]="rm -rf %s/{.*,*} >&/dev/null ; /bin/true"; /*cdirp*/ static char format5[]="rm -rf %s/{.*,*} >&/dev/null ; /bin/true"; /*adirp*/ static char format6[]="mv -f %s/* -t %s";/*tmpp, adirp*/ - static char format7[]="sudo mount -t unionfs -o dirs=%s=rw:%s=ro" - " unionfs %s"; /*cdirp, adirp, mdirp*/ + static char format7[]="sudo mount -t $UNIONFS -o dirs=%s=rw:%s=ro" + " $UNIONFS %s"; /*cdirp, adirp, mdirp*/ int m_len = strlen(get_mdirp()); int t_len = strlen(get_tmpp()); int c_len = strlen(get_cdirp()); diff --git a/src/delete.c b/src/delete.c index 1b7b62e..b62a697 100644 --- a/src/delete.c +++ b/src/delete.c @@ -28,8 +28,8 @@ static void remove_rf(boolean do_umount) command = my_malloc(strlen(get_mdirp()) + strlen(get_cdirp()) + strlen(get_mdirp()) + 100, "delete"); - sprintf(command, "sudo mount -t unionfs -o dirs=%s=rw:%s=ro:" - " unionfs %s", get_cdirp(), get_adirp(), get_mdirp()); + sprintf(command, "sudo mount -t $UNIONFS -o dirs=%s=rw:%s=ro:" + " $UNIONFS %s", get_cdirp(), get_adirp(), get_mdirp()); system(command); free(command); } -- cgit v1.2.3 From 8d6714e356bf64016f5be55f5c4b9bb0a71b5a3c Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Thu, 13 Dec 2007 18:35:06 -0800 Subject: put pid in config lock file --- src/cli_new.c | 47 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/cli_new.c b/src/cli_new.c index d4380d5..3f64489 100644 --- a/src/cli_new.c +++ b/src/cli_new.c @@ -240,19 +240,44 @@ release_config_lock() int get_config_lock() { - int fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660); - if (fd == -1) { - return -1; - } - if (close(fd) == -1) { - release_config_lock(); - return -1; - } - if (atexit(release_config_lock) != 0) { + int fd = -1; + FILE *lfile = NULL; + int ret = -1; + + do { + /* create lock file */ + fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660); + if (fd == -1) { + break; + } + + /* write pid into lock file */ + if ((lfile = fdopen(fd, "w")) == NULL) { + break; + } + if (fprintf(lfile, "%u", getpid()) < 0) { + break; + } + /* fclose also closes fd */ + if (fclose(lfile) != 0) { + break; + } + /* clean up on exit */ + if (atexit(release_config_lock) != 0) { + break; + } + ret = 0; + } while (0); + + if (ret == -1) { + if (lfile) { + fclose(lfile); + } else if (fd != -1) { + close(fd); + } release_config_lock(); - return -1; } - return 0; + return ret; } void internal_error(int line, char *file) -- cgit v1.2.3 From 95d19bd7cb014b65816dd9ccf61733c57f369b05 Mon Sep 17 00:00:00 2001 From: An-Cheng Huang Date: Fri, 14 Dec 2007 16:11:16 -0800 Subject: fix for bug 2479: when commit cannot obtain the config lock, it will retry a fixed number of times and then check if the lock owner is still alive. if not, the orphaned lock is cleaned up so that the later commit can proceed as usual. --- src/cli_new.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/cli_new.c b/src/cli_new.c index 3f64489..b668e5b 100644 --- a/src/cli_new.c +++ b/src/cli_new.c @@ -14,6 +14,8 @@ #include "cli_val.h" #include "cli_parse.h" #include +#include +#include #include "cli_objects.h" #include "cli_val_engine.h" @@ -229,6 +231,7 @@ void di(vtw_sorted *srtp) } #define LOCK_FILE "/opt/vyatta/config/.lock" +#define COMMIT_CMD "/opt/vyatta/sbin/my_commit" static void release_config_lock() @@ -237,6 +240,92 @@ release_config_lock() /* error ignored */ } +/* try to clean up orphaned lock file. return -1 if failed */ +static int +try_lock_cleanup() +{ + char buf[128]; + char proc[128]; + FILE *f = NULL; + int ret = -1; + struct stat statb; + + do { + /* get the proc entry */ + if ((f = fopen(LOCK_FILE, "r")) == NULL) { + break; + } + if (fgets(proc, 128, f) == NULL) { + break; + } + /* read the proc entry */ + if (stat(proc, &statb) == -1) { + if (errno == ENOENT) { + /* proc entry doesn't exist. can clean up the lock now */ + ret = 0; + break; + } + } + fclose(f); + if ((f = fopen(proc, "r")) == NULL) { + /* can't open proc entry. assume we can't clean up */ + break; + } + if (fgets(buf, 128, f) == NULL) { + /* can't read proc entry. assume we can't clean up */ + break; + } + /* check if the process is commit */ + if (strcmp(buf, COMMIT_CMD) == 0) { + /* it is commit. can't clean up */ + break; + } + /* can clean up the lock */ + ret = 0; + } while (0); + if (f) { + fclose(f); + } + if (ret == 0) { + unlink(LOCK_FILE); + if (stat(LOCK_FILE, &statb) != -1 || errno != ENOENT) { + /* proc entry still exists. cleanup failed */ + ret = -1; + } + } + return ret; +} + +static int +create_lock_file(int try_cleanup) +{ + int fd = -1; + int i = 0; + struct timespec req; + +#define LOCK_WAIT_TIME 2 +#define LOCK_NUM_RETRIES 5 + req.tv_sec = LOCK_WAIT_TIME; + req.tv_nsec = 0; + fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660); + if (fd == -1) { + for (i = 0; i < LOCK_NUM_RETRIES; i++) { + nanosleep(&req, NULL); + fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660); + if (fd >= 0) { + break; + } + } + } + if (fd == -1 && try_cleanup) { + if (try_lock_cleanup() != -1) { + /* cleanup succeeded */ + fd = create_lock_file(0); + } + } + return fd; +} + int get_config_lock() { @@ -246,7 +335,7 @@ get_config_lock() do { /* create lock file */ - fd = open(LOCK_FILE, O_WRONLY | O_CREAT | O_EXCL, 0660); + fd = create_lock_file(1); if (fd == -1) { break; } @@ -255,7 +344,7 @@ get_config_lock() if ((lfile = fdopen(fd, "w")) == NULL) { break; } - if (fprintf(lfile, "%u", getpid()) < 0) { + if (fprintf(lfile, "/proc/%u/cmdline", getpid()) < 0) { break; } /* fclose also closes fd */ -- cgit v1.2.3