From patchwork Wed Dec 7 03:47:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dave Chinner X-Patchwork-Id: 9486745 X-Mozilla-Keys: nonjunk Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on sandeen.net X-Spam-Level: X-Spam-Status: No, score=-7.0 required=5.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD autolearn=unavailable autolearn_force=no version=3.4.0 X-Spam-HP: BAYES_00=-1.9,HEADER_FROM_DIFFERENT_DOMAINS=0.001, RCVD_IN_DNSWL_HI=-5,RP_MATCHES_RCVD=-0.1 X-Original-To: sandeen@sandeen.net Delivered-To: sandeen@sandeen.net Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by sandeen.net (Postfix) with ESMTP id 3E0D547968F for ; Tue, 6 Dec 2016 21:46:35 -0600 (CST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752295AbcLGDre (ORCPT ); Tue, 6 Dec 2016 22:47:34 -0500 Received: from ipmail06.adl6.internode.on.net ([150.101.137.145]:56135 "EHLO ipmail06.adl6.internode.on.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751618AbcLGDrd (ORCPT ); Tue, 6 Dec 2016 22:47:33 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A2BVEACUhUdYIGuWLHleGwEBAQMBAQEJAQEBgzkBAQEBAR+BYIZ0nDgBAQEBAQEGgR2Sb4QWhh4CAgKCI1QBAgEBAQEBAgYBAQEBAQE5RYRpBlYjEAgYMTkDBxQZiG6rIIs7AQEIJ4V0j04Fjn+LZ4lchy+CAIIHhjuGCoUqjGeBThMOg1wcgXEqNIkOAQEB Received: from ppp121-44-150-107.lns20.syd7.internode.on.net (HELO dastard) ([121.44.150.107]) by ipmail06.adl6.internode.on.net with ESMTP; 07 Dec 2016 14:17:29 +1030 Received: from discord.disaster.area ([192.168.1.111]) by dastard with esmtp (Exim 4.80) (envelope-from ) id 1cETCZ-00069V-9R; Wed, 07 Dec 2016 14:47:27 +1100 Received: from dave by discord.disaster.area with local (Exim 4.88) (envelope-from ) id 1cETCZ-0000bQ-8K; Wed, 07 Dec 2016 14:47:27 +1100 From: Dave Chinner To: linux-xfs@vger.kernel.org Cc: fstests@vger.kernel.org, amir73il@gmail.com Subject: [PATCH 6/6] libxcmd: add non-iterating user commands Date: Wed, 7 Dec 2016 14:47:24 +1100 Message-Id: <20161207034724.1613-7-david@fromorbit.com> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20161207034724.1613-1-david@fromorbit.com> References: <20161207034724.1613-1-david@fromorbit.com> Sender: linux-xfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-xfs@vger.kernel.org From: Dave Chinner Right now command iteration is not directly controllable by the user; it is controlled entirely by the application command flag setup. Sometimes we don't want commands to iterate but only operate on the currently selected object. For example, the stat command iterates: $ xfs_io -c "open -r foo" -c "open bar" -C "file" -c "stat" foo 000 foo (foreign,non-sync,non-direct,read-write) 001 foo (foreign,non-sync,non-direct,read-only) [002] bar (foreign,non-sync,non-direct,read-write) fd.path = "foo" fd.flags = non-sync,non-direct,read-write stat.ino = 462399 stat.type = regular file stat.size = 776508 stat.blocks = 1528 fd.path = "foo" fd.flags = non-sync,non-direct,read-only stat.ino = 462399 stat.type = regular file stat.size = 776508 stat.blocks = 1528 fd.path = "bar" fd.flags = non-sync,non-direct,read-write stat.ino = 475227 stat.type = regular file stat.size = 0 stat.blocks = 0 $ To do this, add a function to supply a "non-iterating" user command that will execute an iterating-capable command as though it CMD_FLAG_ONESHOT was set. Add a new command line option to xfs_io to drive it (-C ) and connect it all up. Document it in the xfs_IO man page, too. The result of "-C stat": $ xfs_io -c "open -r foo" -c "open bar" -c "file" -C "stat" foo 000 foo (foreign,non-sync,non-direct,read-write) 001 foo (foreign,non-sync,non-direct,read-only) [002] bar (foreign,non-sync,non-direct,read-write) fd.path = "bar" fd.flags = non-sync,non-direct,read-write stat.ino = 475227 stat.type = regular file stat.size = 0 stat.blocks = 0 $ Is that we only see the stat output for the active open file which is "bar". Signed-Off-By: Dave Chinner --- include/command.h | 1 + io/init.c | 7 +++++-- libxcmd/command.c | 33 +++++++++++++++++++++++++++------ man/man8/xfs_io.8 | 36 ++++++++++++++++++++++++++++++------ 4 files changed, 63 insertions(+), 14 deletions(-) diff --git a/include/command.h b/include/command.h index 348002cbe3ed..fb3f5c79b991 100644 --- a/include/command.h +++ b/include/command.h @@ -56,6 +56,7 @@ typedef int (*checkfunc_t)(const cmdinfo_t *ci); extern void add_command(const cmdinfo_t *ci); extern void add_user_command(char *optarg); +extern void add_oneshot_user_command(char *optarg); extern void add_command_iterator(iterfunc_t func); extern void add_check_command(checkfunc_t cf); diff --git a/io/init.c b/io/init.c index 5ce627ef22c9..cf8573f0ecd5 100644 --- a/io/init.c +++ b/io/init.c @@ -34,7 +34,7 @@ void usage(void) { fprintf(stderr, - _("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [-c cmd]... file\n"), +_("Usage: %s [-adfinrRstVx] [-m mode] [-p prog] [[-c|-C] cmd]... file\n"), progname); exit(1); } @@ -145,7 +145,7 @@ init( pagesize = getpagesize(); gettimeofday(&stopwatch, NULL); - while ((c = getopt(argc, argv, "ac:dFfim:p:nrRstTVx")) != EOF) { + while ((c = getopt(argc, argv, "ac:C:dFfim:p:nrRstTVx")) != EOF) { switch (c) { case 'a': flags |= IO_APPEND; @@ -153,6 +153,9 @@ init( case 'c': add_user_command(optarg); break; + case 'C': + add_oneshot_user_command(optarg); + break; case 'd': flags |= IO_DIRECT; break; diff --git a/libxcmd/command.c b/libxcmd/command.c index decc442a9d03..5917aea42611 100644 --- a/libxcmd/command.c +++ b/libxcmd/command.c @@ -25,8 +25,14 @@ int ncmds; static iterfunc_t iter_func; static checkfunc_t check_func; -static int ncmdline; -static char **cmdline; + +struct cmdline { + char *cmdline; + bool iterate; +}; + +static int ncmdline; +struct cmdline *cmdline; static int compare(const void *a, const void *b) @@ -120,12 +126,27 @@ void add_user_command(char *optarg) { ncmdline++; - cmdline = realloc(cmdline, sizeof(char*) * (ncmdline)); + cmdline = realloc(cmdline, sizeof(struct cmdline) * (ncmdline)); + if (!cmdline) { + perror("realloc"); + exit(1); + } + cmdline[ncmdline-1].cmdline = optarg; + cmdline[ncmdline-1].iterate = true; + +} + +void +add_oneshot_user_command(char *optarg) +{ + ncmdline++; + cmdline = realloc(cmdline, sizeof(struct cmdline) * (ncmdline)); if (!cmdline) { perror("realloc"); exit(1); } - cmdline[ncmdline-1] = optarg; + cmdline[ncmdline-1].cmdline = optarg; + cmdline[ncmdline-1].iterate = false; } /* @@ -212,14 +233,14 @@ command_loop(void) /* command line mode */ for (i = 0; !done && i < ncmdline; i++) { - input = strdup(cmdline[i]); + input = strdup(cmdline[i].cmdline); if (!input) { fprintf(stderr, _("cannot strdup command '%s': %s\n"), cmdline[i], strerror(errno)); exit(1); } - done = process_input(input, true); + done = process_input(input, cmdline[i].iterate); } free(cmdline); return; diff --git a/man/man8/xfs_io.8 b/man/man8/xfs_io.8 index 885df7f141e2..d6bacaf0438d 100644 --- a/man/man8/xfs_io.8 +++ b/man/man8/xfs_io.8 @@ -9,10 +9,13 @@ xfs_io \- debug the I/O path of an XFS filesystem .B \-c .I cmd ] ... [ +.B \-C +.I cmd +] ... [ .B \-p .I prog ] -.I file +.I [ file ] .br .B xfs_io \-V .SH DESCRIPTION @@ -25,14 +28,35 @@ These code paths include not only the obvious read/write/mmap interfaces for manipulating files, but also cover all of the XFS extensions (such as space preallocation, additional inode flags, etc). .SH OPTIONS +.B xfs_io +commands may be run interactively (the default) or as arguments on the +command line. +Interactive mode always runs commands on the current open file, whilst commands +run from the command line may operate on all open files rather than the current +open file. +Multiple arguments may be given on the command line and they are run in the +sequence given. The program exits one all commands have +been run. .TP 1.0i .BI \-c " cmd" -.B xfs_io -commands may be run interactively (the default) or as arguments on -the command line. Multiple +Run the specified command on all currently open files. +Some commands can not be run on all open files, so they will execute on only +the current open file to maintain compatibility with historical usage. +Multiple +.B \-c +arguments may be given and may be interleaved on the command line in any order +with +.B \-C +commands. +.TP +.BI \-C " cmd" +Run the specified command only on the active open file. +Multiple +.B \-C +arguments may be given and may be interleaved on the command line in any order +with .B \-c -arguments may be given. The commands are run in the sequence given, -then the program exits. +commands. .TP .BI \-p " prog" Set the program name for prompts and some error messages,