Fix the issue that the pid file cannot be rewritten
This commit is contained in:
parent
27fd1b15ac
commit
280fac351f
136
backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch
Normal file
136
backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch
Normal file
@ -0,0 +1,136 @@
|
||||
From b177311aee0b3cf17af0e1760e18dfb60d99e024 Mon Sep 17 00:00:00 2001
|
||||
From: Wayne Davison <wayne@opencoder.net>
|
||||
Date: Thu, 4 Jun 2020 17:55:20 -0700
|
||||
Subject: [PATCH] Use a lock to not fail on a left-over pid file.
|
||||
|
||||
---
|
||||
clientserver.c | 62 ++++++++++++++++++++++++++++++++++++++------------
|
||||
rsyncd.conf.yo | 7 +++---
|
||||
socket.c | 3 +++
|
||||
3 files changed, 55 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/clientserver.c b/clientserver.c
|
||||
index 3af97d84..d56f5d52 100644
|
||||
--- a/clientserver.c
|
||||
+++ b/clientserver.c
|
||||
@@ -66,6 +66,7 @@ extern gid_t our_gid;
|
||||
char *auth_user;
|
||||
int read_only = 0;
|
||||
int module_id = -1;
|
||||
+int pid_file_fd = -1;
|
||||
struct chmod_mode_struct *daemon_chmod_modes;
|
||||
|
||||
/* module_dirlen is the length of the module_dir string when in daemon
|
||||
@@ -1149,26 +1150,59 @@ int start_daemon(int f_in, int f_out)
|
||||
static void create_pid_file(void)
|
||||
{
|
||||
char *pid_file = lp_pid_file();
|
||||
- char pidbuf[16];
|
||||
- pid_t pid = getpid();
|
||||
- int fd, len;
|
||||
+ char pidbuf[32];
|
||||
+ STRUCT_STAT st1, st2;
|
||||
+ char *fail = NULL;
|
||||
|
||||
if (!pid_file || !*pid_file)
|
||||
return;
|
||||
|
||||
- cleanup_set_pid(pid);
|
||||
- if ((fd = do_open(pid_file, O_WRONLY|O_CREAT|O_EXCL, 0666)) == -1) {
|
||||
- failure:
|
||||
- cleanup_set_pid(0);
|
||||
- fprintf(stderr, "failed to create pid file %s: %s\n", pid_file, strerror(errno));
|
||||
- rsyserr(FLOG, errno, "failed to create pid file %s", pid_file);
|
||||
+ /* These tests make sure that a temp-style lock dir is handled safely. */
|
||||
+ st1.st_mode = 0;
|
||||
+ if (do_lstat(pid_file, &st1) == 0 && !S_ISREG(st1.st_mode) && unlink(pid_file) < 0)
|
||||
+ fail = "unlink";
|
||||
+ else if ((pid_file_fd = do_open(pid_file, O_RDWR|O_CREAT, 0664)) < 0)
|
||||
+ fail = S_ISREG(st1.st_mode) ? "open" : "create";
|
||||
+ else if (!lock_range(pid_file_fd, 0, 4))
|
||||
+ fail = "lock";
|
||||
+ else if (do_fstat(pid_file_fd, &st1) < 0)
|
||||
+ fail = "fstat opened";
|
||||
+ else if (st1.st_size >= (int)sizeof pidbuf)
|
||||
+ fail = "find small";
|
||||
+ else if (do_lstat(pid_file, &st2) < 0)
|
||||
+ fail = "lstat";
|
||||
+ else if (!S_ISREG(st1.st_mode))
|
||||
+ fail = "avoid file overwrite race for";
|
||||
+ else if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
|
||||
+ fail = "verify stat info for";
|
||||
+#ifdef HAVE_FTRUNCATE
|
||||
+ else if (do_ftruncate(pid_file_fd, 0) < 0)
|
||||
+ fail = "truncate";
|
||||
+#endif
|
||||
+ else {
|
||||
+ pid_t pid = getpid();
|
||||
+ int len = snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid);
|
||||
+#ifndef HAVE_FTRUNCATE
|
||||
+ /* What can we do with a too-long file and no truncate? I guess we'll add extra newlines. */
|
||||
+ while (len < st1.st_size) /* We already verfified that size+1 chars fits in the buffer. */
|
||||
+ pidbuf[len++] = '\n';
|
||||
+ /* We don't need the buffer to end in a '\0' (and we may not have room to add it). */
|
||||
+#endif
|
||||
+ if (write(pid_file_fd, pidbuf, len) != len)
|
||||
+ fail = "write";
|
||||
+ cleanup_set_pid(pid); /* Mark the file for removal on exit, even if the write failed. */
|
||||
+ }
|
||||
+
|
||||
+ if (fail) {
|
||||
+ char msg[1024];
|
||||
+ snprintf(msg, sizeof msg, "failed to %s pid file %s: %s\n",
|
||||
+ fail, pid_file, strerror(errno));
|
||||
+ fputs(msg, stderr);
|
||||
+ rprintf(FLOG, "%s", msg);
|
||||
exit_cleanup(RERR_FILEIO);
|
||||
}
|
||||
- snprintf(pidbuf, sizeof pidbuf, "%d\n", (int)pid);
|
||||
- len = strlen(pidbuf);
|
||||
- if (write(fd, pidbuf, len) != len)
|
||||
- goto failure;
|
||||
- close(fd);
|
||||
+
|
||||
+ /* The file is left open so that the lock remains valid. It is closed in our forked child procs. */
|
||||
}
|
||||
|
||||
/* Become a daemon, discarding the controlling terminal. */
|
||||
diff --git a/rsyncd.conf.yo b/rsyncd.conf.yo
|
||||
index aac4a7f2..c8338664 100644
|
||||
--- a/rsyncd.conf.yo
|
||||
+++ b/rsyncd.conf.yo
|
||||
@@ -103,9 +103,10 @@ This can be overridden by the bf(--dparam=motdfile=FILE)
|
||||
command-line option when starting the daemon.
|
||||
|
||||
dit(bf(pid file)) This parameter tells the rsync daemon to write
|
||||
-its process ID to that file. If the file already exists, the rsync
|
||||
-daemon will abort rather than overwrite the file.
|
||||
-This can be overridden by the bf(--dparam=pidfile=FILE)
|
||||
+its process ID to that file. The rsync keeps the file locked so that
|
||||
+it can know when it is safe to overwrite an existing file.
|
||||
+
|
||||
+The filename can be overridden by the bf(--dparam=pidfile=FILE)
|
||||
command-line option when starting the daemon.
|
||||
|
||||
dit(bf(port)) You can override the default port the daemon will listen on
|
||||
diff --git a/socket.c b/socket.c
|
||||
index 70fb1695..11ab4a83 100644
|
||||
--- a/socket.c
|
||||
+++ b/socket.c
|
||||
@@ -38,6 +38,7 @@ extern char *bind_address;
|
||||
extern char *sockopts;
|
||||
extern int default_af_hint;
|
||||
extern int connect_timeout;
|
||||
+extern int pid_file_fd;
|
||||
|
||||
#ifdef HAVE_SIGACTION
|
||||
static struct sigaction sigact;
|
||||
@@ -609,6 +610,8 @@ void start_accept_loop(int port, int (*fn)(int, int))
|
||||
|
||||
if ((pid = fork()) == 0) {
|
||||
int ret;
|
||||
+ if (pid_file_fd >= 0)
|
||||
+ close(pid_file_fd);
|
||||
for (i = 0; sp[i] >= 0; i++)
|
||||
close(sp[i]);
|
||||
/* Re-open log file in child before possibly giving
|
||||
@ -1,6 +1,6 @@
|
||||
Name: rsync
|
||||
Version: 3.1.3
|
||||
Release: 6
|
||||
Release: 7
|
||||
Summary: Fast incremental file transfer utility
|
||||
License: GPLv3+
|
||||
URL: http://rsync.samba.org/
|
||||
@ -32,6 +32,7 @@ Patch6009: Fix-zlib-CVE-2016-9843.patch
|
||||
Patch6010: Fix-bug-in-try_dests_reg-that-Florian-Zumbiehl-point.patch
|
||||
Patch6011: Try-to-fix-the-iconv-crash-in-bug-11338.patch
|
||||
Patch6012: CVE-2017-17433.patch
|
||||
Patch6013: backport-Use-a-lock-to-not-fail-on-a-left-over-pid-file.patch
|
||||
|
||||
%description
|
||||
Rsync is an open source utility that provides fast incremental file transfer.
|
||||
@ -90,6 +91,12 @@ install -D -m644 %{SOURCE6} %{buildroot}/%{_unitdir}/rsyncd@.service
|
||||
%{_mandir}/man5/rsyncd.conf.5*
|
||||
|
||||
%changelog
|
||||
* Mon Dec 20 2021 yangzhuangzhuang<yangzhuangzhuang1@huawei.com> - 3.1.3-7
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
- SUG:NA
|
||||
- DESC:Fix the issue that the pid file cannot be rewritten
|
||||
|
||||
* Fri Sep 27 2019 chengquan<chengquan3@huawei.com> - 3.1.3-6
|
||||
- Type:bugfix
|
||||
- ID:NA
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user