diff --git a/.createrepo_c.metadata b/.createrepo_c.metadata index 231fc19..736e1d7 100644 --- a/.createrepo_c.metadata +++ b/.createrepo_c.metadata @@ -1 +1 @@ -49ce7de5c5d17fafba7dcc171837236f5ef189b6 SOURCES/createrepo_c-0.15.11.tar.gz +39e70f306cff3675e581b204a2754212280342e1 SOURCES/createrepo_c-0.16.2.tar.gz diff --git a/.gitignore b/.gitignore index dfffbcc..87831e1 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/createrepo_c-0.15.11.tar.gz +SOURCES/createrepo_c-0.16.2.tar.gz diff --git a/SOURCES/0001-Never-leave-behind-repodata-lock-on-exit-RhBug-1906831.patch b/SOURCES/0001-Never-leave-behind-repodata-lock-on-exit-RhBug-1906831.patch new file mode 100644 index 0000000..f078b74 --- /dev/null +++ b/SOURCES/0001-Never-leave-behind-repodata-lock-on-exit-RhBug-1906831.patch @@ -0,0 +1,106 @@ +From e21b038a231e2743e30915af9575b8c43e9fda1f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= +Date: Tue, 15 Dec 2020 14:15:39 +0100 +Subject: [PATCH] Never leave behind .repodata lock on exit (RhBug:1906831 + +createrepo_c was removing `.repodata` if `exit_val` was se to failure. +Problem is `exit_val` is set only on a couple of places so most of the +failures (no matter how rare) leave `.repodata` behind. + +However because on a successful run `.repodata` is renamed to normal +output `repodata` we know that if `.repodata` are present there was an +error and we can delete them. +--- + src/createrepo_c.c | 5 +---- + src/createrepo_shared.c | 29 +++++++++-------------------- + 2 files changed, 10 insertions(+), 24 deletions(-) + +diff --git a/src/createrepo_c.c b/src/createrepo_c.c +index 8c90ebd..eeb871c 100644 +--- a/src/createrepo_c.c ++++ b/src/createrepo_c.c +@@ -665,9 +665,6 @@ main(int argc, char **argv) + exit(EXIT_FAILURE); + } + +- // Set exit_value pointer used in cleanup handlers +- cr_set_global_exit_value(&exit_val); +- + // Setup cleanup handlers + if (!cr_set_cleanup_handler(lock_dir, tmp_out_repo, &tmp_err)) { + g_printerr("%s\n", tmp_err->message); +@@ -885,7 +882,7 @@ main(int argc, char **argv) + char *moduleindex_str = modulemd_module_index_dump_to_string (moduleindex, &tmp_err); + g_clear_pointer(&moduleindex, g_object_unref); + if (tmp_err) { +- g_critical("%s: Cannot cannot dump module index: %s", __func__, tmp_err->message); ++ g_critical("%s: Cannot dump module index: %s", __func__, tmp_err->message); + free(moduleindex_str); + g_clear_error(&tmp_err); + exit(EXIT_FAILURE); +diff --git a/src/createrepo_shared.c b/src/createrepo_shared.c +index f8ef998..d1a37bd 100644 +--- a/src/createrepo_shared.c ++++ b/src/createrepo_shared.c +@@ -28,8 +28,6 @@ + #include "misc.h" + #include "cleanup.h" + +-int *global_exit_status = NULL; // pointer to exit_value used in failure_exit_cleanup +- + char *global_lock_dir = NULL; // Path to .repodata/ dir that is used as a lock + char *global_tmp_out_repo = NULL; // Path to temporary repodata directory, + // if NULL that it's same as +@@ -43,18 +41,16 @@ char *global_tmp_out_repo = NULL; // Path to temporary repodata directory, + * + */ + static void +-failure_exit_cleanup() ++exit_cleanup() + { +- if (global_exit_status && *global_exit_status != EXIT_SUCCESS) { +- if (global_lock_dir) { +- g_debug("Removing %s", global_lock_dir); +- cr_remove_dir(global_lock_dir, NULL); +- } ++ if (global_lock_dir) { ++ g_debug("Removing %s", global_lock_dir); ++ cr_remove_dir(global_lock_dir, NULL); ++ } + +- if (global_tmp_out_repo) { +- g_debug("Removing %s", global_tmp_out_repo); +- cr_remove_dir(global_tmp_out_repo, NULL); +- } ++ if (global_tmp_out_repo) { ++ g_debug("Removing %s", global_tmp_out_repo); ++ cr_remove_dir(global_tmp_out_repo, NULL); + } + } + +@@ -65,16 +61,9 @@ static void + sigint_catcher(int sig) + { + g_message("%s caught: Terminating...", strsignal(sig)); +- *global_exit_status = 1; + exit(1); + } + +-void +-cr_set_global_exit_value(int *exit_val) +-{ +- global_exit_status = exit_val; +-} +- + gboolean + cr_set_cleanup_handler(const char *lock_dir, + const char *tmp_out_repo, +@@ -90,7 +79,7 @@ cr_set_cleanup_handler(const char *lock_dir, + global_tmp_out_repo = NULL; + + // Register on exit cleanup function +- if (atexit(failure_exit_cleanup)) ++ if (atexit(exit_cleanup)) + g_warning("Cannot set exit cleanup function by atexit()"); + + // Prepare signal handler configuration diff --git a/SOURCES/0001-Parse-xml-snippet-in-smaller-parts-RhBug1859689.patch b/SOURCES/0001-Parse-xml-snippet-in-smaller-parts-RhBug1859689.patch deleted file mode 100644 index eb8c627..0000000 --- a/SOURCES/0001-Parse-xml-snippet-in-smaller-parts-RhBug1859689.patch +++ /dev/null @@ -1,144 +0,0 @@ -From 76b4a34e04f09596c92fa0326001f18891695e17 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= -Date: Fri, 24 Jul 2020 12:53:47 +0200 -Subject: [PATCH 1/2] Add a test for parsing huge snippet (RhBug:1859689) - -https://bugzilla.redhat.com/show_bug.cgi?id=1859689 ---- - tests/python/tests/test_xml_parser.py | 36 +++++++++++++++++++++++++++ - 1 file changed, 36 insertions(+) - -diff --git a/tests/python/tests/test_xml_parser.py b/tests/python/tests/test_xml_parser.py -index e2c48f0..8856096 100644 ---- a/tests/python/tests/test_xml_parser.py -+++ b/tests/python/tests/test_xml_parser.py -@@ -476,6 +476,42 @@ class TestCaseXmlParserFilelists(unittest.TestCase): - self.assertEqual(userdata["pkgcb_calls"], 2) - self.assertEqual(userdata["warnings"], []) - -+ def test_xml_parser_filelists_snippet_huge(self): -+ -+ userdata = { -+ "pkgs": [], -+ "pkgcb_calls": 0, -+ "warnings": [] -+ } -+ -+ def newpkgcb(pkgId, name, arch): -+ pkg = cr.Package() -+ userdata["pkgs"].append(pkg) -+ return pkg -+ -+ def pkgcb(pkg): -+ userdata["pkgcb_calls"] += 1 -+ -+ def warningcb(warn_type, msg): -+ userdata["warnings"].append((warn_type, msg)) -+ -+ # generete huge filelists snippet -+ content = """ -+ -+ -+ """ -+ for i in range(145951): -+ content += "/usr/share/icons/Flat-Remix-Yellow/status/symbolic/user-available-symbolic.svg" -+ content += "" -+ -+ cr.xml_parse_filelists_snippet(content, newpkgcb, pkgcb, warningcb) -+ -+ self.assertEqual([pkg.name for pkg in userdata["pkgs"]], -+ ['flat-remix-icon-theme']) -+ self.assertEqual(userdata["pkgcb_calls"], 1) -+ self.assertEqual(userdata["warnings"], []) -+ -+ - - def test_xml_parser_filelists_repo02_only_pkgcb(self): - --- -2.28.0.rc1 - - -From 6f08a56c36e6c60d216fff964b31a2c58ce12fc7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ale=C5=A1=20Mat=C4=9Bj?= -Date: Fri, 24 Jul 2020 12:41:50 +0200 -Subject: [PATCH 2/2] Parse xml snippet in smaller parts (RhBug:1859689) - -If string passed to xmlParseChunk (function froml ibxml2) is too -big the function errors out, its safer to parse the snippet in -smaller parts. - -https://bugzilla.redhat.com/show_bug.cgi?id=1859689 ---- - src/xml_parser.c | 48 ++++++++++++++++++++++++++++++++---------------- - 1 file changed, 32 insertions(+), 16 deletions(-) - -diff --git a/src/xml_parser.c b/src/xml_parser.c -index 4727daa..9375107 100644 ---- a/src/xml_parser.c -+++ b/src/xml_parser.c -@@ -243,29 +243,45 @@ cr_xml_parser_generic_from_string(xmlParserCtxtPtr parser, - /* Note: This function uses .err members of cr_ParserData! */ - - int ret = CRE_OK; -+ int block_size = XML_BUFFER_SIZE; -+ const char *next_data = xml_string; -+ const char *end_of_string = xml_string + strlen(xml_string); -+ int finished = 0; - - assert(parser); - assert(pd); - assert(xml_string); - assert(!err || *err == NULL); - -- if (xmlParseChunk(parser, xml_string, strlen(xml_string), 1)) { -- ret = CRE_XMLPARSER; -- xmlErrorPtr xml_err = xmlCtxtGetLastError(parser); -- g_critical("%s: parsing error '%s': %s", -- __func__, -- xml_string, -- xml_err->message); -- g_set_error(err, ERR_DOMAIN, CRE_XMLPARSER, -- "Parse error '%s' at line: %d (%s)", -- xml_string, -- (int) xml_err->line, -- (char *) xml_err->message); -- } -+ const char *data; -+ while (!finished) { -+ data = next_data; -+ -+ // Check if we are in the last loop -+ next_data = data + block_size; -+ if (next_data > end_of_string) { -+ block_size = strlen(data); -+ finished = 1; -+ } -+ -+ if (xmlParseChunk(parser, data, block_size, finished)) { -+ ret = CRE_XMLPARSER; -+ xmlErrorPtr xml_err = xmlCtxtGetLastError(parser); -+ g_critical("%s: parsing error '%s': %s", -+ __func__, -+ data, -+ xml_err->message); -+ g_set_error(err, ERR_DOMAIN, CRE_XMLPARSER, -+ "Parse error '%s' at line: %d (%s)", -+ data, -+ (int) xml_err->line, -+ (char *) xml_err->message); -+ } - -- if (pd->err) { -- ret = pd->err->code; -- g_propagate_error(err, pd->err); -+ if (pd->err) { -+ ret = pd->err->code; -+ g_propagate_error(err, pd->err); -+ } - } - - return ret; --- -2.28.0.rc1 - diff --git a/SPECS/createrepo_c.spec b/SPECS/createrepo_c.spec index 0b70539..4819f89 100644 --- a/SPECS/createrepo_c.spec +++ b/SPECS/createrepo_c.spec @@ -36,12 +36,12 @@ Summary: Creates a common metadata repository Name: createrepo_c -Version: 0.15.11 +Version: 0.16.2 Release: 2%{?dist} License: GPLv2+ URL: https://github.com/rpm-software-management/createrepo_c Source0: %{url}/archive/%{version}/%{name}-%{version}.tar.gz -Patch1: 0001-Parse-xml-snippet-in-smaller-parts-RhBug1859689.patch +Patch0: 0001-Never-leave-behind-repodata-lock-on-exit-RhBug-1906831.patch BuildRequires: cmake BuildRequires: gcc @@ -262,6 +262,14 @@ ln -sr %{buildroot}%{_bindir}/modifyrepo_c %{buildroot}%{_bindir}/modifyrepo %endif %changelog +* Fri Jan 29 2021 Nicola Sella - 0.16.2-2 +- Never leave behind .repodata lock on exit (RhBug:1906831) + +* Mon Nov 09 2020 Nicola Sella - 0.16.2-1 +- Update to 0.16.2 +- Add module metadata support to createrepo_c (RhBug:1795936) +- Fix various memory leaks + * Thu Jul 30 2020 Ales Matej - 0.15.11-2 - Parse xml snippet in smaller parts (RhBug:1859689)