summaryrefslogtreecommitdiff
path: root/rpmio
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2009-04-23 15:54:09 +0300
committerPanu Matilainen <pmatilai@redhat.com>2009-04-23 15:54:09 +0300
commit2ce7b56e621b097b76a2e5059def7d0e5a64d53b (patch)
tree3169750264194baaec554fab32f9725ce3939ba5 /rpmio
parent4b523ac1b85b9d4f71cd024306f01c3fb2418c8f (diff)
downloadrpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.tar.gz
rpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.tar.bz2
rpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.zip
Hide NSS peculiarities from API
- PKCS#11 standard requires modules to be re-initialized after fork(), arrange this to occur automatically. - Most of the time child processes will exec() something else so dont bother shutting down NSS for every child, only lazily re-initialize as needed. - This lets us initialize NSS early to force preloading of its dlopen()'ed libraries to avoid issues on chroot(), without causing problems to API users which fork() after initializing rpm (such as func, urpmi etc).
Diffstat (limited to 'rpmio')
-rw-r--r--rpmio/rpmpgp.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 3498e5665..38194497b 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -5,7 +5,10 @@
#include "system.h"
+#include <pthread.h>
+
#include <rpm/rpmstring.h>
+#include <rpm/rpmlog.h>
#include "rpmio/digest.h"
#include "rpmio/rpmio_internal.h" /* XXX rpmioSlurp */
@@ -18,6 +21,7 @@ static int _debug = 0;
static int _print = 0;
static int _crypto_initialized = 0;
+static int _new_process = 1;
static struct pgpValTbl_s const pgpSigTypeTbl[] = {
{ PGPSIGTYPE_BINARY, "Binary document signature" },
@@ -1570,9 +1574,24 @@ char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
return val;
}
+/*
+ * Only flag for re-initialization here, in the common case the child
+ * exec()'s something else shutting down NSS here would be waste of time.
+ */
+static void at_forkchild(void)
+{
+ _new_process = 1;
+}
+
int rpmInitCrypto(void) {
int rc = 0;
+ /* Lazy NSS shutdown for re-initialization after fork() */
+ if (_new_process && _crypto_initialized) {
+ rpmFreeCrypto();
+ }
+
+ /* Initialize NSS if not already done */
if (!_crypto_initialized) {
if (NSS_NoDB_Init(NULL) != SECSuccess) {
rc = -1;
@@ -1580,6 +1599,14 @@ int rpmInitCrypto(void) {
_crypto_initialized = 1;
}
}
+
+ /* Register one post-fork handler per process */
+ if (_new_process) {
+ if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
+ rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
+ }
+ _new_process = 0;
+ }
return rc;
}