Build result
[binary] [file list]Prerequisites
The same as for the previous version plus:[patched python socket module] [tar 1.22] [bzip2 lib]
Uninstall
If you have the deluge-1.1.0 installed, you have to clean it up first (while preserve all the dependencies).Stop the deluge daemon if it is running. You can do it via console:
box# deluge --ui=null >>> halt >>> quit Thanks!or forcibly:
box# killall delugedNow uninstall the previous version:
dev# cd /mnt/C/ dev# ./filopack.sh --remove deluge-1.1.0 Configuration file .filopack/.config file found and used Sure to remove deluge-1.1.0 locally at /mnt/C (y/n)?y ...If you are not using the filopack packaging system, you can remove the previous version as follows:
box# cd /mnt/C/ box# wget http://filodej.ic.cz/filopack/.filopack/deluge-1.1.0.lst box# xargs rm -f < deluge-1.1.0.lst
Update the system
Before we start installing the new version, we have to update the tar archiver. The one which is part of the busybox has an ugly bug corrupting file names in long paths.box# ./filopack.sh --download bzip2-1.0.5 Configuration file .filopack/.config file found and used Retrieving package index... (Connecting to http://filodej.ic.cz) Downloading package bzip2-1.0.5 from http://filodej.ic.cz ... connected! Length: 191 [text/plain] connected! Length: 40,244 [application/x-tar] box# ./filopack.sh --install bzip2-1.0.5 ... box# ./filopack.sh --download tar-1.22 Configuration file .filopack/.config file found and used Retrieving package index... (Connecting to http://filodej.ic.cz) Downloading package tar-1.22 from http://filodej.ic.cz ... connected! Length: 1,523 [text/plain] connected! Length: 625,455 [application/x-tar] box# ./filopack.sh --install tar-1.22 ...For details about the bug see this section.
Also it may be necessary to download a patched version of python socket library, you can test your system as follows:
box# python -c 'import socket; print socket.gethostbyaddr("80.68.88.204")[2];' Segmentation fault... if you encounter the segfault, it is better to download and install the patched python socket library:
box# wget http://filodej.ic.cz/filopack/_socket.so connected! Length: 116,767 [text/plain] box# mv sys/lib/python2.5/lib-dynload/_socket.so{,.backup} box# mv _socket.so sys/lib/python2.5/lib-dynload/Now the problem should be fixed:
box# python -c 'import socket; print socket.gethostbyaddr("80.68.88.204")[2];' ['80.68.88.204']For details about this issue see this section.
Install
After we updated the system we are ready to install the new version:box# ./filopack.sh --download deluge-1.1.5 Configuration file .filopack/.config file found and used Retrieving package index... (Connecting to http://filodej.ic.cz) Downloading package deluge-1.1.5 from http://filodej.ic.cz ... connected! Length: 89,430 [text/plain] connected! Length: 16,084,717 [application/x-tar] box# ./filopack.sh --install deluge-1.1.5 Sure to unpack deluge-1.1.5 locally at /mnt/C (y/n)? y ...
Run daemon
Now we are ready to try the daemon, still it is necessary to use the LD_PRELOAD prefix or deluged.sh script:box# deluged.shThat's all. Following text just describes details related to the issues I solved. Nothing for ordinary users ;-)
Busybox tar bug
When I run the deluge client (console version) some commands was not properly interpreted:box# deluge >>> info * unknown command: info >>> help * unknown command: helpI found out that any command is implemented in a separate python file:
box# cd sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg box# ls deluge/ui/console/commands/ add.py config.pyc debug.pyc help.pyc __init__.pyc quit.pyc rm.pyc add.pyc connect.py halt.py0000755 info.py0000755 pause.py resume.py add.pyc0000644 connect.pyc halt.pyc info.pyc pause.pyc resume.pyc config.py debug.py help.py0000755 __init__.py quit.py0000755 rm.py... it seems there are some ill-named files in the command directory, and so the console does not know the commands at all.
Let's find all such corrupted files:
box# find . -name *0000* ./deluge/core/preferencesmanager.pyc0000644 ./deluge/ui/console/commands/quit.py0000755 ./deluge/ui/console/commands/help.py0000755 ./deluge/ui/console/commands/halt.py0000755 ./deluge/ui/console/commands/info.py0000755 ./deluge/ui/console/commands/add.pyc0000644 ./deluge/ui/gtkui/torrentdetails.pyc0000644 ./deluge/ui/gtkui/queuedtorrents.pyc0000644 ./deluge/ui/gtkui/filtertreeview.pyc0000644 ./deluge/ui/webui/page_decorators.py0000755 ./deluge/ui/webui/torrent_options.py0000755 ./deluge/ui/webui/lib/egg_handler.py0000755 ./deluge/ui/webui/lib/egg_render.pyc0000644 ./deluge/ui/webui/lib/webpy022/db.py0000755 ./deluge/plugins/Label-0.1-py2.5.egg0000644 ./deluge/plugins/webuipluginbase.pyc0000644 ./deluge/data/pixmaps/checking16.png0000644 ./deluge/data/pixmaps/inactive16.png0000644Let's look also in the deluge tar archive:
box# tar tjvf deluge-1.1.5.tar.bz2 | grep 0000 -rw-r--r-- 0/0 21100 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/core/preferencesmanager.pyc0000644 -rwxr-xr-x 0/0 1079 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/console/commands/quit.py0000755 -rwxr-xr-x 0/0 2299 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/console/commands/help.py0000755 -rwxr-xr-x 0/0 1125 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/console/commands/halt.py0000755 -rwxr-xr-x 0/0 5296 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/console/commands/info.py0000755 -rw-r--r-- 0/0 2036 2009-04-01 12:22:09 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/console/commands/add.pyc0000644 -rw-r--r-- 0/0 13688 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/gtkui/torrentdetails.pyc0000644 -rw-r--r-- 0/0 7346 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/gtkui/queuedtorrents.pyc0000644 -rw-r--r-- 0/0 13073 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/gtkui/filtertreeview.pyc0000644 -rwxr-xr-x 0/0 5062 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/webui/page_decorators.py0000755 -rwxr-xr-x 0/0 3233 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/webui/torrent_options.py0000755 -rwxr-xr-x 0/0 1553 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/webui/lib/egg_handler.py0000755 -rw-r--r-- 0/0 1522 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/webui/lib/egg_render.pyc0000644 -rwxr-xr-x 0/0 20480 2009-04-01 12:22:10 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/ui/webui/lib/webpy022/db.py0000755 -rw-r--r-- 0/0 38041 2009-04-01 12:22:11 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/plugins/Label-0.1-py2.5.egg0000644 -rw-r--r-- 0/0 2982 2009-04-01 12:22:11 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/plugins/webuipluginbase.pyc0000644 -rw-r--r-- 0/0 699 2009-04-01 12:22:11 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/data/pixmaps/checking16.png0000644 -rw-r--r-- 0/0 595 2009-04-01 12:22:11 sys/lib/python2.5/site-packages/deluge-1.1.5-py2.5-linux-i686.egg/deluge/data/pixmaps/inactive16.png0000644At a first glance it seem that the archive is corrupted but when I tried the same operation on my mirror system (on the PC) no corrupted file appeared in the archive.
The difference was that while on the mirror system I have the GNU tar 1.20 installed, on the box there is a busybox version containing tar utility:
box# which tar /bin/tar box# ls -l /bin/tar lrwxrwxrwx 1 root root 7 2008-05-21 13:40 /bin/tar -> busyboxI decided to build the newest GNU tar version (1.22) and install it to the box. A new post containing the build procedure will follow. After the installation the problem disappeared.
Socket related crash
I am not sure whether it was new to this version, but after the installation from time to time I have experienced a weird crash of the deluge daemon. Also the Windows client did not respond for long time when was connected to the daemon running on the box. After some experimenting with the deluge log I decided to debug the daemon to find out what is going on.I was running the gdbserver on the box:
box# LD_PRELOAD="/usr/lib/libssl.so.0.9.7 /usr/lib/libboost_filesystem-gcc41-mt-1_35.so.1.35.0" gdbserver colinux:2345 `which python` `which deluged` -d Process /usr/bin/python created; pid = 31831 Listening on port 2345 Remote debugging from host 192.168.1.102 ...Then I was ready to connect to the gdbserver from my mirror system:
deb# gdb `which python` GNU gdb 6.3 Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-linux-uclibc"...Using host libthread_db library "/lib/libthread_db.so.1". (gdb) target remote storage:2345 Remote debugging using storage:2345 0x40000c90 in ?? () (gdb) cont Continuing. ...After some time when I was connecting and disconnectiong the windows client to the daemon the problem appeared:
[New Thread 32801] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 32801] 0x400a0fb0 in PyString_FromString (str=0xc7c3815b <Address 0xc7c3815b out of bounds>) at Objects/stringobject.c:108 108 size = strlen(str); (gdb)It was at the following stack:
(gdb) where #0 0x400a0fb0 in PyString_FromString (str=0xc7c3815b <Address 0xc7c3815b out of bounds>) at Objects/stringobject.c:108 #1 0x407e8154 in gethost_common (h=0xbb9fdae8, addr=0xbb9fdb08, alen=128, af=2) at /usr/local/src/Python-2.5.2/Modules/socketmodule.c:3048 #2 0x407e5825 in socket_gethostbyaddr (self=0x0, args=0x40f2f48c) at /usr/local/src/Python-2.5.2/Modules/socketmodule.c:3273 #3 0x40094bd2 in PyCFunction_Call (func=0x405ac70c, arg=0x40f2f48c, kw=0x0) at Objects/methodobject.c:108 #4 0x400dcf1a in PyEval_EvalFrameEx (f=0x81f8624, throwflag=0) at Python/ceval.c:3573 #5 0x400de1e6 in PyEval_EvalCodeEx (co=0x405b94e8, globals=0x405b624c, locals=0x0, args=0x820022c, argcount=1, kws=0x8200230, kwcount=0, defs=0x405be518, defcount=1, closure=0x0) at Python/ceval.c:2836 #6 0x400dd6d0 in PyEval_EvalFrameEx (f=0x82000e4, throwflag=0) at Python/ceval.c:3669 #7 0x400dda59 in PyEval_EvalFrameEx (f=0x81e77d4, throwflag=0) at Python/ceval.c:3659 #8 0x400de1e6 in PyEval_EvalCodeEx (co=0x405c13c8, globals=0x405b602c, locals=0x0, args=0x406200b0, argcount=4, kws=0x0, kwcount=0, defs=0x0, defcount=0, closure=0x0) at Python/ceval.c:2836 ...a crash in PyString_FromString seems to be just a consequence, let's look up a bit:
(gdb) up #1 0x407e8154 in gethost_common (h=0xbb9fdae8, addr=0xbb9fdb08, alen=128, af=2) at /usr/local/src/Python-2.5.2/Modules/socketmodule.c:3048 3048 tmp = PyString_FromString(*pch); (gdb) list 3043 3044 /* SF #1511317: h_aliases can be NULL */ 3045 if (h->h_aliases) { 3046 for (pch = h->h_aliases; *pch != NULL; pch++) { 3047 int status; 3048 tmp = PyString_FromString(*pch); 3049 if (tmp == NULL) 3050 goto err; 3051 3052 status = PyList_Append(name_list, tmp); (gdb) print h $1 = (struct hostent *) 0xbb9fdae8 (gdb) print *h $2 = {h_name = 0xbb9f9b00 "filodej.doma", h_aliases = 0x40172891, h_addrtype = 2, h_length = 4, h_addr_list = 0xbb9f9aec} (gdb) print h->h_aliases $3 = (char **) 0x40172891 (gdb) print *h->h_aliases $4 = 0xc7c3815b <Address 0xc7c3815b out of bounds>... It seems that a host entry should contain an array of strings - aliases - but this array is apparently corrupted - it causes a crash of the C string -> Python string conversion routine. Let's look who is responsible for filling the array:
(gdb) up #2 0x407e5825 in socket_gethostbyaddr (self=0x0, args=0x40f2f48c) at /usr/local/src/Python-2.5.2/Modules/socketmodule.c:3273 3273 ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr), af); (gdb) list 3268 PyThread_acquire_lock(netdb_lock, 1); 3269 #endif 3270 h = gethostbyaddr(ap, al, af); 3271 #endif /* HAVE_GETHOSTBYNAME_R */ 3272 Py_END_ALLOW_THREADS 3273 ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr), af); 3274 #ifdef USE_GETHOSTBYNAME_LOCK 3275 PyThread_release_lock(netdb_lock); 3276 #endif 3277 return ret;The gethostbyaddr seems as a good candidate. At first I wondered whether the function is thread safe (see the following text about uClibc thread safety), but after further debugging I have found out that the apparently thread safe variant gethostbyaddr_r is called in my case, so there should be not threading issue there.
(gdb) cont Continuing. [New Thread 1024] Breakpoint 2 at 0x407e574c: file /usr/local/src/Python-2.5.2/Modules/socketmodule.c, li Pending breakpoint "socket_gethostbyaddr" resolved [New Thread 19476] [Switching to Thread 19476] Breakpoint 2, socket_gethostbyaddr (self=0x0, args=0x40f27ccc) at /usr/local/src/Python 3229 if (!PyArg_ParseTuple(args, "s:gethostbyaddr", &ip_num)) ... (gdb) next 3252 Py_BEGIN_ALLOW_THREADS (gdb) next 3255 result = gethostbyaddr_r(ap, al, af, (gdb) next 3272 Py_END_ALLOW_THREADS (gdb) print buf $12 = "À¨\001eè\232?½", '\0' <repeats 16 times>, "filodej.doma\000.in-addr.arpa", '\0' <repeats 16333 times>, "@" (gdb) next 3273 ret = gethost_common(h, (struct sockaddr *)&addr, sizeof(addr), af); (gdb) print *h $14 = {h_name = 0xbd3f9b00 "filodej.doma", h_aliases = 0x40172891, h_addrtype = 2, h_length = 4, h_addr_list = 0xbd3f9aec} (gdb) print h->h_aliases $15 = (char **) 0x40172891 (gdb) print *h->h_aliases $16 = 0xc7c3815b <Address 0xc7c3815b out of bounds>... after some googling I found some hints in the following forum.
Actually it seem there were two related bugs: the first in gethostbyname_r seems to be fixed now, steps to simply reproduce the problem:
box# python -c 'import socket; print socket.gethostbyname_ex("wh0rd.org")[2];' ['80.68.88.204']... it was ok in my case, it seems to be fixed in 0.9.27 version.
The second bug is in gethostbyaddr_r function. The step to reproduce is following:
box# python -c 'import socket; print socket.gethostbyaddr("80.68.88.204")[2];' Segmentation fault... it crashes on my box. Given you have the Python installed, you can test your configuration the same way.
For the solution I decided not to patch or upgrade the uClibc but rather make a workaround in the python socket library. Zeroing the structure prior to the gethostbyaddr_r call should be enough. Let's modify the python Modules/socketmodule.c file. In the PySocket_gethostbyaddr functon there is a hp_allocated structure we are going to reset to zeroes. Just before the gethostbyaddr_r call we add the following code:
#if defined(HAVE_GETHOSTBYNAME_R_6_ARG) memset((void *) &hp_allocated, '\0', sizeof(hp_allocated)); result = gethostbyaddr_r(ap, al, af, &hp_allocated, buf, buf_len, &h, &errnop);... and rebuild and re-pack the python package:
deb# cd /usr/local/src/Python-2.5.2 deb# make case $MAKEFLAGS in \ *-s*) LD_LIBRARY_PATH=/usr/local/src/Python-2.5.2::/mnt/C/sys/lib:/mnt/C/sys/X11/lib CC='gcc -pthread' LDSHARED='gcc -pthread -shared' OPT='-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes' ./python -E ./setup.py -q build;; \ *) LD_LIBRARY_PATH=/usr/local/src/Python-2.5.2::/mnt/C/sys/lib:/mnt/C/sys/X11/lib CC='gcc -pthread' LDSHARED='gcc -pthread -shared' OPT='-DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes' ./python -E ./setup.py build;; \ esac running build running build_ext db.h: found (4, 3) in /mnt/C/sys/include db lib: using (4, 3) db-4.3 /mnt/C/sys/include/sqlite3.h: version 3.5.8 INFO: Can't locate Tcl/Tk libs and/or headers building '_socket' extension gcc -pthread -fPIC -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. -I/usr/local/src/Python-2.5.2/./Include -I/mnt/C/sys/include -I. -IInclude -I./Include -I/usr/local/include -I/usr/local/src/Python-2.5.2/Include -I/usr/local/src/Python-2.5.2 -c /usr/local/src/Python-2.5.2/Modules/socketmodule.c -o build/temp.linux-i686-2.5/usr/local/src/Python-2.5.2/Modules/socketmodule.o gcc -pthread -shared -L/mnt/C/sys/lib -L/mnt/C/sys/X11/lib -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes build/temp.linux-i686-2.5/usr/local/src/Python-2.5.2/Modules/socketmodule.o -L/mnt/C/sys/lib -L/mnt/C/sys/X11/lib -L/usr/local/lib -L. -lpython2.5 -o build/lib.linux-i686-2.5/_socket.so building 'nis' extension gcc -pthread -fPIC -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I. -I/usr/local/src/Python-2.5.2/./Include -I/mnt/C/sys/include -I. -IInclude -I./Include -I/usr/local/include -I/usr/local/src/Python-2.5.2/Include -I/usr/local/src/Python-2.5.2 -c /usr/local/src/Python-2.5.2/Modules/nismodule.c -o build/temp.linux-i686-2.5/usr/local/src/Python-2.5.2/Modules/nismodule.o gcc -pthread -shared -L/mnt/C/sys/lib -L/mnt/C/sys/X11/lib -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes build/temp.linux-i686-2.5/usr/local/src/Python-2.5.2/Modules/nismodule.o -L/mnt/C/sys/lib -L/mnt/C/sys/X11/lib -L/usr/local/lib -L. -lnsl -lpython2.5 -o build/lib.linux-i686-2.5/nis.so *** WARNING: renaming "nis" since importing it failed: dynamic module does not define init function (initnis) running build_scripts box# make install ... deb# cd /mnt/C/ deb# ./filopack.sh -R --pack python-2.5.2 ...
Build process
The build process was identical to 1.1.0 version, I just had to create .pth link file in order to be able to remove the duplicate directories:dev# cd /mnt/C/sys/lib/python2.5/site-packages dev# echo "./deluge-1.1.5-py2.5-linux-i686.egg" > deluge.pth dev# cd /mnt/C/ dev# ./filopack.sh --pack deluge-1.1.5Remove all the "site-packages/deluge/" sub-paths (they seem to be redundant) and re-pack the package once more.