Discussion:
bug#6816: df bug on 64-bit Solaris (need to use getextmntent)
(too old to reply)
Wood, David
2010-08-06 19:56:07 UTC
Permalink
Hello,
Eric Blake
2010-09-15 22:18:37 UTC
Permalink
[digging through older mail, and sorry for the delayed reply]
Post by Wood, David
Hello,
Assaf Gordon
2018-10-10 17:24:22 UTC
Permalink
(triaging old bugs)

Hello,
[...]
At this point, me->me_dev contains a wrongly packed (32-bit) device
number, which forces the find_mount_point() code path (causing other
unpleasantries).  The following patch against coreutils v8.5 fixes the
Thanks for the report.  Yes, this needs to be folded into gnulib, but it
also needs an m4 check for getextmntent, and it would be nice to get by
with less in-function #ifdefs.
In 2014 gnulib gained the following commit:
https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=502809019bd2ca3ce3d041d18c35ce9420eedb72
===
commit 502809019bd2ca3ce3d041d18c35ce9420eedb72
Author: Ben Walton <***@gmail.com>
Date: Tue Jun 3 23:01:14 2014 +0100

mountlist: avoid hasmntopt const type warning on solaris
===

Which seems to address a similar issue as this bug (
https://bugs.gnu.org/6816 ).

I think recent coreutils build well on 64bit solaris.
If there are no objections I will close this bug in couple of days.

regards,
- assaf
Bruno Haible
2018-10-10 23:54:40 UTC
Permalink
Hi Assaf,
Post by Assaf Gordon
https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=502809019bd2ca3ce3d041d18c35ce9420eedb72
===
commit 502809019bd2ca3ce3d041d18c35ce9420eedb72
Date: Tue Jun 3 23:01:14 2014 +0100
mountlist: avoid hasmntopt const type warning on solaris
===
Which seems to address a similar issue as this bug (
https://bugs.gnu.org/6816 ).
I don't think it's the same bug. Gnulib still does not use getextmntent.
Post by Assaf Gordon
I think recent coreutils build well on 64bit solaris.
According to the cited man page, the effect of not using getextmntent
is visible at run-time, not at compile-time.
Post by Assaf Gordon
If there are no objections I will close this bug in couple of days.
Objection.

Bruno
Bruno Haible
2018-10-12 16:17:52 UTC
Permalink
At this point, me->me_dev contains a wrongly packed (32-bit) device
number, which forces the find_mount_point() code path (causing other
unpleasantries). The following patch against coreutils v8.5 fixes the
This problem description was to the point, but I needed a bit of time to
understand the issue entirely.

On Solaris, gnulib's mountlist module proceeds by reading the /etc/mnttab
file.

https://docs.oracle.com/cd/E86824_01/html/E54775/mnttab-4.html says:
"The mnttab file system provides the previously undocumented dev=xxx option
in the option string for each mounted file system. This is provided for
legacy applications that might have been using the dev=information option.

Using dev=option in applications is strongly discouraged. The device number
string represents a 32-bit quantity and might not contain correct
information in 64-bit environments.

Applications requiring device number information for mounted file systems
should use the getextmntent(3C) interface, which functions properly in
either 32- or 64-bit environments."

The 'stat' program displays a dev_t. For example, for '/':
A 32-bit 'stat': 4750002 = (0x11d << 18) + (0x10002 << 0)
A 64-bit 'stat': 11d00010002 = (0x11d << 32) + (0x10002 << 0)

So, device numbers in a 32-bit program and in a 64-bit program are
different!

Additionally, reading /etc/mnttab produces the same(!) result when
done by a 64-bit program as by a 32-bit program. The approach that
converts the dev=... strings found in /etc/mnttab therefore produces
dev_t values according to 32-bit programs, even in a 64-bit program.

Now comes GNU 'df' which, as David noted, has logic to compare the
two dev_t values:
./src/df.c:1371: me->me_dev = disk_stats.st_dev;
./src/df.c:1388: if (statp->st_dev == me->me_dev
./src/df.c:1394: || disk_stats.st_dev != me->me_dev)

So, really, we need to avoid the wrongly encoded dev_t values, and
this means to follow the advice from the mnttab.4 man page.


2018-10-12 Bruno Haible <***@clisp.org>

mountlist: Improve support for Solaris in 64-bit mode.
Reported by David Wood <***@deshaw.com> in
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=6816>.
* m4/ls-mntd-fs.m4 (gl_LIST_MOUNTED_FILE_SYSTEMS): On Solaris 8 or
newer, define MOUNTED_GETEXTMNTENT instead of MOUNTED_GETMNTENT2.
* lib/mountlist.c: Add code for MOUNTED_GETEXTMNTENT case.

diff --git a/lib/mountlist.c b/lib/mountlist.c
index 970c611..845c348 100644
--- a/lib/mountlist.c
+++ b/lib/mountlist.c
@@ -111,7 +111,11 @@
# include <mntent.h>
#endif

-#ifdef MOUNTED_GETMNTENT2 /* Solaris, also (obsolete) SVR4 */
+#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */
+# include <sys/mnttab.h>
+#endif
+
+#ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */
# include <sys/mnttab.h>
#endif

@@ -918,10 +922,55 @@ read_file_system_list (bool need_fs_type)
}
#endif /* MOUNTED_GETMNTTBL */

-#ifdef MOUNTED_GETMNTENT2 /* Solaris, also (obsolete) SVR4 */
+#ifdef MOUNTED_GETEXTMNTENT /* Solaris >= 8 */
+ {
+ struct extmnttab mnt;
+ const char *table = MNTTAB;
+ FILE *fp;
+ int ret;
+
+ /* No locking is needed, because the contents of /etc/mnttab is generated
+ by the kernel. */
+
+ errno = 0;
+ fp = fopen (table, "r");
+ if (fp == NULL)
+ ret = errno;
+ else
+ {
+ while ((ret = getextmntent (fp, &mnt, 1)) == 0)
+ {
+ me = xmalloc (sizeof *me);
+ me->me_devname = xstrdup (mnt.mnt_special);
+ me->me_mountdir = xstrdup (mnt.mnt_mountp);
+ me->me_mntroot = NULL;
+ me->me_type = xstrdup (mnt.mnt_fstype);
+ me->me_type_malloced = 1;
+ me->me_dummy = MNT_IGNORE (&mnt) != 0;
+ me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
+ me->me_dev = makedev (mnt.mnt_major, mnt.mnt_minor);
+
+ /* Add to the linked list. */
+ *mtail = me;
+ mtail = &me->me_next;
+ }
+
+ ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
+ /* Here ret = -1 means success, ret >= 0 means failure. */
+ }
+
+ if (0 <= ret)
+ {
+ errno = ret;
+ goto free_then_fail;
+ }
+ }
+#endif /* MOUNTED_GETMNTTBL */
+
+#ifdef MOUNTED_GETMNTENT2 /* Solaris < 8, also (obsolete) SVR4 */
{
struct mnttab mnt;
- char *table = MNTTAB;
+ const char *table = MNTTAB;
FILE *fp;
int ret;
int lockfd = -1;
@@ -979,6 +1028,7 @@ read_file_system_list (bool need_fs_type)
}

ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
+ /* Here ret = -1 means success, ret >= 0 means failure. */
}

if (0 <= lockfd && close (lockfd) != 0)
diff --git a/m4/ls-mntd-fs.m4 b/m4/ls-mntd-fs.m4
index ff688f5..643d0ce 100644
--- a/m4/ls-mntd-fs.m4
+++ b/m4/ls-mntd-fs.m4
@@ -158,7 +158,23 @@ yes
fi

if test -z "$ac_list_mounted_fs"; then
- # Solaris, also (obsolete) SVR4.
+ # Solaris >= 8.
+ AC_CACHE_CHECK([for getextmntent function],
+ [fu_cv_sys_mounted_getextmntent],
+ [AC_EGREP_HEADER([getextmntent], [sys/mnttab.h],
+ [fu_cv_sys_mounted_getextmntent=yes],
+ [fu_cv_sys_mounted_getextmntent=no])])
+ if test $fu_cv_sys_mounted_getextmntent = yes; then
+ ac_list_mounted_fs=found
+ AC_DEFINE([MOUNTED_GETEXTMNTENT], [1],
+ [Define if there is a function named getextmntent for reading the list
+ of mounted file systems. (Solaris)])
+ fi
+ fi
+
+ if test -z "$ac_list_mounted_fs"; then
+ # Solaris < 8, also (obsolete) SVR4.
+ # Solaris >= 8 has the two-argument getmntent but is already handled above.
AC_CACHE_CHECK([for two-argument getmntent function],
[fu_cv_sys_mounted_getmntent2],
[AC_EGREP_HEADER([getmntent], [sys/mnttab.h],
Assaf Gordon
2018-10-30 05:01:44 UTC
Permalink
Hello Bruno,
Post by Bruno Haible
At this point, me->me_dev contains a wrongly packed (32-bit) device
number, which forces the find_mount_point() code path (causing other
unpleasantries). The following patch against coreutils v8.5 fixes the
This problem description was to the point, but I needed a bit of time to
understand the issue entirely.
[...]
Post by Bruno Haible
So, really, we need to avoid the wrongly encoded dev_t values, and
this means to follow the advice from the mnttab.4 man page.
mountlist: Improve support for Solaris in 64-bit mode.
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=6816>.
* m4/ls-mntd-fs.m4 (gl_LIST_MOUNTED_FILE_SYSTEMS): On Solaris 8 or
newer, define MOUNTED_GETEXTMNTENT instead of MOUNTED_GETMNTENT2.
* lib/mountlist.c: Add code for MOUNTED_GETEXTMNTENT case.
Did this solve the issue (any reports from Solaris users)?
can this bug be closed?

-assaf
Bruno Haible
2018-10-30 08:20:26 UTC
Permalink
Hello Assaf,
Post by Assaf Gordon
Post by Bruno Haible
mountlist: Improve support for Solaris in 64-bit mode.
<https://debbugs.gnu.org/cgi/bugreport.cgi?bug=6816>.
* m4/ls-mntd-fs.m4 (gl_LIST_MOUNTED_FILE_SYSTEMS): On Solaris 8 or
newer, define MOUNTED_GETEXTMNTENT instead of MOUNTED_GETMNTENT2.
* lib/mountlist.c: Add code for MOUNTED_GETEXTMNTENT case.
Did this solve the issue (any reports from Solaris users)?
can this bug be closed?
There was no "how-to-reproduce" recipe, nor did I receive feedback from the
reporter. But in my understanding the issue is fixed in the proper way.
Therefore yes, it can be closed.

Bruno

Loading...