Friday, November 4, 2011

Using Google's CoreDumper library

The Google team has published a library called CoreDumper for generating process core dumps programatically. This can be useful for post-analysis in environments where core files are not or cannot be generated/saved by the system (ulimit restrictions, etc).

At my work we've incorporated the CoreDumper library into our Production code, and are using it in conjunction with our exception handling to generate core files when conditions warrant.

One nice feature of this library is the ability to generate a compressed core file, thus significantly reducing disk space consumed by the core.

An example of using this feature follows.


#include <limits>
#include "google/coredumper.h"

void generateCore( const std::string &p_filenameFullPath )
{
// Be sure to use a mutex for concurrency (not shown).
// Reasons are discussed here:
// http://code.google.com/p/google-coredumper/wiki/WriteCoreDump#ERRORS

// The following will create a core file using the specified filename
// and compressed with the gzip compression algorithm.
// Here we're not enforcing limits on the core file size, so if using C++,
// get the limit of size_t as specified. Else replace with SIZE_MAX.
const int iResult =
WriteCompressedCoreDump( p_filenameFullPath.c_str(),
std::numeric_limits<std::size_t>::max(),
COREDUMPER_GZIP_COMPRESSED,
NULL
);

if( 0 == iResult )
{
// replace this call to std::out with a call to your logging system.
std::cout << "generated core: "
<< p_filenameFullPath.c_str()
<< COREDUMPER_GZIP_COMPRESSED->suffix
<< std::endl;
}
else
{
const unsigned int errLen = 128;
char error[ errLen ] = { '\0' };
strerror_r( errno, error, errLen );

// replace this call to std::cerr with a call to your logging system.
std::cerr << "failed to generate core: "
<< error
<< std::endl;
}
}

Friday, July 23, 2010

VirtualBox WinXP iTunes High CPU Utilization

I recently deployed an instance of VirtualBox 3.2 on my home server (Ubuntu 8.04) with WinXP as a guest. My intent was to run an instance of iTunes within that VirtualBox instance to serve the mp3's residing on my fileserver (with the added benefit of Home Sharing & iTunesRemote/AirportExpress).

Everything is running great, however I noticed that even when idle VirtualBox was using close to 100% CPU even when the XP guest was idle but running iTunes. Strange enough VirtualBox's high cpu utilization would drop to reasonable levels (< 10%) when I quit iTunes but continued to run the XP guest.


To solve, I first updated the XP guest to not use ACPI as described here in the last post by kyboren . After making the modifications I shut down the XP guest and restarted VirtualBox. After the XP guest finished loading, the VirtualBox CPU load was reduced by roughly half, though it was still consuming nearly 50% CPU while the XP guest sat idle but running iTunes. Better, but still not ideal.

Next, I disabled Virtual Memory within the XP guest, and restarted only the XP guest. This time, VirtualBox is only using 15% of CPU while the XP guest sits idle but running iTunes. Much better; to me, 15% CPU utilization is an acceptable amount, and is far lower than the 95+% experienced earlier.

I suspect that it was the XP guest restart (and not changing of the virtual memory) that brought VirtualBox's CPU use down to 15%. Upon starting VirtualBox fresh I see that it again hits 50% CPU utilization with the XP guest idle but running iTunes. However restarting the XP guest (via Start --> Turn Off Computer --> Restart) seems to knock the VirtualBox CPU utilization down to an acceptable 15% with the XP guest idle but running iTunes.

So for now my 'fix' is to start VirtualBox, let my XP guest fully boot, then restart my XP guest. Kludgy, but it meets my needs.

Tuesday, February 23, 2010

Convert long to byte array in C++ or C

This post explains how to convert an unsigned long int into a byte array in C/C++. This post assumes that the datatype unsigned long int uses 4 bytes of internal storage; however the examples can easily be adapted to other built-in datatypes (unsigned short int, unsigned long long int, etc).

The code to convert a 4-byte unsigned long int into a 4-byte array:


unsigned long int longInt = 1234567890;
unsigned char byteArray[4];

// convert from an unsigned long int to a 4-byte array
byteArray[0] = (int)((longInt >> 24) & 0xFF) ;
byteArray[1] = (int)((longInt >> 16) & 0xFF) ;
byteArray[2] = (int)((longInt >> 8) & 0XFF);
byteArray[3] = (int)((longInt & 0XFF));


So what's happening in the above code? We're basically using a combination of bit shifting and bit masking in order to chop up the unsigned long into 4 pieces. Each of these pieces ends up being a value small enough to be stored in the unsigned char array (remember an unsigned char is 1 byte, and capable of holding values 0-255).

The bit shifting "drops" the right-most bytes, and the bit masking serves to convert the "new" right-most byte into a hex value between 0-255.

Note that in the last line of code we didn't need to do any bit shifting; here we're converting the right-most byte of the unsigned long, and therefore don't want to throw it away.

An alternate solution would be to first apply the mask, and then shift:

byteArray[0] = (int)((longInt & 0xFF000000) >> 24 );
byteArray[1] = (int)((longInt & 0x00FF0000) >> 16 );
byteArray[2] = (int)((longInt & 0x0000FF00) >> 8 );
byteArray[3] = (int)((longInt & 0X000000FF));


Next, let's convert the 4-byte array back into an unsigned long int:


unsigned long int anotherLongInt;

anotherLongInt = ( (byteArray[0] << 24)
+ (byteArray[1] << 16)
+ (byteArray[2] << 8)
+ (byteArray[3] ) );


Here we're taking each piece of the byte array, but now shifting the bits to the left, and adding the results. In essence this is taking each value between 0-255 and depending on the position padding the right-side with an appropriate number of zeroes in order to replicate the significance of the individual values before they are summed.

And an alternate solution to accomplish the same:

anotherLongInt = ((unsigned int) byteArray[0]) << 24;
anotherLongInt |= ((unsigned int) byteArray[1]) << 16;
anotherLongInt |= ((unsigned int) byteArray[2]) << 8;
anotherLongInt |= ((unsigned int) byteArray[3]);


And that's it!

Note that additional fortifications are required when these operations are required in portable code. In that case you won't want to make assumptions on the size of the data types and should instead use additional logic to automatically detect the data type sizes at runtime for the platform on which you're running. Otherwise, the above should be fine if you have a homogeneous and controlled environment in which your code will run.

Tuesday, February 16, 2010

Use Cache_Lite without Pear

This post explains how to use Cache_Lite without using Pear.

Sometimes it may be impractical to install Pear packages on the server -- perhaps Pear isn't installed, perhaps you lack administrative rights, etc. Regardless, the steps below should assist you in using Cache_Lite under these circumstances.

  1. Download the 'manual installation' version of Cache_Lite.
  2. Extract this to some location on your local disk. Open a shell and navigate to this location; next we're going to adjust up the extracted files to better mimic the Pear installation.
  3. Rename the top-level directory from Cache_Lite-X.Y.Z to Cache.
  4. Optional -- you are free to remove the docs and test sub-directories if you wish; this will save on disk space.
  5. Now take the Cache directory and all its contents and place them in someplace accessible from your php include path; in my case I chose the quick and dirty approach and put it in $_SERVER['DOCUMENT_ROOT']/include:
  6. [user@localhost:/var/www/web/include/Cache]$ ls -A1
    LICENSE
    Lite
    Lite.php
    TODO

  7. Incorporate Cache_Lite into your PHP pages as described in the documentation, but with the changes listed below. These will insure that Cache_Lite functions adequately in the absence of Pear.

  8. require_once( 'include/Cache/Lite.php' );

    $cache_lifetime = 30; // in seconds
    $cache_id = '1234';
    $cache_options = array( 'cacheDir' => '/tmp/',
    'lifeTime' => $cache_lifetime,
    'pearErrorMode' => CACHE_LITE_ERROR_DIE
    );

    $Cache_Lite = new Cache_Lite( $cache_options );

    if( $data = $Cache_Lite->get( $cache_id ) )
    {
    // data is the JSON connection string
    $returnValue = $data;
    }
    else
    {
    // value is an array of database values (not shown)

    $data = json_encode( $value );

    // cache the JSON-encoded connection string
    $Cache_Lite->save( $data, $cache_id );

    $returnValue = $data;

    }

  9. Notice that we've set the options for Cache_Lite to not use Pear error mode; this line is important as it will otherwise attempt to use the Pear error handler, which can result in a failure to load since it will attempt to include PEAR.php.
  10. Also note the use of the caching mechanism; here we're caching a JSON string created from database entries. Successive loads of this page first check the cache validity, and if valid, returns the existing cached JSON string. If the cache is out of date, the system will then query the database, create the JSON string, then cache it before returning it back to the caller.

Wednesday, December 30, 2009

fence_vmware and the root user

When using the fence_vmware agent to manage a VMware guest via VMWare ESX, be aware that the root user cannot be used for the ssh session to the ESX node (the '-l' argument for fence_vmware). A separate user should be created on the ESX node for the purpose of allowing ssh access for the fence_vmware agent. (Note though that it is safe to use the root user for within the VMware Service console -- the '-L' argument for fence_vmware).

Though may possible to manually launch an ssh session to the ESX node from the command-line, the fence_vmware agent isn't able to do so due to programmatic restriction in the fencing framework. (The reason is that the fencing framework expects a particular format for the shell prompt following login, which the root user's shell does not use.)

One may argue that remotely logging in as the root user is not a good idea to begin with; as such the fencing framework may have been intentionally designed with this restriction in mind. However there may be cases where practicality prevails, such as when setting up a closed test environment.

I did not find this restriction documented anywhere, and only discovered it after debugging the python scripts contained in the fencing framework. It is briefly mentioned here that "ssh is not allowed for user root"; however this is misleading in that it does not explain that the limitation is within the fencing framework and not with ssh itself. (Those of you familiar with ssh server administration may be aware that there is an item in the ssh config file to allow/deny remote access to the root user.)

While on the subject, kudos to the people behind this VMWare fencing documentation. Though I make a small clarification to their work in the previous paragraph, this guide is quite helpful in explaining the methods by which to fence a VMware guest.

Friday, March 6, 2009

OSX Terminal colors

The OSX Terminal application can support font/highlighting colors when connecting to a remote system that supports this. However depending on your choice of Terminal's background color some of the colors can be difficult to read.

For example, I tend to prefer Terminal's "Pro" color scheme, where the background is black. But when I log into a linux box, some of the text colors are difficult to read against the black background.

I looked for a way to adjust the font colors used, but found a much simpler way to adjust this. Turns out there is an option in Terminal's Preferences titled "Use bright colors for bold text". This option can be found under Terminal -> Preferences -> Settings -> Text.

Enabling this option has yielded the text much easier to read.

Thursday, March 5, 2009

Real-time Navigation on OSX using Motorola i335 Cell Phone

This post explains real-time navigation using the GPS from a Motorola i335 cell phone with Google Earth a Mac OSX laptop. (Note: for the best experience, be sure to read up on using Google Earth in offline mode.)

There are some problems when allowing Google Earth to auto-detect the GPS for tracking. Basically Google Earth auto-probes the serial devices which it thinks might be a GPS; this is problematic in that it can sometimes select the wrong device. For example, in this case Google Earth is auto-selecting the BlueTooth dial-up adapter of my phone instead of using the USB serial connection. Since I have not found a way to force Google Earth to use a specific device, I came up with another method of getting the real-time GPS information into Google Earth.

IMPORTANT: Whatever you do, DON'T use the Google Earth GPS stuff (Tools->GPS); if you've already tried it, reboot your Mac before you proceed with this guide. As I mentioned above, Google Earth trips-up when trying to auto-detect the GPS, and creates a bunch of gpsbabel processes that cannot be killed and which conflict with the steps I provide below.

Connect Motorola i335 phone via usb cable.

Look for the device on the OSX the filesystem:
ls /dev/tty.*

Mine shows up as /dev/tty.usbmodem3d11
(Yes, this is the same serial interface as for the modem. I don't yet know if they are mutually exclusive, meaning either GPS or modem.)

On Moto phone, navigate to the GPS menu. Select Interface. Select NMEA Out, and set to ON. (Important: be sure to set NMEA Out back to 'Off' when you are done; else this will continue to run and considerably impact the phone's battery charge after unplugging the USB cable.)

After switching NMEA Out to "On", you should see a new icon on the phone that represents the GPS running. If you don't see the icon, something might not be functioning properly (see my troubleshooting section below).

Launch GPS babel; Google Earth already includes a version of it, so we'll use it rather than downloading another copy.

In a Terminal window enter:

cd /Applications/Google\ Earth.app/Contents/MacOS/
./gpsbabel -T -i nmea -f /dev/tty.usbmodem3d11 -o kml,points=0,line_color=640000ff,max_position_points=10 -F /tmp/nmea.kml


This continuously reads the real-time NMEA coordinates from the Motorola i335 and writes them to a file in the KML format that Google Earth uses.


Now launch Google Earth. We'll need to create a Network Link by which to get Google Earth to read the coordinates that the i335/gpsbabel are putting out.

From the menu bar, Click Add -> Network Link.
In the Name field, enter Motorola i335 GPS
In the Link field, enter /tmp/nmea.kml
Click on the Refresh tab. Change Time-Based Refresh from Once to Periodically. Check Fly to View on Refresh
Click OK.

Now on the left-hand side of the Google Earth in the Places window you should see a folder titled "Motorola i335 GPS", and under that folder you'll see either "ESTIMATED Position" or "Position", depending on whether or not the GPS has locked onto your coordinates. Make sure that the "Motorola i335 GPS" and "Position" folders have check marks in their boxes; this is needed in order for Google Earth to use the GPS data.

Once the coordinates are found, Google Earth should pan and zoom to your location.

If you've made it this far, congratulations and have fun. I encourage you to read up on using Google Earth in offline mode for the best experience with this setup.

Troubleshooting:

  • Motorola phone not putting out coordinates (is USB connected? NMEA out enabled? Can phone acquire GPS information?)
  • GPSbabel not properly reading from Motorola GPS (are command line options correct?)
  • GPSbabel not properly writing kml (are command line options correct?)
  • Google Earth is not reading the proper kml file (are the file paths correct?)


If you don't see the GPS icon on the phone after enabling NMEA Out, you might want to disconnect the phone and power cycle it, as well as rebooting the Mac and starting this guide again from the beginning.


Don't know if this is possible yet with BlueTooth; there is a serial device that appears under the BT profile, though I haven't spent the time to see if it can output the GPS NMEA information. An additional reason for using the USB cord is that the NMEA out will eat up the battery much faster than when set to off, and when using the USB cord you're effectively using USB power instead of the phone's battery.

DISCLAIMER: Be smart when using this while operating a vehicle. Don't be distracted; if you need to reference the map or use the computer in any way, pull over or have a passenger do it. I'm not responsible for any mishaps.

Cites: Thanks to these guys for the ideas behind this solution, who did something similar on Linux.

Wednesday, September 17, 2008

Launching OSX apps from the command-line

Use the following to open apps from the command line in osX:

open /path/to/your.app

Mac OS X wget alternative

WGet is not a native part of OSX; try curl instead.

Wednesday, May 21, 2008

Configuring MySQL for Network access

The typical default install of MySQL server only permits connections from localhost (127.0.0.1); this is presumably for reasons of security. While this is certainly secure, in some cases it is undesirable. This post explains how to permit network access to a MySQL server from remote clients.

Locate the my.cnf file, which is the master configuration file for MySQL server. (On a Ubuntu system this file may be located in /etc/mysql.)

Open this file in your favorite editor and look for the following entry:

bind-address = 127.0.0.1


This limits the MySQL server to listening to connections on the localhost address, as explained earlier.

To instead make the MySQL server listen on all interfaces, edit this entry to the following:

bind-address = 0.0.0.0


Save the file, then restart the MySQL server:

sudo /etc/init.d/mysql restart


Your MySQL server should now be network accessible. To verify that it's listening on all interfaces, issue the following command:

netstat -anp | grep 3306


If you see the following, then your configuration is complete:

tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN     -


You'll want to be certain your database users are permitted to connect via the network. This I'll leave to you to work out, though I will recommend the MySQL Admin tool.

(Conversely this tool can also be used to enable networking of MySQL, though this setting is somewhat buried within the myriad of options, and is more easily accomplished via the method described above.)

Tuesday, May 20, 2008

Macros and Variable Arguments in VisualStudio 2003

The preprocessor in Microsoft VisualStudio 2003 (VC++ 7.1) does not support variable argument lists in macros; instead it spews syntax errors when compiling. However, there is a way to get around this limitation and indeed gain this ability.

In a project I'm working on, we use macros to construct portions of our logging system. A typical declaration looks as such:

#define LOG_TRACE(...) log_routine(__FILE__, __LINE__, __VA_ARGS__)

However this fails to compile on VisualStudio.Net 2003, because as stated before, its preprocessor does not support variable argument lists.

A workaround is to instead use a class to handle the semantics of the variable argument list; observe:

class tracing_output_va
{
private:
const char* m_file;
int m_line;

public:
tracing_output_va(
const char* p_File,
const int p_Line) :
m_file( p_File ),
m_line( p_Line )
{

}

void operator()( const char* p_Format, ... )
{
va_list marker ;
va_start( marker, p_Format ) ;
LoggingOutVa(
m_file,
m_line,
p_Format,
marker ) ;

va_end( marker );

}
};


And then redefine the macro as such:

#define LOG_TRACE_APPLIB (tracing_output_va(__FILE__, __LINE__) )

This will indeed compile and perform as expected in VC++ 7.1

The elegance to this solution is that one need only modify the declaration of this macro, and that existing calls to this macro need not change.

For what it's worth the routine LoggingOutVa( ) wraps the actual magic of formatting and file output.


Cite: http://www.codeproject.com/KB/debug/location_trace.aspx

Thursday, May 15, 2008

VMWare Fusion -- No Hard Links in Shared Folders

VMWare Fusion allows one to use folders on the OSX filesystem from within the guest OS via Shared Folders.

This is useful if you need to access files from both the host OS (OSX) or the guest OS running in VMWare Fusion.

However I have found limitations with this arrangement when the guest OS is a Linux-based system -- it seems that VMWare's driver for Shared Folders does not support all of the linux filesystem operations (most specifically hard links).

Observe (/mnt/hgfs/wa points to a shared folder residing on the OSX filesystem) :


clermontr@synergy:/mnt/hgfs/wa/test$ touch tree
clermontr@synergy:/mnt/hgfs/wa/test$ ln tree shrub
ln: creating hard link `shrub' to `tree': Operation not permitted


Operation not permitted?! How about symbolic links:

clermontr@synergy:/mnt/hgfs/wa/test$ ln -s tree shrub
clermontr@synergy:/mnt/hgfs/wa/test$ ll
total 1
lrwxr-xr-x 1 clermontr ccm_root 4 2008-05-15 14:17 shrub -> tree
-rw-r--r-- 1 clermontr ccm_root 0 2008-05-15 14:16 tree
clermontr@synergy:/mnt/hgfs/wa/test$


Well it looks like symbolic links are permitted, but no chance for hard links. For what it's worth I also attempted to hard-link as sudo but to no avail.

Switching to the OSX filesystem I was able to create hard-links without issue. So then it would appear that this is indeed a limitation of the VMWare Fusion Shared Folders driver (vmhgfs).

I am interested in hearing if others have experienced this issue, and also if anyone has found a workaround.

Friday, March 14, 2008

Compiling MySQL 5 in Ubuntu

If when compiling MySQL5 you get an error similar to the following:

sed: can't read y.tab.c: No such file or directory
make[2]: *** [sql_yacc.cc] Error 2

Then you're probably missing the bison package.

To remedy, first install bison:

sudo apt-get install bison

Then start the mysql build again with a fresh start:

make distclean; ./configure; make

Your troubles should be over.

Tuesday, January 29, 2008

Using a Ubuntu VNC client to connect to a Leopard Remote Desktop

This post explains how to connect to a Leopard Remote Desktop session from a Ubuntu client machine using VNC. It is assumed that Remote Desktop is enabled on their Mac (you should also read this regarding a password on your Leopard Remote Desktop server).

The Leopard Remote Desktop speaks a flavor of vnc, albeit one which common vnc clients seem to have difficulty with. I tried both Ubuntu's default vnc client in addition to a realVNC client, both without success. However I did find that the tightvncviewer successfully connects.

To get xtightvncviewer, install this package:

sudo apt-get install xtightvncviewer


When you want to initiate a Leopard Remote Desktop session, open a terminal and start up xtightvncviewer:

xtightvncviewer ip.of.your.mac


You should be prompted with your password (you did set a password on your Leopard Remote Desktop, correct?), and following that you should then see the desktop of your Mac in the vnc window.

Friday, January 11, 2008

Quicktime video in Firefox on Ubuntu

Quicktime doesn't seem to work by default in Firefox on Ubuntu.

To get it working, you'll need to check/install plugins which Firefox uses to play video.

First, remove any other firefox plugins related to video; on my system these included:

sudo apt-get remove mozilla-mplayer
sudo apt-get remove mozilla-plugin-vlc
(I had previously installed these in attempts to get Quicktime working.)

Next install an additional plugin for gstreamer:

sudo apt-get install gstreamer0.10-gl


Now point your browser to some quicktime content (http://www.apple.com/trailers/) and enjoy.

Note: I was previously using the mozilla-mplayer package with some success, though Firefox would periodically crash for some unknown reason when viewing Quicktime content .

Tuesday, October 30, 2007

Panasonic Fn Keys in Ubuntu

I lost the functionality of the Fn keys to control brightness and volume after upgrading my Panasonic Toughbook Cf-74 from Ubuntu 7.04 Feisty to 7.10 Gutsy. Turns out that for whatever reason the kernel module which controls the Fn keys is not loading automatically.

To get it working, type the following into a terminal:

sudo modprobe pcc_acpi

That will load the Panasonic acpi driver. And that's it -- your Fn keys should now be working.

To insure that this module loads automatically at next boot, add the above command to /etc/rc.local

Monday, September 17, 2007

Encode MP3s in Ubuntu

The default Ubuntu install includes an application called Sound Juicer for use in encoding cd audio. However by default Sound Juicer cannot encode in MP3 format; this post explains how (at least for Feisty).

First, install this package:

gstreamer0.10-plugins-ugly-multiverse

If this package is not found, be sure you have enabled the Multiverse and Restricted software repositories and try again.

Next, after installing the above package, launch Sound Juicer. Click Edit -> Preferences. Next, click on the Edit Profiles button.

Click New. A new window will appear. (Note that on my system none of the fields in this new window can be edited until the Edit Profiles window is closed. So if this is the case for you go back to the Edit Profiles window and click Close.)

Add this text to the following fields:

Profile name: MP3
Profile desc: Encode to mp3 format.
GStreamer pipeline: audio/x-raw-int,rate=44100,channels=2 ! lame name=enc mode=0 vbr=0 bitrate=256 ! id3v2mux
File extension: mp3



This will encode audio files to mp3 format at a constant bitrate of 256; change this number to what suits your needs.

Next, check the Active button, then click Close.

Now back in the Preferences window you should see the MP3 profile in the Output Format dropdown.

Happy encoding.

Sunday, September 16, 2007

Video Resolutions under Ubuntu Remote Desktop

This post explains how to increase/expand the desktop size to match the working resolution of the remote client even if this resolution is higher than that of the server's video hardware.

The setup is Ubuntu Feisty 7.04 with Gnome Remote Desktop enabled, running on a Panasonic Toughbook (max LCD resolution of 1024x768), accessed by a desktop system operating at a resolution of 1280x1024. (UPDATE: this worked for me with xserver-xorg-core-1.2; this no longer works for me after upgrading to xserver-xorg-core-1.3.)

(FYI: The default Remote Desktop software in Ubuntu 7.04 is Vino, which is running with the xrandr extension. Remote Desktop is enabled via System -> Preferences -> Remote Desktop.)

X Windows has provisions for allowing desktop resolutions beyond which the server's hardware can support. These resolutions are called Virtual Resolutions, as rather than they being true hardware resolutions are instead represented in a simulated sense within the software.

On the Remote Desktop server, edit the xorg.conf file and locate the Display subsection matching that which the Defaultdepth is set to. Add the following line after Modes:


Virtual 1280 1024

Where the numbers represent the resolution which you want to use when connecting via Remote Desktop. (Note the absence of an 'x' between the numbers, this is intentional; adding an 'x' will result in the failure of X-Windows to launch.)


This section should now read something similar to the following:

SubSection "Display"
Depth 24
Modes "1024x768" "800x600" "640x480"
Virtual 1280 1024
EndSubSection


Restart X Windows. Check for the new virtual resolution in the list at System -> Preferences -> Screen Resolution. Select the new virtual resolution; the desktop will now be larger than the monitor can display, though the entire desktop can be panned by moving the mouse in the appropriate direction.

Next connect to the Remote Desktop server. The resulting display on the client should be the entire desktop shown at the full virtual resolution. (Note that the screen resolution of the server can also be updated from within the Remote Desktop session.)

My main development system is the laptop described above. I mainly use it in a docked configuration, though I also take advantage of the portability and work offsite. Lacking a dock at home, I instead use Remote Desktop to connect to the laptop. The above solution allows me to run the Remote Desktop session to take advantage of the full resolution of my desktop computer and not be limited to that of the laptop's video hardware.

Wednesday, February 28, 2007

Installing Parallels 2.2 on Ubuntu 6.10 (Edgy)

Installing Parallels Workstation on Ubuntu can be a bit of a challenge. There are a few minor (yet fatal) issues encountered whether using the Debian package or the install script which prevent Parallels Workstation from running. This article shall explain how to overcome these issues.

Overview
The biggest challenge between Parallels Workstation & Ubuntu is /bin/sh . If you open a shell in Ubuntu and type 'll /bin/sh' you'll see the following:

lrwxrwxrwx 1 root root 4 2007-01-29 10:19 /bin/sh -> dash
What this means is that sh is a symbolic link to dash. What's dash? Its a replacement shell for bash (a popular shell environment) which includes various enhancements over bash. However the scripts packaged with Parallels have compatibility issues with dash, and as a result encounter errors which prevent Parallels from running.

So to sort out this mess we'll make some minor edits to a few of the Parallels script files which will allow Parallels to successfully run.


Dependencies
In addition to the script issues discussed above, there are undocumented package dependencies. These dependencies are due to the manner in which Parallels configures its kernel modules -- running the command parallels-config essentially builds these modules specific to your environment.

So to complete the software build environment in preparation for building the Parallels Workstation kernel modules, these packages should be installed on your system:

sudo apt-get install build-essential
sudo apt-get install kernel-package

Install these before installing Parallels Workstation.

(Note that you are free to install Parallels Workstation first if you wish; however Parallels does not run a dependency check and will not alert you if these packages are missing. The first clue that you will see is that parallels-config will fail to build the modules due to missing header files. So it is simply best to just install these dependencies beforehand.)

Installation

For clarity, we shall assume installation using the Parallels Debian package. However the principles described here remain the same for those using the Parallels install script.

First step is to obtain and install the Parallels Workstation Debian package. This can be found on the Downloads page of the Parallels website.

If the package installed successfully, you likely received a message indicating that parallels-config must be run prior to running parallels. Don't do it just yet, as some changes must be made beforehand.

Exercise your sudo powers and edit these Parallels scripts:
/usr/bin/parallels-config
/usr/lib/parallels/autostart/drivers_start
/usr/lib/parallels/autostart/drivers_stop
/usr/lib/parallels/autostart/iscripts
/usr/lib/parallels/autostart/parallels
/usr/lib/parallels/tools/mimelink
/usr/lib/parallels/tools/network.sh

In each of these files, do a search & replace for all instances of /bin/sh replacing it with /bin/bash. (Keep in mind there may be multiple instances of /bin/sh in each file.)

Once the above files have been updated and saved, launch the parallels-config command:
sudo parallels-config
This should successfully build the kernel modules. If it doesn't complete successfully, double-check that you captured every step above.

Otherwise if parallels-config successfully completes, launch Parallels Workstation and enjoy.

Modifying the GLSlideshow Screensaver settings in Ubuntu

UPDATE: This has been verified to work for 7.10 (Gutsy) as well as 7.04 (Feisty).

For whatever reason in Ubuntu the GLSlideshow screensaver settings are not accessible through the screensaver control panel. We're talking the basics here, like changing the filesystem path to the pictures to display, displaying more than one image (in true slideshow fashion), the duration to display a picture for, etc. So then how does one adjust these properties? This post answers that question.

GLSlideshow gets its settings from two files. The first is .xscreensaver, and the second is glslideshow.desktop. We'll tackle these one at a time.

Starting with .xscreensaver, this file should exist in your home directory; if it doesn't already exist go ahead and create it there. Add the following line to .xscreensaver, where the path represents the folder containing the images you wish to display (adjust the path appropriately for your environment):

imageDirectory: /home/username/Photos

Save this file and close it.

Next modify the settings in glslideshow.desktop to get GLSlideshow to perform as we would like. In Ubuntu this file is typically found here:
/usr/share/applications/screensavers/glslideshow.desktop

If this path isn't appropriate for your system, issue this command to locate this file:
slocate glslideshow.desktop

Edit gslideshow.desktop and look for the following entry:
Exec=glslideshow -root

Modify this line to instead read:
Exec=glslideshow -root -duration 15 -pan 15 -fade 5

Where:
  • duration represents the amount of time (in seconds) to display an image for
  • pan represents the amount of time (in seconds) to run the pan effect on this image
  • fade represents the transition time (in seconds) to fade between images
You are free to add additional options if you wish; see the manpage for glslideshow for more options.

Save this file, then activate the screensaver. GLSlideshow should now present a slideshow of images from the specified directory.

Cites
http://ubuntuforums.org/archive/index.php/t-212512.html