summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2018-12-28 12:55:32 +0200
committerSergey Poznyakoff <gray@gnu.org>2018-12-28 13:11:46 +0200
commit56939847bfa9dbfacb7aebd26f48ea8a64dd8b1d (patch)
tree0d7e56970e17fff82ed658c9bc6117c73b9c55e5
parent4ef7f9ab13bcf8483050c932110c88f7ae9c75a7 (diff)
downloadpaxutils-56939847bfa9dbfacb7aebd26f48ea8a64dd8b1d.tar.gz
Improve genfile exec mode
This commit introduces interprocess communication between genfile and subsidiary command in exec mode. Instead of using sleep as part of the checkpoint action chain (as GNU tar did so far), genfile now inserts --checkpoint-action=wait=SIGUSR1 into the command line and sends the process the SIGUSR1 after having finished with the checkpoint. This eliminates the race condition and speeds up the tests based on exec mode. The "wait" action is introduced in GNU tar 1.30.90. * doc/genfile.texi: Document changes. * tests/genfile.c (checkpoint_granularity): New variable. (parse_opt): Optional argument to --run specifies granularity. (CHECKPOINT_TEXT): Customize for genfile. (exec_command): Take command as arguments. Insert the --checkpoint and --checkpoint-action options after the command name. Use checkpoint action wait=SIGUSR1 for synchronization. Send SIGUSR1 after processing checkpoint.
-rw-r--r--doc/genfile.texi80
-rw-r--r--tests/genfile.c75
2 files changed, 74 insertions, 81 deletions
diff --git a/doc/genfile.texi b/doc/genfile.texi
index 58aa593..f65ecc3 100644
--- a/doc/genfile.texi
+++ b/doc/genfile.texi
@@ -1,5 +1,5 @@
@c This is part of the paxutils manual.
-@c Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
+@c Copyright (C) 2005, 2006, 2009, 2108 Free Software Foundation, Inc.
@c Written by Sergey Poznyakoff
@c This file is distributed under GFDL 1.1 or any later version
@c published by the Free Software Foundation.
@@ -283,13 +283,43 @@ genfile --stat=name,atime *
@cindex Exec Mode, @command{genfile}
This mode is designed for testing the behavior of @code{paxutils}
-commands when some of the files change during archiving. It is an
-experimental mode.
-
- The @samp{Exec Mode} is toggled by @option{--run} command line
-option (or its alias @option{-r}). The non-optional arguments to
-@command{getopt} give the command line to be executed. Normally,
-it should contain at least the @option{--checkpoint} option.
+commands when some of the files change during archiving. It supposes
+that the command being executed supports @option{--checkpoint} and
+@option{--checkpoint-action} options (@pxref{checkpoints,
+Checkpoints,,tar,GNU tar}).
+
+ The @samp{Exec Mode} is enabled by @option{--run} command line
+option (or its alias @option{-r}). The non-optional arguments
+supply the command line to be executed. @command{Genfile} modifies
+this command line by inserting the following options between the
+command name and first argument:
+
+@example
+--checkpoint=@var{n}
+--checkpoint-action "echo=genfile checkpoint %u"
+--checkpoint-action "wait=SIGUSR1"
+@end example
+
+ Here, @var{n} stands for the checkpoint granularity (for GNU
+@command{tar}, it is the number of archive records read or written
+between each pair of checkpoints). The default value is 1. This
+value can be changed using the optional argument to the @option{--run}
+option. For example, to run actions on each 10th checkpoint:
+
+@example
+genfile --run=10 ...
+@end example
+
+ If the command line contains options, it must be preceded by a
+double-dash (@samp{--}), which will prevent these options from being
+interpreted by @command{genfile} itself. For example:
+
+@example
+genfile --run --checkpoint=2 --truncate foo -- tar -c -f a.tar .
+@end example
+
+ Notice also, that when running @command{tar}, its command line may
+not contain traditional options (cluster of letters without dash).
A set of options is provided for defining checkpoint values and
actions to be executed upon reaching them. Checkpoint values are
@@ -334,36 +364,6 @@ connected to descriptor 1. All messages it prints to file descriptor
2, except checkpoint notifications, are forwarded to standard
error.
- @command{Genfile} exits with the exit status of the executed command.
-
- For compatibility with previous @command{genfile} versions, the
-@option{--run} option takes an optional argument. If used this way,
-its argument supplies the command line to be executed. There should
-be no non-optional arguments in the @command{genfile} command line.
-
- The actual command line is constructed by inserting
-the @option{--checkpoint} option between the command name and its
-first argument (if any). Due to this, the argument to @option{--run}
-may not use traditional @command{tar} option syntax, i.e., the
-following is wrong:
-
-@smallexample
-# Wrong!
-genfile --run='tar cf foo bar'
-@end smallexample
-
-@noindent
-
-Use the following syntax instead:
-
-@smallexample
-genfile --run='tar -cf foo bar' @var{actions}...
-@end smallexample
-
-The above command line is equivalent to
-
-@smallexample
-genfile @var{actions}... -- tar -cf foo bar
-@end smallexample
+ In exec mode, @command{genfile} exits with the exit status of the
+executed command.
-Notice, that the use of compatibility mode is deprecated.
diff --git a/tests/genfile.c b/tests/genfile.c
index 66c54df..dc822c7 100644
--- a/tests/genfile.c
+++ b/tests/genfile.c
@@ -1,11 +1,9 @@
-/* Generate a file containing some preset patterns.
- Print statistics for existing files.
+/* Multi-purpose tool for tar and cpio testsuite.
- Copyright (C) 1995, 1996, 1997, 2001, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 1995-1997, 2001-2018 Free Software Foundation, Inc.
François Pinard <pinard@iro.umontreal.ca>, 1995.
- Sergey Poznyakoff <gray@mirddin.farlep.net>, 2004, 2005, 2006, 2007, 2008.
+ Sergey Poznyakoff <gray@gnu.org>, 2004-2018.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,8 +16,7 @@
General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software Foundation,
- Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <system.h>
@@ -96,10 +93,8 @@ size_t block_size = 512;
/* Block buffer for sparse file */
char *buffer;
-/* Number of arguments and argument vector for mode == mode_exec */
-int exec_argc;
-char **exec_argv;
-char *checkpoint_option;
+/* Checkpoint granularity for mode == mode_exec */
+char *checkpoint_granularity;
/* Time for --touch option */
struct timespec touch_time;
@@ -165,8 +160,8 @@ static struct argp_option options[] = {
{NULL, 0, NULL, 0,
N_("Synchronous execution options:"), GRP},
- {"run", 'r', N_("OPTION"), OPTION_ARG_OPTIONAL,
- N_("Execute ARGS. Useful with --checkpoint and one of --cut, --append, --touch, --unlink"),
+ {"run", 'r', N_("N"), OPTION_ARG_OPTIONAL,
+ N_("Execute ARGS. Trigger checkpoints every Nth record (default 1). Useful with --checkpoint and one of --cut, --append, --touch, --unlink"),
GRP+1 },
{"checkpoint", OPT_CHECKPOINT, N_("NUMBER"), 0,
N_("Perform given action (see below) upon reaching checkpoint NUMBER"),
@@ -351,11 +346,7 @@ parse_opt (int key, char *arg, struct argp_state *state)
case 'r':
mode = mode_exec;
- if (arg)
- {
- argcv_get (arg, "", NULL, &exec_argc, &exec_argv);
- checkpoint_option = "--checkpoint";
- }
+ checkpoint_granularity = arg ? arg : "1";
break;
case 'T':
@@ -822,10 +813,10 @@ process_checkpoint (size_t n)
}
}
-#define CHECKPOINT_TEXT "Write checkpoint"
+#define CHECKPOINT_TEXT "genfile checkpoint"
void
-exec_command (void)
+exec_command (int argc, char **argv)
{
int status;
pid_t pid;
@@ -833,20 +824,28 @@ exec_command (void)
char *p;
FILE *fp;
char buf[128];
-
+ int xargc;
+ char **xargv;
+ int i;
+ char checkpoint_option[80];
+
/* Insert --checkpoint option.
- FIXME: This assumes that exec_argv does not use traditional tar options
+ FIXME: This assumes that argv does not use traditional tar options
(without dash).
- FIXME: There is no way to set checkpoint argument (granularity).
*/
- if (checkpoint_option)
- {
- exec_argc++;
- exec_argv = xrealloc (exec_argv, (exec_argc + 1) * sizeof (*exec_argv));
- memmove (exec_argv+2, exec_argv+1,
- (exec_argc - 1) * sizeof (*exec_argv));
- exec_argv[1] = checkpoint_option;
- }
+ xargc = argc + 5;
+ xargv = xcalloc (xargc + 1, sizeof (xargv[0]));
+ xargv[0] = argv[0];
+ snprintf (checkpoint_option, sizeof (checkpoint_option),
+ "--checkpoint=%s", checkpoint_granularity);
+ xargv[1] = checkpoint_option;
+ xargv[2] = "--checkpoint-action";
+ xargv[3] = "echo=" CHECKPOINT_TEXT " %u";
+ xargv[4] = "--checkpoint-action";
+ xargv[5] = "wait=SIGUSR1";
+
+ for (i = 1; i <= argc; i++)
+ xargv[i + 5] = argv[i];
#ifdef SIGCHLD
/* System V fork+wait does not work if SIGCHLD is ignored. */
@@ -872,8 +871,8 @@ exec_command (void)
/* Make sure POSIX locale is used */
setenv ("LC_ALL", "POSIX", 1);
- execvp (exec_argv[0], exec_argv);
- error (EXIT_FAILURE, errno, "execvp %s", exec_argv[0]);
+ execvp (xargv[0], xargv);
+ error (EXIT_FAILURE, errno, "execvp %s", xargv[0]);
}
/* Master */
@@ -900,6 +899,7 @@ exec_command (void)
if (!(*end && !isspace ((unsigned char) *end)))
{
process_checkpoint (n);
+ kill (pid, SIGUSR1);
continue;
}
}
@@ -985,14 +985,7 @@ main (int argc, char **argv)
break;
case mode_exec:
- if (!checkpoint_option)
- {
- exec_argc = argc;
- exec_argv = argv;
- }
- else if (argc)
- error (EXIT_FAILURE, 0, _("too many arguments"));
- exec_command ();
+ exec_command (argc, argv);
break;
default: