Tuesday, October 2, 2012

How to maintain an OpenWRT installation

I wondered how to properly maintain an OpenWRT installation that needs to track trunk for one reason or another. For instance the OpenWRT release pace is quite slow and "new" devices or various fixes are only available in this particular branch.

Now the OpenWRT project does offer snapshot builds. These are images built with the default config for the particular device type. You can even upgrade most models using sysupgrade, which preserves a list of configuration files you specify when flashing the new image, instead of doing a dreadful tftp upload. But you still lose all the packages you installed and accumulate a bit of cruft when reinstalling them. If you do not flash new images, you will be unable to install kernel modules after a while, because the kernel version they're based upon was updated.

So what's suggested is this:
  • You checkout the trunk from svn. You enable all the feeds you need (e.g. packages and luci) and install the packages you want. (See scripts/feeds.)
  • Run make menuconfig and select the target system type and the device profile.
  • make defconfig will now give you the default configuration for the selected profile. It is important to use this as the starting point.
  • Again invoke menuconfig and select all the packages you need. You can get the current list of packages installed on your device with opkg list_installed. You can search in menuconfig as you would in a kernel build config screen.
  • If you're happy with the configuration, save the difference to the default configuration to a file: scripts/diffconfig.sh > my-own-config
  • Now start the build with make. With the package configuration I picked I need about 5 GB of disk space. It will start off compiling a toolchain, the kernel and then the packages you selected. If something seems to go wrong, you probably want to restart the build with make V=s to see the build messages (the default is pretty quiet). Some -jX option for parallel building might shorten your waiting time.
  • Finally you will get an image in bin/<system type>. You want to grab the squashfs & sysupgrade image.
  • Check /etc/sysupgrade.conf on the live system if files are missing. /etc/config, passwd, shadow and some other files are preserved even if they are not listed. Those are then the only files that are copied into a temporary ramdisk during upgrade and written back to the filesystem post-flash. You need to keep this file up-to-date if you include new packages that have non-UCI configuration.
  • For actually executing the upgrade process, you can either use the luci web interface or start sysupgrade over SSH. For the latter you will have to copy the image yourself. If you go via luci, you should check the md5 hash presented to you against the one of the image on your disk.
  • If you want to update your image, just svn update (in the hope that the OpenWRT developers did not break anything in trunk), get the new defconfig, append your saved configuration delta (the file "my-own-config" above) to .config and run make oldconfig. This will keep track of feature changes in the default configuration (like shadow password support). Update 2013-03-18: To avoid problems with unclean trees you should call make distclean before running make defconfig again. Make sure you have the config diff ready, because cleaning the tree will drop the .config.
The advantage of building an image that includes all the packages is that you don't get to reinstall them and due to the use of squashfs, all files provided by those packages are actually kept in compressed form in flash. The image I built has a size of about 7 MB and contains "heavyweight" packages like isc-dhcpd, bind, openvpn (using openssl), bash, vim-tiny, tcpdump-mini, luci, and a webserver with TLS support.

As always: Take great care when you're flashing devices. The devices I bought cannot be bricked, but this might not be true for all devices that run OpenWRT. You might need and go doing a tftp image upload if something goes wrong. Check the OpenWRT wiki for instructions and possibly make your computer ready for them before starting to play with your box. For my Buffalo WZR-HP-AG300H the sysupgrade procedure is stable.


  1. This was a great post! I've been wondering how the defconfig was done, since "make wndr3800_defconfig" didn't work. The OpenWRT documentation is scattered around the Wiki and forums and is also often out-of-date.

    One interesting thing is that how much repeated flashing actually wears down the flash memory, since the memory is small and a large percentage of it is consumed by the binary image.

    1. Well, like I said: do a plain make menuconfig first, then do a make defconfig. AFAIK this should preserve your model settings.

      Of course it wears out the flash. However I don't expect the image to be changed once a day and OpenWRT does go to great length to put ephemeral data into tmpfs. My flash, for instance, is 32M big and I'm using a tiny fraction of it. I don't know if wear levelling is done by anyone but in theory it shouldn't fail that quickly. (My WRT54GL had several reflashes over its lifetime and it's still ok.)

  2. Hello,

    nice post. Got myself a nice new TP-Link WRD4300 this week. I will test your procedure on it.