blob: 04cb588db19f497b6c2a3d6133b5abc78a4ea70c [file] [log] [blame]
Brad Bishopd7bf8c12018-02-25 22:55:05 -05001From 517cbff66c8bdbf455bc3b7c1a85a4f990d0f9a6 Mon Sep 17 00:00:00 2001
Patrick Williamsc124f4f2015-09-15 14:41:29 -05002From: Robert Yang <liezhi.yang@windriver.com>
3Date: Tue, 17 Feb 2015 21:08:07 -0800
4Subject: [PATCH] Act as the "mv" command when rotate log
5
6Act as the "mv" command when rotate log, first rename, if failed, then
7read and write.
8
9Upstream-Status: Pending
10
11Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
12---
Brad Bishopd7bf8c12018-02-25 22:55:05 -050013 logrotate.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
14 1 file changed, 60 insertions(+), 12 deletions(-)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050015
16diff --git a/logrotate.c b/logrotate.c
Brad Bishopd7bf8c12018-02-25 22:55:05 -050017index 4ad58d4..ba05884 100644
Patrick Williamsc124f4f2015-09-15 14:41:29 -050018--- a/logrotate.c
19+++ b/logrotate.c
Brad Bishopd7bf8c12018-02-25 22:55:05 -050020@@ -1315,6 +1315,54 @@ static int findNeedRotating(struct logInfo *log, int logNum, int force)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050021 return 0;
22 }
23
24+/* Act as the "mv" command, if rename failed, then read the old file and
25+ * write to new file. The function which invokes the mvFile will use
26+ * the strerror(errorno) to handle the error message, so we don't have
27+ * to print the error message here */
28+
29+int mvFile (char *oldName, char *newName, struct logInfo *log, acl_type acl)
30+{
31+ struct stat sbprev;
32+ int fd_old, fd_new, n;
33+ char buf[BUFSIZ];
34+
35+ /* Do the rename first */
36+ if (!rename(oldName, newName))
37+ return 0;
38+
39+ /* If the errno is EXDEV, then read old file, write newfile and
40+ * remove the oldfile */
41+ if (errno == EXDEV) {
42+ /* Open the old file to read */
43+ if ((fd_old = open(oldName, O_RDONLY)) < 0)
44+ return 1;
45+
46+ /* Create the file to write, keep the same attribute as the old file */
47+ if (stat(oldName, &sbprev))
48+ return 1;
49+ else {
50+ if ((fd_new = createOutputFile(newName,
51+ O_WRONLY | O_CREAT | O_TRUNC, &sbprev, acl, 0)) < 0 )
52+ return 1;
53+ }
54+
55+ /* Read and write */
56+ while ((n = read(fd_old, buf, BUFSIZ)) > 0)
57+ if (write(fd_new, buf, n) != n)
58+ return 1;
59+
60+ if ((close(fd_old) < 0) ||
61+ removeLogFile(oldName, log) ||
62+ (close(fd_new) < 0))
63+ return 1;
64+
65+ return 0;
66+ }
67+
68+ return 1;
69+}
70+
Brad Bishopd7bf8c12018-02-25 22:55:05 -050071+
72 static int prerotateSingleLog(struct logInfo *log, int logNum,
73 struct logState *state, struct logNames *rotNames)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050074 {
Brad Bishopd7bf8c12018-02-25 22:55:05 -050075@@ -1674,15 +1722,15 @@ static int prerotateSingleLog(struct logInfo *log, int logNum,
Patrick Williamsc124f4f2015-09-15 14:41:29 -050076 }
77
78 message(MESS_DEBUG,
79- "renaming %s to %s (rotatecount %d, logstart %d, i %d), \n",
80+ "moving %s to %s (rotatecount %d, logstart %d, i %d), \n",
81 oldName, newName, rotateCount, logStart, i);
82
83- if (!debug && rename(oldName, newName)) {
84+ if (!debug && mvFile(oldName, newName, log, prev_acl)) {
85 if (errno == ENOENT) {
86 message(MESS_DEBUG, "old log %s does not exist\n",
87 oldName);
88 } else {
89- message(MESS_ERROR, "error renaming %s to %s: %s\n",
90+ message(MESS_ERROR, "error moving %s to %s: %s\n",
91 oldName, newName, strerror(errno));
92 hasErrors = 1;
93 }
Brad Bishopd7bf8c12018-02-25 22:55:05 -050094@@ -1767,21 +1815,21 @@ static int rotateSingleLog(struct logInfo *log, int logNum,
Patrick Williamsc124f4f2015-09-15 14:41:29 -050095 return 1;
96 }
97
98- message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
99+ message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
100 tmpFilename);
101- if (!debug && !hasErrors && rename(log->files[logNum], tmpFilename)) {
102- message(MESS_ERROR, "failed to rename %s to %s: %s\n",
103+ if (!debug && !hasErrors && mvFile(log->files[logNum], rotNames->finalName, log, prev_acl)) {
104+ message(MESS_ERROR, "failed to move %s to %s: %s\n",
105 log->files[logNum], tmpFilename,
106 strerror(errno));
107 hasErrors = 1;
108 }
109 }
110 else {
111- message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
112+ message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
113 rotNames->finalName);
114 if (!debug && !hasErrors &&
115- rename(log->files[logNum], rotNames->finalName)) {
116- message(MESS_ERROR, "failed to rename %s to %s: %s\n",
117+ mvFile(log->files[logNum], rotNames->finalName, log, prev_acl)) {
118+ message(MESS_ERROR, "failed to move %s to %s: %s\n",
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500119 log->files[logNum], rotNames->finalName,
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500120 strerror(errno));
121 hasErrors = 1;
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500122@@ -2170,7 +2218,7 @@ static int rotateLogSet(struct logInfo *log, int force)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500123 return hasErrors;
124 }
125
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500126-static int writeState(const char *stateFilename)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500127+static int writeState(struct logInfo *log, char *stateFilename)
128 {
129 struct logState *p;
130 FILE *f;
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500131@@ -2322,7 +2370,7 @@ static int writeState(const char *stateFilename)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500132 fclose(f);
133
134 if (error == 0) {
135- if (rename(tmpFilename, stateFilename)) {
136+ if (mvFile(tmpFilename, stateFilename, log, prev_acl)) {
137 unlink(tmpFilename);
138 error = 1;
139 message(MESS_ERROR, "error renaming temp state file %s\n",
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500140@@ -2648,7 +2696,7 @@ int main(int argc, const char **argv)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500141 rc |= rotateLogSet(log, force);
142
143 if (!debug)
144- rc |= writeState(stateFile);
145+ rc |= writeState(log, stateFile);
146
147 return (rc != 0);
148 }
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500149--
1501.8.3.1
151