From 224b51420b0e3b62cda4bb16f31c6d28e96c7123 Mon Sep 17 00:00:00 2001
From: sunshihao <sunshihao@huawei.com>
Date: Mon, 25 Jan 2021 14:42:23 +0800
Subject: [PATCH] fuser: print umount info to /.reboot-umount-msg.log

The patch tries to save which processes holds the mountpoint
persistently to /.reboot-umount-msg.log, when the system is
suspended during system restart.

This patch change the value of DefaultDFXReboot that is set in
/etc/systemd/system.conf file from no to yes.The systemd reboot
feature will open when the process start.

Signed-off-by: sunshihao <sunshihao@huawei.com>
Signed-off-by: Zhiqiang Liu <liuzhiqiang26@huawei.com>
Signed-off-by: lixiaokeng <lixiaokeng@huawei.com>
---
 src/core/fuser.c        | 57 +++++++++++++++++++++++++++++++++++++----
 src/core/fuser.h        |  3 +++
 src/core/job.c          | 38 +++++++++++++++++++++++++++
 src/core/system.conf.in |  2 +-
 4 files changed, 94 insertions(+), 6 deletions(-)

diff --git a/src/core/fuser.c b/src/core/fuser.c
index e943469..94a0812 100644
--- a/src/core/fuser.c
+++ b/src/core/fuser.c
@@ -383,6 +383,8 @@ static void print_matches(const struct name *name) {
         static char P_cmd_long[MAX_COMM_LEN];
         char cmd_path[PATH_MAX];
         int r = 0;
+        FILE *fp = NULL;
+        int flag = 0;
 
         if (name == NULL) {
                 manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
@@ -390,11 +392,29 @@ static void print_matches(const struct name *name) {
                 return;
         }
 
+        /* Write the content in the back of previous one */
+        fp = fopen(REBOOT_UMOUNT_FILE_NAME, "a+");
+
+        /* print the time info to /.reboot-umount-msg.log file */
+        if (fp == NULL) {
+                manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
+                        "Open %s failed!", REBOOT_UMOUNT_FILE_NAME);
+        }
+
         manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                 "\t\tUSER\t\tPID\tCOMMAND");
         manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                 "%s:", name->filename);
 
+        /* print the umount fail point to the /.reboot-umount-msg.log file */
+        if (fp != NULL) {
+                if (strlen(name->filename) <= MOUNT_FILE_NAME_MAX_LEN) {
+                        fprintf(fp, "%-20s\t", name->filename);
+                } else {
+                        fprintf(fp, "%s\n\t\t\t", name->filename);
+                }
+        }
+
         for (pptr = name->matched_procs; pptr != NULL; pptr = pptr->next) {
                 if (pwent == NULL || pwent->pw_uid != pptr->uid)
                         pwent = getpwuid(pptr->uid); //get username
@@ -402,7 +422,7 @@ static void print_matches(const struct name *name) {
                 r = snprintf(cmd_path, sizeof(cmd_path), "/proc/%d", pptr->pid);
                 if (r <= 0) {
                         manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL, "Can't snprintf /proc/%d.", pptr->pid);
-                        return;
+                        goto out;
                 }
 
                 read_cmdline(P_cmd_long, sizeof(P_cmd_long), cmd_path, "cmdline", ' ');
@@ -415,22 +435,49 @@ static void print_matches(const struct name *name) {
                 if (pptr->command == NULL)
                         continue;
 
+                if (flag > 0) {
+                        if (fp != NULL) {
+                                fprintf(fp, "\t\t\t");
+                        }
+                } else {
+                        flag++;
+                }
+
                 if (pwent != NULL) {
-                        if (pptr->pid != 0)
+                        if (pptr->pid != 0) {
                                 manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                                         "\t\t%-s\t\t%-d\t%-s", pwent->pw_name, pptr->pid, pptr->command);
-                        else
+                                if (fp != NULL) {
+                                        fprintf(fp, "%-s\t\t%-d\t%-s\n", pwent->pw_name, pptr->pid, pptr->command);
+                                }
+                        } else {
                                 manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                                         "\t\t%-s\t\t%-s\t%-s", pwent->pw_name, "kernel", pptr->command);
+                                if (fp != NULL) {
+                                        fprintf(fp, "%-s\t\t%-s\t%-s\n", pwent->pw_name, "kernel", pptr->command);
+                                }
+                        }
                 } else {
-                        if (pptr->pid != 0)
+                        if (pptr->pid != 0) {
                                 manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                                         "\t\t%-u\t\t%-d\t%-s", pptr->uid, pptr->pid, pptr->command);
-                        else
+                                if (fp != NULL) {
+                                        fprintf(fp, "%-u\t\t%-d\t%-s\n", pptr->uid, pptr->pid, pptr->command);
+                                }
+                        } else {
                                 manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
                                       "\t\t%-u\t\t%-s\t%-s", pptr->uid, "kernel", pptr->command);
+                                if (fp != NULL) {
+                                        fprintf(fp, "%-u\t\t%-s\t%-s\n", pptr->uid, "kernel", pptr->command);
+                                }
+                        }
                 }
         }
+
+out:
+        if (fp != NULL) {
+                fclose(fp);
+        }
 }
 
 static void free_matched_procs(struct procs *matched_procs) {
diff --git a/src/core/fuser.h b/src/core/fuser.h
index b74b879..2729c9b 100644
--- a/src/core/fuser.h
+++ b/src/core/fuser.h
@@ -14,6 +14,7 @@
 #include <string.h>
 #include <limits.h>
 #include <errno.h>
+#include <time.h>
 
 #include "manager.h"
 
@@ -51,5 +52,7 @@ struct device {
 #define MAX_COMM_LEN 1024
 #define PROC_MOUNTS "/proc/mounts"
 #define PROC_SWAPS "/proc/swaps"
+#define REBOOT_UMOUNT_FILE_NAME "/.reboot-umount-msg.log"
+#define MOUNT_FILE_NAME_MAX_LEN 20
 
 int fuser(const char *dir);
diff --git a/src/core/job.c b/src/core/job.c
index 34513bc..73c992a 100644
--- a/src/core/job.c
+++ b/src/core/job.c
@@ -31,6 +31,8 @@
 #include "mount.h"
 #include "process-util.h"
 
+bool g_first_print = true;
+
 Job* job_new_raw(Unit *unit) {
         Job *j;
 
@@ -734,6 +736,9 @@ static void job_emit_done_message(Unit *u, uint32_t job_id, JobType t, JobResult
         const char *ident, *format;
         int r = 0;
         pid_t pid;
+        FILE *fp = NULL;
+        time_t tmpt;
+        struct tm local_time;
 
         assert(u);
         assert(t >= 0);
@@ -835,6 +840,39 @@ static void job_emit_done_message(Unit *u, uint32_t job_id, JobType t, JobResult
                 ((u->type == UNIT_MOUNT || u->type == UNIT_AUTOMOUNT) && t == JOB_STOP && result == JOB_FAILED)) {
 
                 Mount *m = MOUNT(u);
+                if (g_first_print) {
+                        /* Overwrite previous content at the first time */
+                        fp = fopen(REBOOT_UMOUNT_FILE_NAME, "w+");
+
+                        /* Only get the local time once */
+                        tmpt = time(NULL);
+                        if (!localtime_r(&tmpt, &local_time)) {
+                                manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
+                                    "Get local time failed!");
+                        }
+                }
+
+                /* print the time info to /.reboot-umount-msg.log file */
+                if (g_first_print && fp == NULL) {
+                        manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
+                                "Open %s failed!", REBOOT_UMOUNT_FILE_NAME);
+                } else if (g_first_print) {
+                        /* Only do this part one time */
+                        g_first_print = false;
+
+                        if (chmod(REBOOT_UMOUNT_FILE_NAME, S_IRUSR | S_IWUSR)) {
+                                manager_status_printf(NULL, STATUS_TYPE_NORMAL, NULL,
+                                    "Set %s file attributes failed!", REBOOT_UMOUNT_FILE_NAME);
+                        }
+
+                        fprintf(fp, "reboot time is %d/%d/%d-%d:%d:%d.\n", local_time.tm_year + 1900,
+                                local_time.tm_mon + 1, local_time.tm_mday, local_time.tm_hour,
+                                local_time.tm_min, local_time.tm_sec);
+
+                        fprintf(fp, "\n\t\t\tUSER\t\tPID\tCOMMAND\n");
+                        fclose(fp);
+                }
+
 
                 r = safe_fork("(fuser-shutdown)", FORK_RESET_SIGNALS, &pid);
                 if (r < 0) {
diff --git a/src/core/system.conf.in b/src/core/system.conf.in
index 3495b8e..74a25ce 100644
--- a/src/core/system.conf.in
+++ b/src/core/system.conf.in
@@ -80,7 +80,7 @@ DefaultLimitMEMLOCK=64M
 #DefaultMemoryPressureThresholdSec=200ms
 #DefaultMemoryPressureWatch=auto
 #DefaultOOMPolicy=stop
-#DefaultDFXReboot=no
+DefaultDFXReboot=yes
 #DefaultSmackProcessLabel=
 #ReloadLimitIntervalSec=
 #ReloadLimitBurst=
-- 
2.33.0

