Adding a new disk to a Xen VM

      No Comments on Adding a new disk to a Xen VM

Create a new image file (10GiB):

dd if=/dev/zero of=mailstore.img bs=1M count=10k

(Note: You can also create a sparse file with dd’s seek option. Have a look at the dd manpage or the examples on http://en.wikipedia.org/wiki/Dd_(Unix))

Create the new filesystem:

mkfs.ext3 mailstore.img

Label the filesystem:

e2label mailstore.img <new-label>

Edit the DomU’s config file, /etc/xen/<hostname>.cfg and add the new disk:

disk = [ "tap:aio:/vm/disk.img,xvda,w", \
         "tap:aio:/vm/mailstore.img,xvdb,w" ]

Start the VM:

xm create <hostname>.cfg

Edit DomU’s /etc/fstab & mount the disk:

[...]
LABEL=/<new-label>   /<mount-point>   ext3   defaults   0 1
[...]

Installing yum build dependencies with yum-builddep

After fiddling around with rpmbuild for quite a while, I stumbled upon yum-builddep. It’s basically a tool to install all packages required to rebuild an RPM package from the SRPM. So if you want to install all “BuildRequires” mentioned in the spec file of a package, invoke

yum-builddep <package name>

The source RPM for the specified package must be available in the yum repository or it can be a local source RPM file.

yum-builddep itself it part of the yum-utils package. You can install it with yum

yum install yum-utils

See also yum-builddep manpage

Display current git branch in bash

      No Comments on Display current git branch in bash

Sometimes it’s very useful to know which git branch you are working on right from the command prompt. There are many solutions out there, but most of them include python and some awk or grep magic which can time a serious amount of time when you cd into a reasonably large git tree.

But you can also take advantage of the __git_ps1 function, provided by /etc/bash_completion.d/git in the git package. Add this line to ~/.bashrc:

export PS1='[\u@\h \W$(__git_ps1 " (%s)")]\$ '

This setting helps you keep track of which branch you are in at a given time. If you are in a git working directory, it shows the current branch as part of the prompt:

[user@host directory-name (master)]$ 

If you do not have the bash-completion package installed, you must manually source the git completion script prior to using __git_ps1(). To do this, add

source /etc/bash_completion.d/git

to ~/.bashrc.

You might also want to display when there are changes in your work tree or the git index:

[user@host directory-name (master*)]$ 
[user@host directory-name (master+)]$ 
[user@host directory-name (master%)]$ 
  • * indicates that a tracked file was modified
  • + indicates that a tracked file was modified and staged (with git add)
  • % indicates that you have untracked files in your tree

To do so, simply add these lines in your ~/.bashrc, right before the line modifying your prompt:

export GIT_PS1_SHOWDIRTYSTATE=true
export GIT_PS1_SHOWUNTRACKEDFILES=true

See the comments at the beginning of /etc/bash_completion.d/git for more details.

BackUpWordPress plugin produces tarballs containing duplicates

I’m using BackUpWordPress to do regular database and file tree backups of this blog. Unfortunately, there is a nasty bug in this plugin which may cause the tarball to contain every backuped file multiple times (to be precise, every file except the first one will go into the tarball exactly three times).

The problem is that the . and .. directories may appear in a somewhat random order and not necessarily as the first entries in a directory. This is probably host specific (I encountered this error for the first time after I relocated this blog to another server).

To fix BackUpWordPress v0.4.5, locate line 103 in Directory.php (resides in wp-content/plugins/backupwordpress/Archive/Reader/) and change the while-loop inside the next() function

...
        while ($this->source === null ||
              ($error = $this->source->next()) !== true) {
...

like this

...
        $file = null; 
        while ($this->source === null ||
              $file == '.' || $file == '..' || 
              ($error = $this->source->next()) !== true) {
...

Alternatively, you can use the following patch:

--- Directory.php.orig	2010-07-17 15:02:56.093238736 +0200
+++ Directory.php	2010-07-17 15:04:10.367237641 +0200
@@ -103,0 +104 @@
+        $file = null; 

@@ -104,0 +106 @@
+              $file == '.' || $file == '..' || 

Resources:
http://pear.php.net/bugs/bug.php?id=6546

Visualizing rpm dependencies with Graphviz

Sometimes, rpm dependencies get rather complex. It’s not always easy for an rpm maintainer to keep track of the runtime requirements of his package and therefore, huge rpm dependency trees develop. And it’s even more difficult so see which packages get pulled by yum, because only a tiny part of those are actually listed as requirements in the spec file. The tree gets huge with recursion!

With rpmdep, there’s a small tool that will help you visualize those dependency trees. It’s part of Fedora’s rpmorphan-package, so you can easily pull it with yum:

# yum install rpmorphan

rpmdep itself is just a perl script, that walks down the rpm tree recursively. It can produce a Graphviz dot-file, which in turn can be used to make rather since pictures. For example,

$ rpmdep -dot firefox.dot firefox
$ dot -Tpng firefox.dot -o firefox.png

produces a complete rpm dependency tree for firefox. An exemplary picture (firefox’s dependencies in Fedora 13):

Click image for full size (1.6MB)

Graphvic can produce quite a few output formats. For an overview about all available commands, have a look at http://www.graphviz.org/doc/info/command.html.

Granting access to X server with xhost

      8 Comments on Granting access to X server with xhost

Every X server internally manages an ACL (Access Control List) of those hosts, that are allowed to connect. The server only authorizes connections from X clients, whose host is on that list and rejects access to all others. The xhost program is used to add or revert access to the X server for specified hosts. It’s also possible to specify a user and a hostname pair.

Host-based Control (xhost)

To see if access control is enabled, type xhost. It displays the current ACL:

$ xhost
access control enabled, only authorized clients can connect
SI:localuser:user
SI:localuser:gdm
SI:localuser:root

If the access control is disabled, it prints:

$ xhost
access control disabled, clients can connect from any host

To disable the access control type xhost + which allows any host to access your X server. You probaly don’t want to do this because it allows the world to open windows on your screen and grab the keystrokes you type.

To enable the access control again type xhost - and only authorized clients/hosts are allowed to do the things mentioned above.

A simple example

Now let’s do something useful, e.g. grant another user on the local machine access to our X server. It’s pretty easy:

$ xhost +SI:localuser:anotheruser
localuser:anotheruser being added to access control list

And after that, anotheruser should show up in the ACL:

$ xhost
access control disabled, clients can connect from any host
SI:localuser:anotheruser
SI:localuser:user
SI:localuser:gdm
SI:localuser:root

To revoke the access right for anotheruser, use

$ xhost -SI:localuser:anotheruser
localuser:anotheruser being removed from access control list

For granting access to users on different hosts, have a look at the xhost manpage or the examples provided on http://linux.about.com/library/cmd/blcmdl_xhost.htm.

Dealing with .rpmnew and .rpmsave files

      1 Comment on Dealing with .rpmnew and .rpmsave files

When an upgrade includes changes to a default configuration file, the package will write either a .rpmnew or a .rpmsave file instead of overwriting the configuration file on your system. Which file a package creates is up to the discretion of the package maintainer.

From “Dealing with .rpmnew and .rpmsave files” By Bruce Byfield:

An .rpmnew file contains the new default configuration file and leaves your original configuration file untouched. By contrast, and .rpmsave file is a copy of your original configuration file, which has been replaced by the new default file.

The following script can be helpful to find (and possibly merge) those files with your original configuration

for a in $(find /etc /var -name '*.rpm?*'); do diff -u $a ${a%.rpm?*}; done

You may also want to check on yum-merge-conf, a yum plugin to merge configuration files.

Cleaning up locally-installed RPMs with package-cleanup

Sometimes, packages you never actually use get installed as dependency by yum (or even during initial installation by anaconda). package-cleanup is a great tool that helps you find packages not required by other packages. It it part of the yum-utils package which can easily be pulled with yum:

# yum install yum-utils

1. Find and review “unused” packages

You can find packages not required by other packages with

# package-cleanup --leaves

These packages could be candidates for removal, but check to see whether you use them directly or if they are used by applications not backed by rpm packages.

2. Find and review “lost” packages

You can find orphaned packages (i.e. packages not in the repositories anymore) with

# package-cleanup --orphans

This will also show packages which have been partially uninstalled but where the “%postun” script failed.

See also package-cleanup manpage

Duplicate log4j output lines

      No Comments on Duplicate log4j output lines

Ever seen duplicate lines in your log4j output? Maybe something like this:

2010-06-28 21:56:11,743 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 1.8.1
2010-06-28 21:56:11,743 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 1.8.1
2010-06-28 21:56:11,750 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler MyScheduler_$_1 started.
2010-06-28 21:56:11,750 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler MyScheduler_$_1 started.

Well, the obvious cause is probably duplicate loggers your log4j configuration:

log4j.rootLogger=INFO, DefaultConsoleAppender
log4j.logger.org.quartz=DEBUG, DefaultConsoleAppender

As the properties are inherited from the root logger, this is telling log4j that all quartz-classes should send their log to the DefaultConsoleAppender (which the root logger is doing anyway). So we simply have to remove the appender from the second logger definition:

log4j.rootLogger=INFO, DefaultConsoleAppender
log4j.logger.org.quartz=DEBUG

So watch your inherited log levels and appenders in your log4j configuration!

If anyone knows, why these duplicate lines appear from time to time in heavily multi-threaded environments (although log4j claims to be thread-safe) despite correct property files, please drop me a mail or leave a comment.