Contents of /trunk/util-linux/patches/util-linux-2.12i-nfsv4.patch
Parent Directory | Revision Log
Revision 153 -
(show annotations)
(download)
Tue May 8 20:52:56 2007 UTC (17 years, 4 months ago) by niro
File size: 12854 byte(s)
Tue May 8 20:52:56 2007 UTC (17 years, 4 months 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 | +} |