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 <wa...@opencoder.net>
Date:   Thu Jun 4 19:05:56 2020 -0700

    Mention more NEWS items.

commit b177311aee0b3cf17af0e1760e18dfb60d99e024
Author: Wayne Davison <wa...@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 <wa...@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.

_______________________________________________
rsync-cvs mailing list
rsync-cvs@lists.samba.org
https://lists.samba.org/mailman/listinfo/rsync-cvs

Reply via email to