diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2018-12-28 12:55:32 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2018-12-28 13:11:46 +0200 |
commit | 56939847bfa9dbfacb7aebd26f48ea8a64dd8b1d (patch) | |
tree | 0d7e56970e17fff82ed658c9bc6117c73b9c55e5 | |
parent | 4ef7f9ab13bcf8483050c932110c88f7ae9c75a7 (diff) | |
download | paxutils-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.texi | 80 | ||||
-rw-r--r-- | tests/genfile.c | 75 |
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: |