undefined reference to “function name”

Since hermes is flooding my mailbox I haven’t looked if all my packages are compiling on Factory. So I had a look for interesting emails today. ctrlproxy (irc proxy/bouncer) didn’t build with undefined reference to ““. I wondered if the libarary packages have been renamed, but everything looked fine. I’ve talked to darix and he told me about the –as-needed flag of the linker which is set by default now. I’ve searched for some documentation didn’t find something which explains the problems so here is my documentation.

The problem is the linking order of the libraries and source code! Lets look at an example:

Assume that you built a static library libwurst and it uses the pow() function from the math library.

$ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lm -lwurst
./libwurst.a(wurst.o): In function `wurst':
wurst.c:(.text+0x29): undefined reference to `pow'

The problem here is, that the linker doesn’t find any reference to pow() in main.c. Then the first library is libm and as it is not needed, the linker skips it. So you have to link against libwurst.a before you link against libm.

$ gcc -Wl,--as-needed --static main.c -o wurstsalat -L. -lwurst -lm

To summarize it: When using –as-needed, the order in which the libraries appear in the command line is relevant: any library X must precede all libraries Y that offer symbols that X uses.

I’ve created a page in the openSUSE wiki, you can find it here.

phonon and amarok wakeups

I’ve used my notebook the first time with openSUSE 11.1 without a power cable attached and wondered why my battery was empty after a short time. So I’ve did some research and found a knotify4 bug, this leads to a phonon and xine bug. I have the latest version of xine installed and the wakeup bug in xine is already fixed sine 1.1.9. So there must be still a bug in the phonen backend of KDE 4.1.3.

I found a new phonon-xine backend on kde-apps.org, here. I’ve found packages in the build service (click) and tested them. The wakeups of the whole system dropped to less than 200 wakeups per second.

During my research I stumbled over a amarok problem too. If you’re playing music with amarok, it produces more than 900 wakeups, even if you stopped playing the music. The whole system should need more than 500 wakeups if you play music and browse the internet.
You have to quit the application!

UPDATE:
The bugs are fixed in KDE SVN (KDE 4.2). Thanks to Mark Kretschmann. The amarok bug for this was #177517.

Hackweek3: Logitech hacking

I planning to rewrite lomoco since a long time now. The problem is that Logitech has introduced a new protocol to talk to the devices. For the main features of these new mice we have already proof of concept code but some features aren’t suppport.

I still don’t know how they identify a cordless mouse connected to a receiver. The MX Revolution and the G7 share the same receiver. Yesterday I’ve discovered how to read the battery status from the MX and VX Revolution. I can display the battery status in percent and if the mouse is charging or is fully charged.

I’ve put together a proof-of-concept code here. Now it is time to think about a library, liblomoco. If someone is interested in hacking, feel free to contact me πŸ˜‰

If you have a VX Nano or G7 please send me the output of the vx_hack. If you own a G7 please send me the output of the ‘lsusb’ command.

csync 0.42.0 alpha1

I’ve released the first alpha version of csync. csync is a client only bidirectional file synchronizer. You can use csync for different things. The intention is to provide Roaming Home Directories for Linux but you can use it to synchronize your music collection or create a backup of a directory. This is *not* intended for production environments and is designed for testing purposes only. This version is fully functional and you can sync two local directories or a local directory with a samba share.

More at http://www.csync.org/

Qemu (kvm) internal network setup

I got a new notebook, a nice Thinkpad T61 with virtualization technology. I need to run some Windows system for development so I’ve decided to use the Kernel based Virtual Machine (KVM). The VMs should communicate over an internal network but should have access to the internet and I want access via network to them. So I setup a bridge with TUN/TAP devices masqueraded to my normal interface.


               HOST            QEMU GUEST1
        +---------------+   +--------------+
        | 10.10.5.158   |   |              |
 LAN ---+---- eth0      |   |              |
        |               |   |              |    QEMU GUEST2
        |   +------+ +--+---+---- nic0     |   +--------------+
        |   | tap0---+  |   |192.168.100.5 |   |              |
        |   | tap1---+  |   +--------------+   |              |
        |   +------+ |  |                      |              |
        |     br0    +--+----------------------+---- nic0     |
        |192.168.100.254|                      |192.168.100.1 |
        +---------------+                      +--------------+


Needed packages:

tunctl (uml-utilities)
bridge-utilities
kvm

Setup the network:

Create a file call kvm-network with the following content and make it executeable.

#!/bin/bash

KVMNET_UID=1000
KVMNET_GID=$(grep kvm /etc/group | cut -d ':' -f 3)

# number of TUN/TAP devices to setup
NUM_OF_DEVICES=3

case $1 in
        start)
                modprobe kvm
                modprobe kvm_intel

                modprobe tun
                echo "Setting up bridge device br0"
                brctl addbr br0
                ifconfig br0 192.168.100.254 netmask 255.255.255.0 up
                for ((i=0; i < NUM_OF_DEVICES ; i++)); do
                        echo -n "Setting up "
                        tunctl -b -g ${KVMNET_GID} -t kvmnet$i
                        #tunctl -b -u ${KVMNET_UID} -t kvmnet$i
                        brctl addif br0 kvmnet$i
                        ifconfig kvmnet$i up 0.0.0.0 promisc
                done
                SuSEfirewall2 stop
                SuSEfirewall2
        ;;
        stop)
                for ((i=0; i < NUM_OF_DEVICES ; i++)); do
                        ifconfig kvmnet$i down
                        brctl delif br0 kvmnet$i
                        tunctl -d kvmnet$i
                done
                ifconfig br0 down
                brctl delbr br0
                SuSEfirewall2 stop
                SuSEfirewall2

                rmmod kvm_intel
                rmmod kvm
        ;;
        *)
                echo "Usage: $(basename $0) (start|stop)"
        ;;
esac

br0 is the gateway to the external network.

Setting up the firewall:

Edit /etc/sysconfig/SuSEfirewall and set the following variables:

FW_DEV_INT="br0 qtap0 qtap1 qtap2 qtap3 qtap4"
FW_ROUTE="yes"
FW_MASQUERADE="yes"
FW_MASQ_NETS="192.168.100.0/24"
FW_PROTECT_FROM_INT="no"

If you don't run a SUSE system use the following lines to setup masquerading:

echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

On the guest you have to set the default gateway to 192.168.100.254 which is the bridge br0 and take a look in /etc/resolv.conf to get the name servers. I run a Windows 2003 Server as a guest which is the dhcp and name server for the other guests (Vista, several Linux installations).

Setting up qemu

Guest 1:

#!/bin/bash

qemu-kvm /path/to/vm.img \
          -net nic,model=rtl8139,macaddr=52:54:00:12:34:56 \
          -net tap,ifname=qtap0,script=no \
          -m 256 \
          -smp 1 \
          -usb \
          -usbdevice tablet \
          -localtime

Guest 2:

#!/bin/bash

qemu-kvm /path/to/vm2.img \
          -net nic,model=rtl8139,macaddr=52:54:00:12:34:57 \
          -net tap,ifname=qtap1,script=no \
          -m 256 \
          -smp 1 \
          -usb \
          -usbdevice tablet \
          -localtime

Note that the VMs have different MAC addresses. It took me a long time to find why I couldn't ping from one guest to another πŸ˜‰ By the way, one of the guests is running Vista, which runs smoothly on my machine with KVM.

WengoPhone 2.1rc1

WengoPhone 2.1rc1 has been released today. We migrated the build system to the CMake and added an abstraction layer called owbuild for WengoPhone. It compiles just fine under Linux, MacOSX and Windows on x86, x86_64 and ppc. The last weekend I have fixed a lot of problematic warnings to be sure it works just fine under x86_64 now.

Back to WengoPhone. It has some nice new features.

  • Secure voice calls using AES 128 bit encryption (Wengo <--> Wengo)
  • The ability to configure a SIP account on any SIP server
  • Massive stability enhancement on Mac and Linux
  • Several usability improvements

WengoPhone 2.1rc1 RPMs for openSUSE 10.2 are available at Packman, here.

If you have some problems with sound, install the portaudio package from Factory. You can get it here.
Please report bugs to the ticket system at: http://dev.openwengo.com/

WengoPhone

Client Integration with Samba

At the beginning of October I started writing my diploma thesis at SUSE Linux in Nuernberg. I’ll develop a library and a PAM module to synchronize the home directory from a Linux client to a Microsoft Windows ADS environment and back.
The main problem of this subject is to write a file synchronizer which works with the infrastructure we already have and acts like the Windows one. This means a client only file synchronizer which just uses libsmbclient and is as simple as the Windows “Merge Algorithm” used for Roaming Profiles since Windows 2000.

Webdav Calendar and Addressbook

UPDATE

Use http://owncloud.org/


Webdav

I want to access my calendar and addressbook from my mainframe and from my notebook. I write exams at the moment so it is the best time to do something else. I’ve setup a webdav to store my adressbook and calendar so I can access it with KOrganizer, Mozilla Sunbird or KAdressbook from everywhere.

First we have to create a directory for the webdav databases (lock, user).

mkdir -p /var/lib/apache2/dav
chgrp www /var/lib/apache2/dav
chmod 775 /var/lib/apache2/dav

Now we need a user

htpasswd2 -c /etc/apache2/dav_users.db <username>

Change <username> to your user and enter a password. Now lets create the web accessible directory.

mkdir /srv/www/webdav
chgrp www /srv/www/webdav
chmod 775 /srv/www/webdav

mod_dav.conf

The next step is to create a config file and add the dav modules.

Edit /etc/sysconfig/apache2 and add “dav” and “dav_fs” to the APACHE_MODULES variable. Then create a file /etc/apache2/mod_dav.conf with the following content:

<IfModule mod_dav_fs.c>
	# Location of the WebDAV lock database.
	DAVLockDB /var/lib/apache2/dav/lockdb
</IfModule>

<IfModule mod_dav.c>
	# XML request bodies are loaded into memory;
	# limit to 128K by default
	LimitXMLRequestBody 131072
	
	# Location of the WebDav Repository.
	Alias /webdav "/srv/www/webdav"
	
	<Directory /srv/www/webdav>
		# enable webdav for this directory
		Dav On
		Options +Indexes
		IndexOptions FancyIndexing
		AddDefaultCharset UTF-8
		AuthType Basic
		AuthName "WebDAV Server"
		# htpasswd2 -c /etc/apache2/dav_users.db <username>
		AuthUserFile /etc/apache2/dav_users.db
		<LimitExcept GET OPTIONS>
			Require valid-user
		</LimitExcept>
		Order allow,deny
		Allow from all
	</Directory>
</IfModule>

and include it in /etc/httpd.conf

# webdav
Include /etc/apache2/mod_dav.conf

Now you can access your webdav directory with http://domain.tld/webdav

SSL

I’m sure you want to access your server the secure way, so we need mod_ssl and a certificate. I have an CACert account so I created a real one πŸ˜‰

You have to create a CSR (Certificate Signing Request) for CACert. This file contains pieces of information about your cert and your public key.
It is used by the Certification Authority to sign your cert.

Generate an encrypted key

Type the following command to generate a private key that is file encrypted.

openssl genrsa -des3 -out server.key 1024

You will be prompted for the password to access the file and also when starting your webserver. Warning: If you lose or forget the passphrase, you must generate another certificate.
If you decide at a later stage that you would rather use an unencrypted key (cause you don’t want to enter the key at boot time), you may create an unencrypted version of server.key in server.key.unsecure by executing:

openssl rsa -in server.key -out server.key.unsecure

Request a Server Certificate

Log in to your CACert account and post the CSR, you’ll will receiver the server.crt by mail. Replace the server.key in /etc/apache2/ssl.key and server.crt in /etc/apache2/ssl.crt with your CSR and your cert.

Configure SSL

Edit in /etc/sysconfig/apache2 the add to APACHE_SERVER_FLAGS the option -DSSL. Restart your apache2 and connect e.g. with konqueror to your webdav and log in:

webdavs://domain.tld/webdav

WengoPhone

Maybe you heard already about that OpenWengo thing. OpenWengo is a community of Free Software enthusiasts. The OpenWengo community is sponsored by Wengo, a French SIP provider, itself backed by Neuf Cegetel, a French telco. WengoPhone, a SIP compliant VoIP client and a multiprotocol instant messanger (MSN, AIM, ICQ, Jabber, Google Talk). We’re talkig here about WengoPhone NG (Next Generation) which is the version in development.

Currently I’m working on a RPM package for WengoPhone NG. I’ve written some patches to build it on x86_64 and to fix some bugs to build it on SUSE. The problem is that I can’t link the application at the moment cause SUSE doesn’t provide libQtUiTools in their QT4 packages (SUSE LINUX 10.1 and factory). To drop it at the build service a bug fix for the boost package is needed too.

I hope that my patches will be in SVN soon and that SUSE will fix the packages. I don’t want to create a fixed QT4 package πŸ™‚