X can be broken down into two major sections: the server and the client. The client makes calls to the server, instructing the server on exactly how to paint the screen. The server, in turn, handles the communication with the hardware. Both of these components have sub-layers, which we touch on as we discuss each component in detail.
X Server Component
When troubleshooting X, start by determining the version and distribution of the server. This information can be extracted with the rpm or dpkg command if the server was installed as part of a distribution or package. Keep in mind that if the program was upgraded from source, the package manager commands might not reflect the current version. In this case, executing the server and passing the flag -version does the trick. However, it should be noted that "X", in this case, is usually a link to the X server your system has installed.
To determine the version of X on your system, try the following command:
# type X X is /usr/X11R6/bin/X
The type command (a built-in shell command) is used to find programs in the PATH variable. Now, using a long list, we can determine the file type.
# ll /usr/X11R6/bin/X lrwxrwxrwx 1 root root 8 May 20 20:56 /usr/X11R6/bin/X -> Xwrapper
Note that the Xwrapper is not installed with every distribution. Most distributions link X right to the X server binary. However, when determining the X version on one of our test Linux distributions, we noticed this Xwrapper binary. To determine the X server version, we simply trace the wrapper's execution.
# strace -o /tmp/xrapper.trace Xwrapper # grep exec /tmp/xrapper.trace execve("/usr/X11R6/bin/Xwrapper", ["Xwrapper"], [/* 45 vars */]) = 0 execve("/etc/X11/X", ["/etc/X11/X"], [/* 45 vars */]) = 0 # ll /etc/X11/X lrwxrwxrwx 1 root root 27 May 20 23:42 /etc/X11/X -> ../../usr/X11R6/bin/XFree86*
In this case, we find that X is linked to the XFree86 server. To determine the version of X server, simply execute the following:
# /usr/X11R6/bin/XFree86 -version XFree86 Version 4.3.0 Release Date: 9 May 2003 X Protocol Version 11, Revision 0, Release 6.6 Build Operating System: Linux 2.4.19-36mdkenterprise i686 [ELF] Build Date: 10 December 2003 Before reporting problems, check http://www.XFree86.Org/ to make sure that you have the latest version. Module Loader present
Performing similar steps on a different distribution, such as SUSE, yields the following:
# type X X is /usr/X11R6/bin/X # ll /usr/X11R6/bin/X lrwxrwxrwx 1 root root 16 2005-04-14 06:52 /usr/X11R6/bin/X -> /var/X11R6/bin/X # ll /var/X11R6/bin/X lrwxrwxrwx 1 root root 19 2005-04-14 06:52 /var/X11R6/bin/X -> /usr/X11R6/bin/Xorg # ll /usr/X11R6/bin/Xorg -rws--x--x 1 root root 2054641 2005-02-25 11:26 /usr/X11R6/bin/Xorg
So, here we find that instead of XFree86, this distribution is using the Xorg version of the X server. To determine the exact version of the X server, we just pass the same argument as shown before:
# /usr/X11R6/bin/Xorg -version X Window System Version 6.8.1 Release Date: 17 September 2004 X Protocol Version 11, Revision 0, Release 6.8.1 Build Operating System: SuSE Linux [ELF] SuSE Current Operating System: Linux nc6000 2.6.8-24.14-default #1 Tue Mar 29 09:27:43 UTC 2005 i686 Build Date: 25 February 2005 Before reporting problems, check http://wiki.X.Org to make sure that you have the latest version. Module Loader present
Before attempting to start the X server, it is a good idea to take inventory of the hardware to be configured. This practice enables you to configure the X server correctly with the hardware connected to the machine. Hardware supported by the X server can be found in the release notes for most versions or on the X organizations'Web sites. In addition to these references, the Linux distribution lists all supported hardware, which includes graphic devices. Some "bleeding edge" interfaces might not be supported yet and might not function at their full capacity or at all. Take inventory of the video card (chip set), amount of video memory on the interface, monitor capability, and Human Interface Devices (HID), such as keyboard, mouse, and so on.
To determine the type of video card in the machine, use tools such as lspci. In the next example, we can determine that the machine has a Matrox G400 dual head video card.
# lspci 0000:00:00.0 Host bridge: Intel Corp. 82865G/PE/P DRAM Controller/Host- \ Hub Interface (rev 02) 0000:00:01.0 PCI bridge: Intel Corp. 82865G/PE/P PCI to AGP Controller \ (rev 02) 0000:00:1d.0 USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R) USB \ UHCI #1 (rev 02) 0000:00:1d.1 USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R) USB \ UHCI #2 (rev 02) 0000:00:1d.2 USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R) USB \ UHCI #3 (rev 02) 0000:00:1d.3 USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R) USB \ UHCI #4 (rev 02) 0000:00:1d.7 USB Controller: Intel Corp. 82801EB/ER (ICH5/ICH5R) USB2 \ EHCI Controller (rev 02) 0000:00:1e.0 PCI bridge: Intel Corp. 82801 PCI Bridge (rev c2) 0000:00:1f.0 ISA bridge: Intel Corp. 82801EB/ER (ICH5/ICH5R) LPC Bridge \ (rev 02) 0000:00:1f.1 IDE interface: Intel Corp. 82801EB/ER (ICH5/ICH5R) Ultra \ ATA 100 Storage Controller (rev 02) 0000:00:1f.3 SMBus: Intel Corp. 82801EB/ER (ICH5/ICH5R) SMBus Controller \ (rev 02) 0000:00:1f.5 Multimedia audio controller: Intel Corp. 82801EB/ER \ (ICH5/ICH5R) AC'97 Audio Controller 0000:01:00.0 VGA compatible controller: Matrox Graphics, Inc. MGA G400 \ AGP (rev 04) 0000:02:05.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL- \ 8139/8139C/8139C+ (rev 10) 0000:02:0b.0 Multimedia audio controller: Creative Labs SB Live! EMU10k1 \ (rev 07) 0000:02:0b.1 Input device controller: Creative Labs SB Live! MIDI/Game \ Port (rev 07) 0000:02:0d.0 Ethernet controller: Realtek Semiconductor Co., Ltd. RTL- \ 8029(AS)
We should also determine the amount of memory on the video card. The kernel accesses this memory and creates user-space address mapping. The vender's specifications for the video card would be a great place to determine the exact amount of VRAM on the card. The memory addresses used to access the interface can be found in /proc/iomem. This file displays the memory map used by the kernel, not only for main memory, but also for memory located on I/O interfaces, which is sometimes referred to as "I/O memory" or "Memory-Mapped I/O". Because the full details of how this memory mapping takes place exceed the scope of this chapter, suffice it to say that having the kernel create a mapping of user-space address to the device's memory increases performance substantially. For example, when the X server reads and writes to the specified address range contained in /proc/iomem, it is actually reading and writing to the video card's memory.
In most cases, the X server detects the memory available on the graphics board. Driver-specific documentation under /usr/X11R6/lib/X11/doc/ or the man pages under /usr/X11R6/man/man4 provide an indication about when the VRAM must be manually specified in the X configuration file. Here is an example of the X server's video driver detecting the VRAM size. This is an example of the XFree86 server using the ATI driver to detect the amount of memory on the ATI Technologies Inc. Rage Mobility interface. Note that when the server starts, it prints a "Marker" legend indicating that "--" stands for probed information.
# grep RAM /var/log/XFree86.0.log (--) ATI(0): Internal RAMDAC (subtype 1) detected. (--) ATI(0): 8192 kB of SDRAM (1:1) detected (using 8191 kB).
Here is an example of /proc/iomem showing the video card and the user-space address range mapped to the device. At address fe000000, the kernel has mapped direct access to the card's memory.
# cat /proc/iomem 00000000-0009fbff : System RAM 0009fc00-0009ffff : reserved 000a0000-000bffff : Video RAM area 000c0000-000c7fff : Video ROM 000f0000-000fffff : System ROM 00100000-1ff2ffff : System RAM 00100000-00306aec : Kernel code 00306aed-003ca37f : Kernel data 1ff30000-1ff3ffff : ACPI Tables 1ff40000-1ffeffff : ACPI Non-volatile Storage 1fff0000-1fffffff : reserved 20000000-200003ff : 0000:00:1f.1 f3f00000-f7efffff : PCI Bus #01 f4000000-f5ffffff : 0000:01:00.0 f4000000-f5ffffff : vesafb f8000000-fbffffff : 0000:00:00.0 fd900000-fe9fffff : PCI Bus #01 fe000000-fe7fffff : 0000:01:00.0 fe9fc000-fe9fffff : 0000:01:00.0 feaffc00-feaffcff : 0000:02:05.0 feaffc00-feaffcff : 8139too febff400-febff4ff : 0000:00:1f.5 febff800-febff9ff : 0000:00:1f.5 febffc00-febfffff : 0000:00:1d.7 febffc00-febfffff : ehci_hcd ffb80000-ffffffff : reserved
This same address can be found when reviewing the memory map of the running process such as X, as shown in this next example:
# X &  6273 # cat /proc/6273/maps | grep fe000 40b14000-41314000 rw-s fe000000 03:41 7318 /dev/mem 42b28000-43328000 rw-s fe000000 03:41 7318 /dev/mem 43b3c000-4433c000 rw-s fe000000 03:41 7318 /dev/mem
The configuration of the server is controlled by a configuration file stored in /etc/X11/. The file referenced depends entirely upon which server is being used. Older versions of XFree86 use /etc/X11/XF86Config, whereas the newer version 4 uses /etc/X11/ XF86Config-4. The Xorg server uses /etc/X11/xorg.conf, and this file is linked to XF86Config. Keep in mind that the server configuration files have changed over the years and will surely change again. The X configuration file needed for your version of the X server should be detailed in the man page on XF86Config. This man page should be used for both XFree86 and Xorg distributions.
To successfully bring the X server online, we must analyze the configuration file and break it down into its sections. The file is made up of several key sections, which include Files, ServerFlags, Module, InputDevice, Monitor, Modes, Screen, Device, and ServerLayout. The full details of the X server's configuration can be found in the man page on XF86Config; however, the following list gives a brief description of each section and its use.
Some Linux distributions, such as Red Hat, SUSE, Debian, Mandriva (formally Mandrake), and others, usually provide tools to aid in X server configuration. However, unless these tools are offered in a TUI version, if the X server does not start, they are not of much use. The Xorg X server has a getconfig.pl Perl script that is called when the X server cannot locate the default configuration file. It attempts to use the most generic configuration to bring the server online. The XFree86 implementation does not use such a script, so if the X configuration file is not present, it simply does not start.
The following example illustrates bringing the X server online.
# X X Window System Version 6.8.2 Release Date: 9 February 2005 X Protocol Version 11, Revision 0, Release 6.8.2 Build Operating System: Linux 2.4.22-26mdk i686 [ELF] Current Operating System: Linux gamer2 2.4.22-26mdk #1 Wed Jan 7 10:47:21 MST 2004 i686 Build Date: 18 August 2005 Before reporting problems, check http://wiki.X.Org to make sure that you have the latest version. Module Loader present Markers: (--) probed, (**) from config file, (==) default setting, (++) from command line, (!!) notice, (II) informational, (WW) warning, (EE) error, (NI) not implemented, (??) unknown. (==) Log file: "/var/log/Xorg.0.log", Time: Thu Aug 18 22:25:32 2005 (EE) Unable to locate/open config file xf86AutoConfig: Primary PCI is 1:0:0 Running "/usr/X11R6/bin/getconfig -X 60802000 -I /etc/X11,/usr/X11R6/etc/X11,/usr/X11R6/lib/modules,/usr/X11R6/lib/X11/ getconfig -v 0x1002 -d 0x4c4d -r 0x64 -s 0x103c -b 0x0010 -c 0x0300" getconfig.pl: Version 1.0. getconfig.pl: Xorg Version: 18.104.22.168. getconfig.pl: 23 built-in rules. getconfig.pl: rules file '/usr/X11R6/lib/X11/getconfig/xorg.cfg' has version 1.0. getconfig.pl: 1 rule added from file '/usr/X11R6/lib/X11/getconfig/xorg.cfg'. getconfig.pl: Evaluated 24 rules with 0 errors. getconfig.pl: Weight of result is 500. New driver is "ati" (==) Using default built-in configuration (53 lines) (EE) open /dev/fb0: No such file or directory Could not init font path element /usr/X11R6/lib/X11/fonts/CID/, removing from list!
At this point, the X server should be up and running as indicated by the "weave" pattern, which should be on the screen. By default, the version and configuration file that it uses are displayed as standard output. Because no display or screen number was passed at the command line, the default:0.0 (or local device) is used. Because no desktop environment has been started yet, we can do little in the window except move the mouse around (if one is attached) or issue Ctrl+Alt+Backspace to reset the server, unless someone has inserted the DontZap server option in the configuration file. Of course, if errors are encountered, we can check the X error log file under /var/log.
Figure 15-1 displays the "weave" pattern that is displayed when the X server is online.
Figure 15-1. The weave displayed when the X server is online
With no options passed to the X server, it starts and listens for client communication. All that is presented to the screen is the "weave" background. A client is now needed to instruct the X server on what to draw. Because the X server is a networked application, we simply can execute a client from another machine and direct it to the display on our test machine. Built into the X server are security measures that prevent just anyone from capturing a display or directing clients to a server. The man page on Xsecurity explains all the different implementations of access control. By default, the X server listens for TCP communication; however, it is not allowed access unless the Host is allowed by the access controls. To disable the X server from listening for TCP, use the option -nolisten tcp detailed in the man page on Xserver.
By default, the X server listens on port 600n, where n is the display value. This can be seen by using netstat and lsof.
# netstat -an ... tcp 0 0 0.0.0.0:6000 0.0.0.0:* LISTEN ...
Here is an example of checking the port on which the X server is listening using lsof.
# ps -ef | grep X root 9359 769 0 08:47 ? 00:00:00 X # lsof -n -P -p 9359 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME X 9359 root cwd DIR 3,1 4096 539675 /etc/X11 X 9359 root rtd DIR 3,1 4096 2 / X 9359 root txt REG 3,1 2048692 150855 /usr/X11R6/bin/Xorg X 9359 root mem CHR 1,1 8 /dev/mem X 9359 root mem REG 3,1 80296 637734 /lib/ld-2.3.2.so X 9359 root mem REG 3,1 55448 637782 /lib/libz.so.1.1.4 X 9359 root mem REG 3,1 139748 277989 /lib/i686/libm-2.3.2.so X 9359 root mem REG 3,1 9160 637745 /lib/libdl-2.3.2.so X 9359 root mem REG 3,1 1237568 277987 /lib/i686/libc-2.3.2.so X 9359 root mem REG 3,1 34516 637755 /lib/libnss_files-2.3.2.so X 9359 root 0w REG 3,1 39041 297910 /var/log/Xorg.0.log X 9359 root 1u IPv4 160240 TCP *:6000 (LISTEN) X 9359 root 2u CHR 136,0 2 /dev/pts/0 X 9359 root 3u unix 0xdca2da20 160241 /tmp/.X11-unix/X0 X 9359 root 4u CHR 10,134 6 /dev/misc/apm_bios X 9359 root 5u CHR 4,7 26 /dev/vc/7 X 9359 root 6u REG 0,2 256 4406 /proc/bus/pci/01/00.0 X 9359 root 7w REG 0,6 137 4 /dev/cpu/mtrr X 9359 root 8u CHR 10,1 85 /dev/misc/psaux
This confirms that the X server is listening for connections on TCP port 6000.
X Client Component
The X client is anything that talks to the X server. A prime example is a window manager or simple xterm. Rarely will there be a time when the X server is up and there is no window manager running. Without the window manager, it would be very difficult to manipulate the window frames. This would result in the X window frames overlapping unless we instructed the server exactly where onscreen to place the frame, as is done with point-of-service or single-purpose screens.
In the next example, we execute the xterm command on a remote machine, instructing the command to display on our test machine's display 0.
# xterm -display testmachine.atl.hp.com:0 Xlib: connection to "testmachine.atl.hp.com:0.0" refused by server Xlib: No protocol specified xterm Xt error: Can't open display: testmachine.atl.hp.com:0
The error in the previous example is due to X security controls. Because we do not have an xterm running in the screen, we need to instruct the server to allow incoming connections. Of course, if we come from the local host using a different port such as the console, all we would need to do is execute xterm -display :0. However, if the client is connecting over the network, we need to grant the client access to our local display. This is achieved through executing the xhost + command, which grants the remote machine access to the local display. See the man pages for xhost for all options. The + opens the X display up to all hosts; therefore, to minimize security risk, the hostname or IP of the connecting client should be used. However, because we have not started an xterm yet, we can create a file called Xn.hosts (n = display). The X server reads this file by default and allows any host named in this file to have access to the local display.
In Figure 15-2, the X server is running on a display with two clients (xterm and xclock) running in the foreground without using a window manager client.
Figure 15-2. Two clients running in the foreground without a window manager client.
As you can see, the clock is sitting on top of the xterm, and we have no way of moving it or defining which window is on top. This is the job of the window manager. After the window manager is started, you can move the window frames around as depicted in Figure 15-3.
Figure 15-3. With the windows manager running, you can move the window frames around.