Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 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 +}