Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
a44ff28
niceness: change nice and ionice level of the local and/or remote pro…
michaelmess-de Jul 31, 2026
15286d6
Skip tests to check if build succeeds
michaelmess-de Oct 22, 2026
e83de81
Added new combined test (incomplete) and skip tests with new helper f…
michaelmess-de Oct 22, 2026
3a2bb40
Use skip method to skip tests
michaelmess-de Oct 22, 2026
ba189a7
Added combined strace test
michaelmess-de Oct 22, 2026
919577b
Added test case
michaelmess-de Oct 22, 2026
4f49ce4
Added test cases
michaelmess-de Oct 22, 2026
ecda7b5
Deleted local + remote test (we have a combined one now)
michaelmess-de Oct 22, 2026
b046534
Improved skip text message
michaelmess-de Oct 22, 2026
27f2894
Removed platform skip
michaelmess-de Oct 22, 2026
e187183
Added cygwin and macos to skip list
michaelmess-de Oct 22, 2026
80094f0
Skip on solaris
michaelmess-de Oct 22, 2026
e84dc47
Corrected Solaris skip
michaelmess-de Oct 22, 2026
249b257
Install strace on almalinux
michaelmess-de Oct 22, 2026
f07325a
Corrected Solaris skip
michaelmess-de Oct 22, 2026
d60594a
Added kernel-headers and glibc-devel package
michaelmess-de Oct 22, 2026
7de42fb
Corrected rsync call
michaelmess-de Oct 22, 2026
4105bf9
Also check for the result with root permissions
michaelmess-de Oct 23, 2026
28f700d
Corrected fail message
michaelmess-de Oct 23, 2026
9fa733e
Corrected split(...)
michaelmess-de Oct 23, 2026
2fc9d8d
Corrected split(...)
michaelmess-de Oct 23, 2026
f947161
Corrected split(...)
michaelmess-de Oct 23, 2026
cea50b6
Corrected split(...)
michaelmess-de Oct 23, 2026
4260e4b
Corrected missing import
michaelmess-de Oct 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/almalinux-8-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ jobs:
dnf -y install epel-release
dnf config-manager --set-enabled powertools
dnf -y install gcc gcc-c++ make autoconf automake m4 \
python39 python39-pip diffutils \
python39 python39-pip diffutils strace \
openssl openssl-devel \
kernel-headers glibc-devel \
attr libattr-devel acl libacl-devel \
zstd libzstd-devel \
lz4 lz4-devel \
Expand Down
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,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
5 changes: 3 additions & 2 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ 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 \
popt/popthelp.o popt/poptparse.o popt/poptint.o
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
NICENESS_OBJS = niceness/ionice_string.o niceness/niceness.o niceness/niceness_syscall.o niceness/parse_arguments.o
Comment thread
steadytao marked this conversation as resolved.
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(NICENESS_OBJS) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@

TLS_OBJ = tls.o syscall.o util2.o t_stub.o lib/compat.o lib/snprintf.o lib/permstring.o lib/sysxattrs.o @BUILD_POPT@

Expand Down Expand Up @@ -233,7 +234,7 @@ t_clean_fname$(EXEEXT): $(T_CLEAN_FNAME_OBJ)
# GNU-make-only; BSD and Solaris make expand it to nothing.
t_safe_arg_main.o: main.c $(HEADERS)
$(CC) -I. -I$(srcdir) $(CFLAGS) $(CPPFLAGS) -Dmain=rsync_unused_main -c $(srcdir)/main.c -o t_safe_arg_main.o
T_SAFE_ARG_OBJ = t_safe_arg.o t_safe_arg_main.o $(OBJS1_NO_MAIN) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
T_SAFE_ARG_OBJ = t_safe_arg.o t_safe_arg_main.o $(OBJS1_NO_MAIN) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(NICENESS_OBJS) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@
t_safe_arg$(EXEEXT): $(T_SAFE_ARG_OBJ)
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(T_SAFE_ARG_OBJ) $(LIBS)

Expand Down
4 changes: 3 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ AC_CHECK_HEADERS(poll.h 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 \
sys/resource.h bsd/string.h idn2.h wchar.h)
sys/resource.h bsd/string.h idn2.h wchar.h linux/ioprio.h sys/syscall.h)
AC_CHECK_HEADERS([netinet/ip.h], [], [], [[#include <netinet/in.h>]])
AC_HEADER_MAJOR_FIXED

Expand Down Expand Up @@ -1571,6 +1571,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

Expand Down
6 changes: 5 additions & 1 deletion main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1950,8 +1950,10 @@ int main(int argc,char *argv[])
#ifdef ICONV_CONST
setup_iconv();
#endif
} else if (am_daemon)
} else if (am_daemon) {
niceness_renice_and_ionice_me();
return daemon_main();
Comment thread
steadytao marked this conversation as resolved.
}

if (am_server && protect_args) {
char buf[MAXPATHLEN];
Expand All @@ -1963,6 +1965,8 @@ int main(int argc,char *argv[])
}
}

niceness_renice_and_ionice_me();
Comment thread
steadytao marked this conversation as resolved.

if (argc < 1) {
usage(FERROR);
exit_cleanup(RERR_SYNTAX);
Expand Down
48 changes: 48 additions & 0 deletions niceness/ionice_string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Renice or ionice the rsync process to reduce its impact on the system
* ionice_string.c - string conversion utilities for ionice
*
* 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 <strings.h>
#include "niceness.h"

/*
* Get the string representation for the given ionice_value
*/
const char *intToIoniceValueString(int ionice_value)
{
if (ionice_value<-8) return 0;
if (ionice_value>9) return 0;
return Ionice_ValueStrings[ionice_value+8];
}

/*
* Parse string into ionice_value. Returns 1 on success, 0 otherwise.
*/
int ioniceStringToInt(char * string, int *ionice_value)
{
for (int i=0; Ionice_ValueStrings[i]; i++)
{
if (strncasecmp(string, Ionice_ValueStrings[i], 4) == 0) // All values are 4 chars long
{
*ionice_value=i-8;
return 1;
}
}
return 0;
}
31 changes: 31 additions & 0 deletions niceness/ionice_string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Renice or ionice the rsync process to reduce its impact on the system
* ionice_string.h - string conversion utilities for ionice
*
* 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 "niceness.h"

/*
* Get the string representation for the given ionice_value
*/
const char *intToIoniceValueString(int ionice_value);

/*
* Parse string into ionice_value. Returns 1 on success, 0 otherwise.
*/
int ioniceStringToInt(char * string, int *ionice_value);
98 changes: 98 additions & 0 deletions niceness/niceness.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Renice or ionice the rsync process to reduce its impact on the system
* niceness.c - core niceness state holder
*
* 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 "niceness.h"

/*
* String representation of ionice. All strings have to be 4 characters long.
*/
const char *Ionice_ValueStrings[] = {
"rt_0",
"rt_1",
"rt_2",
"rt_3",
"rt_4",
"rt_5",
"rt_6",
"rt_7",
"none",
"be_0",
"be_1",
"be_2",
"be_3",
"be_4",
"be_5",
"be_6",
"be_7",
"idle",
0
};

struct niceness niceness = {
/* 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.
*/
.nice_local = 0,
.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.
*/
.ionice_local = 0,
.ionice_remote = 0,
};

/**
* Turn niceness off (no nice and no ionice)
*/
void niceness_turn_off()
{
niceness.nice_local = 0;
niceness.nice_remote = 0;
niceness.ionice_local = 0;
niceness.ionice_remote = 0;
}

/**
* Turn niceness on (nice and ionice set to default values for maximum niceness)
*/
void niceness_turn_on()
{
niceness.nice_local = NICENESS_RENICE_DEFAULT_PRIO;
niceness.nice_remote = NICENESS_RENICE_DEFAULT_PRIO;
niceness.ionice_local = NICENESS_IONICE_DEFAULT_PRIO;
niceness.ionice_remote = NICENESS_IONICE_DEFAULT_PRIO;
}

/**
* Apply nice/ionice local to this rsync process
*/
void niceness_renice_and_ionice_me()
{
if (niceness.nice_local) {
niceness_renice_me(niceness.nice_local);
}

if (niceness.ionice_local) {
niceness_ionice_me(niceness.ionice_local);
}
}
129 changes: 129 additions & 0 deletions niceness/niceness.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/*
* Renice or ionice the rsync 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.
*/

#ifndef NICENESS_H // Ensure that this header file is never included more than once, thus avoiding errors with duplicate definitions
#define NICENESS_H 1

/*
* Enum for ionice values.
* Constants with negative numbers need root permission, others can be set by any user.
* RT_X is realtime priority
* BE_X is best effort with the given level
* IDLE means the process gets served only when no other processes are using disk io.
* NONE means best effort with level calculated by the formula (cpu_nice + 20) / 5
* and is the default that does not need to be set.
*/
enum Ionice_Values {
RT_0 =-8,
RT_1 =-7,
RT_2 =-6,
RT_3 =-5,
RT_4 =-4,
RT_5 =-3,
RT_6 =-2,
RT_7 =-1,
NONE = 0,
BE_0 = 1,
BE_1 = 2,
BE_2 = 3,
BE_3 = 4,
BE_4 = 5,
BE_5 = 6,
BE_6 = 7,
BE_7 = 8,
IDLE = 9
};

/*
* String representation of ionice. All strings have to be 4 characters long.
*/
extern const char *Ionice_ValueStrings[];
/*
const char *Ionice_ValueStrings[] = {
"rt_0",
"rt_1",
"rt_2",
"rt_3",
"rt_4",
"rt_5",
"rt_6",
"rt_7",
"none",
"be_0",
"be_1",
"be_2",
"be_3",
"be_4",
"be_5",
"be_6",
"be_7",
"idle",
0
};
*/

/*
* Constants to be used when no specific argument is given
*/
#define NICENESS_RENICE_DEFAULT_PRIO 19;
#define NICENESS_IONICE_DEFAULT_PRIO IDLE;

/*
* Struct to hold state for niceness
*/
struct niceness {
/* 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;
int nice_remote;

/* 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;
int ionice_remote;
};

extern struct niceness niceness;


/*
* Some methods to simply turn niceness on or off or configure with an argument
*/
void niceness_turn_off();
void niceness_turn_on();
int niceness_parse_argument(const char * arg);
int niceness_local_wants_elevated_priorities();

/*
* Apply nice and ionice on this local process
*/
void niceness_renice_and_ionice_me();
void niceness_renice_me(int prio);
void niceness_ionice_me(int ionice_value);

/*
* Utility function to get the string representation of an ionice value
*/
const char *intToIoniceValueString(int ionice_value);

#endif // ifndef NICENESS_H
Loading
Loading