Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,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
3 changes: 2 additions & 1 deletion Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,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
OBJS=$(OBJS1) $(OBJS2) $(OBJS3) $(DAEMON_OBJ) $(NICENESS_OBJS) $(LIBOBJ) @BUILD_ZLIB@ @BUILD_POPT@

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

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(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 <netinet/in.h>]])
AC_HEADER_MAJOR_FIXED

Expand Down Expand Up @@ -1479,6 +1479,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
2 changes: 2 additions & 0 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,6 +1844,8 @@ int main(int argc,char *argv[])
if (write_batch < 0)
dry_run = 1;

niceness_renice_and_ionice_me();

if (am_server) {
#ifdef ICONV_CONST
setup_iconv();
Expand Down
49 changes: 49 additions & 0 deletions niceness/ionice_string.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* 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);
}
}
128 changes: 128 additions & 0 deletions niceness/niceness.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
* 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);

/*
* 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