Don't turn off the user's open-noatime unless the module is forcing the value.
authorWayne Davison <wayne@opencoder.net>
Sat, 4 Jul 2020 17:23:17 +0000 (10:23 -0700)
committerWayne Davison <wayne@opencoder.net>
Sat, 4 Jul 2020 17:28:38 +0000 (10:28 -0700)
NEWS.md
clientserver.c
daemon-parm.awk
daemon-parm.txt
loadparm.c
rsync.h
rsyncd.conf.5.md

diff --git a/NEWS.md b/NEWS.md
index 516c49f9004f0e415c13421067a685e1dc34152e..cb0d5436bf1480650199d472a3172cef1d5588f0 100644 (file)
--- a/NEWS.md
+++ b/NEWS.md
@@ -37,6 +37,9 @@
    also allows you to specify the value via the RSYNC_MAX_ALLOC environment
    variable.
 
+ - Add the "open atime" daemon parameter to allow a daemon to always enable or
+   disable the use of O_NOATIME (the default is to let the user control it).
+
  - The default systemd config was changed to remove the `ProtectHome=on`
    setting since rsync is often used to serve files in /home and /root and this
    seemed a bit too strict.  Feel free to use `systemctl edit rsync` to add
index ab559e380b182fa6f985be2bc61ec46d4ac2c44d..d1aa6081cc3431f72d993d8b957c35092dbd3136 100644 (file)
@@ -990,8 +990,11 @@ static int rsync_module(int f_in, int f_out, int i, const char *addr, const char
        } else
                orig_early_argv = NULL;
 
+       /* The default is to use the user's setting unless the module sets True or False. */
+       if (lp_open_noatime(module_id) >= 0)
+               open_noatime = lp_open_noatime(module_id);
+
        munge_symlinks = save_munge_symlinks; /* The client mustn't control this. */
-       open_noatime = lp_open_noatime(module_id);
 
        if (am_daemon > 0)
                msgs2stderr = 0; /* A non-rsh-run daemon doesn't have stderr for msgs. */
index c4752c78cbe1bb91f06c37bf73199edb4f186533..dd0eded09dbe54f4755c92cf4335bc950c42b00a 100755 (executable)
@@ -41,7 +41,7 @@ BEGIN {
     next
 }
 
-/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV)[ \t]/ {
+/^(STRING|CHAR|PATH|INTEGER|ENUM|OCTAL|BOOL|BOOLREV|BOOL3)[ \t]/ {
     ptype = $1
     name = $2
     $1 = $2 = ""
@@ -59,7 +59,7 @@ BEGIN {
     if (ptype == "STRING" || ptype == "PATH") {
        atype = "STRING"
        vtype = "char*"
-    } else if (ptype == "BOOL" || ptype == "BOOLREV") {
+    } else if (ptype ~ /BOOL/) {
        atype = vtype = "BOOL"
     } else if (ptype == "CHAR") {
        atype = "CHAR"
index db838124a5a7b6bb21408ef3703b66bdecfb21fc..0f8f01e51ebd1416ee802b1d2a7377e1faaede78 100644 (file)
@@ -55,12 +55,13 @@ BOOL        forward_lookup          True
 BOOL   ignore_errors           False
 BOOL   ignore_nonreadable      False
 BOOL   list                    True
-BOOL   munge_symlinks          (BOOL)-1
-BOOL   numeric_ids             (BOOL)-1
-BOOL   open_noatime            False
 BOOL   read_only               True
 BOOL   reverse_lookup          True
 BOOL   strict_modes            True
 BOOL   transfer_logging        False
 BOOL   use_chroot              True
 BOOL   write_only              False
+
+BOOL3  munge_symlinks          Unset
+BOOL3  numeric_ids             Unset
+BOOL3  open_noatime            Unset
index 5e532da2018b30e8b843a3389053871051b31e82..a1d5992d0d2dd28d6d8b44236beee82e61d88ef5 100644 (file)
@@ -48,7 +48,6 @@
 extern item_list dparam_list;
 
 #define strequal(a, b) (strcasecmp(a, b)==0)
-#define BOOLSTR(b) ((b) ? "Yes" : "No")
 
 #ifndef LOG_DAEMON
 #define LOG_DAEMON 0
@@ -56,7 +55,7 @@ extern item_list dparam_list;
 
 /* the following are used by loadparm for option lists */
 typedef enum {
-       P_BOOL, P_BOOLREV, P_CHAR, P_INTEGER,
+       P_BOOL, P_BOOLREV, P_BOOL3, P_CHAR, P_INTEGER,
        P_OCTAL, P_PATH, P_STRING, P_ENUM
 } parm_type;
 
@@ -279,19 +278,14 @@ static void init_section(local_vars *psection)
        copy_section(psection, &Vars.l);
 }
 
-/* Do a case-insensitive, whitespace-ignoring string compare. */
-static int strwicmp(char *psz1, char *psz2)
+/* Do a case-insensitive, whitespace-ignoring string equality check. */
+static int strwiEQ(char *psz1, char *psz2)
 {
-       /* if BOTH strings are NULL, return TRUE, if ONE is NULL return */
-       /* appropriate value. */
+       /* If one or both strings are NULL, we return equality right away. */
        if (psz1 == psz2)
-               return 0;
-
-       if (psz1 == NULL)
-               return -1;
-
-       if (psz2 == NULL)
                return 1;
+       if (psz1 == NULL || psz2 == NULL)
+               return 0;
 
        /* sync the strings on first non-whitespace */
        while (1) {
@@ -299,12 +293,14 @@ static int strwicmp(char *psz1, char *psz2)
                        psz1++;
                while (isSpace(psz2))
                        psz2++;
-               if (toUpper(psz1) != toUpper(psz2) || *psz1 == '\0' || *psz2 == '\0')
+               if (*psz1 == '\0' || *psz2 == '\0')
+                       break;
+               if (toUpper(psz1) != toUpper(psz2))
                        break;
                psz1++;
                psz2++;
        }
-       return *psz1 - *psz2;
+       return *psz1 == *psz2;
 }
 
 /* Find a section by name. Otherwise works like get_section. */
@@ -313,7 +309,7 @@ static int getsectionbyname(char *name)
        int i;
 
        for (i = section_list.count - 1; i >= 0; i--) {
-               if (strwicmp(iSECTION(i).name, name) == 0)
+               if (strwiEQ(iSECTION(i).name, name))
                        break;
        }
 
@@ -353,7 +349,7 @@ static int map_parameter(char *parmname)
                return -1;
 
        for (iIndex = 0; parm_table[iIndex].label; iIndex++) {
-               if (strwicmp(parm_table[iIndex].label, parmname) == 0)
+               if (strwiEQ(parm_table[iIndex].label, parmname))
                        return iIndex;
        }
 
@@ -364,16 +360,14 @@ static int map_parameter(char *parmname)
 /* Set a boolean variable from the text value stored in the passed string.
  * Returns True in success, False if the passed string does not correctly
  * represent a boolean. */
-static BOOL set_boolean(BOOL *pb, char *parmvalue)
+static BOOL set_boolean(BOOL *pb, char *parmvalue, int allow_unset)
 {
-       if (strwicmp(parmvalue, "yes") == 0
-        || strwicmp(parmvalue, "true") == 0
-        || strwicmp(parmvalue, "1") == 0)
+       if (strwiEQ(parmvalue, "yes") || strwiEQ(parmvalue, "true") || strwiEQ(parmvalue, "1"))
                *pb = True;
-       else if (strwicmp(parmvalue, "no") == 0
-             || strwicmp(parmvalue, "False") == 0
-             || strwicmp(parmvalue, "0") == 0)
+       else if (strwiEQ(parmvalue, "no") || strwiEQ(parmvalue, "false") || strwiEQ(parmvalue, "0"))
                *pb = False;
+       else if (allow_unset && (strwiEQ(parmvalue, "unset") || strwiEQ(parmvalue, "-1")))
+               *pb = Unset;
        else {
                rprintf(FLOG, "Badly formed boolean in configuration file: \"%s\".\n", parmvalue);
                return False;
@@ -422,11 +416,15 @@ static BOOL do_parameter(char *parmname, char *parmvalue)
 
        switch (parm_table[parmnum].type) {
        case P_BOOL:
-               set_boolean(parm_ptr, parmvalue);
+               set_boolean(parm_ptr, parmvalue, False);
+               break;
+
+       case P_BOOL3:
+               set_boolean(parm_ptr, parmvalue, True);
                break;
 
        case P_BOOLREV:
-               set_boolean(parm_ptr, parmvalue);
+               set_boolean(parm_ptr, parmvalue, False);
                *(BOOL *)parm_ptr = ! *(BOOL *)parm_ptr;
                break;
 
@@ -496,7 +494,7 @@ static BOOL do_section(char *sectionname)
                return True;
        }
 
-       isglobal = strwicmp(sectionname, GLOBAL_NAME) == 0;
+       isglobal = strwiEQ(sectionname, GLOBAL_NAME);
 
        /* At the end of the global section, add any --dparam items. */
        if (bInGlobalSection && !isglobal) {
diff --git a/rsync.h b/rsync.h
index 2668d670ed40bac33f5bae8d7d31adc4cf4d233d..41c4052b99fede4fe97a7f4c739fa76282943ca4 100644 (file)
--- a/rsync.h
+++ b/rsync.h
@@ -20,6 +20,7 @@
 
 #define False 0
 #define True 1
+#define Unset (-1) /* Our BOOL values are always an int. */
 
 #define BLOCK_SIZE 700
 #define RSYNC_RSH_ENV "RSYNC_RSH"
index d06ca3ddf8f5a8588013b83fd3f2bd2492a997cd..11f77cb01edb09af37895dd9c81be141f6dd032b 100644 (file)
@@ -426,13 +426,20 @@ the values of parameters.  See the GLOBAL PARAMETERS section for more details.
 
 0.  `open noatime`
 
-    This parameter tells the rsync daemon to open files with the O_NOATIME flag
+    When set to True, this parameter tells the rsync daemon to open files with
+    the O_NOATIME flag
     (on systems that support it) to avoid changing the access time of the files
     that are being transferred.  If your OS does not support the O_NOATIME flag
     then rsync will silently ignore this option.  Note also that some
     filesystems are mounted to avoid updating the atime on read access even
     without the O_NOATIME flag being set.
 
+    When set to False, this parameters ensures that files on the server are not
+    opened with O_NOATIME.
+
+    When set to Unset (the default) the user controls the setting via
+    `--open-noatime`.
+
 0.  `list`
 
     This parameter determines whether this module is listed when the client