Skip to content

Weird CDROM formats

So, I came across these files:
$ ls -goh
-rw-r--r-- 1 526M Sep 29 12:58 file.bin
-rw-r--r-- 1  478 Sep 29 12:50 file.cue
Does anyone remember cue sheets? Luckily, even today there are tools out there to make sense of these and convert them into something usable:
$ bchunk -v file.bin file.cue file.iso
Reading the CUE file:

Track  1: MODE1/2352    01 00:00:00 (startsect 0 ofs 0)
Track  2: AUDIO     01 22:46:13 (startsect 102463 ofs 240992976)
Track  3: AUDIO     01 25:25:74 (startsect 114449 ofs 269184048)
Track  4: AUDIO     01 28:01:35 (startsect 126110 ofs 296610720)
Track  5: AUDIO     01 31:14:31 (startsect 140581 ofs 330646512)
Track  6: AUDIO     01 34:51:35 (startsect 156860 ofs 368934720)
Track  7: AUDIO     01 37:51:22 (startsect 170347 ofs 400656144)
Track  8: AUDIO     01 41:22:03 (startsect 186153 ofs 437831856)
Track  9: AUDIO     01 44:18:34 (startsect 199384 ofs 468951168)
Track 10: AUDIO     01 46:38:03 (startsect 209853 ofs 493574256)
Track 11: AUDIO     01 49:12:05 (startsect 221405 ofs 520744560)

Writing tracks:

 1: file.iso01.iso
 mmc sectors 0->102462 (102463)
 mmc bytes 0->240992975 (240992976)
 sector data at 16, 2048 bytes per sector
 real data 209844224 bytes
 200/200  MB  [********************] 100 %

 2: file.iso02.cdr
 mmc sectors 102463->114448 (11986)
 mmc bytes 240992976->269184047 (28191072)
 sector data at 0, 2352 bytes per sector
 real data 28191072 bytes
  26/26   MB  [********************] 100 %
 3: file.iso03.cdr
[...]
In this case, we don't care for the audio part of the image, so we could discard all the .cdr files later on and just use the ISO image:
$ ls -goh file.*
-rw-r--r-- 1 526M Sep 29 12:58 file.bin
-rw-r--r-- 1  478 Sep 29 12:50 file.cue
-rw-r--r-- 1 201M Oct 31 16:01 file.iso01.iso

$ sudo mount -t iso9660 -o loop,ro file.iso01.iso /mnt/cdrom
$ ls /mnt/cdrom
AUTORUN.INF  Data  Install  readme.txt  Setup.exe  Splash
Oh, yeah :-)

Compression benchmarks 2016

Some time has passed since the last compression benchmarks and new contenders entered the race, so let's do another round of benchmarks, shall we?

MacBook Pro 2009

This laptop ships with an Intel Core2 Duo P8700 processor, so these tests may take a while:
$ tar -cf test.tar /usr/share/ 
$ ls -goh test.tar
-rw-r--r--  1    384M Oct  6 08:00 test.tar

$ time for i in {1..10}; do ~/bin/compress-test.sh test.tar | tee results_${i}.out; done
[...]
real    2046m5.142s
user    222m1.302s
sys     3m30.933s
So, 10 rounds of compressing and decompressing this tarball took 34 hours to complete. The results break down to:
$ for o in 9c 1c dc; do
   for p in gzip pigz bzip2 pbzip2 xz lzma zstd pzstd brotli; do
      awk "/"$p"\/"$o"/ {sum+=\$3} END {print \"$p/$o\t\", sum/10}" results_*.out
   done | sort -nk2; echo
done
pzstd/9c         19.7
zstd/9c          53.4
brotli/9c       234.5
pigz/9c         746.4
pbzip2/9c       764.6
gzip/9c         775.2
lzma/9c        1180.2
bzip2/9c       1563.9
xz/9c          3825

pzstd/1c          2.4
brotli/1c         4.7
zstd/1c           6.1
pigz/1c           6.2
gzip/1c          10.4
pbzip2/1c       752
xz/1c           778.7
lzma/1c         779.5
bzip2/1c       1532.3

pzstd/dc          0.8
zstd/dc           1.8
gzip/dc           2.4
pigz/dc           2.4
brotli/dc         2.9
pbzip2/dc         9.1
lzma/dc          10.2
xz/dc            10.8
bzip2/dc        748

Thinkpad E431

This machine comes with an i7-3632QM CPU and our test tarball is somewhat bigger:
$ tar -cf test.tar /usr/share/locale/ /usr/share/games/quake3/
$ ls -goh test.tar
-rw------- 1 978M Oct  8 22:38 test.tar

$ time for i in {1..10}; do ~/bin/compress-test.sh test.tar | tee results_${i}.out; done
[...]
real	420m39.764s
user	529m13.192s
sys	3m46.148s
After 7 hours, the results are in:
$ for o in 9c 1c dc; do
    for p in gzip pigz bzip2 pbzip2 xz lzma zstd pzstd brotli; do
       awk "/"$p"\/"$o"/ {sum+=\$3} END {print \"$p/$o\t\", sum/10}" results_*.out
    done | sort -nk2; echo
done
pzstd/9c	 17.4
pigz/9c	         17.5
pbzip2/9c	 31.5
zstd/9c    	 70.4
gzip/9c    	 84.4
bzip2/9c	145.3
brotli/9c	260
xz/9c	        612.4
lzma/9c	        622.4

pzstd/1c 	  3.3
pigz/1c	          7.2
brotli/1c	  8
zstd/1c	         10.2
pbzip2/1c	 26
gzip/1c	         27.8
bzip2/1c	141.6
lzma/1c	        181.5
xz/1c	        185.2

pzstd/dc	  0.6
zstd/dc	          2.1
brotli/dc	  4.8
pigz/dc	          5
gzip/dc	          8
pbzip2/dc	  8.8
xz/dc	         36.5
lzma/dc	         40.2
bzip2/dc	 53.3

PowerBook G4

This (older) machine is still running 24/7, so let's see which compressor we should use in the future:
$ tar -cf test.tar /usr/share/doc/gcc-4.9-base/ /usr/share/perl5
$ ls -goh test.tar
-rw-r--r-- 1 41M Oct 15 02:53 test.tar

$ PROGRAMS="gzip bzip2 xz lzma brotli zstd" \
  ~/bin/compress-test.sh -n 10 -f test.tar | tee ~/r.log
$ ~/bin/compress-test.sh -r ~/r.log
### Fastest compressor:
### zstd/1c:      1.90 seconds / 63.300% smaller 
### brotli/1c:    2.20 seconds / 57.900% smaller 
### gzip/1c:      4.80 seconds / 58.800% smaller 
### zstd/9c:     11.30 seconds / 66.000% smaller 
### gzip/9c:     19.00 seconds / 62.500% smaller 
### bzip2/1c:    36.90 seconds / 63.800% smaller 
### lzma/1c:     37.80 seconds / 65.700% smaller 
### xz/1c:       40.20 seconds / 66.000% smaller 
### brotli/9c:   60.50 seconds / 66.800% smaller 
### bzip2/9c:    63.00 seconds / 66.000% smaller 
### xz/9c:      111.90 seconds / 68.000% smaller 
### lzma/9c:    115.90 seconds / 67.700% smaller 

### Smallest size:
### zstd/9c:     11.30 seconds / 66.000% smaller 
### zstd/1c:      1.90 seconds / 63.300% smaller 
### xz/9c:      111.90 seconds / 68.000% smaller 
### xz/1c:       40.20 seconds / 66.000% smaller 
### lzma/9c:    115.90 seconds / 67.700% smaller 
### lzma/1c:     37.80 seconds / 65.700% smaller 
### gzip/9c:     19.00 seconds / 62.500% smaller 
### gzip/1c:      4.80 seconds / 58.800% smaller 
### bzip2/9c:    63.00 seconds / 66.000% smaller 
### bzip2/1c:    36.90 seconds / 63.800% smaller 
### brotli/9c:   60.50 seconds / 66.800% smaller 
### brotli/1c:    2.20 seconds / 57.900% smaller 

### Fastest decompressor:
### zstd/dc:       .80 seconds
### brotli/dc:    1.20 seconds
### gzip/dc:      1.20 seconds
### xz/dc:        1.70 seconds
### lzma/dc:      3.20 seconds
### bzip2/dc:     7.20 seconds

Building NRPE for OpenWRT

In the last article we restored nrpe from backups to a running OpenWRT installation. After another power outage we have to do this again, but let's actually build nrpe this time and only restore its configuration from the backup.

The build process will happen in a VM running Debian/jessie(amd64), so missing utilities or header files will have to be installed via apt-get:
sudo apt-get install autoconf binutils build-essential docbook gawk gettext git libncurses5-dev libssl-dev libz-dev ncurses-term openssl sharutils subversion unzip
We'll check out the source and switch to the v15.05.1 branch, because we'll need to build for the release that's currently running on the router. Since OpenWrt switched to musl last year, we cannot build trunk as the running Chaos Calmer is still linked against uClibc.
git clone https://github.com/openwrt/openwrt.git openwrt-git
cd $_
git checkout -b local v15.05.1
Note: the branch does no longer exist!

Fetch an appropriate .config (again, we cannot use trunk just yet) and enter the configuration menu:
wget https://downloads.openwrt.org/chaos_calmer/15.05.1/ar71xx/generic/config.diff -O .config
make defconfig
make menuconfig
Here, we'll select our target profile and disable the SDK:
  • Target Profile => NETGEAR WNDR3700/WNDR3800/WNDRMAC
  • [_] Build the OpenWrt SDK (disabled)
Let's also disable all modular packages from the build and run the prerequisite check to verfiy that the configuration is still valid:
sed 's/=m$/=n/' -i.bak .config
make prereq
With that, we're ready to build and install the toolchain:
script -c "time make -j4 V=s tools/install && date && time make -j4 V=s toolchain/install" ~/build.log 
This will need some time (and diskspace) to complete. Once completed (check the build.log!), we can finally build our packages:
wget https://github.com/ckujau/openwrt/archive/master.zip -O ~/openwrt_master.zip
(cd /tmp && unzip ~/openwrt_master.zip) && (cd /tmp/openwrt-master/ && tar -cf - package) | tar -xvf -
make oldconfig
script -c "time make -j4 V=s package/nrpe/compile" -a ~/build.log
script -c "time make -j4 V=s package/monitoring-plugins/compile" -a ~/build.log
Note: this will build all dependencies as well:
$ grep -h DEP package/network/utils/{monitoring-plugins,nrpe}/Makefile 
  DEPENDS:=+libopenssl +libpthread
  DEPENDS:=+libopenssl +libwrap
When everything is built correctly, we should have two package files:
$ ls -hgotr bin/ar71xx/packages/base/
total 1.1M
-rw-r--r-- 1  35K Oct  2 13:10 libgcc_5.3.0-1_ar71xx.ipk
-rw-r--r-- 1 268K Oct  2 13:10 libc_1.1.15-1_ar71xx.ipk
-rw-r--r-- 1  857 Oct  2 13:10 libpthread_1.1.15-1_ar71xx.ipk
-rw-r--r-- 1  36K Oct  2 13:11 zlib_1.2.8-1_ar71xx.ipk
-rw-r--r-- 1 741K Oct  2 13:16 libopenssl_1.0.2j-1_ar71xx.ipk
-rw-r--r-- 1  24K Oct  2 13:17 nrpe_3.0.1-1_ar71xx.ipk
-rw-r--r-- 1 768K Oct  2 13:32 monitoring-plugins_2.2-1_ar71xx.ipk

$ file build_dir/target-mips*/*/src/nrpe
build_dir/target-mips_34kc_uClibc-0.9.33.2/nrpe-3.0.1/src/nrpe: ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1, dynamically linked, interpreter /lib/ld-uClibc.so.0, not stripped
The installation should automatically install any dependencies, if needed:
router$ opkg install ./*.ipk
Installing monitoring-plugins (2.1.2-1) to root...
Installing nrpe (3.0.1-1) to root...

router$ /etc/init.d/nrpe enable
router$ /etc/init.d/nrpe start

router$ netstat -lnp | grep 5666
tcp 0 0 192.168.0.2:5666 0.0.0.0:* LISTEN 6771/nrpe
This was the easy part. The difficult part will be to get both packages upstream :-)