Subject: Re: bug#13927: stat --printf %t, %T flags (major and minor device types) don't work on mount points
From: Pádraig Brady <[email-masked]>
To: Tyler Hobbs <[email-masked]>
Cc: [email-masked]
Date: Tue, 12 Mar 2013 13:51:38 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

On 03/11/2013 08:39 PM, Tyler Hobbs wrote:
> If I run stat --printf='%D', the result is "10ca70", which is correct.
> However, if I run stat --printf='%t %T' /mountpoint, the result is
> erroneously "0 0".  If I instead run stat against the device directly (stat
> --printf='%t %T' /dev/xvdx), I get the correct result of "ca 170".
> 
> I believe the proper fix is to replace (in stat.c):
> 
>   out_uint_x (pformat, prefix_len, major (statbuf->st_rdev));
> 
> with:
> 
>   out_uint_x (pformat, prefix_len, major (statbuf->st_dev));
> 
> That is, use statbuf->st_dev instead of st_rdev, which is what the %d and
> %D directives use.
> 
> 
> I'm using coreutils 8.9, compiled from source, and this is the output of
> uname -a:
> 
> Linux ip-10-39-122-238 2.6.32-276.el6.x86_64 #1 SMP Tue May 29 17:38:19 EDT
> 2012 x86_64 x86_64 x86_64 GNU/Linux
> 
> Thanks for your time.
> - Tyler
> 

So %t and %T are only currently defined for device special files,
allowing one to distinguish between the represented device
and the device of the inode storing the representation (the special file).

$ stat -c '%T%t %D' /dev/sda /dev
08 5
00 5

Now %t and %T returning 0 for non special device nodes is not that useful.
I suppose in this case we might use st_rdev only for block and char specials,
and switch to st_dev otherwise.

However...

st_rdev is not always 0
I notice that st_rdev is not 0 on FreeBSD 9 for files.
I don't know what it represents, but it's non random so may be significant.
Also the man page I have here says that on XENIX
named special file subtypes are distinguished by st_rdev values

Also is it useful to get low level access like this
to the backing device major and minor for normal files
from a shell script?

So I think we'll just improve this through documentation.

Hopefully the attached clarifies things.

thanks,
Pádraig.
From 2a887d28aacb6135cdacb9c8776385b8e4d6ab38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Tue, 12 Mar 2013 13:43:08 +0000
Subject: [PATCH] doc: clarify stat the meaning of --format="%t %T"

* src/stat.c (usage): Mention sthat the values are only
defined for character and block special files.
* doc/coreutils.texi (stat invication): Likewise.
Also mention st_rdev.
Reported in http://bugs.gnu.org/13927
---
 doc/coreutils.texi |    9 +++++++--
 src/stat.c         |    4 ++--
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/doc/coreutils.texi b/doc/coreutils.texi
index c6b3b32..8f1df45 100644
--- a/doc/coreutils.texi
+++ b/doc/coreutils.texi
@@ -11631,8 +11631,8 @@ The valid @var{format} directives for files with @option{--format} and
 @item %N - Quoted file name with dereference if symbolic link
 @item %o - Optimal I/O transfer size hint
 @item %s - Total size, in bytes
-@item %t - Major device type in hex
-@item %T - Minor device type in hex
+@item %t - Major device type in hex (see below)
+@item %T - Minor device type in hex (see below)
 @item %u - User ID of owner
 @item %U - User name of owner
 @item %w - Time of file birth, or @samp{-} if unknown
@@ -11645,6 +11645,11 @@ The valid @var{format} directives for files with @option{--format} and
 @item %Z - Time of last change as seconds since Epoch
 @end itemize
 
+The @samp{%t} and @samp{%T} formats operate on the st_rdev member of
+the stat(2) structure, and are only defined for character and block
+special files.  On some systems or file types, st_rdev may be used to
+represent other quantities.
+
 The @samp{%W}, @samp{%X}, @samp{%Y}, and @samp{%Z} formats accept a
 precision preceded by a period to specify the number of digits to
 print after the decimal point.  For example, @samp{%.3X} outputs the
diff --git a/src/stat.c b/src/stat.c
index 2326698..a1938a7 100644
--- a/src/stat.c
+++ b/src/stat.c
@@ -1393,8 +1393,8 @@ The valid format sequences for files (without --file-system):\n\
   %N   quoted file name with dereference if symbolic link\n\
   %o   optimal I/O transfer size hint\n\
   %s   total size, in bytes\n\
-  %t   major device type in hex\n\
-  %T   minor device type in hex\n\
+  %t   major device type in hex, for character/block device special files\n\
+  %T   minor device type in hex, for character/block device special files\n\
 "), stdout);
       fputs (_("\
   %u   user ID of owner\n\
-- 
1.7.7.6