Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 01 Nov 2020 12:47:17 +0000
From:      Alexander V. Chernikov <melifaro@ipfw.ru>
To:        freebsd-arch <freebsd-arch@freebsd.org>
Subject:   Versioning support for kernel<>userland sysctl interface
Message-ID:  <356181604233241@mail.yandex.ru>

next in thread | raw e-mail | index | archive | help

Hey folks,

I would like to propose a change [1] that introduces versioning support for the data structures exposed to userland by sysctl interface.

We have dozens of interfaces exposing various statistics and control data by filling in and exporting structures.
net.inet6.icmp6.stats or net.inet6.icmp6.nd6_prlist can be a good examples of such interaction.

Most of these structure do not have version information embedded, which requires us to break compatibility when changing them.

The idea behind the change is really simple: append current structure version number to the sysctl OID to get the desired version of the structure.

For example, fetching "net.inet6.icmp6.stats" becomes "net.inet6.icmp6.stats.1" (or, code-wise, something like "net.inet6.icmp6.stats." __XSTRING(ICMP6STAT_VER)).

The interface satistifes the following properties:
1) preserving backward compatibility
2) allowing for low-cost kernel ABI maintenance
2) allowing for forward compatibility - application can fetch list of all supported versions of a structure.


Example:
11:25 [1] m@devel0 sysctl -o net.inet6.icmp6.stats
net.inet6.icmp6.stats.0: Format:S Length:4328 Dump:0x00000000000000000000000000000000...
net.inet6.icmp6.stats.1: Format:S Length:4624 Dump:0x00000000000000000000000000000000...

12:42 [1] m@devel0 ~/test net.inet6.icmp6.stats
sysctlnametomib("net.inet6.icmp6.stats")=0 -> 4.28.58.1.
sysctl("net.inet6.icmp6.stats")=-1 sz=512

12:43 [1] m@devel0 ~/test net.inet6.icmp6.stats.1
sysctlnametomib("net.inet6.icmp6.stats.1")=0 -> 4.28.58.1.1.
sysctl("net.inet6.icmp6.stats.1")=-1 sz=512




Some downside of this change would be the potential need to duplicate structures definitions to be 100% sure we don't break API. For example, rebuilding & running 3rd-party software may result in error fetching the necessary structure. Unmodified application build with the latest structure version will request an oldest version of a structure.

I see multiple approaches to address it:
1) duplicate structure with a new name (appending postfix like _v) - works the best for small structure
2) do nothing specific - will mostly work for append-only statistics structures
3) rely on kernel warning on calling unversioned sysctls to identify & fix the problematic customers

Please take a look at [1] for a more detailed technical description of a change. 

Any feedback is highly appreciated.

[1] https://reviews.freebsd.org/D27035

/Alexander



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?356181604233241>