]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Xapcmd.pm
xapcmd: remove redundant searchidx require
[public-inbox.git] / lib / PublicInbox / Xapcmd.pm
index 8e2b9063c7443e3f0b8916560e22f054789dc71b..47a018d2b6e538ecc16f1338d43c1343ef6388a1 100644 (file)
@@ -5,7 +5,7 @@ use strict;
 use warnings;
 use PublicInbox::Spawn qw(which popen_rd);
 use PublicInbox::Over;
-use PublicInbox::SearchIdx;
+use PublicInbox::SearchIdx qw(nodatacow_dir);
 use File::Temp 0.19 (); # ->newdir
 use File::Path qw(remove_tree);
 use File::Basename qw(dirname);
@@ -23,6 +23,7 @@ sub commit_changes ($$$$) {
 
        $SIG{INT} or die 'BUG: $SIG{INT} not handled';
        my @old_shard;
+       my $over_chg;
 
        while (my ($old, $newdir) = each %$tmp) {
                next if $old eq ''; # no invalid paths
@@ -39,6 +40,7 @@ sub commit_changes ($$$$) {
                        my $tmp_over = "$new/over.sqlite3";
                        $over->connect->sqlite_backup_to_file($tmp_over);
                        $over = undef;
+                       $over_chg = 1;
                }
 
                if (!defined($new)) { # culled shard
@@ -59,6 +61,10 @@ sub commit_changes ($$$$) {
                                die "failed to remove $prev: $!\n";
                }
        }
+
+       # trigger ->check_inodes in read-only daemons
+       syswrite($im->{lockfh}, '.') if $over_chg;
+
        remove_tree(@old_shard);
        $tmp = undef;
        if (!$opt->{-coarse_lock}) {
@@ -123,7 +129,7 @@ sub same_fs_or_die ($$) {
 
 sub process_queue {
        my ($queue, $cb, $opt) = @_;
-       my $max = $opt->{jobs} || scalar(@$queue);
+       my $max = $opt->{jobs} // scalar(@$queue);
        if ($max <= 1) {
                while (defined(my $args = shift @$queue)) {
                        $cb->($args, $opt);
@@ -142,7 +148,11 @@ sub process_queue {
                while (scalar keys %pids) {
                        my $pid = waitpid(-1, 0);
                        my $args = delete $pids{$pid};
-                       die join(' ', @$args)." failed: $?\n" if $?;
+                       if ($args) {
+                               die join(' ', @$args)." failed: $?\n" if $?;
+                       } else {
+                               warn "unknown PID($pid) reaped: $?\n";
+                       }
                }
        }
 }
@@ -157,9 +167,11 @@ sub prepare_run {
        my ($ibx, $opt) = @_;
        my $tmp = {}; # old shard dir => File::Temp->newdir object or undef
        my @queue; # ([old//src,newdir]) - list of args for cpdb() or compact()
-
-       my $old = $ibx->search->xdir(1);
-       -d $old or die "$old does not exist\n";
+       my $old;
+       if (my $srch = $ibx->search) {
+               $old = $srch->xdir(1);
+               -d $old or die "$old does not exist\n";
+       }
        my $reshard = $opt->{reshard};
        if (defined $reshard && $reshard <= 0) {
                die "--reshard must be a positive number\n";
@@ -167,7 +179,7 @@ sub prepare_run {
 
        # we want temporary directories to be as deep as possible,
        # so v2 shards can keep "xap$SCHEMA_VERSION" on a separate FS.
-       if ($ibx->version == 1) {
+       if ($old && $ibx->version == 1) {
                if (defined $reshard) {
                        warn
 "--reshard=$reshard ignored for v1 $ibx->{inboxdir}\n";
@@ -177,8 +189,9 @@ sub prepare_run {
                my $v = PublicInbox::Search::SCHEMA_VERSION();
                my $wip = File::Temp->newdir("xapian$v-XXXXXXXX", DIR => $dir);
                $tmp->{$old} = $wip;
+               nodatacow_dir($wip->dirname);
                push @queue, [ $old, $wip ];
-       } else {
+       } elsif ($old) {
                opendir my $dh, $old or die "Failed to opendir $old: $!\n";
                my @old_shards;
                while (defined(my $dn = readdir($dh))) {
@@ -207,6 +220,7 @@ sub prepare_run {
                        same_fs_or_die($old, $wip->dirname);
                        my $cur = "$old/$dn";
                        push @queue, [ $src // $cur , $wip ];
+                       nodatacow_dir($wip->dirname);
                        $tmp->{$cur} = $wip;
                }
                # mark old shards to be unlinked
@@ -219,41 +233,44 @@ sub prepare_run {
 
 sub check_compact () { runnable_or_die($XAPIAN_COMPACT) }
 
+sub _run {
+       my ($ibx, $cb, $opt, $reindex) = @_;
+       my $im = $ibx->importer(0);
+       $im->lock_acquire;
+       my ($tmp, $queue) = prepare_run($ibx, $opt);
+
+       # fine-grained locking if we prepare for reindex
+       if (!$opt->{-coarse_lock}) {
+               prepare_reindex($ibx, $im, $reindex);
+               $im->lock_release;
+       }
+
+       $ibx->cleanup;
+       process_queue($queue, $cb, $opt);
+       $im->lock_acquire if !$opt->{-coarse_lock};
+       commit_changes($ibx, $im, $tmp, $opt);
+}
+
 sub run {
        my ($ibx, $task, $opt) = @_; # task = 'cpdb' or 'compact'
        my $cb = \&${\"PublicInbox::Xapcmd::$task"};
        PublicInbox::Admin::progress_prepare($opt ||= {});
        defined(my $dir = $ibx->{inboxdir}) or die "no inboxdir defined\n";
        -d $dir or die "inboxdir=$dir does not exist\n";
-       check_compact() if $opt->{compact};
+       check_compact() if $opt->{compact} && $ibx->search;
        my $reindex; # v1:{ from => $x40 }, v2:{ from => [ $x40, $x40, .. ] } }
 
        if (!$opt->{-coarse_lock}) {
-               $reindex = $opt->{reindex} = {};
-               $reindex->{from} = []; # per-epoch ranges
-               require PublicInbox::SearchIdx;
+               $reindex = $opt->{reindex} = { # per-epoch ranges for v2
+                       from => $ibx->version == 1 ? '' : [],
+               };
                PublicInbox::SearchIdx::load_xapian_writable();
        }
 
        local %SIG = %SIG;
        setup_signals();
        $ibx->umask_prepare;
-       $ibx->with_umask(sub {
-               my $im = $ibx->importer(0);
-               $im->lock_acquire;
-               my ($tmp, $queue) = prepare_run($ibx, $opt);
-
-               # fine-grained locking if we prepare for reindex
-               if (!$opt->{-coarse_lock}) {
-                       prepare_reindex($ibx, $im, $reindex);
-                       $im->lock_release;
-               }
-
-               $ibx->cleanup;
-               process_queue($queue, $cb, $opt);
-               $im->lock_acquire if !$opt->{-coarse_lock};
-               commit_changes($ibx, $im, $tmp, $opt);
-       });
+       $ibx->with_umask(\&_run, $ibx, $cb, $opt, $reindex);
 }
 
 sub cpdb_retryable ($$) {
@@ -392,16 +409,18 @@ sub cpdb ($$) {
                $ft = File::Temp->newdir("$new.compact-XXXXXX", DIR => $dir);
                setup_signals();
                $tmp = $ft->dirname;
+               nodatacow_dir($tmp);
        } else {
                $tmp = $new;
        }
 
        # like copydatabase(1), be sure we don't overwrite anything in case
        # of other bugs:
-       my $creat = eval($PublicInbox::Search::Xap.'::DB_CREATE()');
+       my $flag = eval($PublicInbox::Search::Xap.'::DB_CREATE()');
        die if $@;
        my $XapianWritableDatabase = $PublicInbox::Search::X{WritableDatabase};
-       my $dst = $XapianWritableDatabase->new($tmp, $creat);
+       $flag |= $PublicInbox::SearchIdx::DB_NO_SYNC if !$opt->{sync};
+       my $dst = $XapianWritableDatabase->new($tmp, $flag);
        my $pr = $opt->{-progress};
        my $pfx = $opt->{-progress_pfx} = progress_pfx($new);
        my $pr_data = { pr => $pr, pfx => $pfx, nr => 0 } if $pr;