Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Mar 2015 10:51:05 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-stable@freebsd.org
Cc:        Peter Olsson <list-freebsd-stable@jyborn.se>
Subject:   Re: There has to be a better way of merging /etc during a major freebsd-update
Message-ID:  <6135520.eb0tS7GDFh@ralph.baldwin.cx>
In-Reply-To: <20150311091933.GM9442@pol-server.leissner.se>
References:  <20150310120540.GN8223@pol-server.leissner.se> <20150310220635.GA90305@anubis.morrow.me.uk> <20150311091933.GM9442@pol-server.leissner.se>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wednesday, March 11, 2015 10:19:33 AM Peter Olsson wrote:
> On Tue, Mar 10, 2015 at 10:06:37PM +0000, Ben Morrow wrote:
> > Quoth Peter Olsson <list-freebsd-stable@jyborn.se>:
> > >
> > > (But I will try running freebsd-update without merging /etc,
> > > and use mergemaster -F instead. Should solve my problem.)
> > 
> > I'm fairly sure this won't do what you want, and in fact won't work at
> > all, unless your /etc is identical to the stock /etc installed from the
> > ISO. (Which it isn't, of course.)
> > 
> > installworld specifically avoids installing the files in /etc; then,
> > when you run mergemaster, it installs the new versions of those files
> > into a temporary directory and merges them with the existing /etc. 
> > 
> > freebsd-update works a little differently: because it doesn't have a
> > source tree available, it has to fetch the stock versions of the files
> > in /etc for the release you're upgrading from, so that it can patch them
> > to the new release and then merge the changes into your current /etc. If
> > you tell freebsd-update to install /etc without merging it will blindly
> > update files you haven't changed (which is probably what you want) but
> > (I think) will fail to update the files that you have changed, because
> > it uses binary patches which won't apply to your modified versions.
> > 
> > If you want a rather hackish solution, you could try something like
> > this:
> > 
> >     - Rename /etc to /oldetc.
> >     - Find yourself a copy of the stock /etc for the version you are
> >       upgrading from. (tar -xpf base.txz --include /etc)
> >     - Run freebsd-update with /etc removed from the merge list. This
> >       will (should?) give you a stock /etc for the version you are
> >       upgrading to.
> >     - Rename /etc -> /tmp/etc, /oldetc -> /etc and run mergemaster with
> >       -t /tmp.
> > 
> > Obviously I would script this if I was doing more than one or two
> > machines
> > 
> > Ben
> 
> I'm not really clear on what will happen if I remove /etc/ from
> MergeChanges in freebsd-update.conf. Will my /etc then be ignored
> by freebsd-update, or will my /etc be completely overwritten by
> freebsd-update?
> 
> Anyway, your hack could be useful to me. There are no more than
> about ten files I usually change in /etc, so saving the current
> /etc, installing a stock /etc, running freebsd-update and then
> running diff -r to sort out my changes could work. But I'm a
> little worried about removing my /etc changes from a running server.

BTW, this is kind of how etcupdate works (except that it does a full 3-way
merge unlike mergemaster since it keeps the previous /etc around to compare
with the new /etc and apply the diffs to the real /etc).  It even has a mode
to allow it to generate tarballs on the build machine that can then be used
in place of having a source tree during upgrades so that freebsd-update could
be changed to ship the updated bundle on each update.  However, I haven't had
time to look at what it would take to update freebsd-update to do this (and
freebsd-update would have to include building the tarballs in its upstream
build process as well).

OTOH, if you ask freebsd-update to update your source tree after each
update, you can use etcupdate to manage /etc instead of using freebsd-update.
(Note that starting with 10.1 and 9.3 etcupdate is in base now and new
releases ship with an initial etcupdate database that matches the release
ISOs).

The (completely untested) process might go something like this:

Before your next freebsd-update run, ensure etcupdate is setup:

1) See if etcupdate already works by running 'etcupdate diff' and seeing if
   you get a sane diff.  If you get a nice diff (without lots of noise like
   $FreeBSD$ changes), skip to step 3.

2) Ensure you have an up-to-date source tree with your current world.
   Run 'etcupdate extract'.  'etcupdate diff' should now give you a
   reasonable diff of your changes to /etc files.  (Note that it does not
   show "new" files like /etc/fstab, just changes to files installed by
   a clean install.)

3) Review the output of 'etcupdate diff'.  If there are local changes that
   are not correct, you can edit the files in /etc to reduce the diffs.
   If you want to restore a file to its original state, you can use
   'cp /var/db/etcupdate/current/etc/<foo> /etc/<foo>' (I will someday add
   an 'etcupdate revert' command for this)

4) Ensure that freebsd-update is set to update your source tree on each
   update and to not do any /etc merges

After your next run of 'freebsd-update', run 'etcupdate' to merge in any
changes to '/etc'.  It can generally cope with simple merges similar to
'svn up'.  If it encounters a conflict, it saves off a copy of the file
with conflict markers for you to resolve via 'etcupdate resolve' but leaves
the "old" file in /etc untouched until you resolve the conflict.

-- 
John Baldwin



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