From patchwork Wed Mar 2 17:13:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Schwab X-Patchwork-Id: 11168 Received: (qmail 104676 invoked by alias); 2 Mar 2016 17:13:54 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 104665 invoked by uid 89); 2 Mar 2016 17:13:53 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=first, shares, 17515, Hx-languages-length:2584 X-HELO: mx2.suse.de From: Andreas Schwab To: libc-alpha@sourceware.org Subject: [PATCH] Fix nscd assertion failure in gc (bug 19755) X-Yow: OKAY!! Turn on the sound ONLY for TRYNEL CARPETING, FULLY-EQUIPPED R.V.'S and FLOATATION SYSTEMS!! Date: Wed, 02 Mar 2016 18:13:48 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 If a GETxxBYyy request (for passwd or group) is running in parallel to an INVALIDATE request (for the same database) then in a particular order of events the garbage collector is not properly marking all used memory and fails an assertion: GETGRBYNAME (root) Haven't found "root" in group cache! add new entry "root" of type GETGRBYNAME for group to cache (first) handle_request: request received (Version = 2) from PID 7413 INVALIDATE (group) pruning group cache; time 9223372036854775807 considering GETGRBYNAME entry "root", timeout 1456763027 add new entry "0" of type GETGRBYGID for group to cache remove GETGRBYNAME entry "root" nscd: mem.c:403: gc: Assertion `next_data == &he_data[db->head->nentries]' failed. Here the first call to cache_add added the GETGRBYNAME entry, which is immediately marked for collection by prune_cache. Then the GETGRBYGID entry is added which shares the data packet with the first entry and therefore is marked as !first, while the marking look in prune_cache has already finished. When the garbage collector runs, it only considers references by entries marked as first, missing the reference by the secondary entry. [BZ #19755] * nscd/mem.c (gc): Consider all references to the same data packet. --- nscd/mem.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/nscd/mem.c b/nscd/mem.c index 1aafd37..49a3b60 100644 --- a/nscd/mem.c +++ b/nscd/mem.c @@ -175,14 +175,15 @@ gc (struct database_dyn *db) /* This is the hash entry itself. */ markrange (mark, run, sizeof (struct hashentry)); - /* Add the information for the data itself. We do this - only for the one special entry marked with FIRST. */ - if (he[cnt]->first) - { - struct datahead *dh - = (struct datahead *) (db->data + he[cnt]->packet); - markrange (mark, he[cnt]->packet, dh->allocsize); - } + /* Add the information for the data itself. We need to do this + for all entries that point to the same data packet, not only + the one marked as first. Otherwise if the entry marked as + first has already been collected while the secondary entry + was added we may miss the reference from the latter one. + This can happen when processing an INVALIDATE request. */ + struct datahead *dh + = (struct datahead *) (db->data + he[cnt]->packet); + markrange (mark, he[cnt]->packet, dh->allocsize); run = he[cnt]->next;