108 lines
3.4 KiB
Diff
108 lines
3.4 KiB
Diff
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 | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++------
|
|
1 files changed, 53 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/logrotate.c b/logrotate.c
|
|
index 537e8d6..b04482f 100644
|
|
--- a/logrotate.c
|
|
+++ b/logrotate.c
|
|
@@ -808,6 +808,53 @@ int findNeedRotating(struct logInfo *log, int logNum)
|
|
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)
|
|
+{
|
|
+ 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)) < 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)
|
|
{
|
|
@@ -1148,15 +1195,15 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
rotNames->baseName, i, fileext, compext);
|
|
|
|
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)) {
|
|
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;
|
|
}
|
|
@@ -1286,11 +1333,11 @@ int rotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
}
|
|
}
|
|
#endif /* WITH_ACL */
|
|
- 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)) {
|
|
+ message(MESS_ERROR, "failed to move %s to %s: %s\n",
|
|
log->files[logNum], rotNames->finalName,
|
|
strerror(errno));
|
|
hasErrors = 1;
|
|
--
|
|
1.7.4.1
|
|
|