Skip to content

Neues Spielzeug I

KartonsGestern habe ich in Karlsruhe mehrere Kartons abgeholt. Was sich daran befindet, wird allerdings erst in einigen Wochen verraten. :-)

Categories: IT

KVM and Graceful Shutdown on Ubuntu

For quite some time, I have been trying to figure out, how to gracefully shutdown the KVM-based virtual machines running on a Ubuntu 10.04 LTS (Lucid Lynx) host system. This problem consists of two parts: First you have to make the virtual machines support the shutdown event from libvirt and second you have to call the shutdown action for each virtual machine on system shutdown.

The first part is very easy for Linux VMs and also not too hard for Windows VMs. I described the necessary steps in my wiki

The seconds part is harder to accomplish: On Ubuntu 8.04 LTS (Hardy Heron) I just modified the /etc/init.d/libvirt-bin script to call a Python script in the stop action. This solution was not perfect, as it meant that the virtual machines were also shutdown, when libvirtd was just restarted, however it was a quick and easy solution.

For Ubuntu 10.04, the init script has been converted to an Upstart job. So the easiest way was to create a upstart job that is starting on the stopping libvirt-bin event. However, this did not solve the problem, because the system powered off or rebooted before the shutdown of the virtual machines was finished. As it turns out, Ubuntu 10.04 uses an odd combination of Upstart jobs and traditional init scripts. This leads to a situation, where /etc/init.d/halt or /etc/init.d/reboot are called, before all upstart jobs have stopped, when one of the upstart jobs needs a significant amount of time to stop. This can be solved by adding an init script, than runs before the halt or reboot scripts and waits for the respective Upstart job to finish. In fact, it is best to run this script before the sendsigs script to avoid processes started by one of the upstart jobs to receive a SIGKILL.

I added the complete scripts and configuration files needed for this feature to my wiki. In fact, this solution also ensures, that the virtual machines are only shutdown if libvirt is stopped because of a runlevel change. Thus, the libvirt-bin package can now be upgraded without resulting in a restart of the VMs.

For me, automatically shutting down the virtual machines is very important. The KVM hosts I manage are connected to an uninterruptible power supply with limited battery time. Although in the past years I remember only a single time, the host systems were shutdown because the battery was nearly empty (most power interrupts are very short), I want to make sure that all virtual machines are in a safe, consistent state, when the power finally goes off. So I hope that the scripts in the wiki are also helpful to other people, having the same problem.

Problems when Upgrading to GRUB 2

Yesterday, I upgraded the last systems, which where still running on GRUB Legacy (GRUB 1) to GRUB 2 (the grub-pc package on Ubuntu).

On one of the systems, I experienced the problem, that upgrade-from-grub-legacy could not install GRUB. When I tried to install GRUB manully using grub-install, I got a strange error message:

/usr/sbin/grub-setup: warn: Your embedding area is unusually small.  core.img won't fit in it..
/usr/sbin/grub-setup: warn: Embedding is not possible.  GRUB can only be installed in this setup by using blocklists.  However, blocklists are UNRELIABLE and its use is discouraged..
/usr/sbin/grub-setup: error: if you really want blocklists, use --force.

It took me some time to figure out, that this system had an unusual disk geometry, resulting in not enough space being available before the start of the first partition. The output of fdisk -lu /dev/sda looked like this:

Disk /dev/sda: 320.1 GB, 320071884800 bytes
64 heads, 32 sectors/track, 305244 cylinders, total 625140400 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x0009153c

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1              32      585727      292848   83  Linux
/dev/sda2          585728   625139711   312276992    5  Extended
/dev/sda5          585760   215429119   107421680   8e  Linux LVM
/dev/sda6       215429152   430272511   107421680   8e  Linux LVM
/dev/sda7       430272544   625139711    97433584   8e  Linux LVM

Usually, the first partition starts at sector 63 (for systems installed more recently, 2048 is also common), but for this system it started at sector 32. I guess that this was cause by the strange geometry, which did not specify the usual 255 heads and 63 sectors/track. I am not sure, whether the disks (two Western Digital 320 GB drives) really have this strange geometry, or the RAID-Controller, a 3ware Escalade 8006-2LP, reports a different geometry. However, for sure the first partition being to close to the start of the disk was the cause of the problem with GRUB.

Unfortunately, I could not move the partition using parted and gparted does not allow to specify the start and end of a partition in sectors, but only in MiB (and only supports aligning to MiB or cylinders, which did not help considering the odd geometry). Therefore I decided to delete the partition (after all it was only the boot partition and its content could easily be stored on the root partition) and create a new partition using fdisk.

In fact, when (re-)creating the partition, fdisk suggested to start the partition at sector 2048, which I accepted. No surprise, after that change GRUB could be installed to the MBR without any problems.

The good thing about this problem was, that the time I invested to get a high-availability setup running for most important services, finally paid of. I for sure would have been less relaxed, while figuring out and fixing the GRUB problem, when the services usually running on this machine would have been offline.

Speicherprobleme lösen mit Valgrind

Beim Versuch EDM auf einem openSUSE-11.2-System (x86_64) zum Laufen zu bekommen, traten in bestimmten Fällen immer wieder Speicherzugriffsfehler auf. Nun ist es so, dass ich wirklich kein Freund von RPM-basierten Distributionen im allgemeinen und SUSE im speziellen bin. Aber es wäre zu einfach gewesen dieses Problem auf die Distribution zu schieben. Eine Suche im EPICS-Mailinglisten-Archiv ergab dann auch relativ schnell, dass dieses Problem auch schon auf anderen 64-Bit-Systemen aufgetreten war.

Zunächst untersuchte ich das Problem also mit dem GDB. Damit konnte ich aber lediglich herausfinden, dass der Fehler beim "delete[]" eines Arrays auftrat. Mit etwas Debug-Code konnte ich schnell feststellen, dass es (trotz entsprechender Meldungen der glibc) kein Double-Free-Problem war, kam aber ansonsten nicht wirklich weiter.

Dann entdeckte ich das Werkzeug Valgrind. Valgrind wurde speziell entwickelt um Speicher-Probleme, wie Buffer-Overflows und Memory-Leaks, in C/C++-Programmen zu finden. Tatsächlich konnte ich damit sehr schnell herausfinden, dass ein Array über die Grenzen hinweg beschrieben wurde.

Die Ursache war dann auch schnell gefunden. Der Code, der den Speicher für den Array reserviert, hatte die Größe verschiedener Datentypen fest kodiert. Die Annahme, dass ein "long"-Wert 4 Bytes hat, ist allerdings nur auf 32-Bit-Systemen richtig. Auf 64-Bit-Systemen kann ein "long" 8 Bytes lang sein.Nachdem die festen Größen durch den "sizeof"-Operator ersetzt wurden, verschwand dann auch der Speicherzugriffsfehler.

Valgrind kann also ein wertvolles Werkzeug bei der Lösung von Speicherproblem in C- oder C++-Code sein, deren Ursache andernfalls nur schwer zu finden wäre.

Merkwürdige Probleme nach Ubuntu-Update

Nachdem ich auf einem Ubuntu 10.04 LTS (Lucid Lynx) System ein reguläres System-Update durchgeführt hatte, welches auch ein Update von libvirt enthielt, konnte ich merkwürdigerweise eine bestimmte VM nicht mehr starten.

Die ausgegebene Meldung

error: Failed to start domain mydomain
error: monitor socket did not show up.: Connection refused
war leider auch nicht besonders aussagekräftig. In den Logfiles fanden sich auch keine weiteren Informationen und libvirtd mit der Option "-v" zu starten brachte mich auch nicht weiter.

Nach viel herumprobieren stellte sich letztendlich heraus, dass die folgenden Zeilen in der Domain-Konfiguration für das Problem verantwortlich waren:

    <disk type='block' device='cdrom'>
      <source dev='/dev/cdrom'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>

Warum genau die gleiche Konfiguration vor dem Update noch funktioniert hat, kann ich auch nicht sagen. Da ich für die betroffene VM das CD-Laufwerk sowieso nicht benötige, habe ich die Zeilen einfach nur entfernt.

Squid 3.1 on Ubuntu 8.04 Hardy Heron

Squid 3.1 introduced support for IPv6, so there is a very good reason for an upgrade from Squid 3.0.

Unfortunately, there is no Ubuntu package for this version, not even in the upcoming Ubuntu release 10.04 Lucid Lynx.

For a while, I have been using the Debian experimental packages of Squid 3.1.0, compiled from source on Ubuntu 8.04. However, now a stable version of Squid 3.1 has been released, but there is no Debian package for Squid 3.1.1.

Therefore, I used the Debian package for Squid 3.1.0.14 as the base for building a package for Squid 3.1.1. I have published this package in source as well as built for Ubuntu 8.04 on amd64. There you can also find a package for libcap2, which is required by Squid 3.1 but not included in Ubuntu 8.04.

Of course, there is no kind of warranty for this packages, so use them at your own risk.

Spring IDE for Eclipse breaks JDT weaving

I experiences a problem, when trying to use Scala IDE for Eclipse and Spring IDE at the same time in Eclipse 3.5 Galileo on Mac OS X:

Scala IDE need JDT weaving support, however the JDT weaving seems to be broken by Spring IDE. If Spring IDE is installed and JDT Weaving is enabled, on startup the following problem occurrs:

[org.eclipse.equinox.weaving.hook] info adding AspectJ hooks ...
[org.eclipse.equinox.weaving.aspectj] info Starting AspectJ weaving service ...
21.03.2010 18:29:10 org.aspectj.weaver.tools.Jdk14Trace error
SCHWERWIEGEND: register definition failed
java.lang.ClassCastException: org.aspectj.weaver.loadtime.definition.Definition cannot be cast to org.aspectj.weaver.loadtime.definition.Definition
    at ...

This problem seems to be related to the fact that the com.springsource.org.aspectj.weaver_1.6.5.RELEASE.jar plugin brings a second class file for org.aspectj.weaver.loadtime.definition.Definition in addition to the class file already shipped with Eclipse. This probably cause the ClassCastException on startup.

By uninstalling the Spring IDE features, this problem can be resolved and JDT Weaving can be enabled.

Schneller Kundendienst

Am Samstag hatte ich auf einem Server, der bei Hetzner steht, ein Kernel-Update vorgenommen.

Nach dem obligatorischen Neustart konnte ich das System allerdings nicht mehr erreichen. Auch eine Untersuchung im Rettungssystem brachte keine neuen Erkenntnisse zu Tage. Insbesondere funktionierte auch ein Start mit der alten Kernel-Version nicht mehr.

Daher erstellte ich bei Hetzner ein Ticket mit der Bitte, mir eine Remote-Konsole zur Verfügung zu stellen. Tatsächlich erhielt ich nach rund 30 Minuten eine Antwort mit den Zugangsdaten für die Konsole.

Mit Hilfe der Konsole konnte ich schnell feststellen, dass GRUB erst gar nicht richtig gestartet wurde.

Dieses Problem ließ sich dann relativ schnell aus der GRUB-Shell mit Hilfe von

device (hd0) /dev/sda
root (hd0,1)
setup(hd0)
device (hd0) /dev/sdb
root (hd0,1)
setup(hd0)

lösen.

Ich möchte an dieser Stelle die schnelle Unterstützung von Hetzner hervorheben. Ohne die Remote-Konsole wäre ich wahrscheinlich nicht auf die Idee gekommen, dass GRUB im MBR beschädigt sein könnte.

Categories: IT

Sicherheit total

Ich komme momentan nicht wirklich zum Schreiben, deshalb heute nur ein Link auf einen interessanten Artikel in der Zeit.

Unter dem Titel "Sicherheit total" erklären Ilija Trojanow und Juli Zeh, warum uns auch noch so viel Überwachung keine Sicherheit bringen kann.

[via lawblog]

Wer im Glashaus sitzt...

Wie SPIEGEL ONLINE berichtet, hat Bundesfamilienministerin Ursula von der Leyen (CDU) die Bundesgesundheitsministerin Ulla Schmidt (SPD) wegen der Nutzung ihres Dienstwagens in Spanien angegriffen.

Ursula von der Leyen und Dienstwagen? Bei diesen Stichworten musste ich an einen Artikel des Stern vom Anfang dieses Jahres denken. Laut diesem Bericht pflegt Frau von der Leyen selbst eine fragwürdige Praxis bei der Nutzung ihres Dienstwagens. Tatsächlich wurde vom Familienministerium erst vor kurzem eine Veröffentlichung der Fahrenbücher abgelehnt.

Die Kritik an Ulla Schmidt ist dadurch nicht weniger berechtigt, aber wenn Ursula von der Leyen feststellt das Wichtigste sei "ein Gespür zu behalten für das, was in Ordnung ist" und von Frau Schmidt verlangt "Vorbild und Maßstab" zu sein, sollte sie auch selbst mit gutem Beispiel vorangehen und zurücktreten.

Damit könnte Frau von der Leyen tatsächlich Gespür für das, was in Ordnung ist, beweisen, aber die Familienministerin bezieht diese Forderung anscheinend nur auf ihre Kollegin im Kabinett und nicht auf sich selbst.

(Ähnliche Gedanken kann man auch in den stern blogs finden.)

Thunderbird with Exchange Server 2007

The university I am studying at recently migrated the mail system from Cyrus IMAP to Exchange Server 2007.

Unfortunately Mozilla Thunderbird does not work well with Exchange's IMAP server, unless you do some manual configuration:

First in order to make Thunderbird delete e-mails on the IMAP server correctly, you have to set the mail.imap.expunge_after_delete option to true (see KB article).

Besides, you want to set the mail.server.server#.trash_folder_name property to the name of the "deleted items" folder on the server (see KB article).

With this options changed, Thunderbird will interact with Exchange's IMAP server quite well.

Fighting SPAM Bounces with Exim (Part II)

In the previous article I described how you can reduce the number of bounce mails generated by your mail server. In this article, I will describe a method to automatically distinguish between legitimate and unsolicited bounce mails, thus reducing the number of bounce mails you receive.

Bounce mails should always be sent to the envelope sender (aka "return path") and the bounce mail itself should use an empty envelope sender (some misconfgured systems however use "postmaster@...").

As the user usually does not see the envelope sender, we can set it to anything different from the true sender's address. In fact we can append some kind of signature to the local part of the address, which proves that the mail has really been sent by our mail server. The spammer does not now this signature (which contains a timestamp), unless he has received a mail from us very recently, and therefore will use the normal address (which might have been collected from some webpage or whois information).

Then our mail server can just reject any bounce mails to an address with an invalid signature, because it is probably not a reaction to a mail from our server. This mechanism is called Bounce Address Tag Validation (BATV) and supported by newer Exim versions.

In the first section of our Exim configuration, we define a macro containing the secret signing key and the list of addresses, we want to enable BATV for:

PRVS_SECRET=VerySecretKeyThatYouHaveToChange
addresslist prvs_senders = an-address@example.com : another-address@example.com

If you want to enable BATV for all addresses, you could skip this step and enable BATV for a list of whole domains. However, usually only a few addresses are affected by spam bounces and enabling BATV only for them reduces the risk of breaking something.

Then you have to extend the acl_smtp_rcpt ACL with the following rules:

  deny    message     = This address does not send an unsigned return path
          senders     = : postmaster@*
          recipients  = +prvs_senders

  deny    message     = Invalid return path signature
          senders     = : postmaster@*
          condition   = ${prvscheck {$local_part@$domain}{PRVS_SECRET}{1}}
         !condition   = $prvscheck_result

The first rule will deny bounce mails (actually any mails with an empty envelope sender or postmaster@ in the envelope sender) which are targeted at a BATV enabled address and do not have a signature. The second rule checks any bounce mails that have a signature for the correctness of this signature.

In the next step we have to add a router that rewrites a BATV address to the original address:

prvs_redirect:
  driver = redirect
  data = ${prvscheck {$local_part@$domain}{PRVS_SECRET}}

This router should be placed following any remote but preceding any local routers.

Finally, we have to add the signing configuration to the SMTP transport:

remote_smtp:
  driver = smtp
  return_path = ${if match_address{$return_path}{+prvs_senders} \
{${prvs {$return_path}{PRVS_SECRET}}}{$return_path}}

This will cause the sender address to be signed, if it is listed in prvs_senders.

Since enabling this, I receive virtually no spam bounces any longer.