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  *      Michael Rausch  :       Fixed recognition of an incoming RARP answer.
  19  *
  20  */
  21 
  22 
  23 /* Define this to allow debugging output */
  24 #undef NFSROOT_DEBUG 1
  25 
  26 /* Define the timeout for waiting for a RARP reply */
  27 #define RARP_TIMEOUT    30      /* 30 seconds */
  28 #define RARP_RETRIES     5      /* 5 retries */
  29 
  30 #include <linux/config.h>
  31 #include <linux/types.h>
  32 #include <linux/string.h>
  33 #include <linux/kernel.h>
  34 #include <linux/sched.h>
  35 #include <linux/fs.h>
  36 
  37 #include <asm/param.h>
  38 #include <linux/utsname.h>
  39 #include <linux/in.h>
  40 #include <linux/if.h>
  41 #include <linux/inet.h>
  42 #include <linux/net.h>
  43 #include <linux/if_arp.h>
  44 #include <linux/netdevice.h>
  45 #ifdef CONFIG_AX25
  46 #include <net/ax25.h>   /* For AX25_P_IP */
  47 #endif
  48 #include <linux/skbuff.h>
  49 #include <linux/socket.h>
  50 #include <linux/route.h>
  51 #include <linux/nfs.h>
  52 #include <linux/nfs_fs.h>
  53 #include <linux/nfs_mount.h>
  54 #include <linux/in.h>
  55 #include <net/route.h>
  56 
  57 
  58 /* Range of privileged ports */
  59 #define STARTPORT       600
  60 #define ENDPORT         1023
  61 #define NPORTS          (ENDPORT - STARTPORT + 1)
  62 
  63 
  64 
  65 struct open_dev {
  66         struct device *dev;
  67         unsigned short old_flags;
  68         struct open_dev *next;
  69 };
  70 
  71 static struct open_dev *open_base = NULL;
  72 static struct device *root_dev = NULL;
  73 static struct sockaddr_in myaddr;       /* My IP address */
  74 static struct sockaddr_in server;       /* Server IP address */
  75 static struct sockaddr_in gateway;      /* Gateway IP address */
  76 static struct sockaddr_in netmask;      /* Netmask for local subnet */
  77 static struct nfs_mount_data nfs_data;  /* NFS mount info */
  78 static char nfs_path[NFS_MAXPATHLEN];   /* Name of directory to mount */
  79 static int nfs_port;                    /* Port to connect to for NFS service */
  80 
  81 
  82 
  83 /***************************************************************************
  84 
  85                         Device Handling Subroutines
  86 
  87  ***************************************************************************/
  88 
  89 /*
  90  * Setup and initialize all network devices
  91  */
  92 static int root_dev_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94         struct open_dev *openp;
  95         struct device *dev;
  96         unsigned short old_flags;
  97         int num = 0;
  98 
  99         for (dev = dev_base; dev != NULL; dev = dev->next) {
 100                 if (dev->type < ARPHRD_SLIP &&
 101                     dev->family == AF_INET &&
 102                     !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
 103                         /* First up the interface */
 104                         old_flags = dev->flags;
 105                         dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
 106                         if (!(old_flags & IFF_UP) && dev_open(dev)) {
 107                                 dev->flags = old_flags;
 108                                 continue;
 109                         }
 110                         openp = (struct open_dev *) kmalloc(sizeof(struct open_dev),
 111                                                 GFP_ATOMIC);
 112                         if (openp == NULL)
 113                                 continue;
 114                         openp->dev = dev;
 115                         openp->old_flags = old_flags;
 116                         openp->next = open_base;
 117                         open_base = openp;
 118                         num++;
 119                 }
 120         }
 121 
 122         if (num == 0) {
 123                 printk(KERN_ERR "NFS: Unable to open at least one network device\n");
 124                 return -1;
 125         }
 126 #ifdef NFSROOT_DEBUG
 127         printk(KERN_NOTICE "NFS: Opened %d network interfaces\n", num);
 128 #endif
 129         return 0;
 130 }
 131 
 132 
 133 /*
 134  *  Restore the state of all devices. However, keep the root device open
 135  *  for the upcoming mount.
 136  */
 137 static void root_dev_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 138 {
 139         struct open_dev *openp;
 140         struct open_dev *nextp;
 141 
 142         openp = open_base;
 143         while (openp != NULL) {
 144                 nextp = openp->next;
 145                 openp->next = NULL;
 146                 if (openp->dev != root_dev) {
 147                         if (!(openp->old_flags & IFF_UP))
 148                                 dev_close(openp->dev);
 149                         openp->dev->flags = openp->old_flags;
 150                 }
 151                 kfree_s(openp, sizeof(struct open_dev));
 152                 openp = nextp;
 153         }
 154 }
 155 
 156 
 157 
 158 
 159 /***************************************************************************
 160 
 161                         RARP Subroutines
 162 
 163  ***************************************************************************/
 164 
 165 extern void arp_send(int type, int ptype, unsigned long target_ip,
 166                      struct device *dev, unsigned long src_ip,
 167                      unsigned char *dest_hw, unsigned char *src_hw,
 168                      unsigned char *target_hw);
 169 
 170 static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
 171                           struct packet_type *pt);
 172 
 173 
 174 static struct packet_type rarp_packet_type = {
 175         0,                      /* Should be: __constant_htons(ETH_P_RARP)
 176                                  * - but this _doesn't_ come out constant! */
 177         NULL,                   /* Listen to all devices */
 178         root_rarp_recv,
 179         NULL,
 180         NULL
 181 };
 182 
 183 
 184 /*
 185  *  Register the packet type for RARP
 186  */
 187 static void root_rarp_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 188 {
 189         rarp_packet_type.type = htons(ETH_P_RARP);
 190         dev_add_pack(&rarp_packet_type);
 191 }
 192 
 193 
 194 /*
 195  *  Deregister the RARP packet type
 196  */
 197 static void root_rarp_close(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 198 {
 199         rarp_packet_type.type = htons(ETH_P_RARP);
 200         dev_remove_pack(&rarp_packet_type);
 201 }
 202 
 203 
 204 /*
 205  *  Receive RARP packets.
 206  */
 207 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209         struct arphdr *rarp = (struct arphdr *)skb->h.raw;
 210         unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 211         unsigned long sip, tip;
 212         unsigned char *sha, *tha;               /* s for "source", t for "target" */
 213 
 214         /* If this test doesn't pass, its not IP, or we should ignore it anyway */
 215         if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
 216                 kfree_skb(skb, FREE_READ);
 217                 return 0;
 218         }
 219 
 220         /* If it's not a RARP reply, delete it. */
 221         if (rarp->ar_op != htons(ARPOP_RREPLY)) {
 222                 kfree_skb(skb, FREE_READ);
 223                 return 0;
 224         }
 225 
 226         /* If it's not ethernet or AX25, delete it. */
 227         if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
 228 #ifdef CONFIG_AX25
 229            (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 230 #endif
 231             rarp->ar_pln != 4) {
 232                 kfree_skb(skb, FREE_READ);
 233                 return 0;
 234         }
 235 
 236         /* Extract variable width fields */
 237         sha = rarp_ptr;
 238         rarp_ptr += dev->addr_len;
 239         memcpy(&sip, rarp_ptr, 4);
 240         rarp_ptr += 4;
 241         tha = rarp_ptr;
 242         rarp_ptr += dev->addr_len;
 243         memcpy(&tip, rarp_ptr, 4);
 244 
 245         /* Discard packets which are not meant for us. */
 246         if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
 247                 kfree_skb(skb, FREE_READ);
 248                 return 0;
 249         }
 250         /* Discard packets which are not from specified server. */
 251         if (server.sin_addr.s_addr != INADDR_NONE &&
 252             server.sin_addr.s_addr != sip) {
 253                 kfree_skb(skb, FREE_READ);
 254                 return 0;
 255         }
 256 
 257         /*
 258          * The packet is what we were looking for. Setup the global
 259          * variables.
 260          */
 261         cli();
 262         if (root_dev != NULL) {
 263                 sti();
 264                 kfree_skb(skb, FREE_READ);
 265                 return 0;
 266         }
 267         root_dev = dev;
 268         sti();
 269 
 270         if (myaddr.sin_addr.s_addr == INADDR_NONE) {
 271                 myaddr.sin_family = dev->family;
 272                 myaddr.sin_addr.s_addr = tip;
 273         }
 274         if (server.sin_addr.s_addr == INADDR_NONE) {
 275                 server.sin_family = dev->family;
 276                 server.sin_addr.s_addr = sip;
 277         }
 278         kfree_skb(skb, FREE_READ);
 279         return 0;
 280 }
 281 
 282 
 283 /*
 284  *  Send RARP request packet over all devices which allow RARP.
 285  */
 286 static int root_rarp_send(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 287 {
 288         struct open_dev *openp;
 289         struct device *dev;
 290         int num = 0;
 291 
 292         /* always print this message so user knows what's going on... */
 293         printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 294         for (openp = open_base; openp != NULL; openp = openp->next) {
 295                 dev = openp->dev;
 296                 if (!(dev->flags & IFF_NOARP)) {
 297                         arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 298                                  dev->dev_addr, dev->dev_addr);
 299                         num++;
 300                 }
 301         }
 302 
 303         if (num == 0) {
 304                 printk(KERN_ERR "NFS: Couldn't find device to send RARP request to\n");
 305                 return -1;
 306         }
 307         return 0;
 308 }
 309 
 310 
 311 /*
 312  *  Determine client and server IP numbers and appropriate device by using
 313  *  the RARP protocol.
 314  */
 315 static int do_rarp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 316 {
 317         int retries = 0;
 318         unsigned long timeout = 0;
 319         volatile struct device **root_dev_ptr = (volatile struct device **) &root_dev;
 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_ptr == NULL; retries++) {
 333                 if (root_rarp_send() < 0)
 334                         break;
 335                 timeout = jiffies + (RARP_TIMEOUT * HZ);
 336                 while (jiffies < timeout && *root_dev_ptr == NULL)
 337                         ;
 338         }
 339 
 340         root_rarp_close();
 341         if (*root_dev_ptr == 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_socket(int family, int type, int protocol);
 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 
 688         /* Open the socket */
 689         if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 690                 printk(KERN_ERR "NFS: Cannot open UDP socket\n");
 691                 return -1;
 692         }
 693         /*
 694          * Copy the file and inode data area so that we can remove the
 695          * file lateron without killing the socket. After all this the
 696          * closing routine just needs to remove the file pointer from the
 697          * init-task descriptor.
 698          */
 699         filp = current->files->fd[nfs_data.fd];
 700         memcpy(&nfs_file, filp, sizeof(struct file));
 701         nfs_file.f_next = nfs_file.f_prev = NULL;
 702         current->files->fd[nfs_data.fd] = &nfs_file;
 703         filp->f_count = 0;              /* Free the file descriptor */
 704 
 705         memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
 706         nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
 707         nfs_inode.i_next = nfs_inode.i_prev = NULL;
 708         clear_inode(nfs_file.f_inode);
 709         nfs_file.f_inode = &nfs_inode;
 710         nfs_inode.u.socket_i.inode = &nfs_inode;
 711         nfs_file.private_data = NULL;
 712 
 713         return 0;
 714 }
 715 
 716 
 717 /*
 718  *  Close the UDP file descriptor. The main part of preserving the socket
 719  *  has already been done after opening it. Now we have to remove the file
 720  *  descriptor from the init task.
 721  */
 722 static void root_nfs_close(int close_all)
     /* [previous][next][first][last][top][bottom][index][help] */
 723 {
 724         /* Remove the file from the list of open files */
 725         current->files->fd[nfs_data.fd] = NULL;
 726         if (current->files->count > 0)
 727                 current->files->count--;
 728 
 729         /* Clear memory used by the RPC packet */
 730         if (rpc_packet != NULL)
 731                 kfree_s(rpc_packet, nfs_data.wsize + 1024);
 732 
 733         /*
 734          * In case of an error we also have to close the socket again
 735          * (sigh)
 736          */
 737         if (close_all) {
 738                 nfs_inode.u.socket_i.inode = NULL;      /* The inode is already
 739                                                          * cleared */
 740                 if (nfs_file.f_op->release)
 741                         nfs_file.f_op->release(&nfs_inode, &nfs_file);
 742         }
 743 }
 744 
 745 
 746 /*
 747  *  Find a suitable listening port and bind to it
 748  */
 749 static int root_nfs_bind(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 750 {
 751         int res = -1;
 752         short port = STARTPORT;
 753         struct sockaddr_in *sin = &myaddr;
 754         int i;
 755 
 756         if (nfs_inode.u.socket_i.ops->bind) {
 757                 for (i = 0; i < NPORTS && res < 0; i++) {
 758                         sin->sin_port = htons(port++);
 759                         if (port > ENDPORT) {
 760                                 port = STARTPORT;
 761                         }
 762                         res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
 763                                                              (struct sockaddr *)sin, sizeof(struct sockaddr_in));
 764                 }
 765         }
 766         if (res < 0) {
 767                 printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
 768                 root_nfs_close(1);
 769                 return -1;
 770         }
 771 #ifdef NFSROOT_DEBUG
 772         printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
 773 #endif
 774         return 0;
 775 }
 776 
 777 
 778 /*
 779  *  Send an RPC request and wait for the answer
 780  */
 781 static int *root_nfs_call(int *end)
     /* [previous][next][first][last][top][bottom][index][help] */
 782 {
 783         struct file *filp;
 784         struct socket *sock;
 785         int dummylen;
 786         static struct nfs_server s = {
 787                 &nfs_file,              /* struct file *         */
 788                 0,                      /* struct rsock *        */
 789                 {
 790                     0, "",
 791                 },                      /* toaddr                */
 792                 0,                      /* lock                  */
 793                 NULL,                   /* wait queue            */
 794                 NFS_MOUNT_SOFT,         /* flags                 */
 795                 0, 0,                   /* rsize, wsize          */
 796                 0,                      /* timeo                 */
 797                 0,                      /* retrans               */
 798                 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
 799         };
 800 
 801         filp = &nfs_file;
 802         sock = &((filp->f_inode)->u.socket_i);
 803 
 804         /* extract the other end of the socket into s->toaddr */
 805         sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
 806         ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
 807         ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
 808         ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
 809 
 810         s.rsock = rpc_makesock(filp);
 811         s.flags = nfs_data.flags;
 812         s.rsize = nfs_data.rsize;
 813         s.wsize = nfs_data.wsize;
 814         s.timeo = nfs_data.timeo * HZ / 10;
 815         s.retrans = nfs_data.retrans;
 816         strcpy(s.hostname, nfs_data.hostname);
 817 
 818         /*
 819          * First connect the UDP socket to a server port, then send the
 820          * packet out, and finally check wether the answer is OK.
 821          */
 822         if (nfs_inode.u.socket_i.ops->connect &&
 823             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 824                                                 (struct sockaddr *) &server,
 825                                                 sizeof(struct sockaddr_in),
 826                                                 nfs_file.f_flags) < 0)
 827                             return NULL;
 828         if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
 829                 return NULL;
 830         return rpc_verify(rpc_packet);
 831 }
 832 
 833 
 834 /*
 835  *  Create an RPC packet header
 836  */
 837 static int *root_nfs_header(int proc, int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 838 {
 839         int groups[] = { 0, NOGROUP };
 840 
 841         if (rpc_packet == NULL) {
 842                 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
 843                         printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
 844                         return NULL;
 845                 }
 846         }
 847         return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 848 }
 849 
 850 
 851 /*
 852  *  Query server portmapper for the port of a daemon program
 853  */
 854 static int root_nfs_get_port(int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 855 {
 856         int *p;
 857 
 858         /* Prepare header for portmap request */
 859         server.sin_port = htons(NFS_PMAP_PORT);
 860         p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
 861         if (!p)
 862                 return -1;
 863 
 864         /* Set arguments for portmapper */
 865         *p++ = htonl(program);
 866         *p++ = htonl(version);
 867         *p++ = htonl(IPPROTO_UDP);
 868         *p++ = 0;
 869 
 870         /* Send request to server portmapper */
 871         if ((p = root_nfs_call(p)) == NULL)
 872                 return -1;
 873 
 874         return ntohl(*p);
 875 }
 876 
 877 
 878 /*
 879  *  Get portnumbers for mountd and nfsd from server
 880  */
 881 static int root_nfs_ports(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 882 {
 883         int port;
 884 
 885         if (nfs_port < 0) {
 886                 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
 887                         printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
 888                         port = NFS_NFS_PORT;
 889                 }
 890                 nfs_port = port;
 891 #ifdef NFSROOT_DEBUG
 892                 printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 893 #endif
 894         }
 895         if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
 896                 printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
 897                 port = NFS_MOUNT_PORT;
 898         }
 899         server.sin_port = htons(port);
 900 #ifdef NFSROOT_DEBUG
 901         printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 902 #endif
 903 
 904         return 0;
 905 }
 906 
 907 
 908 /*
 909  *  Get a file handle from the server for the directory which is to be
 910  *  mounted
 911  */
 912 static int root_nfs_get_handle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 913 {
 914         int len, status, *p;
 915 
 916         /* Prepare header for mountd request */
 917         p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
 918         if (!p) {
 919                 root_nfs_close(1);
 920                 return -1;
 921         }
 922         /* Set arguments for mountd */
 923         len = strlen(nfs_path);
 924         *p++ = htonl(len);
 925         memcpy(p, nfs_path, len);
 926         len = (len + 3) >> 2;
 927         p[len] = 0;
 928         p += len;
 929 
 930         /* Send request to server mountd */
 931         if ((p = root_nfs_call(p)) == NULL) {
 932                 root_nfs_close(1);
 933                 return -1;
 934         }
 935         status = ntohl(*p++);
 936         if (status == 0) {
 937                 nfs_data.root = *((struct nfs_fh *) p);
 938                 printk(KERN_NOTICE "NFS: ");
 939                 printk("Got file handle for %s via RPC\n", nfs_path);
 940         } else {
 941                 printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
 942                         status, nfs_path);
 943                 root_nfs_close(1);
 944                 return -1;
 945         }
 946 
 947         return 0;
 948 }
 949 
 950 
 951 /*
 952  *  Now actually mount the given directory
 953  */
 954 static int root_nfs_do_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 955 {
 956         /* First connect to the nfsd port on the server */
 957         server.sin_port = htons(nfs_port);
 958         nfs_data.addr = server;
 959         if (nfs_inode.u.socket_i.ops->connect &&
 960             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 961                                                 (struct sockaddr *) &server,
 962                                                 sizeof(struct sockaddr_in),
 963                                                 nfs_file.f_flags) < 0) {
 964                 root_nfs_close(1);
 965                 return -1;
 966         }
 967         /* Now (finally ;-)) read the super block for mounting */
 968         if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
 969                 root_nfs_close(1);
 970                 return -1;
 971         }
 972         return 0;
 973 }
 974 
 975 
 976 /*
 977  *  Get the NFS port numbers and file handle, and then read the super-
 978  *  block for mounting.
 979  */
 980 int nfs_root_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 981 {
 982         if (root_nfs_open() < 0)
 983                 return -1;
 984         if (root_nfs_bind() < 0)
 985                 return -1;
 986         if (root_nfs_ports() < 0)
 987                 return -1;
 988         if (root_nfs_get_handle() < 0)
 989                 return -1;
 990         if (root_nfs_do_mount(sb) < 0)
 991                 return -1;
 992         root_nfs_close(0);
 993         return 0;
 994 }

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