summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2009-10-09 19:44:23 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2009-10-09 19:44:23 -0700
commit9e85f9cee6d0d923d4d76d5f936bbcb7a0610f26 (patch)
tree44f8f49c85ccc515d7ba071de1bd7eb69f411c8b
parent085b30c4fb0afe2dce88363b16068113c7c267c1 (diff)
downloadvyatta-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.am1
-rw-r--r--src/commit2.c3
-rw-r--r--src/common/unionfs.c96
-rw-r--r--src/delete.c3
-rw-r--r--src/dump_session.c4
-rw-r--r--src/exe_action.c3
-rw-r--r--src/priority.c3
-rw-r--r--src/set.c3
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) {
diff --git a/src/set.c b/src/set.c
index 195beeb..9be3fc8 100644
--- a/src/set.c
+++ b/src/set.c
@@ -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) {