Tag Archives: QNAP

Upgrading Qnap TS109 from Wheezy to Jessie

The Qnap TS-109 runs Debian Wheezy just fine, but it has to be upgraded from Squeeze (no direct install). How about upgrading Wheezy to Jessie? This device is old and slow, so I decided to find out, and if it does not work, so be it.

Debian links:

Below follows a shorter version of the upgrade guide, focusing on what I actually did with my Qnap.

Getting ready
First you should of course backup your stuff if the device contains anything you can not lose.

It can also be a good idea to clean out packages that you dont need (to both avoid problems when upgrading them, and to save time during the upgrade):

$ sudo dpkg -l
$ sudo apt-get purge SOMEPACKAGES

It is also adviced to make sure you dont have packages on hold. You can do this with:

$ sudo dpkg --get-selections | grep 'hold$'

I confirmed that my system was then fully wheezy-updated

$ sudo apt-get update

$ sudo apt-get upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

$ sudo apt-get dist-upgrade
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

With that, I decided I was ready for an upgrade to Jessie.

Upgrade itself
I first updated /etc/apt/sources.list.

Old version:

deb http://ftp.se.debian.org/debian/ wheezy main
deb-src http://ftp.se.debian.org/debian/ wheezy main non-free

deb http://security.debian.org/ wheezy/updates main
deb-src http://security.debian.org/ wheezy/updates main non-free

deb http://ftp.df.lth.se/debian wheezy-backports main

New version:

deb http://ftp.se.debian.org/debian/ jessie main
deb-src http://ftp.se.debian.org/debian/ jessie main non-free

deb http://security.debian.org/ jessie/updates main
deb-src http://security.debian.org/ jessie/updates main non-free

I just deleted the backports source.

And begin upgrade:

$ sudo apt-get update
$ sudo apt-get upgrade

That went fine, so I did a reboot. It took longer than usual, but it came up. So I proceeded with:

$ sudo apt-get dist-upgrade

…which went fine, and I rebooted.

System came up and it seems good! If I encounter problems later I will write about it here.

Build Node.js on Debian ARM

Update 2015-02-15: So far, I have failed building Nodejs v0.12.0 on ARMv5

I have a QNAP TS109 running Debian (port:armel, version:7), and of course I want to run node.js on it. I don’t think there are any binaries, so building from source is the way to go.

About my environment:

$ cat /etc/debian_version
7.2
$ gcc --version | head -n 1
gcc (Debian 4.6.3-14) 4.6.3
$ uname -a
Linux kvaser 3.2.0-4-orion5x #1 Debian 3.2.51-1 armv5tel GNU/Linux
$ cat /proc/cpuinfo
Processor       : Feroceon rev 0 (v5l)
BogoMIPS        : 331.77
Features        : swp half thumb fastmult edsp
CPU implementer : 0x41
CPU architecture: 5TEJ
CPU variant     : 0x0
CPU part        : 0x926
CPU revision    : 0

Hardware        : QNAP TS-109/TS-209
Revision        : 0000
Serial          : 0000000000000000

I downloaded the latest version of node.js: node-v0.10.25, and this is how I ended up compiling it (first writing build.sh, then executing it as root):

$ cat build.sh
#!/bin/sh
export CFLAGS='-march=armv5t'
export CXXFLAGS='-march=armv5t'
./configure
make install
$ sudo ./build.sh

That takes almost four hours.

A few notes…

make install
Naturally, make install has to be run as root. When I do that, everything is built again, from scratch. This is not what I expect of make install, and to me this seems like a bug. This is why I put the build lines into a little shell script, and ran the entire script with sudo. Compiling as root does not make sense

-march=armv4 and -march=armv4t
Compiling with -march=armv4t (or no -march at all, defaulting to armv4 I believe) results in an error:

../deps/v8/src/arm/macro-assembler-arm.cc:65:3: error:
#error "For thumb inter-working we require an architecture which supports blx"

You can workaround this by above line 65 in the above file:

#define CAN_USE_THUMB_INSTRUCTIONS 1

as I mentioned in my old article about building Node.js on Debian ARM.

-march=armv5te
I first tried building with -march=armv5te (since that seemed closest to armv5tel which is what uname tells me I have). The build completed, but the node binary generated Segmentation fault (however node -h did work, so the binary was not completely broken).

I do not know if this problem is caused by my CPU not being compatible with/capable of armv5te, or, if there is something about armv5te that is not compatible with the way Debian and its libraries are built.

Upgrading Qnap TS109 from Squeeze to Wheezy

Update: new instructions for upgrading Wheezy to Jessie

Now that Wheezy has been out for a while I thought it is stable enough even for my old QNAP TS109. A great source of information for Debian on Qnaps is Martin Michlmeyr, so I decided to upgrade from squeeze to wheezy using Debain standard instructions.

Package Checking
I did not have any packages on hold, but over the years I have installed quite many packages I dont need. So I spent some time listing and removing packages:

$ sudo dpkg -l
$ sudo apt-get purge SOMEPACKAGES

I thought, faster to delete them now, than to upgrade them a little later.

/etc/apt/sources.list
First real upgrade-related step is fixing /etc/apt/sources.list:

deb http://ftp.se.debian.org/debian/ wheezy main
deb-src http://ftp.se.debian.org/debian/ wheezy main non-free

deb http://security.debian.org/ wheezy/updates main
deb-src http://security.debian.org/ wheezy/updates main non-free

I have just replaced ‘squeeze’ for ‘wheezy’ four times.

update upgrade
Now the point of no return:

$ sudo apt-get update
$ sudo apt-get upgrade

This presented me with a few challenges.

???????????????????????????Configuring linux-base?????????????????????????????
? Boot loader configuration check needed                                     ?
?                                                                            ?
? The boot loader configuration for this system was not recognized. These    ?
? settings in the configuration may need to be updated:                      ?
?                                                                            ?
?  * The root device ID passed as a kernel parameter;                        ?
?  * The boot device ID used to install and update the boot loader.          ?
?                                                                            ?
?                                                                            ?
? You should generally identify these devices by UUID or label. However,     ?
? on MIPS systems the root device must be identified by name.                ?
?                                                                            ?
?                                                                            ?
??????????????????????????????????????????????????????????????????????????????
?                                 <  OK  >                                   ?
??????????????????????????????????????????????????????????????????????????????

What is an ARM user gonna do about it? You can safely ignore this (if you are upgrading Debian on a QNAP – probably not if you are upgrading Ubuntu on your laptop!). This is supposed to be grub/lilo-related, and not relevant.

In the end of apt-get upgrade I got these messages, ensuring my system will boot properly even after upgrade. You should probably see something like this too, or consider to find out how to do it manually.

Processing triggers for initramfs-tools ...
update-initramfs: Generating /boot/initrd.img-2.6.32-5-orion5x
flash-kernel: installing version 2.6.32-5-orion5x
Generating kernel u-boot image... done.
Flashing kernel... done.
Flashing initramfs... done.

Sudo was a little challenge:

Configuration file `/etc/sudoers'
 ==> File on system created by you or by a script.
 ==> File also in package provided by package maintainer.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** sudoers (Y/I/N/O/D/Z) [default=N] ? D

The “diff” told me that it intended to delete my sudo line related to me; the new way is to add people to the group (/etc/group) named sudo. So I added myself to the sudo group and bravely answered ‘Y’ to the question above.

Immediately, sudo did not work, as I was no longer in the sudoers file… However, a little logout/login fixed that, and the group works all fine.

After apt-get upgrade had completed I decided to reboot my system, before proceeding. For the first time ever it came up with another IP-address than usual. Obviously the dhcp-client did not bother to ask for the same address anymore, and the dhcp-server did not bother to hand out the same address either. So, a few nervous minutes before I found my QNAP on another IP.

apt-get dist-upgrade
Now that the system rebooted properly it was time for the final upgrade step:

$ sudo apt-get dist-upgrade

This procedure mostly works on it own, occationally asking something.

I answered Yes to this question (after reading the diff, not remembering having edited this file)

Configuration file `/etc/default/rcS'
 ==> File on system created by you or by a script.
 ==> File also in package provided by package maintainer.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** rcS (Y/I/N/O/D/Z) [default=N] ? y

The dist-upgrade once again replaced the kernel…

Processing triggers for initramfs-tools ...
update-initramfs: Generating /boot/initrd.img-3.2.0-4-orion5x
flash-kernel: installing version 3.2.0-4-orion5x
Generating kernel u-boot image... done.
Flashing kernel... done.
Flashing initramfs... done.

…so I made a final reboot. Everything seems just fine.

Building Node.js on Debian ARM (old)

Update 20140130: I suggest you first have a look at my new article on the same topic.

I thought it was about time to extend my JavaScript curiosity to the server side and Node.js.

A first step was to install it on my web server, a QNAP TS-109 running Debian 6. I downloaded the latest version (v0.10.15), and did the usual:

$ ./configure
$ make

after hours:

../deps/v8/src/arm/macro-assembler-arm.cc:65:3: error: #error "For thumb inter-working we require an architecture which supports blx"

That is not the first time my TS 109 has been too old. However, the english translation of the above message is that you have to have an ARM cpu V5 or later, and it has to have a ‘t’ in its name (at least, this is what the source tells, see below). In my case

$ uname -a
Linux kvaser 2.6.32-5-orion5x #1 Sat May 11 02:12:29 UTC 2013 armv5tel GNU/Linux

so I should be fine. I found a workaround from which I extracted the essential part.

// We always generate arm code, never thumb code, even if V8 is compiled to
// thumb, so we require inter-working support
#if defined(__thumb__) && !defined(USE_THUMB_INTERWORK)
#error "flag -mthumb-interwork missing"
#endif

// ADD THESE THREE LINES TO macro-assembler-arm.cc

#if !defined(CAN_USE_THUMB_INSTRUCTIONS)
# define CAN_USE_THUMB_INSTRUCTIONS 1
#endif

// We do not support thumb inter-working with an arm architecture not supporting
// the blx instruction (below v5t).  If you know what CPU you are compiling for
// you can use -march=armv7 or similar.
#if defined(USE_THUMB_INTERWORK) && !defined(CAN_USE_THUMB_INSTRUCTIONS)
# error "For thumb inter-working we require an architecture which supports blx"
#endif

After adding the three lines, I just ran make again, and after a few hours more everything was fine. Next time I will try the -march or -mcpu option instead.

Lisp on Debian/ARM

After reading Revenge of the Nerds I decided it was time to learn Lisp. Programming without some kind of real project is boring, so my plan is to write some web applications using jquery and Lisp (for the back end).

Since I have a Qnap TS-109 running 24×7 I thought it would make a good development machine and Lisp web server. It runs Debian 6.0, but running Lisp on it turned out to be a challenge.

Debian, Lisp and ASDF
Debian supports installing different implementations of (Common) Lisp. However, it seems to be tricky to find a version that installs a binary on Debian ARM.

Also, there is a package depency tool for lisp called ASDF. Lisp implementations should come with it.

GCL
The only Common Lisp that I managed to easily install (i.e. with apt-get) in Debain 6.0 ARM was GCL. But it is a version of GCL that is 5 years old, and it does not come with ASDF.

clisp
I spent much time trying to compile clisp, but in the end I ended up with:

  > ( / 6 3)
  2
  > ( / 5 2)
  Segmentation Fault

Not so fun. Significant parts of clisp is written in assembly (both a good thing and a bad thing), and I was really not able to figure out if it was supposed to work on ARM EABI at all, or just on the old ARM ABI. So after much struggle I gave up clisp.

ECL
I managed to compile ECL from source. Not completely without hassle though. It comes with libffi, but I ended up with compilation errors (the processor does not support…). So, I downloaded libffi, compiled it myself and installed it in /opt/libffi. That was no problem, but I ended up making a symbolic link to include myself:

kvaser@kvaser:/opt/libffi$ ls -l
total 8
lrwxrwxrwx 1 root root   40 Mar 11 16:52 include -> /opt/libffi/lib/libffi-3.0.10rc9/include
drwxr-xr-x 4 root root 4096 Mar 11 16:37 lib
drwxr-xr-x 4 root root 4096 Mar 11 16:37 share

Now I configured ecl with:

CPPFLAGS=-I/opt/libffi/include LDFLAGS=-L/opt/libffi/lib ./configure --prefix=/opt/ecl --with-dffi=auto

That worked, and compiling went fine until ecl_min could not be executed, because it could not find libffi.so.6. I tried to fix that a while, but finally ended up making another symbolic link:

kvaser@kvaser:/usr/lib$ ls -l libffi.so.6
lrwxrwxrwx 1 root root 31 Mar 11 19:56 libffi.so.6 -> /opt/libffi/lib/libffi.so.6.0.0

After that, I ran make again to finish compilation. It went fine.

ECL, ASDF and cl-who
Now, where to put the Lisp http library cl-who? I copied the asd-file and the lisp-files to the ecl library folder and ran ecl as root:

kvaser@kvaser:~/lisp/cl-who-0.11.1$ sudo cp cl-who.asd /opt/ecl/lib/ecl-11.1.1/
kvaser@kvaser:~/lisp/cl-who-0.11.1$ sudo cp *.lisp /opt/ecl/lib/ecl-11.1.1/
kvaser@kvaser:~$ sudo /opt/ecl/bin/ecl
  ... ...
> (require 'asdf)

;;; Loading #P"/opt/ecl/lib/ecl-11.1.1/asdf.fas"
;;; Loading #P"/opt/ecl/lib/ecl-11.1.1/cmp.fas"
("ASDF" "CMP")

> (asdf:operate 'asdf:load-op :cl-who)    
  ... ...

Now, cl-who is compiled and installed, ready to use. Next time, it does not need to be compiled.

Hello LISP
I wrote a little Hello World program:

kvaser@kvaser:~/lisp$ cat hello.lisp 
(format T "Hello Lisp~%")
(quit)
kvaser@kvaser:~/lisp$ /opt/ecl/bin/ecl -load hello.lisp 
;;; Loading "/home/kvaser/lisp/hello.lisp"
Hello Lisp

Quite good (except I already know the file was loaded and it disturbs my output, but whatever. How about compiling it?


kvaser@kvaser:~/lisp$ /opt/ecl/bin/ecl -compile hello.lisp 
;;; Loading #P"/opt/ecl/lib/ecl-11.1.1/cmp.fas"
;;;
;;; Compiling hello.lisp.
;;; OPTIMIZE levels: Safety=2, Space=0, Speed=3, Debug=0
;;;
;;; End of Pass 1.
;;; Note:
;;;   Invoking external command:
;;;   gcc -I. -I/opt/ecl/include/ -I/opt/libffi/include -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -g -O2 -fPIC -Dlinux -O2 -w -c hello.c -o hello.o 
;;; Note:
;;;   Invoking external command:
;;;   gcc -o hello.fas -L/opt/ecl/lib/ /home/kvaser/lisp/hello.o -Wl,--rpath,/opt/ecl/lib/ -shared -L/opt/libffi/lib -L/opt/libffi/lib -lecl -lgmp -lgc -lffi -ldl -lm 
;;; Finished compiling hello.lisp.
;;;
kvaser@kvaser:~/lisp$ ls
cl-who-0.11.1  cl-who.tar.gz  hello.fas  hello.lisp
kvaser@kvaser:~/lisp$ ./hello.fas 
Segmentation fault
kvaser@kvaser:~/lisp$ /opt/ecl/bin/ecl -load hello.fas 
;;; Loading "/home/kvaser/lisp/hello.fas"
Hello Lisp

Ok, how to make a standalone executable?

> (compile-file "hello.lisp" :system-p t)
  ... ...
#P"/home/kvaser/lisp/hello.o"

> (c:build-program "hello" :lisp-files '("hello.o"))
  ... ...
#P"hello"
> (quit)
kvaser@kvaser:~/lisp$ ls
hello  hello.fas  hello.lisp  hello.o
kvaser@kvaser:~/lisp$ time ./hello
Hello Lisp

real	0m3.084s
user	0m2.920s
sys	0m0.160s
kvaser@kvaser:~/lisp$ time /opt/ecl/bin/ecl -load hello.fas 
;;; Loading "/home/kvaser/lisp/hello.fas"
Hello Lisp

real	0m3.127s
user	0m3.060s
sys	0m0.080s
kvaser@kvaser:~/lisp$ time /opt/ecl/bin/ecl -load hello.lisp
;;; Loading "/home/kvaser/lisp/hello.lisp"
Hello Lisp

real	0m3.113s
user	0m2.960s
sys	0m0.160s
kvaser@kvaser:~/lisp$ 

Clearly, some overhead is involved in invoking ECL. I compared to C:

kvaser@kvaser:~/lisp$ cat hello.c 
#include 

int main(int argc, char **argv) {
	printf("Hello C\n");
}
kvaser@kvaser:~/lisp$ gcc -o hello_c hello.c 
kvaser@kvaser:~/lisp$ time ./hello_c 
Hello C

real	0m0.012s
user	0m0.010s
sys	0m0.000s
kvaser@kvaser:~/lisp$ 

So, I can not use this method for CGI programming right away – each call to the webserver will take at least 3 seconds.

Some performance benchmarks of QNAP TS 109

I bought a QNAP TS-109 with the intention of using it as a linux server (DNS, DHCP, www, vpn, ssh, file, mysql). The QNAP comes with its own (very nice) linux based firmware, but my plan was to run Debian on it. However, performance seemed not so good (found something on Google about missing DMA Engine in the kernel), so I decided to do some benchmarks before picking Debian or qnap firmware.

The harddrive is a Samsung 2TB drive (so those one works). All tests are made with a 500 Mb mpeg-file (high entropy). The server is a Mac OS X machine.

The commands used are:

#nc
  qnap$ nc -l -p 9999 > nc-500Mb.img
  mac$ time nc 192.168.0.21 9999 < 500Mb.img

#scp
  qnap$ time scp o@192.168.0.20:500Mb.img scp-500Mb.img

#md5sum
  qnap$ time md5sum nc-500Mb.img

#cp
  qnap$ time cp scp-500Mb.img cp-500Mb.img

Results follow:

                   nc       scp      md5sum   cp   
Debian 6.0 btrfs   87s      273s     40s      71s
           ext3    73s      284s     22s      39s
           ext2    59s      273s     22s      27s
Debian 5.0 ext3    81s      259s     23s      40s
           ext2    62s      246s     23s      26s
Qnap FW            N/A      394s     N/A      27s

The commands nc and md5sum was not available in the qnap firmware.

Bricking, and recovery
I made a mistake when making backup of the original qnap firmware. So, when intending to restore the qnap firmware over Debian, I ended up making the qnap unbootable.

Another mistake was to not follow good advice; they tell you very clearly to "install recovery mode" before trying Debian.

I got a USB to 3.3V TTL serial cable and tried to revive it. It worked using these instructions 🙂 I ended up doing some soldering inside the qnap.

My advice: when you backup /dev/mtdblocks, make a simple cmp to verify that the file you created matches the block you intended to backup. Much quicker than realising later that recovering old OS actually bricks you machine.

Conclusion
As I see it, there are no performance reasons to use the Qnap firmware with the Qnap. Debain seems to be equally fast. Still, both are surprisingly slow - do I have a hard drive incompability issue?

After deploying Debian, I can say that real world performance for rsync (mostly large files) is just over 5 Mb/s.