[augeas-devel] [PATCH] Preserve parse errors under /augeas//error
lutter at redhat.com
lutter at redhat.com
Thu Sep 23 23:47:56 UTC 2010
From: David Lutterkort <lutter at redhat.com>
With the changes in commit 5ee81630, a subtree in /augeas/files that is
dirty after trying to load all files indicates a file that was loaded
before, but is not loaded anymore (e.g., because the set of lenses changed
since the last time we loaded) In that situation, both the subtree in
/augeas/files as well as the corresponding subtree in /files is deleted.
The code in store_error, which is called by load_file when a parse error
happens, would leave that subtree in /augeas/files dirty. This commit fixes
that by making sure we mark the error entries as clean. It also revamps
store_error to use the lighter-weight tree_xxx functions instead of the
aug_xxx functions.
Fixes bug #138
---
src/transform.c | 71 +++++++++++++++++++++++++++++++---------------------
tests/test-load.c | 28 +++++++++++++++++++++
2 files changed, 70 insertions(+), 29 deletions(-)
diff --git a/src/transform.c b/src/transform.c
index f449471..521414b 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -296,30 +296,29 @@ static char *err_path(const char *filename) {
}
ATTRIBUTE_FORMAT(printf, 4, 5)
-static int err_set(struct augeas *aug, char **ep, const char *sub,
- const char *format, ...) {
+static void err_set(struct augeas *aug,
+ struct tree *err_info, const char *sub,
+ const char *format, ...) {
int r;
va_list ap;
- size_t ep_len = strlen(*ep);
char *value = NULL;
-
- r = pathjoin(ep, 1, sub);
- if (r < 0)
- goto error;
+ struct tree *tree = NULL;
va_start(ap, format);
r = vasprintf(&value, format, ap);
va_end(ap);
- if (r < 0) {
+ if (r < 0)
value = NULL;
- goto error;
- }
+ ERR_NOMEM(r < 0, aug);
+
+ tree = tree_child_cr(err_info, sub);
+ ERR_NOMEM(tree == NULL, aug);
+
+ r = tree_set_value(tree, value);
+ ERR_NOMEM(r < 0, aug);
- r = aug_set(aug, *ep, value);
error:
free(value);
- (*ep)[ep_len] = '\0';
- return (r < 0) ? -1 : 0;
}
/* Record an error in the tree. The error will show up underneath
@@ -331,51 +330,65 @@ static int store_error(struct augeas *aug,
const char *filename, const char *path,
const char *status, int errnum,
const struct lns_error *err, const char *text) {
- char *ep = err_path(filename);
+ struct tree *err_info = NULL, *finfo = NULL;
+ char *fip = NULL;
int r;
int result = -1;
- if (ep == NULL)
- return -1;
+ r = pathjoin(&fip, 2, AUGEAS_META_FILES, filename);
+ ERR_NOMEM(r < 0, aug);
+
+ finfo = tree_find_cr(aug, fip);
+ ERR_BAIL(aug);
- aug_rm(aug, ep);
if (status != NULL) {
- r = aug_set(aug, ep, status);
- if (r < 0)
- goto done;
+ err_info = tree_child_cr(finfo, s_error);
+ ERR_NOMEM(err_info == NULL, aug);
+
+ r = tree_set_value(err_info, status);
+ ERR_NOMEM(r < 0, aug);
/* Errors from err_set are ignored on purpose. We try
* to report as much as we can */
if (err != NULL) {
if (err->pos >= 0) {
size_t line, ofs;
- err_set(aug, &ep, s_pos, "%d", err->pos);
+ err_set(aug, err_info, s_pos, "%d", err->pos);
if (text != NULL) {
calc_line_ofs(text, err->pos, &line, &ofs);
- err_set(aug, &ep, s_line, "%zd", line);
- err_set(aug, &ep, s_char, "%zd", ofs);
+ err_set(aug, err_info, s_line, "%zd", line);
+ err_set(aug, err_info, s_char, "%zd", ofs);
}
}
if (err->path != NULL) {
- err_set(aug, &ep, s_path, "%s%s", path, err->path);
+ err_set(aug, err_info, s_path, "%s%s", path, err->path);
}
if (err->lens != NULL) {
char *fi = format_info(err->lens->info);
if (fi != NULL) {
- err_set(aug, &ep, s_lens, "%s", fi);
+ err_set(aug, err_info, s_lens, "%s", fi);
free(fi);
}
}
- err_set(aug, &ep, s_message, "%s", err->message);
+ err_set(aug, err_info, s_message, "%s", err->message);
} else if (errnum != 0) {
const char *msg = strerror(errnum);
- err_set(aug, &ep, s_message, "%s", msg);
+ err_set(aug, err_info, s_message, "%s", msg);
+ }
+ } else {
+ /* No error, nuke the error node if it exists */
+ err_info = tree_child(finfo, s_error);
+ if (err_info != NULL) {
+ tree_unlink_children(aug, err_info);
+ pathx_symtab_remove_descendants(aug->symtab, err_info);
+ tree_unlink(err_info);
}
}
+ tree_clean(finfo);
result = 0;
- done:
- free(ep);
+ error:
+ free(fip);
return result;
}
diff --git a/tests/test-load.c b/tests/test-load.c
index f11b86f..6110ebc 100644
--- a/tests/test-load.c
+++ b/tests/test-load.c
@@ -457,6 +457,33 @@ static void testReloadExternalMod(CuTest *tc) {
CuAssertIntEquals(tc, 5, r);
}
+/* Make sure parse errors from applying a lens to a file that does not
+ * match get reported under /augeas//error
+ *
+ * Tests bug #138
+ */
+static void testParseErrorReported(CuTest *tc) {
+ augeas *aug = NULL;
+ int nmatches, r;
+
+ aug = aug_init(root, loadpath, AUG_NO_MODL_AUTOLOAD);
+ CuAssertPtrNotNull(tc, aug);
+
+ r = aug_set(aug, "/augeas/load/Bad/lens", "Yum.lns");
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_set(aug, "/augeas/load/Bad/incl", "/etc/fstab");
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_load(aug);
+ CuAssertRetSuccess(tc, r);
+
+ nmatches = aug_match(aug, "/augeas/files/etc/fstab/error", NULL);
+ CuAssertIntEquals(tc, 1, nmatches);
+
+ aug_close(aug);
+}
+
int main(void) {
char *output = NULL;
CuSuite* suite = CuSuiteNew();
@@ -474,6 +501,7 @@ int main(void) {
SUITE_ADD_TEST(suite, testReloadDeleted);
SUITE_ADD_TEST(suite, testReloadDeletedMeta);
SUITE_ADD_TEST(suite, testReloadExternalMod);
+ SUITE_ADD_TEST(suite, testParseErrorReported);
abs_top_srcdir = getenv("abs_top_srcdir");
if (abs_top_srcdir == NULL)
--
1.7.2.3
More information about the augeas-devel
mailing list