<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook V4.1//EN">

<!-- TOCTITLE="Table of Contents" -->

<book id="ltsp-4.1-0" lang="en">

  <bookinfo>
    <title>LTSP - Linux Terminal Server Project - v4.1</title>

    <authorgroup>
        <author>
           <firstname>James</firstname>
           <surname>McQuillan</surname>
           <affiliation>
              <address><email>jam@LTSP.org</email>
              </address>
           </affiliation>
        </author>
    </authorgroup>

    <revhistory>
       <revision>
         <revnumber>4.1.3-en&nbsp;</revnumber>
         <date>2004-06-20</date>
         <authorinitials>jam</authorinitials>
       </revision>
    </revhistory>

    <copyright>
        <year>2004</year>
        <holder>James A. McQuillan</holder>
    </copyright>

    <abstract>
       <para>
           GNU/Linux makes a great platform for deploying diskless thin clients.
           The primary purpose of this document is to show you how to deploy
           thin clients using LTSP.  But, this document also covers many issues
           with diskless workstations in general.
       </para>
    </abstract>
  </bookinfo>

<preface>
    <title>Introduction</title>

    <para>
        The LTSP provides a simple way to utilize low cost workstations
        as either graphical or character based terminals on a GNU/Linux server.
    </para>

    <para>
        In a traditional office setting, there are relatively high powered
        Intel based PC's spread around at every desk.  Each with several
        gigabytes of hard disk space.  Users store their own data on the local
        hard drives and backups are rarely (if ever) performed.
    </para>

    <para>
        Does it really make sense to have a full computer at each desk?
    </para>

    <para>
        We say no.
    </para>

    <para>
        Fortunately, there is another way.  Utilizing the LTSP, you can take
        very low-end PCs, remove the hard drive, floppy and CDRom, and add
        a bootable network card.  Many network cards have bootrom sockets,
        just waiting for a bootrom to be inserted.
    </para>

    <para>
        During the boot phase, the diskless workstation obtains its IP info
        and a kernel from the
        server, then mounts the root filesystem from the server via NFS.
    </para>

    <para>
        The workstation can be configured in one of 3 modes:
        <itemizedlist>
            <listitem>
                <para><command>Graphical X Window System interface</command></para>
                <para>
                    Using X Windows, the workstation can be used to access
                    any applications on the server, or on other servers
                    within the network.
                </para>
            </listitem>
        </itemizedlist>

        <itemizedlist>
            <listitem>
                <para><command>Character based Telnet sessions</command></para>
                <para>
                    The workstation can invoke multiple telnet sessions to the
                    server.  Each Telnet session will be on a separate virtual
                    screen.  Pressing Alt-F1 through Alt-F9 will switch
                    between the telnet sessions.
                </para>
            </listitem>
        </itemizedlist>

        <itemizedlist>
            <listitem>
                <para><command>Shell prompt</command></para>
                <para>
                    The workstation can be configured to drop you right into
                    a bash shell at the console.  This is very useful when
                    debugging problems with X Windows or NFS.
                </para>
            </listitem>
        </itemizedlist>
    </para>

    <para>
        The really neat thing is that you can have lots of workstations served
        by a single GNU/Linux server.  How many workstations?  Well, that
        depends on the size of the server, and the applications that will
        be used.
    </para>

    <para>
        It's not unusual to have 50 workstations, all running Mozilla and
        OpenOffice from a Dual P4-2.4 with 4GB of ram.  We know this works.
        In fact, the load-average is rarely above 1.0!
    </para>

    <sect1>
        <title>Disclaimer</title>
        <para>
            Neither the author nor the distributors, or any other contributor of
            this document are in any way responsible for physical, financial,
            moral or any other type of damage incurred by following the
            suggestions in this text.
        </para>
    </sect1>

    <sect1 id="copyright">
        <title>Copyright and License</title>
        <para>
            This document is copyright 2004 by James McQuillan, and is 
            released under the terms of the GNU Free Documentation License,
            which is hereby incorporated by reference.  The GNU Free
            Documentation License can be found at
            http://www.gnu.org/licenses/fdl.html.
        </para>
    </sect1>
</preface>

<chapter>
    <title>Theory of operation</title>
    <para>
        Booting a diskless workstation involves several steps.  Understanding
        what is happening along the way will make it much easier to solve
        problems, should they arise.
    </para>
    <para>
        There are four basic services required to boot an LTSP workstation.
        They are:
        <itemizedlist>
            <listitem>
                <para>DHCP</para>
            </listitem>
            <listitem>
                <para>TFTP</para>
            </listitem>
            <listitem>
                <para>NFS</para>
            </listitem>
            <listitem>
                <para>XDMCP</para>
            </listitem>
        </itemizedlist>

    </para>

    <para>
        LTSP is very flexible.  Each of the above services can be
        served from the same server, or from several different servers.
        For our example, we'll describe a simple setup which consists
        of a single server, handling all of the above services.
    </para>

  <sect1>
    <title>The steps that the workstation will go through</title>

    <orderedlist spacing="normal">

        <listitem>
            <para>
                Load the linux kernel into the memory of the workstation.
                This can be done several different ways, including:
                <orderedlist>
                  <listitem>
                    <para>
                      Bootrom (Etherboot,PXE,MBA,Netboot)
                    </para>
                  </listitem>
                  <listitem>
                    <para>
                      Floppy
                    </para>
                  </listitem>
                  <listitem>
                    <para>
                      Harddisk
                    </para>
                  </listitem>
                  <listitem>
                    <para>
                      CD-ROM
                    </para>
                  </listitem>
                  <listitem>
                    <para>
                      USB Memory device
                    </para>
                  </listitem>
                </orderedlist>
            </para>
            <para>
              Each of the above booting methods will be explained later in this
              chapter.
            </para>
        </listitem>

        <listitem>
            <para>
                Once the kernel has been loaded into memory, it will begin
                executing.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The kernel will
                initialize the entire system and all of the peripherals
                that it recognizes.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                This is where the fun really begins.  During the kernel
                loading process, a ramdisk image will also be loaded
                into memory.
                A kernel command line argument of
                <command>root=/dev/ram0</command> tells the kernel to mount
                the image as the root directory.
            </para>
            <para></para>
        </listitem>
                 
        <listitem>
            <para>
                Normally, when the kernel is finished booting, it will launch
                the <command>init</command> program.  But, in this case,
                we've instructed the kernel to load a small shell script
                instead.
                We do this by passing <command>init=/linuxrc</command> on
                the kernel command line.
            </para>
            <para></para>
        </listitem>
                
        <listitem>
            <para>
                The <command>/linuxrc</command> script begins by scanning
                the PCI bus, looking for a network card. For each PCI device
                it finds, it does a lookup in the /etc/niclist file, to see
                if it finds a match.  Once a match is found, the name of
                the NIC driver module is returned, and that kernel module
                is loaded.  For ISA cards, the driver module MUST be specified
                on the kernel command line, along with any IRQ or address
                parameters that may be required.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                A small DHCP client called <command>dhclient</command> will
                then be run, to make another
                query from the DHCP server.  We need to do this separate
                user-space query, because we need more information than the
                bootrom retrieved with the first dhcp query.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                When <command>dhclient</command> gets a reply from the server,
                it will run the <command>/etc/dhclient-script</command> file,
                which will take the information retrieved, and configure the
                eth0 interface.
            </para>
            <para></para>
        </listitem>


        <listitem>
            <para>
                Upto this point, the root filesystem has been a ram disk.
                Now, the /linuxrc script will mount a new root filesystem
                via NFS.  The directory that is exported from the server
                is typlically <command>/opt/ltsp/i386</command>.
                It can't just mount the new filesystem as /.  It must
                first mount it as /mnt.  Then, it will do a
                <command>pivot_root</command>.  pivot_root will swap the
                current root filesystem for a new filesystem.  When it
                completes, the NFS filesystem will be mounted on /, and the
                old root filesystem will be mounted on /oldroot.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                Once the mounting and pivoting of the new root filesystem
                is complete, we are done with the /linuxrc shell script and
                we need to invoke the real <command>/sbin/init</command>
                program.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                Init will read the <filename>/etc/inittab</filename> file
                and begin setting up the workstation environment.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                One of the first items in the inittab file is the
                <command>rc.sysinit</command>
                command that will be run while the workstation is in the
                '<emphasis role="strong">sysinit</emphasis>' state.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The rc.sysinit script will create a 1mb ramdisk to contain
                all of
                the things that need to be written to or modified in any way.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The ramdisk will be mounted as the
                <filename class="directory">/tmp</filename>
                directory.  Any files that need to be written will actually
                exist in the <filename class="directory">/tmp</filename>
                directory, and there are symbolic links pointing to these files.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The <filename class="directory">/proc</filename> filesystem
                is mounted.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The <filename>lts.conf</filename> file will be parsed, and
                all of the parameters in that file that pertain to this
                workstation will be set as environment variables for the
                rc.sysinit script to use.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                If the workstation is configured to swap over NFS, the
                <command>/var/opt/ltsp/swapfiles</command> directory will
                be mounted as /tmp/swapfiles.  Then, if there isn't a 
                swapfile for this workstation yet, it will be created
                automatically.  The size of the swapfile is configured
                in the <filename>lts.conf</filename> file.
            </para>
            <para>
                The swapfile will then be enabled, using the
                <command>swapon</command> command.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The <emphasis role="strong">loopback</emphasis> network
                interface is configured.  This is the networking interface
                that has <emphasis>127.0.0.1</emphasis> as its IP address.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                If Local apps is enabled, then the <command>/home</command>
                directory will be mounted, so that the apps can access the
                users home directories.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                Several directories are created in the
                <filename class="directory">/tmp</filename> filesystem for
                holding some of the transient files that are needed while
                the system is running.  Directories such as:
                <orderedlist>
                    <listitem>
                        <para>
                            <filename>/tmp/compiled</filename>
                        </para>
                        <para></para>
                    </listitem>
                    <listitem>
                        <para>
                            <filename>/tmp/var</filename>
                        </para>
                        <para></para>
                    </listitem>
                    <listitem>
                        <para>
                            <filename>/tmp/var/run</filename>
                        </para>
                        <para></para>
                    </listitem>
                    <listitem>
                        <para>
                            <filename>/tmp/var/log</filename>
                        </para>
                        <para></para>
                    </listitem>
                    <listitem>
                        <para>
                            <filename>/tmp/var/lock</filename>
                        </para>
                        <para></para>
                    </listitem>
                    <listitem>
                        <para>
                            <filename>/tmp/var/lock/subsys</filename>
                        </para>
                        <para></para>
                    </listitem>
                </orderedlist>
            </para>
            <para></para>

            <para>
                will all be created.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The <filename>/tmp/syslog.conf</filename> file will be created.
                This file will contain information telling the
                <command>syslogd</command> daemon which host on the network
                to send the logging information to.  The syslog host is
                specified in the <filename>lts.conf</filename> file.  There
                is a symbolic
                link called <filename>/etc/syslog.conf</filename> that points
                to the <filename>/tmp/syslog.conf</filename> file.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The <command>syslogd</command> daemon is started, using the
                config file created in the previous step.
            </para>
            <para></para>
        </listitem>

        <listitem>
          <para>
               Once the rc.sysinit script is finished, control returns
               back to the /sbin/init program, which will change the
               runlevel from <emphasis role="strong">sysinit</emphasis>
               to <emphasis role="strong">5</emphasis>.
          </para>
          <para>
               This will cause any of the entries in the
               <filename>/etc/inittab</filename> file to be executed.
          </para>
          <para></para>
        </listitem>

        <listitem>
          <para>
               By default, there are entries in inittab to run
               the <command>/etc/screen_session</command> script on tty1,
               tty2 and tty3.  That means that you can run 3 sessions
               at a time, and the type of session is controlled by
               the <emphasis role="strong">SCREEN_01</emphasis>,
               <emphasis role="strong">SCREEN_02</emphasis> and
               <emphasis role="strong">SCREEN_03</emphasis> entries
               in <filename>lts.conf</filename>.
          </para>
          <para>
               More entries can be setup in <filename>inittab</filename>
               for more sessions, if desired.
          </para>
          <para></para>
        </listitem>

        <listitem>
            <para>
                If <emphasis role="strong">SCREEN_01</emphasis> is set
                to a value of <emphasis role="strong">startx</emphasis>,
                then the <command>/etc/screen.d/startx</command> script
                will be executed, which will launch the X Windows System,
                giving you a graphical user interface.
            </para>
            <para>
                In the <command>lts.conf</command> file, there is a parameter
                called <command>XSERVER</command>.  If this parameter
                is missing, or set to "<command>auto</command>", then
                an automatic detection of the video card will be attempted.
                If the card is PCI or AGP, then it will get the PCI Vendor
                and Device id, and
                do a lookup in the <command>/etc/vidlist</command> file.
            </para>
            <para>
                If the card is supported by Xorg 6.7, the pci_scan routine
                will return the name of the driver module.  If it is only
                supported by XFree86 3.3.6, pci_scan will return the name of
                the X server to use.  The startx script can tell the
                difference because the older 3.3.6 server names start
                with 'XF86_', whereas the newer Xorg X sesrver modules
                are typically lowercase names, like <emphasis>ati</emphasis>
                or <emphasis>trident</emphasis>.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                If Xorg is used, then the
                <command>/etc/build_x4_cfg</command> script will be called to
                build an XF86Config file.  If XFree86 3.3.6 is used,
                then <command>/etc/build_x3_cfg</command> will be called to
                build the XF86Config file.  These files are placed in the
                <filename>/tmp</filename> directory.  Which, if you'll remember,
                is a ramdisk, seen only by the workstation.
            </para>
            <para>
                The XF86Config file will be built, based on entries in the
                <command>/etc/lts.conf</command> file.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                Once the XF86Config file has been built, then the
                <command>startx</command> script will launch the X server
                with that new config file.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                The X server will send an
                <emphasis role="strong">XDMCP</emphasis> query to the LTSP
                server, which will offer a login dialog.
            </para>
            <para></para>
        </listitem>

        <listitem>
            <para>
                At this point, the user can log in.  They'll get a
                session on the server.
            </para>
            <para>
                This confuses alot of people at first.  They are sitting
                at a workstation, but they are running a session on the
                server.  All commands they run, will be run on the server,
                but the output will be displayed on the workstation.
            </para>
            <para></para>
        </listitem>

    </orderedlist>
  </sect1>

  <sect1>
    <title>Loading the kernel into memory</title>
    <para>
      Getting the Linux kernel into the workstations memory can be accomplished
      in a variety of ways.
    </para>
    <itemizedlist>
      <listitem>
        <para>Boot ROM</para>
      </listitem>
      <listitem>
        <para>Local media</para>
      </listitem>
    </itemizedlist>
    <para></para>

    <sect2>
      <title>Boot ROM</title>
      <itemizedlist>
         <listitem>
           <para>Etherboot</para>
           <para>
             Etherboot is a very popular open-source bootrom project.
             It contains drivers for many common network cards, and
             works very well with LTSP.
           </para>
           <para>
             Linux kernels must be tagged with the
             <command>mknbi-linux</command>, which will prepare the kernel
             for network booting, by prefixing the kernel with some additional
             code, and appending the initrd to the end of the kernel.
           </para>
           <para>
             The kernels that are supplied with LTSP are already tagged, and
             ready to boot with Etherboot.
           </para>
           <para>
             Etherboot can also be written to a floppy, which works great
             for testing.
           </para>
         </listitem>
         <listitem>
           <para>PXE</para>
           <para>
              Part of the 'Wired for Management' specification from the late
              1990's included a specification for a bootrom technology known
              as the <emphasis>Pre-boot Execution Environment</emphasis> 
              commonly abreviated as <emphasis role="strong">PXE</emphasis>.
           </para>

           <para>
              A PXE bootrom can load at most a 32 kilo-byte file.  A Linux
              kernel is quite a bit larger than that. Therefore, we setup
              PXE to load a 2nd stage boot-loader called
              <emphasis role="strong">pxelinux</emphasis>.  pxelinux is
              small enough to be loaded, and it knows how to load much
              larger files, such as a Linux kernel.
           </para>
         </listitem>
         <listitem>
           <para>MBA</para>
           <para>
              Managed Boot Agent (MBA) is a bootrom from a company named
              <emphasis role="strong">emBoot</emphasis>.  emBoot used to be
              the Lanworks division of 3Com.  MBA is really
              four bootroms in one.  It will handle PXE, TCP/IP, RPL and
              Netware.
           </para>
           <para>
              The MBA implementation of PXE works very well.  You can use
              it with pxelinux to boot a Linux kernel.
           </para>
           <para>
              The <emphasis role="strong">TCP/IP</emphasis> method can be used,
              but the kernel must first be prepared with a utility called
              <command>imggen</command>.
           </para>
         </listitem>
         <listitem>
           <para>Netboot</para>
           <para>
             Netboot, like Etherboot, is a free software project that provides
             boot ROM images.  The difference is that Netboot is a wrapper
             around the NDIS driver or packet drivers that the manufacturer
             ships with the card.
           </para>
         </listitem>
      </itemizedlist>
    </sect2>

    <sect2>
      <title>Local media</title>
      <itemizedlist>
         <listitem>
           <para>Floppy disk</para>
           <para>
             There are 2 ways to boot a LTSP workstation with a floppy.
             One way is to load Etherboot in the boot sector of the floppy.
             Then, it will act just like a bootrom.  The boot code will be
             executed, the network card will be initialized, and the kernel
             will be loaded from the network server.
           </para>
           <para>
             You can also write the kernel and initrd to the floppy, and boot
             that way.  However, it is actually faster to load the kernel
             over the network.
           </para>
         </listitem>
         <listitem>
           <para>Hard disk</para>
           <para>
              The hard disk can be used with LILO or GRUB, to load the 
              Linux kernel and initrd. OR, you can load the Etherboot bootrom
              image from the harddisk, and it will act like a bootrom.
           </para>
         </listitem>
         <listitem>
           <para>CD-ROM</para>
           <para>
              A bootable CD-ROM can be loaded either with a Linux kernel, or
              an Etherboot image.
           </para>
         </listitem>
         <listitem>
           <para>USB Memory device</para>
           <para>
              Just like a CD-ROM, Floppy disk and Hard disk, you can use a
              USB Memory device to boot either an Etherboot module, or a
              complete Linux kernel and initrd image.
           </para>
         </listitem>
      </itemizedlist>
    </sect2>

  </sect1>

</chapter>


<chapter>
    <title>Installing LTSP on the server</title>
    <para>
      LTSP is best thought of as a complete distribution of Linux.  It's a
      distribution that sits on top of a host distribution.  the Host distro
      can be any Linux distro that you want.   In fact, there's no real
      requirement that the host be running Linux.  
      The only requirement is that the host system needs to be able
      to serve NFS (Network File System).  Most any Unix system can handle
      that. In fact, even some versions of Microsoft Windows can be configured
      to work as a LTSP server.
    </para>

    <para>
      There are three phases to building an LTSP server.
      <itemizedlist>

        <listitem>
          <para>Installing the LTSP utilities</para>
        </listitem>

        <listitem>
          <para>Installing the LTSP client packages</para>
        </listitem>

        <listitem>
          <para>Configuring the services needed by LTSP</para>
        </listitem>

      </itemizedlist>
    </para>

    <sect1>
        <title>Installing the LTSP utilities</title>
      <para>
        Starting with version 4.1, LTSP has a package of utilities for
        installing and managing the LTSP client packages (The stuff that
        is executed on the thin clients), and for configuring
        the services on the LTSP server.
      </para>

      <para>
        The administration utility is called <command>ltspadmin</command>
        and the configuration tool is called <command>ltspcfg</command>.
        Both of these tools are part of the <command>ltsp-utils</command>
        package.
      </para>

      <para>
        The <emphasis role="strong">ltsp-utils</emphasis> package is available
        in both
        <emphasis role="strong">RPM</emphasis> and
        <emphasis role="strong">TGZ</emphasis> formats.  Choose which
        format you prefer to install, and follow the appropriate
        instructions.
      </para>

      <sect2>
        <title>Installing the RPM package</title>
        <para>
            Download the latest release of the ltsp-utils RPM package, and
            install it using the following command:
            <programlisting>
rpm -ivh ltsp-utils-0.1-0.noarch.rpm</programlisting>
            The above commands will install the utilities on the server.
        </para>
      </sect2>

      <sect2>
        <title>Installing the TGZ packages</title>
        <para>
            Download the latest release of the ltsp-utils TGZ package
            and install it using the following commands:
            <programlisting>
tar xzf ltsp-utils-0.1-0.noarch.tgz
cd ltsp_utils
./install.sh
cd ..</programlisting>
            The above commands will install the utilities on the server.
            This is useful for non-RPM based systems.
        </para>
      </sect2>
    </sect1>

    <sect1>
        <title>Installing the LTSP client packages</title>
        <para>
            Once the installation of the ltsp-utils package is complete,
            you can run the <command>ltspadmin</command> command.
            This utility is used to manage the LTSP Client packages.
            It will query the LTSP download repository, and get the
            list of currently available packages.
        </para>

        <para>
          Run the <command>ltspadmin</command> command and you'll see
          a screen like the following:
        </para>
        <para>
          <figure>
            <title>LTSP installer - Main Screen</title>
            <GRAPHIC FILEREF="pics/installer_main_window.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>

        </para>

        <para>
          From this screen, you can choose "Install/Update", and
          if this is your first time running the utility, it will
          display the installer configuration screen.
        </para>
        <para>
          <figure>
            <title>LTSP installer - Configuration Screen</title>
            <GRAPHIC FILEREF="pics/installer_config_window.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>
        </para>

        <para>
          In the <emphasis role="strong">configuration</emphasis> screen,
          you can set several values that the installer will use, for
          downloading and installing the LTSP packages.
          Those values are:
          <variablelist>

            <varlistentry>
              <term><command>Where to retrieve packages from</command></term>
              <listitem>
                <para>
                  This is a URL, pointing to the the package repository.
                  Typically, this would be
                  <filename>http://www.ltsp.org/ltsp-4.1</filename>, but if you
                  want to install the packages from a local filesystem, you
                  can use the <filename>file:</filename> instead.  For instance,
                  if the packages are on a CD-ROM, and you've mounted the CD-ROM
                  on <filename>/mnt/cdrom</filename>, then the value for the
                  package repository would be:
                  <filename>file:///mnt/cdrom</filename>. (Notice the 3
                  slashes).
                </para>
                <para></para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>In which directory would you like to place the LTSP client tree</command></term>
              <listitem>
                <para>
                  This is the directory on the server, where you'd like to
                  put the LTSP client tree.  Typically, this would be:
                  <filename>/opt/ltsp</filename>.  The directory will be
                  created, if it does not already exist.
                </para>
                <para>
                  Within this directory, the root directories for each
                  architecture will be created.  Currently, only x86
                  workstations are officially supported by LTSP, but there
                  are several people working on ports to other architectures,
                  such as PPC and Sparc.
                </para>
                <para></para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>HTTP Proxy</command></term>
              <listitem>
                <para>
                  If the server is behind a firewall, and all web access must
                  go through a proxy, you can configure the installer to use
                  the proxy here.  The value should contain the URL to the
                  proxy, including the protocol and the port.  An example
                  for this setting is:
                  <filename>http://firewall.yourdomain.com:3128</filename>.
                </para>
                <para>
                  If you don't need a proxy, you should set this to 
                  "<filename>none</filename>".
                </para>
                <para></para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>FTP Proxy</command></term>
              <listitem>
                <para>
                  For packages located on an FTP server, if you need to
                  go through an FTP proxy, you can enter it here.  The syntax
                  is similar to the HTTP Proxy option above.
                </para>
                <para>
                  If you don't need a proxy, you should set this to 
                  "<filename>none</filename>".
                </para>
                <para></para>
              </listitem>
            </varlistentry>
          </variablelist>
        </para>

        <para>
          Once you get past the configuration screen, the installer will
          query the package repository, and obtain the list of currently
          available components.
        </para>

        <para>
          <figure>
            <title>LTSP installer - Component list</title>
            <GRAPHIC FILEREF="pics/installer_comp_list_window.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>
          Select each component that you want to install.  To select it,
          move the high-lighted line to that component, and press
          '<command>I</command>' to select the individual component.
          You can also press '<command>A</command>' to select ALL of the
          components.  Most of the time, this will be what you want.  That
          way, you can support the broadest range of thin client hardware.
        </para>

        <para>
          There are several keys that can be used to navigate around this
          screen.  You can get help on those keys by pressing the
          '<command>H</command>' key.
          <figure>
            <title>LTSP installer - Help window</title>
            <GRAPHIC FILEREF="pics/installer_help_window.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>
        </para>

        <para>
          If you want to see the list of packages that are in a particular
          component, you can press '<command>S</command>', and the list
          of packages will be displayed.  It will show the version currently
          installed, and also the latest available version.

          <figure>
            <title>LTSP installer - Package list</title>
            <GRAPHIC FILEREF="pics/installer_pkg_list_window.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>
        </para>

        <para>
          Once the desired components are selected, you can exit the
          component selection screen.  The installer will prompt you,
          to see if you really want to install/update the selected
          packages.  If you answer '<command>Y</command>', then it will
          download and install the selected packages.
        </para>

    </sect1>

    <sect1>
        <title>Configuring the services needed by LTSP</title>
        <para>
          There are four basic services required to support the booting
          of an LTSP workstation.  They are:
          <itemizedlist>
            <listitem><para>DHCP</para></listitem>
            <listitem><para>TFTP</para></listitem>
            <listitem><para>NFS</para></listitem>
            <listitem><para>XDMCP</para></listitem>
          </itemizedlist>
        </para>

        <para>
          The <command>ltspcfg</command> can be used to configure all of
          those services, plus alot of other LTSP related things.
        </para>
        <para>
          You can access <command>ltspcfg</command> from the
          <command>ltspadmin</command>, or you can run
          <command>ltspcfg</command> by typing it at the command line.
        </para>

        <para>
          When you run the ltspcfg utility, it will scan the server, to
          assess what is currently installed and running.  You'll
          see a screen like:
          <figure>
            <title>ltspcfg - Initial screen</title>
            <GRAPHIC FILEREF="pics/ltspcfg_initial_screen.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>
          This shows all of the things that the utility is looking for.
        </para>

        <para>
          To configure all of the things that need to be setup, choose
          '<command>C</command>', and the configuration menu will be displayed.
          From the configuration menu, you'll need to go through each item, to
          make sure it is configured properly for serving LTSP workstations.

          <figure>
            <title>ltspcfg - Initial screen</title>
            <GRAPHIC FILEREF="pics/ltspcfg_service_list.jpg"
                     FORMAT="JPG"
                     SRCCREDIT="James McQuillan, 2004" >
          </figure>

          <variablelist>
            <varlistentry>
              <term><command>1 - Runlevel</command></term>
              <listitem>
                <para>
                  The <command>Runlevel</command> is variable used by the
                  <command>init</command> program.  With Linux and Unix
                  systems, at any given time, the system is said to be in
                  a specific "Runlevel".  Runlevel 2 or 3 is typically used
                  when the server is in text mode.  Runlevel 5 typically
                  indicates the system is in graphical mode on a network.
                </para>
                <para>
                  For an LTSP server, traditionally Runlevel 5 is used.  Most
                  systems are already configured to serve NFS and XDMCP when
                  in Runlevel 5.  For those systems that aren't already
                  configured for that, this utility will take care of them.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>2 - Interface selection</command></term>
              <listitem>
                <para>
                  For systems that have multiple network interfaces, you'll
                  need to specify which interface the Thin clients are 
                  connected to.
                </para>
                <para>
                  By selecting the interface, the configuration tool will be
                  able to properly create other configuration files, such
                  as the <filename>dhcpd.conf</filename> and the 
                  <filename>/etc/exports</filename> files.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>3 - DHCP configuration</command></term>
              <listitem>
                <para>
                  DHCP needs to be configured to supply the required
                  fields to the workstation.  Among those fields are
                  <command>fixed-address</command>, <command>filename</command>,
                  <command>subnet-mask</command>,
                  <command>broadcast-address</command> and 
                  <command>root-path</command>.
                </para>
                <para>
                  By selecting this menu item, you'll be able to create the
                  <filename>dhcpd.conf</filename> configuration file, and
                  enable <command>dhcpd</command> to run at startup time.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>4 - TFTP configuration</command></term>
              <listitem>
                <para>
                  TFTP is used by the thin client to download the Linux
                  kernel.  The <command>tftpd</command> service needs to
                  be enabled on the server, to serve up the kernel.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>5 - Portmapper configuration</command></term>
              <listitem>
                <para>
                  The <command>Portmapper</command> is used by RPC services.
                  Each RPC service, such as NFS.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>6 - NFS configuration</command></term>
              <listitem>
                <para>
                  NFS is the service that allows local directory trees to be
                  mounted by remote machines.  This is required for LTSP,
                  because the workstations mount their root filesystems
                  from the server.
                </para>
                <para>
                  This menu item will take care of configuring NFS to start
                  at bootup time.  The configuration file is
                  <filename>/etc/exports</filename> and its creating is
                  described later in this section.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>7 - XDMCP configuration</command></term>
              <listitem>
                <para>
                  XDMCP is the "X Display Manager Control Protocol".  The
                  X server sends an XDMCP query to the Display manager on
                  the server, to get a login prompt.
                </para>
                <para>
                  Common display managers in use are <command>XDM</command>,
                  <command>GDM</command> and <command>KDM</command>.
                  This menu item will display which display managers are found,
                  and which one is configured to run.
                </para>

                <para>
                  For security purposes, the Display manager is configured by
                  default to NOT allow remote workstations to connect.  This is
                  usually the reason for the infamous
                  <emphasis role="strong">Gray screen with large X cursor</emphasis>.
                  ltspcfg can usually configure the display manager to
                  allow remote workstations to get a connection.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term><command>8 - Create /etc/hosts entries</command></term>
              <listitem>
                <para>
                  Many services, like NFS and the Display manager need to be
                  able to map the IP address of the workstation to a hostname.
                  You could setup the Berkeley Intenet Naming Daemon (BIND)
                  to do that, but you'd have to make sure you get the
                  <emphasis role="strong">reverses</emphasis> setup properly.
                  Ultimately, using bind is probably the best way to do it,
                  but configuration of bind is beyond the scope of this 
                  document and the ltspcfg utility.
                </para>

                <para>
                  A much simpler approach for configuring the mapping of
                  IP addresses and hostnames is the
                  <filename>/etc/hosts</filename> file.
                </para>

              </listitem>
            </varlistentry>

            <varlistentry>
              <term>
                     <command>9 - Create /etc/hosts.allow entries</command>
              </term>
              <listitem>
                <para>
                  Some services use a layer of security known as
                  <emphasis role="strong">tcpwrappers</emphasis>.  This is
                  configured through the <filename>/etc/hosts.allow</filename>
                  file.  This menu item will setup that file for you.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>
                     <command>10 - Create the /etc/exports file</command>
              </term>
              <listitem>
                <para>
                  This is the file that NFS uses, to determine which
                  directories are allowed to be mounted by remote machines.
                  This menu item will create that file.
                </para>
              </listitem>
            </varlistentry>

            <varlistentry>
              <term>
                     <command>11 - Create the lts.conf file</command>
              </term>
              <listitem>
                <para>
                  The configuration of each workstation is directed by 
                  entries in the <filename>lts.conf</filename> file.  For
                  fairly modern workstations with a PCI bus, it shouldn't
                  require any additional entries in the lts.conf file. But,
                  the file still needs to exist.  This menu item will
                  create the default lts.conf file for you.
                </para>
              </listitem>
            </varlistentry>

          </variablelist>
        </para>

    </sect1>

    <sect1>
        <title>Workstation specific configuration</title>
        <para>
            Now, it's time to tell the LTSP server about your specific
            workstation.  There are three files that contain information
            about the workstation.

            <orderedlist>

                <listitem>
                    <para>/etc/dhcpd.conf</para>
                </listitem>

                <listitem>
                    <para>/etc/hosts</para>
                </listitem>

                <listitem>
                    <para>/opt/ltsp/i386/etc/lts.conf</para>
                </listitem>

            </orderedlist>

        </para>

        <sect2>
            <title>/etc/dhcpd.conf</title>
            <para>
                The workstation needs an IP address and other information.
                It will get the following from the DHCP server:
                <itemizedlist>
                    <listitem> <para>IP address</para> </listitem>
                    <listitem> <para>hostname</para> </listitem>
                    <listitem> <para>Server IP address</para> </listitem>
                    <listitem> <para>Default gateway</para> </listitem>
                    <listitem> <para>Pathname of kernel to load</para> </listitem>
                    <listitem> <para>Server and directory path
                                     to be mounted as the root filesystem
                               </para> </listitem>
                </itemizedlist>
            </para>
            <para>
                For our example LTSP environment, we have chosen DHCP
                for handling IP address assignment to the workstations.
            </para>
            <para>
                During the ltsp_initialize script, a sample dhcpd.conf file
                is installed.  It is called
                <filename>/etc/dhcpd.conf.example</filename>
                you can copy that file to 
                <filename>/etc/dhcpd.conf</filename> to use it as
                a basis for your dhcp configuration.  You will need to
                modify the parts of this file that pertain to your
                specific workstation and server environment.
                <figure float="1">
                <title>/etc/dhcpd.conf</title>
                <programlisting>
default-lease-time            21600;
max-lease-time                21600;
    
option subnet-mask            255.255.255.0;
option broadcast-address      192.168.0.255;
option routers                192.168.0.254;
option domain-name-servers    192.168.0.254;
option domain-name            "ltsp.org";
option root-path              "192.168.0.254:/opt/ltsp/i386";
    
shared-network WORKSTATIONS {
    subnet 192.168.0.0 netmask 255.255.255.0 {
    }
}
    
group	{
    use-host-decl-names       on;
    option log-servers        192.168.0.254;
    
    host ws001 {
        hardware ethernet     00:E0:18:E0:04:82;
        fixed-address         192.168.0.1;
        filename              "/lts/vmlinuz.ltsp";
    }
} </programlisting>
                </figure>
            </para>

            <para>
                As of LTSP, version 2.09pre2, you no longer have to
                specify a particular kernel to load.  The standard
                kernel package supports all of the network cards that
                Linux supports.  There are two kernel files included
                in the LTSP kernel package.  One kernel has the
                Linux Progress Patch (LPP) applied, and the other
                kernel does not.  The names for the kernels are:
                <programlisting>
vmlinuz-2.4.9-ltsp-5
vmlinuz-2.4.9-ltsp-lpp-5 </programlisting>
            </para>
            <para>
                You may have noticed that the kernel is sitting in
                the <filename class="directory">/tftpboot/lts</filename>
                directory, but in the "filename" entry in the 
                <filename>/etc/dhcpd.conf</filename> file is missing the
                leading <filename class="directory">/tftpboot</filename>
                component of the pathname.  That is because on Redhat 
                versions 7.1 and above,
                TFTP is run with the '-s' option.  That causes the tftpd
                daemon to run in <emphasis role="strong">secure</emphasis>
                mode.  That is, it does a <command>chroot</command> to the
                <filename class="directory">/tftpboot</filename> directory
                when it starts.  Therefore, all files that are available
                to the tftpd daemon are relative to the 
                <filename class="directory">/tftpboot</filename> directory.
            </para>
            <para>
                Other Linux distributions may not have the '-s' option
                set for tftpd, so you will need to add the 
                <filename class="directory">/tftpboot</filename> prefix
                to the kernel pathname.
            </para>
        </sect2>

        <sect2>
            <title>/etc/hosts</title>
            <para>IP address to hostname mapping</para>
            <para>
                Computers generally communicate just fine with IP
                addresses.  Then, us humans come along and 
                need to put names on the computers, because we can't
                remember the numbers.  That's where DNS or the
                <filename>/etc/hosts</filename> file come into play.  This
                IP address to hostname mapping generally isn't required,
                except in an LTSP environment.  That's because without it,
                NFS will give you permissions errors when the workstation
                attempts to mount the root filesystem.
            </para>
            <para>
                In addition to NFS problems, if the workstation is
                not listed in the <filename>/etc/hosts</filename> file,
                you may also have problems with the
                <emphasis role="strong">GDM</emphasis> or
                <emphasis role="strong">KDM</emphasis> display managers.
            </para>
        </sect2>

        <sect2>
            <title>/opt/ltsp/i386/etc/lts.conf</title>
            <para>
                There are a number of configuration entries that can
                be specified in the lts.conf file.
            </para>

            <para>
                The <filename>lts.conf</filename> file has a simple
                syntax, that consists of multiple sections.  There is
                a default section called <command>[default]</command> and
                there can be sections for individual workstations.  The
                workstations can be identified by hostname, IP address or
                MAC address.
            </para>

            <para>
                A typical <filename>lts.conf</filename> file looks like
                this:
                <example>
                    <title>lts.conf file</title>
                    <programlisting>
#
# Config file for the Linux Terminal Server Project (www.ltsp.org)
#

[Default]
        SERVER             = 192.168.0.254
        XSERVER            = auto
        X_MOUSE_PROTOCOL   = "PS/2"
        X_MOUSE_DEVICE     = "/dev/psaux"
        X_MOUSE_RESOLUTION = 400
        X_MOUSE_BUTTONS    = 3
        USE_XFS            = N
        LOCAL_APPS         = N
        RUNLEVEL           = 5

[ws001]
        USE_NFS_SWAP       = Y
        SWAPFILE_SIZE      = 48m
        RUNLEVEL           = 5

[ws002]
        XSERVER            = XF86_SVGA
        LOCAL_APPS         = N
        USE_NFS_SWAP       = Y
        SWAPFILE_SIZE      = 64m
        RUNLEVEL           = 3</programlisting>
                </example>
            </para>

            <para>
                The following is a list of some of those entries:
                <variablelist>
                    <varlistentry>
                        <term><command>XSERVER</command></term>
                        <listitem>
                            <para>
                                If your video card is a PCI card, and if
                                it is supported by X.org 6.7.0, then you
                                just need the lts_x_core package.  That
                                contains all of the driver modules for X4.
                            </para>
                            <para>
                                There are several XFree86 3.3.6 packages
                                available for LTSP.  This is in case your
                                card isn't supported by X.org 6.7.0.
                            </para>
                            <para>
                                You can make entries in the
                                <filename>lts.conf</filename> for each
                                individual workstation, or you can make
                                default entries that are shared by all
                                workstations.
                            </para>
                            <para>
                                Our workstation has an Intel i810 video
                                chipset, and it can correctly be auto
                                detected, so we don't need any XSERVER
                                entry in the lts.conf file.  The XSERVER
                                entry can be specified, if you want, or it
                                can be set to 'auto' to show that it is
                                going to be auto detected.
                            </para>
                        </listitem>
                    </varlistentry>

                    <varlistentry>
                        <term><command>RUNLEVEL</command></term>
                        <listitem>
                            <para>
                                We want to run the workstation in graphical
                                mode, so we need to set the runlevel to
                                '5'.  This is done by another entry in
                                the <filename>lts.conf</filename> file.
                            </para>
                        </listitem>
                    </varlistentry>
                </variablelist>
            </para>
        </sect2>

    </sect1>

    <sect1>
        <title>Displaying the current configuration</title>
        <para>
            With <command>ltspcfg</command>, you can get a look at the
            current status of all of the services required by LTSP.
            From the ltspcfg main menu, press '<command>S</command>', and
            you will see the current status.

            <figure>
              <title>ltspcfg - Current Status</title>
              <GRAPHIC FILEREF="pics/ltspcfg_status.jpg"
                       FORMAT="JPG"
                       SRCCREDIT="James McQuillan, 2004" >
            </figure>
        </para>

    </sect1>

</chapter>


<chapter>
    <title>Setting up the workstation</title>
    <para>
        Once the server is setup, it is time to focus on setting
        up the workstation.
    </para>
    <para>
        The LTSP project is all about what happens after the kernel
        is in memory.  There are several ways to get the kernel
        into memory, including Etherboot, Netboot, PXE and floppy disk.
    </para>

    <sect1>
      <title>Booting with PXE</title>
      <para>
        If your network card or PC has PXE built into it, then you 
        can use that to load the Linux kernel.  PXE is a bootrom technology,
        similar to Etherboot or Netboot.
      </para>

      <para>
        You may need to enable the PXE bootrom on your NIC.   You may also
        need to change the boot device order in your BIOS, to make
        "Boot from LAN" the first choice, rather than booting from the floppy
        or the hard disk.
      </para>

      <para>
        PXE has a limitation of only being able to load files that are
        32kb or smaller.  The Linux kernel is quite a bit larger than that,
        so you can't load the Linux kernel directly with PXE.  You need to
        load something known as a 'Network Bootstrap Program' or NBP.
      </para>

      <para>
        There is an NBP available for loading Linux kernels called
        <command>pxelinux.0</command>.  This is part of the
        <command>syslinux</command> package from kernel developer
        H. Peter Anvin.
      </para>

      <para>
        The LTSP kernel package includes the pxelinux.0 NBP and the
        configuration file needed to load the Linux kernel and an initial
        ramdisk image.
      </para>
      <para>
        The way it works, is this:
        <itemizedlist>
          <listitem>
            <para>
              The PXE bootrom initialializes the network card and
              sends a DHCP request.
            </para>
          </listitem>
          <listitem>
            <para>
              The DHCP server replies with an IP address, and the name of
              the NBP to load.
            </para>
          </listitem>
          <listitem>
            <para>
              The PXE bootrom downloads the NBP, places it in memory, and
              starts executing it.
            </para>
          </listitem>
          <listitem>
            <para>
              The NBP uses tftp to download the configuration file from the
              server.
            </para>
          </listitem>
          <listitem>
            <para>
              The configuration file contains the name of the kernel, the name
              of the initial ramdisk file, and options to pass to the kernel,
              once it is loaded.
            </para>

            <para>
              Here is an example of the pxelinux configuration file:
              <programlisting>
prompt=0
label linux
        kernel bzImage-2.4.24-ltsp-4
        append init=/linuxrc rw root=/dev/ram0 initrd=initrd-2.4.24-ltsp-4.gz
              </programlisting>
            </para>
          </listitem>
          <listitem>
            <para>
              The NBP then uses tftp to download the Linux kernel, and
              the initial ramdisk (initrd).
            </para>
          </listitem>
          <listitem>
            <para>
              Control is then passed to the Linux kernel, it boots up, mounts
              the initrd, and continues on with the startup of the Thin client.
            </para>
          </listitem>
        </itemizedlist>
      </para>

    </sect1>

    <sect1>
      <title>Booting with Etherboot</title>
      <blockquote><attribution>Ken Yap</attribution>
        <para>
          Etherboot is a software package for creating ROM images that
          can download code over an Ethernet network to be executed on
          an x86 computer.  Many network adapters have a socket where
          a ROM chip can be installed.  Etherboot is code that can be
          put in such a ROM.
        </para>
      </blockquote>

      <para>
          Etherboot is also Open Source, protected under the GNU General
          Public License, Version 2 (GPL2).
      </para>

      <para>
          To use Etherboot, if you have a network card with an Etherboot
          bootrom, may need to change your BIOS configuration to tell it to
          "Boot from LAN" before booting from floppy or hard disk.
      </para>

      <para>
          If you don't yet have an Etherboot bootrom, you can either make
          a bootrom, or you can make a floppy disk with an Etherboot image
          on its boot sector.
      </para>
      <para>
          Etherboot supports a very large number of network cards.  Over 200
          models, with more being added all the time.
          Whether you choose to make a floppy or a burn the code to an Eprom,
          you'll need to determine which model network card you have.
      </para>

      <sect2>
        <title>Choosing an Etherboot driver for an ISA network card</title>
        <para>
            For older ISA based network cards, it isn't so important that you
            determine the exact type.  First of all, most of them are either
            ne2000 or 3Com 3c509 cards.  You just need to pick the right
            Etherboot driver, the one that selects the correct media type
            on cards that both 10 base-2 (Coax) and 10 base-T (Twisted pair).
        </para>
      </sect2>

      <sect2>
        <title>Choosing an Etherboot driver for a PCI network card</title>
        <para>
            For PCI cards, it is important that you pick the Etherboot driver
            that matches the PCI Vendor and Device ID of the network card.
        </para>

        <para>
          Sometimes, you'll get lucky.  You'll know exactly which model card
          you have, because the model number is printed on the card, and
          it exactly matches the description of one of the Etherboot
          modules.  But, in many cases, you will need to find the PCI
          ID numbers.
        </para>

        <para>
          If your workstation has a floppy drive, you can boot a
          tomsrtbt (Tom's Root Boot) floppy.  Or, if your workstation has
          a CD-ROM drive, you can boot a Knoppix CD.
          If you can't load linux on your workstation, then your only hope
          may be to move the network card to a machine that can boot
          Linux.
        </para>


        <para>
          Once you have Linux booted, you can use the <command>lspci</command>
          command.  with the '-n' option.
          <programlisting>
[root@jamlap root]# lspci -n
0000:00:00.0 Class 0600: 8086:7190 (rev 03)
0000:00:01.0 Class 0604: 8086:7191 (rev 03)
0000:00:03.0 Class 0607: 104c:ac1c (rev 01)
0000:00:03.1 Class 0607: 104c:ac1c (rev 01)
0000:00:07.0 Class 0680: 8086:7110 (rev 02)
0000:00:07.1 Class 0101: 8086:7111 (rev 01)
0000:00:07.2 Class 0c03: 8086:7112 (rev 01)
0000:00:07.3 Class 0680: 8086:7113 (rev 03)
0000:00:08.0 Class 0401: 125d:1978 (rev 10)
0000:01:00.0 Class 0300: 1002:4c4d (rev 64)
0000:06:00.0 Class 0200: 8086:1229 (rev 09)
          </programlisting>
          In the example above, you can
          see an entry for each of the PCI cards in the system.  You only need
          to look at the <emphasis role="strong">Class 0200</emphasis> devices.
          So, running the command again, looking only at the Ethernet 
          interfaces, the list becomes much more manageable.
          <programlisting>
[root@jamlap root]# lspci -n | grep "Class 0200"
0000:06:00.0 Class 0200: 8086:1229 (rev 09)
          </programlisting>
          The PCI ID numbers are: <command>8086:1229</command>.  The
          first field, <command>8086</command> is the PCI Vendor ID. In this
          example, the vendor is the Intel Corporation.  The second field,
          <command>1229</command> is the PCI Device ID.  That tells us which
          model of the network card.  In this case, it's an 
          EtherExpress 100 card.
        </para>

      </sect2>

      <sect2>
          <title>Creating a boot floppy</title>

          <para>
          </para>

          <para>
              You can download the Etherboot package and configure it for
              the type of bootrom that you need.  Then, you can compile the
              source to produce a bootrom image that can be written to an
              EPROM, or written to a floppy disk.
          </para>

          <para>
              A much simpler approach is to go to Marty Connor's
              <ulink url="http://www.rom-o-matic.net"><citetitle>www.Rom-O-Matic.net</citetitle></ulink>
              website.
          </para>

          <para>
              Marty has done an excellent job of putting a web based
              front-end on the configuration and compilation process of
              making bootrom images with Etherboot.  On his site, you
              select what type of network card you have, and what kind
              of image you want.  Then, you have an opportunity to
              modify many Etherboot configuration options.  Then, you
              can press the 'Get ROM' button and a custom bootrom image
              will be generated while you wait.
          </para>

          <para>
              For the ROM output format, choose 'Floppy Bootable ROM Image'.
              This will cause it to include a 512 byte header that is a boot
              loader for loading the etherboot image into ram where it can be
              executed.
          </para>

          <para>
              Press the 'Get ROM' button.  The bootrom image will be generated
              while you wait.
              It only takes a few seconds, and when it completes, your browser
              will pop-up a "Save As" window where you can designate where
              you want the bootrom image to be saved on your computer.
          </para>

        <para>
            Once you've saved the image to your hard drive, you need
            to write it out to a floppy disk.  Insert a floppy diskette into
            the drive and run the following
            command to write the floppy:
            <programlisting>
dd if=<emphasis>Etherboot_Image</emphasis> of=/dev/fd0 </programlisting>
        </para>
      </sect2>

      <sect2>
        <title>Creating a bootrom</title>
        <para>
           Writing the Etherboot image to an EPROM requires an EPROM
           programmer.  This is a piece of equipment that ranges in price from
           few hundred dollars to several thousand dollars, depending on the
           features.
        </para>
        <para>
           The process of creating a bootrom is entirely dependent on the
           EPROM programmer.  This is beyond the scope of this
           document.
        </para>
      </sect2>

    </sect1>

</chapter>


<chapter>
    <title>Running the workstation</title>
    <para>
        Assuming that the server and workstation are configured properly,
        it should just be a matter of inserting the boot floppy in the floppy
        drive and turning on the workstation.
    </para>

    <para>
        The Etherboot code will be read from the floppy into memory, the network
        card will be found and initialized, the dhcp request will be sent on
        the network and a reply will be sent from the server and the kernel will
        be downloaded to the workstation.  Once the kernel has initialized the 
        workstation hardware, X windows will start and a login box should
        appear on the workstation, similar to the example below.
    </para>

    <figure><title>Login screen</title>
        <GRAPHIC FILEREF="pics/ltsplogin1.gif"
                 FORMAT="GIF"
                 SRCCREDIT="James McQuillan, 2001" >
    </figure>

    <para>
        At this point, you can log in.  An important thing to keep in mind
        is that you are logging into the server.  All of the commands that 
        you run are actually running on the server, and displaying their
        output on the workstation.  That's the power of X windows.
    </para>

    <para>
        You can run any program that is supported by the server.
    </para>

</chapter>


<chapter>
    <title>Printing</title>
    <para>
        Aside from the workstation being a fully functioning GUI or
        character mode terminal, it can also act as a print server,
        allowing upto 3 printers to be attached to the parallel and
        serial ports.
    </para>

    <para>
        This is all transparent to the user of the workstation.  They
        won't even notice the small amount of traffic that is going
        through the workstation to the printers.
    </para>

    <sect1>
        <title>Client side setup</title>

        <para>
            LTSP uses the <command>lp_server</command> program on the
            workstation, to redirect print jobs from the server to
            the printer attached to one of the ports on the workstation.
        </para>

        <para>
            To enable the printer on the workstation, there are a set of
            configuration entries in the <command>lts.conf</command> file.
            <programlisting>
[ws001]
    PRINTER_0_DEVICE = /dev/lp0
    PRINTER_0_TYPE   = P </programlisting>
            The above entry will cause the lp_server program to run as a 
            daemon, listening on TCP/IP port 9100 for a print stream from the
            server.  The print data will then be redirected to the printer
            attached to the /dev/lp0 parallel port.
        </para>

        <para>
            There are many more options available.  Check the lts.conf section
            later in this document for more information on printer
            configuration entries.
        </para>
    </sect1>

    <sect1>
        <title>Server side setup</title>

        <para>
            Setting up the printer on the server is a matter of defining a
            print queue, using the printer configuration tool on the server.
        </para>

        <para>
            On Redhat 7.2, there is both a GUI and a Text based printer
            configuration tool.  The GUI tool is called
            <command>printconf-gui</command>, and the text based tool
            is called <command>printconf-tui</command>.  Older versions of
            Redhat have a program called <command>printtool</command>.
            Printtool also exists on Redhat 7.2, but it will call
            printconf-gui.  Other Linux distributions have their own
            printer configuration tool.
        </para>

        <figure>
            <title>Printconf-gui Adding new printer</title>
            <GRAPHIC FILEREF="pics/printconf-gui-add.gif"
                     FORMAT="GIF"
                     SRCCREDIT="James McQuillan, 2001" >
        </figure>

        <para>
            Once you launch the printer configuration tool, you need to
            add a new printer.  The lp_server program allows the workstation
            to emulate an HP JetDirect print server.  You just need to create a
            <command>JetDirect</command> printer.
        </para>

        <para>
            You need to give the printer a Queue name.  The name can be
            anything, but make it a meaningful name, and the name can contain
            only the following characters:
            <itemizedlist>
                <listitem>
                    <para>
                        <computeroutput>
                            "a-z"  lower-case letters
                        </computeroutput>
                    </para></listitem>
                <listitem>
                    <para>
                        <computeroutput>
                            "A-Z"  upper-case letters
                        </computeroutput>
                    </para></listitem>
                <listitem>
                    <para>
                        <computeroutput>
                            "0-9"  numeric digits
                        </computeroutput>
                    </para></listitem>
                <listitem>
                    <para>
                        <computeroutput>
                            "-"    &nbsp;&nbsp;hyphen
                        </computeroutput>
                    </para></listitem>
                <listitem>
                    <para>
                        <computeroutput>
                            "_"    &nbsp;&nbsp;underscore
                        </computeroutput>
                    </para></listitem>
            </itemizedlist>
        </para>
        <para>
            The name chosen in the example above is
            <command>ws001_lp</command>.  This name makes it easy to see
            that the printer is associated with <command>ws001</command>.
        </para>

        <figure>
            <title>Printconf-gui Detail info</title>
            <GRAPHIC FILEREF="pics/printconf-gui-detail.gif"
                     FORMAT="GIF"
                     SRCCREDIT="James McQuillan, 2001" >
        </figure>
        <para>
            There are two fields required to communicate with the printer:
            <orderedlist>
                <listitem>
                    <para>
                        IP Address or hostname of the workstation that
                        the printer is associated with.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        The TCP port that the <command>lp_server</command>
                        daemon is listening on.
                    </para>
                    <para>
                        The first printer you connect to a workstation
                        will be on TCP/IP port <command>9100</command>.  The
                        second printer will be on port <command>9101</command>,
                        and the third printer will be on port
                        <command>9102</command>.
                    </para>
                </listitem>
            </orderedlist>
        </para>
    </sect1>

</chapter>


<chapter>
    <title>Screen Scripts</title>
    <para>
        A feature of LTSP that was added with version 4.0 is something
        called <command>Screen Scripts</command>.  These are scripts for
        starting various types of sessions.
    </para>

    <para>
        You can specify multiple screen scripts for a workstation.
        Doing so, will all you to have multiple sessions.  They can be
        different types of sessions, or they can be the same type of session.
        For example, you could specify the following:
        <programlisting>
   SCREEN_01 = startx
   SCREEN_02 = shell</programlisting>
        This would start an X server on the first screen, and a shell prompt
        on the second screen.  You can switch between the screens by
        pressing Ctrl-Alt-F1 to get to the first screen, and Ctrl-Alt-F2 to
        get to the second screen.
    </para>

    <para>
        You can specify upto 12 screen scripts for a workstation, but most 
        people would just have a single one.
    </para>

    <para>
        Available types of screen scripts:
        <variablelist>
          <varlistentry>
              <term><command>startx</command></term>
              <listitem>
                  <para>
                      This script will launch the Xserver with a -query
                      option, to send an XDMCP request to a display manager
                      to get a login dialog box to display on the screen.
                  </para> 
              </listitem>
          </varlistentry>

          <varlistentry>
              <term><command>shell</command></term>
              <listitem>
                  <para>
                      This script will launch a shell on the terminal.
                      This is really intended to be used for troubleshooting
                      problems with the workstation.  Because it gives you
                      a session on the thin client, rather than the server,
                      it isn't very useful for running applications.
                  </para> 
              </listitem>
          </varlistentry>

          <varlistentry>
              <term><command>telnet</command></term>
              <listitem>
                  <para>
                      This script will launch a telnet session that will
                      connect to the server.  This will give you a character
                      based session on the server.
                  </para> 
                  <para> 
                      By default, telnet will connect to the LTSP server.  If
                      you want to specify a different server, you can pass
                      it on the same line as the screen script.  For example:
                      <programlisting>
    SCREEN_01 = telnet server2.mydomain.com</programlisting>
                      You can also specify any options that Telnet understands,
                      But, if you do specify any options, then you must also
                      specify the server to connect to.
                  </para> 
              </listitem>
          </varlistentry>

          <varlistentry>
              <term><command>rdesktop</command></term>
              <listitem>
                  <para>
                      This script will launch the rdesktop program, which
                      will connect to a Microsoft Window server.
                      You can specify any rdesktop options you want on the
                      line, directly after the name of the screen script name.
                      For example, if you want to specify the server to
                      connect to, you can do it like this:
                      <programlisting>
    SCREEN_01 = rdesktop -f w2k.mydomain.com</programlisting>
                      The above example will launch rdesktop in full screen
                      mode.  The user will see a windows login dialog, and
                      they will only have to log in once.  This is very useful
                      when you just want to get a windows login, without having
                      a Linux login or window manager.  The user won't even
                      know they are running Linux.
                  </para> 
              </listitem>
          </varlistentry>

        </variablelist>

    </para>

    <para>
      The screen scripts reside in the
      <filename class="directory">/opt/ltsp/i386/etc/screen.d</filename>
      directory.  You can create your own screen scripts and place them in
      this directory.   It's best to follow one of the existing scripts
      as an example.
    </para>

</chapter>


<chapter>
    <title>Troubleshooting</title>
    <para>
        If, after following through the previous chapters, your workstation
        doesn't boot, then you've got to start the process of troubleshooting
        the installation.
    </para>

    <para>
        The first thing to do is figure out how far through the bootup the
        workstation has gotten.
    </para>

    <sect1>
        <title>Troubleshooting Etherboot floppy image</title>
        <para>
            When you boot from the floppy, you should see something similar
            to this:
        </para>
        <para>
        <screen>
loaded ROM segment 0x0800 length 0x4000 reloc 0x9400
Etherboot 5.0.1 (GPL) Tagged ELF for [LANCE/PCI]
Found AMD Lance/PCI at 0x1000, ROM address 0x0000
Probing...[LANCE/PCI] PCnet/PCI-II 79C970A base 0x1000, addr 00:50:56:81:00:01
Searching for server (DHCP)...
&#60;sleep&#62; </screen>
        </para>
        <para>
            The above example shows what you can expect to see on the
            screen when booting from a floppy.  If you don't see those
            messages, indicating that Etherboot has started, then you
            may have a bad floppy disk, or you didn't write the image
            to it properly.
        </para>

        <para>
        If, you see a message like the following, then it probably
        indicates that the Etherboot image you have generated is not
        the correct image for your network card.
        <screen>
ROM segment 0x0800 length 0x8000 reloc 0x9400
Etherboot 5.0.2 (GPL) Tagged ELF for [Tulip]
Probing...[Tulip]No adapter found
&#60;sleep&#62;
&#60;abort&#62; </screen>
        </para>

        <para>
            If it does get to the point where it detects the network card
            and displays the proper MAC address, then the floppy is probably
            good.
        </para>
 
    </sect1>

    <sect1>
        <title>Troubleshooting DHCP</title>
        <para>
            Once the network card is initialized, it will send out a
            DHCP broadcast on the local network, looking for a DHCP server.
        </para>

        <para>
            If the workstation gets a valid reply from the DHCP server, then it
            will configure the network card.  You can tell if it worked properly
            if the IP address information is displayed on the screen.  Here's an
            example of what it should look like:
            <screen>
ROM segment 0x0800 length 0x4000 reloc 0x9400
Etherboot 5.0.1 (GPL) Tagged ELF for [LANCE/PCI]
Found AMD Lance/PCI at 0x1000, ROM address 0x0000
Probing...[LANCE/PCI] PCnet/PCI-II 79C970A base 0x1000, addr 00:50:56:81:00:01
Searching for server (DHCP)...
&#60;sleep&#62;
Me: 192.168.0.1, Server: 192.168.0.254, Gateway 192.168.0.254 </screen>
            If you see the line that starts with 'Me:', following by an IP
            address, then you know that DHCP is working properly.  You can move
            on to checking to see if TFTP is working.
        </para>

        <para>
            If instead, you see the following message on the workstation,
            followed by lots of &#60;sleep&#62; messages, then something
            is wrong.  Although, it is common to see one or two
            &#60;sleep&#62; messages, after which the dhcp server replies.
            <screen>
Searching for server (DHCP)...  </screen>
        </para>

        <para>
            Figuring out what is wrong can sometimes be difficult, but
            here are some things to look for.
        </para>
            <sect2>
                <title>Check the connections</title>
                <para>
                    Is the workstation physically connected to the same
                    network that the server is connected to?
                </para>
                <para>
                    With the workstation turned on, make sure that the link
                    lights are lit at all of the connections.
                </para>

                <para>
                    If you are connecting directly between the workstation and
                    the server (no hub or switch), make sure that you are using
                    a cross-over cable.  If you are using a hub or switch, then
                    make sure you are using a normal straight-thru cable, both
                    between the workstation and hub, and also between the hub
                    and server.
                </para>

            </sect2>

            <sect2>
                <title>Is dhcpd running?</title>
                <para>
                    You need to determine whether <command>dhcpd</command> is
                    running on the server.  We can find the answer a couple
                    of ways.
                </para>

                <para>
                    <command>dhcpd</command> normally sits in the background,
                    listening on udp port 67.  Try running the
                    <command>netstat</command> command to see if anything
                    is listening on that port:
                    <programlisting>
netstat -an | grep ":67 " </programlisting>
                    You should see output similar to the following:
                    <programlisting>
udp     0    0   0.0.0.0:67         0.0.0.0:*</programlisting>
                    The 4th column contains the IP address and port, separated
                    by a colon (':').  An address of all zeroes ('0.0.0.0')
                    indicates that it is listening on all interfaces.  That
                    is, you may have an <command>eth0</command> and an
                    <command>eth1</command> interface, and
                    <command>dhcpd</command> is listening on both interfaces.
                </para>

                <para>
                    Just because netstat shows that something is listening
                    on udp port 67, it doesn't mean that it is definately
                    <command>dhcpd</command> that is listening.  It could
                    be <command>bootpd</command>, but that is unlikely,
                    because <command>bootp</command> is no longer included
                    on most distributions of Linux.
                </para>

                <para>
                    To make sure that it is the <command>dhcpd</command>
                    that is running, try running the <command>ps</command>
                    command.
                    <programlisting>
ps aux | grep dhcpd </programlisting>

                    You should see something like the following:

                    <programlisting>
root 23814 0.0 0.3 1676 820 ?      S 15:13 0:00 /usr/sbin/dhcpd
root 23834 0.0 0.2 1552 600 pts/0  S 15:52 0:00 grep dhcp </programlisting>

                    The first line shows that <command>dhcpd</command> is 
                    running. The second line is just our <command>grep</command>
                    command.
                </para>

                <para>
                    If you don't see any lines showing that dhcpd is running,
                    then you need to check that the server is configured for
                    runlevel 5, and that <command>dhcpd</command> is configured
                    to start in runlevel 5.  On Redhat based systems, you can
                    run the <command>ntsysv</command> and scroll down to make
                    sure <command>dhcpd</command> is configured to start.
                </para>

                <para>
                    You can try starting <command>dhcpd</command> with
                    this command:
                    <programlisting>
service dhcpd start</programlisting>

                    Pay attention to the output, it may show errors.
                </para>
                
            </sect2>

            <sect2>
                <title>Double-check the dhcpd configuration</title>
                <para>
                    Does the <filename>/etc/dhcpd.conf</filename> file have an
                    entry for our workstation?
                </para>
                <para>
                    You should double-check the 'fixed-address' setting in the
                    config file, to make sure it exactly matches the card in the
                    workstation.
                </para>
            </sect2>
           
            <sect2>
                <title>Is ipchains or iptables blocking the request?</title>
                <sect3>
                    <title>Checking for ipchains</title>
                    <para>
                        Run the following command to see what it says:
                        <programlisting>
ipchains -L -v </programlisting>
                        If you see something like this:
                        <programlisting>
Chain input (policy ACCEPT: 229714 packets, 115477216 bytes):
Chain forward (policy ACCEPT: 10 packets, 1794 bytes):
Chain output (policy ACCEPT: 188978 packets, 66087385 bytes): </programlisting>
                        Then it isn't ipchains that is getting in the way.
                    </para>
                </sect3>
                <sect3>
                    <title>Checking for iptables</title>
                    <para>
                        Run the following command to see what it says:
                        <programlisting>
iptables -L -v </programlisting>
                        If you see something like this:
                        <programlisting>
Chain INPUT (policy ACCEPT 18148 packets, 2623K bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain OUTPUT (policy ACCEPT 17721 packets, 2732K bytes)
 pkts bytes target     prot opt in     out     source               destination</programlisting>
                        Then it is not iptables getting in the way.
                    </para>
                </sect3>
            </sect2>
           
            <sect2>
                <title>Is the workstation sending the request?</title>
                <para>
                    Try watching the <filename>/var/log/messages</filename>
                    file while the workstation is booting.  You can do that with
                    the following command:
                    <programlisting>
tail -f /var/log/messages </programlisting>
                    This will 'follow' the log file as new records are
                    written to it.
                    <programlisting>
server dhcpd: DHCPDISCOVER from 00:50:56:81:00:01 via eth0
server dhcpd: no free leases on subnet WORKSTATIONS
server dhcpd: DHCPDISCOVER from 00:50:56:81:00:01 via eth0
server dhcpd: no free leases on subnet WORKSTATIONS </programlisting>
                    If you see messages like those above, saying
                    'no free leases',
                    that indicates that <command>dhcpd</command> is running,
                    but it doesn't know anything about the workstation that
                    is requesting an IP address.
                </para>
            </sect2>
           
    </sect1>

    <sect1>
        <title>Troubleshooting TFTP</title>
        <para>
            Etherboot uses TFTP to retrieve a Linux kernel from the server.
            This is a fairly simple protocol, but sometimes there are problems
            trying to get it to work.
        </para>

        <para>
            If you see a message similar to this:
        <screen>
Loading 192.168.0.254:/lts/vmlinuz-2.4.24-ltsp-4......... </screen>
          with the dots filling the screen rather quickly, that
          normally indicates that TFTP is working properly, and the
          kernel is downloading.
        </para>

        <para>
          If, instead, you don't see the dots, there is a
          problem.  Possible problems include:
        </para>

        <sect2>
            <title><command>tftpd</command> is not running</title>
            <para>
                If <command>tftpd</command> isn't configured to run, then
                it certainly won't be able to answer the request from
                the workstation.  You can see if it is running, you can
                use the <command>netstat</command> command, like this:
                <programlisting>
[root@bigdog]# netstat -anp | grep ":69 "

udp     0   0 0.0.0.0:69         0.0.0.0:*                 453/inetd        
                </programlisting>
                If you don't see any output from that command, then tftpd is
                likely not running.
            </para>
            <para>
                There are two common methods for invoking tftpd,  They
                are <command>inetd</command> and the newer
                <command>xinetd</command>
            </para>
            <para>
                <command>inetd</command> uses a configuration file called
                <filename>/etc/inetd.conf</filename>.  In that file, make sure
                that the line for starting tftpd is NOT commented out.
                This is what the line should look like:
                <programlisting>
tftp dgram udp wait nobody /usr/sbin/tcpd  /usr/sbin/in.tftpd -s /tftpboot
                </programlisting>
            </para>
            <para>
                <command>xinetd</command> uses a directory of individual
                configuration files.  One file for each service.  If your 
                server is using xinetd, then the configuration file for
                tftpd is called <filename>/etc/xinetd.d/tftp</filename>.
                Below is an example:
                <programlisting>
service tftp
{
  disable          = no
  socket_type      = dgram
  protocol         = udp
  wait             = yes
  user             = root
  server           = /usr/sbin/in.tftpd
  server_args      = -s /tftpboot
}
                </programlisting>

                Make sure that the <command>disable</command> line 
                doesn't say <command>yes</command>.
            </para>
        </sect2>

        <sect2>
            <title>Kernel not where tftpd expects to find it</title>
            <para>
                The kernel needs to be in a location that the tftpd daemon can
                access it.  If the '-s' option is specified for the
                <command>tftpd</command> daemon, then whatever the workstation
                is asking for must be relative to the
                <filename class="directory">/tftpboot</filename>.  So, if the
                <command>filename</command> entry in the
                <filename>/etc/dhcpd.conf</filename> file is set to
                <filename>/lts/vmlinuz-2.4.24-ltsp-4</filename>, then the kernel
                actually needs to be
                <filename>/tftpboot/lts/vmlinuz-2.4.24-ltsp-4</filename>
            </para>
        </sect2>
    </sect1>

    <sect1>
        <title>Troubleshooting NFS root filesystem</title>
        <para>
            There are several things that can prevent a root filesystem from
            being mounted.  Including the following:
        </para>
        <sect2>
            <title>No init found</title>
            <para>
                If you get the following error:
                <screen>
Kernel panic: No init found.  Try passing init= option to kernel.  </screen>
                Then it is is most likely that either you are mounting
                the wrong directory as the root filesystem, or the
                <filename>/opt/ltsp/i386</filename> directory is empty.
            </para>
        </sect2>

        <sect2>
            <title>Server returned error -13</title>
            <para>
                If you get the following error:
                <screen>
Root-NFS: Server returned error -13 while mounting /opt/ltsp/i386 </screen>
                This indicates that either the
                <filename class="directory">/opt/ltsp/i386</filename>
                directory isn't listed in the <filename>/etc/exports</filename>
                file.
            </para>
            <para>
                Take a look in the <filename>/var/log/messages</filename> file
                to see if there are any clues.  An entry like this:
                <screen>
Jul 20 00:28:39 bigdog rpc.mountd: refused mount request from ws004
                  for /opt/ltsp/i386 (/): no export entry </screen>
                Then it confirms our suspicion that the entry in
                <filename>/etc/exports</filename> isn't correct.
            </para>
        </sect2>

        <sect2>
            <title>NFS Daemon problems (portmap, nfsd &amp; mountd)</title>
            <para>
                NFS can be a complex and difficult service to trouble-shoot, but
                understanding what should be setup and what tools are
                available to diagnose the problems will surely help to
                make it easier.
            </para>
            <para>
                There are three daemons that need to be running on the server
                for NFS to work properly.  <command>portmap</command>,
                <command>nfsd</command> and <command>mountd</command>.
            </para>
            <sect3>
                <title>The Portmapper (portmap)</title>
                <para>
                    If you get the following messages:
                    <screen>
Looking up port of RPC 100003/2 on 192.168.0.254
portmap: server 192.168.0.254 not responding, timed out
Root-NFS: Unable to get nfsd port number from server, using default
Looking up port of RPC 100005/2 on 192.168.0.254
portmap: server 192.168.0.254 not responding, timed out
Root-NFS: Unable to get mountd port number from server, using default
mount: server 192.168.0.254 not responding, timed out
Root-NFS: Server returned error -5 while mounting /opt/ltsp/i386
VFS: unable to mount root fs via NFS, trying floppy.
VFS: Cannot open root device "nfs" or 02:00
Please append a correct "root=" boot option
Kernel panic: VFS: Unable to mount root fs on 02:00 </screen>
                    This most likely is caused by the <command>portmap</command>
                    daemon not running.  You can confirm whether or not the
                    portmapper is running by using the <command>ps</command>
                    command:
                    <screen>
ps -e | grep portmap </screen>
                    If the portmapper is running, you should see output
                    like this:
                    <screen>
30455 ?        00:00:00 portmap </screen>
                    Another test is to use the <command>netstat</command>.
                    The portmapper uses TCP and UDP ports 111.  Try running
                    this:
                    <screen>
netstat -an | grep ":111 " </screen>
                    You should see the following output:
                    <screen>
tcp   0   0 0.0.0.0:111       0.0.0.0:*          LISTEN      
udp   0   0 0.0.0.0:111       0.0.0.0:*                           </screen>
                    If you don't see similar output, then the portmapper
                    isn't running.  You start the portmapper by running:
                    <screen>
/etc/rc.d/init.d/portmap   start </screen>
                    Then, you should make sure that the portmapper is setup to
                    start when the server boots.  Run
                    <command>ntsysv</command> to make sure it is selected to
                    run.
                </para>
            </sect3>

            <sect3>
                <title>The NFS and MOUNT daemons (nfsd &amp; mountd)</title>
                <para>
                    NFS has 2 daemons that need to be running.
                    <command>nfsd</command> and <command>mountd</command>.
                    They are both started by the
                    <filename>/etc/rc.d/init.d/nfs</filename> script.
                </para>
                <para>
                    You can run the <command>ps</command> command to make sure
                    that they are running.
                    <screen>
ps -e | grep nfs
ps -e | grep mountd </screen>
                    If it shows that one or both of the daemons are not
                    running, then you will need to start them.
                </para>

                <para>
                    Normally, you should be able to run the startup script
                    with the <command>restart</command> argument to cause
                    them both to startup, but for some reason, the
                    <filename>/etc/rc.d/init.d/nfs</filename>
                    script doesn't restart <command>nfsd</command> that way.
                    It only restarts <command>mountd</command> (bug?).  So,
                    you should instead run the following sequence of
                    commands:
                    <screen>
/etc/rc.d/init.d/nfs  stop
/etc/rc.d/init.d/nfs  start </screen>
                    You may get errors on the <command>stop</command> command,
                    but that is Ok.  The <command>start</command> command
                    should show <command>OK</command> as the status.
                </para>

                <para>
                    If the daemons are running, but NFS is still not working,
                    you can verify that they have registered themselves with
                    the portmapper by using the <command>rpcinfo</command>
                    command.
                    <screen>
rpcinfo -p localhost </screen>
                    You should see results similar to the following:
                    <screen>
program vers proto   port
 100000    2   tcp    111  portmapper
 100000    2   udp    111  portmapper
 100003    2   udp   2049  nfs
 100003    3   udp   2049  nfs
 100021    1   udp  32771  nlockmgr
 100021    3   udp  32771  nlockmgr
 100021    4   udp  32771  nlockmgr
 100005    1   udp    648  mountd
 100005    1   tcp    651  mountd
 100005    2   udp    648  mountd
 100005    2   tcp    651  mountd
 100005    3   udp    648  mountd
 100005    3   tcp    651  mountd
 100024    1   udp    750  status
 100024    1   tcp    753  status</screen>
                    This indicates that <command>nfs</command> (nfsd) and
                    <command>mountd</command> are both running and have
                    registered themselves with the portmapper.
                </para>
            </sect3>
        </sect2>
    </sect1>

    <sect1>
        <title>Troubleshooting the Xserver</title>
        <para>
            Oh boy!,  Probably the single most difficult part of setting up an
            LTSP workstation is getting the X server configured properly.  If
            you are using a fairly new video card, and it is supported by
            the Xorg Xservers, and you have a fairly new monitor that
            can handle a large range
            of frequencies and resolutions, then it is fairly straight
            forward.  Usually, in that case, if it doesn't work, it is most
            likely the wrong X server for that card.
        </para>
        <para>
            When an X server doesn't work with your card, it is usually pretty
            obvious.  Either the X server won't start, or the display will be
            incorrect.
        </para>
        <para>
            When the workstation is ready to start the X server,
            it calls the <filename>startx</filename> script, which
            starts the X server on the local workstation, with a
            <command>-query</command> option pointing to a server, where
            a display manager, such as <command>XDM</command>,
            <command>GDM</command> or <command>KDM</command> is running.
        </para>

        <para>
           

























 
        </para>


        <para>
            Because the X server is started by the <filename>startx</filename>
            script, which is itself started by the <command>init</command>
            program, when it fails, <command>init</command> will attempt to
            run it again.  <command>init</command> will continue this loop
            of trying to run the X server 10 times, then give up, because
            it thinks that it is respawning too quickly.  After it finally
            gives up, the error message from the X server should be left
            on the screen.
        </para>

        <para>
            Waiting for the X server to fail 10 times can be rather irritating,
            so a simple way to avoid the repeated failures is to start the
            workstation in runlevel 3, so that the X server is NOT started
            automatically.  Instead, when you boot the workstation, you will
            get a <command>bash</command> prompt.
            From the bash prompt, you can start the X server manually with the
            following command:
            <screen>
sh  /tmp/start_ws </screen>
            The X server will attempt to start, then when it fails, it will
            return back to the bash prompt, so you can see what the reason for
            the failure is.
        </para>
    </sect1>

    <sect1>
        <title>Troubleshooting the Display manager</title>
        <para>
            The display manager is the daemon that runs on the server, waiting
            for an X server to make contact with it.  Once contact has been
            made, it will display a login dialog box on the screen, offering
            the user a chance to log into the server.
        </para>

        <para>
            The three most common display managers are:
            <itemizedlist>
                <listitem>
                    <para>
                        XDM - It's been around forever.  It is included with the
                        standard X windows system.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        GDM - The 'Gnome Display Manager'.  This is part of the
                        Gnome package.
                    </para>
                </listitem>
                <listitem>
                    <para>
                        KDM - The 'KDE Display Manager'.  This is part of the
                        K Desktop system.
                    </para>
                </listitem>
            </itemizedlist>
            Most recent GNU/Linux distributions include all three display
            managers.
        </para>

        <sect2>
            <title>Grey screen with large X cursor</title>
            <para>
                This indicates that the X server is running, but it has not
                been able to make contact with a display manager.  Some possible
                reasons for that are:
                <orderedlist>
                    <listitem>
                        <para>
                            The display manager may not be running
                        </para>
                        <para>
                            On recent versions of Redhat (7.0 and above), the
                            display manager is started from
                            <command>init</command>.  In the
                            <filename>/etc/inittab</filename> file, there is
                            a line that looks like this:
                            <screen>
x:5:respawn:/etc/X11/prefdm -nodaemon </screen>
                            The <command>prefdm</command> script will make
                            the determination of which display manager to run.
                        </para>

                        <para>
                            The default display manager depends on which
                            packages have been installed.  If Gnome is
                            installed, then GDM is the default display
                            manager.  If Gnome is not installed, then the
                            prefdm script will check to see if KDE is
                            installed.  If it is, then KDM will be the default
                            display manager.  If KDE also is not installed,
                            then XDM will be the default display manager.
                        </para>

                        <para>
                            Using the <command>netstat</command> command,
                            you should be able to see if there is a display
                            manager running.  On the server, run the
                            following command:
                            <screen>
netstat -ap | grep xdmcp </screen>
                            You should see results showing that there is
                            a process listening on the xdmcp port (177).
                            <screen>
udp     0   0 *:xdmcp            *:*               1493/gdm </screen>
                            This shows clearly that <command>gdm</command>
                            is running with a PID of 1493, and it is listening
                            on the xdmcp port.
                        </para>

                        <para>
                            If you see a line like the one shown above,
                            indicating that there is definately a display
                            manager listening, then you need to make sure
                            that the workstation is sending the XDMCP query
                            to the correct server.
                        </para>

                        <para>
                            In the <filename>lts.conf</filename> file, you can
                            have an entry which specifies the IP address of the
                            server that is running the display manager.
                            the entry is optional, but if present, should
                            look like this:
                            <screen>
XDM_SERVER  =  192.168.0.254 </screen>
                            of course, the IP address for your network may
                            be different than the example above.
                        </para>

                        <para>
                            If the 'XDM_SERVER' entry is not present, it
                            will then use the value of the 'SERVER' entry,
                            if present.  If that is not present, then it
                            will use <command>192.168.0.254</command>.
                        </para>

                        <para>
                            Which ever way it is specified, you just need
                            to make sure that the IP address is actually
                            the correct address of the server running the
                            display manager.
                        </para>
                    </listitem>
                    <listitem>
                        <para>
                            The display manager may be configured to ignore
                            requests from remote hosts.
                        </para>

                        <para>
                            If you've determined that the display manager
                            is running, then it is possible that it has been
                            configured to ignore XDMCP requests from remote
                            hosts.  You will need to check the configuration
                            files of the particular running display manager,
                            to determine if it is configured properly.
                        </para>

                        <itemizedlist>
                            <listitem>
                                <para><command>XDM</command></para>
                                <para>
                                    The default configuration for Redhat is to
                                    disable the ability for workstations to
                                    get login access from XDM.  The
                                    <command>ltsp_initialize</command> script
                                    will take care of enabling this for you,
                                    but if it's not working, you should check
                                    the
                                    <filename>/etc/X11/xdm/xdm-config</filename>
                                    file.  Look for an entry that looks like
                                    this:
                                    <screen>
DisplayManager.requestPort:     0 </screen>
                                    This entry MUST be commented out in order
                                    for XDM to listen on port 177 for remote
                                    requests.
                                </para>
                                <para>
                                    Another configuration file is also
                                    important for XDM to serve up remote login
                                    requests.  There is a file called
                                    <filename>/etc/X11/xdm/Xaccess</filename>
                                    that MUST have a line that starts with an
                                    asterisk '*'.  the line is normally
                                    included in the file, but Redhat leaves
                                    the line commented out.  the
                                    <command>ltsp_initialize</command> script
                                    will fix the line for you, but if XDM
                                    doesn't seem to be working, you should
                                    check this file.  A valid line should look
                                    like this:
                                    <screen>
*        #any host can get a login window </screen>
                                </para>
                            </listitem>

                            <listitem>
                                <para><command>KDM</command></para>
                                <para>
                                    Newer versions of KDM have a file
                                    called <command>kdmrc</command>.  Different
                                    Linux distributions store that file in 
                                    different locations.  For Redhat 7.2,
                                    it is <command>/etc/kde/kdm/kdmrc</command>.
                                    For the other distros, you should run
                                    the <command>locate</command> command to
                                    find out where it is stored.
                                </para>
                                <para>
                                    The entry that controls whether remote
                                    workstations can get a login is in
                                    the <command>[Xdmcp]</command> section.
                                    Make sure that the <command>Enable</command>
                                    entry is set to <command>true</command>.
                                </para>
                                <para>
                                    Older versions of KDM use the XDM
                                    configuration files, located in
                                    /etc/X11/xdm.
                                </para>
                            </listitem>

                            <listitem>
                                <para><command>GDM</command></para>
                                <para>
                                    GDM uses a different set of configuration
                                    files.  They are located in the
                                    <filename class="directory">/etc/X11/gdm</filename>
                                    directory.
                                </para>

                                <para>
                                    The main file to look at is the
                                    <filename>gdm.conf</filename> file.  Look for the
                                    <command>[xdmcp]</command> section.  you should
                                    see an entry within that section called 'Enable'.  It
                                    must be set to '1' or 'true', depending on
                                    the version of GDM.  Here is an example:
                                    <screen>
[xdmcp]
Enable=true
HonorIndirect=0
MaxPending=4
MaxPendingIndirect=4
MaxSessions=16
MaxWait=30
MaxWaitIndirect=30
Port=177 </screen>
                                </para>
                                <para>
                                    Notice the 'Enable=true' line.
                                    Older versions of GDM use '0' and '1' to
                                    signify whether to Disable or Enable the
                                    remote XDMCP.  Newer versions use 'false'
                                    and 'true'.
                                </para>
                            </listitem>
                        </itemizedlist>
                    </listitem>

                    <listitem>
                        <para>
                            If the Display manager is definately running,
                            and it is listening for requests from remote
                            workstations, it may be a simple problem that
                            the display manager is unable to map the IP
                            address to a hostname.  The workstation either
                            needs to be listed in the 
                            <filename>/etc/hosts</filename> file, or 
                            it needs to be correctly setup in the DNS tables.
                        </para>
                    </listitem>

                </orderedlist>
            </para>
        </sect2>
    </sect1>
</chapter>


<chapter>
    <title>Kernels</title>
    <para>
        There are a few decisions that need to be made about the kernel
        that is run on the workstation.  You need to decide whether you
        want to run one of the standard kernels available for download,
        or build your own.  And, you need to decide if you want to display
        the graphic screen, complete with the progress bar which, which
        is made possible by the <command>Linux Progress Patch (LPP)</command>.
    </para>

    <sect1>
        <title>Standard LTSP supplied kernels</title>
        <para>
            The kernel package that is available with LTSP actually includes
            two kernels.  One has the Linux Progress Patch already applied
            and configured, and the other does not have the patch applied.
        </para>

        <para>
            Both of the kernels already have the NFS Swap patch applied.
        </para>
    </sect1>

    <sect1>
        <title>Build your own kernel</title>
        <para>
            There are two ways to configure a kernel for LTSP.  The default
            method is to use something called an 'Initial Ram Disk', or
            <command>initrd</command> for short.  The initrd image is a small
            filesystem that is appended to the kernel.  The initrd filesystem
            image is loaded into memory, and once the kernel is booted, it
            will mount the ramdisk as its root filesystem.  There are a
            couple of advantages of using an initrd image.  First, we can
            compile the network drivers as modules and load the correct
            module during bootup.  This allows a single kernel which will
            support virtually all network cards.  The other advantage is that
            we can run the DHCP client as a "user-land" program rather than
            in kernel-space.  Running the client in user-land provides
            better control over the options requested and received from the
            server.  Also, it makes the kernel slightly smaller.  The other way
            to configure the kernel is without the initrd.  Building a kernel
            without an initrd requires that the specific network card driver
            be statically linked into the kernel, and it also requires that
            IP-Autoconfig and "Root filesystem on NFS" are set when building
            the kernel.  The advantage of not using an initrd is that the
            kernel is slightly smaller, and it will boot slightly faster.
            once the workstation is up and running, there is virtually no
            difference in how the workstation functions.
        </para>

        <para>
            The standard kernel for LTSP includes an Initial Ramdisk
            (initrd) that takes care of detecting the network card, and
            making a user-space DHCP request.  A major goal for the image
            was to make it as small as possible.  So, we chose the uClinux
            libc replacement library, and busybox for the utilities that
            we need during the boot.
        </para>

        <para>
            If you want to build your own kernels, you should download the
            ltsp_initrd_kit package.  It contains the root filesystem hierarchy,
            and a script for building the image.
        </para>

        <sect2>
            <title>Obtaining the source for the kernel</title>
 
            <para>
                When building a custom kernel, it's usually a good idea to
                start with fresh kernel sources direct from the
                <command>ftp.kernel.org</command> site.  The reason for this
                is that the distributions, like Redhat, apply many patches to
                their kernel sources, leaving you with a set of source code
                that really doesn't match that of the official kernel.
            </para>
    
            <para>
                Download the kernel source package of your choice, and save
                it in the <filename class="directory">/usr/src</filename>
                directory.  The kernels are located in the
                <filename class="directory">/pub/linux/kernel</filename>
                directory of the ftp.kernel.org ftp server.  You will need to
                grab a recent 2.4.x series kernel, because you need to include
                <command>devfs</command> support.
            </para>

            <para>
                Also, if you want to include support for swapping over NFS or
                the Linux Progress Patch (LPP), you will need to make sure that
                you get the patches and kernel sources that are all the same.
                At the time of this writing, the 2.4.9 kernel is the latest to
                support those features.
            </para>

            <para>
                For our example, we will use the 2.4.9 kernel.  The entire
                path is
                <filename>ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.9.tar.bz2</filename>
            </para>

            <para>
                Unpack the kernel sources in the
                <filename class="directory">/usr/src</filename>
                directory.  You need to be careful, because when you un-tar the
                package, it will be in a directory called
                <filename>linux</filename>.  You may already have a
                directory called <filename>linux</filename> with a different
                set of source code, and you don't want to clobber it.  So,
                check for an existing directory, and if it is there, rename it
                to something else before unpacking the sources.
            </para>

            <para>
                The source package we downloaded had been compressed with the
                <command>bzip2</command> compression utility.  So, we need
                to uncompress it before we feed it to the <command>tar</command>
                program.  You can use the following command to unpack it:
                <screen>
bunzip2 &#60;linux-2.4.9.tar.bz2 | tar xf - </screen>
                When the unpacking completes, you will have a directory called 
                <filename>linux</filename> containing the entire source tree.
                At this point, I usually like to rename the directory to
                something more meaningful.
                <screen>
mv linux linux-2.4.9 </screen>
                Once the directory has been renamed, then change into the
                new directory:
                <screen>
cd linux-2.4.9 </screen>
            </para>
            <para>
                I usually like to modify the <filename>Makefile</filename>
                before I start configuring the new kernel.  Near the top
                of the file is a variable named
                <command>EXTRAVERSION</command>.  I set this to 'ltsp-1', so
                that the actual version number of the kernel will be
                '2.4.9-ltsp-1', which makes it easier to identify the kernel
                later.  The top of the Makefile should look like this when you
                are done:
                <screen>
VERSION = 2
PATCHLEVEL = 4
SUBLEVEL = 9
EXTRAVERSION = -ltsp-1

KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) </screen>
            </para>
        </sect2>

        <sect2>
            <title>Kernel Patches</title>
            <para>
                After unpacking the kernel, you may have various patches
                you want to apply.  For example, the NFS Swap patch or
                the Linux Progress Patch.  These patches MUST be applied
                before configuring the kernel.
            </para>
            <sect3>
                <title>NFS Swap patch</title>
                <para>
                    The NFS Swap patch will allow the workstation kernel
                    to use a swapfile located on an NFS server.  While it
                    usually recommended to have enough memory in the
                    workstation to not require swapping, it can sometimes
                    be difficult to add more memory, especially on older
                    computers.  So, the ability to swap over NFS can make
                    an otherwise unuseable computer actually useable.
                </para>
                <para>
                    If the current directory is /usr/src/linux-2.4.9, and the
                    patch is in /usr/src, you can do the following to test
                    the patch:
                    <screen>
patch -p1 --dry-run &#60;../linux-2.4.9-nfs-swap.diff </screen>
                    This will test the patch, to make sure it can be applied
                    cleanly.  If it finishes with no errors, then you can
                    apply the patch without the <command>--dry-run</command>
                    option.
                    <screen>
patch -p1 &#60;../linux-2.4.9-nfs-swap.diff </screen>
                </para>
            </sect3>
            <sect3>
                <title>Linux Progress Patch (LPP)</title>
                <para>
                    The Linux Progress Patch (LPP) will allow you to configure
                    a graphic logo to display during the boot process.  The
                    normal kernel boot messages are redirected to another
                    tty screen, and special instructions are added to the
                    boot scripts to cause the Progress bar to reflect how far
                    along the boot process is.
                </para>
                <para>
                    Like the NFS Swap patch, you can test the LPP patch by
                    issuing this command:
                    <screen>
patch -p1 --dry-run &#60;../lpp-2.4.9 </screen>
                    If the test completes successfully, then you can apply
                    the patch with:
                    <screen>
patch -p1 &#60;../lpp-2.4.9 </screen>
                </para>
            </sect3>
        </sect2>

        <sect2>
            <title>Configuring kernel options</title>
            <para>
                You can now run the kernel configuration program of your choice.
                Available choices are:
                <itemizedlist>
                    <listitem>
                        <para>make xconfig</para>
                        <para>
                            This will invoke the X Windows version of the kernel
                            configuration utility.
                        </para>
                    </listitem>
                    <listitem>
                        <para>make menuconfig</para>
                        <para>
                            This will invoke the curses based version of the
                            kernel configuration utility.
                        </para>
                    </listitem>
                    <listitem>
                        <para>make config</para>
                        <para>
                            This will invoke the simple line-at-a-time version
                            of the kernel configuration utility.
                        </para>
                    </list