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))