summaryrefslogtreecommitdiffstats
path: root/meta/recipes-extended/logrotate/logrotate/act-as-mv-when-rotate.patch
blob: 4efd47190611c8c3db8c28b6dc4c3b4f2978a09f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
From 17d57a2a923a4af53c8910a9999aebeab3f5d83a Mon Sep 17 00:00:00 2001
From: Robert Yang <liezhi.yang@windriver.com>
Date: Tue, 17 Feb 2015 21:08:07 -0800
Subject: [PATCH] Act as the "mv" command when rotate log

Act as the "mv" command when rotate log, first rename, if failed, then
read and write.

Upstream-Status: Inappropriate [needs a rework according to https://github.com/logrotate/logrotate/pull/429]

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>

---
 logrotate.c | 71 ++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 59 insertions(+), 12 deletions(-)

diff --git a/logrotate.c b/logrotate.c
index 45b3eb6..231371a 100644
--- a/logrotate.c
+++ b/logrotate.c
@@ -1463,6 +1463,53 @@ static int findNeedRotating(const struct logInfo *log, unsigned logNum, int forc
     return 0;
 }
 
+/* Act as the "mv" command, if rename failed, then read the old file and
+ * write to new file. The function which invokes the mvFile will use
+ * the strerror(errorno) to handle the error message, so we don't have
+ * to print the error message here */
+
+int mvFile (char *oldName, char *newName, struct logInfo *log, acl_type acl)
+{
+    struct stat sbprev;
+    int fd_old, fd_new, n;
+    char buf[BUFSIZ];
+
+    /* Do the rename first */
+    if (!rename(oldName, newName))
+        return 0;
+
+    /* If the errno is EXDEV, then read old file, write newfile and
+     * remove the oldfile */
+    if (errno == EXDEV) {
+        /* Open the old file to read */
+        if ((fd_old = open(oldName, O_RDONLY)) < 0)
+            return 1;
+
+        /* Create the file to write, keep the same attribute as the old file */
+        if (stat(oldName, &sbprev))
+            return 1;
+        else {
+            if ((fd_new = createOutputFile(newName,
+                O_WRONLY | O_CREAT | O_TRUNC, &sbprev, acl, 0)) < 0 )
+                return 1;
+        }
+
+        /* Read and write */
+        while ((n = read(fd_old, buf, BUFSIZ)) > 0)
+            if (write(fd_new, buf, n) != n)
+                return 1;
+
+        if ((close(fd_old) < 0) ||
+            removeLogFile(oldName, log) ||
+            (close(fd_new) < 0))
+            return 1;
+
+        return 0;
+    }
+
+    return 1;
+}
+
 /* find the rotated file with the highest index */
 static int findLastRotated(const struct logNames *rotNames,
                            const char *fileext, const char *compext)
@@ -1958,15 +2005,15 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
             }
 
             message(MESS_DEBUG,
-                    "renaming %s to %s (rotatecount %d, logstart %d, i %d), \n",
+                    "moving %s to %s (rotatecount %d, logstart %d, i %d), \n",
                     oldName, newName, rotateCount, logStart, i);
 
-            if (!debug && rename(oldName, newName)) {
+            if (!debug && mvFile(oldName, newName, log, prev_acl)) {
                 if (errno == ENOENT) {
                     message(MESS_DEBUG, "old log %s does not exist\n",
                             oldName);
                 } else {
-                    message(MESS_ERROR, "error renaming %s to %s: %s\n",
+                    message(MESS_ERROR, "error moving %s to %s: %s\n",
                             oldName, newName, strerror(errno));
                     hasErrors = 1;
                 }
@@ -2051,10 +2098,10 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
                     return 1;
                 }
 
-                message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
+                message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
                         tmpFilename);
-                if (!debug && !hasErrors && rename(log->files[logNum], tmpFilename)) {
-                    message(MESS_ERROR, "failed to rename %s to %s: %s\n",
+                if (!debug && !hasErrors && mvFile(log->files[logNum], rotNames->finalName, log, prev_acl)) {
+                    message(MESS_ERROR, "failed to move %s to %s: %s\n",
                             log->files[logNum], tmpFilename,
                             strerror(errno));
                     hasErrors = 1;
@@ -2063,11 +2110,11 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
                 free(tmpFilename);
             }
             else {
-                message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
+                message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
                         rotNames->finalName);
                 if (!debug && !hasErrors &&
-                        rename(log->files[logNum], rotNames->finalName)) {
-                    message(MESS_ERROR, "failed to rename %s to %s: %s\n",
+                        mvFile(log->files[logNum], rotNames->finalName, log, prev_acl)) {
+                    message(MESS_ERROR, "failed to move %s to %s: %s\n",
                             log->files[logNum], rotNames->finalName,
                             strerror(errno));
                     hasErrors = 1;
@@ -2480,7 +2527,7 @@ static int rotateLogSet(const struct logInfo *log, int force)
     return hasErrors;
 }
 
-static int writeState(const char *stateFilename)
+static int writeState(struct logInfo *log, char *stateFilename)
 {
     struct logState *p;
     FILE *f;
@@ -2659,7 +2706,7 @@ static int writeState(const char *stateFilename)
         fclose(f);
 
     if (error == 0) {
-        if (rename(tmpFilename, stateFilename)) {
+        if (mvFile(tmpFilename, stateFilename, log, prev_acl)) {
             message(MESS_ERROR, "error renaming temp state file %s to %s: %s\n",
                     tmpFilename, stateFilename, strerror(errno));
             unlink(tmpFilename);
@@ -3073,7 +3120,7 @@ int main(int argc, const char **argv)
         rc |= rotateLogSet(log, force);
 
     if (!debug)
-        rc |= writeState(stateFile);
+        rc |= writeState(log, stateFile);
 
     return (rc != 0);
 }