From: Wayne Davison Date: Sat, 4 Jul 2020 17:23:17 +0000 (-0700) Subject: Don't turn off the user's open-noatime unless the module is forcing the value. X-Git-Tag: v3.2.2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=565cde84a71b212b25289e0e32221a66b3263837;p=thirdparty%2Frsync.git Don't turn off the user's open-noatime unless the module is forcing the value. --- diff --git a/NEWS.md b/NEWS.md index 516c49f9..cb0d5436 100644 --- 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 diff --git a/clientserver.c b/clientserver.c index ab559e38..d1aa6081 100644 --- a/clientserver.c +++ b/clientserver.c @@ -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. */ diff --git a/daemon-parm.awk b/daemon-parm.awk index c4752c78..dd0eded0 100755 --- a/daemon-parm.awk +++ b/daemon-parm.awk @@ -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" diff --git a/daemon-parm.txt b/daemon-parm.txt index db838124..0f8f01e5 100644 --- a/daemon-parm.txt +++ b/daemon-parm.txt @@ -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 diff --git a/loadparm.c b/loadparm.c index 5e532da2..a1d5992d 100644 --- a/loadparm.c +++ b/loadparm.c @@ -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 2668d670..41c4052b 100644 --- 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" diff --git a/rsyncd.conf.5.md b/rsyncd.conf.5.md index d06ca3dd..11f77cb0 100644 --- a/rsyncd.conf.5.md +++ b/rsyncd.conf.5.md @@ -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