#6 Schedule interrupted cache update for the next boot, instead of blocking system reboot/shutdown
Closed 4 years ago by nforro. Opened 4 years ago by nforro.

file modified
+5 -4
@@ -1,14 +1,15 @@ 

  [Unit]

- DefaultDependencies=no

  After=local-fs.target

- Before=reboot.target shutdown.target halt.target

- JobTimeoutSec=15min

  

  [Service]

  Type=oneshot

- TimeoutStartSec=infinity

  Environment=MAN_NO_LOCALE_WARNING=1

  EnvironmentFile=/etc/sysconfig/man-db

  ExecStart=/bin/sh -c '[ "$SERVICE" != "no" ] && /usr/bin/mandb $OPTS || true'

+ ExecStartPost=/usr/bin/systemctl disable man-db-restart-cache-update.service

+ ExecStopPost=/bin/sh -c '[ "$SERVICE_RESULT" == "signal" ] && /usr/bin/systemctl enable man-db-restart-cache-update.service || true'

  Nice=19

  IOWeight=20

+ 

+ [Install]

+ WantedBy=multi-user.target

@@ -0,0 +1,10 @@ 

+ [Unit]

+ Before=multi-user.target

+ 

+ [Service]

+ Type=oneshot

+ ExecStartPre=/usr/bin/rm -rf /var/cache/man/*

+ ExecStart=/usr/bin/systemd-run /usr/bin/systemctl start man-db-cache-update.service

+ 

+ [Install]

+ WantedBy=multi-user.target

file modified
+10 -2
@@ -4,7 +4,7 @@ 

  Summary: Tools for searching and reading man pages

  Name: man-db

  Version: 2.8.7

- Release: 1%{?dist}

+ Release: 2%{?dist}

  # GPLv2+ .. man-db

  # GPLv3+ .. gnulib

  License: GPLv2+ and GPLv3+
@@ -14,6 +14,7 @@ 

  Source1: man-db.crondaily

  Source2: man-db.sysconfig

  Source3: man-db-cache-update.service

+ Source4: man-db-restart-cache-update.service

  Patch0: man-db-2.8.3-change-owner-of-man-cache.patch

  

  # http://lists.nongnu.org/archive/html/man-db-devel/2017-01/msg00013.html
@@ -91,8 +92,9 @@ 

  # config for tmpfiles.d

  install -D -p -m 0644 init/systemd/man-db.conf $RPM_BUILD_ROOT/usr/lib/tmpfiles.d/.

  

- # man-db-cache-update.service

+ # man-db-cache-update.service and man-db-restart-cache-update.service

  install -D -p -m 0644 %{SOURCE3} $RPM_BUILD_ROOT%{_unitdir}/man-db-cache-update.service

+ install -D -p -m 0644 %{SOURCE4} $RPM_BUILD_ROOT%{_unitdir}/man-db-restart-cache-update.service

  

  %find_lang %{name}

  %find_lang %{name}-gnulib
@@ -131,6 +133,7 @@ 

  %config(noreplace) %{_sysconfdir}/sysconfig/man-db

  %config(noreplace) %{_tmpfilesdir}/man-db.conf

  %{_unitdir}/man-db-cache-update.service

+ %{_unitdir}/man-db-restart-cache-update.service

  %{_sbindir}/accessdb

  %{_bindir}/man

  %{_bindir}/whatis
@@ -178,6 +181,11 @@ 

  %config(noreplace) %{_sysconfdir}/cron.daily/man-db.cron

  

  %changelog

+ * Fri Sep 27 2019 Nikola Forró <nforro@redhat.com> - 2.8.7-2

+ - schedule interrupted cache update for the next boot, instead of blocking

+   system reboot/shutdown

+   resolves #1678464

+ 

  * Fri Aug 30 2019 Nikola Forró <nforro@redhat.com> - 2.8.7-1

  - update to 2.8.7

    resolves #1747042

If man-db-cache-update service is interrupted by a signal (reboot/shutdown), it enables man-db-restart-cache-update, to ensure it will run again on the next boot.

1 new commit added

  • make sure the scheduled cache update doesn't block boot
4 years ago

Pull-Request has been closed by nforro

4 years ago

This is piling another workaround on top of an existing hack. I know I suggested the original version of this hack, so I'm guilty too ;), but let's solve this properly. Doing full parsing of all man pages every time one of them is updates is just too expensive. Also, making the mandb call asynchronous makes it necessary to retry (e.g. if the machine is rebooted too quickly), and makes the whole thing much more complicated. It is also always possible to schedule this job at inopportune time, taking 100% CPU for a few minutes.

Let's just do the minimum amount of work necessary, synchronously:

  1. Add mode where mandb adds to the database. mandb has -f switch, but that disables database creation. A new switch like that is needed, that does not disable -c. Let's call it --update-path.
  2. It must be also possible to remove existing paths. It would be simplest if --update-path also accepted a filename of a removed man page, and would simply remove this path from the database.
  3. Add scriptlets:
%transfiletriggerun -- /usr/share/man/
mkdir -p "%{_localstatedir}/lib/rpm-state/man"
cat >"%{_localstatedir}/lib/rpm-state/man/uninstalled"

%transfiletriggerin -- /usr/share/man/
mkdir -p "%{_localstatedir}/lib/rpm-state/man"
cat >"%{_localstatedir}/lib/rpm-state/man/installed"
mandb --update-path $(cat "%{_localstatedir}/lib/rpm-state/man/uninstalled" "%{_localstatedir}/lib/rpm-state/man/installed"|sort -u)
rm -r "%{_localstatedir}/lib/rpm-state/man"

This is a POC and obviously untested, but I think this approach is much better. There is a list of uninstalled paths, and a list of installed paths. Some files might be on both. But mandb knows exactly which paths were touched and need to be adjusted.

Thanks, your suggestion is much better. I'll see what I can do about mandb.