Installing mytop on RHEL5

I recently installed mytop on a new 64-bit Red Hat Enterprise Linux 5.4 server. Here are my notes.

The mytop program requires two Perl modules. So let's make sure those are installed first. The perl-DBI package is usually installed as a dependency already. Check if it's there:


# yum list installed *DBI
Loaded plugins: rhnplugin, security
Installed Packages
perl-DBI.x86_64 1.52-2.el5 installed

Install TermReadKey module, also known as Term::ReadKey. I am installing this from the EPEL repository, which I regard as very safe (in terms of compatibility, longevity and maintenance). If you're not set up with EPEL, you can do

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

Anyway, installing Term::ReadKey from EPEL:


# yum install perl-TermReadKey
Loaded plugins: rhnplugin, security
Setting up Install Process
Resolving Dependencies
--> Running transaction check
---> Package perl-TermReadKey.x86_64 0:2.30-4.el5 set to be updated
--> Finished Dependency Resolution
...
Running rpm_check_debug
Running Transaction Test
Finished Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : perl-TermReadKey 1/1

Installed:
perl-TermReadKey.x86_64 0:2.30-4.el5

Now it's time to get mytop.


# wget http://jeremy.zawodny.com/mysql/mytop/mytop-1.6.tar.gz
# tar zxvf mytop-1.6.tar.gz
# cd mytop-1.6
# perl Makefile.PL
Writing Makefile for mytop

# make test
cp mytop blib/script/mytop
/usr/bin/perl "-MExtUtils::MY" -e "MY->fixin(shift)" blib/script/mytop
PERL_DL_NONLAZY=1 /usr/bin/perl "-Iblib/lib" "-Iblib/arch" test.pl
1..1
ok 1

# make
Manifying blib/man1/mytop.1

# make install
Installing /usr/share/man/man1/mytop.1
Installing /usr/bin/mytop
Writing /usr/lib64/perl5/site_perl/5.8.8/x86_64-linux-thread-multi/auto/mytop/.packlist
Appending installation info to /usr/lib64/perl5/5.8.8/x86_64-linux-thread-multi/perllocal.pod

# which mytop
/usr/bin/mytop

[ Submitted by John on Tue, 2009-09-08 08:31. | | ]

Eudora, Snow Leopard and Kerberos

I upgraded to OS X 10.6 "Snow Leopard" yesterday. A smooth upgrade except for one thing.

Eudora 6.2.4 for Mac OS X works on 10.6 (provided the optional Rosetta PowerPC-emulation code is installed), but not with kerberos.

To use kerberized POP, Eudora depends on the Code Fragment Manager library "Kerberos" which is part of the MIT Kerberos Extras for OS X package.

The actual library is installed to /System/Library/CFMSupport/Kerberos and is a 983k file last updated in 2003. It's labeled version 4.2.

If the MIT Kerberos Extras for OS X have been installed, and thus this library is installed, Eudora will fail to launch with the following errors:

Launch failed with error code -2821 (cfragInitFunctionErr) for application /System/Library/Frameworks/Carbon.framework/Versions/A/Support/LaunchCFM App

Eudora can be launched by removing the library. But then kerberos-enabled POP cannot be accomplished.

[ Submitted by John on Tue, 2009-09-01 10:55. | | ]

RHEL5 won't install on Dell OptiPlex 745 with more than 4G RAM

I wanted to install RHEL5 x86_64 on a Dell OptiPlex 745 (that's an Intel Q965 (ICH8) Express chipset). I had a spare one sitting around and it had 6G of RAM.

However, when I booted from the installer CD and chose the RHEL 5 Server x86_64 option, it got up to the initrd line and then lots of text started scrolling by. The text was hard to read but I could make out the following phrases:

  • mapcount

  • trying to fix it up, but a reboot is needed

After letting that scroll by for a while, I ended up with a message stating that there was a kernel panic.

I was frustrated at not even being able to run the installer, but I solved this by passing the following parameters to the kernel:

mem=2G text

I then hopefully updated the box to kernel-2.6.18-128.4.1.el5.x86_64.rpm but alas, the same problem returned at boot time.

Finally, I pulled two 1G sticks from the box, reducing the memory to 4G. Now it boots fine.

[ Submitted by John on Wed, 2009-08-19 15:54. | | ]

Postliteracy

Adam Engst's article Have We Entered a Post-Literate Technological Age? is worth reading.

When TidBITS contributing editor Matt Neuburg tried to teach a group of his friends' kids REALbasic one summer, he found himself frustrated at almost every turn - they lacked the conceptual underpinning that they could make the computer do something. And more important, they didn't care...

[ Submitted by John on Tue, 2009-08-18 16:49. | ]

Programmatically suspending, quitting, and resuming Parallels Desktop for scheduled backup

I wanted to do automatic scheduled backups with the awesomely amazing SuperDuper!. The computer to be backed up was a Mac Mini running Mac OS X 10.5 Leopard. But the problem was that Parallels Desktop was running all the time. And everyone knows that when you try to back up open files that may be changing, Bad Things Happen.

"No problem," I thought. Since SuperDuper! allows you to run a script before and after a scheduled backup (have I mentioned how brilliant SuperDuper! is?) I'll use a script to suspend the virtual machine before the backup, and resume it afterward.

SuperDuper! with shell scripts assigned

So I fired up Script Editor and went to open up Parallels Desktop's AppleScript Dictionary.

Uh.

Apparently Parallels Desktop does not implement AppleScript.

I was stymied until I remembered something that the indefatigable Matt Neuburg had written in AppleScript: The Definitive Guide, Second Edition in a chapter titled Unscriptable Applications. The approach is to cheat by using the Accessibility API built into Mac OS X. From there you can direct mouse clicks, radio button selection...in short, all sorts of mayhem. "Aha!" I thought. "I'll just direct Parallels from the Accessibility API! Sort of like the puppeteer in Being John Malkovich."

First I made sure that accessibility was enabled by going to the Universal Access preference pane in System Preferences.

Enable assistive devices

Then I made a shell script for SuperDuper! to run before backup. Here's the script:

#!/bin/sh
osascript /Users/john/suspendparallels.txt
sleep 35
osascript /Users/john/quitparallels.txt
sleep 10

The shell script first executes the suspendparallels.txt AppleScript to suspend the virtual machine:

-- Suspend a Parallels virtual machine.
-- Assumptions:
--  - only one virtual machine is running
--  - the "Enable access for assistive devices" checkbox is checked in the Universal Access control panel
-- Tested on Mac OS X 10.5.7 with Parallels Desktop 4.0.
-- John VanDyk 7/22/2009
tell application "Parallels Desktop" to activate
tell application "System Events"
  tell application process "Parallels Desktop"
    tell menu "Virtual Machine" of menu bar 1
      click menu item "Suspend"
    end tell
  end tell
end tell

Then the shell script waits for 35 seconds (enough time for the virtual machine to be written to disk), and executes the quitparallels.txt AppleScript:

-- Quit Parallels.
-- Assumptions:
--  - only one virtual machine is running
--  - the "Enable access for assistive devices" checkbox is checked in the Universal Access control panel
-- Tested on Mac OS X 10.5.7 with Parallels Desktop 4.0.
-- John VanDyk 7/22/2009
tell application "Parallels Desktop" to activate
tell application "System Events"
  tell application process "Parallels Desktop"
    tell menu "Parallels Desktop" of menu bar 1
      click menu item "Quit Parallels Desktop"
    end tell
  end tell
end tell

"But John," I can hear you asking, "why not put these together into one simple AppleScript and just use 'delay 35' to create the pause?" I'll tell you why. Because when you do it that way it doesn't work. Plus I got a scary error about "class released with no pool in place - just leaking". Seriously. So I figured, since AppleScript is always, well, flaky for me, I'd just put as much as I could in the shell script and call out to AppleScript only when necessary.

All right. So now SuperDuper! can clone the drive since the Parallels Desktop Windows XP virtual machine has been suspended and the program has been closed. But what about afterwards, when we want to bring Parallels Desktop up just like it was? Turns out, that's even easier. Here's the shell script that SuperDuper! runs after it completes the copy:

#!/bin/sh
osascript -e 'tell app "Parallels Desktop" to activate'
sleep 10
osascript /Users/john/resumeparallels.txt

That first osascript call is actually launching Parallels Desktop. We give it 10 seconds to launch, which is plenty.

Fortunately it launches with the suspended virtual machine. All we have to do is tell it to resume. Here's resumeparallels.txt:

-- Resume a Parallels virtual machine.
-- Assumptions:
--  - only one virtual machine is running
--  - the "Enable access for assistive devices" checkbox is checked in the Universal Access control panel
-- Tested on Mac OS X 10.5.7 with Parallels Desktop 4.0.
-- John VanDyk 7/22/2009
tell application "Parallels Desktop" to activate
tell application "System Events"
  tell application process "Parallels Desktop"
    tell menu "Virtual Machine" of menu bar 1
      click menu item "Resume"
    end tell
  end tell
end tell

Presto! It works.

[ Submitted by John on Wed, 2009-07-22 13:07. | | ]

Deduplicating Drupal history table

Recently I had to do a migration of an old Drupal site with 4.6 million rows in the history table. The history table records when a user has viewed a node. A record looks like this:

nid uid timestamp

Because old versions of Drupal didn't enforce a unique index on the nid-uid combination, sometimes race conditions let two records in with the same nid-uid combo but different timestamps. I got rid of duplicate records with the following process.

1. Find out how many duplicates we have:

SELECT nid, uid, count( * ) AS n
FROM history
GROUP BY nid, uid
HAVING n > 1;

In this case I had 276 records.

2. Since I didn't really care which of the two duplicate records was kept, I could use this approach to quickly throw out duplicates:

ALTER IGNORE TABLE history ADD UNIQUE INDEX unique_index ( uid, nid );

3. Now I discarded the unique index, since I was only using it as a tool to remove duplicates. When I import the data into a modern Drupal, uniques will be enforced anyway.

ALTER TABLE history DROP INDEX unique_index;

4. Repeat step 1, with 0 records in the result set.

[ Submitted by John on Tue, 2009-07-21 20:45. | ]

Negative deletion

I'm confused...does this mean Leopard is actually creating files?

[ Submitted by John on Wed, 2009-07-08 15:05. | | ]

Example: How to install a package for R on Mac OS X 10.5 Leopard

Assuming that you already have the R statistics program installed on your Mac, the following can be used to install a package from the command line.

First, get the .tgz file (we'll use plotrix as the package we want to install):

$ curl http://cran.r-project.org/bin/macosx/universal/contrib/r-release/plotrix_2.6-1.tgz > plotrix_2.6-1.tgz

Check that R is properly installed:

$ which R
/usr/bin/R

Install the package:

$ sudo R CMD INSTALL plotrix_2.6-1.tgz
Password:
* Installing to library '/Library/Frameworks/R.framework/Resources/library'
* Installing *binary* package 'plotrix' ...
* DONE (plotrix)

Check that everything is happy:

$ ls -l /Library/Frameworks/R.framework/Resources/library/
total 8
drwxrwxr-x 16 root admin 544 Jun 26 09:59 KernSmooth
drwxrwxr-x 20 root admin 680 Jun 26 09:59 MASS
drwxrwxr-x 22 root admin 748 Jun 26 09:59 Matrix
-rw-rw-r-- 1 root admin 866 Jun 26 10:00 R.css
drwxrwxr-x 15 root admin 510 Jun 26 09:59 base
drwxrwxr-x 16 root admin 544 Jun 26 09:59 boot
drwxrwxr-x 18 root admin 612 Jun 26 09:59 class
drwxrwxr-x 16 root admin 544 Jun 26 09:59 cluster
drwxrwxr-x 13 root admin 442 Jun 26 09:59 codetools
drwxrwxr-x 13 root admin 442 Jun 26 09:59 datasets
drwxrwxr-x 18 root admin 612 Jun 26 09:59 foreign
drwxrwxr-x 17 root admin 578 Jun 26 09:59 grDevices
drwxrwxr-x 15 root admin 510 Jun 26 09:59 graphics
drwxrwxr-x 16 root admin 544 Jun 26 09:59 grid
drwxrwxr-x 19 root admin 646 Jun 26 09:59 lattice
drwxrwxr-x 15 root admin 510 Jun 26 10:00 methods
drwxrwxr-x 15 root admin 510 Jun 26 09:59 mgcv
drwxrwxr-x 21 root admin 714 Jun 26 09:59 nlme
drwxrwxr-x 18 root admin 612 Jun 26 09:59 nnet
drwxr-xr-x 15 root admin 510 Jul 7 14:30 plotrix
drwxrwxr-x 17 root admin 578 Jun 26 09:59 rpart
drwxrwxr-x 20 root admin 680 Jun 26 09:59 spatial
drwxrwxr-x 15 root admin 510 Jun 26 09:59 splines
drwxrwxr-x 18 root admin 612 Jun 26 09:59 stats
drwxrwxr-x 14 root admin 476 Jun 26 09:59 stats4
drwxrwxr-x 16 root admin 544 Jun 26 09:59 survival
drwxrwxr-x 17 root admin 578 Jun 26 09:59 tcltk
drwxrwxr-x 15 root admin 510 Jun 26 09:59 tools
drwxrwxr-x 17 root admin 578 Jun 26 09:59 utils

Sure enough, plotrix is there nestled among the other packages.

[ Submitted by John on Tue, 2009-07-07 14:20. | | ]

Blast2GO BLAST results not opening in Mac web browser

If you use Blast2GO on Mac OS X 10.5 Leopard (and haven't been derailed completely by Apple moving Java Web Start around), you might have run into the issue of not being able to view BLAST results in a web browser. Blast2GO even helpfully opens a window for you to choose which browser you want to use, but no matter what you select, nothing happens. Except the following gets written to the Application Messages pane:

Error with choosen Browser! /Applications/Firefox.app: cannot execute

The solution is to tell Blast2GO which browser you want to use. You do that by specifying a path in the blast2go.properties file. You can find the file at /Users/yourusername/blast2go/blast2go.properties.

When you open the file in your text editor* you'll see a property entry under User Pathes (sic) called BlastBrowser.Explorer. You may be tempted to put /Applications/Firefox.app here or even, if you're clever, /Applications/Firefox.app/Contents/MacOS/firefox. But don't do that. Firefox will just complain at you about more than one instance running at a time. Rather, use /usr/bin/open and it will automatically launch the appropriate browser.


// User Pathes
MainGui.Workspace=/Volumes/Data/blast2go_datafile.dat
MainGui.Favorites=/Volumes/Data/blast2go_datafile.dat,
BlastBrowser.Explorer=/usr/bin/open

I ensured that Firefox was the default application to open .fcgi files by creating a text file called foo.fcgi and then selecting Get Info. Probably unnecessary because /usr/bin/open opens URLs in the default browser anyway.

*I used TextWrangler -- if you're still opening files in TextEdit do yourself a favor and download TextWrangler, then make it the default text editor.

[ Submitted by John on Thu, 2009-06-25 14:58. | | ]

Permissions fix for Podcast Producer

I'm setting up Podcast Producer, a proprietary podcast workflow system from Apple. After wading through the setup of OpenDirectory, Kerberos, NFS, etc., I attempted to submit my first podcast. On the client console, I got


pcast[5802]: Starting file upload for 63165854-E6A9-46F6-ADE7-BF84D67568A4
pcast[5802]: Total Upload Size: 259255
pcast[5802]: Destination directory: '/Volumes/SFS/Recordings/783AEE7D-C6EA-4F7D-8D1A-17AAFF7905AA' is not mounted on client machine. Skipping.
pcast[5802]: Trying HTTPS POST of '63165854-E6A9-46F6-ADE7-BF84D67568A4.plist' to 'https://podcastserver.example.com:8170/cgi-bin/pcastupload.cgi'
pcast[5802]: Uploaded: 355/259255 bytes (0 %)
pcast[5802]: Time elapsed: 0.064978 and remaining: Infinity (seconds)
pcast[5802]: 500 "Internal Server Error"
pcast[5802]: FTP upload not configured
pcast[5802]: Unable to upload file: /Users/john/Library/Application Support/pcastuploader/metadata/63165854-E6A9-46F6-ADE7-BF84D67568A4.plist
pcast[5802]: pcastuploader quit

On the server, I got

pcastupload.cgi[9708]: /var/pcast/server/cgi.conf does not exist

Digging in further on the server, /Library/Logs/pcastserverd/apache_error.log says

[error] [client x.x.x.x] /usr/share/podcastproducer/cgi-bin/pcastupload.cgi:36:in `read_config': CGI Configuration file does not exist (CGIException)
[error] [client x.x.x.x] \tfrom /usr/share/podcastproducer/cgi-bin/pcastupload.cgi:30:in `initialize'
[error] [client x.x.x.x] \tfrom /usr/share/podcastproducer/cgi-bin/pcastupload.cgi:275:in `new'
[error] [client x.x.x.x] \tfrom /usr/share/podcastproducer/cgi-bin/pcastupload.cgi:275
[error] [client x.x.x.x] Premature end of script headers: pcastupload.cgi

Well, all pcastupload.cgi is trying to do is read the config file at /var/pcast/server/cgi.conf. A quick check showed that /var/pcast and /var/pcast/server were not readable by anyone except the owner, root.

So to fix the problem:


sudo chmod o+rx /var/pcast/
sudo chmod o+rx /var/pcast/server/

Now the podcast is successfully uploaded to the server. Of course, it's dying there now, and I'm off to investigate.

[ Submitted by John on Tue, 2009-06-23 14:57. | | ]