root/fs/nfs/nfsroot.c

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

DEFINITIONS

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

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