diff --git a/rpm-4.4.2.1-checksignals.patch b/rpm-4.4.2.1-checksignals.patch new file mode 100644 index 0000000..8991450 --- /dev/null +++ b/rpm-4.4.2.1-checksignals.patch @@ -0,0 +1,87 @@ +changeset: 6176:c0237c16e2e3 +user: Panu Matilainen +date: Fri Jul 20 10:41:15 2007 +0300 +files: python/rpmmodule.c +description: +Add python methods for checking pending signals from rpmsqCaught. +- a thin wrapper for rpmdbCheckSignals() from rpm5.org / Jeff Johnson +- a function taking a list of signals to check and returning list caught + signals (python doesn't know about signal sets so rpmsqCaught needs + wrapping) + + +diff -r d8e2ec20c948 -r c0237c16e2e3 python/rpmmodule.c +--- a/python/rpmmodule.c Wed Jul 18 16:05:56 2007 +0300 ++++ b/python/rpmmodule.c Fri Jul 20 10:41:15 2007 +0300 +@@ -7,6 +7,7 @@ + #include + #include /* XXX for rpmCheckSig */ + #include ++#include + + #include "legacy.h" + #include "misc.h" +@@ -58,6 +59,50 @@ static PyObject * archScore(PyObject * s + } + + /** ++ * */ ++static PyObject * signalsCaught(PyObject * self, PyObject * check) ++{ ++ PyObject *caught, *o; ++ Py_ssize_t llen; ++ int signum, i; ++ sigset_t newMask, oldMask; ++ ++ if (!PyList_Check(check)) { ++ PyErr_SetString(PyExc_TypeError, "list expected"); ++ return NULL; ++ } ++ ++ llen = PyList_Size(check); ++ caught = PyList_New(0); ++ ++ /* block signals while checking for them */ ++ (void) sigfillset(&newMask); ++ (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); ++ ++ for (i = 0; i < llen; i++) { ++ o = PyList_GetItem(check, i); ++ signum = PyInt_AsLong(o); ++ if (sigismember(&rpmsqCaught, signum)) { ++ PyList_Append(caught, o); ++ } ++ } ++ (void) sigprocmask(SIG_SETMASK, &oldMask, NULL); ++ ++ return caught; ++} ++ ++/** ++ * */ ++static PyObject * checkSignals(PyObject * self, PyObject * args) ++{ ++ if (!PyArg_ParseTuple(args, ":checkSignals")) return NULL; ++ rpmdbCheckSignals(); ++ Py_INCREF(Py_None); ++ return Py_None; ++} ++ ++ ++/** + */ + static PyObject * setLogFile (PyObject * self, PyObject * args, PyObject *kwds) + { +@@ -145,6 +190,11 @@ static PyMethodDef rpmModuleMethods[] = + + { "archscore", (PyCFunction) archScore, METH_VARARGS|METH_KEYWORDS, + NULL }, ++ ++ { "signalsCaught", (PyCFunction) signalsCaught, METH_O, ++ NULL }, ++ { "checkSignals", (PyCFunction) checkSignals, METH_VARARGS, ++ NULL }, + + { "headerLoad", (PyCFunction) hdrLoad, METH_VARARGS|METH_KEYWORDS, + NULL }, + diff --git a/rpm-4.4.2.1-checkterminate.patch b/rpm-4.4.2.1-checkterminate.patch new file mode 100644 index 0000000..0d456fb --- /dev/null +++ b/rpm-4.4.2.1-checkterminate.patch @@ -0,0 +1,87 @@ +changeset: 6177:6acd7701e4df +user: Panu Matilainen +date: Fri Jul 20 11:19:56 2007 +0300 +files: rpmdb/rpmdb.c rpmdb/rpmdb.h +description: +Support explicitly asking from rpmdb cleanup + termination. +New rpmdbCheckTerminate() function which checks for termination signals +and allows requesting termination via parameter as well. Make +rpmdbCheckSignals() just a wrapper that calls it with terminate=0. + + +diff -r c0237c16e2e3 -r 6acd7701e4df rpmdb/rpmdb.c +--- a/rpmdb/rpmdb.c Fri Jul 20 10:41:15 2007 +0300 ++++ b/rpmdb/rpmdb.c Fri Jul 20 11:19:56 2007 +0300 +@@ -700,14 +700,14 @@ static rpmdb rpmdbRock; + /*@unchecked@*/ /*@exposed@*/ /*@null@*/ + static rpmdbMatchIterator rpmmiRock; + +-int rpmdbCheckSignals(void) ++int rpmdbCheckTerminate(int terminate) + /*@globals rpmdbRock, rpmmiRock @*/ + /*@modifies rpmdbRock, rpmmiRock @*/ + { + sigset_t newMask, oldMask; +- static int terminate = 0; +- +- if (terminate) return 0; ++ static int terminating = 0; ++ ++ if (terminating) return 0; + + (void) sigfillset(&newMask); /* block all signals */ + (void) sigprocmask(SIG_BLOCK, &newMask, &oldMask); +@@ -716,10 +716,11 @@ int rpmdbCheckSignals(void) + || sigismember(&rpmsqCaught, SIGQUIT) + || sigismember(&rpmsqCaught, SIGHUP) + || sigismember(&rpmsqCaught, SIGTERM) +- || sigismember(&rpmsqCaught, SIGPIPE)) +- terminate = 1; +- +- if (terminate) { ++ || sigismember(&rpmsqCaught, SIGPIPE) ++ || terminate) ++ terminating = 1; ++ ++ if (terminating) { + rpmdb db; + rpmdbMatchIterator mi; + +@@ -745,6 +746,11 @@ int rpmdbCheckSignals(void) + exit(EXIT_FAILURE); + } + return sigprocmask(SIG_SETMASK, &oldMask, NULL); ++} ++ ++int rpmdbCheckSignals(void) ++{ ++ return rpmdbCheckTerminate(0); + } + + /** +diff -r c0237c16e2e3 -r 6acd7701e4df rpmdb/rpmdb.h +--- a/rpmdb/rpmdb.h Fri Jul 20 10:41:15 2007 +0300 ++++ b/rpmdb/rpmdb.h Fri Jul 20 11:19:56 2007 +0300 +@@ -1039,12 +1039,20 @@ Header rpmdbNextIterator(/*@null@*/ rpmd + /*@modifies mi, rpmGlobalMacroContext, fileSystem, internalState @*/; + + /** \ingroup rpmdb +- * Check rpmdb signal handler for trapped signal exit. ++ * Check rpmdb signal handler for trapped signal exit. Just a compatibility ++ * wrapper for rpmdbCheckTerminate() + */ + /*@mayexit@*/ + int rpmdbCheckSignals(void) + /*@globals fileSystem, internalState @*/ + /*@modifies fileSystem, internalState @*/; ++ ++/** \ingroup rpmdb ++ * Check rpmdb signal handler for trapped signal or requested exit. ++ * @param terminate 0 to only check for signals, 1 to terminate anyway ++ */ ++/*@mayexit@*/ ++int rpmdbCheckTerminate(int terminate); + + /** \ingroup rpmdb + * Destroy rpm database iterator. + diff --git a/rpm-4.4.2.1-python-exithook.patch b/rpm-4.4.2.1-python-exithook.patch new file mode 100644 index 0000000..9b24f80 --- /dev/null +++ b/rpm-4.4.2.1-python-exithook.patch @@ -0,0 +1,47 @@ +changeset: 6178:e9ced408b17f +tag: tip +user: Panu Matilainen +date: Fri Jul 20 11:23:11 2007 +0300 +files: python/rpmmodule.c +description: +Force rpmdb clean termination on exit from python. +Python process tracebacking with active iterators can and will otherwise leave +stale locks around (as is presumably the reason for rhbz#235389 and various +other locking issues) + + +diff -r 6acd7701e4df -r e9ced408b17f python/rpmmodule.c +--- a/python/rpmmodule.c Fri Jul 20 11:19:56 2007 +0300 ++++ b/python/rpmmodule.c Fri Jul 20 11:23:11 2007 +0300 +@@ -227,6 +227,16 @@ static PyMethodDef rpmModuleMethods[] = + { NULL } + } ; + ++/* ++* Force clean up of open iterators and dbs on exit. ++* This ends up calling exit() while we're already exiting but exit ++* handlers will only get called once so it wont loop. ++*/ ++static void rpm_exithook(void) ++{ ++ rpmdbCheckTerminate(1); ++} ++ + /** + */ + static char rpm__doc__[] = +@@ -263,6 +273,13 @@ void init_rpm(void) + + m = Py_InitModule3("_rpm", rpmModuleMethods, rpm__doc__); + if (m == NULL) ++ return; ++ ++ /* ++ * 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; + + rpmReadConfigFiles(NULL, NULL); + diff --git a/rpm.spec b/rpm.spec index a3cd4e4..890434b 100644 --- a/rpm.spec +++ b/rpm.spec @@ -14,7 +14,7 @@ Summary: The RPM package management system Name: rpm Version: 4.4.2.1 %{expand: %%define rpm_version %{version}-rc3} -Release: 0.4.rc3 +Release: 0.5.rc3 Group: System Environment/Base Url: http://www.rpm.org/ Source: rpm-%{rpm_version}.tar.gz @@ -24,12 +24,16 @@ Patch3: rpm-4.4.2-trust.patch Patch4: rpm-4.4.2-devel-autodep.patch Patch5: rpm-4.4.2-rpmfc-skip.patch Patch6: rpm-4.4.2-matchpathcon.patch +Patch7: rpm-4.4.2.1-checksignals.patch +Patch8: rpm-4.4.2.1-checkterminate.patch +Patch9: rpm-4.4.2.1-python-exithook.patch License: GPL Requires(pre): shadow-utils Requires(postun): shadow-utils Requires(post): coreutils Requires: popt = 1.10.2.1 Requires: crontabs +Requires: logrotate BuildRequires: autoconf BuildRequires: elfutils-devel >= 0.112 @@ -133,6 +137,9 @@ shell-like rules. %patch4 -p1 -b .develdeps %patch5 -p1 -b .fcskip %patch6 -p1 -b .matchpathcon +%patch7 -p1 -b .checksignals +%patch8 -p1 -b .checkterminate +%patch9 -p1 -b .py-exithook %build @@ -429,6 +436,11 @@ exit 0 %{__includedir}/popt.h %changelog +* Fri Jul 20 2007 Panu Matilainen 4.4.2.1-0.5.rc3 +- require logrotate (#248629) +- allow checking for pending signals from python (#181434) +- add hook to python for cleaning up on unclean exit (#245389) + * Mon Jul 09 2007 Panu Matilainen 4.4.2.1-0.4.rc3 - 4.4.2.1-rc3