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>