Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 04 Oct 2022 16:25:53 +0000
From:      bugzilla-noreply@freebsd.org
To:        bugs@FreeBSD.org
Subject:   [Bug 263879] pkgbase removes critical etc files upon upgrade
Message-ID:  <bug-263879-227-eAbYj0CWrw@https.bugs.freebsd.org/bugzilla/>
In-Reply-To: <bug-263879-227@https.bugs.freebsd.org/bugzilla/>
References:  <bug-263879-227@https.bugs.freebsd.org/bugzilla/>

next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D263879

--- Comment #4 from Mark Johnston <markj@FreeBSD.org> ---
I spent some time reading the libpkg job scheduler and I think I see part of
the problem, but I'm not sure yet how to fix it.

Basically, upon an upgrade I get a conflict on /etc/termcap.small between
FreeBSD-runtime(local) and FreeBSD-utilities(remote).  When handling the
conflict, pkg decides to split the upgrade of -runtime into separate uninst=
all
and install jobs, which wipes my /etc files.  But, obviously we can avoid t=
he
conflict by simply upgrading -runtime before -utilities; the split is not
needed.  And, pkg schedules the uninstall/install of -runtime back-to-back
anyway, so it's no different from an upgrade.

After pkg has figured out which jobs (i.e. package installs/upgrades/remova=
ls)
it will execute, it assigns priorities to determine the execution order.  T=
his
happens in pkg_jobs_set_priorities().  If there's a conflict on a package b=
eing
deleted as part of an upgrade, pkg bumps the priorities of both the deletion
and the addition jobs:

 770         if (rit->priority >=3D req->items[1]->priority) {=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 771             pkg_jobs_update_universe_item_priority(universe,
req->items[1],=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 772                 rit->priority + 1, PKG_PRIORITY_UPDATE_CONFLICT);=20=
=20=20=20=20=20=20=20=20=20
 773             /*=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 774              * Update priorities for a remote part as well=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20
 775              */=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 776             pkg_jobs_update_universe_item_priority(universe,
req->items[0],=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 777                 req->items[0]->priority, PKG_PRIORITY_UPDATE_REQUEST);=
=20=20=20=20=20
 778         }

pkg_jobs_update_universe_item_priority() recursively updates the priorities=
 of
dependent jobs.  However, it also has this check which I do not quite
understand:

 668                 if ((item->next !=3D NULL || item->prev !=3D NULL) &&=
=20=20=20=20=20=20=20=20=20=20
 669                     it->pkg->type !=3D PKG_INSTALLED &&=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 670                     (type =3D=3D PKG_PRIORITY_UPDATE_CONFLICT ||=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20
 671                      type =3D=3D PKG_PRIORITY_UPDATE_DELETE)) {=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 672                         /*=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20
 673                          * We do not update priority of a remote part =
of
conflict, as we know=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 674                          * that remote packages should not contain
conflicts (they should be=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 675                          * resolved in request prior to calling of this
function)=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20
 676                          */=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20
 677                         pkg_debug(2, "skip update priority for %s-%s",=
=20=20=20=20=20
 678                             it->pkg->uid, it->pkg->digest);=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20
 679                         continue;=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=20=
=20=20=20=20=20
 680                 }

In my case, it causes installation of the remote FreeBSD-runtime to have lo=
wer
priority than removal of the local FreeBSD-runtime package.  This causes pk=
g to
split the job.  Commenting out this block "fixes" my problem, but I can't t=
ell
if it actually affects correctness of the code, or if it's just an
optimization, or...

BTW, this behaviour is highly dependent on the order in which packages are
loaded into various lists.  If I fetch packages first, then cancel the upgr=
ade,
then try to upgrade again, I get different behaviour from the job scheduler=
.=20
So it's not too surprising that others may not observe the problem.

What's an example of an upgrade where a package really does need to be spli=
t?=20
Consider two packages p1, p2 with files a and b respectively, and suppose t=
hat
new versions of those packages switch ownership, so p1 contains b and p2
contains a.  Then to upgrade, we have to uninstall one of p1 or p2, upgrade=
 the
other, then install the missing package.  This situation can arise in the b=
ase
system, so how do we handle the case where two critical pkgbase packages are
entangled this way?

--=20
You are receiving this mail because:
You are the assignee for the bug.=



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