OpenWRT is a favorite flavor of Linux intended for embedded devices such as firewalls, routers and so forth. Increasingly those devices based on various ARM SoCs are appearing with integrated SATA controllers. That, in turn, pushes use cases of such devices more and more into fileservers, backups, media server, etc.
If you’re going to use an ARM SoC as a file server, it would be nice to know the performance of your storage backend. There is a good storage performance testing Linux program called Fio. Unfortunately, fio is not a part of the OpenWRT Linux flavor but luckily porting an application over to OpenWRT can be quite simple.
1. Clone OpenWRT git repository
ds@codeminutia:~/src$ git clone https://git.openwrt.org/openwrt/openwrt.git
2. Decide on a good place where to add the application, package/utils seems like a reasonable place:
ds@codeminutia:~/src/openwrt$ mkdir package/utils/fio
3. Create a Makefile under package/utils/fio
ds@codeminutia:~/src/openwrt$ vi package/utils/fio/Makefile
4. The makefile can be copied from another package in OpenWRT, you will need to adjust some variables. Package name and release versions, PKG_VERSION is fio version; the PKG_RELEASE is OpenWRT release number.
PKG_NAME:=fio PKG_VERSION:=3.6 PKG_RELEASE:=1
5. Variables below tell the build system where to get this software. We use git to fetch the exact revision of fio 3.6. The PKG_MIRROR_HASH is the hash of source file when it is pulled from git and compressed into fio-3.6.tar.xz.
PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/axboe/fio.git PKG_SOURCE_VERSION:=c5477c6a3b3e0042b1f74414071429ca66d94c2f PKG_SOURCE_DATE:=2018-04-16 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_MIRROR_HASH:=""
6. The tricky part is PKG_MIRROR_HASH variable; you can put an empty string in there and then run make. This will download the source from git and create io-3.6.tar.xz:
ds@codeminutia:~/src/openwrt$ make package/utils/fio/download V=s
7. Now we need to fix up the HASH so we run:
ds@codeminutia:~/src/openwrt$ make package/utils/fio/check V=s FIXUP=1
8. That updated PKG_MIRROR_HASH variable in your makefile.
PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/axboe/fio.git PKG_SOURCE_VERSION:=c5477c6a3b3e0042b1f74414071429ca66d94c2f PKG_SOURCE_DATE:=2018-04-16 PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_MIRROR_HASH:=eecd190a100ccf803575a7f0027c111fb3ff322b05b98b83f01ad88039b33741
9. Section below tells the build system where to place the menu option when you use “make menuconfig”. We are placing fio under “Utilities” menu.
define Package/fio SECTION:=utils CATEGORY:=Utilities TITLE:=Flexible I/O Tester URL:=https://github.com/axboe/fio/ DEPENDS:= +zlib endef
10. This is not needed in all cases, but in our case, we make sure that configure script in fio gets the right parameters by exporting proper CONFIGURE_ARGS
# Remove quotes from CONFIG_CPU_TYPE CONFIG_CPU_TYPE_NQ:= $(patsubst "%",%,$(CONFIG_CPU_TYPE)) # get CPU type so we can pass it to fio configure script CONF_CPU:=$(firstword $(subst +, ,$(CONFIG_CPU_TYPE_NQ))) CONFIGURE_ARGS = --prefix="$(PKG_INSTALL_DIR)" --cpu="$(CONF_CPU)" --cc="$(TARGET_CC)" --extra-cflags="$(TARGET_CFLAGS)"
You can see the full Makefile below:
#
# Copyright (C) 2018 - <ds@codeminutia.com>
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=fio
PKG_VERSION:=3.6
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/axboe/fio.git
PKG_SOURCE_VERSION:=c5477c6a3b3e0042b1f74414071429ca66d94c2f
PKG_SOURCE_DATE:=2018-04-16
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_MIRROR_HASH:=eecd190a100ccf803575a7f0027c111fb3ff322b05b98b83f01ad88039b33741
PKG_MAINTAINER:=<ds@codeminutia.com>
PKG_LICENSE:=GPL-2.0
PKG_LICENSE_FILES:=COPYING
PKG_BUILD_DEPENDS:= +zlib
HOST_BUILD_DIR:=$(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/host-build.mk
include $(INCLUDE_DIR)/package.mk
define Package/fio
SECTION:=utils
CATEGORY:=Utilities
TITLE:=Flexible I/O Tester
URL:=https://github.com/axboe/fio/
DEPENDS:= +zlib
endef
define Package/fio/description
Flexible I/O Tester
Fio was originally written to save me the hassle of writing special test case
programs when I wanted to test a specific workload, either for performance
reasons or to find/reproduce a bug. The process of writing such a test app can
be tiresome, especially if you have to do it often. Hence I needed a tool that
would be able to simulate a given I/O workload without resorting to writing a
tailored test case again and again.
A test work load is difficult to define, though. There can be any number of
processes or threads involved, and they can each be using their own way of
generating I/O. You could have someone dirtying large amounts of memory in an
memory mapped file, or maybe several threads issuing reads using asynchronous
I/O. fio needed to be flexible enough to simulate both of these cases, and many
more.
Fio spawns a number of threads or processes doing a particular type of I/O
action as specified by the user. fio takes a number of global parameters, each
inherited by the thread unless otherwise parameters given to them overriding
that setting is given. The typical use of fio is to write a job file matching
the I/O load one wants to simulate.
Author: Jens Axboe <axboe@kernel.dk>
Package Maintainer: <ds@codeminutia.com> http://codeminutia.com/
endef
# Remove quotes from CONFIG_CPU_TYPE
CONFIG_CPU_TYPE_NQ:= $(patsubst "%",%,$(CONFIG_CPU_TYPE))
# get CPU type so we can pass it to fio configure script
CONF_CPU:=$(firstword $(subst +, ,$(CONFIG_CPU_TYPE_NQ)))
CONFIGURE_ARGS = --prefix="$(PKG_INSTALL_DIR)" --cpu="$(CONF_CPU)" --cc="$(TARGET_CC)" --extra-cflags="$(TARGET_CFLAGS)"
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)
$(MAKE) -C $(PKG_BUILD_DIR) INSTALL_PREFIX="$(PKG_INSTALL_DIR)" install
endef
define Package/fio/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/$(PKG_NAME) $(1)/usr/bin/
endef
$(eval $(call BuildPackage,fio, +zlib))
