Bits and Bytes from Johnny Mac

Friday, January 19, 2007

Compile errors with VMWare Server 1.0.1 on 2.6.19 kernel

I just did a 'yum upgrade' and received kernel-2.6.19-1.2895.fc6. Unfortunately, when I reran vmware-config.pl, I got the following error:

Using 2.6.x kernel build system.
make: Entering directory `/tmp/vmware-config1/vmnet-only'
make -C /lib/modules/2.6.19-1.2895.fc6/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. modules
make[1]: Entering directory `/usr/src/kernels/2.6.19-1.2895.fc6-i686'
CC [M] /tmp/vmware-config1/vmnet-only/driver.o
CC [M] /tmp/vmware-config1/vmnet-only/hub.o
CC [M] /tmp/vmware-config1/vmnet-only/userif.o
/tmp/vmware-config1/vmnet-only/userif.c: In function ‘VNetCopyDatagramToUser’:
/tmp/vmware-config1/vmnet-only/userif.c:629: error: ‘CHECKSUM_HW’ undeclared (first use in this function)
/tmp/vmware-config1/vmnet-only/userif.c:629: error: (Each undeclared identifier is reported only once
/tmp/vmware-config1/vmnet-only/userif.c:629: error: for each function it appears in.)
make[2]: *** [/tmp/vmware-config1/vmnet-only/userif.o] Error 1
make[1]: *** [_module_/tmp/vmware-config1/vmnet-only] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.19-1.2895.fc6-i686'
make: *** [vmnet.ko] Error 2
make: Leaving directory `/tmp/vmware-config1/vmnet-only'
Unable to build the vmnet module.

Luckily I was able to find a solution in the VMWare forums:

VMTN Discussion Forums: vmware-server on kernel 2.6.19 ...

Instead of using the solution I related here, I symlinked config.h to autoconf.h:

cd /lib/modules/2.6.19-1.2895.fc6/build/include/linux
ln -s autoconf.h config.h

Additionally, I fixed the compile error by editing two VMWare Server source as described in the first post of the aforementioned VMWare forum link. I followed the advice of the next poster and set both variables to CHECKSUM_PARTIAL.

I'm not sure if there are lurking negative consequences, but this has enabled me to work with VMWare server again.

Friday, December 22, 2006

Running VMware Server in FC6

I run VMware Server 1.0.1 for a number of different development tasks. At some point after upgrading Fedora, I used vmware-config.pl to reconfigure VMware for my new kernel. This basically means recompiling a few VMware kernel modules. I ran into this error message that halted my progress:
/tmp/vmware-config4/vmnet-only/procfs.c:33:26: error: linux/config.h: No such file o directory
make[2]: *** [/tmp/vmware-config4/vmnet-only/procfs.o] Error 1
make[1]: *** [_module_/tmp/vmware-config4/vmnet-only] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.18-1.2868.fc6-i686'
make: *** [vmnet.ko] Error 2
make: Leaving directory `/tmp/vmware-config4/vmnet-only'
Unable to build the vmnet module.

At first glance, missing a kernel header file seems like a bad thing. It turns out to be a simple issue though. The use of linux/config.h has been deprecated. It remained as a placeholder for a while, but it has now been completely removed. Since VMware has not been getting anything from that header, the fix is simple:

touch /lib/modules/2.6.18-1.2868.fc6/build/include/linux/config.h

After that, vmware-config.pl completes successfully, and the world is right again. The only downer is that you have to do this extra step every time you upgrade the kernel. In all likelihood though, you would think VMware would address this issue in the next release.

Saturday, December 16, 2006

Beryl Workaround

As I noted in my previous post, I recently switched from FC5 to FC6. It was a very easy upgrade, and FC6 is most definitely worth it. The fonts are so much crisper, yum is way faster, and many things are generally just a little more polished than FC5.

One of the whizziest new features is the 3D desktop. This is enabled by use of OpenGL acceleration in the window manager. Very, very cool. Fedora encourages using Compiz as the window manager to get access to the eye candy.

This really tickled my fancy, so I kept digging into Compiz. As I looked more into Compiz, I found a fork of that project called Beryl. Perhaps I didn't dig deeply enough into Compiz, but one thing I didn't like was that there were almost zero configuration options and no plugins came with it by default.

Beryl, on the other hand, comes with all kinds of goodies. It is highly configurable, and it comes with all kinds of special effects by default. So I stuck with Beryl.

The only downer so far is that resuming from suspend does not work correctly. Everything on my laptop is functioning as expected except that the video does not resume cleanly. I can ssh in from another machine and restart beryl-manager at which point everything is fine. That's a simple enough workaround, but it's kind of annoying, and it doesn't work too well when I am moving my laptop from one network to another.

To work around this issue, I wrote a little perl script to act as a watchdog. I use this to launch beryl-manager in my session startup, and I modified my resume_video function in /etc/pm/functions-nvidia (part of pm-utils) to signal the watchdog. The watchdog then kills beryl (the window manager) and beryl-manager and restarts beryl-manager. This seems to work very reliably.

Hopefully we'll get a real fix soon. The behavior is kind of similar to the bad ole days when the nVidia driver was kind of wonky. I'm not 100% sure that it is Beryl. Compiz appears to exhibit the same behavior, but Metacity has no problem. Perhaps there's something flaky in the nVidia OpenGL code. However, since restarting Beryl fixes the issue, they have an opportunity to make life better for the user.

In any event, Beryl is well worth a little extra work. I'm never looking back!

Here's how to implement the watchdog workaround:
  • Download the watchdog script
  • tar xzvf beryl_watchdog.tar.gz
  • mv beryl_watchdog.pl <installation location> (e.g. ~/bin, /usr/local/bin)
  • Edit System->Preferences->More Preferences->Sessions->Startup Programs
  • Add beryl_watchdog.pl to the list of programs to start
  • Edit /etc/pm/functions-nvidia and add 'killall -USR1 beryl_watchdog.pl' as the last line in resume_video()
The net effect of all this is:
  • The watchdog script will be launched as part of the session startup
  • Upon resuming from suspend, the watchdog will get a USR1 signal
  • Upon receiving that signal the watchdog script will kill beryl and beryl-manager and relaunch beryl-manager
The last thing to note is that this only addresses Gnome usage. I'm not sure there is a problem under KDE. If the same problem does exist, the watchdog script may be useful, but the mechanics of including it in the session startup will differ.

This is a dirty little hack, but it is the difference between being able to use suspend plus Beryl and not. Hopefully this will be short-lived and I can delete this in a couple of months.

Thursday, December 14, 2006

Fix AdobeReader on Fedora Core 6

I recently upgraded from Fedora Core 5 to Fedora Core 6 on my laptop. It was one of the easiest in place upgrades I've ever done. However, I did experience a glitch with Adobe Acrobat Reader (AdobeReader_enu-7.0.8-1).

When running from the command line, I got this error in an endless loop:

jmcnair@laptop.mcnair.org:0 $ acroread
expr: syntax error
expr: syntax error
...


I found the solution in this forum:
FULL Fedora Core 6 Probs - LinuxQuestions.org

In that forum, there is a link to this small patch.

To apply the patch, become root and then:

cd
wget http://remi.collet.free.fr/files/acroread.patch
cd /usr/local/Adobe/Acrobat7.0/bin
cp -a acroread acroread.orig
patch -p0 < ~/acroread.patch


You should see this output:
patching file acroread


You should then be able to run 'acroread' from the command line with no errors.

Thursday, February 23, 2006

New Scientist Quantum computer works best switched off - News

New Scientist Quantum computer works best switched off - News

Wonders never cease. Computers that are more reliable when not running.

Tuesday, December 27, 2005

How Do I Turn On NumLock in X by Default?

yum install numlockx

Yes, it's that easy. This is a utility package found in Fedora Extras. It installs a command line program that will set NumLock to on or off. It also installs the shell script /etc/X11/xinit/xinitrc.d/numlockx.sh. This is executed at X startup time and sets the NumLock key to on.

The shell script was a nice surprise. I found it when I was about to open vi to create exactly the same script. Every once in a while, things just work.

Friday, December 09, 2005

Listening to 750AM, Finally

I enjoy listening to various talk shows on one of my local radio stations, but until very recently, it was impossible for me to listen on my laptop. The station has gone through a couple of iterations of Windows-only internet delivery options despite the ready availability of more inclusive alternatives. I fail to grasp why some companies practically bend over backwards to exclude certain users, but that's another story altogether.

The purpose of this post is that 750AM is finally obtainable from Linux. Using Firefox 1.5 and current mplayer rpms, I am able to go to the 750AM streaming site and listen. The screen is stilled jumbled, but the play button is easily recognizable.

Even better, using 'ps auwx', I found the command line arguments passed to mplayer. I stripped off some of the browser related options, and I wound up creating the following alias:
alias 750am='mplayer -user-agent NSPlayer -osdlevel 0 -nojoystick -cookies -slave -cache 512 mms://uni4.cox.streamaudio.com/WSB_AM'

This allows me to listen by simply typing '750am' on the command line, leaving my browser less cluttered.

Happy listening.

Thursday, December 01, 2005

JDBC: Patterns and Anti-Patterns

Because of the nature of JDBC, the code for executing any given query is strikingly similar. There is a certain pattern that cannot be avoided when using this API directly. The driving factor is that the developer is directly manipulating, at least to some degree, the state of a remote resource and the state of the connection to that resource. Fortunately, the template is fairly straightforward.

A method to select information will look substantially like this:

public String getFooNameById(long id)
{
String fooName = null;
Connection connection = null;
PreparedStatement preparedStatement = null; // PreparedStatements are compiled and cached and sometimes pooled.
// Always favor them over Statements.
ResultSet results = null;

try
{
connection = _poolManager.getConnection(); // Always get the connection from some managed resource pool
preparedStatement = connection.prepareStatement("select name from foo where id = ?");
preparedStatement.setLong(1, new Long(id)); // JDBC is 1-indexed
results = preparedStatement.executeQuery();

if (results.next()) // Cursor always starts before the first row
fooName = results.getString(1);
}
catch (SQLException ex)
{
_log.error("getFooNameById() caught an SQLException while attempting to retrieve data", ex);
}
finally // Resources must always be freed so execute in a finally block
{
try
{
// close entities in reverse order
if (null != results)
results.close();
if (null != preparedStatement)
preparedStatement.close();
if (null != connection)
connection.close(); // With a pool manager, this just returns the connection to the pool
}
catch (SQLException ex)
{
_log.warn("getFooNameById() caught an SQLException while freeing resources", ex);
}
}

return fooName;
}

If you are slightly more paranoid, you would wrap each of the three closes in independent try-catch blocks. This method eats the data retrieval SQLException if it occurs and simply returns null. This is a policy decision. The method could just as easily allow the SQLException to propagate up the stack, or it could wrap it in another Exception subclass. You generally would not want to propagate the SQLException related to freeing resources. Regardless, the pattern remains largely the same. Inserts, updates and deletes are similar but would not involve a ResultSet.

Consider the following anti-patterns:
{
Connection connection = ...;
PreparedStatement preparedStatement = ...;
ResultSet results = ...;
return results.getString(1);
}

The above example always leaks a connection from its pool (or a socket connection if there is no pool, yet another anti-pattern) and a prepared statement from its pool (if there is one). It also leaves the cursor open on the database side because the PreparedStatement is never closed. This would usually be recognized very quickly, because the application would only be able to execute maxPoolSize queries, say 30 to 50, before running out of resources.

Consider something more subtle:
{
Connection connection = ...;
PreparedStatement preparedStatement = ...;
ResultSet results = ...;
String fooName = results.getString(1);

results.close();
preparedStatement.close();
connection.close();

return fooName;
}

This example again leaks everything, but only if an exception is thrown past the close() statements. This could slowly leak resources depending on usage.

Last one:
{
...
try
{
connection = ...;
preparedStatement = ...;
results = ...;
fooName = results.getString(1);
}
catch (...) {}
finally
{
connection.close();
}

return fooName;
}

This example is almost correct, and it may work with some JDBC drivers. The vendor may opt for Connection.close() to propagate down to subordinate resources. However, this is not required, and it's a bad habit to start. I believe this works fine with MySQL. With Oracle it leaks memory. I'm not sure if it leaks cursors. This could be really interesting to find if the application supports multiple database platforms, but the one that doesn't leak is more favored in development.

Hopefully this will save someone a couple of hours of frustration. If you have a fair amount of database access code to write, you might consider using an OR mapper such as Hibernate. This approach hides some of the repititive, error-prone tasks associated with JDBC.

Wednesday, November 16, 2005

Wireless networking

I am using an Intel® PRO/Wireless 2200 chip in my Inspiron laptop. When I first installed Fedora Core 3, I installed the firmware and drivers and achieved wireless nirvana with little difficulty. However, sometime along the way, this functionality disappeared. It happened to me a few kernels into Fedora Core 4. It wasn't really troubling me since I've been using my laptop in tethered environments lately. My colleague, Darin, sparked my interest, however, when he informed me that his wireless capability magically reappeared after upgrading to 2.6.14.

This kernel includes the ieee80211 and ipw2200 modules, obviating the need to maintain those by hand. In addition, the wireless tools are now a yum-accessible rpm called wireless-tools. This leaves only the firmware to maintain manually. Forward progress!

Unfortunately, I did not meet with the same success. I noticed in the 'dmesg' output that the ipw2200 modules was actually trying to access a particular firmware version number, 2.2. I had maintained my wireless packages to some degree and had already upgraded to 2.3. This turned out to be my undoing. Apparently the version of ipw2200 that is shipped with the kernel is slightly older.

I downgraded to 2.2, and all is right with the world again. This little nugget of knowledge does not seem to be on the website of the ipw2200 team, hence the motivation to share in my blog.

The conclusion is be aware of firmware versions when using the default ieee80211 and ipw2200 drivers.

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.