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 #ifdef NFSROOT_DEBUG
 293         printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 294 #endif
 295 
 296         for (openp = open_base; openp != NULL; openp = openp->next) {
 297                 dev = openp->dev;
 298                 if (!(dev->flags & IFF_NOARP)) {
 299                         arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
 300                                  dev->dev_addr, dev->dev_addr);
 301                         num++;
 302                 }
 303         }
 304 
 305         if (num == 0) {
 306                 printk(KERN_ERR "NFS: Couldn't find device to send RARP request to\n");
 307                 return -1;
 308         }
 309         return 0;
 310 }
 311 
 312 
 313 /*
 314  *  Determine client and server IP numbers and appropriate device by using
 315  *  the RARP protocol.
 316  */
 317 static int do_rarp(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 318 {
 319         int retries = 0;
 320         unsigned long timeout = 0;
 321         volatile struct device **root_dev_ptr = (volatile struct device **) &root_dev;
 322 
 323         /* Setup RARP protocol */
 324         root_rarp_open();
 325 
 326         /*
 327          * Send RARP request and wait, until we get an answer. This loop
 328          * seems to be a terrible waste of cpu time, but actually there is
 329          * no process running at all, so we don't need to use any
 330          * scheduler functions.
 331          * [Actually we could now, but the nothing else running note still 
 332          *  applies.. - AC]
 333          */
 334         for (retries = 0; retries < RARP_RETRIES && *root_dev_ptr == NULL; retries++) {
 335                 if (root_rarp_send() < 0)
 336                         break;
 337                 timeout = jiffies + (RARP_TIMEOUT * HZ);
 338                 while (jiffies < timeout && *root_dev_ptr == NULL)
 339                         ;
 340         }
 341 
 342         root_rarp_close();
 343         if (*root_dev_ptr == NULL && timeout > 0) {
 344                 printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
 345                 return -1;
 346         }
 347         printk(KERN_NOTICE "NFS: ");
 348         printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
 349         printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
 350 
 351         return 0;
 352 }
 353 
 354 
 355 
 356 
 357 /***************************************************************************
 358 
 359                         Routines to setup NFS
 360 
 361  ***************************************************************************/
 362 
 363 
 364 
 365 /*
 366  *  The following integer options are recognized
 367  */
 368 static struct nfs_int_opts {
 369         char *name;
 370         int  *val;
 371 } root_int_opts[] = {
 372         { "port",       &nfs_port },
 373         { "rsize",      &nfs_data.rsize },
 374         { "wsize",      &nfs_data.wsize },
 375         { "timeo",      &nfs_data.timeo },
 376         { "retrans",    &nfs_data.retrans },
 377         { "acregmin",   &nfs_data.acregmin },
 378         { "acregmax",   &nfs_data.acregmax },
 379         { "acdirmin",   &nfs_data.acdirmin },
 380         { "acdirmax",   &nfs_data.acdirmax },
 381         { NULL,         NULL }
 382 };
 383 
 384 
 385 /*
 386  *  And now the flag options
 387  */
 388 static struct nfs_bool_opts {
 389         char *name;
 390         int  and_mask;
 391         int  or_mask;
 392 } root_bool_opts[] = {
 393         { "soft",       ~NFS_MOUNT_SOFT,        NFS_MOUNT_SOFT },
 394         { "hard",       ~NFS_MOUNT_SOFT,        0 },
 395         { "intr",       ~NFS_MOUNT_INTR,        NFS_MOUNT_INTR },
 396         { "nointr",     ~NFS_MOUNT_INTR,        0 },
 397         { "posix",      ~NFS_MOUNT_POSIX,       NFS_MOUNT_POSIX },
 398         { "noposix",    ~NFS_MOUNT_POSIX,       0 },
 399         { "cto",        ~NFS_MOUNT_NOCTO,       0 },
 400         { "nocto",      ~NFS_MOUNT_NOCTO,       NFS_MOUNT_NOCTO },
 401         { "ac",         ~NFS_MOUNT_NOAC,        0 },
 402         { "noac",       ~NFS_MOUNT_NOAC,        NFS_MOUNT_NOAC },
 403         { NULL,         0,                      0 }
 404 };
 405 
 406 
 407 /*
 408  *  Prepare the NFS data structure and parse any options
 409  */
 410 static int root_nfs_parse(char *name)
     /* [previous][next][first][last][top][bottom][index][help] */
 411 {
 412         char buf[NFS_MAXPATHLEN];
 413         char *cp, *options, *val;
 414 
 415         /* Set the default system name in case none was previously found */
 416         if (!system_utsname.nodename[0]) {
 417                 strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
 418                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 419         }
 420         /* It is possible to override the host IP number here */
 421         if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
 422                 *cp++ = '\0';
 423                 server.sin_addr.s_addr = in_aton(name);
 424                 name = cp;
 425         }
 426 
 427         /* Setup the server hostname */
 428         cp = in_ntoa(server.sin_addr.s_addr);
 429         strncpy(nfs_data.hostname, cp, 255);
 430 
 431         /* Set the name of the directory to mount */
 432         cp = in_ntoa(myaddr.sin_addr.s_addr);
 433         strncpy(buf, name, 255);
 434         if ((options = strchr(buf, ',')))
 435                 *options++ = '\0';
 436         if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
 437                 printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
 438                 return -1;
 439         }
 440         sprintf(nfs_path, buf, cp);
 441 
 442         /* Set some default values */
 443         nfs_port          = -1;
 444         nfs_data.version  = NFS_MOUNT_VERSION;
 445         nfs_data.flags    = 0;
 446         nfs_data.rsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 447         nfs_data.wsize    = NFS_DEF_FILE_IO_BUFFER_SIZE;
 448         nfs_data.timeo    = 7;
 449         nfs_data.retrans  = 3;
 450         nfs_data.acregmin = 3;
 451         nfs_data.acregmax = 60;
 452         nfs_data.acdirmin = 30;
 453         nfs_data.acdirmax = 60;
 454 
 455         /* Process any options */
 456         if (options) {
 457                 cp = strtok(options, ",");
 458                 while (cp) {
 459                         if ((val = strchr(cp, '='))) {
 460                                 struct nfs_int_opts *opts = root_int_opts;
 461                                 *val++ = '\0';
 462                                 while (opts->name && strcmp(opts->name, cp))
 463                                         opts++;
 464                                 if (opts->name)
 465                                         *(opts->val) = (int) simple_strtoul(val, NULL, 10);
 466                         } else {
 467                                 struct nfs_bool_opts *opts = root_bool_opts;
 468                                 while (opts->name && strcmp(opts->name, cp))
 469                                         opts++;
 470                                 if (opts->name) {
 471                                         nfs_data.flags &= opts->and_mask;
 472                                         nfs_data.flags |= opts->or_mask;
 473                                 }
 474                         }
 475                         cp = strtok(NULL, ",");
 476                 }
 477         }
 478         return 0;
 479 }
 480 
 481 
 482 /*
 483  *  Tell the user what's going on.
 484  */
 485 static void root_nfs_print(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 486 {
 487 #ifdef NFSROOT_DEBUG
 488         printk(KERN_NOTICE "NFS: Mounting %s on server %s as root\n",
 489                 nfs_path, nfs_data.hostname);
 490         printk(KERN_NOTICE "NFS:     rsize = %d, wsize = %d, timeo = %d, retrans = %d\n",
 491                 nfs_data.rsize, nfs_data.wsize, nfs_data.timeo, nfs_data.retrans);
 492         printk(KERN_NOTICE "NFS:     acreg (min,max) = (%d,%d), acdir (min,max) = (%d,%d)\n",
 493                 nfs_data.acregmin, nfs_data.acregmax,
 494                 nfs_data.acdirmin, nfs_data.acdirmax);
 495         printk(KERN_NOTICE "NFS:     port = %d, flags = %08x\n",
 496                 nfs_port, nfs_data.flags);
 497 #endif
 498 }
 499 
 500 
 501 /*
 502  *  Parse any IP addresses
 503  */
 504 static void root_nfs_addrs(char *addrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 505 {
 506         char *cp, *ip, *dp;
 507         int num = 0;
 508 
 509         /* Clear all addresses and strings */
 510         myaddr.sin_family = server.sin_family =
 511             gateway.sin_family = netmask.sin_family = AF_INET;
 512         myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
 513             gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
 514         system_utsname.nodename[0] = '\0';
 515         system_utsname.domainname[0] = '\0';
 516 
 517         /*
 518          * Parse the address field. It contains 4 IP addresses which are
 519          * separated by colons: Field 0 = my own address Field 1 = server
 520          * address Field 2 = gateway address Field 3 = netmask address
 521          * Field 4 = client host name
 522          */
 523         ip = addrs;
 524         while (ip && *ip) {
 525                 if ((cp = strchr(ip, ':')))
 526                         *cp++ = '\0';
 527                 if (strlen(ip) > 0) {
 528 #ifdef NFSROOT_DEBUG
 529                         printk(KERN_NOTICE "NFS: IP address num %d is \"%s\"\n", num, ip);
 530 #endif
 531                         switch (num) {
 532                         case 0:
 533                                 myaddr.sin_addr.s_addr = in_aton(ip);
 534                                 break;
 535                         case 1:
 536                                 server.sin_addr.s_addr = in_aton(ip);
 537                                 break;
 538                         case 2:
 539                                 gateway.sin_addr.s_addr = in_aton(ip);
 540                                 break;
 541                         case 3:
 542                                 netmask.sin_addr.s_addr = in_aton(ip);
 543                                 break;
 544                         case 4:
 545                                 if ((dp = strchr(ip, '.'))) {
 546                                         *dp++ = '\0';
 547                                         strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
 548                                         system_utsname.domainname[__NEW_UTS_LEN] = '\0';
 549                                 }
 550                                 strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
 551                                 system_utsname.nodename[__NEW_UTS_LEN] = '\0';
 552                                 break;
 553                         default:
 554                                 break;
 555                         }
 556                 }
 557                 ip = cp;
 558                 num++;
 559         }
 560 }
 561 
 562 
 563 /*
 564  *  Set the interface address and configure a route to the server.
 565  */
 566 static void root_nfs_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 567 {
 568         struct rtentry route;
 569 
 570         /* Set the correct netmask */
 571         if (netmask.sin_addr.s_addr == INADDR_NONE)
 572                 netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
 573 
 574         /* Setup the device correctly */
 575         root_dev->family     = myaddr.sin_family;
 576         root_dev->pa_addr    = myaddr.sin_addr.s_addr;
 577         root_dev->pa_mask    = netmask.sin_addr.s_addr;
 578         root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
 579         root_dev->pa_dstaddr = 0;
 580 
 581         /*
 582          * Now add a route to the server. If there is no gateway given,
 583          * the server is on our own local network, so a host route is
 584          * sufficient. Otherwise we first have to create a host route to
 585          * the gateway, and then setup a gatewayed host route to the
 586          * server. Note that it's not possible to setup a network route
 587          * because we don't know the network mask of the server network.
 588          */
 589         memset(&route, 0, sizeof(route));
 590         route.rt_dev = root_dev->name;
 591         route.rt_mss = root_dev->mtu;
 592         route.rt_flags = RTF_HOST | RTF_UP;
 593         *((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
 594 
 595         if (gateway.sin_addr.s_addr == INADDR_NONE ||
 596             gateway.sin_addr.s_addr == server.sin_addr.s_addr ||
 597             !((server.sin_addr.s_addr ^ root_dev->pa_addr) & root_dev->pa_mask)) {
 598                 *((struct sockaddr_in *) &(route.rt_dst)) = server;
 599                 ip_rt_new(&route);
 600         } else {
 601                 *((struct sockaddr_in *) &(route.rt_dst)) = gateway;
 602                 ip_rt_new(&route);
 603                 route.rt_flags |= RTF_GATEWAY;
 604                 *((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
 605                 *((struct sockaddr_in *) &(route.rt_dst)) = server;
 606                 ip_rt_new(&route);
 607         }
 608 }
 609 
 610 
 611 /*
 612  *  Get the necessary IP addresses and prepare for mounting the required
 613  *  NFS filesystem.
 614  */
 615 int nfs_root_init(char *nfsname, char *nfsaddrs)
     /* [previous][next][first][last][top][bottom][index][help] */
 616 {
 617         /* Setup all network devices */
 618         if (root_dev_open() < 0)
 619                 return -1;
 620 
 621         /*
 622          * Get local and server IP address. First check for addresses in
 623          * command line parameter. If one of the IP addresses is missing,
 624          * or there's more than one network interface in the system, use
 625          * RARP to get the missing values and routing information. If all
 626          * addresses are given, the best way to find a proper routing is
 627          * to use icmp echo requests ("ping"), but that would add a lot of
 628          * code to this module, which is only really necessary in the rare
 629          * case of multiple ethernet devices in the (diskless) system and
 630          * if the server is on another subnet (otherwise RARP can serve as
 631          * a ping substitute). If only one device is installed the routing
 632          * is obvious.
 633          */
 634         root_nfs_addrs(nfsaddrs);
 635         if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
 636              server.sin_addr.s_addr == INADDR_NONE ||
 637              (open_base != NULL && open_base->next != NULL)) && do_rarp() < 0) {
 638                 root_dev_close();
 639                 return -1;
 640         }
 641         if (root_dev == NULL) {
 642                 if (open_base != NULL && open_base->next == NULL) {
 643                         root_dev = open_base->dev;
 644                 } else {
 645                         printk(KERN_ERR "NFS: Unable to find routing to server\n");
 646                         root_dev_close();
 647                         return -1;
 648                 }
 649         }
 650         /*
 651          * Close all network devices except the device which connects to
 652          * server
 653          */
 654         root_dev_close();
 655 
 656         /*
 657          * Initialize the global variables necessary for NFS. The server
 658          * directory is actually mounted after init() has been started.
 659          */
 660         if (root_nfs_parse(nfsname) < 0)
 661                 return -1;
 662         root_nfs_print();
 663         root_nfs_setup();
 664         return 0;
 665 }
 666 
 667 
 668 
 669 
 670 /***************************************************************************
 671 
 672                 Routines to actually mount the root directory
 673 
 674  ***************************************************************************/
 675 
 676 static struct file nfs_file;            /* File descriptor containing socket */
 677 static struct inode nfs_inode;          /* Inode containing socket */
 678 static int *rpc_packet = NULL;          /* RPC packet */
 679 
 680 extern asmlinkage int sys_socket(int family, int type, int protocol);
 681 
 682 
 683 /*
 684  *  Open a UDP socket.
 685  */
 686 static int root_nfs_open(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 687 {
 688         struct file *filp;
 689 
 690         /* Open the socket */
 691         if ((nfs_data.fd = sys_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
 692                 printk(KERN_ERR "NFS: Cannot open UDP socket\n");
 693                 return -1;
 694         }
 695         /*
 696          * Copy the file and inode data area so that we can remove the
 697          * file lateron without killing the socket. After all this the
 698          * closing routine just needs to remove the file pointer from the
 699          * init-task descriptor.
 700          */
 701         filp = current->files->fd[nfs_data.fd];
 702         memcpy(&nfs_file, filp, sizeof(struct file));
 703         nfs_file.f_next = nfs_file.f_prev = NULL;
 704         current->files->fd[nfs_data.fd] = &nfs_file;
 705         filp->f_count = 0;              /* Free the file descriptor */
 706 
 707         memcpy(&nfs_inode, nfs_file.f_inode, sizeof(struct inode));
 708         nfs_inode.i_hash_next = nfs_inode.i_hash_prev = NULL;
 709         nfs_inode.i_next = nfs_inode.i_prev = NULL;
 710         clear_inode(nfs_file.f_inode);
 711         nfs_file.f_inode = &nfs_inode;
 712         nfs_inode.u.socket_i.inode = &nfs_inode;
 713         nfs_file.private_data = NULL;
 714 
 715         return 0;
 716 }
 717 
 718 
 719 /*
 720  *  Close the UDP file descriptor. The main part of preserving the socket
 721  *  has already been done after opening it. Now we have to remove the file
 722  *  descriptor from the init task.
 723  */
 724 static void root_nfs_close(int close_all)
     /* [previous][next][first][last][top][bottom][index][help] */
 725 {
 726         /* Remove the file from the list of open files */
 727         current->files->fd[nfs_data.fd] = NULL;
 728         if (current->files->count > 0)
 729                 current->files->count--;
 730 
 731         /* Clear memory used by the RPC packet */
 732         if (rpc_packet != NULL)
 733                 kfree_s(rpc_packet, nfs_data.wsize + 1024);
 734 
 735         /*
 736          * In case of an error we also have to close the socket again
 737          * (sigh)
 738          */
 739         if (close_all) {
 740                 nfs_inode.u.socket_i.inode = NULL;      /* The inode is already
 741                                                          * cleared */
 742                 if (nfs_file.f_op->release)
 743                         nfs_file.f_op->release(&nfs_inode, &nfs_file);
 744         }
 745 }
 746 
 747 
 748 /*
 749  *  Find a suitable listening port and bind to it
 750  */
 751 static int root_nfs_bind(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 752 {
 753         int res = -1;
 754         short port = STARTPORT;
 755         struct sockaddr_in *sin = &myaddr;
 756         int i;
 757 
 758         if (nfs_inode.u.socket_i.ops->bind) {
 759                 for (i = 0; i < NPORTS && res < 0; i++) {
 760                         sin->sin_port = htons(port++);
 761                         if (port > ENDPORT) {
 762                                 port = STARTPORT;
 763                         }
 764                         res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
 765                                                              (struct sockaddr *)sin, sizeof(struct sockaddr_in));
 766                 }
 767         }
 768         if (res < 0) {
 769                 printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
 770                 root_nfs_close(1);
 771                 return -1;
 772         }
 773 #ifdef NFSROOT_DEBUG
 774         printk(KERN_NOTICE "NFS: Binding to listening port %d\n", port);
 775 #endif
 776         return 0;
 777 }
 778 
 779 
 780 /*
 781  *  Send an RPC request and wait for the answer
 782  */
 783 static int *root_nfs_call(int *end)
     /* [previous][next][first][last][top][bottom][index][help] */
 784 {
 785         struct file *filp;
 786         struct socket *sock;
 787         int dummylen;
 788         static struct nfs_server s = {
 789                 &nfs_file,              /* struct file *         */
 790                 0,                      /* struct rsock *        */
 791                 {
 792                     0, "",
 793                 },                      /* toaddr                */
 794                 0,                      /* lock                  */
 795                 NULL,                   /* wait queue            */
 796                 NFS_MOUNT_SOFT,         /* flags                 */
 797                 0, 0,                   /* rsize, wsize          */
 798                 0,                      /* timeo                 */
 799                 0,                      /* retrans               */
 800                 3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
 801         };
 802 
 803         filp = &nfs_file;
 804         sock = &((filp->f_inode)->u.socket_i);
 805 
 806         /* extract the other end of the socket into s->toaddr */
 807         sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
 808         ((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
 809         ((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
 810         ((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
 811 
 812         s.rsock = rpc_makesock(filp);
 813         s.flags = nfs_data.flags;
 814         s.rsize = nfs_data.rsize;
 815         s.wsize = nfs_data.wsize;
 816         s.timeo = nfs_data.timeo * HZ / 10;
 817         s.retrans = nfs_data.retrans;
 818         strcpy(s.hostname, nfs_data.hostname);
 819 
 820         /*
 821          * First connect the UDP socket to a server port, then send the
 822          * packet out, and finally check wether the answer is OK.
 823          */
 824         if (nfs_inode.u.socket_i.ops->connect &&
 825             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 826                                                 (struct sockaddr *) &server,
 827                                                 sizeof(struct sockaddr_in),
 828                                                 nfs_file.f_flags) < 0)
 829                             return NULL;
 830         if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
 831                 return NULL;
 832         return rpc_verify(rpc_packet);
 833 }
 834 
 835 
 836 /*
 837  *  Create an RPC packet header
 838  */
 839 static int *root_nfs_header(int proc, int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 840 {
 841         int groups[] = { 0, NOGROUP };
 842 
 843         if (rpc_packet == NULL) {
 844                 if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
 845                         printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
 846                         return NULL;
 847                 }
 848         }
 849         return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 850 }
 851 
 852 
 853 /*
 854  *  Query server portmapper for the port of a daemon program
 855  */
 856 static int root_nfs_get_port(int program, int version)
     /* [previous][next][first][last][top][bottom][index][help] */
 857 {
 858         int *p;
 859 
 860         /* Prepare header for portmap request */
 861         server.sin_port = htons(NFS_PMAP_PORT);
 862         p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
 863         if (!p)
 864                 return -1;
 865 
 866         /* Set arguments for portmapper */
 867         *p++ = htonl(program);
 868         *p++ = htonl(version);
 869         *p++ = htonl(IPPROTO_UDP);
 870         *p++ = 0;
 871 
 872         /* Send request to server portmapper */
 873         if ((p = root_nfs_call(p)) == NULL)
 874                 return -1;
 875 
 876         return ntohl(*p);
 877 }
 878 
 879 
 880 /*
 881  *  Get portnumbers for mountd and nfsd from server
 882  */
 883 static int root_nfs_ports(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 884 {
 885         int port;
 886 
 887         if (nfs_port < 0) {
 888                 if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
 889                         printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
 890                         port = NFS_NFS_PORT;
 891                 }
 892                 nfs_port = port;
 893 #ifdef NFSROOT_DEBUG
 894                 printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 895 #endif
 896         }
 897         if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
 898                 printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
 899                 port = NFS_MOUNT_PORT;
 900         }
 901         server.sin_port = htons(port);
 902 #ifdef NFSROOT_DEBUG
 903         printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 904 #endif
 905 
 906         return 0;
 907 }
 908 
 909 
 910 /*
 911  *  Get a file handle from the server for the directory which is to be
 912  *  mounted
 913  */
 914 static int root_nfs_get_handle(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 915 {
 916         int len, status, *p;
 917 
 918         /* Prepare header for mountd request */
 919         p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
 920         if (!p) {
 921                 root_nfs_close(1);
 922                 return -1;
 923         }
 924         /* Set arguments for mountd */
 925         len = strlen(nfs_path);
 926         *p++ = htonl(len);
 927         memcpy(p, nfs_path, len);
 928         len = (len + 3) >> 2;
 929         p[len] = 0;
 930         p += len;
 931 
 932         /* Send request to server mountd */
 933         if ((p = root_nfs_call(p)) == NULL) {
 934                 root_nfs_close(1);
 935                 return -1;
 936         }
 937         status = ntohl(*p++);
 938         if (status == 0) {
 939                 nfs_data.root = *((struct nfs_fh *) p);
 940                 printk(KERN_NOTICE "NFS: ");
 941                 printk("Got file handle for %s via RPC\n", nfs_path);
 942         } else {
 943                 printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
 944                         status, nfs_path);
 945                 root_nfs_close(1);
 946                 return -1;
 947         }
 948 
 949         return 0;
 950 }
 951 
 952 
 953 /*
 954  *  Now actually mount the given directory
 955  */
 956 static int root_nfs_do_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 957 {
 958         /* First connect to the nfsd port on the server */
 959         server.sin_port = htons(nfs_port);
 960         nfs_data.addr = server;
 961         if (nfs_inode.u.socket_i.ops->connect &&
 962             nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
 963                                                 (struct sockaddr *) &server,
 964                                                 sizeof(struct sockaddr_in),
 965                                                 nfs_file.f_flags) < 0) {
 966                 root_nfs_close(1);
 967                 return -1;
 968         }
 969         /* Now (finally ;-)) read the super block for mounting */
 970         if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
 971                 root_nfs_close(1);
 972                 return -1;
 973         }
 974         return 0;
 975 }
 976 
 977 
 978 /*
 979  *  Get the NFS port numbers and file handle, and then read the super-
 980  *  block for mounting.
 981  */
 982 int nfs_root_mount(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
 983 {
 984         if (root_nfs_open() < 0)
 985                 return -1;
 986         if (root_nfs_bind() < 0)
 987                 return -1;
 988         if (root_nfs_ports() < 0)
 989                 return -1;
 990         if (root_nfs_get_handle() < 0)
 991                 return -1;
 992         if (root_nfs_do_mount(sb) < 0)
 993                 return -1;
 994         root_nfs_close(0);
 995         return 0;
 996 }

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