How to check filesystems in a qcow2 image

A useful post how to fsck (check and fix) a filesystem in a qcow2 image (as typically used for KVM VMs, e.g. in Proxmox):

How to recover a qcow2 file using fsck

On Proxmox or Debian, one does the following:

Attention:

  • Make sure the according VM isn’t running, i.e. the partition not mounted
  • Adjust the commands below to match your system, use the correct qcow2 image, use the correct fsck-variant, fsck the correct filesystem, note that -p tries to automatically fix errors!
# modprobe nbd max_part=8
# qemu-nbd --connect=/dev/nbd0 /var/lib/vz/images/100/vm-100-disk-1.qcow2
# fdisk -l /dev/ndb0
/dev/nbd0p1            2048     7813119     3905536   82  Linux swap / Solaris
/dev/nbd0p2   *     7813120   119537663    55862272   83  Linux
# fsck.ext4 /dev/nbd0p2
# fsck.ext4 -p /dev/nbd0p2
# qemu-nbd --disconnect /dev/nbd0

Like this, one doesn’t need to boot the VM using a boot ISO/CDROM and can fix the filesystem right from the host node.

 

zpool: Symbol `spa_feature_table’ has different size in shared object, consider re-linking

If you see the following error message when executing ‘zpool status’ after “upgrading” Proxmox to the (currently) latest version with ZoL 0.6.4 instead of 0.6.3:

zpool: Symbol `spa_feature_table' has different size in shared object, consider re-linking

Explanation:

“Re-linking” doesn’t have a special meaning in ZFS/ZoL terminology, it rather just describes the usual linking step after compiling some source code.

Solution:

The most likely cause is that some new, updated and required packages have not been installed (e.g. with ‘uname -a’, you’ll see that the old kernel is still running, even after rebooting). Usually, this happens if one executes “apt-get update && apt-get upgrade” (as usual) rather than “apt-get update && apt-get dist-upgrade“. So, in order to solve this problem, do:

# apt-get update && apt-get dist-upgrade
# reboot

In this case, ZoL 0.6.4 also includes a couple of new features which can be enabled for all local ZFS pools by executing:

# zpool upgrade -a
This system supports ZFS pool feature flags.

Enabled the following features on 'rpool':
 spacemap_histogram
 enabled_txg
 hole_birth
 extensible_dataset
 embedded_data
 bookmarks

Using IRC on the go

Running the console IRC client weechat (not to confuse with the wechat messenger) in a screen or tmux session on a Linux (or Mac OS X) server and accessing it trough mosh is a great way to use IRC on the go, i.e. with a unsteady Internet connection.

P.S. Thanks to Devaux and rmeyer for the hints

Delete duplicate e-mail messages

If you need to delete duplicate e-mail messages on an IMAP server, take a look at this useful IMAP de-duplicator script:

IMAP de-duplicator – IMAPdedup

As IMAPdedup is a command line interface tool (a python script), it’s particularly useful for:

  • automated deletion of duplicates (as it can be called from other scripts)
  • extraordinarily big mailboxes or if you have many subfolders (as there’s no intervention by the user required)
  • if you have console/shell access to the IMAP server (as you can then run the script on the server itself, speeding the de-duplication process further up)

I also found that it deals relatively well with failures (e.g. when a folder is read-only and hence messages can’t be deleted): It simply reports them on the screen and carries on.

Here’s a quick’n’dirty bash script to de-dup the inbox and all subfolders of the specified account:

#!/bin/sh
# Delete all duplicate messages in all folders of said account.
# Note that we connect through SSL (-x) to the default port.

SERVER="my.server.com"
USER="mylogin"
PASS="mypass"

for folder in `imapdedup.py -s $SERVER -x -u $USER -w $PASS -l`;
do
 imapdedup.py -s $SERVER -x -u $USER -w $PASS $folder
done

If you only have to de-duplicate messages in a small folder, you could also use the following de-duplication add-on for Mozilla Thunderbird:

Remove Duplicate Messages Add-on for Thunderbird

Note however that the ‘Remove Duplicate Messages’ add-on is intended for interactive use only, not for batch processing. I also noticed that it fails at cleaning big mail folders (e.g. containing 50’000 messages).

 

Moving Zimbra Collaboration Server to a new IP address

Here’s a quick overview how to migrate a ZCS mail server (based on Ubuntu) to a new IP address:

0) Not covered here: Adjusting DNS entries. Make sure you lower the TTLs of the relevant DNS entries a couple of days in advance in order to minimize downtime for clients (e.g. set a TTL of 300 for a 5 minute downtime).

1) Set the new IP address in:
* The relevant DNS entries
* /etc/network/interfaces
* /etc/hosts
* If ZCS runs in a container/VM, don’t forget to adjust its IP address too.

2) If the new IP address is part of a new subnet, make sure to add this new subnet to ZCS’s trusted_networks, otherwise, sending (relaying) messages through ZCS from Zimbra Desktop (or any other mail client) won’t work[1]. This can be set using ZCS’s web admin interface (i.e. https://mail.myserver.com:7071/zimbraAdmin/):
Navigate to “Server settings”, then open the “MTA” tab and set something analogous to the following in “MTA Trusted Networks”:
127.0.0.0/8 w.x.y.z/26

3) Restart networking and the ZCS services (it’s important, as this adjusts the trusted_network setting in ZCS’s amavisd too):
# /etc/init.d/zimbra stop
# /etc/init.d/networking restart
# /etc/init.d/zimbra start

Alternatively, just reboot the server, particularly if it runs in a VM.

Voilà!

Note: The need for the adjustments in step 2) might come as a surprise. Authenticated messages to be relayed through ZCS apparently seem to originate from the external IP address, not localhost/127.0.0.1.

[1] A typical postfix error message might look like:
Delivery Failure Notification: Invalid address: somebody . com.zimbra.cs.mailbox.MailSender$SafeSendFailedException: MESSAGE_NOT_DELIVERED; chained exception is: com.zimbra.cs.mailclient.smtp.InvalidRecipientException: RCPT failed: Invalid recipient somebody@somedomain.com: 554 5.7.1 : Relay access denied

Less is more: colordiff and more or less

In the Unix/Linux/Mac OS X world, less is more. Literally, in that ‘less‘ fully emulates ‘more‘, and figuratively, as it provides useful additional functionality like backwards scrolling. So, you really want to use ‘less’ instead of ‘more’ for paging another command’s output, e.g.

cat a_long_document.txt|less

When used to page the output of colordiff however, ‘less’ displays a mess instead of properly displaying colored output like ‘more’.
The trick is to use ‘less’ with either the -r or -R option (which both repaint the screen), i.e.

colordiff -u file_old.py file_new.py|less -r

or

colordiff -u file_old.py file_new.py|less -R

(try which one works better with your system and terminal)

Linux: Saving energy using auto-poweroff

I used to have a headless Linux LAN server that ran 24/7, i.e. even when I actually didn’t use it. Now, it powers itself off automatically as soon as it doesn’t detect any running workstations/notebooks (with dynamically assigned IP addresses) in the LAN.

Here’s how to do it:

In /usr/local/bin, create a new bash script named “shutdown_if_no_dhcp_client_in_lan” with the following content:

#!/bin/sh
# Shutdown the box if there aren't any (not ignored)
# DHCP clients in the LAN

# ignore the skype base station
ignored_macaddr="aa:bb:cc:dd:ee:ff"

# dhcp range starts at 192.168.1.$dhcpstart
dhcpstart=32

# dhcp range ends at 192.168.1.$dhcpend
dhcpend=46

for i in $(seq $dhcpstart 1 $dhcpend)
do
  # returns 0, if ip reachable. returns 1, if not reachable
  ping -w 1 -q 192.168.1.$i >/dev/null
  if [ "$?" = "0" ]; then
    # check whether this ip should be ignored
    if [ "`ip neighbor|grep 192.168.1.$i|grep $ignored_macaddr|wc -l`" = "1" ]; then
      echo "192.168.1.$i is reachable but ignored"
    else
      echo "192.168.1.$i is reachable and NOT ignored"
      # exit the program without shutting down the box
      exit;
    fi
  else
    echo "192.168.1.$i is NOT reachable"
  fi
done
# we didn't find any (not ignored) DHCP client in the LAN
# we can thus shutdown this box
echo "warning the users and shutting down the box in 5 minutes"
shutdown -h -P +5 Please save your work now!

(Adjust the script to your LAN environment)

In /etc/crontabs, add:

*/20  * * * * root /usr/local/bin/shutdown_if_no_dhcp_client_in_lan >/dev/null 2>&1

Now the LAN server will shutdown automatically after a while when no workstations/notebooks are running anymore. Note that this can happen 5 to 25 minutes after the last activity and isn’t fault-tolerant at all. The script can easily be improved however.