summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2016-12-13 11:19:03 +0200
committerPanu Matilainen <pmatilai@redhat.com>2016-12-13 11:19:03 +0200
commit8cc3342cff0ef5721cda720809066a9ee4cb17eb (patch)
tree2c88d03e408b64c3ca1b7f16c94c49ebc18e4bbf
parent9b9e998c9afe33a5e2552ec03d33e13a22215394 (diff)
downloadrpm-8cc3342cff0ef5721cda720809066a9ee4cb17eb.tar.gz
Clean up rpmdb leftovers from an atexit() handler.
There's a standard C mechanism for cleaning up cruft at exit and it's known as atexit handler. atexit() handlers do not get called when exiting due to signal, but we're trapping the signals and calling exit() voluntarily in that case so... for fsck's sake Sherlock. This removes rpmdbCheckTerminate() from the API, the semantics change incompatibly here and it makes even less sense after this. It's a good time for this change since we're removing all sorts of other goo out from the API as well. Also rip out the previous workarounds from python side, RIP.
-rw-r--r--lib/misc.h2
-rw-r--r--lib/rpmdb.c44
-rw-r--r--lib/rpmdb.h10
-rw-r--r--lib/rpmrc.c9
-rw-r--r--python/rpmmodule.c15
-rw-r--r--python/rpmts-py.c1
6 files changed, 34 insertions, 47 deletions
diff --git a/lib/misc.h b/lib/misc.h
index fcd258438..74e94a2e7 100644
--- a/lib/misc.h
+++ b/lib/misc.h
@@ -62,6 +62,8 @@ RPM_GNUC_INTERNAL
void rpmRelocationBuild(Header h, rpmRelocation *rawrelocs,
int *rnrelocs, rpmRelocation **rrelocs, uint8_t **rbadrelocs);
+RPM_GNUC_INTERNAL
+void rpmAtExit(void);
#ifdef __cplusplus
}
#endif
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index c6718ab43..545e0517c 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -33,6 +33,7 @@
#include "lib/fprint.h"
#include "lib/header_internal.h" /* XXX for headerSetInstance() */
#include "lib/backend/dbiset.h"
+#include "lib/misc.h"
#include "debug.h"
#undef HASHTYPE
@@ -310,12 +311,26 @@ static rpmdb rpmdbRock;
static rpmdbMatchIterator rpmmiRock;
static rpmdbIndexIterator rpmiiRock;
-int rpmdbCheckTerminate(int terminate)
+void rpmAtExit(void)
{
- sigset_t newMask, oldMask;
- static int terminating = 0;
+ rpmdb db;
+ rpmdbMatchIterator mi;
+ rpmdbIndexIterator ii;
- if (terminating) return 0;
+ while ((mi = rpmmiRock) != NULL)
+ rpmdbFreeIterator(mi);
+
+ while ((ii = rpmiiRock) != NULL)
+ rpmdbIndexIteratorFree(ii);
+
+ while ((db = rpmdbRock) != NULL)
+ (void) rpmdbClose(db);
+}
+
+static int rpmdbCheckTerminate(void)
+{
+ sigset_t newMask, oldMask;
+ int terminating = 0;
(void) sigfillset(&newMask); /* block all signals */
(void) sigprocmask(SIG_BLOCK, &newMask, &oldMask);
@@ -324,31 +339,18 @@ int rpmdbCheckTerminate(int terminate)
|| rpmsqIsCaught(SIGQUIT) > 0
|| rpmsqIsCaught(SIGHUP) > 0
|| rpmsqIsCaught(SIGTERM) > 0
- || rpmsqIsCaught(SIGPIPE) > 0
- || terminate)
+ || rpmsqIsCaught(SIGPIPE) > 0)
terminating = 1;
- if (terminating) {
- rpmdb db;
- rpmdbMatchIterator mi;
- rpmdbIndexIterator ii;
-
- while ((mi = rpmmiRock) != NULL)
- rpmdbFreeIterator(mi);
-
- while ((ii = rpmiiRock) != NULL)
- rpmdbIndexIteratorFree(ii);
-
- while ((db = rpmdbRock) != NULL)
- (void) rpmdbClose(db);
- }
sigprocmask(SIG_SETMASK, &oldMask, NULL);
return terminating;
}
int rpmdbCheckSignals(void)
{
- if (rpmdbCheckTerminate(0)) {
+ static int terminating = 0;
+ if (!terminating && rpmdbCheckTerminate()) {
+ terminating = 1;
rpmlog(RPMLOG_DEBUG, "Exiting on signal...\n");
exit(EXIT_FAILURE);
}
diff --git a/lib/rpmdb.h b/lib/rpmdb.h
index 122cbd040..3a782738b 100644
--- a/lib/rpmdb.h
+++ b/lib/rpmdb.h
@@ -151,16 +151,6 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi);
int rpmdbCheckSignals(void);
/** \ingroup rpmdb
- * Check rpmdb signal handler for trapped signal and/or requested exit,
- * clean up any open iterators and databases on termination condition.
- * On non-zero exit any open references to rpmdb are invalid and cannot
- * be accessed anymore, calling process should terminate immediately.
- * @param terminate 0 to only check for signals, 1 to terminate anyway
- * @return 0 to continue, 1 if termination cleanup was done.
- */
-int rpmdbCheckTerminate(int terminate);
-
-/** \ingroup rpmdb
* Destroy rpm database iterator.
* @param mi rpm database iterator
* @return NULL always
diff --git a/lib/rpmrc.c b/lib/rpmrc.c
index 7d67e6c46..4ed991321 100644
--- a/lib/rpmrc.c
+++ b/lib/rpmrc.c
@@ -1602,13 +1602,22 @@ exit:
return rc;
}
+static void register_atexit(void)
+{
+ if (atexit(rpmAtExit) != 0)
+ rpmlog(RPMLOG_WARNING, _("failed to register exit handler"));
+}
+
/* External interfaces */
int rpmReadConfigFiles(const char * file, const char * target)
{
+ static pthread_once_t atexit_registered = PTHREAD_ONCE_INIT;
int rc = -1; /* assume failure */
rpmrcCtx ctx = rpmrcCtxAcquire(1);
+ pthread_once(&atexit_registered, register_atexit);
+
/* Force preloading of dlopen()'ed libraries in case we go chrooting */
if (rpmugInit())
goto exit;
diff --git a/python/rpmmodule.c b/python/rpmmodule.c
index a708563bd..6f4a6f3ed 100644
--- a/python/rpmmodule.c
+++ b/python/rpmmodule.c
@@ -208,14 +208,6 @@ static PyMethodDef rpmModuleMethods[] = {
{ NULL }
} ;
-/*
-* Force clean up of open iterators and dbs on exit.
-*/
-static void rpm_exithook(void)
-{
- rpmdbCheckTerminate(1);
-}
-
static char rpm__doc__[] = "";
/*
@@ -327,13 +319,6 @@ static int initModule(PyObject *m)
{
PyObject * d;
- /*
- * treat error to register rpm cleanup hook as fatal, tracebacks
- * can and will leave stale locks around if we can't clean up
- */
- if (Py_AtExit(rpm_exithook) == -1)
- return 0;
-
/* failure to initialize rpm (crypto and all) is rather fatal too... */
if (rpmReadConfigFiles(NULL, NULL) == -1)
return 0;
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
index f05371c5e..d56a09c22 100644
--- a/python/rpmts-py.c
+++ b/python/rpmts-py.c
@@ -167,7 +167,6 @@ static void die(PyObject *cb)
}
fprintf(stderr, "FATAL ERROR: python callback %s failed, aborting!\n",
pyfn ? pyfn : "???");
- rpmdbCheckTerminate(1);
exit(EXIT_FAILURE);
}