From patchwork Mon Aug 28 07:22:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 74810 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 55A313858C2F for ; Mon, 28 Aug 2023 07:23:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 55A313858C2F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1693207395; bh=5xnDCHNhSctgoIxbZnQoDa0MbHbd+11Qw5rrFrrUKFE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=mmDaAgtgHH7R0v76aBiT8GZ30eC10ZWKCS84BFUeyNi1mSX2yoR8/58GupUYzDgHd QfARvBJMzAo/a2+yFjqbkj/9nVPWk7fm8Udo3UmD9yLHK19jux6nLQj0ke5lI1KlUv L5DWU0kzl391pRMO4r/lCqftG4IsqNX4LSQIYSpQ= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTPS id 197143858D28 for ; Mon, 28 Aug 2023 07:22:53 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 197143858D28 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-31-DkotYUSJN4a7eKdM5LsldA-1; Mon, 28 Aug 2023 03:22:51 -0400 X-MC-Unique: DkotYUSJN4a7eKdM5LsldA-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CDD17185A793 for ; Mon, 28 Aug 2023 07:22:50 +0000 (UTC) Received: from oldenburg.str.redhat.com (unknown [10.2.16.25]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 773B82166B25 for ; Mon, 28 Aug 2023 07:22:50 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH] nscd: Skip unusable entries in first pass in prune_cache (bug 30800) Date: Mon, 28 Aug 2023 09:22:49 +0200 Message-ID: <87o7iry6k6.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-10.6 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" Previously, if an entry was marked unusable for any reason, but had not timed out yet, the assert would trigger. One way to get into such state is if a data change is detected during re-validation of an entry. This causes the entry to be marked as not usable. If exits nscd soon after that, then the clock jumps backwards, and nscd restarted, the cache re-validation run after startup triggers the removed assert. The change is more complicated than just the removal of the assert because entries marked as not usable should be garbage-collected in the second pass. To make this happen, it is necessary to update some book-keeping data. Tested on x86_64-linux-gnu with a problematic /var/db/nscd/passwd file that triggered the assert before. The assert is gone, and unusable entries are pruned as expected. Reviewed-by: DJ Delorie --- nscd/cache.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) base-commit: 87ced255bdf2681f5bf6c89d7121e59f6f342161 diff --git a/nscd/cache.c b/nscd/cache.c index b4b54d82bb..336ff548cb 100644 --- a/nscd/cache.c +++ b/nscd/cache.c @@ -370,8 +370,11 @@ prune_cache (struct database_dyn *table, time_t now, int fd) serv2str[runp->type], str, dh->timeout); } - /* Check whether the entry timed out. */ - if (dh->timeout < now) + /* Check whether the entry timed out. Timed out entries + will be revalidated. For unusable records, it is still + necessary to record that the bucket needs to be scanned + again below. */ + if (dh->timeout < now || !dh->usable) { /* This hash bucket could contain entries which need to be looked at. */ @@ -383,7 +386,7 @@ prune_cache (struct database_dyn *table, time_t now, int fd) /* We only have to look at the data of the first entries since the count information is kept in the data part which is shared. */ - if (runp->first) + if (runp->first && dh->usable) { /* At this point there are two choices: we reload the @@ -399,9 +402,6 @@ prune_cache (struct database_dyn *table, time_t now, int fd) { /* Remove the value. */ dh->usable = false; - - /* We definitely have some garbage entries now. */ - any = true; } else { @@ -413,18 +413,15 @@ prune_cache (struct database_dyn *table, time_t now, int fd) time_t timeout = readdfcts[runp->type] (table, runp, dh); next_timeout = MIN (next_timeout, timeout); - - /* If the entry has been replaced, we might need - cleanup. */ - any |= !dh->usable; } } + + /* If the entry has been replaced, we might need cleanup. */ + any |= !dh->usable; } else - { - assert (dh->usable); - next_timeout = MIN (next_timeout, dh->timeout); - } + /* Entry has not timed out and is usable. */ + next_timeout = MIN (next_timeout, dh->timeout); run = runp->next; }