diff --git a/lib/clixon/clixon_yang.h b/lib/clixon/clixon_yang.h
index b9ce42c4..4a254e36 100644
--- a/lib/clixon/clixon_yang.h
+++ b/lib/clixon/clixon_yang.h
@@ -266,6 +266,9 @@ cvec *yang_cvec_get(yang_stmt *ys);
int yang_cvec_set(yang_stmt *ys, cvec *cvv);
cg_var *yang_cvec_add(yang_stmt *ys, enum cv_type type, char *name);
int yang_cvec_rm(yang_stmt *ys, char *name);
+int yang_ref_get(yang_stmt *ys);
+int yang_ref_inc(yang_stmt *ys);
+int yang_ref_dec(yang_stmt *ys);
uint16_t yang_flag_get(yang_stmt *ys, uint16_t flag);
int yang_flag_set(yang_stmt *ys, uint16_t flag);
int yang_flag_reset(yang_stmt *ys, uint16_t flag);
diff --git a/lib/src/clixon_datastore_read.c b/lib/src/clixon_datastore_read.c
index 63ffcb31..d728b5ae 100644
--- a/lib/src/clixon_datastore_read.c
+++ b/lib/src/clixon_datastore_read.c
@@ -708,7 +708,7 @@ xmldb_readfile(clixon_handle h,
* Same ymodules are inserted into yspec1, ie pointers only
*/
if (needclone && xmodfile){
- if ((yspec1 = yspec_new1(h, YANG_DOMAIN_TOP, "tmp")) == NULL)
+ if ((yspec1 = yspec_new1(h, YANG_DOMAIN_TOP, "prevyang")) == NULL)
goto done;
xmsd = NULL;
while ((xmsd = xml_child_each(xmodfile, xmsd, CX_ELMNT)) != NULL) {
@@ -722,6 +722,7 @@ xmldb_readfile(clixon_handle h,
continue; // XXX error?
if (yn_insert1(yspec1, ymod) < 0)
goto done;
+ yang_ref_inc(ymod);
}
}
} /* if msdiff */
@@ -747,8 +748,6 @@ xmldb_readfile(clixon_handle h,
done:
if (mr.mr_subdir)
free(mr.mr_subdir);
- if (yspec1)
- ys_free1(yspec1, 1);
if (xmodfile)
xml_free(xmodfile);
if (msdiff)
diff --git a/lib/src/clixon_yang.c b/lib/src/clixon_yang.c
index c9fdab3f..90c515f9 100644
--- a/lib/src/clixon_yang.c
+++ b/lib/src/clixon_yang.c
@@ -425,6 +425,47 @@ yang_cvec_rm(yang_stmt *ys,
return 0;
}
+/*! Get yang object reference count
+ *
+ * @param[in] ys Yang statement
+ * @retval ref Reference coun t
+ */
+int
+yang_ref_get(yang_stmt *ys)
+{
+ return ys->ys_ref;
+}
+
+/*! Increment yang object reference count with +1
+ *
+ * @param[in] ys Yang statement
+ * @retval 0
+ */
+int
+yang_ref_inc(yang_stmt *ys)
+{
+ ys->ys_ref++;
+ return 0;
+}
+
+/*! Decrement yang object reference count with -1
+ *
+ * @param[in] ys Yang statement
+ * @retval 0 Ok
+ * @retval -1 Error
+ */
+int
+yang_ref_dec(yang_stmt *ys)
+{
+ int retval = -1;
+
+ if (ys->ys_ref > 0)
+ ys->ys_ref--;
+ retval = 0;
+ // done:
+ return retval;
+}
+
/*! Get yang stmt flags, used for internal algorithms
*
* @param[in] ys Yang statement
@@ -1154,8 +1195,13 @@ ys_freechildren(yang_stmt *ys)
int
ys_free(yang_stmt *ys)
{
- ys_freechildren(ys);
- ys_free1(ys, 1);
+ if (yang_ref_get(ys) > 0){
+ yang_ref_dec(ys);
+ }
+ else {
+ ys_freechildren(ys);
+ ys_free1(ys, 1);
+ }
return 0;
}
diff --git a/lib/src/clixon_yang_internal.h b/lib/src/clixon_yang_internal.h
index 0d239a87..7e8b4080 100644
--- a/lib/src/clixon_yang_internal.h
+++ b/lib/src/clixon_yang_internal.h
@@ -68,7 +68,9 @@ typedef struct yang_type_cache yang_type_cache;
*/
struct yang_stmt {
/* On x86_64, the following three fields take 8 bytes */
- enum rfc_6020 ys_keyword:16; /* YANG keyword */
+ enum rfc_6020 ys_keyword:8; /* YANG keyword */
+ uint8_t ys_ref; /* Reference count for free: 0 means
+ * no sharing, 1: two references */
uint16_t ys_flags; /* Flags according to YANG_FLAG_MARK and others */
uint32_t ys_len; /* Number of children */
#ifdef YANG_SPEC_LINENR
@@ -112,6 +114,7 @@ struct yang_stmt {
rpc_callback_t *ysu_action_cb; /* Y_ACTION: Action callback list*/
char *ysu_filename; /* Y_MODULE/Y_SUBMODULE: For debug/errors: filename */
yang_type_cache *ysu_typecache; /* Y_TYPE: cache all typedef data except unions */
+
} u;
};
diff --git a/test/test_confirmed_commit.sh b/test/test_confirmed_commit.sh
index b8a2af10..f6ab7a24 100755
--- a/test/test_confirmed_commit.sh
+++ b/test/test_confirmed_commit.sh
@@ -184,9 +184,10 @@ rpc "ab" ""
new "6. netconf persistent confirmed-commit with timeout"
reset
edit_config "candidate" "$CONFIGB"
-commit "3abcd"
+# need 5 for valgrind netconf that takes a couple of seconds to finish
+commit "5abcd"
assert_config_equals "running" "$CONFIGB"
-sleep 3
+sleep 5
assert_config_equals "running" ""
################################################################################