From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.6 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 3F1DE1F784 for ; Tue, 23 Jul 2024 21:28:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1721770118; bh=xdjjz8xLA6gz96Yi/At+nmVD2r2Rnpuw6E5rYrxBxLc=; h=From:To:Subject:Date:In-Reply-To:References:From; b=lPTRIt+cHoZpeBhEGeVIDzmEmj0Vn7WpsELADhq6txUjJ6mAhiPLDF1QDeRmS36dz hB+ypYOfzkfqeEbM3sK+s5ppgPSBW4cgAtL9DaZ80UlK3wXLxQ5NzDwj2zNg5PmLhT ihbvWkz2xVpWSLKdthTfdlyABcyiHN2mD7Qu+sv4= From: Eric Wong To: meta@public-inbox.org Subject: [PATCH 2/4] msgmap: mid_insert: reraise on unexpected errors Date: Tue, 23 Jul 2024 21:28:35 +0000 Message-ID: <20240723212837.3931413-3-e@80x24.org> In-Reply-To: <20240723212837.3931413-1-e@80x24.org> References: <20240723212837.3931413-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: SQLITE_CONSTRAINT is the only SQLite error we really expect under normal circumstances. This avoids infinite loops when writing to inboxes after hitting ENOSPC. Reported-by: Robin H. Johnson Link: https://public-inbox.org/git/robbat2-20240722T060013-765939809Z@orbis-terrarum.net/ --- lib/PublicInbox/Msgmap.pm | 6 +++++- t/msgmap.t | 18 +++++++++++++++++- t/v2writable.t | 18 +++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/lib/PublicInbox/Msgmap.pm b/lib/PublicInbox/Msgmap.pm index cb4bb295..c4bc766d 100644 --- a/lib/PublicInbox/Msgmap.pm +++ b/lib/PublicInbox/Msgmap.pm @@ -12,6 +12,7 @@ use strict; use v5.10.1; use DBI; use DBD::SQLite; +use DBD::SQLite::Constants qw(SQLITE_CONSTRAINT); use PublicInbox::Over; use Scalar::Util qw(blessed); @@ -113,7 +114,10 @@ sub mid_insert { my $sth = $self->{dbh}->prepare_cached(<<''); INSERT INTO msgmap (mid) VALUES (?) - return unless eval { $sth->execute($mid) }; + unless (eval { $sth->execute($mid) }) { + return if $self->{dbh}->err == SQLITE_CONSTRAINT; + die $@; + } my $num = $self->{dbh}->last_insert_id(undef, undef, 'msgmap', 'num'); $self->num_highwater($num) if defined($num); $num; diff --git a/t/msgmap.t b/t/msgmap.t index 124d3b10..031854e0 100644 --- a/t/msgmap.t +++ b/t/msgmap.t @@ -3,6 +3,9 @@ # License: AGPL-3.0+ use v5.12; use PublicInbox::TestCommon; +use autodie; +use Config; +use PublicInbox::Spawn qw(popen_rd); require_mods('DBD::SQLite'); use_ok 'PublicInbox::Msgmap'; my ($tmpdir, $for_destroy) = tmpdir(); @@ -70,4 +73,17 @@ is(eval { 'ok' }, 'ok', 'atfork_* work on tmp_clone'); -done_testing(); +SKIP: { + my $strace = strace_inject; + open my $fh, '>', my $trace = "$tmpdir/trace.out"; + my $rd = popen_rd([ $strace, '-p', $$, '-o', $trace, + '-e', 'inject=pwrite64:error=ENOSPC'], undef, { 2 => 1 }); + $rd->poll_in(10) or die 'strace not ready'; + is eval { $d->mid_insert('this-better-trigger-ENOSPC@error') }, + undef, 'insert fails w/ ENOSPC'; + like $@, qr/ disk is full/, 'set $@ for ENOSPC'; + kill 'TERM', $rd->attached_pid; + $rd->close; +} + +done_testing; diff --git a/t/v2writable.t b/t/v2writable.t index 1b7e9e7d..a062d1b3 100644 --- a/t/v2writable.t +++ b/t/v2writable.t @@ -6,6 +6,8 @@ use Test::More; use PublicInbox::Eml; use PublicInbox::ContentHash qw(content_digest content_hash); use PublicInbox::TestCommon; +use PublicInbox::Spawn qw(popen_rd); +use Config; use Cwd qw(abs_path); require_git(2.6); require_mods(qw(DBD::SQLite Xapian)); @@ -335,4 +337,18 @@ ok($@, 'V2Writable fails on non-existent dir'); is($mode, 0664, sprintf('0%03o', $mode).' is 0664'); } -done_testing(); +SKIP: { + my $strace = strace_inject; + my $eml = eml_load 't/plack-qp.eml'; + open my $fh, '>', my $trace = "$inboxdir/trace.out"; + my $rd = popen_rd([ $strace, '-p', $$, '-o', $trace, + '-e', 'inject=pwrite64:error=ENOSPC'], undef, { 2 => 1 }); + $rd->poll_in(10) or die 'strace not ready'; + ok ! eval { $im->add($eml) }, 'v2w->add fails on ENOSPC'; + like $@, qr/ disk is full/, 'set $@ for ENOSPC'; + $im->done; + kill 'TERM', $rd->attached_pid; + $rd->close; +} + +done_testing;