Updates at 2019-06-23 / libjson-c

Hi!

Why did I have to do this this time?

opkg install --force-reinstall jsonfilter
opkg install --force-reinstall ubus
opkg install --force-reinstall ubusd

The old packages needed libjson-c.so.2, but the new ones use libjson-c.so.4 with the same version number, so that opkg did not detect, that they were upgradable, so that I had to use tftp in the bootloader to flash it freshly.

Btw: Is there a better way to revert to the revision? :slight_smile:

EDIT#1: This might be related to that problem:

EDIT#2: Btw: I use 18.6.2 on a TPlink Archer VR200v (mips_24kc).

Thx.

Bye.

Bulk update of packages is strongly discouraged for just this kind of reason as well as for more subtle ABI problems.

When you feel a need to update, flashing a ROM and a self-consistent set of packages is recommended

3 Likes

so i need to flash a ROM for each security fix?
or is it safe to upgrade single packages?
or maybe lib-packages first and then the others?

but why didnt u bump the version of packages jsonfilter, ubus and ubus?
i mean: they clearly need to be upgraded (after libjson* has been upgraded), because they changed...

furthermore: since opkg knows about dependencies: why cant it determine the right order of upgrades?
and: can opkg restart upgraded services in order to avoid a reboot, if necessary? i just had to kill rpcd and ubusd manually... :slight_smile:

Did you try to make a symlink?

opkg isn't a full-featured package management system like apt or the like.

The features you describe require ABI information on all the packages, as well as the infrastructure on the router itself to walk the dependency tree. For resource-constrained devices (since many still insist on running devices with less that 16 MB of flash and less than 128 MB or RAM, down to 4/32 or less), this can be a challenge. As I understand it, there is work being done to capture the ABI information.

Once you look into the differences between flash-based "disk" and SSD/spinning-platter disk, there are other considerations that desktop/server distros don't have to worry about.

Best plan, yes

If a user-installed, application package with no library dependencies, probably. Otherwise, better to flash a ROM and a full set of self-consistent packages.

Even more complex than the dependencies alone. Since OpenWrt typically boots in well under a minute (more like 30 seconds), is it really worth dev effort?

I'm comfortable with a quarterly cadence for "routine" upgrades to packages on my servers. 30 seconds of downtime once every three months, at least for me, doesn't justify focusing dev effort on making sure something like that was "100%" -- if it's not 100%, then I'm going to have to reboot anyways.

1 Like

ok... thx.

and how can i make my own ROM image?
and how do i flash it to the device?
if it fails: can it automatically boot to the previous image?

yup...
i m up and running again...
took an hour or so... :slight_smile:

Either the image builder (relies on pre-built kernels and packages), or with the same build-system requirements, from source.

Flashing to the device is typically through sysupgrade / LuCI, like "release" or "snapshot" images, but you can configure to have your own package selection (and even configuration and other files) pre-installed.

As to booting to a previous image, it depends on if your device supports dual-firmware operation (select NAND-based devices only). If your device supports "serial-less" U-Boot TFTP, then if there are problems, you can flash a TFTP-style copy of an image to recover. If you don't have that feature, an appropriate serial adapter is highly recommended. Unless you're doing things like replacing dropbear with OpenSSH or really messing around with things in the code, you probably won't need it, but at least having it on hand will save a couple days of downtime.

2 Likes

can someone say, why some packages (e. g.: jsonfilter, ubus and ubus) did not get a new version number, although they have been re-built due to the new libjson-c?

This is a very good question. It boils down to the fact that there exists no mechanism for that yet. Basically a package maintainer would have to update the package revision whenever any direct or transient dependency changes its ABI version level.

This obviously does not scale, therefor we're in the middle of drafting a possible process for future updates.

It will probably end up being a policy change for packages with some buildroot-assisted checking to enforce the stricter rules.

Mainly:

  1. Packages must start to depend on all linked libraries directly (for example up until recently, procd depended on libblobmsg-json which depends on libjson-c but libjson-c.so.2 was linked by procd directly, therefor procd needs to depend on libjson-c directly).

    Buildroot has some dependency checking logic which triggers an error when a package links a library but does not depend on it, but this logic currently accepts indirect dependencies too. In a first step we'll likely turn such indirect library dependencies into a warning, in a later stage we'll make buildroot fail the package in such a situation.

  2. Start to pin direct library dependencies to ABI levels. Right now a package like procd merely depends on libjson-c which is a virtual name satisfied by any version of libjson-c. We will need to change library package dependencies to include the ABI version level, means instead of DEPENDS:=libjson-c, procd would start to use DEPENDS:=libjson-c4 which means it depends on any version of libjson-c with ABI/SOVERSION 4.

    Due to that, any future incompatible library version change would also imply a change to DEPENDS in all packages relying on that library (or that package would subsequently fail to build). Per policy, any change to the DEPENDS:= of a package must be accompanied by a PKG_RELEASE increase which would then bump the opkg-visible version number.

Downsides of this are:

  • Incompatible library package updates must happen in lockstep with depeendency updates to all packages using that library in multiple disconnected repositories at once in a very short timeframe; at the very least all essential core packages (those that are built into images) must be changed at the same time
  • Packaging libraries requires way more maintainer awareness and skills (the whole mechanisms outlined above are useless if a library maintainer improperly tracks the ABI version of a package)
  • The tooling in its current form (buildroot, CI tools etc.) is insufficient to support such a workflow well, so a lot of work is required to make the tooling more robust.
3 Likes

Thx for the explanation...

would it be a good idea, to just give a package a new version, whenever it has been rebuilt, so that it shows up as upgradable in opkg?
i mean: that should not take a lot of time... e. g. u could just use the seconds since 2000-01-01T00:00:00 (or the build start timestamp) as version number...
or am i missing something?

We do want packages to be reproducible and idempotent so we cannot simply emit a version depending on the time of build since that would mean that with every rebuild of the sources, the package would end up with a different version.

1 Like
  1. u could just increase a minor version number... e. g.: ubus 2018-10-06-221ce7e7-1 becomes 2018-10-06-221ce7e7-2
  2. only if the package changed (e. g. the sha256sum of its .ipk file), the version is changed?