From 93db05ea3cb892be0d19c65fdf7dc9be6759a651 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Tue, 31 May 2016 21:38:37 +1000 Subject: [PATCH 117/119] Limit key retrieval to a single thread per CA Before implementing lightweight CA key retrieval retry with exponential backoff, ensure that only one key retriever thread can execute at a time, for each CA. Also make SigningUnit initialisation (initSigUnit) synchronised. Part of: https://fedorahosted.org/pki/ticket/2293 --- .../src/com/netscape/ca/CertificateAuthority.java | 28 +++++++++++++++++----- 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java index 5b2f382c29a716f3e72695b7da5406bb85b34845..c2a7d0c907b4dd5774b22cfbb404194da162a535 100644 --- a/base/ca/src/com/netscape/ca/CertificateAuthority.java +++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java @@ -204,6 +204,8 @@ public class CertificateAuthority private static final Map caMap = Collections.synchronizedSortedMap(new TreeMap()); + private static final Map keyRetrieverThreads = + Collections.synchronizedSortedMap(new TreeMap()); protected CertificateAuthority hostCA = null; protected AuthorityID authorityID = null; protected AuthorityID authorityParentID = null; @@ -1460,7 +1462,7 @@ public class CertificateAuthority /** * init CA signing unit & cert chain. */ - private boolean initSigUnit(boolean retrieveKeys) + private synchronized boolean initSigUnit(boolean retrieveKeys) throws EBaseException { try { // init signing unit @@ -1491,11 +1493,16 @@ public class CertificateAuthority CMS.debug("CA signing key and cert not (yet) present in NSSDB"); signingUnitException = e; if (retrieveKeys == true) { - CMS.debug("Starting KeyRetrieverRunner thread"); - new Thread( - new KeyRetrieverRunner(this), - "KeyRetrieverRunner-" + authorityID - ).start(); + if (!keyRetrieverThreads.containsKey(authorityID)) { + CMS.debug("Starting KeyRetrieverRunner thread"); + Thread t = new Thread( + new KeyRetrieverRunner(this), + "KeyRetrieverRunner-" + authorityID); + t.start(); + keyRetrieverThreads.put(authorityID, t); + } else { + CMS.debug("KeyRetriever thread already running for authority " + authorityID); + } } return false; } @@ -3180,6 +3187,15 @@ public class CertificateAuthority } public void run() { + try { + _run(); + } finally { + // remove self from tracker + keyRetrieverThreads.remove(ca.authorityID); + } + } + + private void _run() { String KR_CLASS_KEY = "features.authority.keyRetrieverClass"; String className = null; try { -- 2.5.5