[SCM] The rsync repository. - branch master updated

Rsync CVS commit messages rsync-cvs at lists.samba.org
Fri Jun 5 02:11:10 UTC 2020


The branch, master has been updated
       via  0dde65a2 Mention more NEWS items.
       via  b177311a Use a lock to not fail on a left-over pid file.
       via  778f0dff Use more switch statements.
      from  342579aa Make -V the short opt for --version.

https://git.samba.org/?p=rsync.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 0dde65a26b38255bea51cc3ec210ddfc4863f12b
Author: Wayne Davison <wayne at opencoder.net>
Date:   Thu Jun 4 19:05:56 2020 -0700

    Mention more NEWS items.

commit b177311aee0b3cf17af0e1760e18dfb60d99e024
Author: Wayne Davison <wayne at opencoder.net>
Date:   Thu Jun 4 17:55:20 2020 -0700

    Use a lock to not fail on a left-over pid file.

commit 778f0dff9b321af9149a706d2ed2c6f6218b9c8a
Author: Wayne Davison <wayne at opencoder.net>
Date:   Thu Jun 4 16:17:12 2020 -0700

    Use more switch statements.

-----------------------------------------------------------------------

Summary of changes:
 NEWS.md        | 22 +++++++++++++++++++-
 clientserver.c | 62 +++++++++++++++++++++++++++++++++++++++++++-------------
 rsyncd.conf.yo |  7 ++++---
 socket.c       |  3 +++
 token.c        | 64 +++++++++++++++++++++++++++++++++++++++++++---------------
 5 files changed, 124 insertions(+), 34 deletions(-)


Changeset truncated at 500 lines:

diff --git a/NEWS.md b/NEWS.md
index 6782b5cb..1807fe4e 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -45,6 +45,8 @@ Protocol: 31 (unchanged)
  - Fixed a bug in the writing of the batch.sh file (w/--write-batch) when the
    source & destination args were not last on the command-line.
 
+ - Avoid a hang when an overabundance of messages clogs up all the I/O buffers.
+
 ### ENHANCEMENTS:
 
  - Various checksum enhancements, including the optional use of openssl's MD4 &
@@ -63,6 +65,19 @@ Protocol: 31 (unchanged)
    `RSYNC_COMPRESS_LIST` can be used to customize the preference order of the
    heuristic when speaking to another rsync 3.2.0 version.
 
+ - Added a --debug=NSTR option that outputs details of the new negotiation
+   strings (for checksums and compression).  The first level just outputs the
+   result of each negotiation on the client, level 2 outputs the values of the
+   strings that were sent to and received from the server, and level 3 outputs
+   all those values on the server side too.
+
+ - The --debug=OPTS command-line option is no longer auto-forwarded to the
+   remote rsync which allows for the client and server to have different levels
+   of debug specified. This also allows for newer debug options to be
+   specified, such as using --debug=NSTR to see the negotiated hash result,
+   without having the command fail if the server version is too old to handle
+   that debug item. Use -M--debug=OPTS to send the options to the remote side.
+
  - Added the `--atimes` option based on the long-standing patch (just with some
    fixes that the patch has been needing).
 
@@ -99,7 +114,12 @@ Protocol: 31 (unchanged)
  - Have a daemon that is logging include the normal-exit sent/received stats
    even when the transfer exited with an error.
 
- - Various manpage improvements.
+ - The daemon now locks its pid file (when configured to use one) so that it
+   will not fail to start when the file exists and it is unlocked.
+
+ - Various man page improvements.
+
+ - Made -V the short option for --version.
 
 ### DEVELOPER RELATED:
 
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
diff --git a/token.c b/token.c
index f169b756..cfcfdcc6 100644
--- a/token.c
+++ b/token.c
@@ -57,6 +57,8 @@ void init_compression_level(void)
 	int min_level, max_level, def_level, off_level;
 
 	switch (do_compression) {
+	case CPRES_NONE:
+		break;
 	case CPRES_ZLIB:
 	case CPRES_ZLIBX:
 		min_level = 1;
@@ -83,7 +85,7 @@ void init_compression_level(void)
 		break;
 #endif
 	default: /* paranoia to prevent missing case values */
-		exit_cleanup(RERR_UNSUPPORTED);
+		assert(0);
 	}
 
 	if (do_compression_level == CLVL_NOT_SPECIFIED)
@@ -1105,18 +1107,27 @@ static void see_uncompressed_token(char *buf, int32 len)
 void send_token(int f, int32 token, struct map_struct *buf, OFF_T offset,
 		int32 n, int32 toklen)
 {
-	if (!do_compression)
+	switch (do_compression) {
+	case CPRES_NONE:
 		simple_send_token(f, token, buf, offset, n);
+		break;
+	case CPRES_ZLIB:
+	case CPRES_ZLIBX:
+		send_deflated_token(f, token, buf, offset, n, toklen);
+		break;
 #ifdef SUPPORT_ZSTD
-	else if (do_compression == CPRES_ZSTD)
+	case CPRES_ZSTD:
 		send_zstd_token(f, token, buf, offset, n);
+		break;
 #endif
 #ifdef SUPPORT_LZ4
-	else if (do_compression == CPRES_LZ4)
+	case CPRES_LZ4:
 		send_compressed_token(f, token, buf, offset, n);
+		break;
 #endif
-	else
-		send_deflated_token(f, token, buf, offset, n, toklen);
+	default:
+		assert(0);
+	}
 }
 
 /*
@@ -1129,18 +1140,27 @@ int32 recv_token(int f, char **data)
 {
 	int tok;
 
-	if (!do_compression)
+	switch (do_compression) {
+	case CPRES_NONE:
 		tok = simple_recv_token(f,data);
+		break;
+	case CPRES_ZLIB:
+	case CPRES_ZLIBX:
+		tok = recv_deflated_token(f, data);
+		break;
 #ifdef SUPPORT_ZSTD
-	else if (do_compression == CPRES_ZSTD)
+	case CPRES_ZSTD:
 		tok = recv_zstd_token(f, data);
+		break;
 #endif
 #ifdef SUPPORT_LZ4
-	else if (do_compression == CPRES_LZ4)
+	case CPRES_LZ4:
 		tok = recv_compressed_token(f, data);
+		break;
 #endif
-	else /* CPRES_ZLIB & CPRES_ZLIBX */
-		tok = recv_deflated_token(f, data);
+	default:
+		assert(0);
+	}
 	return tok;
 }
 
@@ -1149,12 +1169,24 @@ int32 recv_token(int f, char **data)
  */
 void see_token(char *data, int32 toklen)
 {
-	if (do_compression == CPRES_ZLIB)
+	switch (do_compression) {
+	case CPRES_NONE:
+		break;
+	case CPRES_ZLIB:
 		see_deflate_token(data, toklen);
+		break;
+	case CPRES_ZLIBX:
+		break;
 #ifdef SUPPORT_LZ4
-# if 0
-	else if (do_compression == CPRES_LZ4)
-		see_uncompressed_token(data, toklen);
-# endif
+	case CPRES_LZ4:
+		/*see_uncompressed_token(data, toklen);*/
+		break;
 #endif
+#ifdef SUPPORT_LZ4
+	case CPRES_ZSTD:
+		break;
+#endif
+	default:
+		assert(0);
+	}
 }


-- 
The rsync repository.



More information about the rsync-cvs mailing list