From bc601d1e4e29b4377d4a662a79704a2e3ffca757 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 09:19:12 +0200 Subject: [PATCH 01/17] Added methods renice_me() and ionice_me() to reduce priority --- niceness.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 niceness.c diff --git a/niceness.c b/niceness.c new file mode 100644 index 000000000..f1625f061 --- /dev/null +++ b/niceness.c @@ -0,0 +1,48 @@ +/* + * Renice or ionice the current process to reduce its impact on the system + * + * Copyright (C) 2026 Michael Mess + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, visit the http://fsf.org website. + */ + +#include "rsync.h" + +void renice_me() +{ +#ifdef SUPPORT_RENICE + int which = PRIO_PROCESS; // who specifies a Process ID + int who = 0; // 0 means current process + int prio = 19; // lowest CPU Priority + int result = setpriority(which, who, prio); + if ( result < 0 ) { + // Failed to set priority, TODO: log or inform user, but can be ignored (it's just not so nice). + } +#endif +} + +void ionice_me() +{ +#ifdef SUPPORT_IONICE + int which = IOPRIO_WHO_PROCESS; // who specifies a Process ID + int who = 0; // 0 means current process + int class = IOPRIO_CLASS_IDLE; + int data = 0; // Ignored when using the IOPRIO_CLASS_IDLE class + int ioprio = IOPRIO_PRIO_VALUE(class, data); + int result = syscall(SYS_ioprio_set, which, who, ioprio); + if ( result < 0 ) { + // Failed to set priority, TODO: log or inform user, but can be ignored (it's just not so ionice). + } +#endif +} From 9b590a04ed2a8456a9f9c7d95291bb2060372374 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 11:31:09 +0200 Subject: [PATCH 02/17] configure.ac: Check for sys/resource.h linux/ioprio.h sys/syscall.h header files. --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 4faab5fcb..a4071f539 100644 --- a/configure.ac +++ b/configure.ac @@ -13,7 +13,7 @@ AC_CHECK_HEADERS(sys/fcntl.h sys/select.h fcntl.h sys/time.h sys/unistd.h \ sys/acl.h acl/libacl.h attr/xattr.h sys/xattr.h sys/extattr.h dl.h \ popt.h popt/popt.h linux/falloc.h netinet/in_systm.h netgroup.h \ zlib.h xxhash.h openssl/md4.h openssl/md5.h zstd.h lz4.h sys/file.h \ - bsd/string.h) + bsd/string.h sys/resource.h linux/ioprio.h sys/syscall.h) AC_CHECK_HEADERS([netinet/ip.h], [], [], [[#include ]]) AC_HEADER_MAJOR_FIXED From 2631ad58203df9bd9c0e453ffe86e65d42fada72 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 11:32:20 +0200 Subject: [PATCH 03/17] Added niceness.o to Makefile.in for build --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.in b/Makefile.in index bde2c5897..b595aa4f2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,7 +46,7 @@ zlib_OBJS=zlib/deflate.o zlib/inffast.o zlib/inflate.o zlib/inftrees.o \ OBJS1=flist.o rsync.o generator.o receiver.o cleanup.o sender.o exclude.o \ util1.o util2.o main.o checksum.o match.o syscall.o log.o backup.o delete.o OBJS2=options.o io.o compat.o hlink.o token.o uidlist.o socket.o hashtable.o \ - usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o + usage.o fileio.o batch.o clientname.o chmod.o acls.o xattrs.o niceness.o OBJS3=progress.o pipe.o @MD5_ASM@ @ROLL_SIMD@ @ROLL_ASM@ DAEMON_OBJ = params.o loadparm.o clientserver.o access.o connection.o authenticate.o popt_OBJS= popt/popt.o popt/poptconfig.o \ From 608cc2e70cfaa18ecb876f80db535f1c73796de7 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 13:33:39 +0200 Subject: [PATCH 04/17] Define SUPPORT_RENICE and SUPPORT_IONICE if the necessary header files exist --- rsync.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/rsync.h b/rsync.h index cdc2d2c0d..cd6225c23 100644 --- a/rsync.h +++ b/rsync.h @@ -1510,3 +1510,13 @@ const char *get_panic_action(void); #elif defined HAVE_MALLINFO #define MEM_ALLOC_INFO mallinfo #endif + + /* Some header files needed to be nice ;) */ +#ifdef HAVE_SYS_RESOURCE_H +#define SUPPORT_RENICE +#endif + +#if defined HAVE_LINUX_IOPRIO_H && defined HAVE_SYS_SYSCALL_H +#define SUPPORT_IONICE +#endif + From c058cf1b298e1ae2b2cc328b6fcec9db8132d41f Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 13:37:09 +0200 Subject: [PATCH 05/17] Added includes --- rsync.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rsync.h b/rsync.h index cd6225c23..0b4a2f769 100644 --- a/rsync.h +++ b/rsync.h @@ -1514,9 +1514,12 @@ const char *get_panic_action(void); /* Some header files needed to be nice ;) */ #ifdef HAVE_SYS_RESOURCE_H #define SUPPORT_RENICE +#include #endif #if defined HAVE_LINUX_IOPRIO_H && defined HAVE_SYS_SYSCALL_H #define SUPPORT_IONICE +#include +#include #endif From 0cc2224d4b938853323d62e4421f4de492f7d484 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 14:00:02 +0200 Subject: [PATCH 06/17] Ensure that rsync.h definitions are included only once --- rsync.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/rsync.h b/rsync.h index 0b4a2f769..0c9e935ec 100644 --- a/rsync.h +++ b/rsync.h @@ -18,6 +18,9 @@ * with this program; if not, visit the http://fsf.org website. */ +#ifndef RSYNC_H // Ensure that this header file is never included more than once, thus avoiding errors with duplicate definitions +#define RSYNC_H 1 + #define False 0 #define True 1 #define Unset (-1) /* Our BOOL values are always an int. */ @@ -1523,3 +1526,4 @@ const char *get_panic_action(void); #include #endif +#endif // ifndef RSYNC_H From bece7fe960513894ed811f0f0bd5f8fbd97805c0 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 20:59:45 +0200 Subject: [PATCH 07/17] Option parsing for nice and ionice and remote argument --- options.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/options.c b/options.c index 3c2d23526..dccda125d 100644 --- a/options.c +++ b/options.c @@ -35,6 +35,12 @@ extern filter_rule_list daemon_filter_list; int make_backups = 0; +/* If set, be nice on the local or remote site */ +int nice_local = 0; +int nice_remote = 0; +int ionice_local = 0; +int ionice_remote = 0; + /** * If 1, send the whole file as literal data rather than trying to * create an incremental diff. @@ -594,7 +600,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE, OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS, OPT_OLD_ARGS, - OPT_STOP_AFTER, OPT_STOP_AT, + OPT_STOP_AFTER, OPT_STOP_AT, OPT_NICE, OPT_NO_NICE, OPT_IONICE, OPT_NO_IONICE, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { @@ -845,6 +851,19 @@ static struct poptOption long_options[] = { {"remote-option", 'M', POPT_ARG_STRING, 0, 'M', 0, 0 }, {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, + {"nice-local", 0, POPT_ARG_VAL, &nice_local, 1, 0, 0 }, + {"nice-remote", 0, POPT_ARG_VAL, &nice_remote, 1, 0, 0 }, + {"ionice-local", 0, POPT_ARG_VAL, &ionice_local, 1, 0, 0 }, + {"ionice-remote", 0, POPT_ARG_VAL, &ionice_remote, 1, 0, 0 }, + {"no-nice-local", 0, POPT_ARG_VAL, &nice_local, 0, 0, 0 }, + {"no-nice-remote", 0, POPT_ARG_VAL, &nice_remote, 0, 0, 0 }, + {"no-ionice-local", 0, POPT_ARG_VAL, &ionice_local, 0, 0, 0 }, + {"no-ionice-remote", 0, POPT_ARG_VAL, &ionice_remote, 0, 0, 0 }, + {"nice", 0, POPT_ARG_NONE, 0, OPT_NICE, 0, 0 }, + {"ionice", 0, POPT_ARG_NONE, 0, OPT_IONICE, 0, 0 }, + {"no-nice", 0, POPT_ARG_NONE, 0, OPT_NO_NICE, 0, 0 }, + {"no-ionice", 0, POPT_ARG_NONE, 0, OPT_NO_IONICE, 0, 0 }, + {"nice-and-ionice", 'Q', POPT_ARG_NONE, 0, 'Q', 0, 0 }, {"server", 0, POPT_ARG_NONE, 0, OPT_SERVER, 0, 0 }, {"sender", 0, POPT_ARG_NONE, 0, OPT_SENDER, 0, 0 }, /* All the following options switch us into daemon-mode option-parsing. */ @@ -1598,6 +1617,33 @@ int parse_arguments(int *argc_p, const char ***argv_p) quiet++; break; + case 'Q': + nice_local = 1; + nice_remote = 1; + ionice_local = 1; + ionice_remote = 1; + break; + + case OPT_NICE: + nice_local = 1; + nice_remote = 1; + break; + + case OPT_IONICE: + ionice_local = 1; + ionice_remote = 1; + break; + + case OPT_NO_NICE: + nice_local = 0; + nice_remote = 0; + break; + + case OPT_NO_IONICE: + ionice_local = 0; + ionice_remote = 0; + break; + case 'x': one_file_system++; break; @@ -2996,6 +3042,12 @@ void server_options(char **args, int *argc_p) if (mkpath_dest_arg && am_sender) args[ac++] = "--mkpath"; + if (nice_remote) + args[ac++] = "--nice-local"; + + if (ionice_remote) + args[ac++] = "--ionice-local"; + if (ac > MAX_SERVER_ARGS) { /* Not possible... */ rprintf(FERROR, "argc overflow in server_options().\n"); exit_cleanup(RERR_MALLOC); From a0b5bb1dcd6dc4027acdd2f9c590fb4a78550e75 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 21:29:39 +0200 Subject: [PATCH 08/17] rsync --help --- rsync.1.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rsync.1.md b/rsync.1.md index 2b4b75087..5bc5c7ec5 100644 --- a/rsync.1.md +++ b/rsync.1.md @@ -559,6 +559,13 @@ has its own detailed description later in this manpage. --checksum-seed=NUM set block/file checksum seed (advanced) --ipv4, -4 prefer IPv4 --ipv6, -6 prefer IPv6 +--nice-local renice local process to low priority +--nice-remote renice remote process to low priority +--ionice-local ionice local process to low priority +--ionice-remote ionice remote process to low priority +--nice, --ionice set local and remote process to low priority +--no-nice, ... prepending "no-" turns the given option off +--nice-and-ionice, -Q same as --nice --ionice --version, -V print the version + other info and exit --help, -h (*) show this help (* -h is help only on its own) ``` From 50252360da0c92d529dd5a64489a88006410d702 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 21:40:33 +0200 Subject: [PATCH 09/17] rsync help for daemon process --- rsync.1.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rsync.1.md b/rsync.1.md index 5bc5c7ec5..115610b30 100644 --- a/rsync.1.md +++ b/rsync.1.md @@ -586,6 +586,9 @@ accepted: --log-file=FILE override the "log file" setting --log-file-format=FMT override the "log format" setting --sockopts=OPTIONS specify custom TCP options +--nice-local renice local daemon process to low priority +--ionice-local ionice local daemon process to low priority + They are given at client site as (io)nice-remote --verbose, -v increase verbosity --ipv4, -4 prefer IPv4 --ipv6, -6 prefer IPv6 From 8aa3c5016146329ae3ea9f4f35522928e558768d Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sat, 30 May 2026 21:49:41 +0200 Subject: [PATCH 10/17] Set renice or ionice locally --- main.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/main.c b/main.c index c54fd79bc..6ccd9a0d7 100644 --- a/main.c +++ b/main.c @@ -107,6 +107,8 @@ extern char backup_dir_buf[MAXPATHLEN]; extern char *basis_dir[MAX_BASIS_DIRS+1]; extern struct file_list *first_flist; extern filter_rule_list daemon_filter_list, implied_filter_list; +extern int nice_local; +extern int ionice_local; uid_t our_uid; gid_t our_gid; @@ -1835,6 +1837,14 @@ int main(int argc,char *argv[]) if (write_batch < 0) dry_run = 1; + if (nice_local) { + renice_me(); + } + + if (ionice_local) { + ionice_me(); + } + if (am_server) { #ifdef ICONV_CONST setup_iconv(); From e621a6f7ef20b051204003ea4d34172a147d9088 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Sun, 31 May 2026 09:39:02 +0200 Subject: [PATCH 11/17] Added debug/warning messages for renice/ionice --- configure.ac | 2 ++ niceness.c | 22 ++++++++++++++++++++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index a4071f539..84e28dfb5 100644 --- a/configure.ac +++ b/configure.ac @@ -1465,6 +1465,8 @@ case "$CC" in ;; esac +AC_DEFINE_UNQUOTED([COMPILE_TARGET], ["$host"], [String describing the compiled target OS and architecture]) + AC_CONFIG_FILES([Makefile lib/dummy zlib/dummy popt/dummy shconfig]) AC_OUTPUT diff --git a/niceness.c b/niceness.c index f1625f061..37bbb08b0 100644 --- a/niceness.c +++ b/niceness.c @@ -19,6 +19,8 @@ #include "rsync.h" +extern int am_server; + void renice_me() { #ifdef SUPPORT_RENICE @@ -27,8 +29,16 @@ void renice_me() int prio = 19; // lowest CPU Priority int result = setpriority(which, who, prio); if ( result < 0 ) { - // Failed to set priority, TODO: log or inform user, but can be ignored (it's just not so nice). + // Failed to set priority, inform user, but can be ignored (it's just not so nice). + rprintf(FWARNING, "renice rejected by OS (%s version %s)\n", + RSYNC_NAME, rsync_version()); + } else { + if (DEBUG_GTE(CMD, 1)) + rprintf(FINFO, "successfully reniced %s\n", am_server ? "server" : "client"); } +#else + rprintf(FWARNING, "renice not supported for %s (%s: %s version %s)\n", + COMPILE_TARGET, am_server ? "server" : "client", RSYNC_NAME, rsync_version()); #endif } @@ -42,7 +52,15 @@ void ionice_me() int ioprio = IOPRIO_PRIO_VALUE(class, data); int result = syscall(SYS_ioprio_set, which, who, ioprio); if ( result < 0 ) { - // Failed to set priority, TODO: log or inform user, but can be ignored (it's just not so ionice). + // Failed to set priority, inform user, but can be ignored (it's just not so ionice). + rprintf(FWARNING, "ionice rejected by OS (%s version %s)\n", + RSYNC_NAME, rsync_version()); + } else { + if (DEBUG_GTE(CMD, 1)) + rprintf(FINFO, "successfully ioniced %s\n", am_server ? "server" : "client"); } +#else + rprintf(FWARNING, "ionice not supported for %s (%s: %s version %s)\n", + COMPILE_TARGET, am_server ? "server" : "client", RSYNC_NAME, rsync_version()); #endif } From 605c1483bbc521e7929bb8cc462ec7227c2f64b5 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Mon, 1 Jun 2026 17:21:49 +0200 Subject: [PATCH 12/17] Added some files generated by unit test cases to .gitignore. --- .gitignore | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitignore b/.gitignore index a1f912b77..1d234fc59 100644 --- a/.gitignore +++ b/.gitignore @@ -59,3 +59,11 @@ aclocal.m4 .deps /*.exe *.dSYM/ +simdtest +t_chmod_secure +t_secure_relpath +testsuite/__pycache__/ +testsuite/chown-fake_test.py +testsuite/devices-fake_test.py +testsuite/exclude-lsh_test.py +testsuite/xattrs-hlink_test.py From a67d7a1ca605c13dceed5ab41b0827d8c9256d42 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Mon, 1 Jun 2026 18:25:17 +0200 Subject: [PATCH 13/17] Turned nice_local and nice_remote from a simple on/off switch to a value for the nice level --- main.c | 2 +- niceness.c | 8 ++++++-- options.c | 45 +++++++++++++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 11 deletions(-) diff --git a/main.c b/main.c index 6ccd9a0d7..d342688e9 100644 --- a/main.c +++ b/main.c @@ -1838,7 +1838,7 @@ int main(int argc,char *argv[]) dry_run = 1; if (nice_local) { - renice_me(); + renice_me(nice_local); } if (ionice_local) { diff --git a/niceness.c b/niceness.c index 37bbb08b0..a13c3aea6 100644 --- a/niceness.c +++ b/niceness.c @@ -21,12 +21,16 @@ extern int am_server; -void renice_me() +int get_renice_default_prio() +{ + return 19; // lowest CPU Priority +} + +void renice_me(int prio) { #ifdef SUPPORT_RENICE int which = PRIO_PROCESS; // who specifies a Process ID int who = 0; // 0 means current process - int prio = 19; // lowest CPU Priority int result = setpriority(which, who, prio); if ( result < 0 ) { // Failed to set priority, inform user, but can be ignored (it's just not so nice). diff --git a/options.c b/options.c index dccda125d..a4c866f22 100644 --- a/options.c +++ b/options.c @@ -35,9 +35,16 @@ extern filter_rule_list daemon_filter_list; int make_backups = 0; -/* If set, be nice on the local or remote site */ +/* If set to other than 0, be nice on the local or remote site + * Contains the nice priority to be set on the process, or 0=feature is turned off, no priority will be set. + * I have to admit, that it is not possible to set a nice value of 0 with this code, + * but in most cases 0 should be the priority of the newly started rsync process already anyway. + */ int nice_local = 0; int nice_remote = 0; +/* If set to other than 0, be ionice on the local or remote site + * Currently only idle is supported for ionice when turned on. + */ int ionice_local = 0; int ionice_remote = 0; @@ -600,7 +607,8 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_NO_D, OPT_APPEND, OPT_NO_ICONV, OPT_INFO, OPT_DEBUG, OPT_BLOCK_SIZE, OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS, OPT_OLD_ARGS, - OPT_STOP_AFTER, OPT_STOP_AT, OPT_NICE, OPT_NO_NICE, OPT_IONICE, OPT_NO_IONICE, + OPT_STOP_AFTER, OPT_STOP_AT, OPT_NICE, OPT_NO_NICE, OPT_IONICE, OPT_NO_IONICE, + OPT_NICE_LOCAL, OPT_NICE_REMOTE, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { @@ -851,8 +859,8 @@ static struct poptOption long_options[] = { {"remote-option", 'M', POPT_ARG_STRING, 0, 'M', 0, 0 }, {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, - {"nice-local", 0, POPT_ARG_VAL, &nice_local, 1, 0, 0 }, - {"nice-remote", 0, POPT_ARG_VAL, &nice_remote, 1, 0, 0 }, + {"nice-local", 0, POPT_ARG_NONE, 0, OPT_NICE_LOCAL, 0, 0 }, + {"nice-remote", 0, POPT_ARG_NONE, 0, OPT_NICE_REMOTE, 0, 0 }, {"ionice-local", 0, POPT_ARG_VAL, &ionice_local, 1, 0, 0 }, {"ionice-remote", 0, POPT_ARG_VAL, &ionice_remote, 1, 0, 0 }, {"no-nice-local", 0, POPT_ARG_VAL, &nice_local, 0, 0, 0 }, @@ -1384,6 +1392,7 @@ int parse_arguments(int *argc_p, const char ***argv_p) int argc = *argc_p; int opt, want_dest_type; int orig_protect_args = protect_args; + int default_nice_prio = get_renice_default_prio(); // default nice priority to be used, if no explicit priority is given. if (argc == 0) { strlcpy(err_buf, "argc is zero!\n", sizeof err_buf); @@ -1618,15 +1627,35 @@ int parse_arguments(int *argc_p, const char ***argv_p) break; case 'Q': - nice_local = 1; - nice_remote = 1; + /* + * Turn nice on with default prio when it was turned off, but do not overwrite any previously set nice value. + */ + nice_local = nice_local==0 ? default_nice_prio : nice_local; + nice_remote = nice_remote==0 ? default_nice_prio : nice_remote; ionice_local = 1; ionice_remote = 1; break; case OPT_NICE: - nice_local = 1; - nice_remote = 1; + /* + * Turn nice on with default prio when it was turned off, but do not overwrite any previously set nice value. + */ + nice_local = nice_local==0 ? default_nice_prio : nice_local; + nice_remote = nice_remote==0 ? default_nice_prio : nice_remote; + break; + + case OPT_NICE_LOCAL: + /* + * Turn nice on with default prio when it was turned off, but do not overwrite any previously set nice value. + */ + nice_local = nice_local==0 ? default_nice_prio : nice_local; + break; + + case OPT_NICE_REMOTE: + /* + * Turn nice on with default prio when it was turned off, but do not overwrite any previously set nice value. + */ + nice_remote = nice_remote==0 ? default_nice_prio : nice_remote; break; case OPT_IONICE: From 3e234f91cf6f83b3ef3038270885261624740997 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Tue, 2 Jun 2026 00:16:20 +0200 Subject: [PATCH 14/17] prepare command line option --nice-local for remote rsync with and without given nice value (nice-remote) --- options.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/options.c b/options.c index a4c866f22..6e0fae145 100644 --- a/options.c +++ b/options.c @@ -860,7 +860,9 @@ static struct poptOption long_options[] = { {"protocol", 0, POPT_ARG_INT, &protocol_version, 0, 0, 0 }, {"checksum-seed", 0, POPT_ARG_INT, &checksum_seed, 0, 0, 0 }, {"nice-local", 0, POPT_ARG_NONE, 0, OPT_NICE_LOCAL, 0, 0 }, + {"nice-local-value", 0, POPT_ARG_INT, &nice_local, 0, 0, 0 }, {"nice-remote", 0, POPT_ARG_NONE, 0, OPT_NICE_REMOTE, 0, 0 }, + {"nice-remote-value",0, POPT_ARG_INT, &nice_remote, 0, 0, 0 }, {"ionice-local", 0, POPT_ARG_VAL, &ionice_local, 1, 0, 0 }, {"ionice-remote", 0, POPT_ARG_VAL, &ionice_remote, 1, 0, 0 }, {"no-nice-local", 0, POPT_ARG_VAL, &nice_local, 0, 0, 0 }, @@ -3071,8 +3073,15 @@ void server_options(char **args, int *argc_p) if (mkpath_dest_arg && am_sender) args[ac++] = "--mkpath"; - if (nice_remote) - args[ac++] = "--nice-local"; + if (nice_remote) { + if (get_renice_default_prio()==nice_remote) { + args[ac++] = "--nice-local"; + } else { + if (asprintf(&arg, "--nice-local-value=%d", nice_remote) < 0) + goto oom; + args[ac++] = arg; + } + } if (ionice_remote) args[ac++] = "--ionice-local"; From 762ab196ea794bfafc9031c12e1b762b2813fc73 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Tue, 2 Jun 2026 00:29:05 +0200 Subject: [PATCH 15/17] Renice: Print more details about new priority and error on failure --- niceness.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/niceness.c b/niceness.c index a13c3aea6..3f5b0fcb5 100644 --- a/niceness.c +++ b/niceness.c @@ -34,11 +34,11 @@ void renice_me(int prio) int result = setpriority(which, who, prio); if ( result < 0 ) { // Failed to set priority, inform user, but can be ignored (it's just not so nice). - rprintf(FWARNING, "renice rejected by OS (%s version %s)\n", - RSYNC_NAME, rsync_version()); + rprintf(FWARNING, "renice to %d rejected by OS (%s version %s): %s\n", + prio, RSYNC_NAME, rsync_version(), strerror(errno)); } else { if (DEBUG_GTE(CMD, 1)) - rprintf(FINFO, "successfully reniced %s\n", am_server ? "server" : "client"); + rprintf(FINFO, "successfully reniced %s to new priority %d\n", am_server ? "server" : "client", prio); } #else rprintf(FWARNING, "renice not supported for %s (%s: %s version %s)\n", @@ -57,7 +57,7 @@ void ionice_me() int result = syscall(SYS_ioprio_set, which, who, ioprio); if ( result < 0 ) { // Failed to set priority, inform user, but can be ignored (it's just not so ionice). - rprintf(FWARNING, "ionice rejected by OS (%s version %s)\n", + rprintf(FWARNING, "ionice rejected by OS (%s version %s)\n", RSYNC_NAME, rsync_version()); } else { if (DEBUG_GTE(CMD, 1)) From 4ba0fbfa7e58206cef7c623d254a45235b8ef037 Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Tue, 2 Jun 2026 17:39:18 +0200 Subject: [PATCH 16/17] Implemented --nice-value option --- options.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/options.c b/options.c index 6e0fae145..68f1433f9 100644 --- a/options.c +++ b/options.c @@ -608,7 +608,7 @@ enum {OPT_SERVER = 1000, OPT_DAEMON, OPT_SENDER, OPT_EXCLUDE, OPT_EXCLUDE_FROM, OPT_USERMAP, OPT_GROUPMAP, OPT_CHOWN, OPT_BWLIMIT, OPT_STDERR, OPT_OLD_COMPRESS, OPT_NEW_COMPRESS, OPT_NO_COMPRESS, OPT_OLD_ARGS, OPT_STOP_AFTER, OPT_STOP_AT, OPT_NICE, OPT_NO_NICE, OPT_IONICE, OPT_NO_IONICE, - OPT_NICE_LOCAL, OPT_NICE_REMOTE, + OPT_NICE_LOCAL, OPT_NICE_REMOTE, OPT_NICE_VALUE, OPT_REFUSED_BASE = 9000}; static struct poptOption long_options[] = { @@ -870,6 +870,7 @@ static struct poptOption long_options[] = { {"no-ionice-local", 0, POPT_ARG_VAL, &ionice_local, 0, 0, 0 }, {"no-ionice-remote", 0, POPT_ARG_VAL, &ionice_remote, 0, 0, 0 }, {"nice", 0, POPT_ARG_NONE, 0, OPT_NICE, 0, 0 }, + {"nice-value", 0, POPT_ARG_INT, &nice_local, OPT_NICE_VALUE, 0, 0 }, {"ionice", 0, POPT_ARG_NONE, 0, OPT_IONICE, 0, 0 }, {"no-nice", 0, POPT_ARG_NONE, 0, OPT_NO_NICE, 0, 0 }, {"no-ionice", 0, POPT_ARG_NONE, 0, OPT_NO_IONICE, 0, 0 }, @@ -1646,6 +1647,13 @@ int parse_arguments(int *argc_p, const char ***argv_p) nice_remote = nice_remote==0 ? default_nice_prio : nice_remote; break; + case OPT_NICE_VALUE: + /* + * POPT writes to nice_local. We have to copy the value from nice-local to nice-remote here. + */ + nice_remote = nice_local; + break; + case OPT_NICE_LOCAL: /* * Turn nice on with default prio when it was turned off, but do not overwrite any previously set nice value. From 70949e3faa406eb58e028e98937bd1a652098e2f Mon Sep 17 00:00:00 2001 From: Michael Mess Date: Tue, 2 Jun 2026 18:15:46 +0200 Subject: [PATCH 17/17] Updated help --- rsync.1.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rsync.1.md b/rsync.1.md index 115610b30..ff738c538 100644 --- a/rsync.1.md +++ b/rsync.1.md @@ -564,6 +564,9 @@ has its own detailed description later in this manpage. --ionice-local ionice local process to low priority --ionice-remote ionice remote process to low priority --nice, --ionice set local and remote process to low priority +--nice-local-value=10 renice local process to given priority +--nice-remote-value=10 renice remote process to given priority +--nice-value=10 renice local+remote process to given priority --no-nice, ... prepending "no-" turns the given option off --nice-and-ionice, -Q same as --nice --ionice --version, -V print the version + other info and exit