blob: 671fce4ac850b8b24ec568ef4e547230949208b2 [file] [log] [blame]
Andrew Geissler635e0e42020-08-21 15:58:33 -05001From 17d57a2a923a4af53c8910a9999aebeab3f5d83a 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>
Andrew Geissler4b740dc2020-05-05 08:54:39 -050012
Patrick Williamsc124f4f2015-09-15 14:41:29 -050013---
Brad Bishop19323692019-04-05 15:28:33 -040014 logrotate.c | 71 ++++++++++++++++++++++++++++++++++++++++++++---------
15 1 file changed, 59 insertions(+), 12 deletions(-)
Patrick Williamsc124f4f2015-09-15 14:41:29 -050016
17diff --git a/logrotate.c b/logrotate.c
Andrew Geissler635e0e42020-08-21 15:58:33 -050018index 45b3eb6..231371a 100644
Patrick Williamsc124f4f2015-09-15 14:41:29 -050019--- a/logrotate.c
20+++ b/logrotate.c
Andrew Geissler635e0e42020-08-21 15:58:33 -050021@@ -1463,6 +1463,53 @@ static int findNeedRotating(const struct logInfo *log, unsigned logNum, int forc
Patrick Williamsc124f4f2015-09-15 14:41:29 -050022 return 0;
23 }
24
25+/* Act as the "mv" command, if rename failed, then read the old file and
26+ * write to new file. The function which invokes the mvFile will use
27+ * the strerror(errorno) to handle the error message, so we don't have
28+ * to print the error message here */
29+
30+int mvFile (char *oldName, char *newName, struct logInfo *log, acl_type acl)
31+{
32+ struct stat sbprev;
33+ int fd_old, fd_new, n;
34+ char buf[BUFSIZ];
35+
36+ /* Do the rename first */
37+ if (!rename(oldName, newName))
38+ return 0;
39+
40+ /* If the errno is EXDEV, then read old file, write newfile and
41+ * remove the oldfile */
42+ if (errno == EXDEV) {
43+ /* Open the old file to read */
44+ if ((fd_old = open(oldName, O_RDONLY)) < 0)
45+ return 1;
46+
47+ /* Create the file to write, keep the same attribute as the old file */
48+ if (stat(oldName, &sbprev))
49+ return 1;
50+ else {
51+ if ((fd_new = createOutputFile(newName,
52+ O_WRONLY | O_CREAT | O_TRUNC, &sbprev, acl, 0)) < 0 )
53+ return 1;
54+ }
55+
56+ /* Read and write */
57+ while ((n = read(fd_old, buf, BUFSIZ)) > 0)
58+ if (write(fd_new, buf, n) != n)
59+ return 1;
60+
61+ if ((close(fd_old) < 0) ||
62+ removeLogFile(oldName, log) ||
63+ (close(fd_new) < 0))
64+ return 1;
65+
66+ return 0;
67+ }
68+
69+ return 1;
70+}
71+
Brad Bishop19323692019-04-05 15:28:33 -040072 /* find the rotated file with the highest index */
73 static int findLastRotated(const struct logNames *rotNames,
74 const char *fileext, const char *compext)
Andrew Geissler635e0e42020-08-21 15:58:33 -050075@@ -1958,15 +2005,15 @@ static int prerotateSingleLog(const struct logInfo *log, unsigned logNum,
Brad Bishop19323692019-04-05 15:28:33 -040076 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -050077
Brad Bishop19323692019-04-05 15:28:33 -040078 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);
Patrick Williamsc124f4f2015-09-15 14:41:29 -050082
Brad Bishop19323692019-04-05 15:28:33 -040083- 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 }
Andrew Geissler635e0e42020-08-21 15:58:33 -050094@@ -2051,10 +2098,10 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
Brad Bishop19323692019-04-05 15:28:33 -040095 return 1;
96 }
Patrick Williamsc124f4f2015-09-15 14:41:29 -050097
Brad Bishop19323692019-04-05 15:28:33 -040098- 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;
Andrew Geissler635e0e42020-08-21 15:58:33 -0500108@@ -2063,11 +2110,11 @@ static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
Andrew Geissler4b740dc2020-05-05 08:54:39 -0500109 free(tmpFilename);
Brad Bishop19323692019-04-05 15:28:33 -0400110 }
111 else {
112- message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
113+ message(MESS_DEBUG, "moving %s to %s\n", log->files[logNum],
114 rotNames->finalName);
115 if (!debug && !hasErrors &&
116- rename(log->files[logNum], rotNames->finalName)) {
117- message(MESS_ERROR, "failed to rename %s to %s: %s\n",
118+ mvFile(log->files[logNum], rotNames->finalName, log, prev_acl)) {
119+ message(MESS_ERROR, "failed to move %s to %s: %s\n",
120 log->files[logNum], rotNames->finalName,
121 strerror(errno));
122 hasErrors = 1;
Andrew Geissler635e0e42020-08-21 15:58:33 -0500123@@ -2480,7 +2527,7 @@ static int rotateLogSet(const struct logInfo *log, int force)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500124 return hasErrors;
125 }
126
Brad Bishopd7bf8c12018-02-25 22:55:05 -0500127-static int writeState(const char *stateFilename)
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500128+static int writeState(struct logInfo *log, char *stateFilename)
129 {
Brad Bishop19323692019-04-05 15:28:33 -0400130 struct logState *p;
131 FILE *f;
Andrew Geissler635e0e42020-08-21 15:58:33 -0500132@@ -2659,7 +2706,7 @@ static int writeState(const char *stateFilename)
Brad Bishop19323692019-04-05 15:28:33 -0400133 fclose(f);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500134
Brad Bishop19323692019-04-05 15:28:33 -0400135 if (error == 0) {
136- if (rename(tmpFilename, stateFilename)) {
137+ if (mvFile(tmpFilename, stateFilename, log, prev_acl)) {
Andrew Geissler635e0e42020-08-21 15:58:33 -0500138 message(MESS_ERROR, "error renaming temp state file %s to %s: %s\n",
139 tmpFilename, stateFilename, strerror(errno));
Brad Bishop19323692019-04-05 15:28:33 -0400140 unlink(tmpFilename);
Andrew Geissler635e0e42020-08-21 15:58:33 -0500141@@ -3073,7 +3120,7 @@ int main(int argc, const char **argv)
Brad Bishop19323692019-04-05 15:28:33 -0400142 rc |= rotateLogSet(log, force);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500143
Brad Bishop19323692019-04-05 15:28:33 -0400144 if (!debug)
145- rc |= writeState(stateFile);
146+ rc |= writeState(log, stateFile);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500147
Brad Bishop19323692019-04-05 15:28:33 -0400148 return (rc != 0);
Patrick Williamsc124f4f2015-09-15 14:41:29 -0500149 }