S h o r t S t o r i e s

// Tales from software development

Archive for April 2009

Ubuntu 9.04 and cloud computing

leave a comment »

Ubuntu 9.04 was released earlier today. Browsing the list of new features this paragraph struck me as potentially very significant:

Ubuntu 9.04 Server Edition makes it easy to experiment with cloud computing. Eucalyptus, an open source technology which is included in Ubuntu as a technology preview, enables you to use your own servers to deploy, experiment and test your own private cloud that matches the Amazon EC2 API. You can dynamically create virtual machines, configure multiple clusters into a single Cloud and even provide an EBS (elastic block storage) equivalent and an S3 compatible storage manager.

Written by Sea Monkey

April 23, 2009 at 9:06 pm

Posted in Environments

Tagged with

How long has my computer been idle ?

leave a comment »

I have a few applications that periodically perform disk intensive tasks. For example, one checks for new or changed files in the folders that I normally backup. If the number of new or changed files, or the total size of these files, exceeds a threshold then the application starts nagging me to run a backup.

These tasks run with a very low thread priority and any performance impact is usually unnoticable. Nevertheless, it’d be nice to change these tasks so that they run when the computer is not being used. I looked through the .NET framework for methods that might help me determine the current level of activity on the computer but didn’t find anything paritcularly relevant.

Using this code I can now change my tasks to check if the computer is being used before they perform their disk intensive processing.

Then I stumbled across the GetLastInfo function in the Win32 API. This obscure function returns a single value that represents the time that the user last interacted with the computer using the keyboard or mouse. The value is expressed in ticks. This is the number of milliseconds that the Windows has been running since it was started. The .NET Framework Environment class has a static property called TickCount() that returns the current tick value. So, subtracting the value returned by GetLastInfo() from Environment.TickCount gives the number of millseconds since the user last interacted with the computer. For example:

namespace IdleTime
{
    using System;
    using System.Runtime.InteropServices;  

    public static class IdleTime
    {
        [DllImport("user32.dll")]
        private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii);

        private struct LASTINPUTINFO
        {
            public uint cbSize;
            public uint dwTime;
        }
 
        public static int Get()
        {
            int idleSeconds = 0;
 
            LASTINPUTINFO LastInputInfo = new LASTINPUTINFO();
            LastInputInfo.cbSize = (uint)Marshal.SizeOf(LastInputInfo);
            LastInputInfo.dwTime = 0;
            
            // If we have a value from the function
            if (GetLastInputInfo(ref LastInputInfo))
            {
                // Get the number of ticks at the point when the last activity was seen
                int lastInputTicks = (int)LastInputInfo.dwTime;
 
                // Number of idle ticks = system uptime ticks - number of ticks at last input
                idleSeconds = (Environment.TickCount - lastInputTicks) / 1000;
            }

            return idleSeconds;
        }
    }
}

Using this code I can now change my tasks to check if the computer is being used before they perform their disk intensive processing.

Written by Sea Monkey

April 23, 2009 at 8:00 pm

Posted in Development

Tagged with

CompuServe Classic R.I.P.

leave a comment »

An email from member services landed in my CompuServe classic mail account yesterday:

Dear member,

After many years of service we regret to advise that as of 30 June 2009
CompuServe can no longer offer the internet access we provided to your
address. Subsequently, your CompuServe account will be
closed June 30th 2009.

I signed up with CompuServe in 1994 and although I haven’t used it for the online content for the past six or seven years I still use the email account. The ‘classic’ users such as myself have probably been an inconvenience ever since AOL bought CompuServe but we were still paying a few dollars a month that you’d have thought allowed the service to pay for itself.

CompuServe first offered an online service to personal computer users in 1979. It’s a pity that the 30th anniversary is its death knell rather than a celebration.

Written by Sea Monkey

April 17, 2009 at 2:00 pm

Posted in Comment

Tagged with

Running Ubuntu 8.10 headless

leave a comment »

As mentioned in previous posts, I’ve had no end of problems getting SqueezeCenter to stream reliably when running under Windows 2003 Server on a Tranquil T7. I did what I said I was going to do – buy another T7 and install Ubuntu 8.10 Desktop and use this as my SqueezeCenter host.

I’ve run Linux on some of my machines in the past and done some professional development work on AIX based machines but I’ve generally stuck with Windows both professionally and personally. So, it was a bit of a surprise to see just how good Ubuntu 8.10 Desktop is. It is very impressive and performs flawlessly as a SqueezeCenter host.

Once I’d installed and configured SqueezeCenter and copied over all my FLAC files I pulled out the keyboard and mouse USB connectors and the VGA monitor cable. I used RealVNC to control the PC remotely but the first reboot appeared to fail. I plugged the monitor back in and saw this:

Ubuntu is running in low-graphic mode.
The following error was encountered.
You may need to update your configuration to solve this.
(EE) No devices detected

After a bit of googling it appeared that the issue is that Ubuntu’s display manager is querying the hardware to determine which graphics driver to use. This fails when a monitor isn’t attached. The easiest solution for me was to change the xorg.conf file to specify that the VESA driver is used as this doesn’t require a monitor to be attached to work:

1. Open a terminal window (from the menu: Applications | Accessories | Terminal)

2. To edit a system file you’ll need administrator priviliges so use sudo to run an editor such as gedit:

sudo gedit /etc/X11/xorg.conf

3. The default xorg.conf will look something like this:

Section "Device"
	Identifier "Configured Video Device"
EndSection

Section "Monitor"
	Identifier "Configured Monitor"
EndSection

Section "Screen"
	Identifier "Default Screen"
	Monitor "Configured Monitor"
	Device "Configured Video Device"
EndSection

Just add this under the Identifier line in the Device section:

	Driver "vesa"

so that the section looks like this:

Section "Device"
	Identifier "Configured Video Device"
	Driver "vesa"
EndSection

You’ll now be able to run Ubuntu headless.

 

 

Written by Sea Monkey

April 16, 2009 at 8:00 pm

Why do I get a 'disk full' error copying a large file to my USB hard drive ?

leave a comment »

I was at a client site. They had a VM image that they wanted me to take away and do some work on. I wasn’t prepared for this and didn’t have an external disk drive with me.

Then I remembered I had my 60gb iPod in my coat pocket. And, luckily I had a spare iPod-USB cable in my rucksack.

I connected the iPod to the PC with the ZIP file containing the VM files and tried to copy it to the iPod. After 30 seconds of thinking about it Windows Explorer threw up an error message: 

This was crazy – there was over 30gb free on the drive and I was only trying to copy a 4.5gb file.

It took a few minutes of frantic Googling to realise what the problem was. Despite the text of the error message, it was nothing to do with the amount of space on the iPod. The problem was that the iPod was formatted as FAT32 which has a 4gb maximum file size limit. I’ll avoid drawing comparisons with Bill’s apocryphal “640K is enough for anyone” comment (oops, too late).

The only practical solution was to use WinZip’s Split action to save the ZIP file as a set of smaller (than 4gb) files.

Written by Sea Monkey

April 14, 2009 at 8:00 pm

Posted in Debugging, Hardware

Tagged with ,

Reading FLAC files

leave a comment »

I’ve just finished writing a small appplication to read the tags in a FLAC file. The numeric values in the various FLAC blocks are generally big endian which required me to implement methods to do this as Windows and .NET use little endian values.

The exception is the VORBISCOMMENT block where the tags are stored. This uses big endian values and I used the various ReadXXXX() methods of the BinaryReader class to process the data in this block. Each tag is stored as a 32 integer indicating the length of the tag string and the tag string itself as a sequence of characters. 

My initial tests showed that my implementation appeared to be correct and bug free but when I ran the application against several hundred FLAC files it failed on one of them. When I debugged the failure I found that a ReadInt32() method appeared to be returning the wrong value.

I noticed that the 32 bit integer value in the file was not word or half-word aligned and my initial suspicion was that the ReadInt32() method was expecting an aligned value. So, I implemented my own method based on the method that I’d written to read a little endian 32 bit integer value. This simply reads four bytes from the file stream and then multiplies and adds the individual bytes as required to give the 32 bit integer value. When I ran a test against the problem file the result was the same – something else was causing the failure.

The exception was occuring on the second tag in the block but the problem appeared to be in the way that my application was handling the first tag.

What was odd was the two lines of code that read the length of a tag and then the tag string itself just didn’t seem to be working as expected on the first tag. When the string was read it appeared to be one byte longer than the string data in the file stream. This didn’t make any sense because the string was being read using the BinaryReader’s ReadChars() method with the length passed in as the number of characters to read. So why wasn’t it reading the correct number of characters ?

I should have seen it sooner… I noticed that the first tag string had a non-ASCII character in it. When I looked carefully at the data for the tag value I realised that this character was represented by a double byte character sequence. Hmmm… So does the length value indicate the number of characters in the string or the number of bytes required to store the string ?

It turned out to be the latter – the tag length value indicates the number of bytes used to store the string not the number of characters in the string. So, when I called ReadChars() using the length, it read one character too many and moved the current position in the filestream one byte further than it should have. When I called ReadInt32() to get the next tag string length instead of reading x’35 00 00 00′ as the length (53 bytes), it read the three bytes of zeros and the first byte of the string: x’00 00 00 54′. This gives a length of 1409286144. Calling the ReadChars() method with this value understandably results in:

An unhandled exception of type 'System.OutOfMemoryException' occurred in mscorlib.dll

There are probably more sophisticated ways of handling this but my quick solution was to override ReadChars() as:

        public override char[] ReadChars(int count)
        {
            byte[] bytes = this.ReadBytes(count);
            return Encoding.UTF8.GetString(bytes).ToCharArray();
        }

This ensures that the number of bytes, not characters, specified in the tag field length descriptor is read and then rendered as a UNICODE character sequence.

Since then I’ve realised that this isn’t a good idea as it confuses exactly what the ReadChars() method should do. The name sounds like it’s reading chars but I’m passing in the number of bytes to read not chars. A better solution would be to implement this as a new method named something like ReadCharBytes().

Written by Sea Monkey

April 9, 2009 at 1:00 pm

Posted in Debugging, Development

Tagged with ,