aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfsroot.c
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2010-09-17 10:54:37 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2010-09-17 10:54:37 -0400
commit8d2321037896aa4868a67f45b2d6ed52b579a48a (patch)
tree9b7c7d75ce392539696dbe0992d8163dc0bf53a5 /fs/nfs/nfsroot.c
parent56463e50d1fc3f070492434cea6303b35ea000de (diff)
NFS: Clean up nfsroot.c
Clean up: now that mount option parsing for nfsroot is handled in fs/nfs/super.c, remove code in fs/nfs/nfsroot.c that is no longer used. This includes code that constructs the legacy nfs_mount_data structure, and code that does a MNT call to the server. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfsroot.c')
-rw-r--r--fs/nfs/nfsroot.c419
1 files changed, 1 insertions, 418 deletions
diff --git a/fs/nfs/nfsroot.c b/fs/nfs/nfsroot.c
index cb4a6bdca871..8e7d623173a9 100644
--- a/fs/nfs/nfsroot.c
+++ b/fs/nfs/nfsroot.c
@@ -71,22 +71,12 @@
71 71
72#include <linux/types.h> 72#include <linux/types.h>
73#include <linux/string.h> 73#include <linux/string.h>
74#include <linux/kernel.h>
75#include <linux/time.h>
76#include <linux/fs.h>
77#include <linux/init.h> 74#include <linux/init.h>
78#include <linux/sunrpc/clnt.h>
79#include <linux/sunrpc/xprtsock.h>
80#include <linux/nfs.h> 75#include <linux/nfs.h>
81#include <linux/nfs_fs.h> 76#include <linux/nfs_fs.h>
82#include <linux/nfs_mount.h>
83#include <linux/in.h>
84#include <linux/major.h>
85#include <linux/utsname.h> 77#include <linux/utsname.h>
86#include <linux/inet.h>
87#include <linux/root_dev.h> 78#include <linux/root_dev.h>
88#include <net/ipconfig.h> 79#include <net/ipconfig.h>
89#include <linux/parser.h>
90 80
91#include "internal.h" 81#include "internal.h"
92 82
@@ -94,9 +84,6 @@
94#undef NFSROOT_DEBUG 84#undef NFSROOT_DEBUG
95#define NFSDBG_FACILITY NFSDBG_ROOT 85#define NFSDBG_FACILITY NFSDBG_ROOT
96 86
97/* Default port to use if server is not running a portmapper */
98#define NFS_MNT_PORT 627
99
100/* Default path we try to mount. "%s" gets replaced by our IP address */ 87/* Default path we try to mount. "%s" gets replaced by our IP address */
101#define NFS_ROOT "/tftpboot/%s" 88#define NFS_ROOT "/tftpboot/%s"
102 89
@@ -107,7 +94,7 @@ static char nfs_root_parms[256] __initdata = "";
107static char nfs_root_options[256] __initdata = ""; 94static char nfs_root_options[256] __initdata = "";
108 95
109/* Address of NFS server */ 96/* Address of NFS server */
110static __be32 servaddr __initdata = 0; 97static __be32 servaddr __initdata = htonl(INADDR_NONE);
111 98
112/* Name of directory to mount */ 99/* Name of directory to mount */
113static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = ""; 100static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = "";
@@ -115,279 +102,6 @@ static char nfs_export_path[NFS_MAXPATHLEN + 1] __initdata = "";
115/* server:export path string passed to super.c */ 102/* server:export path string passed to super.c */
116static char nfs_root_device[NFS_MAXPATHLEN + 1] __initdata = ""; 103static char nfs_root_device[NFS_MAXPATHLEN + 1] __initdata = "";
117 104
118/* NFS-related data */
119static struct nfs_mount_data nfs_data __initdata = { 0, };/* NFS mount info */
120static int nfs_port __initdata = 0; /* Port to connect to for NFS */
121static int mount_port __initdata = 0; /* Mount daemon port number */
122
123
124/***************************************************************************
125
126 Parsing of options
127
128 ***************************************************************************/
129
130enum {
131 /* Options that take integer arguments */
132 Opt_port, Opt_rsize, Opt_wsize, Opt_timeo, Opt_retrans, Opt_acregmin,
133 Opt_acregmax, Opt_acdirmin, Opt_acdirmax,
134 /* Options that take no arguments */
135 Opt_soft, Opt_hard, Opt_intr,
136 Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac,
137 Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp,
138 Opt_acl, Opt_noacl,
139 /* Error token */
140 Opt_err
141};
142
143static const match_table_t tokens __initconst = {
144 {Opt_port, "port=%u"},
145 {Opt_rsize, "rsize=%u"},
146 {Opt_wsize, "wsize=%u"},
147 {Opt_timeo, "timeo=%u"},
148 {Opt_retrans, "retrans=%u"},
149 {Opt_acregmin, "acregmin=%u"},
150 {Opt_acregmax, "acregmax=%u"},
151 {Opt_acdirmin, "acdirmin=%u"},
152 {Opt_acdirmax, "acdirmax=%u"},
153 {Opt_soft, "soft"},
154 {Opt_hard, "hard"},
155 {Opt_intr, "intr"},
156 {Opt_nointr, "nointr"},
157 {Opt_posix, "posix"},
158 {Opt_noposix, "noposix"},
159 {Opt_cto, "cto"},
160 {Opt_nocto, "nocto"},
161 {Opt_ac, "ac"},
162 {Opt_noac, "noac"},
163 {Opt_lock, "lock"},
164 {Opt_nolock, "nolock"},
165 {Opt_v2, "nfsvers=2"},
166 {Opt_v2, "v2"},
167 {Opt_v3, "nfsvers=3"},
168 {Opt_v3, "v3"},
169 {Opt_udp, "proto=udp"},
170 {Opt_udp, "udp"},
171 {Opt_tcp, "proto=tcp"},
172 {Opt_tcp, "tcp"},
173 {Opt_acl, "acl"},
174 {Opt_noacl, "noacl"},
175 {Opt_err, NULL}
176
177};
178
179/*
180 * Parse option string.
181 */
182
183static int __init root_nfs_parse(char *name, char *buf)
184{
185
186 char *p;
187 substring_t args[MAX_OPT_ARGS];
188 int option;
189
190 if (!name)
191 return 1;
192
193 /* Set the NFS remote path */
194 p = strsep(&name, ",");
195 if (p[0] != '\0' && strcmp(p, "default") != 0)
196 strlcpy(buf, p, NFS_MAXPATHLEN);
197
198 while ((p = strsep (&name, ",")) != NULL) {
199 int token;
200 if (!*p)
201 continue;
202 token = match_token(p, tokens, args);
203
204 /* %u tokens only. Beware if you add new tokens! */
205 if (token < Opt_soft && match_int(&args[0], &option))
206 return 0;
207 switch (token) {
208 case Opt_port:
209 nfs_port = option;
210 break;
211 case Opt_rsize:
212 nfs_data.rsize = option;
213 break;
214 case Opt_wsize:
215 nfs_data.wsize = option;
216 break;
217 case Opt_timeo:
218 nfs_data.timeo = option;
219 break;
220 case Opt_retrans:
221 nfs_data.retrans = option;
222 break;
223 case Opt_acregmin:
224 nfs_data.acregmin = option;
225 break;
226 case Opt_acregmax:
227 nfs_data.acregmax = option;
228 break;
229 case Opt_acdirmin:
230 nfs_data.acdirmin = option;
231 break;
232 case Opt_acdirmax:
233 nfs_data.acdirmax = option;
234 break;
235 case Opt_soft:
236 nfs_data.flags |= NFS_MOUNT_SOFT;
237 break;
238 case Opt_hard:
239 nfs_data.flags &= ~NFS_MOUNT_SOFT;
240 break;
241 case Opt_intr:
242 case Opt_nointr:
243 break;
244 case Opt_posix:
245 nfs_data.flags |= NFS_MOUNT_POSIX;
246 break;
247 case Opt_noposix:
248 nfs_data.flags &= ~NFS_MOUNT_POSIX;
249 break;
250 case Opt_cto:
251 nfs_data.flags &= ~NFS_MOUNT_NOCTO;
252 break;
253 case Opt_nocto:
254 nfs_data.flags |= NFS_MOUNT_NOCTO;
255 break;
256 case Opt_ac:
257 nfs_data.flags &= ~NFS_MOUNT_NOAC;
258 break;
259 case Opt_noac:
260 nfs_data.flags |= NFS_MOUNT_NOAC;
261 break;
262 case Opt_lock:
263 nfs_data.flags &= ~NFS_MOUNT_NONLM;
264 break;
265 case Opt_nolock:
266 nfs_data.flags |= NFS_MOUNT_NONLM;
267 break;
268 case Opt_v2:
269 nfs_data.flags &= ~NFS_MOUNT_VER3;
270 break;
271 case Opt_v3:
272 nfs_data.flags |= NFS_MOUNT_VER3;
273 break;
274 case Opt_udp:
275 nfs_data.flags &= ~NFS_MOUNT_TCP;
276 break;
277 case Opt_tcp:
278 nfs_data.flags |= NFS_MOUNT_TCP;
279 break;
280 case Opt_acl:
281 nfs_data.flags &= ~NFS_MOUNT_NOACL;
282 break;
283 case Opt_noacl:
284 nfs_data.flags |= NFS_MOUNT_NOACL;
285 break;
286 default:
287 printk(KERN_WARNING "Root-NFS: unknown "
288 "option: %s\n", p);
289 return 0;
290 }
291 }
292
293 return 1;
294}
295
296/*
297 * Prepare the NFS data structure and parse all options.
298 */
299static int __init root_nfs_name(char *name)
300{
301 static char buf[NFS_MAXPATHLEN] __initdata;
302 char *cp;
303
304 /* Set some default values */
305 memset(&nfs_data, 0, sizeof(nfs_data));
306 nfs_port = -1;
307 nfs_data.version = NFS_MOUNT_VERSION;
308 nfs_data.flags = NFS_MOUNT_NONLM; /* No lockd in nfs root yet */
309 nfs_data.rsize = NFS_DEF_FILE_IO_SIZE;
310 nfs_data.wsize = NFS_DEF_FILE_IO_SIZE;
311 nfs_data.acregmin = NFS_DEF_ACREGMIN;
312 nfs_data.acregmax = NFS_DEF_ACREGMAX;
313 nfs_data.acdirmin = NFS_DEF_ACDIRMIN;
314 nfs_data.acdirmax = NFS_DEF_ACDIRMAX;
315 strcpy(buf, NFS_ROOT);
316
317 /* Process options received from the remote server */
318 root_nfs_parse(root_server_path, buf);
319
320 /* Override them by options set on kernel command-line */
321 root_nfs_parse(name, buf);
322
323 cp = utsname()->nodename;
324 if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
325 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long.\n");
326 return -1;
327 }
328 sprintf(nfs_export_path, buf, cp);
329
330 return 1;
331}
332
333
334/*
335 * Get NFS server address.
336 */
337static int __init root_nfs_addr(void)
338{
339 if ((servaddr = root_server_addr) == htonl(INADDR_NONE)) {
340 printk(KERN_ERR "Root-NFS: No NFS server available, giving up.\n");
341 return -1;
342 }
343
344 snprintf(nfs_data.hostname, sizeof(nfs_data.hostname),
345 "%pI4", &servaddr);
346 return 0;
347}
348
349/*
350 * Tell the user what's going on.
351 */
352#ifdef NFSROOT_DEBUG
353static void __init root_nfs_print(void)
354{
355 printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
356 nfs_export_path, nfs_data.hostname);
357 printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
358 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
359 printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
360 nfs_data.acregmin, nfs_data.acregmax,
361 nfs_data.acdirmin, nfs_data.acdirmax);
362 printk(KERN_NOTICE "Root-NFS: nfsd port = %d, mountd port = %d, flags = %08x\n",
363 nfs_port, mount_port, nfs_data.flags);
364}
365#endif
366
367
368static int __init root_nfs_init(void)
369{
370#ifdef NFSROOT_DEBUG
371 nfs_debug |= NFSDBG_ROOT;
372#endif
373
374 /*
375 * Decode the root directory path name and NFS options from
376 * the kernel command line. This has to go here in order to
377 * be able to use the client IP address for the remote root
378 * directory (necessary for pure RARP booting).
379 */
380 if (root_nfs_name(nfs_root_parms) < 0 ||
381 root_nfs_addr() < 0)
382 return -1;
383
384#ifdef NFSROOT_DEBUG
385 root_nfs_print();
386#endif
387
388 return 0;
389}
390
391/* 105/*
392 * Parse NFS server and directory information passed on the kernel 106 * Parse NFS server and directory information passed on the kernel
393 * command line. 107 * command line.
@@ -424,137 +138,6 @@ static int __init nfs_root_setup(char *line)
424 138
425__setup("nfsroot=", nfs_root_setup); 139__setup("nfsroot=", nfs_root_setup);
426 140
427/***************************************************************************
428
429 Routines to actually mount the root directory
430
431 ***************************************************************************/
432
433/*
434 * Construct sockaddr_in from address and port number.
435 */
436static inline void
437set_sockaddr(struct sockaddr_in *sin, __be32 addr, __be16 port)
438{
439 sin->sin_family = AF_INET;
440 sin->sin_addr.s_addr = addr;
441 sin->sin_port = port;
442}
443
444/*
445 * Query server portmapper for the port of a daemon program.
446 */
447static int __init root_nfs_getport(int program, int version, int proto)
448{
449 struct sockaddr_in sin;
450
451 printk(KERN_NOTICE "Looking up port of RPC %d/%d on %pI4\n",
452 program, version, &servaddr);
453 set_sockaddr(&sin, servaddr, 0);
454 return rpcb_getport_sync(&sin, program, version, proto);
455}
456
457
458/*
459 * Use portmapper to find mountd and nfsd port numbers if not overriden
460 * by the user. Use defaults if portmapper is not available.
461 * XXX: Is there any nfs server with no portmapper?
462 */
463static int __init root_nfs_ports(void)
464{
465 int port;
466 int nfsd_ver, mountd_ver;
467 int nfsd_port, mountd_port;
468 int proto;
469
470 if (nfs_data.flags & NFS_MOUNT_VER3) {
471 nfsd_ver = NFS3_VERSION;
472 mountd_ver = NFS_MNT3_VERSION;
473 nfsd_port = NFS_PORT;
474 mountd_port = NFS_MNT_PORT;
475 } else {
476 nfsd_ver = NFS2_VERSION;
477 mountd_ver = NFS_MNT_VERSION;
478 nfsd_port = NFS_PORT;
479 mountd_port = NFS_MNT_PORT;
480 }
481
482 proto = (nfs_data.flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
483
484 if (nfs_port < 0) {
485 if ((port = root_nfs_getport(NFS_PROGRAM, nfsd_ver, proto)) < 0) {
486 printk(KERN_ERR "Root-NFS: Unable to get nfsd port "
487 "number from server, using default\n");
488 port = nfsd_port;
489 }
490 nfs_port = port;
491 dprintk("Root-NFS: Portmapper on server returned %d "
492 "as nfsd port\n", port);
493 }
494
495 if ((port = root_nfs_getport(NFS_MNT_PROGRAM, mountd_ver, proto)) < 0) {
496 printk(KERN_ERR "Root-NFS: Unable to get mountd port "
497 "number from server, using default\n");
498 port = mountd_port;
499 }
500 mount_port = port;
501 dprintk("Root-NFS: mountd port is %d\n", port);
502
503 return 0;
504}
505
506
507/*
508 * Get a file handle from the server for the directory which is to be
509 * mounted.
510 */
511static int __init root_nfs_get_handle(void)
512{
513 struct sockaddr_in sin;
514 unsigned int auth_flav_len = 0;
515 struct nfs_mount_request request = {
516 .sap = (struct sockaddr *)&sin,
517 .salen = sizeof(sin),
518 .dirpath = nfs_export_path,
519 .version = (nfs_data.flags & NFS_MOUNT_VER3) ?
520 NFS_MNT3_VERSION : NFS_MNT_VERSION,
521 .protocol = (nfs_data.flags & NFS_MOUNT_TCP) ?
522 XPRT_TRANSPORT_TCP : XPRT_TRANSPORT_UDP,
523 .auth_flav_len = &auth_flav_len,
524 };
525 int status = -ENOMEM;
526
527 request.fh = nfs_alloc_fhandle();
528 if (!request.fh)
529 goto out;
530 set_sockaddr(&sin, servaddr, htons(mount_port));
531 status = nfs_mount(&request);
532 if (status < 0)
533 printk(KERN_ERR "Root-NFS: Server returned error %d "
534 "while mounting %s\n", status, nfs_export_path);
535 else {
536 nfs_data.root.size = request.fh->size;
537 memcpy(&nfs_data.root.data, request.fh->data, request.fh->size);
538 }
539 nfs_free_fhandle(request.fh);
540out:
541 return status;
542}
543
544/*
545 * Get the NFS port numbers and file handle, and return the prepared 'data'
546 * argument for mount() if everything went OK. Return NULL otherwise.
547 */
548void * __init old_nfs_root_data(void)
549{
550 if (root_nfs_init() < 0
551 || root_nfs_ports() < 0
552 || root_nfs_get_handle() < 0)
553 return NULL;
554 set_sockaddr((struct sockaddr_in *) &nfs_data.addr, servaddr, htons(nfs_port));
555 return (void*)&nfs_data;
556}
557
558static int __init root_nfs_copy(char *dest, const char *src, 141static int __init root_nfs_copy(char *dest, const char *src,
559 const size_t destlen) 142 const size_t destlen)
560{ 143{