ZFS with HP Smart Array P410i

As I was trying out zfs (on Ubuntu) on our HP server, I realised the RAID card that came with the server, HP Smart Array P410i, does not have a JBOD (Initiator-Target) mode. Now this is a First-world-problem – the card can support RAID 0, 1, 10, 5, 6, 50, 60, but not JBOD (?!).

Moving on, the next best thing is to configure every disk (we have 8 SSD) to be a 1-disk RAID 0 array to “simulate” a JBOD setup. Inside Ubuntu, there is now a 1-to-1 mapping of device to drive (sda – sdh), which is what is recommended by zfs.

Creating the zfs pool and setting some options:

zpool create tank sda sdb sdc sdd sde sdf sdg sdh
zfs set atime=off tank
zfs set sharesmb=on tank

But this is not the crux of this article. The problem is that random write performance is not as good as we expected out of zfs. The ideal setup would be to expose individual disks to zfs, but we could only expose the disks through the RAID card. After some tinkering, we found that the drive write cache was disabled, probably due to the fact that there is no battery unit on the RAID card.

To enable drive write cache:

hpacucli controller slot=0 modify drivewritecache=enable

IIRC there was some warnings, but I ignored them as what I want is a JBOD setup to hold non-mission critical data. A raidz pool can be setup if need be for redundancy, but at this point I lost myself looking at the 2x increase in write bandwidth. Next up, trying to saturate the pipe :D

diffutils for windows 64-bit

Needed to diff large (> 1GB) text files as part of a toolset, but DiffUtils provided by gnuwin32 is 32-bit only :( Of course I tried, but expectedly, it failed to diff the large files. Next solution: compile a native 64-bit version of diff. (Why is there no gnuwin64?) Anyway, I chose to compile on a x86_64 linux machine because I happen to have such a test machine around.

apt-get install mingw-w64
wget http://ftp.gnu.org/gnu/diffutils/diffutils-3.3.tar.xz
tar xJf diffutils-3.3.tar.xz
cd diffutils-3.3
# get diffutils-3.3-mingw64.patch and place it here
patch -p1 -i diffutils-3.3-mingw64.patch
./configure --host=x86_64-w64-mingw32 --prefix=/tmp/diffutils-3.3-mingw64
make && make install

Now, the goods are in /tmp/diffutils-3.3-mingw64/bin. Enjoy!

The file diffutils-3.3-mingw64.patch can be found under Resources. I would have gladly pasted the file here if not for the non-printable character found in the original source. If anyone knows the settings for diff to generate pure printable patch file do drop a comment below, thanks!

Further interesting read: MinGW 64 how-to


Point to note when using idapython get_func()

For those who are interested in IDA Pro/idapython, here is a “mystery” I found myself getting stuck. Consider the following snippet for a .idb of a sizeable binary (e.g. user32.dll):

f = idaapi.get_func(idc.here())
print f.startEA
for x in idautils.Heads():
print f.startEA

The output will be something like this:


Different addresses?! Mind-blowing!! (Of course, ignorance is the #1 reason for getting mind-blown.) Now for the reason behind this phenomenon, from idapython project site:

What happens is that the returned func_t* points inside the internal cache of func_t objects, and as you do more get_func() calls eventually that cache slot gets replaced by another function.

So instead of the code above, we can replace with the following using helper class lock_func:

f = idaapi.get_func(idc.here())
print f.startEA
flock = idaapi.lock_func(f) # lock the pointer
for x in idautils.Heads():
print f.startEA
flock = None # don't need it anymore, free the lock

In short, excessive use of idapython idaapi.get_func() inside IDA Pro should be complemented with helper class idaapi.lock_func unless you are fine with references changing under your nose (a.k.a. without warning).


On-Line IDA Python Plugin manual: idaapi.lock_func


Pin deprecates nmake on windows

The latest release of Pin (version 2.12-56759) removed support for nmake (and the nmake.bat that came with it) :( Instead, make is now the recommended way of compiling pintools. There are several ways to get GNU make: via Cygwin, MinGW, or download the setup for Make for windows manually. I chose the latter because I have no love for cygwin, which also explains why there is no link for it :P Also, getting the entire cygwin just for make is a total overkill. I am already running MinGW from Git for Windows, so the setup alone will suffice.

There we go! Go ahead and make (or make TARGET=ia32, for those who are compiling 32-bit pintools on 64-bit OS). However, make clean still breaks (see link at bottom of post for possible explanation, however the proposed solution is still quirky for Pin), but we shall “make” do for now.

Below are the recent changes, for completeness:

Changes added _After_ Pin 2.12 / 54730
o The PinTools makefile infrastructure has been changed. It is now simpler to use and to modify.
For detailed information, read the documentation in source/tools/Config/makefile.config.
o Nmake is no longer supported on windows. Either use make or the example vcproj file in the
MyPinTool directory.
o Android support has been added. An Android tutorial is avaliable at: <android-kit-root>/AndroidTutorial.
o The directory tree under <pinkit>/source/include has been changed, the include files are now located at:
<pinkit>/source/include/pin and <pinkit>/source/include/pin/gen.

windows – make: Interrupt/Exception caught – Super User

Static routing on windows network using consumer router

I never really understood the presence of static routing on consumer grade routers. But recently, I got the opportunity to try out that functionality in office and tearing out my hair at the same time (read: networking n00b). Documenting the steps here to prevent further hair-loss.


ISP <—> Router A [] <—> Router B []

Router A
WAN IP: DHCP-assigned by ISP
Gateway: DHCP-assigned by ISP
Static route: (Destination), (Netmask), (Gateway), (Interface) LAN

Router B

Basically that is all for configuration on both routers for the illustrated setup. For windows machines that are directly connected to Router A [], an incoming rule has to be added to the hosts’ firewall to allow incoming ICMP redirect packets from the Router A, assuming the firewall is enabled.

On Windows Vista and above, the following command (run as administrator) will add the rule:

netsh advfirewall firewall add rule name="enable static routing" dir=in action=allow enable=yes profile=private remoteip=defaultgateway protocol=icmpv4:5,any

In English, the command “adds a rule with name ‘enable static routing’, for the incoming direction, that allows traffic to pass, at the same time enabling the rule, for the private profile, only from the default gateway, with ICMP v4 redirect packets”. Tweak as needed.

Yes, it potentially requires configuration on the clients. A more transparent alternative is to dish out static routes to clients via DHCP server and eliminating the need to configure the firewall, but that is out of the scope of this post. Which brings me back to my original thought: if a user need to configure so many items, on both routers and clients, will it be better to provide an option to serve routes via DHCP? Without which, is this whole static routing even suitable for a home user on a home router?

Netsh Commands for Windows Firewall

DHCP option 121

HP Management Component Pack for Ubuntu

We got a couple of HP ProLiant DL380 G7 servers, and this is what HP has to offer for being certified for Ubuntu: Management Component Pack (on its Software Delivery Repository).

And here’s how to set it up on Ubuntu 12.04 LTS.

Add the repo:

add-apt-repository 'deb http://downloads.linux.hp.com/SDR/repo/mcp/ubuntu precise/current non-free'

And the repo keys:

wget -qO - http://downloads.linux.hp.com/SDR/repo/mcp/GPG-KEY-mcp | sudo apt-key add -

Finally, get the list of packages from the repo and install whichever packages required (hpacucli to configure the disk array controller):

apt-get update
apt-get install hpacucli


Auto-mount using udev

I have an entry for my new shiny USB drive in /etc/fstab. But I like my USB drive to auto-mount when it is plugged in (and unmount when appropriate). Here comes udev.

In /etc/udev/rules.d/50-usb.rules:

SUBSYSTEM=="block", DEVTYPE=="disk", DEVNAME=="/dev/", ACTION=="add", RUN+="/bin/mount -a"
SUBSYSTEM=="block", DEVTYPE=="disk", DEVNAME=="/dev/", ACTION=="remove", RUN+="/bin/umount /dev/%k"

To list the environment variables available for matching in udev, use udevadm monitor --environment