Magellan Linux

Annotation of /trunk/util-linux/patches/util-linux-2.12i-nfsv4.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 153 - (hide annotations) (download)
Tue May 8 20:52:56 2007 UTC (17 years, 1 month ago) by niro
File size: 12854 byte(s)
-import

1 niro 153 diff -ur util-linux-2.12i.orig/mount/Makefile util-linux-2.12i/mount/Makefile
2     --- util-linux-2.12i.orig/mount/Makefile 2004-11-11 20:03:33.032897551 -0500
3     +++ util-linux-2.12i/mount/Makefile 2004-11-11 20:04:38.279986828 -0500
4     @@ -29,2 +29,4 @@
5    
6     +NFS_OBJS += nfs4mount.o
7     +GEN_FILES += nfs4mount.c
8     all: $(PROGS)
9     diff -ur util-linux-2.12i.orig/mount/mount.c util-linux-2.12i/mount/mount.c
10     --- util-linux-2.12i.orig/mount/mount.c 2004-11-11 20:03:33.033897369 -0500
11     +++ util-linux-2.12i/mount/mount.c 2004-11-11 20:03:40.384555521 -0500
12     @@ -810,6 +810,19 @@
13     "without support for the type `nfs'"));
14     #endif
15     }
16     +#ifdef HAVE_NFS
17     + /*
18     + * NFSv4 support
19     + */
20     + if (!fake && types && streq (types, "nfs4")) {
21     + mnt_err = nfs4mount(spec, node, &flags, &extra_opts, &mount_opts, bg);
22     + if (mnt_err)
23     + return mnt_err;
24     +#else
25     + die (EX_SOFTWARE, _("mount: this version was compiled "
26     + "without support for the type `nfs4'"));
27     +#endif
28     + }
29    
30     block_signals (SIG_BLOCK);
31    
32     diff -ur util-linux-2.12i.orig/mount/sundries.h util-linux-2.12i/mount/sundries.h
33     --- util-linux-2.12i.orig/mount/sundries.h 2004-11-11 20:03:33.034897186 -0500
34     +++ util-linux-2.12i/mount/sundries.h 2004-11-11 20:03:40.386555156 -0500
35     @@ -37,6 +37,8 @@
36     #ifdef HAVE_NFS
37     int nfsmount (const char *spec, const char *node, int *flags,
38     char **orig_opts, char **opt_args, int *version, int running_bg);
39     +int nfs4mount (const char *spec, const char *node, int *flags,
40     + char **orig_opts, char **opt_args, int running_bg);
41     #endif
42    
43     /* exit status - bits below are ORed */
44     diff -puN /dev/null mount/nfs4_mount.h
45     --- /dev/null 2003-01-08 17:56:04.000000000 -0500
46     +++ util-linux-2.11z-bfields/mount/nfs4_mount.h 2003-04-23 16:40:57.000000000 -0400
47     @@ -0,0 +1,82 @@
48     +#ifndef _LINUX_NFS4_MOUNT_H
49     +#define _LINUX_NFS4_MOUNT_H
50     +
51     +/*
52     + * linux/include/linux/nfs4_mount.h
53     + *
54     + * Copyright (C) 2002 Trond Myklebust
55     + *
56     + * structure passed from user-space to kernel-space during an nfsv4 mount
57     + */
58     +
59     +/*
60     + * WARNING! Do not delete or change the order of these fields. If
61     + * a new field is required then add it to the end. The version field
62     + * tracks which fields are present. This will ensure some measure of
63     + * mount-to-kernel version compatibility. Some of these aren't used yet
64     + * but here they are anyway.
65     + */
66     +#define NFS4_MOUNT_VERSION 1
67     +
68     +struct nfs_string {
69     + unsigned int len;
70     + const char* data;
71     +};
72     +
73     +struct nfs4_mount_data {
74     + int version; /* 1 */
75     + int flags; /* 1 */
76     + int rsize; /* 1 */
77     + int wsize; /* 1 */
78     + int timeo; /* 1 */
79     + int retrans; /* 1 */
80     + int acregmin; /* 1 */
81     + int acregmax; /* 1 */
82     + int acdirmin; /* 1 */
83     + int acdirmax; /* 1 */
84     +
85     + /* see the definition of 'struct clientaddr4' in RFC3010 */
86     + struct nfs_string client_addr; /* 1 */
87     +
88     + /* Mount path */
89     + struct nfs_string mnt_path; /* 1 */
90     +
91     + /* Server details */
92     + struct nfs_string hostname; /* 1 */
93     + /* Server IP address */
94     + unsigned int host_addrlen; /* 1 */
95     + struct sockaddr* host_addr; /* 1 */
96     +
97     + /* Transport protocol to use */
98     + int proto; /* 1 */
99     +
100     + /* Pseudo-flavours to use for authentication. See RFC2623 */
101     + int auth_flavourlen; /* 1 */
102     + int *auth_flavours; /* 1 */
103     +};
104     +
105     +/* bits in the flags field */
106     +/* Note: the fields that correspond to existing NFSv2/v3 mount options
107     + * should mirror the values from include/linux/nfs_mount.h
108     + */
109     +
110     +#define NFS4_MOUNT_SOFT 0x0001 /* 1 */
111     +#define NFS4_MOUNT_INTR 0x0002 /* 1 */
112     +#define NFS4_MOUNT_NOCTO 0x0010 /* 1 */
113     +#define NFS4_MOUNT_NOAC 0x0020 /* 1 */
114     +#define NFS4_MOUNT_STRICTLOCK 0x1000 /* 1 */
115     +#define NFS4_MOUNT_FLAGMASK 0xFFFF
116     +
117     +/* pseudoflavors: */
118     +
119     +#define RPC_AUTH_GSS_KRB5 390003
120     +#define RPC_AUTH_GSS_KRB5I 390004
121     +#define RPC_AUTH_GSS_KRB5P 390005
122     +#define RPC_AUTH_GSS_LKEY 390006
123     +#define RPC_AUTH_GSS_LKEYI 390007
124     +#define RPC_AUTH_GSS_LKEYP 390008
125     +#define RPC_AUTH_GSS_SPKM 390009
126     +#define RPC_AUTH_GSS_SPKMI 390010
127     +#define RPC_AUTH_GSS_SPKMP 390011
128     +
129     +#endif
130     diff -puN /dev/null mount/nfs4mount.c
131     --- /dev/null 2003-01-08 17:56:04.000000000 -0500
132     +++ util-linux-2.11z-bfields/mount/nfs4mount.c 2003-04-23 17:28:54.000000000 -0400
133     @@ -0,0 +1,323 @@
134     +/*
135     + * nfs4mount.c -- Linux NFS mount
136     + * Copyright (C) 2002 Trond Myklebust <trond.myklebust@fys.uio.no>
137     + *
138     + * This program is free software; you can redistribute it and/or modify
139     + * it under the terms of the GNU General Public License as published by
140     + * the Free Software Foundation; either version 2, or (at your option)
141     + * any later version.
142     + *
143     + * This program is distributed in the hope that it will be useful,
144     + * but WITHOUT ANY WARRANTY; without even the implied warranty of
145     + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
146     + * GNU General Public License for more details.
147     + *
148     + * Note: this file based on the original nfsmount.c
149     + */
150     +
151     +#include "../defines.h" /* for HAVE_rpcsvc_nfs_prot_h and HAVE_inet_aton */
152     +
153     +#include <linux/posix_types.h>
154     +#include <asm/posix_types.h>
155     +#undef __FD_CLR
156     +#undef __FD_SET
157     +#undef __FD_ISSET
158     +#undef __FD_ZERO
159     +
160     +#include <unistd.h>
161     +#include <stdio.h>
162     +#include <string.h>
163     +#include <errno.h>
164     +#include <netdb.h>
165     +#include <time.h>
166     +#include <sys/socket.h>
167     +#include <sys/time.h>
168     +#include <sys/utsname.h>
169     +#include <sys/stat.h>
170     +#include <netinet/in.h>
171     +#include <arpa/inet.h>
172     +
173     +#include "sundries.h"
174     +
175     +#include "mount_constants.h"
176     +#include "nfs4_mount.h"
177     +
178     +#include "nls.h"
179     +
180     +#ifndef NFS_PORT
181     +#define NFS_PORT 2049
182     +#endif
183     +
184     +static int parse_devname(char *hostdir, char **hostname, char **dirname)
185     +{
186     + char *s;
187     +
188     + if (!(s = strchr(hostdir, ':'))) {
189     + fprintf(stderr,
190     + _("mount: "
191     + "directory to mount not in host:dir format\n"));
192     + return -1;
193     + }
194     + *hostname = hostdir;
195     + *dirname = s + 1;
196     + *s = '\0';
197     + /* Ignore all but first hostname in replicated mounts
198     + until they can be fully supported. (mack@sgi.com) */
199     + if ((s = strchr(hostdir, ','))) {
200     + *s = '\0';
201     + fprintf(stderr,
202     + _("mount: warning: "
203     + "multiple hostnames not supported\n"));
204     + }
205     + return 0;
206     +}
207     +
208     +static int fill_ipv4_sockaddr(const char *hostname, struct sockaddr_in *addr)
209     +{
210     + struct hostent *hp;
211     + addr->sin_family = AF_INET;
212     +
213     + if (inet_aton(hostname, &addr->sin_addr))
214     + return 0;
215     + if ((hp = gethostbyname(hostname)) == NULL) {
216     + fprintf(stderr, _("mount: can't get address for %s\n"),
217     + hostname);
218     + return -1;
219     + }
220     + if (hp->h_length > sizeof(struct in_addr)) {
221     + fprintf(stderr,
222     + _("mount: got bad hp->h_length\n"));
223     + hp->h_length = sizeof(struct in_addr);
224     + }
225     + memcpy(&addr->sin_addr, hp->h_addr, hp->h_length);
226     + return 0;
227     +}
228     +
229     +static int get_my_ipv4addr(char *ip_addr, int len)
230     +{
231     + char myname[1024];
232     + struct sockaddr_in myaddr;
233     +
234     + if (gethostname(myname, sizeof(myname))) {
235     + fprintf(stderr, _("mount: can't determine client address\n"));
236     + return -1;
237     + }
238     + if (fill_ipv4_sockaddr(myname, &myaddr))
239     + return -1;
240     + snprintf(ip_addr, len, "%s", inet_ntoa(myaddr.sin_addr));
241     + ip_addr[len-1] = '\0';
242     + return 0;
243     +}
244     +
245     +int nfs4mount(const char *spec, const char *node, int *flags,
246     + char **extra_opts, char **mount_opts,
247     + int running_bg)
248     +{
249     + static struct nfs4_mount_data data;
250     + static char hostdir[1024];
251     + static char ip_addr[16] = "127.0.0.1";
252     + static struct sockaddr_in server_addr;
253     + static int pseudoflavour = 0;
254     +
255     + char *hostname, *dirname, *old_opts;
256     + char new_opts[1024];
257     + char *opt, *opteq;
258     + char *s;
259     + int val;
260     + int port, bg, soft, intr;
261     + int nocto, noac;
262     + int retry;
263     + int retval;
264     +
265     + retval = EX_FAIL;
266     + if (strlen(spec) >= sizeof(hostdir)) {
267     + fprintf(stderr, _("mount: "
268     + "excessively long host:dir argument\n"));
269     + goto fail;
270     + }
271     + strcpy(hostdir, spec);
272     + if (parse_devname(hostdir, &hostname, &dirname))
273     + goto fail;
274     +
275     + if (fill_ipv4_sockaddr(hostname, &server_addr))
276     + goto fail;
277     + if (get_my_ipv4addr(ip_addr, sizeof(ip_addr)))
278     + goto fail;
279     +
280     + /* add IP address to mtab options for use when unmounting */
281     + s = inet_ntoa(server_addr.sin_addr);
282     + old_opts = *extra_opts;
283     + if (!old_opts)
284     + old_opts = "";
285     + if (strlen(old_opts) + strlen(s) + 10 >= sizeof(new_opts)) {
286     + fprintf(stderr, _("mount: "
287     + "excessively long option argument\n"));
288     + goto fail;
289     + }
290     + snprintf(new_opts, sizeof(new_opts), "%s%saddr=%s",
291     + old_opts, *old_opts ? "," : "", s);
292     + *extra_opts = xstrdup(new_opts);
293     +
294     + /* Set default options.
295     + * rsize/wsize and timeo are left 0 in order to
296     + * let the kernel decide.
297     + */
298     + memset(&data, 0, sizeof(data));
299     + data.retrans = 3;
300     + data.acregmin = 3;
301     + data.acregmax = 60;
302     + data.acdirmin = 30;
303     + data.acdirmax = 60;
304     + data.proto = IPPROTO_TCP;
305     +
306     + bg = 0;
307     + soft = 0;
308     + intr = 0;
309     + nocto = 0;
310     + noac = 0;
311     + retry = 10000; /* 10000 minutes ~ 1 week */
312     +
313     + /*
314     + * NFSv4 specifies that the default port should be 2049
315     + */
316     + port = NFS_PORT;
317     +
318     + /* parse options */
319     +
320     + for (opt = strtok(old_opts, ","); opt; opt = strtok(NULL, ",")) {
321     + if ((opteq = strchr(opt, '='))) {
322     + val = atoi(opteq + 1);
323     + *opteq = '\0';
324     + if (!strcmp(opt, "rsize"))
325     + data.rsize = val;
326     + else if (!strcmp(opt, "wsize"))
327     + data.wsize = val;
328     + else if (!strcmp(opt, "timeo"))
329     + data.timeo = val;
330     + else if (!strcmp(opt, "retrans"))
331     + data.retrans = val;
332     + else if (!strcmp(opt, "acregmin"))
333     + data.acregmin = val;
334     + else if (!strcmp(opt, "acregmax"))
335     + data.acregmax = val;
336     + else if (!strcmp(opt, "acdirmin"))
337     + data.acdirmin = val;
338     + else if (!strcmp(opt, "acdirmax"))
339     + data.acdirmax = val;
340     + else if (!strcmp(opt, "actimeo")) {
341     + data.acregmin = val;
342     + data.acregmax = val;
343     + data.acdirmin = val;
344     + data.acdirmax = val;
345     + }
346     + else if (!strcmp(opt, "retry"))
347     + retry = val;
348     + else if (!strcmp(opt, "port"))
349     + port = val;
350     + else if (!strcmp(opt, "proto")) {
351     + if (!strncmp(opteq+1, "tcp", 3))
352     + data.proto = IPPROTO_TCP;
353     + else if (!strncmp(opteq+1, "udp", 3))
354     + data.proto = IPPROTO_UDP;
355     + else
356     + printf(_("Warning: Unrecognized proto= option.\n"));
357     + } else if (!strcmp(opt, "clientaddr")) {
358     + if (strlen(opteq+1) >= sizeof(ip_addr))
359     + printf(_("Invalid client address %s"),
360     + opteq+1);
361     + strncpy(ip_addr,opteq+1, sizeof(ip_addr));
362     + ip_addr[sizeof(ip_addr)-1] = '\0';
363     + } else if (!strcmp(opt, "sec")) {
364     + if (!strncmp(opteq+1, "krb5i",5))
365     + pseudoflavour = 390004;
366     + else if (!strncmp(opteq+1, "krb5p",5))
367     + pseudoflavour = 390005;
368     + else if (!strncmp(opteq+1, "krb5",4))
369     + pseudoflavour = 390003;
370     + else {
371     + printf(_("unknown security type %s\n"),
372     + opteq+1);
373     + goto fail;
374     + }
375     + } else if (!strcmp(opt, "addr")) {
376     + /* ignore */;
377     + } else {
378     + printf(_("unknown nfs mount parameter: "
379     + "%s=%d\n"), opt, val);
380     + goto fail;
381     + }
382     + } else {
383     + val = 1;
384     + if (!strncmp(opt, "no", 2)) {
385     + val = 0;
386     + opt += 2;
387     + }
388     + if (!strcmp(opt, "bg"))
389     + bg = val;
390     + else if (!strcmp(opt, "fg"))
391     + bg = !val;
392     + else if (!strcmp(opt, "soft"))
393     + soft = val;
394     + else if (!strcmp(opt, "hard"))
395     + soft = !val;
396     + else if (!strcmp(opt, "intr"))
397     + intr = val;
398     + else if (!strcmp(opt, "cto"))
399     + nocto = !val;
400     + else if (!strcmp(opt, "ac"))
401     + noac = !val;
402     + else {
403     + if (!sloppy) {
404     + printf(_("unknown nfs mount option: "
405     + "%s%s\n"), val ? "" : "no", opt);
406     + goto fail;
407     + }
408     + }
409     + }
410     + }
411     +
412     + data.flags = (soft ? NFS4_MOUNT_SOFT : 0)
413     + | (intr ? NFS4_MOUNT_INTR : 0)
414     + | (nocto ? NFS4_MOUNT_NOCTO : 0)
415     + | (noac ? NFS4_MOUNT_NOAC : 0);
416     +
417     + if (pseudoflavour != 0) {
418     + data.auth_flavourlen = 1;
419     + data.auth_flavours = &pseudoflavour;
420     + }
421     +
422     + data.client_addr.data = ip_addr;
423     + data.client_addr.len = strlen(ip_addr);
424     +
425     + data.mnt_path.data = dirname;
426     + data.mnt_path.len = strlen(dirname);
427     +
428     + data.hostname.data = hostname;
429     + data.hostname.len = strlen(hostname);
430     + data.host_addr = (struct sockaddr *)&server_addr;
431     + data.host_addrlen = sizeof(server_addr);
432     +
433     +#ifdef NFS_MOUNT_DEBUG
434     + printf("rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
435     + data.rsize, data.wsize, data.timeo, data.retrans);
436     + printf("acreg (min, max) = (%d, %d), acdir (min, max) = (%d, %d)\n",
437     + data.acregmin, data.acregmax, data.acdirmin, data.acdirmax);
438     + printf("port = %d, bg = %d, retry = %d, flags = %.8x\n",
439     + port, bg, retry, data.flags);
440     + printf("soft = %d, intr = %d, nocto = %d, noac = %d\n",
441     + (data.flags & NFS4_MOUNT_SOFT) != 0,
442     + (data.flags & NFS4_MOUNT_INTR) != 0,
443     + (data.flags & NFS4_MOUNT_NOCTO) != 0,
444     + (data.flags & NFS4_MOUNT_NOAC) != 0);
445     + printf("proto = %s\n", (data.proto == IPPROTO_TCP) ? "tcp" : "udp");
446     +#endif
447     +
448     + data.version = NFS4_MOUNT_VERSION;
449     +
450     + *mount_opts = (char *) &data;
451     + /* clean up */
452     + return 0;
453     +
454     +fail:
455     + return retval;
456     +}