148 lines
4.8 KiB
Diff
148 lines
4.8 KiB
Diff
From 68f29ab490cf987aa34b5f4caf1784b58a021308 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: Pending
|
|
|
|
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 d3deb6a..cf8bf2c 100644
|
|
--- a/logrotate.c
|
|
+++ b/logrotate.c
|
|
@@ -1157,6 +1157,53 @@ int findNeedRotating(struct logInfo *log, int logNum, int force)
|
|
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;
|
|
+}
|
|
+
|
|
int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
struct logNames *rotNames)
|
|
{
|
|
@@ -1523,15 +1570,15 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
}
|
|
|
|
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;
|
|
}
|
|
@@ -1669,21 +1716,21 @@ int rotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
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;
|
|
}
|
|
}
|
|
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], tmpFilename,
|
|
strerror(errno));
|
|
hasErrors = 1;
|
|
@@ -2063,7 +2110,7 @@ int rotateLogSet(struct logInfo *log, int force)
|
|
return hasErrors;
|
|
}
|
|
|
|
-static int writeState(char *stateFilename)
|
|
+static int writeState(struct logInfo *log, char *stateFilename)
|
|
{
|
|
struct logState *p;
|
|
FILE *f;
|
|
@@ -2227,7 +2274,7 @@ static int writeState(char *stateFilename)
|
|
fclose(f);
|
|
|
|
if (error == 0) {
|
|
- if (rename(tmpFilename, stateFilename)) {
|
|
+ if (mvFile(tmpFilename, stateFilename, log, prev_acl)) {
|
|
unlink(tmpFilename);
|
|
error = 1;
|
|
message(MESS_ERROR, "error renaming temp state file %s\n",
|
|
@@ -2525,7 +2572,7 @@ int main(int argc, const char **argv)
|
|
rc |= rotateLogSet(log, force);
|
|
|
|
if (!debug)
|
|
- rc |= writeState(stateFile);
|
|
+ rc |= writeState(log, stateFile);
|
|
|
|
return (rc != 0);
|
|
}
|