diff options
author | An-Cheng Huang <ancheng@vyatta.com> | 2009-10-09 19:44:23 -0700 |
---|---|---|
committer | An-Cheng Huang <ancheng@vyatta.com> | 2009-10-09 19:44:23 -0700 |
commit | 9e85f9cee6d0d923d4d76d5f936bbcb7a0610f26 (patch) | |
tree | 44f8f49c85ccc515d7ba071de1bd7eb69f411c8b | |
parent | 085b30c4fb0afe2dce88363b16068113c7c267c1 (diff) | |
download | vyatta-cfg-9e85f9cee6d0d923d4d76d5f936bbcb7a0610f26.tar.gz vyatta-cfg-9e85f9cee6d0d923d4d76d5f936bbcb7a0610f26.zip |
commit post-processing performance optimization
* convert subshell invocations to library function calls.
* reduce boot time by ~40 seconds for "certain configuration".
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/commit2.c | 3 | ||||
-rw-r--r-- | src/common/unionfs.c | 96 | ||||
-rw-r--r-- | src/delete.c | 3 | ||||
-rw-r--r-- | src/dump_session.c | 4 | ||||
-rw-r--r-- | src/exe_action.c | 3 | ||||
-rw-r--r-- | src/priority.c | 3 | ||||
-rw-r--r-- | src/set.c | 3 |
8 files changed, 95 insertions, 21 deletions
diff --git a/Makefile.am b/Makefile.am index 76c174c..faa68f7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,6 +18,7 @@ modprobe_SCRIPTS = etc/modprobe.d/vyatta_nocopybreak lib_LTLIBRARIES = src/libvyatta-cfg.la src_libvyatta_cfg_la_LIBADD = /usr/lib/libglib-2.0.la +src_libvyatta_cfg_la_LIBADD += /usr/lib/libgio-2.0.la src_libvyatta_cfg_la_LDFLAGS = -version-info 1:0:0 src_libvyatta_cfg_la_SOURCES = src/cli_parse.y src/cli_def.l src/cli_val.l \ src/cli_new.c src/cli_path_utils.c \ diff --git a/src/commit2.c b/src/commit2.c index 67e3889..4215ccc 100644 --- a/src/commit2.c +++ b/src/commit2.c @@ -124,6 +124,9 @@ main(int argc, char** argv) boolean disable_partial_commit = FALSE; boolean full_commit_check = FALSE; + /* this is needed before calling certain glib functions */ + g_type_init(); + //grab inputs while ((ch = getopt(argc, argv, "dpthsecoaf")) != -1) { switch (ch) { diff --git a/src/common/unionfs.c b/src/common/unionfs.c index 6642c05..b053d80 100644 --- a/src/common/unionfs.c +++ b/src/common/unionfs.c @@ -6,6 +6,7 @@ #include <syslog.h> #include <unistd.h> #include <glib-2.0/glib.h> +#include <gio/gio.h> #include "common/defs.h" #include "common/unionfs.h" @@ -14,6 +15,43 @@ boolean g_debug; extern vtw_path m_path; extern vtw_path t_path; +/*** functions for filesystem operations ***/ +/* these functions replace the system() invocations that were a major source + * of commit overhead. note that they currently duplicate the previous + * behavior so no status is returned (since system() return code was not + * checked). this should probably be changed so each invocation is checked + * for error. + */ +static inline void +sys_mkdir_p(const char *path) +{ + if (g_mkdir_with_parents(path, 0775) != 0) { + /* error */ + return; + } +} + +static inline void +sys_rm(const char *file) +{ + GFile *target = g_file_new_for_path(file); + if (!g_file_delete(target, NULL, NULL)) { + /* error */ + return; + } +} + +static inline void +sys_cp(const char *src_file, const char *dst_file) +{ + GFile *src = g_file_new_for_path(src_file); + GFile *dst = g_file_new_for_path(dst_file); + if (!g_file_copy(src, dst, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, NULL)) { + /* error */ + return; + } +} + void retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op); @@ -1119,63 +1157,79 @@ piecewise_copy(GNode *root_node, boolean test_mode) static gboolean copy_func(GNode *node, gpointer data) { + char buf[MAX_LENGTH_DIR_PATH]; + if (node == NULL) { return FALSE; } - char *command = malloc(MAX_LENGTH_DIR_PATH); - struct SrcDst *sd = (struct SrcDst*)data; - static const char format[]="mkdir -p %s%s";/*tmpp, adirp*/ - static const char format_value[]="cp %s%s{node.val,def} %s%s. 2>/dev/null";/*tmpp, adirp*/ - static const char clear_def[]="rm %s%sdef 2>/dev/null";/*adirp*/ char *path = ((struct VyattaNode*)(node->data))->_data._path; //might not work for terminating multinodes as the node.val won't be copied if (((struct VyattaNode*)(node->data))->_data._value == TRUE && ((struct VyattaNode*)(node->data))->_config._def.tag == FALSE) { + char *parent_path; + char buf1[MAX_LENGTH_DIR_PATH]; + //THIS IS ONLY FOR NODE.VAL (or leafs, term multis) //before copy also need to clear out def file in active directory (will copy over current if found) //this is for the case where it is set by default, then unset at the node--i.e. no longer a default value. if (((struct VyattaNode*)(node->data))->_config._multi == FALSE) { //only for leaf char *parent_path = ((struct VyattaNode*)(node->parent->data))->_data._path; - sprintf(command,clear_def,sd->_dst,parent_path); if (g_debug) { - printf("%s\n",command); - syslog(LOG_DEBUG,"%s\n",command); + printf("rm %s%sdef\n", sd->_dst, parent_path); + syslog(LOG_DEBUG, "rm %s%sdef", sd->_dst, parent_path); fflush(NULL); } if (sd->_test_mode == FALSE) { - system(command); + if (snprintf(buf, MAX_LENGTH_DIR_PATH, "%s%sdef", + sd->_dst, parent_path) < MAX_LENGTH_DIR_PATH) { + sys_rm(buf); + } } } - char *parent_path = ((struct VyattaNode*)(node->parent->data))->_data._path; - sprintf(command,format_value,sd->_src,parent_path,sd->_dst,parent_path); + parent_path = ((struct VyattaNode*)(node->parent->data))->_data._path; if (g_debug) { - printf("%s\n",command); - syslog(LOG_DEBUG,"%s\n",command); + printf("cp %s%s{node.val,def} %s%s\n", sd->_src, parent_path, + sd->_dst, parent_path); + syslog(LOG_DEBUG, "cp %s%s{node.val,def} %s%s\n", + sd->_src, parent_path, sd->_dst, parent_path); fflush(NULL); } if (sd->_test_mode == FALSE) { - system(command); + if (snprintf(buf, MAX_LENGTH_DIR_PATH, "%s%snode.val", + sd->_src, parent_path) < MAX_LENGTH_DIR_PATH + && + snprintf(buf1, MAX_LENGTH_DIR_PATH, "%s%snode.val", + sd->_dst, parent_path) < MAX_LENGTH_DIR_PATH) { + sys_cp(buf, buf1); + } + if (snprintf(buf, MAX_LENGTH_DIR_PATH, "%s%sdef", + sd->_src, parent_path) < MAX_LENGTH_DIR_PATH + && + snprintf(buf1, MAX_LENGTH_DIR_PATH, "%s%sdef", + sd->_dst, parent_path) < MAX_LENGTH_DIR_PATH) { + sys_cp(buf, buf1); + } } - } - else { + } else { if (!IS_DELETE(((struct VyattaNode*)(node->data))->_data._operation)) { - sprintf(command,format,sd->_dst,path); if (g_debug) { - printf("%s\n",command); - syslog(LOG_DEBUG,"%s\n",command); + printf("mkdir_p %s%s\n", sd->_dst, path); + syslog(LOG_DEBUG, "mkdir_p %s%s", sd->_dst, path); fflush(NULL); } if (sd->_test_mode == FALSE) { - system(command); + if (snprintf(buf, MAX_LENGTH_DIR_PATH, "%s%s", sd->_dst, path) + < MAX_LENGTH_DIR_PATH) { + sys_mkdir_p(buf); + } } } } - free(command); return FALSE; } diff --git a/src/delete.c b/src/delete.c index 3011c12..f432934 100644 --- a/src/delete.c +++ b/src/delete.c @@ -148,6 +148,9 @@ int main(int argc, char **argv) char *cp, *delp, *endp; boolean do_umount; + /* this is needed before calling certain glib functions */ + g_type_init(); + cli_operation_name = "Delete"; if (initialize_output() == -1) { diff --git a/src/dump_session.c b/src/dump_session.c index d6b85cf..db54927 100644 --- a/src/dump_session.c +++ b/src/dump_session.c @@ -45,6 +45,10 @@ int main(int argc, char** argv) { int ch; + + /* this is needed before calling certain glib functions */ + g_type_init(); + //grab inputs while ((ch = getopt(argc, argv, "dvh")) != -1) { switch (ch) { diff --git a/src/exe_action.c b/src/exe_action.c index 200ec2d..ee884c3 100644 --- a/src/exe_action.c +++ b/src/exe_action.c @@ -49,6 +49,9 @@ main(int argc, char** argv) char *path = NULL; unsigned long act = 0; + /* this is needed before calling certain glib functions */ + g_type_init(); + //grab inputs while ((ch = getopt(argc, argv, "dhp:a:")) != -1) { switch (ch) { diff --git a/src/priority.c b/src/priority.c index 60388e8..cb40b9a 100644 --- a/src/priority.c +++ b/src/priority.c @@ -32,6 +32,9 @@ main(int argc, char** argv) int ch; char *filename = NULL; + /* this is needed before calling certain glib functions */ + g_type_init(); + //grab inputs while ((ch = getopt(argc, argv, "hf:")) != -1) { switch (ch) { @@ -109,6 +109,9 @@ int main(int argc, char **argv) boolean need_mod = FALSE, not_new = FALSE; boolean empty_val = FALSE; + /* this is needed before calling certain glib functions */ + g_type_init(); + cli_operation_name = "Set"; if (initialize_output() == -1) { |