This source file includes following definitions.
- root_dev_open
- root_dev_close
- root_rarp_open
- root_rarp_close
- root_rarp_recv
- root_rarp_send
- root_free_bootp
- root_alloc_bootp
- root_add_bootp_route
- root_del_bootp_route
- root_open_udp_sock
- root_connect_udp_sock
- root_bind_udp_sock
- root_send_udp
- root_recv_udp
- root_bootp_init_ext
- root_bootp_close
- root_bootp_open
- root_bootp_send
- root_bootp_string
- root_do_bootp_ext
- root_bootp_recv
- root_auto_config
- root_nfs_parse
- root_nfs_print
- root_nfs_ip_config
- root_nfs_setup
- nfs_root_init
- root_nfs_open
- root_nfs_close
- root_nfs_bind
- root_nfs_call
- root_nfs_header
- root_nfs_get_port
- root_nfs_ports
- root_nfs_get_handle
- root_nfs_do_mount
- nfs_root_mount
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40 #undef NFSROOT_DEBUG
41 #undef NFSROOT_MORE_DEBUG
42
43
44 #define CONFIG_USE_BOOTP
45 #define CONFIG_USE_RARP
46
47
48 #define CONF_BASE_TIMEOUT (HZ*5)
49 #define CONF_RETRIES 10
50 #define CONF_TIMEOUT_RANDOM (HZ)
51 #define CONF_TIMEOUT_MULT *5/4
52 #define CONF_TIMEOUT_MAX (HZ*30)
53
54 #include <linux/config.h>
55 #include <linux/types.h>
56 #include <linux/string.h>
57 #include <linux/kernel.h>
58 #include <linux/sched.h>
59 #include <linux/fs.h>
60
61 #include <asm/param.h>
62 #include <linux/utsname.h>
63 #include <linux/in.h>
64 #include <linux/if.h>
65 #include <linux/inet.h>
66 #include <linux/net.h>
67 #include <linux/if_arp.h>
68 #include <linux/netdevice.h>
69 #ifdef CONFIG_AX25
70 #include <net/ax25.h>
71 #endif
72 #include <linux/skbuff.h>
73 #include <linux/socket.h>
74 #include <linux/route.h>
75 #include <linux/nfs.h>
76 #include <linux/nfs_fs.h>
77 #include <linux/nfs_mount.h>
78 #include <linux/in.h>
79 #include <net/route.h>
80 #include <net/sock.h>
81 #include <linux/random.h>
82 #include <linux/fcntl.h>
83
84
85
86 #define STARTPORT 600
87 #define ENDPORT 1023
88 #define NPORTS (ENDPORT - STARTPORT + 1)
89
90
91
92 struct open_dev {
93 struct device *dev;
94 unsigned short old_flags;
95 struct open_dev *next;
96 };
97
98 static struct open_dev *open_base = NULL;
99
100
101 static struct device *root_dev = NULL;
102 static char user_dev_name[IFNAMSIZ];
103 static struct sockaddr_in myaddr;
104 static struct sockaddr_in server;
105 static struct sockaddr_in gateway;
106 static struct sockaddr_in netmask;
107
108
109 static int bootp_flag;
110 static int rarp_flag;
111 static int bootp_dev_count = 0;
112 static int rarp_dev_count = 0;
113 volatile static int pkt_arrived;
114
115 #define ARRIVED_BOOTP 1
116 #define ARRIVED_RARP 2
117
118
119 static struct nfs_mount_data nfs_data;
120 static char nfs_path[NFS_MAXPATHLEN];
121 static int nfs_port;
122
123
124 #define IN_NTOA(x) (((x) == INADDR_NONE) ? "none" : in_ntoa(x))
125
126
127 extern asmlinkage int sys_socket(int family, int type, int protocol);
128
129
130
131
132
133
134
135
136
137
138
139
140 static int root_dev_open(void)
141 {
142 struct open_dev *openp, **last;
143 struct device *dev;
144 unsigned short old_flags;
145
146 last = &open_base;
147 for (dev = dev_base; dev != NULL; dev = dev->next) {
148 if (dev->type < ARPHRD_SLIP &&
149 dev->family == AF_INET &&
150 !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) &&
151 (!user_dev_name[0] || !strcmp(dev->name, user_dev_name))) {
152
153 old_flags = dev->flags;
154 dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
155 if (!(old_flags & IFF_UP) && dev_open(dev)) {
156 dev->flags = old_flags;
157 continue;
158 }
159 openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
160 GFP_ATOMIC);
161 if (openp == NULL)
162 continue;
163 openp->dev = dev;
164 openp->old_flags = old_flags;
165 *last = openp;
166 last = &openp->next;
167 bootp_dev_count++;
168 if (!(dev->flags & IFF_NOARP))
169 rarp_dev_count++;
170 #ifdef NFSROOT_DEBUG
171 printk(KERN_NOTICE "Root-NFS: Opened %s\n", dev->name);
172 #endif
173 }
174 }
175 *last = NULL;
176
177 if (!bootp_dev_count && !rarp_dev_count) {
178 printk(KERN_ERR "Root-NFS: Unable to open at least one network device\n");
179 return -1;
180 }
181 return 0;
182 }
183
184
185
186
187
188
189 static void root_dev_close(void)
190 {
191 struct open_dev *openp;
192 struct open_dev *nextp;
193
194 openp = open_base;
195 while (openp != NULL) {
196 nextp = openp->next;
197 openp->next = NULL;
198 if (openp->dev != root_dev) {
199 if (!(openp->old_flags & IFF_UP))
200 dev_close(openp->dev);
201 openp->dev->flags = openp->old_flags;
202 }
203 kfree_s(openp, sizeof(struct open_dev));
204 openp = nextp;
205 }
206 }
207
208
209
210
211
212
213
214
215 extern void arp_send(int type, int ptype, unsigned long target_ip,
216 struct device *dev, unsigned long src_ip,
217 unsigned char *dest_hw, unsigned char *src_hw,
218 unsigned char *target_hw);
219
220 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
221 struct packet_type *pt);
222
223
224 static struct packet_type rarp_packet_type = {
225 0,
226
227 NULL,
228 root_rarp_recv,
229 NULL,
230 NULL
231 };
232
233
234
235
236
237 static void root_rarp_open(void)
238 {
239 rarp_packet_type.type = htons(ETH_P_RARP);
240 dev_add_pack(&rarp_packet_type);
241 }
242
243
244
245
246
247 static void root_rarp_close(void)
248 {
249 rarp_packet_type.type = htons(ETH_P_RARP);
250 dev_remove_pack(&rarp_packet_type);
251 }
252
253
254
255
256
257 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
258 {
259 struct arphdr *rarp = (struct arphdr *)skb->h.raw;
260 unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
261 unsigned long sip, tip;
262 unsigned char *sha, *tha;
263
264
265 if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
266 kfree_skb(skb, FREE_READ);
267 return 0;
268 }
269
270
271 if (rarp->ar_op != htons(ARPOP_RREPLY)) {
272 kfree_skb(skb, FREE_READ);
273 return 0;
274 }
275
276
277 if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
278 #ifdef CONFIG_AX25
279 (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
280 #endif
281 rarp->ar_pln != 4) {
282 kfree_skb(skb, FREE_READ);
283 return 0;
284 }
285
286
287 sha = rarp_ptr;
288 rarp_ptr += dev->addr_len;
289 memcpy(&sip, rarp_ptr, 4);
290 rarp_ptr += 4;
291 tha = rarp_ptr;
292 rarp_ptr += dev->addr_len;
293 memcpy(&tip, rarp_ptr, 4);
294
295
296 if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
297 kfree_skb(skb, FREE_READ);
298 return 0;
299 }
300
301 if (server.sin_addr.s_addr != INADDR_NONE &&
302 server.sin_addr.s_addr != sip) {
303 kfree_skb(skb, FREE_READ);
304 return 0;
305 }
306
307
308
309
310
311 cli();
312 if (pkt_arrived) {
313 sti();
314 kfree_skb(skb, FREE_READ);
315 return 0;
316 }
317 pkt_arrived = ARRIVED_RARP;
318 sti();
319 root_dev = dev;
320
321 if (myaddr.sin_addr.s_addr == INADDR_NONE) {
322 myaddr.sin_family = dev->family;
323 myaddr.sin_addr.s_addr = tip;
324 }
325 if (server.sin_addr.s_addr == INADDR_NONE) {
326 server.sin_family = dev->family;
327 server.sin_addr.s_addr = sip;
328 }
329 kfree_skb(skb, FREE_READ);
330 return 0;
331 }
332
333
334
335
336
337 static void root_rarp_send(void)
338 {
339 struct open_dev *openp;
340 struct device *dev;
341 int num = 0;
342
343 for (openp = open_base; openp != NULL; openp = openp->next) {
344 dev = openp->dev;
345 if (!(dev->flags & IFF_NOARP)) {
346 arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
347 dev->dev_addr, dev->dev_addr);
348 num++;
349 }
350 }
351 }
352
353
354
355
356
357
358
359
360 static struct device *bootp_dev = NULL;
361
362 static int bootp_xmit_fd = -1;
363 static struct socket *bootp_xmit_sock;
364 static int bootp_recv_fd = -1;
365 static struct socket *bootp_recv_sock;
366
367 struct bootp_pkt {
368 u8 op;
369 u8 htype;
370 u8 hlen;
371 u8 hops;
372 u32 xid;
373 u16 secs;
374 u16 flags;
375 u32 client_ip;
376 u32 your_ip;
377 u32 server_ip;
378 u32 relay_ip;
379 u8 hw_addr[16];
380 u8 serv_name[64];
381 u8 boot_file[128];
382 u8 vendor_area[128];
383 };
384
385 #define BOOTP_REQUEST 1
386 #define BOOTP_REPLY 2
387
388 static struct bootp_pkt *xmit_bootp;
389 static struct bootp_pkt *recv_bootp;
390
391 static int bootp_have_route = 0;
392
393
394
395
396 static void root_free_bootp(void)
397 {
398 if (xmit_bootp) {
399 kfree_s(xmit_bootp, sizeof(struct bootp_pkt));
400 xmit_bootp = NULL;
401 }
402 if (recv_bootp) {
403 kfree_s(recv_bootp, sizeof(struct bootp_pkt));
404 recv_bootp = NULL;
405 }
406 }
407
408
409
410
411
412 static inline int root_alloc_bootp(void)
413 {
414 if (!(xmit_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL)) ||
415 !(recv_bootp = kmalloc(sizeof(struct bootp_pkt), GFP_KERNEL))) {
416 printk("BOOTP: Out of memory!");
417 return -1;
418 }
419 return 0;
420 }
421
422
423
424
425
426 static int root_add_bootp_route(void)
427 {
428 struct rtentry route;
429
430 memset(&route, 0, sizeof(route));
431 route.rt_dev = bootp_dev->name;
432 route.rt_mss = bootp_dev->mtu;
433 route.rt_flags = RTF_UP;
434 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
435 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_family = AF_INET;
436 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
437 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_family = AF_INET;
438 if (ip_rt_new(&route)) {
439 printk(KERN_ERR "BOOTP: Adding of route failed!\n");
440 return -1;
441 }
442 bootp_have_route = 1;
443 return 0;
444 }
445
446
447
448
449
450 static int root_del_bootp_route(void)
451 {
452 struct rtentry route;
453
454 if (!bootp_have_route)
455 return 0;
456 memset(&route, 0, sizeof(route));
457 ((struct sockaddr_in *) &(route.rt_dst)) -> sin_addr.s_addr = 0;
458 ((struct sockaddr_in *) &(route.rt_genmask)) -> sin_addr.s_addr = 0;
459 if (ip_rt_kill(&route)) {
460 printk(KERN_ERR "BOOTP: Deleting of route failed!\n");
461 return -1;
462 }
463 bootp_have_route = 0;
464 return 0;
465 }
466
467
468
469
470
471 static int root_open_udp_sock(int *fd, struct socket **sock)
472 {
473 struct file *file;
474 struct inode *inode;
475
476 *fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
477 if (*fd >= 0) {
478 file = current->files->fd[*fd];
479 inode = file->f_inode;
480 *sock = &inode->u.socket_i;
481 return 0;
482 }
483
484 printk(KERN_ERR "BOOTP: Cannot open UDP socket!\n");
485 return -1;
486 }
487
488
489
490
491
492 static int root_connect_udp_sock(struct socket *sock, u32 addr, u16 port)
493 {
494 struct sockaddr_in sa;
495 int result;
496
497 sa.sin_family = AF_INET;
498 sa.sin_addr.s_addr = htonl(addr);
499 sa.sin_port = htons(port);
500 result = sock->ops->connect(sock, (struct sockaddr *) &sa, sizeof(sa), 0);
501 if (result < 0) {
502 printk(KERN_ERR "BOOTP: connect() failed\n");
503 return -1;
504 }
505 return 0;
506 }
507
508
509
510
511
512 static int root_bind_udp_sock(struct socket *sock, u32 addr, u16 port)
513 {
514 struct sockaddr_in sa;
515 int result;
516
517 sa.sin_family = AF_INET;
518 sa.sin_addr.s_addr = htonl(addr);
519 sa.sin_port = htons(port);
520 result = sock->ops->bind(sock, (struct sockaddr *) &sa, sizeof(sa));
521 if (result < 0) {
522 printk(KERN_ERR "BOOTP: bind() failed\n");
523 return -1;
524 }
525 return 0;
526 }
527
528
529
530
531
532 static inline int root_send_udp(struct socket *sock, void *buf, int size)
533 {
534 u32 oldfs;
535 int result;
536 struct msghdr msg;
537 struct iovec iov;
538
539 oldfs = get_fs();
540 set_fs(get_ds());
541 iov.iov_base = buf;
542 iov.iov_len = size;
543 msg.msg_name = NULL;
544 msg.msg_iov = &iov;
545 msg.msg_iovlen = 1;
546 msg.msg_accrights = NULL;
547 result = sock->ops->sendmsg(sock, &msg, size, 0, 0);
548 set_fs(oldfs);
549 return (result != size);
550 }
551
552
553
554
555
556 static inline int root_recv_udp(struct socket *sock, void *buf, int size)
557 {
558 u32 oldfs;
559 int result;
560 struct msghdr msg;
561 struct iovec iov;
562
563 oldfs = get_fs();
564 set_fs(get_ds());
565 iov.iov_base = buf;
566 iov.iov_len = size;
567 msg.msg_name = NULL;
568 msg.msg_iov = &iov;
569 msg.msg_iovlen = 1;
570 msg.msg_accrights = NULL;
571 msg.msg_namelen = 0;
572 result = sock->ops->recvmsg(sock, &msg, size, O_NONBLOCK, 0, &msg.msg_namelen);
573 set_fs(oldfs);
574 return result;
575 }
576
577
578
579
580
581 static void root_bootp_init_ext(u8 *e)
582 {
583 *e++ = 99;
584 *e++ = 130;
585 *e++ = 83;
586 *e++ = 99;
587 *e++ = 1;
588 *e++ = 4;
589 e += 4;
590 *e++ = 3;
591 *e++ = 4;
592 e += 4;
593 *e++ = 12;
594 *e++ = 32;
595 e += 32;
596 *e++ = 15;
597 *e++ = 32;
598 e += 32;
599 *e++ = 17;
600 *e++ = 32;
601 e += 32;
602 *e = 255;
603 }
604
605
606
607
608
609 static void root_bootp_close(void)
610 {
611 if (bootp_xmit_fd != -1)
612 sys_close(bootp_xmit_fd);
613 if (bootp_recv_fd != -1)
614 sys_close(bootp_recv_fd);
615 root_del_bootp_route();
616 root_free_bootp();
617 }
618
619
620
621
622
623 static int root_bootp_open(void)
624 {
625 struct open_dev *openp;
626 struct device *dev, *best_dev;
627
628
629
630
631
632
633
634
635 best_dev = NULL;
636 for (openp = open_base; openp != NULL; openp = openp->next) {
637 dev = openp->dev;
638 if (dev->flags & IFF_BROADCAST) {
639 if (!best_dev ||
640 ((best_dev->flags & IFF_NOARP) && !(dev->flags & IFF_NOARP)))
641 best_dev = dev;
642 }
643 }
644
645 if (!best_dev) {
646 printk(KERN_ERR "BOOTP: This cannot happen!\n");
647 return -1;
648 }
649 bootp_dev = best_dev;
650
651
652 if (root_alloc_bootp())
653 return -1;
654
655
656 memset(xmit_bootp, 0, sizeof(struct bootp_pkt));
657 xmit_bootp->op = BOOTP_REQUEST;
658 get_random_bytes(&xmit_bootp->xid, sizeof(xmit_bootp->xid));
659 xmit_bootp->htype = best_dev->type;
660 xmit_bootp->hlen = best_dev->addr_len;
661 memcpy(xmit_bootp->hw_addr, best_dev->dev_addr, best_dev->addr_len);
662 root_bootp_init_ext(xmit_bootp->vendor_area);
663 #ifdef NFSROOT_DEBUG
664 {
665 int x;
666 printk(KERN_NOTICE "BOOTP: XID=%08x, DE=%s, HT=%02x, HL=%02x, HA=",
667 xmit_bootp->xid,
668 best_dev->name,
669 xmit_bootp->htype,
670 xmit_bootp->hlen);
671 for(x=0; x<xmit_bootp->hlen; x++)
672 printk("%02x", xmit_bootp->hw_addr[x]);
673 printk("\n");
674 }
675 #endif
676
677
678 if (root_add_bootp_route())
679 return -1;
680
681
682 if (root_open_udp_sock(&bootp_xmit_fd, &bootp_xmit_sock) ||
683 root_open_udp_sock(&bootp_recv_fd, &bootp_recv_sock))
684 return -1;
685
686
687 ((struct sock *) bootp_xmit_sock->data) -> broadcast = 1;
688 ((struct sock *) bootp_xmit_sock->data) -> reuse = 1;
689 ((struct sock *) bootp_recv_sock->data) -> reuse = 1;
690 if (root_bind_udp_sock(bootp_recv_sock, INADDR_ANY, 68) ||
691 root_bind_udp_sock(bootp_xmit_sock, INADDR_ANY, 68) ||
692 root_connect_udp_sock(bootp_xmit_sock, INADDR_BROADCAST, 67))
693 return -1;
694
695 return 0;
696 }
697
698
699
700
701
702 static int root_bootp_send(u32 jiffies)
703 {
704 xmit_bootp->secs = htons(jiffies / HZ);
705 return root_send_udp(bootp_xmit_sock, xmit_bootp, sizeof(struct bootp_pkt));
706 }
707
708
709
710
711
712 static int root_bootp_string(char *dest, char *src, int len, int max)
713 {
714 if (*dest || !len)
715 return 0;
716 if (len > max-1)
717 len = max-1;
718 strncpy(dest, src, len);
719 dest[len] = '\0';
720 return 1;
721 }
722
723
724
725
726
727 static void root_do_bootp_ext(u8 *ext)
728 {
729 u8 *c;
730 static int got_bootp_domain = 0;
731
732 #ifdef NFSROOT_MORE_DEBUG
733 printk("BOOTP: Got extension %02x",*ext);
734 for(c=ext+2; c<ext+2+ext[1]; c++)
735 printk(" %02x", *c);
736 printk("\n");
737 #endif
738
739 switch (*ext++) {
740 case 1:
741 if (netmask.sin_addr.s_addr == INADDR_NONE)
742 memcpy(&netmask.sin_addr.s_addr, ext+1, 4);
743 break;
744 case 3:
745 if (gateway.sin_addr.s_addr == INADDR_NONE)
746 memcpy(&gateway.sin_addr.s_addr, ext+1, 4);
747 break;
748 case 12:
749 if (root_bootp_string(system_utsname.nodename, ext+1, *ext, __NEW_UTS_LEN)) {
750 c = strchr(system_utsname.nodename, '.');
751 if (c) {
752 *c++ = 0;
753 if (!system_utsname.domainname[0]) {
754 strcpy(system_utsname.domainname, c);
755 got_bootp_domain = 1;
756 }
757 }
758 }
759 break;
760 case 15:
761 if (got_bootp_domain && *ext && ext[1])
762 system_utsname.domainname[0] = '\0';
763 root_bootp_string(system_utsname.domainname, ext+1, *ext, __NEW_UTS_LEN);
764 break;
765 case 17:
766 root_bootp_string(nfs_path, ext+1, *ext, NFS_MAXPATHLEN);
767 break;
768 }
769 }
770
771
772
773
774
775 static void root_bootp_recv(void)
776 {
777 int len;
778 u8 *ext, *end, *opt;
779
780 len = root_recv_udp(bootp_recv_sock, recv_bootp, sizeof(struct bootp_pkt));
781 if (len < 0)
782 return;
783
784
785 if (len < 300 ||
786 recv_bootp->op != BOOTP_REPLY ||
787 recv_bootp->htype != xmit_bootp->htype ||
788 recv_bootp->hlen != xmit_bootp->hlen ||
789 recv_bootp->xid != xmit_bootp->xid) {
790 #ifdef NFSROOT_DEBUG
791 printk("?");
792 #endif
793 return;
794 }
795
796
797 cli();
798 if (pkt_arrived) {
799 sti();
800 return;
801 }
802 pkt_arrived = ARRIVED_BOOTP;
803 sti();
804 root_dev = bootp_dev;
805
806
807 myaddr.sin_addr.s_addr = recv_bootp->your_ip;
808 server.sin_addr.s_addr = recv_bootp->server_ip;
809
810
811 if (recv_bootp->vendor_area[0] == 99 &&
812 recv_bootp->vendor_area[1] == 130 &&
813 recv_bootp->vendor_area[2] == 83 &&
814 recv_bootp->vendor_area[3] == 99) {
815 ext = &recv_bootp->vendor_area[4];
816 end = (u8 *) recv_bootp + len;
817 while (ext < end && *ext != 255) {
818 if (*ext == 0)
819 ext++;
820 else {
821 opt = ext;
822 ext += ext[1] + 2;
823 if (ext <= end)
824 root_do_bootp_ext(opt);
825 }
826 }
827 }
828 }
829
830
831
832
833
834
835
836
837
838
839
840
841 static int root_auto_config(void)
842 {
843 int retries;
844 u32 timeout, jiff;
845 u32 start_jiffies;
846
847
848 if (bootp_flag && !bootp_dev_count) {
849 printk(KERN_ERR "BOOTP: No suitable device found.\n");
850 bootp_flag = 0;
851 }
852 if (rarp_flag && !rarp_dev_count) {
853 printk(KERN_ERR "RARP: No suitable device found.\n");
854 rarp_flag = 0;
855 }
856
857
858 if (!bootp_flag && !rarp_flag) {
859 #ifdef CONFIG_USE_BOOTP
860 if (bootp_dev_count)
861 bootp_flag = 1;
862 #endif
863 #ifdef CONFIG_USE_RARP
864 if (rarp_dev_count)
865 rarp_flag = 1;
866 #endif
867 if (!bootp_flag && !rarp_flag)
868 return -1;
869 }
870
871
872 if (rarp_flag)
873 root_rarp_open();
874 if (bootp_flag && root_bootp_open()) {
875 root_bootp_close();
876 return -1;
877 }
878
879
880
881
882
883
884
885
886
887 printk(KERN_NOTICE "Sending %s%s%s requests...",
888 bootp_flag ? "BOOTP" : "",
889 bootp_flag && rarp_flag ? " and " : "",
890 rarp_flag ? "RARP" : "");
891 start_jiffies = jiffies;
892 retries = CONF_RETRIES;
893 get_random_bytes(&timeout, sizeof(timeout));
894 timeout = CONF_BASE_TIMEOUT + (timeout % (unsigned) CONF_TIMEOUT_RANDOM);
895 for(;;) {
896 if (bootp_flag && root_bootp_send(jiffies - start_jiffies)) {
897 printk("...BOOTP failed!\n");
898 root_bootp_close();
899 bootp_flag = 0;
900 if (!rarp_flag)
901 break;
902 }
903 if (rarp_flag)
904 root_rarp_send();
905 printk(".");
906 jiff = jiffies + timeout;
907 while (jiffies < jiff && !pkt_arrived)
908 root_bootp_recv();
909 if (pkt_arrived)
910 break;
911 if (! --retries) {
912 printk("timed out!\n");
913 break;
914 }
915 timeout = timeout CONF_TIMEOUT_MULT;
916 if (timeout > CONF_TIMEOUT_MAX)
917 timeout = CONF_TIMEOUT_MAX;
918 }
919
920 if (rarp_flag)
921 root_rarp_close();
922 if (bootp_flag)
923 root_bootp_close();
924
925 if (!pkt_arrived)
926 return -1;
927
928 printk("OK\n");
929 printk(KERN_NOTICE "Root-NFS: Got %s answer from %s, ",
930 (pkt_arrived == ARRIVED_BOOTP) ? "BOOTP" : "RARP",
931 in_ntoa(server.sin_addr.s_addr));
932 printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
933
934 return 0;
935 }
936
937
938
939
940
941
942
943
944
945
946
947
948 static struct nfs_int_opts {
949 char *name;
950 int *val;
951 } root_int_opts[] = {
952 { "port", &nfs_port },
953 { "rsize", &nfs_data.rsize },
954 { "wsize", &nfs_data.wsize },
955 { "timeo", &nfs_data.timeo },
956 { "retrans", &nfs_data.retrans },
957 { "acregmin", &nfs_data.acregmin },
958 { "acregmax", &nfs_data.acregmax },
959 { "acdirmin", &nfs_data.acdirmin },
960 { "acdirmax", &nfs_data.acdirmax },
961 { NULL, NULL }
962 };
963
964
965
966
967
968 static struct nfs_bool_opts {
969 char *name;
970 int and_mask;
971 int or_mask;
972 } root_bool_opts[] = {
973 { "soft", ~NFS_MOUNT_SOFT, NFS_MOUNT_SOFT },
974 { "hard", ~NFS_MOUNT_SOFT, 0 },
975 { "intr", ~NFS_MOUNT_INTR, NFS_MOUNT_INTR },
976 { "nointr", ~NFS_MOUNT_INTR, 0 },
977 { "posix", ~NFS_MOUNT_POSIX, NFS_MOUNT_POSIX },
978 { "noposix", ~NFS_MOUNT_POSIX, 0 },
979 { "cto", ~NFS_MOUNT_NOCTO, 0 },
980 { "nocto", ~NFS_MOUNT_NOCTO, NFS_MOUNT_NOCTO },
981 { "ac", ~NFS_MOUNT_NOAC, 0 },
982 { "noac", ~NFS_MOUNT_NOAC, NFS_MOUNT_NOAC },
983 { NULL, 0, 0 }
984 };
985
986
987
988
989
990 static int root_nfs_parse(char *name)
991 {
992 char buf[NFS_MAXPATHLEN];
993 char *cp, *options, *val;
994
995
996 if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
997 *cp++ = '\0';
998 server.sin_addr.s_addr = in_aton(name);
999 name = cp;
1000 }
1001
1002
1003 cp = in_ntoa(server.sin_addr.s_addr);
1004 strncpy(nfs_data.hostname, cp, 255);
1005
1006
1007 cp = in_ntoa(myaddr.sin_addr.s_addr);
1008 strncpy(buf, name, 255);
1009 if ((options = strchr(buf, ',')))
1010 *options++ = '\0';
1011 if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
1012 printk(KERN_ERR "Root-NFS: Pathname for remote directory too long\n");
1013 return -1;
1014 }
1015 sprintf(nfs_path, buf, cp);
1016
1017
1018 nfs_port = -1;
1019 nfs_data.version = NFS_MOUNT_VERSION;
1020 nfs_data.flags = 0;
1021 nfs_data.rsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
1022 nfs_data.wsize = NFS_DEF_FILE_IO_BUFFER_SIZE;
1023 nfs_data.timeo = 7;
1024 nfs_data.retrans = 3;
1025 nfs_data.acregmin = 3;
1026 nfs_data.acregmax = 60;
1027 nfs_data.acdirmin = 30;
1028 nfs_data.acdirmax = 60;
1029
1030
1031 if (options) {
1032 cp = strtok(options, ",");
1033 while (cp) {
1034 if ((val = strchr(cp, '='))) {
1035 struct nfs_int_opts *opts = root_int_opts;
1036 *val++ = '\0';
1037 while (opts->name && strcmp(opts->name, cp))
1038 opts++;
1039 if (opts->name)
1040 *(opts->val) = (int) simple_strtoul(val, NULL, 10);
1041 } else {
1042 struct nfs_bool_opts *opts = root_bool_opts;
1043 while (opts->name && strcmp(opts->name, cp))
1044 opts++;
1045 if (opts->name) {
1046 nfs_data.flags &= opts->and_mask;
1047 nfs_data.flags |= opts->or_mask;
1048 }
1049 }
1050 cp = strtok(NULL, ",");
1051 }
1052 }
1053 return 0;
1054 }
1055
1056
1057
1058
1059
1060 #ifdef NFSROOT_DEBUG
1061 static void root_nfs_print(void)
1062 {
1063 printk(KERN_NOTICE "Root-NFS: IP config: dev=%s, ",
1064 root_dev ? root_dev->name : "none");
1065 printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1066 printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1067 printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1068 printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1069 printk("host=%s, domain=%s\n",
1070 system_utsname.nodename[0] ? system_utsname.nodename : "none",
1071 system_utsname.domainname[0] ? system_utsname.domainname : "none");
1072 printk(KERN_NOTICE "Root-NFS: Mounting %s on server %s as root\n",
1073 nfs_path, nfs_data.hostname);
1074 printk(KERN_NOTICE "Root-NFS: rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
1075 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
1076 printk(KERN_NOTICE "Root-NFS: acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
1077 nfs_data.acregmin, nfs_data.acregmax,
1078 nfs_data.acdirmin, nfs_data.acdirmax);
1079 printk(KERN_NOTICE "Root-NFS: port = %d, flags = %08x\n",
1080 nfs_port, nfs_data.flags);
1081 }
1082 #endif
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 static void root_nfs_ip_config(char *addrs)
1094 {
1095 char *cp, *ip, *dp;
1096 int num = 0;
1097
1098
1099 myaddr.sin_family = server.sin_family =
1100 gateway.sin_family = netmask.sin_family = AF_INET;
1101 myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
1102 gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
1103 system_utsname.nodename[0] = '\0';
1104 system_utsname.domainname[0] = '\0';
1105 user_dev_name[0] = '\0';
1106 bootp_flag = rarp_flag = 0;
1107
1108
1109 ip = addrs;
1110 while (ip && *ip && (*ip < '0' || *ip > '9')) {
1111 if ((cp = strchr(ip, ':')))
1112 *cp++ = '\0';
1113 if (*ip) {
1114 if (!strcmp(ip, "rarp"))
1115 rarp_flag = 1;
1116 else if (!strcmp(ip, "bootp"))
1117 bootp_flag = 1;
1118 else if (!user_dev_name[0]) {
1119 strncpy(user_dev_name, ip, IFNAMSIZ);
1120 user_dev_name[IFNAMSIZ-1] = '\0';
1121 }
1122 }
1123 ip = cp;
1124 }
1125
1126
1127 while (ip && *ip) {
1128 if ((cp = strchr(ip, ':')))
1129 *cp++ = '\0';
1130 if (strlen(ip) > 0) {
1131 switch (num) {
1132 case 0:
1133 myaddr.sin_addr.s_addr = in_aton(ip);
1134 break;
1135 case 1:
1136 server.sin_addr.s_addr = in_aton(ip);
1137 break;
1138 case 2:
1139 gateway.sin_addr.s_addr = in_aton(ip);
1140 break;
1141 case 3:
1142 netmask.sin_addr.s_addr = in_aton(ip);
1143 break;
1144 case 4:
1145 if ((dp = strchr(ip, '.'))) {
1146 *dp++ = '\0';
1147 strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
1148 system_utsname.domainname[__NEW_UTS_LEN] = '\0';
1149 }
1150 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
1151 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1152 break;
1153 default:
1154 break;
1155 }
1156 }
1157 ip = cp;
1158 num++;
1159 }
1160 #ifdef NFSROOT_DEBUG
1161 printk(KERN_NOTICE "Root-NFS: IP options: dev=%s, RARP=%d, BOOTP=%d, ",
1162 user_dev_name[0] ? user_dev_name : "none",
1163 rarp_flag,
1164 bootp_flag);
1165 printk("local=%s, ", IN_NTOA(myaddr.sin_addr.s_addr));
1166 printk("server=%s, ", IN_NTOA(server.sin_addr.s_addr));
1167 printk("gw=%s, ", IN_NTOA(gateway.sin_addr.s_addr));
1168 printk("mask=%s, ", IN_NTOA(netmask.sin_addr.s_addr));
1169 printk("host=%s, domain=%s\n",
1170 system_utsname.nodename[0] ? system_utsname.nodename : "none",
1171 system_utsname.domainname[0] ? system_utsname.domainname : "none");
1172 #endif
1173 }
1174
1175
1176
1177
1178
1179 static int root_nfs_setup(void)
1180 {
1181 struct rtentry route;
1182
1183
1184 if (!system_utsname.nodename[0]) {
1185 strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
1186 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
1187 }
1188
1189
1190 if (netmask.sin_addr.s_addr == INADDR_NONE)
1191 netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
1192
1193
1194 root_dev->family = myaddr.sin_family;
1195 root_dev->pa_addr = myaddr.sin_addr.s_addr;
1196 root_dev->pa_mask = netmask.sin_addr.s_addr;
1197 root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
1198 root_dev->pa_dstaddr = 0;
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 memset(&route, 0, sizeof(route));
1209 route.rt_dev = root_dev->name;
1210 route.rt_mss = root_dev->mtu;
1211 route.rt_flags = RTF_UP;
1212 *((struct sockaddr_in *) &(route.rt_dst)) = myaddr;
1213 (((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr &= netmask.sin_addr.s_addr;
1214 *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
1215 if (ip_rt_new(&route)) {
1216 printk(KERN_ERR "Root-NFS: Adding of local route failed!\n");
1217 return -1;
1218 }
1219
1220 if (gateway.sin_addr.s_addr != INADDR_NONE) {
1221 (((struct sockaddr_in *) &(route.rt_dst))) -> sin_addr.s_addr = 0;
1222 (((struct sockaddr_in *) &(route.rt_genmask))) -> sin_addr.s_addr = 0;
1223 *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
1224 route.rt_flags |= RTF_GATEWAY;
1225 if ((gateway.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1226 printk(KERN_ERR "Root-NFS: Gateway not on local network!\n");
1227 return -1;
1228 }
1229 if (ip_rt_new(&route)) {
1230 printk(KERN_ERR "Root-NFS: Adding of default route failed!\n");
1231 return -1;
1232 }
1233 } else if ((server.sin_addr.s_addr ^ myaddr.sin_addr.s_addr) & netmask.sin_addr.s_addr) {
1234 printk(KERN_ERR "Root-NFS: Boot server not on local network and no default gateway configured!\n");
1235 return -1;
1236 }
1237
1238 return 0;
1239 }
1240
1241
1242
1243
1244
1245
1246 int nfs_root_init(char *nfsname, char *nfsaddrs)
1247 {
1248
1249
1250
1251
1252 root_nfs_ip_config(nfsaddrs);
1253
1254
1255 if (root_nfs_parse(nfsname))
1256 return -1;
1257
1258
1259 if (root_dev_open() < 0)
1260 return -1;
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274 if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
1275 server.sin_addr.s_addr == INADDR_NONE ||
1276 (open_base != NULL && open_base->next != NULL)) &&
1277 root_auto_config() < 0) {
1278 root_dev_close();
1279 return -1;
1280 }
1281 if (root_dev == NULL) {
1282 if (open_base != NULL && open_base->next == NULL) {
1283 root_dev = open_base->dev;
1284 } else {
1285
1286 printk(KERN_ERR "Root-NFS: 1 == 0!\n");
1287 root_dev_close();
1288 return -1;
1289 }
1290 }
1291
1292
1293
1294
1295 root_dev_close();
1296
1297
1298 if (root_nfs_setup())
1299 return -1;
1300
1301 #ifdef NFSROOT_DEBUG
1302 root_nfs_print();
1303 #endif
1304
1305 return 0;
1306 }
1307
1308
1309
1310
1311
1312
1313
1314
1315 static struct file nfs_file;
1316 static struct inode nfs_inode;
1317 static int *rpc_packet = NULL;
1318
1319
1320
1321
1322
1323 static int root_nfs_open(void)
1324 {
1325 struct file *filp;
1326
1327
1328 if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
1329 printk(KERN_ERR "Root-NFS: Cannot open UDP socket!\n");
1330 return -1;
1331 }
1332
1333
1334
1335
1336
1337
1338 filp = current->files->fd[nfs_data.fd];
1339 memcpy(&nfs_file, filp, sizeof(struct file));
1340 nfs_file.f_next = nfs_file.f_prev = NULL;
1341 current->files->fd[nfs_data.fd] = &nfs_file;
1342 filp->f_count = 0;
1343
1344 memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
1345 nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
1346 nfs_inode.i_next = nfs_inode.i_prev = NULL;
1347 clear_inode(nfs_file.f_inode);
1348 nfs_file.f_inode = &nfs_inode;
1349 nfs_inode.u.socket_i.inode = &nfs_inode;
1350 nfs_file.private_data = NULL;
1351
1352 return 0;
1353 }
1354
1355
1356
1357
1358
1359
1360
1361 static void root_nfs_close(int close_all)
1362 {
1363
1364 current->files->fd[nfs_data.fd] = NULL;
1365 if (current->files->count > 0)
1366 current->files->count--;
1367
1368
1369 if (rpc_packet != NULL)
1370 kfree_s(rpc_packet, nfs_data.wsize + 1024);
1371
1372
1373
1374
1375
1376 if (close_all) {
1377 nfs_inode.u.socket_i.inode = NULL;
1378
1379 if (nfs_file.f_op->release)
1380 nfs_file.f_op->release(&nfs_inode, &nfs_file);
1381 }
1382 }
1383
1384
1385
1386
1387
1388 static int root_nfs_bind(void)
1389 {
1390 int res = -1;
1391 short port = STARTPORT;
1392 struct sockaddr_in *sin = &myaddr;
1393 int i;
1394
1395 if (nfs_inode.u.socket_i.ops->bind) {
1396 for (i = 0; i < NPORTS && res < 0; i++) {
1397 sin->sin_port = htons(port++);
1398 if (port > ENDPORT) {
1399 port = STARTPORT;
1400 }
1401 res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
1402 (struct sockaddr *)sin, sizeof(struct sockaddr_in));
1403 }
1404 }
1405 if (res < 0) {
1406 printk(KERN_ERR "Root-NFS: Cannot find a suitable listening port\n");
1407 root_nfs_close(1);
1408 return -1;
1409 }
1410 #ifdef NFSROOT_DEBUG
1411 printk(KERN_NOTICE "Root-NFS: Binding to listening port %d\n", port);
1412 #endif
1413 return 0;
1414 }
1415
1416
1417
1418
1419
1420 static int *root_nfs_call(int *end)
1421 {
1422 struct file *filp;
1423 struct socket *sock;
1424 int dummylen;
1425 static struct nfs_server s = {
1426 &nfs_file,
1427 0,
1428 {
1429 0, "",
1430 },
1431 0,
1432 NULL,
1433 NFS_MOUNT_SOFT,
1434 0, 0,
1435 0,
1436 0,
1437 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
1438 };
1439
1440 filp = &nfs_file;
1441 sock = &((filp->f_inode)->u.socket_i);
1442
1443
1444 sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
1445 ((struct sockaddr_in *) &s.toaddr)->sin_port = server.sin_port;
1446 ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
1447 ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
1448
1449 s.rsock = rpc_makesock(filp);
1450 s.flags = nfs_data.flags;
1451 s.rsize = nfs_data.rsize;
1452 s.wsize = nfs_data.wsize;
1453 s.timeo = nfs_data.timeo * HZ / 10;
1454 s.retrans = nfs_data.retrans;
1455 strcpy(s.hostname, nfs_data.hostname);
1456
1457
1458
1459
1460
1461 if (nfs_inode.u.socket_i.ops->connect &&
1462 nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
1463 (struct sockaddr *) &server,
1464 sizeof(struct sockaddr_in),
1465 nfs_file.f_flags) < 0)
1466 return NULL;
1467 if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
1468 return NULL;
1469 return rpc_verify(rpc_packet);
1470 }
1471
1472
1473
1474
1475
1476 static int *root_nfs_header(int proc, int program, int version)
1477 {
1478 int groups[] = { 0, NOGROUP };
1479
1480 if (rpc_packet == NULL) {
1481 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
1482 printk(KERN_ERR "Root-NFS: Cannot allocate UDP buffer\n");
1483 return NULL;
1484 }
1485 }
1486 return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
1487 }
1488
1489
1490
1491
1492
1493 static int root_nfs_get_port(int program, int version)
1494 {
1495 int *p;
1496
1497
1498 server.sin_port = htons(NFS_PMAP_PORT);
1499 p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
1500 if (!p)
1501 return -1;
1502
1503
1504 *p++ = htonl(program);
1505 *p++ = htonl(version);
1506 *p++ = htonl(IPPROTO_UDP);
1507 *p++ = 0;
1508
1509
1510 if ((p = root_nfs_call(p)) == NULL)
1511 return -1;
1512
1513 return ntohl(*p);
1514 }
1515
1516
1517
1518
1519
1520 static int root_nfs_ports(void)
1521 {
1522 int port;
1523
1524 if (nfs_port < 0) {
1525 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
1526 printk(KERN_ERR "Root-NFS: Unable to get nfsd port number from server, using default\n");
1527 port = NFS_NFS_PORT;
1528 }
1529 nfs_port = port;
1530 #ifdef NFSROOT_DEBUG
1531 printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as nfsd port\n", port);
1532 #endif
1533 }
1534 if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
1535 printk(KERN_ERR "Root-NFS: Unable to get mountd port number from server, using default\n");
1536 port = NFS_MOUNT_PORT;
1537 }
1538 server.sin_port = htons(port);
1539 #ifdef NFSROOT_DEBUG
1540 printk(KERN_NOTICE "Root-NFS: Portmapper on server returned %d as mountd port\n", port);
1541 #endif
1542
1543 return 0;
1544 }
1545
1546
1547
1548
1549
1550
1551 static int root_nfs_get_handle(void)
1552 {
1553 int len, status, *p;
1554
1555
1556 p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
1557 if (!p) {
1558 root_nfs_close(1);
1559 return -1;
1560 }
1561
1562 len = strlen(nfs_path);
1563 *p++ = htonl(len);
1564 memcpy(p, nfs_path, len);
1565 len = (len + 3) >> 2;
1566 p[len] = 0;
1567 p += len;
1568
1569
1570 if ((p = root_nfs_call(p)) == NULL) {
1571 root_nfs_close(1);
1572 return -1;
1573 }
1574 status = ntohl(*p++);
1575 if (status == 0) {
1576 nfs_data.root = *((struct nfs_fh *) p);
1577 printk(KERN_NOTICE "Root-NFS: Got file handle for %s via RPC\n", nfs_path);
1578 } else {
1579 printk(KERN_ERR "Root-NFS: Server returned error %d while mounting %s\n",
1580 status, nfs_path);
1581 root_nfs_close(1);
1582 return -1;
1583 }
1584
1585 return 0;
1586 }
1587
1588
1589
1590
1591
1592 static int root_nfs_do_mount(struct super_block *sb)
1593 {
1594
1595 server.sin_port = htons(nfs_port);
1596 nfs_data.addr = server;
1597 if (nfs_inode.u.socket_i.ops->connect &&
1598 nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
1599 (struct sockaddr *) &server,
1600 sizeof(struct sockaddr_in),
1601 nfs_file.f_flags) < 0) {
1602 root_nfs_close(1);
1603 return -1;
1604 }
1605
1606 if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
1607 root_nfs_close(1);
1608 return -1;
1609 }
1610 return 0;
1611 }
1612
1613
1614
1615
1616
1617
1618 int nfs_root_mount(struct super_block *sb)
1619 {
1620 if (root_nfs_open() < 0)
1621 return -1;
1622 if (root_nfs_bind() < 0)
1623 return -1;
1624 if (root_nfs_ports() < 0)
1625 return -1;
1626 if (root_nfs_get_handle() < 0)
1627 return -1;
1628 if (root_nfs_do_mount(sb) < 0)
1629 return -1;
1630 root_nfs_close(0);
1631 return 0;
1632 }