From 6b607c92e19430eda5ebf8d64bca94722a4f0d39 Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Tue, 7 Apr 2009 13:17:22 +0200 Subject: [PATCH] df: new option --direct to not resolve a mount point * src/df.c (print_header): Print `File' instead of `Mounted on'. (show_entry): Handle global variable direct_statfs. (usage): Show the option --direct in --help. (main): Handle the option --direct. * tests/df/direct: New test for the --direct option. * tests/Makefile.am: Add the test to list. * doc/coreutils.texi: Document the option --direct. * NEWS: Mention the change. --- NEWS | 5 ++++ doc/coreutils.texi | 7 ++++++ src/df.c | 33 ++++++++++++++++++++++++++-- tests/Makefile.am | 1 + tests/df/direct | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 102 insertions(+), 3 deletions(-) create mode 100755 tests/df/direct diff --git a/NEWS b/NEWS index 7c507ef..bc8d344 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,11 @@ GNU coreutils NEWS -*- outline -*- * Noteworthy changes in release ?.? (????-??-??) [?] +** New features + + df now accepts a new option --direct to not resolve mount point and show + statistics directly for a file. + ** Bug fixes ls now aligns output correctly in the presence of abbreviated month diff --git a/doc/coreutils.texi b/doc/coreutils.texi index 70effa1..65bfd6f 100644 --- a/doc/coreutils.texi +++ b/doc/coreutils.texi @@ -9879,6 +9879,13 @@ pseudo-file-systems, such as automounter entries. Scale sizes by @var{size} before printing them (@pxref{Block size}). For example, @option{-BG} prints sizes in units of 1,073,741,824 bytes. address@hidden --direct address@hidden --direct address@hidden direct statfs for a file +Do not resolve mount point and show statistics directly for a file. It can be +especially useful for NFS mount points if there is a boundary between two +storage policies behind the mount point. + @itemx --total @opindex --total @cindex grand total of disk size, usage and available space diff --git a/src/df.c b/src/df.c index bbbb47d..6cbdaec 100644 --- a/src/df.c +++ b/src/df.c @@ -1,5 +1,5 @@ /* df - summarize free disk space - Copyright (C) 91, 1995-2008 Free Software Foundation, Inc. + Copyright (C) 91, 1995-2009 Free Software Foundation, Inc. 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 @@ -111,6 +111,9 @@ static bool print_type; /* If true, print a grand total at the end. */ static bool print_grand_total; +/* If true, show statistics for a file instead of mount point. */ +static bool direct_statfs; + /* Grand total data. */ static struct fs_usage grand_fsu; @@ -119,13 +122,15 @@ static struct fs_usage grand_fsu; enum { NO_SYNC_OPTION = CHAR_MAX + 1, - SYNC_OPTION + SYNC_OPTION, + DIRECT_OPTION }; static struct option const long_options[] = { {"all", no_argument, NULL, 'a'}, {"block-size", required_argument, NULL, 'B'}, + {"direct", no_argument, NULL, DIRECT_OPTION}, {"inodes", no_argument, NULL, 'i'}, {"human-readable", no_argument, NULL, 'h'}, {"si", no_argument, NULL, 'H'}, @@ -198,7 +203,10 @@ print_header (void) human_readable (output_block_size, buf, opts, 1, 1)); } - printf (_(" Mounted on\n")); + if (direct_statfs) + printf (_(" File\n")); + else + printf (_(" Mounted on\n")); } /* Is FSTYPE a type of file system that should be listed? */ @@ -747,6 +755,14 @@ show_point (const char *point, const struct stat *statp) static void show_entry (char const *name, struct stat const *statp) { + if (direct_statfs) + { + char *resolved = canonicalize_file_name (name); + show_dev (NULL, resolved, NULL, NULL, false, false, NULL); + free (resolved); + return; + } + if ((S_ISBLK (statp->st_mode) || S_ISCHR (statp->st_mode)) && show_disk (name)) return; @@ -813,6 +829,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\ fputs (_("\ -a, --all include dummy file systems\n\ -B, --block-size=SIZE use SIZE-byte blocks\n\ + --direct show statistics for a file instead of mount point\n\ --total produce a grand total\n\ -h, --human-readable print sizes in human readable format (e.g., 1K 234M 2G)\n\ -H, --si likewise, but use powers of 1000 not 1024\n\ @@ -889,6 +906,9 @@ main (int argc, char **argv) xstrtol_fatal (e, oi, c, long_options, optarg); } break; + case DIRECT_OPTION: + direct_statfs = true; + break; case 'i': inode_format = true; break; @@ -949,6 +969,13 @@ main (int argc, char **argv) } } + if (direct_statfs && show_local_fs) + { + error (0, 0, _("options --direct and --local (-l) are mutually " + "exclusive")); + usage (EXIT_FAILURE); + } + if (human_output_opts == -1) { if (posix_format) diff --git a/tests/Makefile.am b/tests/Makefile.am index 07f34ec..f8f07d4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -296,6 +296,7 @@ TESTS = \ dd/skip-seek2 \ dd/skip-seek-past-file \ dd/unblock-sync \ + df/direct \ df/total-verify \ du/2g \ du/8gb \ diff --git a/tests/df/direct b/tests/df/direct new file mode 100755 index 0000000..5c098f8 --- /dev/null +++ b/tests/df/direct @@ -0,0 +1,59 @@ +#!/bin/sh +# Ensure "df --direct" works as documented + +# Copyright (C) 2009 Free Software Foundation, Inc. + +# 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +if test "$VERBOSE" = yes; then + set -x + df --version +fi + +. $srcdir/test-lib.sh + +df || skip_test_ "df fails" + +DIR=`pwd` || framework_failure +FILE="$DIR/file" +touch "$FILE" || framework_failure +echo "$FILE" > file_exp || framework_failure +echo "Mounted on" > header_mounted_exp || framework_failure +echo "File" > header_file_exp || framework_failure + +fail=0 + +df --portability "$FILE" > df_out || fail=1 +df --portability --direct "$FILE" > df_direct_out || fail=1 +df --portability --direct --local "$FILE" > /dev/null 2>&1 && fail=1 + +# check df header +$AWK '{ if (NR==1) print $6 " " $7; }' df_out > header_mounted_out \ + || framework_failure +$AWK '{ if (NR==1) print $6; }' df_direct_out > header_file_out \ + || framework_failure +compare header_mounted_out header_mounted_exp || fail=1 +compare header_file_out header_file_exp || fail=1 + +# check df output (without --direct) +$AWK '{ if (NR==2) print $6; }' df_out > file_out \ + || framework_failure +compare file_out file_exp && fail=1 + +# check df output (with --direct) +$AWK '{ if (NR==2) print $6; }' df_direct_out > file_out \ + || framework_failure +compare file_out file_exp || fail=1 + +Exit $fail -- 1.6.1.2