From 758760a3610e3c6674de8a1d51b12b991eafef7c Mon Sep 17 00:00:00 2001
From: Mike Yuan <me@yhndnzj.com>
Date: Wed, 5 Jun 2024 17:53:27 +0200
Subject: [PATCH] shutdown: clean up sync_with_progress a bit

Also, ignore the error on caller's side.

Conflict:context adaption.
Reference:https://github.com/systemd/systemd/commit/758760a3610e3c6674de8a1d51b12b991eafef7c

---
 src/shutdown/shutdown.c | 67 ++++++++++++++++++-----------------------
 1 file changed, 29 insertions(+), 38 deletions(-)

diff --git a/src/shutdown/shutdown.c b/src/shutdown/shutdown.c
index 46f22cfc..8e11e353 100644
--- a/src/shutdown/shutdown.c
+++ b/src/shutdown/shutdown.c
@@ -188,7 +188,9 @@ static int switch_root_initramfs(void) {
 static int sync_making_progress(unsigned long long *prev_dirty) {
         _cleanup_fclose_ FILE *f = NULL;
         unsigned long long val = 0;
-        int ret;
+        int r;
+
+        assert(prev_dirty);
 
         f = fopen("/proc/meminfo", "re");
         if (!f)
@@ -196,13 +198,12 @@ static int sync_making_progress(unsigned long long *prev_dirty) {
 
         for (;;) {
                 _cleanup_free_ char *line = NULL;
-                unsigned long long ull = 0;
-                int q;
+                unsigned long long ull;
 
-                q = read_line(f, LONG_LINE_MAX, &line);
-                if (q < 0)
-                        return log_warning_errno(q, "Failed to parse /proc/meminfo: %m");
-                if (q == 0)
+                r = read_line(f, LONG_LINE_MAX, &line);
+                if (r < 0)
+                        return log_warning_errno(r, "Failed to parse /proc/meminfo: %m");
+                if (r == 0)
                         break;
 
                 if (!first_word(line, "NFS_Unstable:") && !first_word(line, "Writeback:") && !first_word(line, "Dirty:"))
@@ -210,25 +211,20 @@ static int sync_making_progress(unsigned long long *prev_dirty) {
 
                 errno = 0;
                 if (sscanf(line, "%*s %llu %*s", &ull) != 1) {
-                        if (errno != 0)
-                                log_warning_errno(errno, "Failed to parse /proc/meminfo: %m");
-                        else
-                                log_warning("Failed to parse /proc/meminfo");
-
+                        log_warning_errno(errno_or_else(EIO), "Failed to parse /proc/meminfo field, ignoring: %m");
                         return false;
                 }
 
                 val += ull;
         }
 
-        ret = *prev_dirty > val;
+        r = *prev_dirty > val;
         *prev_dirty = val;
-        return ret;
+        return r;
 }
 
-static void sync_with_progress(void) {
+static int sync_with_progress(void) {
         unsigned long long dirty = ULLONG_MAX;
-        unsigned checks;
         pid_t pid;
         int r;
 
@@ -238,37 +234,32 @@ static void sync_with_progress(void) {
          * the progress. If the timeout lapses, the assumption is that the particular sync stalled. */
 
         r = asynchronous_sync(&pid);
-        if (r < 0) {
-                log_error_errno(r, "Failed to fork sync(): %m");
-                return;
-        }
+        if (r < 0)
+                return log_error_errno(r, "Failed to fork sync(): %m");
 
         log_info("Syncing filesystems and block devices.");
 
         /* Start monitoring the sync operation. If more than
          * SYNC_PROGRESS_ATTEMPTS lapse without progress being made,
          * we assume that the sync is stalled */
-        for (checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) {
+        for (unsigned checks = 0; checks < SYNC_PROGRESS_ATTEMPTS; checks++) {
                 r = wait_for_terminate_with_timeout(pid, SYNC_TIMEOUT_USEC);
                 if (r == 0)
-                        /* Sync finished without error.
-                         * (The sync itself does not return an error code) */
-                        return;
-                else if (r == -ETIMEDOUT) {
-                        /* Reset the check counter if the "Dirty" value is
-                         * decreasing */
-                        if (sync_making_progress(&dirty) > 0)
-                                checks = 0;
-                } else {
-                        log_error_errno(r, "Failed to sync filesystems and block devices: %m");
-                        return;
-                }
+                        /* Sync finished without error (sync() call itself does not return an error code) */
+                        return 0;
+                if (r != -ETIMEDOUT)
+                        return log_error_errno(r, "Failed to sync filesystems and block devices: %m");
+
+                /* Reset the check counter if we made some progress */
+                if (sync_making_progress(&dirty) > 0)
+                        checks = 0;
         }
 
-        /* Only reached in the event of a timeout. We should issue a kill
-         * to the stray process. */
-        log_error("Syncing filesystems and block devices - timed out, issuing SIGKILL to PID "PID_FMT".", pid);
+        /* Only reached in the event of a timeout. We should issue a kill to the stray process. */
         (void) kill(pid, SIGKILL);
+        return log_error_errno(SYNTHETIC_ERRNO(ETIMEDOUT),
+                               "Syncing filesystems and block devices - timed out, issuing SIGKILL to PID "PID_FMT".",
+                               pid);
 }
 
 static int read_current_sysctl_printk_log_level(void) {
@@ -436,7 +427,7 @@ int main(int argc, char *argv[]) {
          * desperately trying to sync IO to disk within their timeout. Do not remove this sync, data corruption will
          * result. */
         if (!in_container)
-                sync_with_progress();
+                (void) sync_with_progress();
 
         disable_coredumps();
         disable_binfmt();
@@ -604,7 +595,7 @@ int main(int argc, char *argv[]) {
          * which might have caused IO, hence let's do it once more. Do not remove this sync, data corruption
          * will result. */
         if (!in_container)
-                sync_with_progress();
+                (void) sync_with_progress();
 
         /* This is primarily useful when running systemd in a VM, as it provides the user running the VM with
          * a mechanism to pick up systemd's exit status in the VM. */
-- 
2.43.0

