summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-12-28 13:17:44 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-12-28 13:27:02 +0200
commite7cd377f7801d42aa8e07addff93d2150666c237 (patch)
treee2a7c118bde14224e96e604e925d65448ab96fc3
parentc15c42ccd1e2377945fd0414eca1a49294bff454 (diff)
downloadtar-e7cd377f7801d42aa8e07addff93d2150666c237.tar.gz
Implement the "wait" checkpoint action.
This action instructs tar to pause until given signal is delivered. The newer genfile tool uses this action for communication between genfile and tar in exec mode. This eliminates race conitions and speeds up the tests based on exec mode. * doc/tar.texi: Document changes. * paxutils: Upgrade. * src/checkpoint.c: Implement the wait action. * src/common.h (decode_signal): New proto. * src/tar.c (decode_signal): New function. (set_stat_signal): Rewrite. * tests/dirrem01.at: Adjust genfile and tar command line arguments to use the new feature. * tests/dirrem02.at: Likewise. * tests/filerem01.at: Likewise. * tests/filerem02.at: Likewise. * tests/grow.at: Likewise. * tests/sptrcreat.at: Likewise. * tests/sptrdiff00.at: Likewise. * tests/sptrdiff01.at: Likewise. * tests/truncate.at: Likewise.
-rw-r--r--doc/tar.texi25
m---------paxutils0
-rw-r--r--src/checkpoint.c57
-rw-r--r--src/common.h2
-rw-r--r--src/tar.c25
-rw-r--r--tests/dirrem01.at5
-rw-r--r--tests/dirrem02.at5
-rw-r--r--tests/filerem01.at7
-rw-r--r--tests/filerem02.at7
-rw-r--r--tests/grow.at4
-rw-r--r--tests/sptrcreat.at10
-rw-r--r--tests/sptrdiff00.at5
-rw-r--r--tests/sptrdiff01.at5
-rw-r--r--tests/truncate.at10
14 files changed, 110 insertions, 57 deletions
diff --git a/doc/tar.texi b/doc/tar.texi
index 1362216c..a81851b3 100644
--- a/doc/tar.texi
+++ b/doc/tar.texi
@@ -2553,6 +2553,12 @@ Wait for @var{time} seconds.
@item ttyout=@var{string}
Output @var{string} on the current console (@file{/dev/tty}).
+
+@item totals
+Print statistics (see @pxref{totals}).
+
+@item wait=@var{signo}
+Wait for signal @var{signo}.
@end table
Several @option{--checkpoint-action} options can be specified. The
@@ -4452,6 +4458,25 @@ checkpoint:
$ @kbd{tar -c --checkpoint=1000 --checkpoint-action=sleep=30}
@end smallexample
+@anchor{checkpoint wait}
+@cindex @code{wait}, checkpoint action
+The @code{wait=@var{signo}} action stops further execution until the
+signal @var{signo} is delivered. Valid values for @var{signo} are:
+@code{SIGHUP}, @code{SIGQUIT}, @code{SIGINT}, @code{SIGUSR1} and
+@code{SIGUSR2}. The @samp{SIG} prefix is optional. For example:
+
+@example
+$ @kbd{tar -c -f arc --checkpoint=1000 --checkpoint-action wait=USR1 .}
+@end example
+
+In this example, @GNUTAR{} will stop archivation at each 1000th
+checkpoint. wait until the @samp{SIGUSR1} signal is delivered,
+and resume processing.
+
+This action is used by the @command{genfile} utility to perform
+modifications on the input files upon hitting certain checkpoints
+(@pxref{Exec Mode, genfile}).
+
@anchor{checkpoint exec}
@cindex @code{exec}, checkpoint action
Finally, the @code{exec} action executes a given external command.
diff --git a/paxutils b/paxutils
-Subproject 4ef7f9ab13bcf8483050c932110c88f7ae9c75a
+Subproject 56939847bfa9dbfacb7aebd26f48ea8a64dd8b1
diff --git a/src/checkpoint.c b/src/checkpoint.c
index 4c86b526..a8dc64a0 100644
--- a/src/checkpoint.c
+++ b/src/checkpoint.c
@@ -1,6 +1,6 @@
/* Checkpoint management for tar.
- Copyright 2007, 2013-2014, 2016-2017 Free Software Foundation, Inc.
+ Copyright 2007, 2013-2014, 2016-2018 Free Software Foundation, Inc.
This file is part of GNU tar.
@@ -23,6 +23,7 @@
#include <sys/ioctl.h>
#include <termios.h>
#include "fprintftime.h"
+#include <signal.h>
enum checkpoint_opcode
{
@@ -32,7 +33,8 @@ enum checkpoint_opcode
cop_ttyout,
cop_sleep,
cop_exec,
- cop_totals
+ cop_totals,
+ cop_wait
};
struct checkpoint_action
@@ -43,6 +45,7 @@ struct checkpoint_action
{
time_t time;
char *command;
+ int signal;
} v;
};
@@ -52,6 +55,16 @@ static unsigned checkpoint;
/* List of checkpoint actions */
static struct checkpoint_action *checkpoint_action, *checkpoint_action_tail;
+/* State of the checkpoint system */
+enum {
+ CHKP_INIT, /* Needs initialization */
+ CHKP_COMPILE, /* Actions are being compiled */
+ CHKP_RUN /* Actions are being run */
+};
+static int checkpoint_state;
+/* Blocked signals */
+static sigset_t sigs;
+
static struct checkpoint_action *
alloc_action (enum checkpoint_opcode opcode)
{
@@ -85,6 +98,12 @@ checkpoint_compile_action (const char *str)
{
struct checkpoint_action *act;
+ if (checkpoint_state == CHKP_INIT)
+ {
+ sigemptyset (&sigs);
+ checkpoint_state = CHKP_COMPILE;
+ }
+
if (strcmp (str, ".") == 0 || strcmp (str, "dot") == 0)
alloc_action (cop_dot);
else if (strcmp (str, "bell") == 0)
@@ -117,6 +136,12 @@ checkpoint_compile_action (const char *str)
}
else if (strcmp (str, "totals") == 0)
alloc_action (cop_totals);
+ else if (strncmp (str, "wait=", 5) == 0)
+ {
+ act = alloc_action (cop_wait);
+ act->v.signal = decode_signal (str + 5);
+ sigaddset (&sigs, act->v.signal);
+ }
else
FATAL_ERROR ((0, 0, _("%s: unknown checkpoint action"), str));
}
@@ -124,15 +149,22 @@ checkpoint_compile_action (const char *str)
void
checkpoint_finish_compile (void)
{
- if (checkpoint_option)
+ if (checkpoint_state == CHKP_COMPILE)
{
- if (!checkpoint_action)
- /* Provide a historical default */
- checkpoint_compile_action ("echo");
+ sigprocmask (SIG_BLOCK, &sigs, NULL);
+
+ if (checkpoint_option)
+ {
+ if (!checkpoint_action)
+ /* Provide a historical default */
+ checkpoint_compile_action ("echo");
+ }
+ else if (checkpoint_action)
+ /* Otherwise, set default checkpoint rate */
+ checkpoint_option = DEFAULT_CHECKPOINT;
+
+ checkpoint_state = CHKP_RUN;
}
- else if (checkpoint_action)
- /* Otherwise, set default checkpoint rate */
- checkpoint_option = DEFAULT_CHECKPOINT;
}
static const char *checkpoint_total_format[] = {
@@ -390,6 +422,13 @@ run_checkpoint_actions (bool do_write)
case cop_totals:
compute_duration ();
print_total_stats ();
+ break;
+
+ case cop_wait:
+ {
+ int n;
+ sigwait (&sigs, &n);
+ }
}
}
}
diff --git a/src/common.h b/src/common.h
index 885169fb..a4f6052d 100644
--- a/src/common.h
+++ b/src/common.h
@@ -798,6 +798,8 @@ void set_exit_status (int val);
void request_stdin (const char *option);
+int decode_signal (const char *);
+
/* Where an option comes from: */
enum option_source
{
diff --git a/src/tar.c b/src/tar.c
index 9919e87e..9c939f39 100644
--- a/src/tar.c
+++ b/src/tar.c
@@ -976,36 +976,37 @@ stat_on_signal (int signo)
#endif
}
-static void
-set_stat_signal (const char *name)
+int
+decode_signal (const char *name)
{
static struct sigtab
{
char const *name;
int signo;
} const sigtab[] = {
- { "SIGUSR1", SIGUSR1 },
{ "USR1", SIGUSR1 },
- { "SIGUSR2", SIGUSR2 },
{ "USR2", SIGUSR2 },
- { "SIGHUP", SIGHUP },
{ "HUP", SIGHUP },
- { "SIGINT", SIGINT },
{ "INT", SIGINT },
- { "SIGQUIT", SIGQUIT },
{ "QUIT", SIGQUIT }
};
struct sigtab const *p;
+ char const *s = name;
+ if (strncmp (s, "SIG", 3) == 0)
+ s += 3;
for (p = sigtab; p < sigtab + sizeof (sigtab) / sizeof (sigtab[0]); p++)
- if (strcmp (p->name, name) == 0)
- {
- stat_on_signal (p->signo);
- return;
- }
+ if (strcmp (p->name, s) == 0)
+ return p->signo;
FATAL_ERROR ((0, 0, _("Unknown signal name: %s"), name));
}
+static void
+set_stat_signal (const char *name)
+{
+ stat_on_signal (decode_signal (name));
+}
+
struct textual_date
{
diff --git a/tests/dirrem01.at b/tests/dirrem01.at
index dabc206f..b82be02b 100644
--- a/tests/dirrem01.at
+++ b/tests/dirrem01.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2017 Free Software Foundation, Inc.
+# Copyright 2017-2018 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -47,8 +47,7 @@ gnu) CPT=3;;
esac
genfile --run --checkpoint=$CPT --unlink dir/sub/file2 --unlink dir/sub -- \
- tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='echo' \
- --checkpoint-action='sleep=1' -c -f archive.tar \
+ tar --blocking-factor=1 -c -f archive.tar \
--listed-incremental db -v dir >/dev/null
],
[1],
diff --git a/tests/dirrem02.at b/tests/dirrem02.at
index 924454f1..c28989e6 100644
--- a/tests/dirrem02.at
+++ b/tests/dirrem02.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2017 Free Software Foundation, Inc.
+# Copyright 2017-2018 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -44,8 +44,7 @@ gnu) CPT=3;;
esac
genfile --run --checkpoint=$CPT --unlink dir/sub/file2 --unlink dir/sub -- \
- tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='echo' \
- --checkpoint-action='sleep=1' -c -f archive.tar \
+ tar --blocking-factor=1 -c -f archive.tar \
--listed-incremental db -v dir dir/sub >/dev/null
],
[2],
diff --git a/tests/filerem01.at b/tests/filerem01.at
index bf020538..0440277d 100644
--- a/tests/filerem01.at
+++ b/tests/filerem01.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2009, 2013-2014, 2016-2017 Free Software Foundation, Inc.
+# Copyright 2009, 2013-2014, 2016-2018 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -33,7 +33,7 @@
# http://lists.gnu.org/archive/html/bug-tar/2009-03/msg00000.html
#
-AT_SETUP([file removed as we read it (ca. 22 seconds)])
+AT_SETUP([file removed as we read it])
AT_KEYWORDS([create incremental listed filechange filerem filerem01])
AT_TAR_CHECK([
@@ -43,8 +43,7 @@ genfile --file dir/file1
genfile --file dir/sub/file2
genfile --run --checkpoint=3 --unlink dir/file1 -- \
- tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='sleep=1' \
- --checkpoint-action='echo' -c -f archive.tar \
+ tar --blocking-factor=1 -c -f archive.tar \
--listed-incremental db -v dir >/dev/null
],
[1],
diff --git a/tests/filerem02.at b/tests/filerem02.at
index 5e6d1bef..34625d6d 100644
--- a/tests/filerem02.at
+++ b/tests/filerem02.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2009, 2013-2014, 2016-2017 Free Software Foundation, Inc.
+# Copyright 2009, 2013-2014, 2016-2018 Free Software Foundation, Inc.
# This file is part of GNU tar.
@@ -23,7 +23,7 @@
# file or directory disappears that is explicitly mentioned
# in the command line.
-AT_SETUP([toplevel file removed (ca. 24 seconds)])
+AT_SETUP([toplevel file removed])
AT_KEYWORDS([create incremental listed filechange filerem filerem02])
AT_TAR_CHECK([
@@ -35,8 +35,7 @@ mkdir dir2
genfile --file dir2/file1
genfile --run --checkpoint=3 --exec 'rm -rf dir2' -- \
- tar --blocking-factor=1 --checkpoint=1 --checkpoint-action='sleep=1' \
- --checkpoint-action='echo' -c -f archive.tar \
+ tar --blocking-factor=1 -c -f archive.tar \
--listed-incremental db -v --warning=no-new-dir dir dir2 >/dev/null
],
[2],
diff --git a/tests/grow.at b/tests/grow.at
index b04250db..a4a047bf 100644
--- a/tests/grow.at
+++ b/tests/grow.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2006-2007, 2013-2014, 2016-2017 Free Software Foundation,
+# Copyright 2006-2007, 2013-2014, 2016-2018 Free Software Foundation,
# Inc.
# This file is part of GNU tar.
@@ -28,7 +28,7 @@ AT_KEYWORDS([grow filechange])
AT_TAR_CHECK([
genfile --file foo --length 50000k
genfile --file baz
-genfile --run --checkpoint 10 --length 1024 --append foo -- tar --checkpoint -vcf bar foo baz
+genfile --run=10 --checkpoint 10 --length 1024 --append foo -- tar -vcf bar foo baz
],
[1],
[foo
diff --git a/tests/sptrcreat.at b/tests/sptrcreat.at
index 8e28f0e0..cfc9e3b0 100644
--- a/tests/sptrcreat.at
+++ b/tests/sptrcreat.at
@@ -38,21 +38,17 @@ genfile --sparse --block-size=1024 --file foo \
0 ABCDEFGHIJ 1M ABCDEFGHIJ 10M ABCDEFGHIJ 200M ABCDEFGHIJ
genfile --file baz
genfile --run --checkpoint 3 --length 200m --truncate foo -- \
- tar --checkpoint=1 \
- --checkpoint-action=echo \
- --checkpoint-action=sleep=1 \
- --sparse -vcf bar foo baz
+ tar --sparse -vcf bar foo baz
echo Exit status: $?
echo separator
genfile --file foo --seek 200m --length 11575296 --pattern=zeros
-tar dvf bar],
-[1],
+tar dvf bar | sed '/foo: Mod time differs/d'],
+[0],
[foo
baz
Exit status: 1
separator
foo
-foo: Mod time differs
baz
],
[tar: foo: File shrank by 11575296 bytes; padding with zeros
diff --git a/tests/sptrdiff00.at b/tests/sptrdiff00.at
index c4105610..4a8cdc7b 100644
--- a/tests/sptrdiff00.at
+++ b/tests/sptrdiff00.at
@@ -35,10 +35,7 @@ echo creating
tar --sparse -vcf bar foo baz
echo comparing
genfile --run --checkpoint 3 --length 200m --truncate foo -- \
- tar --checkpoint=1 \
- --checkpoint-action=echo='Write checkpoint %u' \
- --checkpoint-action=sleep=1 \
- --sparse -vdf bar
+ tar --sparse -vdf bar
],
[1],
[creating
diff --git a/tests/sptrdiff01.at b/tests/sptrdiff01.at
index 2da22679..53c716b7 100644
--- a/tests/sptrdiff01.at
+++ b/tests/sptrdiff01.at
@@ -35,10 +35,7 @@ echo creating
tar --sparse -vcf bar foo baz
echo comparing
genfile --run --checkpoint 5 --length 221278210 --truncate foo -- \
- tar --checkpoint=1 \
- --checkpoint-action=echo='Write checkpoint %u' \
- --checkpoint-action=sleep=1 \
- --sparse -vdf bar
+ tar --sparse -vdf bar
],
[1],
[creating
diff --git a/tests/truncate.at b/tests/truncate.at
index a743e4b7..7bd1443d 100644
--- a/tests/truncate.at
+++ b/tests/truncate.at
@@ -1,7 +1,7 @@
# Process this file with autom4te to create testsuite. -*- Autotest -*-
# Test suite for GNU tar.
-# Copyright 2005, 2007, 2013-2014, 2016-2017 Free Software Foundation,
+# Copyright 2005, 2007, 2013-2014, 2016-2018 Free Software Foundation,
# Inc.
# This file is part of GNU tar.
@@ -33,18 +33,18 @@ AT_KEYWORDS([truncate filechange])
AT_TAR_CHECK([
genfile --file foo --length 200k
genfile --file baz
-genfile --run --checkpoint 10 --length 195k --truncate foo -- tar --checkpoint --checkpoint-action=echo --checkpoint-action=sleep=1 -vcf bar foo baz
+genfile --run --checkpoint 10 --length 195k --truncate foo -- \
+ tar -vcf bar foo baz
echo Exit status: $?
echo separator
genfile --file foo --seek 195k --length 5k --pattern=zeros
-tar dvf bar],
-[1],
+tar dvf bar|sed '/foo: Mod time differs/d'],
+[0],
[foo
baz
Exit status: 1
separator
foo
-foo: Mod time differs
baz
],
[tar: foo: File shrank by 5120 bytes; padding with zeros