root/fs/nfs/nfsroot.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. root_dev_open
  2. root_dev_close
  3. root_rarp_open
  4. root_rarp_close
  5. root_rarp_recv
  6. root_rarp_send
  7. do_rarp
  8. root_nfs_parse
  9. root_nfs_print
  10. root_nfs_addrs
  11. root_nfs_setup
  12. nfs_root_init
  13. root_nfs_open
  14. root_nfs_close
  15. root_nfs_bind
  16. root_nfs_call
  17. root_nfs_header
  18. root_nfs_get_port
  19. root_nfs_ports
  20. root_nfs_get_handle
  21. root_nfs_do_mount
  22. nfs_root_mount

   1 /*
   2  *  linux/fs/nfs/nfsroot.c
   3  *
   4  *  Copyright (C) 1995  Gero Kuhlmann <gero@gkminix.han.de>
   5  *
   6  *  Allow an NFS filesystem to be mounted as root. The way this works
   7  *  is to first determine the local IP address via RARP. Then handle
   8  *  the RPC negotiation with the system which replied to the RARP. The
   9  *  actual mounting is done later, when init() is running. In addition
  10  *  it's possible to avoid using RARP if the necessary addresses are
  11  *  provided on the kernel command line. This is necessary to use boot-
  12  *  roms which use bootp instead of RARP.
  13  *
  14  *      Changes:
  15  *
  16  *      Alan Cox        :       Removed get_address name clash with FPU.
  17  *      Alan Cox        :       Reformatted a bit.
  18  *
  19  */
  20 
  21 
  22 /* Define this to allow debugging output */
  23 #undef NFSROOT_DEBUG 1
  24 
  25 /* Define the timeout for waiting for a RARP reply */
  26 #define RARP_TIMEOUT    30      /* 30 seconds */
  27 #define RARP_RETRIES     5      /* 5 retries */
  28 
  29 #include <linux/config.h>
  30 #include <linux/types.h>
  31 #include <linux/string.h>
  32 #include <linux/kernel.h>
  33 #include <linux/sched.h>
  34 #include <linux/fs.h>
  35 
  36 #include <asm/param.h>
  37 #include <linux/utsname.h>
  38 #include <linux/in.h>
  39 #include <linux/if.h>
  40 #include <linux/inet.h>
  41 #include <linux/net.h>
  42 #include <linux/if_arp.h>
  43 #include <linux/netdevice.h>
  44 #ifdef CONFIG_AX25
  45 #include <net/ax25.h>   /* For AX25_P_IP */
  46 #endif
  47 #include <linux/skbuff.h>
  48 #include <linux/socket.h>
  49 #include <linux/route.h>
  50 #include <linux/nfs.h>
  51 #include <linux/nfs_fs.h>
  52 #include <linux/nfs_mount.h>
  53 #include <linux/in.h>
  54 #include <net/route.h>
  55 
  56 
  57 /* Range of privileged ports */
  58 #define STARTPORT       600
  59 #define ENDPORT         1023
  60 #define NPORTS          (ENDPORT - STARTPORT + 1)
  61 
  62 
  63 
  64 struct open_dev {
  65         struct device *dev;
  66         unsigned short old_flags;
  67         struct open_dev *next;
  68 };
  69 
  70 static struct open_dev *open_base = NULL;
  71 static struct device *root_dev = NULL;
  72 static struct sockaddr_in myaddr;       /* My IP address */
  73 static struct sockaddr_in server;       /* Server IP address */
  74 static struct sockaddr_in gateway;      /* Gateway IP address */
  75 static struct sockaddr_in netmask;      /* Netmask for local subnet */
  76 static struct nfs_mount_data nfs_data;  /* NFS mount info */
  77 static char nfs_path[NFS_MAXPATHLEN];   /* Name of directory to mount */
  78 static int nfs_port;                    /* Port to connect to for NFS service */
  79 
  80 
  81 
  82 /***************************************************************************
  83 
  84                         Device Handling Subroutines
  85 
  86  ***************************************************************************/
  87 
  88 /*
  89  * Setup and initialize all network devices
  90  */
  91 static int root_dev_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93         struct open_dev *openp;
  94         struct device *dev;
  95         unsigned short old_flags;
  96         int num = 0;
  97 
  98         for (dev = dev_base; dev != NULL; dev = dev->next) {
  99                 if (dev->type < ARPHRD_SLIP &&
 100                     dev->family == AF_INET &&
 101                     !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
 102                         /* First up the interface */
 103                         old_flags = dev->flags;
 104                         dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
 105                         if (!(old_flags & IFF_UP) && dev_open(dev)) {
 106                                 dev->flags = old_flags;
 107                                 continue;
 108                         }
 109                         openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 110                                                 GFP_ATOMIC);
 111                         if (openp == NULL)
 112                                 continue;
 113                         openp->dev = dev;
 114                         openp->old_flags = old_flags;
 115                         openp->next = open_base;
 116                         open_base = openp;
 117                         num++;
 118                 }
 119         }
 120 
 121         if (num == 0) {
 122                 printk(KERN_ERR "NFS: Unable to open at least one network device\n");
 123                 return -1;
 124         }
 125 #ifdef NFSROOT_DEBUG
 126         printk(KERN_NOTICE "NFS: Opened %d network interfaces\n", num);
 127 #endif
 128         return 0;
 129 }
 130 
 131 
 132 /*
 133  *  Restore the state of all devices. However, keep the root device open
 134  *  for the upcoming mount.
 135  */
 136 static void root_dev_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 137 {
 138         struct open_dev *openp;
 139         struct open_dev *nextp;
 140 
 141         openp = open_base;
 142         while (openp != NULL) {
 143                 nextp = openp->next;
 144                 openp->next = NULL;
 145                 if (openp->dev != root_dev) {
 146                         if (!(openp->old_flags & IFF_UP))
 147                                 dev_close(openp->dev);
 148                         openp->dev->flags = openp->old_flags;
 149                 }
 150                 kfree_s(openp, sizeof(struct open_dev));
 151                 openp = nextp;
 152         }
 153 }
 154 
 155 
 156 
 157 
 158 /***************************************************************************
 159 
 160                         RARP Subroutines
 161 
 162  ***************************************************************************/
 163 
 164 extern void arp_send(int type, int ptype, unsigned long target_ip,
 165                      struct device *dev, unsigned long src_ip,
 166                      unsigned char *dest_hw, unsigned char *src_hw,
 167                      unsigned char *target_hw);
 168 
 169 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
 170                           struct packet_type *pt);
 171 
 172 
 173 static struct packet_type rarp_packet_type = {
 174         0,                      /* Should be: __constant_htons(ETH_P_RARP)
 175                                  * - but this _doesn't_ come out constant! */
 176         NULL,                   /* Listen to all devices */
 177         root_rarp_recv,
 178         NULL,
 179         NULL
 180 };
 181 
 182 
 183 /*
 184  *  Register the packet type for RARP
 185  */
 186 static void root_rarp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         rarp_packet_type.type = htons(ETH_P_RARP);
 189         dev_add_pack(&rarp_packet_type);
 190 }
 191 
 192 
 193 /*
 194  *  Deregister the RARP packet type
 195  */
 196 static void root_rarp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 197 {
 198         rarp_packet_type.type = htons(ETH_P_RARP);
 199         dev_remove_pack(&rarp_packet_type);
 200 }
 201 
 202 
 203 /*
 204  *  Receive RARP packets.
 205  */
 206 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208         struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 209         unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 210         unsigned long sip, tip;
 211         unsigned char *sha, *tha;               /* s for "source", t for "target" */
 212 
 213         /* If this test doesn't pass, its not IP, or we should ignore it anyway */
 214         if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
 215                 kfree_skb(skb, FREE_READ);
 216                 return 0;
 217         }
 218 
 219         /* If it's not a RARP reply, delete it. */
 220         if (rarp->ar_op != htons(ARPOP_RREPLY)) {
 221                 kfree_skb(skb, FREE_READ);
 222                 return 0;
 223         }
 224 
 225         /* If it's not ethernet or AX25, delete it. */
 226         if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
 227 #ifdef CONFIG_AX25
 228            (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 229 #endif
 230             rarp->ar_pln != 4) {
 231                 kfree_skb(skb, FREE_READ);
 232                 return 0;
 233         }
 234 
 235         /* Extract variable width fields */
 236         sha = rarp_ptr;
 237         rarp_ptr += dev->addr_len;
 238         memcpy(&sip, rarp_ptr, 4);
 239         rarp_ptr += 4;
 240         tha = rarp_ptr;
 241         rarp_ptr += dev->addr_len;
 242         memcpy(&tip, rarp_ptr, 4);
 243 
 244         /* Discard packets which are not meant for us. */
 245         if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
 246                 kfree_skb(skb, FREE_READ);
 247                 return 0;
 248         }
 249         /* Discard packets which are not from specified server. */
 250         if (server.sin_addr.s_addr != INADDR_NONE &&
 251             server.sin_addr.s_addr != sip) {
 252                 kfree_skb(skb, FREE_READ);
 253                 return 0;
 254         }
 255 
 256         /*
 257          * The packet is what we were looking for. Setup the global
 258          * variables.
 259          */
 260         cli();
 261         if (root_dev != NULL) {
 262                 sti();
 263                 kfree_skb(skb, FREE_READ);
 264                 return 0;
 265         }
 266         root_dev = dev;
 267         sti();
 268 
 269         if (myaddr.sin_addr.s_addr == INADDR_NONE) {
 270                 myaddr.sin_family = dev->family;
 271                 myaddr.sin_addr.s_addr = tip;
 272         }
 273         if (server.sin_addr.s_addr == INADDR_NONE) {
 274                 server.sin_family = dev->family;
 275                 server.sin_addr.s_addr = sip;
 276         }
 277         kfree_skb(skb, FREE_READ);
 278         return 0;
 279 }
 280 
 281 
 282 /*
 283  *  Send RARP request packet over all devices which allow RARP.
 284  */
 285 static int root_rarp_send(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 286 {
 287         struct open_dev *openp;
 288         struct device *dev;
 289         int num = 0;
 290 
 291 #ifdef NFSROOT_DEBUG
 292         printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 293 #endif
 294 
 295         for (openp = open_base; openp != NULL; openp = openp->next) {
 296                 dev = openp->dev;
 297                 if (!(dev->flags & IFF_NOARP)) {
 298                         arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 299                                  dev->dev_addr, dev->dev_addr);
 300                         num++;
 301                 }
 302         }
 303 
 304         if (num == 0) {
 305                 printk(KERN_ERR "NFS: Couldn't find device to send RARP request to\n");
 306                 return -1;
 307         }
 308         return 0;
 309 }
 310 
 311 
 312 /*
 313  *  Determine client and server IP numbers and appropriate device by using
 314  *  the RARP protocol.
 315  */
 316 static int do_rarp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 317 {
 318         int retries = 0;
 319         unsigned long timeout = 0;
 320 
 321         /* Setup RARP protocol */
 322         root_rarp_open();
 323 
 324         /*
 325          * Send RARP request and wait, until we get an answer. This loop
 326          * seems to be a terrible waste of cpu time, but actually there is
 327          * no process running at all, so we don't need to use any
 328          * scheduler functions.
 329          * [Actually we could now, but the nothing else running note still 
 330          *  applies.. - AC]
 331          */
 332         for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) {
 333                 if (root_rarp_send() < 0)
 334                         break;
 335                 timeout = jiffies + (RARP_TIMEOUT * HZ);
 336                 while (jiffies < timeout && root_dev == NULL)
 337                         ;;
 338         }
 339 
 340         root_rarp_close();
 341         if (root_dev == NULL && timeout > 0) {
 342                 printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
 343                 return -1;
 344         }
 345         printk(KERN_NOTICE "NFS: ");
 346         printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
 347         printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 348 
 349         return 0;
 350 }
 351 
 352 
 353 
 354 
 355 /***************************************************************************
 356 
 357                         Routines to setup NFS
 358 
 359  ***************************************************************************/
 360 
 361 
 362 
 363 /*
 364  *  The following integer options are recognized
 365  */
 366 static struct nfs_int_opts {
 367         char *name;
 368         int  *val;
 369 } root_int_opts[] = {
 370         { "port",       &nfs_port },
 371         { "rsize",      &nfs_data.rsize },
 372         { "wsize",      &nfs_data.wsize },
 373         { "timeo",      &nfs_data.timeo },
 374         { "retrans",    &nfs_data.retrans },
 375         { "acregmin",   &nfs_data.acregmin },
 376         { "acregmax",   &nfs_data.acregmax },
 377         { "acdirmin",   &nfs_data.acdirmin },
 378         { "acdirmax",   &nfs_data.acdirmax },
 379         { NULL,         NULL }
 380 };
 381 
 382 
 383 /*
 384  *  And now the flag options
 385  */
 386 static struct nfs_bool_opts {
 387         char *name;
 388         int  and_mask;
 389         int  or_mask;
 390 } root_bool_opts[] = {
 391         { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
 392         { "hard",       ~NFS_MOUNT_SOFT,        0 },
 393         { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
 394         { "nointr",     ~NFS_MOUNT_INTR,        0 },
 395         { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
 396         { "noposix",    ~NFS_MOUNT_POSIX,       0 },
 397         { "cto",        ~NFS_MOUNT_NOCTO,       0 },
 398         { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
 399         { "ac",         ~NFS_MOUNT_NOAC,        0 },
 400         { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
 401         { NULL,         0,                      0 }
 402 };
 403 
 404 
 405 /*
 406  *  Prepare the NFS data structure and parse any options
 407  */
 408 static int root_nfs_parse(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410         char buf[NFS_MAXPATHLEN];
 411         char *cp, *options, *val;
 412 
 413         /* Set the default system name in case none was previously found */
 414         if (!system_utsname.nodename[0]) {
 415                 strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
 416                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 417         }
 418         /* It is possible to override the host IP number here */
 419         if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
 420                 *cp++ = '\0';
 421                 server.sin_addr.s_addr = in_aton(name);
 422                 name = cp;
 423         }
 424 
 425         /* Setup the server hostname */
 426         cp = in_ntoa(server.sin_addr.s_addr);
 427         strncpy(nfs_data.hostname, cp, 255);
 428 
 429         /* Set the name of the directory to mount */
 430         cp = in_ntoa(myaddr.sin_addr.s_addr);
 431         strncpy(buf, name, 255);
 432         if ((options = strchr(buf, ',')))
 433                 *options++ = '\0';
 434         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
 435                 printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
 436                 return -1;
 437         }
 438         sprintf(nfs_path, buf, cp);
 439 
 440         /* Set some default values */
 441         nfs_port          = -1;
 442         nfs_data.version  = NFS_MOUNT_VERSION;
 443         nfs_data.flags    = 0;
 444         nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 445         nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 446         nfs_data.timeo    = 7;
 447         nfs_data.retrans  = 3;
 448         nfs_data.acregmin = 3;
 449         nfs_data.acregmax = 60;
 450         nfs_data.acdirmin = 30;
 451         nfs_data.acdirmax = 60;
 452 
 453         /* Process any options */
 454         if (options) {
 455                 cp = strtok(options, ",");
 456                 while (cp) {
 457                         if ((val = strchr(cp, '='))) {
 458                                 struct nfs_int_opts *opts = root_int_opts;
 459                                 *val++ = '\0';
 460                                 while (opts->name && strcmp(opts->name, cp))
 461                                         opts++;
 462                                 if (opts->name)
 463                                         *(opts->val) = (int) simple_strtoul(val, NULL, 10);
 464                         } else {
 465                                 struct nfs_bool_opts *opts = root_bool_opts;
 466                                 while (opts->name && strcmp(opts->name, cp))
 467                                         opts++;
 468                                 if (opts->name) {
 469                                         nfs_data.flags &= opts->and_mask;
 470                                         nfs_data.flags |= opts->or_mask;
 471                                 }
 472                         }
 473                         cp = strtok(NULL, ",");
 474                 }
 475         }
 476         return 0;
 477 }
 478 
 479 
 480 /*
 481  *  Tell the user what's going on.
 482  */
 483 static void root_nfs_print(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 484 {
 485 #ifdef NFSROOT_DEBUG
 486         printk(KERN_NOTICE "NFS: Mounting %s on server %s as root\n",
 487                 nfs_path, nfs_data.hostname);
 488         printk(KERN_NOTICE "NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
 489                 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
 490         printk(KERN_NOTICE "NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
 491                 nfs_data.acregmin, nfs_data.acregmax,
 492                 nfs_data.acdirmin, nfs_data.acdirmax);
 493         printk(KERN_NOTICE "NFS:     port = %d, flags = %08x\n",
 494                 nfs_port, nfs_data.flags);
 495 #endif
 496 }
 497 
 498 
 499 /*
 500  *  Parse any IP addresses
 501  */
 502 static void root_nfs_addrs(char *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 503 {
 504         char *cp, *ip, *dp;
 505         int num = 0;
 506 
 507         /* Clear all addresses and strings */
 508         myaddr.sin_family = server.sin_family =
 509             gateway.sin_family = netmask.sin_family = AF_INET;
 510         myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
 511             gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
 512         system_utsname.nodename[0] = '\0';
 513         system_utsname.domainname[0] = '\0';
 514 
 515         /*
 516          * Parse the address field. It contains 4 IP addresses which are
 517          * separated by colons: Field 0 = my own address Field 1 = server
 518          * address Field 2 = gateway address Field 3 = netmask address
 519          * Field 4 = client host name
 520          */
 521         ip = addrs;
 522         while (ip && *ip) {
 523                 if ((cp = strchr(ip, ':')))
 524                         *cp++ = '\0';
 525                 if (strlen(ip) > 0) {
 526 #ifdef NFSROOT_DEBUG
 527                         printk(KERN_NOTICE "NFS: IP address num %d is \"%s\"\n", num, ip);
 528 #endif
 529                         switch (num) {
 530                         case 0:
 531                                 myaddr.sin_addr.s_addr = in_aton(ip);
 532                                 break;
 533                         case 1:
 534                                 server.sin_addr.s_addr = in_aton(ip);
 535                                 break;
 536                         case 2:
 537                                 gateway.sin_addr.s_addr = in_aton(ip);
 538                                 break;
 539                         case 3:
 540                                 netmask.sin_addr.s_addr = in_aton(ip);
 541                                 break;
 542                         case 4:
 543                                 if ((dp = strchr(ip, '.'))) {
 544                                         *dp++ = '\0';
 545                                         strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
 546                                         system_utsname.domainname[__NEW_UTS_LEN] = '\0';
 547                                 }
 548                                 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
 549                                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 550                                 break;
 551                         default:
 552                                 break;
 553                         }
 554                 }
 555                 ip = cp;
 556                 num++;
 557         }
 558 }
 559 
 560 
 561 /*
 562  *  Set the interface address and configure a route to the server.
 563  */
 564 static void root_nfs_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 565 {
 566         struct rtentry route;
 567 
 568         /* Set the correct netmask */
 569         if (netmask.sin_addr.s_addr == INADDR_NONE)
 570                 netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
 571 
 572         /* Setup the device correctly */
 573         root_dev->family     = myaddr.sin_family;
 574         root_dev->pa_addr    = myaddr.sin_addr.s_addr;
 575         root_dev->pa_mask    = netmask.sin_addr.s_addr;
 576         root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
 577         root_dev->pa_dstaddr = 0;
 578 
 579         /*
 580          * Now add a route to the server. If there is no gateway given,
 581          * the server is on our own local network, so a host route is
 582          * sufficient. Otherwise we first have to create a host route to
 583          * the gateway, and then setup a gatewayed host route to the
 584          * server. Note that it's not possible to setup a network route
 585          * because we don't know the network mask of the server network.
 586          */
 587         memset(&route, 0, sizeof(route));
 588         route.rt_dev = root_dev->name;
 589         route.rt_mss = root_dev->mtu;
 590         route.rt_flags = RTF_HOST | RTF_UP;
 591         *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
 592 
 593         if (gateway.sin_addr.s_addr == INADDR_NONE ||
 594             gateway.sin_addr.s_addr == server.sin_addr.s_addr ||
 595             !((server.sin_addr.s_addr ^ root_dev->pa_addr) & root_dev->pa_mask)) {
 596                 *((struct sockaddr_in *) &(route.rt_dst)) = server;
 597                 ip_rt_new(&route);
 598         } else {
 599                 *((struct sockaddr_in *) &(route.rt_dst)) = gateway;
 600                 ip_rt_new(&route);
 601                 route.rt_flags |= RTF_GATEWAY;
 602                 *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
 603                 *((struct sockaddr_in *) &(route.rt_dst)) = server;
 604                 ip_rt_new(&route);
 605         }
 606 }
 607 
 608 
 609 /*
 610  *  Get the necessary IP addresses and prepare for mounting the required
 611  *  NFS filesystem.
 612  */
 613 int nfs_root_init(char *nfsname, char *nfsaddrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 614 {
 615         /* Setup all network devices */
 616         if (root_dev_open() < 0)
 617                 return -1;
 618 
 619         /*
 620          * Get local and server IP address. First check for addresses in
 621          * command line parameter. If one of the IP addresses is missing,
 622          * or there's more than one network interface in the system, use
 623          * RARP to get the missing values and routing information. If all
 624          * addresses are given, the best way to find a proper routing is
 625          * to use icmp echo requests ("ping"), but that would add a lot of
 626          * code to this module, which is only really necessary in the rare
 627          * case of multiple ethernet devices in the (diskless) system and
 628          * if the server is on another subnet (otherwise RARP can serve as
 629          * a ping substitute). If only one device is installed the routing
 630          * is obvious.
 631          */
 632         root_nfs_addrs(nfsaddrs);
 633         if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
 634              server.sin_addr.s_addr == INADDR_NONE ||
 635              (open_base != NULL && open_base->next != NULL)) && do_rarp() < 0) {
 636                 root_dev_close();
 637                 return -1;
 638         }
 639         if (root_dev == NULL) {
 640                 if (open_base != NULL && open_base->next == NULL) {
 641                         root_dev = open_base->dev;
 642                 } else {
 643                         printk(KERN_ERR "NFS: Unable to find routing to server\n");
 644                         root_dev_close();
 645                         return -1;
 646                 }
 647         }
 648         /*
 649          * Close all network devices except the device which connects to
 650          * server
 651          */
 652         root_dev_close();
 653 
 654         /*
 655          * Initialize the global variables necessary for NFS. The server
 656          * directory is actually mounted after init() has been started.
 657          */
 658         if (root_nfs_parse(nfsname) < 0)
 659                 return -1;
 660         root_nfs_print();
 661         root_nfs_setup();
 662         return 0;
 663 }
 664 
 665 
 666 
 667 
 668 /***************************************************************************
 669 
 670                 Routines to actually mount the root directory
 671 
 672  ***************************************************************************/
 673 
 674 static struct file nfs_file;            /* File descriptor containing socket */
 675 static struct inode nfs_inode;          /* Inode containing socket */
 676 static int *rpc_packet = NULL;          /* RPC packet */
 677 
 678 extern asmlinkage int sys_socketcall(int call, unsigned long *args);
 679 
 680 
 681 /*
 682  *  Open a UDP socket.
 683  */
 684 static int root_nfs_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 685 {
 686         struct file *filp;
 687         unsigned long opt[] = { AF_INET, SOCK_DGRAM, IPPROTO_UDP };
 688 
 689         /* Open the socket */
 690         if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) {
 691                 printk(KERN_ERR "NFS: Cannot open UDP socket\n");
 692                 return -1;
 693         }
 694         /*
 695          * Copy the file and inode data area so that we can remove the
 696          * file lateron without killing the socket. After all this the
 697          * closing routine just needs to remove the file pointer from the
 698          * init-task descriptor.
 699          */
 700         filp = current->files->fd[nfs_data.fd];
 701         memcpy(&nfs_file, filp, sizeof(struct file));
 702         nfs_file.f_next = nfs_file.f_prev = NULL;
 703         current->files->fd[nfs_data.fd] = &nfs_file;
 704         filp->f_count = 0;              /* Free the file descriptor */
 705 
 706         memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
 707         nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
 708         nfs_inode.i_next = nfs_inode.i_prev = NULL;
 709         clear_inode(nfs_file.f_inode);
 710         nfs_file.f_inode = &nfs_inode;
 711         nfs_inode.u.socket_i.inode = &nfs_inode;
 712         nfs_file.private_data = NULL;
 713 
 714         return 0;
 715 }
 716 
 717 
 718 /*
 719  *  Close the UDP file descriptor. The main part of preserving the socket
 720  *  has already been done after opening it. Now we have to remove the file
 721  *  descriptor from the init task.
 722  */
 723 static void root_nfs_close(int close_all)
     /* [previous][next][first][last][top][bottom][index][help] */
 724 {
 725         /* Remove the file from the list of open files */
 726         current->files->fd[nfs_data.fd] = NULL;
 727         if (current->files->count > 0)
 728                 current->files->count--;
 729 
 730         /* Clear memory used by the RPC packet */
 731         if (rpc_packet != NULL)
 732                 kfree_s(rpc_packet, nfs_data.wsize + 1024);
 733 
 734         /*
 735          * In case of an error we also have to close the socket again
 736          * (sigh)
 737          */
 738         if (close_all) {
 739                 nfs_inode.u.socket_i.inode = NULL;      /* The inode is already
 740                                                          * cleared */
 741                 if (nfs_file.f_op->release)
 742                         nfs_file.f_op->release(&nfs_inode, &nfs_file);
 743         }
 744 }
 745 
 746 
 747 /*
 748  *  Find a suitable listening port and bind to it
 749  */
 750 static int root_nfs_bind(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 751 {
 752         int res = -1;
 753         short port = STARTPORT;
 754         struct sockaddr_in *sin = &myaddr;
 755         int i;
 756 
 757         if (nfs_inode.u.socket_i.ops->bind) {
 758                 for (i = 0; i < NPORTS && res < 0; i++) {
 759                         sin->sin_port = htons(port++);
 760                         if (port > ENDPORT) {
 761                                 port = STARTPORT;
 762                         }
 763                         res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
 764                                                              (struct sockaddr *)sin, sizeof(struct sockaddr_in));
 765                 }
 766         }
 767         if (res < 0) {
 768                 printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
 769                 root_nfs_close(1);
 770                 return -1;
 771         }
 772 #ifdef NFSROOT_DEBUG
 773         printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
 774 #endif
 775         return 0;
 776 }
 777 
 778 
 779 /*
 780  *  Send an RPC request and wait for the answer
 781  */
 782 static int *root_nfs_call(int *end)
     /* [previous][next][first][last][top][bottom][index][help] */
 783 {
 784         struct file *filp;
 785         struct socket *sock;
 786         int dummylen;
 787         static struct nfs_server s = {
 788                 &nfs_file,              /* struct file *         */
 789                 0,                      /* struct rsock *        */
 790                 {
 791                     0, "",
 792                 },                      /* toaddr                */
 793                 0,                      /* lock                  */
 794                 NULL,                   /* wait queue            */
 795                 NFS_MOUNT_SOFT,         /* flags                 */
 796                 0, 0,                   /* rsize, wsize          */
 797                 0,                      /* timeo                 */
 798                 0,                      /* retrans               */
 799                 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
 800         };
 801 
 802         filp = &nfs_file;
 803         sock = &((filp->f_inode)->u.socket_i);
 804 
 805         /* extract the other end of the socket into s->toaddr */
 806         sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
 807         ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
 808         ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
 809         ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
 810 
 811         s.rsock = rpc_makesock(filp);
 812         s.flags = nfs_data.flags;
 813         s.rsize = nfs_data.rsize;
 814         s.wsize = nfs_data.wsize;
 815         s.timeo = nfs_data.timeo * HZ / 10;
 816         s.retrans = nfs_data.retrans;
 817         strcpy(s.hostname, nfs_data.hostname);
 818 
 819         /*
 820          * First connect the UDP socket to a server port, then send the
 821          * packet out, and finally check wether the answer is OK.
 822          */
 823         if (nfs_inode.u.socket_i.ops->connect &&
 824             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 825                                                 (struct sockaddr *) &server,
 826                                                 sizeof(struct sockaddr_in),
 827                                                 nfs_file.f_flags) < 0)
 828                             return NULL;
 829         if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
 830                 return NULL;
 831         return rpc_verify(rpc_packet);
 832 }
 833 
 834 
 835 /*
 836  *  Create an RPC packet header
 837  */
 838 static int *root_nfs_header(int proc, int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 839 {
 840         int groups[] = { 0, NOGROUP };
 841 
 842         if (rpc_packet == NULL) {
 843                 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
 844                         printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
 845                         return NULL;
 846                 }
 847         }
 848         return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 849 }
 850 
 851 
 852 /*
 853  *  Query server portmapper for the port of a daemon program
 854  */
 855 static int root_nfs_get_port(int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 856 {
 857         int *p;
 858 
 859         /* Prepare header for portmap request */
 860         server.sin_port = htons(NFS_PMAP_PORT);
 861         p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
 862         if (!p)
 863                 return -1;
 864 
 865         /* Set arguments for portmapper */
 866         *p++ = htonl(program);
 867         *p++ = htonl(version);
 868         *p++ = htonl(IPPROTO_UDP);
 869         *p++ = 0;
 870 
 871         /* Send request to server portmapper */
 872         if ((p = root_nfs_call(p)) == NULL)
 873                 return -1;
 874 
 875         return ntohl(*p);
 876 }
 877 
 878 
 879 /*
 880  *  Get portnumbers for mountd and nfsd from server
 881  */
 882 static int root_nfs_ports(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 883 {
 884         int port;
 885 
 886         if (nfs_port < 0) {
 887                 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
 888                         printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
 889                         port = NFS_NFS_PORT;
 890                 }
 891                 nfs_port = port;
 892 #ifdef NFSROOT_DEBUG
 893                 printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 894 #endif
 895         }
 896         if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
 897                 printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
 898                 port = NFS_MOUNT_PORT;
 899         }
 900         server.sin_port = htons(port);
 901 #ifdef NFSROOT_DEBUG
 902         printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 903 #endif
 904 
 905         return 0;
 906 }
 907 
 908 
 909 /*
 910  *  Get a file handle from the server for the directory which is to be
 911  *  mounted
 912  */
 913 static int root_nfs_get_handle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 914 {
 915         int len, status, *p;
 916 
 917         /* Prepare header for mountd request */
 918         p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
 919         if (!p) {
 920                 root_nfs_close(1);
 921                 return -1;
 922         }
 923         /* Set arguments for mountd */
 924         len = strlen(nfs_path);
 925         *p++ = htonl(len);
 926         memcpy(p, nfs_path, len);
 927         len = (len + 3) >> 2;
 928         p[len] = 0;
 929         p += len;
 930 
 931         /* Send request to server mountd */
 932         if ((p = root_nfs_call(p)) == NULL) {
 933                 root_nfs_close(1);
 934                 return -1;
 935         }
 936         status = ntohl(*p++);
 937         if (status == 0) {
 938                 nfs_data.root = *((struct nfs_fh *) p);
 939                 printk(KERN_NOTICE "NFS: ");
 940                 printk("Got file handle for %s via RPC\n", nfs_path);
 941         } else {
 942                 printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
 943                         status, nfs_path);
 944                 root_nfs_close(1);
 945                 return -1;
 946         }
 947 
 948         return 0;
 949 }
 950 
 951 
 952 /*
 953  *  Now actually mount the given directory
 954  */
 955 static int root_nfs_do_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 956 {
 957         /* First connect to the nfsd port on the server */
 958         server.sin_port = htons(nfs_port);
 959         nfs_data.addr = server;
 960         if (nfs_inode.u.socket_i.ops->connect &&
 961             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 962                                                 (struct sockaddr *) &server,
 963                                                 sizeof(struct sockaddr_in),
 964                                                 nfs_file.f_flags) < 0) {
 965                 root_nfs_close(1);
 966                 return -1;
 967         }
 968         /* Now (finally ;-)) read the super block for mounting */
 969         if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
 970                 root_nfs_close(1);
 971                 return -1;
 972         }
 973         return 0;
 974 }
 975 
 976 
 977 /*
 978  *  Get the NFS port numbers and file handle, and then read the super-
 979  *  block for mounting.
 980  */
 981 int nfs_root_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 982 {
 983         if (root_nfs_open() < 0)
 984                 return -1;
 985         if (root_nfs_bind() < 0)
 986                 return -1;
 987         if (root_nfs_ports() < 0)
 988                 return -1;
 989         if (root_nfs_get_handle() < 0)
 990                 return -1;
 991         if (root_nfs_do_mount(sb) < 0)
 992                 return -1;
 993         root_nfs_close(0);
 994         return 0;
 995 }

/* [previous][next][first][last][top][bottom][index][help] */