Subject: [nfsv4] I-D Action: draft-ietf-nfsv4-rfc3530bis-dot-x-20.txt

From: [email-masked]
Date: Thu, 28 Nov 2013 10:04:51 -0800

A New Internet-Draft is available from the on-line Internet-Drafts directories.
 This draft is a work item of the Network File System Version 4 Working Group of the IETF.

	Title           : Network File System (NFS) Version 4 External Data Representation Standard (XDR) Description
	Author(s)       : Thomas Haynes
                          David Noveck
	Filename        : draft-ietf-nfsv4-rfc3530bis-dot-x-20.txt
	Pages           : 38
	Date            : 2013-11-28

Abstract:
   The Network File System (NFS) version 4 is a distributed filesystem
   protocol which owes its heritage to NFS protocol version 2, RFC 1094,
   and version 3, RFC 1813.  Unlike earlier versions, the NFS version 4
   protocol supports traditional file access, while integrating support
   for file locking and the mount protocol.  In addition, support for
   strong security (and its negotiation), compound operations, client
   caching, and internationalization have been added.  Of course,
   attention has been applied to making NFS version 4 operate well in an
   Internet environment.

   RFC3530bis formally obsoleting RFC 3530.  This document, together
   with RFC3530bis replaces RFC 3530 as the definition of the NFS
   version 4 protocol.

The IETF datatracker status page for this draft is:
https://datatracker.ietf.org/doc/draft-ietf-nfsv4-rfc3530bis-dot-x

There's also a htmlized version available at:
http://tools.ietf.org/html/draft-ietf-nfsv4-rfc3530bis-dot-x-20

A diff from the previous version is available at:
http://www.ietf.org/rfcdiff?url2=draft-ietf-nfsv4-rfc3530bis-dot-x-20

Please note that it may take a couple of minutes from the time of submission
until the htmlized version and diff are available at tools.ietf.org.

Internet-Drafts are also available by anonymous FTP at:
ftp://ftp.ietf.org/internet-drafts/

---

From: Christoph Hellwig <[email-masked]>
Date: Fri, 29 Nov 2013 15:22:06 +0100

After I had some issue with compiling the rpcgen generated code of the
current NFSv4.2 draft Tom pointed out that I should check this one for
the issues I saw aswell.

Turns out I ran into another issue with the RFC3530bis XDR:

rpcgen trips over the linktext4 typedef:

typedef opaque linktext4;
^^^^^^^^^^^^^^^^^^^^^^^^^
nfs4_prot.x.orig, line 154: array declaration expected

looking over the XDR I tend to agree with it, and would suggest the
following update:

--- draft-ietf-nfsv4-rfc3530bis-dot-x-20.txt	2013-11-28 19:01:58.000000000 +0100
+++ draft-ietf-nfsv4-rfc3530bis-dot-x-20.txt.hch	2013-11-29 15:09:22.508522185 +0100
@@ -370,7 +370,7 @@
     /// typedef utf8string      utf8str_cs;
     /// typedef utf8string      utf8str_mixed;
     /// typedef utf8str_cs      component4;
-    /// typedef opaque          linktext4;
+    /// typedef opaque          linktext4<>;
     /// typedef utf8string      ascii_REQUIRED4;
     /// typedef component4      pathname4<>;
     /// typedef uint64_t        nfs_lockid4;

Once that is fixed we can return to my original problem: types.

The various NFSv4 specs make heavy use of the uint32_t and uint64_t
types, which do not exist in most of the RPC libraries.  As far as I can
tell only two implementations support it:  Solaris, and the old
Linux/glibc librpc.  The way I found this is because the Linux/glibc rpc
lib does not support RPCSEC_GSS or other newer features, so I tried to
compile the code against libtirpc which doesn't support these types
just like all the other Unix variants I've checked:

hch@brick:~/work/NFSv4.2$ gcc nfs4_prot.c -I /usr/include/tirpc/ -ltirpc
foo.c: In function "xdr_bitmap":
foo.c:44:34: error: "xdr_uint32_t" undeclared (first use in this function)
foo.c:44:34: note: each undeclared identifier is reported only once for each function it appears in

The easiest way to fix the issue would be to replace all occuranges
of uint32_t with the more portable u_int32_t and uint64_t with u_int64_t.

---

From: Chuck Lever <[email-masked]>
Date: Fri, 29 Nov 2013 11:20:12 -0500

> typedef opaque linktext4;

From /usr/include/tirpc/rpc/xdr.h:

extern bool_t   xdr_int(XDR *, int *); 
extern bool_t   xdr_u_int(XDR *, u_int *); 
extern bool_t   xdr_long(XDR *, long *); 
extern bool_t   xdr_u_long(XDR *, u_long *); 
extern bool_t   xdr_short(XDR *, short *); 
extern bool_t   xdr_u_short(XDR *, u_short *); 
extern bool_t   xdr_int16_t(XDR *, int16_t *); 
extern bool_t   xdr_u_int16_t(XDR *, u_int16_t *); 
extern bool_t   xdr_int32_t(XDR *, int32_t *); 
extern bool_t   xdr_u_int32_t(XDR *, u_int32_t *); 
extern bool_t   xdr_int64_t(XDR *, int64_t *); 
extern bool_t   xdr_u_int64_t(XDR *, u_int64_t *); 

The problem is that the XDR functions were renamed sometime in the past (note the addition of an underscore).  glibc's rpcgen wants to use xdr_uint32_t(), libtirpc provides xdr_u_int32_t().

I have a libtirpc patch pending to address this, since clearly Linux's libtirpc implementation is not compatible with the version of rpcgen shipping in Linux distributions.

> of uint32_t with the more portable u_int32_t and uint64_t with u_int64_t.

Unfortunately RFC 1832 never refers to either "uint" or u_int".  No guidance from the standards here.

-- 
Chuck Lever
chuck[dot]lever[at]oracle[dot]com

---

From: Christoph Hellwig <[email-masked]>
Date: Fri, 29 Nov 2013 17:32:35 +0100

> The problem is that the XDR functions were renamed sometime in the past (note the addition of an underscore).  glibc's rpcgen wants to use xdr_uint32_t(), libtirpc provides xdr_u_int32_t().

rpcgen doesn't care, it doesn't have any sized types hardcoded.

But it seems like glibc indeed misses the ones with the underscore, while
Solaris apparently provides both.  Given that the glibc rpc is outdated
and not compatible with modern NFS ecosystem code that seems to be a moot
point, though.

> I have a libtirpc patch pending to address this, since clearly Linux's libtirpc implementation is not compatible with the version of rpcgen shipping in Linux distributions.

While it probably makes sense to add them for compatiblity reasons rpcgen
doesn't really care.

> Unfortunately RFC 1832 never refers to either "uint" or u_int".  No guidance from the standards here.

On the other hand it defines unsigned int as being equivalent to an
uint32, and unsigned hyper as uint64.  While fairly ugly they'd at least
be standards conform.

---

From: Chuck Lever <[email-masked]>
Date: Fri, 29 Nov 2013 13:18:58 -0500

> uint32, and unsigned hyper as uint64.  While fairly ugly they'd at least

My copy of rpc/xdr.h from Solaris 11 update 1 has xdr_u_int() and xdr_uint*_t(), but it does not have xdr_u_int*_t().

I think xdr_u_int*_t() in the forked versions of libtirpc is wrong.  The point of XDR functions for these sized integer types seems to be to match the stdint.h types uint*_t.

I say leave the NFSv4 specs as they are, and fix libtirpc.

---

From: Christoph Hellwig <[email-masked]>
Date: Sat, 30 Nov 2013 17:28:28 +0100

> I think xdr_u_int*_t() in the forked versions of libtirpc is wrong.  The point of XDR functions for these sized integer types seems to be to match the stdint.h types uint*_t.

It's not just libtirpc, it's just about anyone else.

Summary from gnulib, although not always the newest versions:

	http://www.gnu.org/software/gnulib/manual/html_node/xdr_005fuint32_005ft.html

Seems like FreeBSD has added it in the mean time, but NetBSD and OpenBSD
haven't:

  http://cvsweb.netbsd.org/bsdweb.cgi/src/include/rpc/xdr.h?rev=1.27&content-type=text/x-cvsweb-markup&only_with_tag=MAIN
  http://www.openbsd.org/cgi-bin/cvsweb/src/include/rpc/xdr.h?rev=1.12;content-type=text%2Fx-cvsweb-markup

And I'd be surprised if other have.  I suspect the best way ahead is indeed
to use the uint and u_hyper types from RFC 1832.