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 From edb8226cb91b197f022bfdd28246ff5a86541614 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 17 Dec 2007 15:34:27 -0800 Subject: Fixed commit after partial deletion of the multivalue. --- src/commit.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/commit.c b/src/commit.c index 400328e..24aff34 100644 --- a/src/commit.c +++ b/src/commit.c @@ -157,6 +157,7 @@ static boolean validate_dir_for_commit() cp = NULL; status = get_value(&cp, &m_path); if (status == VTWERR_OK) { + size_t value_size = 0; #ifdef DEBUG1 printf("Validating value |%s|\n" "for path %s\n", cp, m_path.path); @@ -167,6 +168,7 @@ static boolean validate_dir_for_commit() // Bug #2509 if (def.multi) { char *old_value = NULL; + value_size = strlen(cp); switch_path(APATH); // temporarily switching to the active config path status = get_value(&old_value, &m_path); if (status == VTWERR_OK) { @@ -176,8 +178,10 @@ static boolean validate_dir_for_commit() if (old_value) my_free(old_value); } - - status = validate_value(&def, cp); + if (strlen(cp) > 0 || value_size == 0) + status = validate_value(&def, cp); + else + status = TRUE; ret = ret && status; } if (cp) @@ -238,7 +242,7 @@ static boolean validate_dir_for_commit() if (!def_present || !def.tag) pop_path(&t_path); /* for PUSH 2b */ - } + } // while status = closedir(dp); if (status) bye("Cannot close dir %s\n", m_path.path); -- cgit v1.2.3 From f536748a2ffdf1c9c9803f816eb15d3a9c8afa1e Mon Sep 17 00:00:00 2001 From: alex Date: Tue, 18 Dec 2007 04:19:54 -0800 Subject: Reorganized things a bit in a value subtraction algorithm. --- src/cli_new.c | 80 ++++++++++++++++++----------------------------------------- 1 file changed, 24 insertions(+), 56 deletions(-) (limited to 'src') diff --git a/src/cli_new.c b/src/cli_new.c index b668e5b..e3a7955 100644 --- a/src/cli_new.c +++ b/src/cli_new.c @@ -58,12 +58,6 @@ static int cond_format_lens[DOMAIN_TYPE] = 6 /* MACADDR_TYPE */ }; -struct __slist_t; - -typedef struct __slist_t { - struct __slist_t *next; -} slist_t; - static int cli_val_len; static char *cli_val_ptr; @@ -1901,85 +1895,59 @@ boolean validate_value(vtw_def *def, char *cp) return ret; } -typedef struct __value_list { - slist_t link; - const char *value; -} value_list; - -static void delete_list(slist_t *head) -{ - while (head != NULL) { - slist_t *elem = head; - head = head->next; - my_free(elem); - } -} - void subtract_values(char **lhs, const char *rhs) { - size_t length = 0; + size_t length = 0, lhs_cnt = 0, rhs_cnt = 0, i; const char *line = NULL; char *rhs_copy = NULL, *res = NULL; - slist_t *head = NULL, *ptr = NULL; - slist_t *new_head = NULL, *new_ptr = NULL; + const char **head = NULL, **ptr = NULL; + const char **new_head = NULL, **new_ptr = NULL; if (lhs == NULL || *lhs == NULL || **lhs == '\0' || rhs == NULL || *rhs == '\0') return; - rhs_copy = my_malloc(strlen(rhs), "subtract_values rhs_copy"); - strcpy(rhs_copy, rhs); - - head = ptr = my_malloc(sizeof(slist_t), "subtract_values list1"); - memset(head, 0, sizeof(slist_t)); + rhs_copy = strdup(rhs); + length = strlen(rhs) / 2; + head = ptr = my_malloc(length, "subtract_values list1"); + memset(head, 0, length); line = strtok(rhs_copy, "\n\r"); while (line != NULL && *line != '\0') { - value_list *elem = NULL; - - elem = (value_list *) my_malloc(sizeof(value_list), "subtract_values elem1"); - memset(elem, 0, sizeof(value_list)); - elem->value = line; - ptr->next = (slist_t *) elem; - ptr = ptr->next; + *ptr = line; + ptr++; + rhs_cnt++; line = strtok(NULL, "\n\r"); } - new_head = new_ptr = my_malloc(sizeof(slist_t), "subtract_values list2"); - memset(new_head, 0, sizeof(slist_t)); + length = strlen(*lhs) / 2; + new_head = new_ptr = my_malloc(length, "subtract_values list2"); + memset(new_head, 0, length); + length = 0; line = strtok(*lhs, "\n\r"); while (line != NULL && *line != '\0') { - value_list *elem = NULL; - - ptr = head; - while (ptr->next != NULL) { - elem = (value_list *) ptr->next; - if (strncmp(line, elem->value, strlen(line)) == 0) + for (i = 0; i < rhs_cnt; i++) { + if (strncmp(line, head[i], strlen(line)) == 0) break; - ptr = ptr->next; } - if (ptr->next == NULL) { - elem = (value_list *) my_malloc(sizeof(value_list), "subtract_values elem2"); - memset(elem, 0, sizeof(value_list)); - elem->value = line; - new_ptr->next = elem; - new_ptr = new_ptr->next; + if (i >= rhs_cnt) { + *new_ptr = line; length += strlen(line) + 1; + new_ptr++; + lhs_cnt++; } line = strtok(NULL, "\n\r"); } - new_ptr = new_head->next; res = (char *) my_malloc(length + 1, "subtract_values result"); *res = '\0'; - while (new_ptr != NULL) { - strcat(res, ((value_list *) new_ptr)->value); + for (i = 0; i < lhs_cnt; i++) { + strcat(res, new_head[i]); strcat(res, "\n"); - new_ptr = new_ptr->next; } - delete_list(head); - delete_list(new_head); + my_free(head); + my_free(new_head); if (rhs_copy != NULL) my_free(rhs_copy); my_free(*lhs); -- cgit v1.2.3