Custom Linux Shutdown Scripts

Everyone knows one of the beauties of Linux (and FOSS in general) is the ability to delve in and change functionality for your own requirements. I was having an issue where a standard “poweroff” or “halt” was not shutting the computer down properly, so I needed to write my own scripts to replace them.

On Ubuntu /sbin/poweroff and /sbin/halt are symlinks to /sbin/reboot which is a binary (on debian reboot and poweroff symlink to halt), but the binary is aware of which command is being called, and acts accordingly. This means if you replace one of the symlinks with a script which in turn calls the binary, it will not necessarily perform the action you want (i.e. it will reboot rather than halt or poweroff).

On Ubuntu I solved this problem by creating a /sbin/local directory, copying the binary into there and creating local symlinks.

mkdir /sbin/local
cp /sbin/reboot /sbin/local/reboot
ln -s reboot /sbin/local/poweroff
ln -s reboot /sbin/local/halt

I was then free to replace the /sbin/poweroff, /sbin/halt and /sbin/reboot scripts with my own custom scripts, which were able to call the scripts in /sbin/local and would execute those correctly.

Installation of Memcache in PHP on Ubuntu/Debian

Happy new year all! Just a quick post about how to install Memcache in PHP on an Ubuntu or Debian server (I think it will apply to Redhat based servers, just substitute the apt-get for yum).

Log on to your server as root (either directly or using sudo su), then install the Memcache daemon through apt:

apt-get install memcached

Once installed you need to install the Memcache module into PHP. This is done through PECL which in turn is installed through PEAR. When they are both installed, you need to run the command:

pecl install memcache

This will install the memcache extension, and once done will tell you to add the the line “extension=memcache.so” into your php.ini file. I prefer keeping these in separate files (so that the php.ini file can be updated). The easy way to do this is:

echo "extension=memcache.so" > /etc/php5/conf.d/memcache.ini

And finally, reload Apache

/etc/init.d/apache2 reload

If successful, Memcache will now appear in your phpinfo().

Virtual Hosts for Development with Apache on Ubuntu

I do a lot of development on Ubuntu, as I often have multiple projects on the go which are nothing to do with each other, it’s often easier to create separate virtual hosts on my local development machine. This means that when they are ready for the “real world”, they are already set up as isolated sites at the root of their domain (rather than in a subdirectory of an existing site).

In order to do this, you need to create a new virtual host in your Apache config. Create a new file in the directory /etc/apache2/sites-available and open it in your favourite editor. It doesn’t matter what the file is called, but it’s best to keep it descriptive. We’ll call this project “mysite”, so the file can be called “mysite”. In the file we need to configure the Apache virtual host.

<VirtualHost 127.0.0.1>
ServerName mysite.localhost
DocumentRoot /var/www/mysite/public/
</VirtualHost>

In the VirtualHost tag, you put the IP, seeing as I only want this for local loopback (for development) I have just put 127.0.0.1. The ServerName is the URL that you use to connect to the site and the DocumentRoot is where the public documents are stored. This is a very basic set up, so there are many more options you can add.

To make the site enabled, you create a symbolic link to the file from the sites-enabled directory.

cd /etc/apache2/sites-enabled
ln -s ../sites-available/mysite mysite

You now need to add the subdomain (mysite.localhost) to the list of hosts, so open /etc/hosts in your favourite editor and append the line:

127.0.0.1 mysite.localhost

And then restart Apache:

sudo /etc/init.d/apache2 restart

Now you should be able to visit http://mysite.localhost on the local machine (assuming the directory does actually exist).

This should also be similar on MacOS and other linux Distros, but the file locations (particularly for Apache) will vary.

LTSP Part 2 – Configuration

In the previous post I had the problem:

… when I boot up, I get the Ubuntu boot screen, which shows it’s connecting to the terminal server, however it then fails with an errror saying

Error: Failed to connect to NBD server

And I get sent to a basic busybox shell.

There were two reasons for this.

PXE… booted

First of all, because I obtain the DHCP separately from the network boot, I need to treat it as if it’s a static IP. LTSP can handle static IPs, but this posed a couple of problems. I would need to specify a separate config file for each MAC address in the pxelinux.cfg/ directory. Secondly it would require each MAC address to be given the same IP each time (this was not going to happen).

So instead of getting gPXE to PXE boot, I completely bypass pxelinux.0 and use my own boot script. In this script I pass in the IP and other information. gPXE has some environment variables which can be used for this, so I wrote a script (The ‘x’s should be replaced by the terminal server’s IP address).

#!gpxe
dhcp net0
kernel tftp://xxx.xxx.xxx.xxx/ltsp/i386/vmlinuz ip=${ip}:xxx.xxx.xxx.xxx:${gateway}:${netmask}:${hostname}:eth0:none nbdroot=xxx.xxx.xxx.xxx:2000
initrd tftp://xxx.xxx.xxx.xxx/ltsp/i386/initrd.img
boot vmlinuz

This script retrieves the kernel, and passes as parameters the environment variables (which were set by the dhcp) the IP, gateway, netmask and hostname. Another parameter is the nbd server location and port. The we retrieve the initial ramdisk (initrd) and boot.

More haste less speed

After that was fixed, on my test machines it still didn’t connect to the NBD server. This is because my test machines are core2duo 3ghz with 4gb RAM; they were so fast at booting up, that it didn’t get a response from the NBD server in time. I diagnosed this by adding the parameter:

break=mount

To the kernel line in the script above. This stopped the boot, then it got a response from the server, and when I pressed ctrl+D (to continue the boot) it booted up fine. This is a bug in the ltsp_nbd script.

I solved this by logging into the terminal server and opening the file /opt/ltsp/i386/usr/share/initramfs-tools/scripts/ltsp_nbd, then added the line:

sleep 5

after the line:

ip link set lo up

This meant that the script paused for 5 seconds to allow the NBD server to respond.

Once edited the initramfs needs updating, as do the kernels:

chroot /opt/ltsp/i386 update-initramfs -u
ltsp-update-kernels

I will be writing a part 3 to this sometime soon talking about some of the customisations I will be adding.

LTSP Part 1 – gPXE

Disclaimer: This is a work in progress blog post. There may be better ways of doing things, and things may have been done wrong. Although I hope you will find this helpful, please don’t take the contents of this post as gospel.

At work we have Ubuntu terminal servers which the students currently connect to using NX on ThinStation in the labs. This is not an ideal setup, especially because the ThinStation kernel is too old to run on (even relatively) modern hardware. It is designed to setup an old computer as a thin client, and allow it to access a terminal server which will do all the hard work.

The other issue which we have is that the network is not owned or managed by my department (computer science), but by the central IT department of the university. This means I do not have access to the DHCP server which is required to PXE boot the computers. On top of this, the computers need to dual boot between the thin client/terminal server and a local installation of Windows.

This is where gPXE comes to the rescue! What gPXE allows me to do is retrieve an IP address from the university DHCP server, and then create my own network boot script completely separately.

Continue reading