coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Du feature request - user reporting


From: Daniel Gall
Subject: Re: Du feature request - user reporting
Date: Wed, 7 Feb 2018 06:55:10 -0500

Sigh I am new at git.  Will have to fix that printf (" Groups"); back to Users.

On Wed, Feb 7, 2018 at 6:54 AM, Daniel Gall <address@hidden> wrote:
> And I had to clarify a variable name to enable trivial integration of
> the group subtotal reporting feature requested in other
> correspondence.
>
> Also, this feature (user subtotal reporting) will be really useful for
> quickly getting at which users are the primary space hogs in large
> shared directories.  An admin doesn't care if a user has 10,000 files
> of 4KiB each.  An admin definitely does care if another user's 3 files
> consume several GiB.  Especially in /tmp.  Also in large shared
> directories in fast scratch file systems like lustre or GPFS.
>
> From 9c728a4cde1d023131a5a675b878de3a05dec920 Mon Sep 17 00:00:00 2001
> From: Daniel Gall <address@hidden>
> Date: Wed, 7 Feb 2018 01:48:13 -0500
> Subject: [PATCH 2/2] du: clarified a variable name
>
> The user subtotal reporting feature should integrate trivially
> with the group subtotal reporting feature described in other
> correspondence.  Thus I changed a variable name for clarity in
> reading.  passwd *g is now passwd *u.
> ---
>  src/du.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/src/du.c b/src/du.c
> index a1d06d5..53349c2 100644
> --- a/src/du.c
> +++ b/src/du.c
> @@ -457,17 +457,17 @@ print_size (const struct duinfo *pdui, const char 
> *string)
>    if (opt_user_sizes)
>      {
>        uintmax_t i=0;
> -      struct passwd *g;
> -      printf(" Users");
> +      struct passwd *u;
> +      printf(" Groups");
>        for (i=0; i<65535; i++){
>          if (pdui->user_size[i] > 0)
>            {
> -            g = getpwuid(i);
> +            u = getpwuid(i);
>              printf (",");
> -            if (g == NULL){
> +            if (u == NULL){
>                printf (" %Ld:", (long long unsigned int)i);
>              }else{
> -              printf(" %s:", g->pw_name);
> +              printf(" %s:", u->pw_name);
>              }
>              print_only_size(pdui->user_size[i]);
>            }
> --
> 2.10.2
>
>
> On Wed, Feb 7, 2018 at 6:35 AM, Daniel Gall <address@hidden> wrote:
>> From d57cf221746eadf87e612f8d4596cbed91f4860d Mon Sep 17 00:00:00 2001
>> From: Daniel Gall <address@hidden>
>> Date: Wed, 7 Feb 2018 01:27:43 -0500
>> Subject: [PATCH] :Added user subtotal repoting to du
>>
>> ---
>>  NEWS               |   2 +
>>  doc/coreutils.texi |   5 ++
>>  src/du.c           | 179 
>> ++++++++++++++++++++++++++++++++++++++++++++++++++---
>>  3 files changed, 176 insertions(+), 10 deletions(-)
>>
>> diff --git a/NEWS b/NEWS
>> index 8a9e09e..6192b07 100644
>> --- a/NEWS
>> +++ b/NEWS
>> @@ -56,6 +56,8 @@ GNU coreutils NEWS
>>  -*- outline -*-
>>
>>    timeout now supports the --verbose option to diagnose forced termination.
>>
>> +  du now supports the -u option for user reporting
>> +
>>  ** Improvements
>>
>>    dd now supports iflag=direct with arbitrary sized files on all file 
>> systems.
>> diff --git a/doc/coreutils.texi b/doc/coreutils.texi
>> index cdde136..fb61345 100644
>> --- a/doc/coreutils.texi
>> +++ b/doc/coreutils.texi
>> @@ -12100,6 +12100,11 @@ the newline and any later characters are
>> ignored; if @env{TIME_STYLE}
>>  begins with @samp{posix-} the @samp{posix-} is ignored; and if
>>  @env{TIME_STYLE} is @samp{locale} it is ignored.
>>
>> +@item -u
>> +@opindex -u
>> +@cindex user reporting
>> +Show user subtotals for each item reported on.
>> +
>>  @item -X @var{file}
>>  @itemx --exclude-from=@var{file}
>>  @opindex -X @var{file}
>> diff --git a/src/du.c b/src/du.c
>> index ac4489f..a1d06d5 100644
>> --- a/src/du.c
>> +++ b/src/du.c
>> @@ -37,6 +37,7 @@
>>  #include "fprintftime.h"
>>  #include "human.h"
>>  #include "mountlist.h"
>> +#include "pwd.h"
>>  #include "quote.h"
>>  #include "stat-size.h"
>>  #include "stat-time.h"
>> @@ -61,6 +62,9 @@ extern bool fts_debug;
>>  # define FTS_CROSS_CHECK(Fts)
>>  #endif
>>
>> +/* If true, display user size info. */
>> +bool opt_user_sizes = false;
>> +
>>  /* A set of dev/ino pairs to help identify files and directories
>>     whose sizes have already been counted.  */
>>  static struct di_set *di_files;
>> @@ -81,6 +85,9 @@ struct duinfo
>>    /* Number of inodes in directory.  */
>>    uintmax_t inodes;
>>
>> +  /* Pointer to array of uid indexed size subtotals. */
>> +  uintmax_t *user_size;
>> +
>>    /* Latest timestamp found.  If tmax.tv_sec == TYPE_MINIMUM (time_t)
>>       && tmax.tv_nsec < 0, no timestamp has been found.  */
>>    struct timespec tmax;
>> @@ -90,28 +97,62 @@ struct duinfo
>>  static inline void
>>  duinfo_init (struct duinfo *a)
>>  {
>> +  uintmax_t i = 0;
>>    a->size = 0;
>>    a->inodes = 0;
>>    a->tmax.tv_sec = TYPE_MINIMUM (time_t);
>>    a->tmax.tv_nsec = -1;
>> +  if (opt_user_sizes)
>> +    {
>> +      for (i=0; i<65535; i++)
>> +        {
>> +      a->user_size[i] = 0;
>> +    }
>> +    }
>>  }
>>
>>  /* Set directory data.  */
>>  static inline void
>> -duinfo_set (struct duinfo *a, uintmax_t size, struct timespec tmax)
>> +duinfo_set (struct duinfo *a, uintmax_t size, struct timespec tmax,
>> uintmax_t uid)
>>  {
>> +  uintmax_t uid_u = (uintmax_t)uid;
>> +  uintmax_t uid_s;
>>    a->size = size;
>>    a->inodes = 1;
>>    a->tmax = tmax;
>> +  if (opt_user_sizes)
>> +    {
>> +      if (uid_u > 65534)
>> +        {
>> +      uid_s = 65534;
>> +    }
>> +      else
>> +        {
>> +      uid_s = uid_u;
>> +    }
>> +      if (uid_s >=0 && uid_s <=65534)
>> +        {
>> +      a->user_size[uid_s] = size;
>> +    }
>> +    }
>>  }
>>
>>  /* Accumulate directory data.  */
>>  static inline void
>>  duinfo_add (struct duinfo *a, struct duinfo const *b)
>>  {
>> +  uintmax_t i = 0;
>>    uintmax_t sum = a->size + b->size;
>>    a->size = a->size <= sum ? sum : UINTMAX_MAX;
>>    a->inodes = a->inodes + b->inodes;
>> +  if (opt_user_sizes)
>> +    {
>> +      for (i=0; i<65535; i++)
>> +        {
>> +          sum = a->user_size[i] + b->user_size[i];
>> +          a->user_size[i] = a->user_size[i] <= sum ? sum : UINTMAX_MAX;
>> +        }
>> +    }
>>    if (timespec_cmp (a->tmax, b->tmax) < 0)
>>      a->tmax = b->tmax;
>>  }
>> @@ -239,6 +280,7 @@ static struct option const long_options[] =
>>    {"threshold", required_argument, NULL, 't'},
>>    {"time", optional_argument, NULL, TIME_OPTION},
>>    {"time-style", required_argument, NULL, TIME_STYLE_OPTION},
>> +  {"user-reporting", no_argument, NULL, 'u'},
>>    {GETOPT_HELP_OPTION_DECL},
>>    {GETOPT_VERSION_OPTION_DECL},
>>    {NULL, 0, NULL, 0}
>> @@ -346,6 +388,7 @@ Summarize disk usage of the set of FILEs,
>> recursively for directories.\n\
>>                              FORMAT is interpreted like in 'date'\n\
>>  "), stdout);
>>        fputs (_("\
>> +  -u, --user-reporting also print user subtotals\n\
>>    -X, --exclude-from=FILE  exclude files that match any pattern in FILE\n\
>>        --exclude=PATTERN    exclude files that match PATTERN\n\
>>    -x, --one-file-system    skip directories on different file systems\n\
>> @@ -411,7 +454,25 @@ print_size (const struct duinfo *pdui, const char 
>> *string)
>>    print_only_size (opt_inodes
>>                     ? pdui->inodes
>>                     : pdui->size);
>> -
>> +  if (opt_user_sizes)
>> +    {
>> +      uintmax_t i=0;
>> +      struct passwd *g;
>> +      printf(" Users");
>> +      for (i=0; i<65535; i++){
>> +        if (pdui->user_size[i] > 0)
>> +          {
>> +            g = getpwuid(i);
>> +            printf (",");
>> +            if (g == NULL){
>> +              printf (" %Ld:", (long long unsigned int)i);
>> +            }else{
>> +              printf(" %s:", g->pw_name);
>> +            }
>> +            print_only_size(pdui->user_size[i]);
>> +          }
>> +      }
>> +    }
>>    if (opt_time)
>>      {
>>        putchar ('\t');
>> @@ -506,6 +567,12 @@ process_file (FTS *fts, FTSENT *ent)
>>    const struct stat *sb = ent->fts_statp;
>>    int info = ent->fts_info;
>>
>> +  if(opt_user_sizes)
>> +    {
>> +      dui.user_size = xcalloc (65536, sizeof (uintmax_t));
>> +      dui_to_print.user_size = xcalloc (65536, sizeof (uintmax_t));
>> +    }
>> +
>>    if (info == FTS_DNR)
>>      {
>>        /* An error occurred, but the size is known, so count it.  */
>> @@ -530,7 +597,18 @@ process_file (FTS *fts, FTSENT *ent)
>>            if (info == FTS_NS || info == FTS_SLNONE)
>>              {
>>                error (0, ent->fts_errno, _("cannot access %s"), quoteaf 
>> (file));
>> -              return false;
>> +              if(opt_user_sizes)
>> +                {
>> +                  if (dui.user_size != NULL)
>> +                    {
>> +                      free(dui.user_size);
>> +                    }
>> +                  if (dui_to_print.user_size != NULL)
>> +                    {
>> +                      free(dui_to_print.user_size);
>> +                    }
>> +                }
>> +          return false;
>>              }
>>
>>            /* The --one-file-system (-x) option cannot exclude anything
>> @@ -558,13 +636,34 @@ process_file (FTS *fts, FTSENT *ent)
>>                FTSENT const *e = fts_read (fts);
>>                assert (e == ent);
>>              }
>> -
>> +          if(opt_user_sizes)
>> +            {
>> +              if (dui.user_size != NULL)
>> +                {
>> +                  free(dui.user_size);
>> +                }
>> +              if (dui_to_print.user_size != NULL)
>> +                {
>> +                  free(dui_to_print.user_size);
>> +                }
>> +            }
>>            return true;
>>          }
>>
>>        switch (info)
>>          {
>>          case FTS_D:
>> +      if(opt_user_sizes)
>> +            {
>> +              if (dui.user_size != NULL)
>> +                {
>> +                  free(dui.user_size);
>> +                }
>> +              if (dui_to_print.user_size != NULL)
>> +                {
>> +                  free(dui_to_print.user_size);
>> +                }
>> +            }
>>            return true;
>>
>>          case FTS_ERR:
>> @@ -574,6 +673,17 @@ process_file (FTS *fts, FTSENT *ent)
>>            break;
>>
>>          case FTS_DC:
>> +      if(opt_user_sizes)
>> +            {
>> +              if (dui.user_size != NULL)
>> +                {
>> +                  free(dui.user_size);
>> +                }
>> +              if (dui_to_print.user_size != NULL)
>> +                {
>> +                  free(dui_to_print.user_size);
>> +                }
>> +            }
>>            /* If not following symlinks and not a (bind) mount point.  */
>>            if (cycle_warning_required (fts, ent)
>>                && ! mount_point_in_fts_cycle (ent))
>> @@ -584,22 +694,46 @@ process_file (FTS *fts, FTSENT *ent)
>>            return true;
>>          }
>>      }
>> -
>>    duinfo_set (&dui,
>>                (apparent_size
>>                 ? MAX (0, sb->st_size)
>>                 : (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
>>                (time_type == time_mtime ? get_stat_mtime (sb)
>>                 : time_type == time_atime ? get_stat_atime (sb)
>> -               : get_stat_ctime (sb)));
>> +               : get_stat_ctime (sb)),
>> +           sb->st_uid);
>>
>>    level = ent->fts_level;
>> -  dui_to_print = dui;
>> +
>> +  if (opt_user_sizes)
>> +    {
>> +      duinfo_set (&dui_to_print,
>> +              (apparent_size
>> +               ? MAX (0, sb->st_size)
>> +               : (uintmax_t) ST_NBLOCKS (*sb) * ST_NBLOCKSIZE),
>> +              (time_type == time_mtime ? get_stat_mtime (sb)
>> +               : time_type == time_atime ? get_stat_atime (sb)
>> +               : get_stat_ctime (sb)),
>> +               sb->st_uid);
>> +    }
>> +  else
>> +    {
>> +      dui_to_print = dui;
>> +    }
>>
>>    if (n_alloc == 0)
>>      {
>> +      size_t i;
>>        n_alloc = level + 10;
>>        dulvl = xcalloc (n_alloc, sizeof *dulvl);
>> +      if(opt_user_sizes)
>> +        {
>> +          for (i=0; i<n_alloc; i++)
>> +            {
>> +              dulvl[i].ent.user_size = xcalloc (65536, sizeof (uintmax_t));
>> +              dulvl[i].subdir.user_size = xcalloc (65536, sizeof 
>> (uintmax_t));
>> +            }
>> +        }
>>      }
>>    else
>>      {
>> @@ -613,14 +747,23 @@ process_file (FTS *fts, FTSENT *ent)
>>               Clear the accumulators for *all* levels between prev_level
>>               and the current one.  The depth may change dramatically,
>>               e.g., from 1 to 10.  */
>> +          size_t i;
>>
>>            if (n_alloc <= level)
>>              {
>>                dulvl = xnrealloc (dulvl, level, 2 * sizeof *dulvl);
>> +              if(opt_user_sizes)
>> +                {
>> +                  for (i=n_alloc; i<level*2; i++)
>> +                    {
>> +                      dulvl[i].ent.user_size = xcalloc (65536, sizeof
>> (uintmax_t));
>> +                      dulvl[i].subdir.user_size = xcalloc (65536,
>> sizeof (uintmax_t));
>> +                    }
>> +                }
>>                n_alloc = level * 2;
>>              }
>>
>> -          for (size_t i = prev_level + 1; i <= level; i++)
>> +          for (i = prev_level + 1; i <= level; i++)
>>              {
>>                duinfo_init (&dulvl[i].ent);
>>                duinfo_init (&dulvl[i].subdir);
>> @@ -666,6 +809,18 @@ process_file (FTS *fts, FTSENT *ent)
>>          print_size (&dui_to_print, file);
>>      }
>>
>> +  if(opt_user_sizes)
>> +    {
>> +      if (dui.user_size != NULL)
>> +        {
>> +          free(dui.user_size);
>> +        }
>> +      if (dui_to_print.user_size != NULL)
>> +        {
>> +          free(dui_to_print.user_size);
>> +        }
>> +    }
>> +
>>    return ok;
>>  }
>>
>> @@ -678,7 +833,6 @@ static bool
>>  du_files (char **files, int bit_flags)
>>  {
>>    bool ok = true;
>> -
>>    if (*files)
>>      {
>>        FTS *fts = xfts_open (files, bit_flags, NULL);
>> @@ -755,7 +909,7 @@ main (int argc, char **argv)
>>    while (true)
>>      {
>>        int oi = -1;
>> -      int c = getopt_long (argc, argv, "0abd:chHklmst:xB:DLPSX:",
>> +      int c = getopt_long (argc, argv, "0abd:chHklmst:uxB:DLPSX:",
>>                             long_options, &oi);
>>        if (c == -1)
>>          break;
>> @@ -850,6 +1004,11 @@ main (int argc, char **argv)
>>            }
>>            break;
>>
>> +        case 'u':
>> +          tot_dui.user_size = xcalloc (65536, sizeof (uintmax_t));
>> +          opt_user_sizes = true;
>> +          break;
>> +
>>          case 'x':
>>            bit_flags |= FTS_XDEV;
>>            break;
>> --
>> 2.10.2



reply via email to

[Prev in Thread] Current Thread [Next in Thread]