freebsd-update not updating reported patchlevel

Robert Bonomi bonomi at mail.r-bonomi.com
Fri May 4 09:13:03 UTC 2012


> From owner-freebsd-questions at freebsd.org  Fri May  4 02:54:56 2012
> Date: Fri, 04 May 2012 08:52:24 +0100
> From: Matthew Seaman <m.seaman at infracaninophile.co.uk>
> To: freebsd-questions at freebsd.org
> Subject: Re: freebsd-update not updating reported patchlevel
>
> On 03/05/2012 23:43, Robert Bonomi wrote:
> > Amazingly, this very question was covered on this list within the last few
> > hours.   <grin>
>
> It's not that much of a coincidence. ...

No kidding. <wry grin>

The 'amazingly' was a wry commentary on that very fact.

>
> I wonder if it would be possible or indeed worthwhile to have a very
> small kld or sysctl that shows the current patch level and that can be
> updated without replacing the kernel entire.  Obviously, this introduces
> the possibility of faking the patchlevel, so perhaps this should be
> constructed so it can only be modified on reboot.

What is required is a differentation between the _kernel_ revision level,
and the patchlevel of the entire base system.

Store the kernel revision level -in- the kernel.  Use the 'standard'
THREE-level version numbering  {Major}.{Minor}.{revision} for the kernel.
Bump 'revision' for each set fo kernel patches.

The patchlevel info for the base system can be a simple data file.
I'd suggest a dotfile' in /etc, mode 644, with the followig flags
set: 'system append only', 'system undlink'.

Bump 'patchlevel' every time -anything- in the base system changes,
regardless of whether it is part of the kernel or the 'world'.

Both kernel revision level and 'world' patchlevel are reset -only-
when a new minor (or major) release of the O/S is installed. Aside
from that, they increment semi-independantly -- 'world' patchlevel
is always greater-equal to kernel revision level.

Ideally, this is a _log_ of all the actual changes, something along the
lines of:

    BEGIN updates
      updated {foo}, Vers x.y.z, old file renamed to {foo}.x.y.x-replaced
      patchfile {foo1} for {pathname}, patch application succeeded
      patchfile {foo2} for {pathname}, patch application FAILED
      obselete file {foo3} renamed to {foo3}.x.y.z-obselete
    END updates   Now at patchlevel {quux}

For 'audit' purposes', every line is prefixed with 
    timestamp,
    login username/effective UID(as a username)
    the tty device from which the action was performed.

When a new release of the O/S is installed, the patchlog file is renamed
or deleted, and a single line of the form:

    END install   Now at patchlevel 0

is written.  Thus there is always an END line with the patchlevel ID.

The numeric patchlevel is written as a fixed-width *right-justiied* field.

Thus, the last 'END' starts at a 'known' position before the end of the
file, allowing an application to do a direct fseek(3)/lseek(2) to it (or 
the patchlevel) without having to read the entire file.  ('install' and
'updates' are chosen with malice aforethought, they're the same length ;)

>From the command-line, 'tail -1 {patchlog}' gets everything.


With this kind of setup, and assuming that all distributed patchfiles have
'unique' names, the 'patchlog' provides a roadmap for reconstructing the
state of the kernel and 'world' as of any particular point in time.

AT LEAST as important, it provides a record that would let one 'back out'
an update, to revert to a prior system state, if needed.  In fact, it
would be 'easy' to have automation perform that task.




More information about the freebsd-questions mailing list