Bits and Bytes from Johnny Mac

Tuesday, October 18, 2005

Hey, Did You Hear That?

I didn't either. Somewhere along the path of switching yum repos and upgrading various X11, KDE and Gnome rpms, I lost my sound configuration. Every time I rebooted, which is quite often on my laptop, I had to reset all the Alsa Mixer volume controls. This grew to be rather tiresome since this includes 6 different sliders. Even one slider is too many though. It would be cool if the computer could simply remember.

Luckily there is a solution, xinit.

Scripts placed in the /etc/X11/xinit/xinitrc.d directory are executed automatically whenever the X server is started. (Caveat: xinitrc-common actually only executes scripts that end in '.sh'.) I added the following script:
BEGIN /etc/X11/xinit/xinitrc.d/soundcard.sh
#!/bin/bash

/usr/sbin/alsactl restore
END /etc/X11/xinit/xinitrc.d/soundcard.sh

This restores the previously saved Alsa Mixer settings. Those settings are persisted by the following command:
/usr/sbin/alsactl store

That command must be run as root because the settings are saved to /etc/asound.state. You could instead use the '-f' parameter to specify an alternate file if you feel the need to have per user settings.

I happened upon this information by digging through /etc/modprobe.conf. My colleague had noticed the playing the test sound under "Soundcard Detection" triggered the restoration of sound. I figured it was simply a module loading problem. However, I already had the proper pieces in place in modprobe.conf:

alias snd-card-0 snd-intel8x0
options snd-card-0 index=0
install snd-intel8x0 /sbin/modprobe --ignore-install snd-intel8x0 && /usr/sbin/alsactl restore >/dev/null 2>&1 || :
remove snd-intel8x0 { /usr/sbin/alsactl store >/dev/null 2>&1 || : ; }; /sbin/modprobe -r --ignore-remove snd-intel8x0

This seems to indicate that the Alsa Mixer settings should be automatically saved at shutdown and restored at bootup. I even tried adding an initialization script to /etc/init.d to perform these functions explicitly. This did not work for me. There must be some sort of reset to the sound card settings each time X starts that overwrites anything that happened at boot time.

I noticed that if I ran '/usr/sbin/alsactl restore' from a terminal window after X had started that sound was correctly restored. I am not sure why, but I had to run '/usr/bin/alsactl store' by hand as root before my soundcard.sh script would function properly. In any event, this fairly simple change saves a little frustration on each reboot.

Friday, October 14, 2005

SSH Command Completion

Fedora Core 4 (and others) ship with some sort of command completion for ssh. I had heard about it but never seen it work until recently. I work in a small office, and we were using /etc/hosts instead of DNS. I recently setup BIND on an internal server, but I needed to make it use a third-level domain. I didn't want to maintain an independent authoritative DNS server that would have to include our outward facing servers, but BIND is probably a whole post unto itself.

It turns out that ssh command completion only works on /etc/hosts. Yeah, that's about useful. So we lengthened our FQDNs and lost command completion. Cool. So every ssh command line is 30 characters.

Unitl now.

I wrote a new command completion function for ssh that operates on ~/.ssh/known_hosts. It works correctly with no user name or with the user@host syntax.

Enjoy.


function ssh_complete
{
local c=${COMP_WORDS[COMP_CWORD]};
local commands=`cat ~/.ssh/known_hosts | cut -f 1 -d ' ' | sed 's/,/ /g'`

if [ 1 -eq `echo $c | grep -c '@'` ]; then
c=`echo $c | sed 's/^.*@/@/'`
commands=`echo @$commands | sed 's/ / @/g'`
fi

if [ -z "$c" ]; then
COMPREPLY=($commands)
else
COMPREPLY=(`echo $commands | sed 's/ /\n/g' | grep ^$c`)
fi
}


Of course this must be followed by the command to associate the 'ssh' command with the 'ssh_complete' function:

complete -o default -F ssh_complete ssh

Wednesday, October 12, 2005

Frustrating TOra/QT Bug

I have been preaching the wonders of Toolkit for Oracle (TOra) to my colleague. I got him to install it, and it would not connect to the database. No matter what we tried he failed with the error ORA-12545, "Connect failed because target host or object does not exist". He was less than impressed.

We sit in the same office, use nearly identical laptops, run the same OS (Fedora Core 4) and use the same database servers. I had gotten the same error previously and remedied it by fixing resolv.conf. I noticed that when I got this error, my sqlnet.log contained "PROTOCOL=TCP" while his contained "PROTOCOL=beq". I went down the painful path of comparing strace outputs to no avail. He googled. No joy.

Finally, my colleague read the help forum on TOra's Sourceforge project page. He found this thread from March, 2005:
http://sourceforge.net/forum/forum.php?thread_id=1249082&forum_id=52737

Joy! In summary, the thread indicates that there was a bug at some point in qt-3.3.4 that caused problems for TOra. We checked versions, and mine was more current. He had 3.3.4-15 while I had 3.3.4-17.4. The difference was due to the fact that I had enabled the kde yum repository. He enabled kde-redhat and kde-redhat-all and ran 'yum upgrade'. The QT libraries were upgraded and the TOra problem was solved.

To enable the two yum repositories, edit /etc/yum.repos.d/kde-redhat.repo. Set 'enable=1' on the top pair of repositories. That's it.

Sunday, October 09, 2005

Xorg/NVidia/Dual Monitor Fun

I recently bought a monitor for work to augment my display for my laptop. If you've ever done this with a laptop, you probably know the pain.

I have a Dell Inspiron 9300 (17", 1440x900). This means that Fedora Core 4 cannot configure my laptop display, so I was already starting from custom modeline entries and a hand-tuned xorg.conf. This also meant I could not expect much help from the Fedora configuration tools. Furthermore, it seems to do the wrong thing for NVidia cards. Or perhaps it's wrong for all cards with dual outputs. Either way, Fedora tried to configure X to see two monitors when really only the video card needs to know.

So that's the starting point. Luckily I work with someone who had already experienced some of this, and he pointed me to the NVidia README that is included with their driver installation. Based on his work, I was able to configure an analog output to an LCD without too much difficulty.

The only thing that I found troublesome at all was the MetaModes line. This line specifies the desired resolutions, in order, for the two monitors. It appears that you cannot specify the primary and secondary display. You get what you get. For me, the analog output is display 0, and my laptop LCD is display 1. This means that the laptop resolution must go second:

Option "MetaModes" "1280x1024,1440x900_70; NULL,1440x900_70"

Here is my entire video card configuration:

Section "Device"
Identifier "Videocard0"
Driver "nvidia"
VendorName "Videocard vendor"
BoardName "NVIDIA GeForce DDR (generic)"
Option "TwinView"
Option "DPMS"
Option "RenderAccel" "true"
Option "TwinViewOrientation" "RightOf"
Option "MetaModes" "1280x1024,1440x900_70; NULL,1440x900_70"
Option "SecondMonitorHorizSync" "31-82"
Option "SecondMonitorVertRefresh" "55-120"
EndSection

About two days after I completed this operation, my monitor at home suddenly died. Having rapidly become a dual monitor addict, I decided to purchase an LCD with two inputs. I use the analog for my desktop, and I use the DVI for a dual monitor setup with my laptop.

This brought about much more pain. Armed with my recently acquired knowledge about dual monitor configuration, I embarked in high spirits. This was not to last.

First things first. The current release of Xorg for FC4 did not have a default modeline for my new monitor. I was a little surprised because it's a fairly vanilla resolution/frequency setup. I bought a ViewSonic VA912b 19" LCD. It runs 1280x1024, non-interlaced at 30-82 (H kHz), 50-85 (V Hz). Luckily I am running SuSE 9.1 on my desktop, and it had no trouble at all. I simply ran xvidtune and generated a modeline entry. This was easier than the usual xvidtune foray, since SuSE was already using the modeline I wanted.

Remember how I said FC4 mistakenly tried to configure multiple monitors? Well I did too. I created a new monitor section with the appropriate frequencies and the modeline. Not only was this not useful, it set me back because the new modeline was not visible to X. There should only be one Monitor section, and it should contain the custom modelines needed by both monitors.

I'm not sure what you should do if you have two displays with wildly conflicting frequency ranges. If the laptop is the primary, it does not matter. The frequencies from the Monitor section would always apply to the laptop, and the "SecondMonitor*" lines inside the video card configuration would apply to the secondary monitor if it is available. However, if the laptop becomes the secondary, then it seems like the frequencies in the Monitor section would apply to the external monitor when it's plugged in, to the laptop when it's not.

Next I found that I had to add the new monitor's resolution to the Screen section under the appropriate Display subsection. I added this while troubleshooting, but when I removed it from a working xorg.conf, I lost the external monitor. For some reason, my coworker did not have the same experience though he is using a different external display.

The last two changes are to the video card configuration. The NVidia README recommends against using this line:

Option "ConnectedMonitor" "dfp,dfp"

unless absolutely necessary. It turns out that it was absolutely necessary for me. Without that line, NVidia would only look for an analog output besides the built in display. This was something that I discovered early on.

The last change is the one that took me the longest to find. I had a mental block about not being about able to rearrange the ordering of the primary and secondary displays. Well, I was still correct, but with a DVI output, my laptop is always the primary! My MetaModes line had to be switched around:

Option "MetaModes" "1440x900_70,1280x1024_73; 1440x900_70,NULL"

This was the last thing I expected to change, and it turns out that it was. I wish this stuff was better documented somewhere.

There is one more small chapter to this saga. Anyone who has used X for any length of time knows good and well that I don't have one xorg.conf that correctly configures: laptop alone, laptop plus analog output AND laptop plus DVI out to a different monitor. Both configurations work in the absence of any external monitor. This is handled by the second MetaModes entry, e.g. "1440x900_70,NULL". However, I cannot start X if I am plugged into the wrong external monitor.

To handled this more gracefully, I hacked together a startup/shutdown script. This script uses the IP address to determine if I am running at home or in the office and copies the appropriate xorg.conf into place. On shutdown, it copies my previous xorg.conf (the one that only supports the laptop display) into place so that I will be able to start the X-based display on boot up regardless of where I am or what I have plugged in. Obviously, the script needs to run after /etc/init.d/network on startup, and it probably should run early in the shutdown sequence. Now, when I go home or to work, my computer automatically configures itself for the appropriate display setup.

I googled quite a bit, and I could not locate this scenario. Hopefully this will save someone else an hour or two down the line.