Hi folks,

This is a patch for rsync 2.6.9 - I'm not sure if this is the proper vehicle
for submitting them. It's been working great for us for months, and I hope
it's seen as offering useful utility in general.

Steve (who is not a subscriber to this list)

--- 
Stephen J Friedl | Security Consultant |  UNIX Wizard  |   +1 714 544-6561
www.unixwiz.net  | Tustin, Calif. USA  | Microsoft MVP | [EMAIL PROTECTED]

----------------------------------------------------------------------------

Date:   2007/10/09
By:     Stephen J. Friedl
        [EMAIL PROTECTED]

Purpose:
        This patch introduces a "nice = <N>" variable in the rsyncd.conf
        file so that the daemon will raise its nice value (lower CPU
        priority) by the given integer delta for a given rsync module.

Background:

        When doing full-system backups with rsync across the data center,
        we use several techniques to avoid swamping the backed up machine
        when the rsync kicks in. We set a --bwlimit to cut down on the I/O,
        but we also wanted to lower the CPU priority as well.

        We've had real problems with the rsync backups adversely affecting
        production workloads, and though it's probably possible to build
        some kind of wrapper that nices the process priority up before
        execing the real daemon, that would apply the nice to all modules
        served by that daemon. That's not what we wanted.

Using this:

        In an rsyncd.conf:

                [fullbackup]
                        path = /
                        ...
                        nice = 10

        This *adds* 10 to the current nice, which *lowers* the CPU priority.
        Though the nice(2) system call can take negative numbers to lower
        the nice/raise the priority, that's disallowed here. We only allow
        lowering of the CPU priority, never raising it.

The patch:

        This was a pretty easy patch to make: I found where the variables
        were defined and simply added a new integral one in the pattern
        of the timeout variable.

        Not being terribly familiar with the internals of rsync, I was
        not absolutely sure that rsync forked a child for each client
        request, and since nice(2) is additive, doing this in the wrong
        place means that each client gets lower and lower priority.

        So I put the call right after the chroot(2) call - I was sure that
        *this* was not in a loop, and I wouldn't have to worry about it.

        The nice(2) system call has different return semantics across
        different operating systems (Linux returns 0 on success, BSD
        returns the new nice value), and there's no real point in checking
        for success or failure: nice() with positive values is supposed
        to work for everybody anyway.

        It might be possible to support *raising* CPU priority (via a
        negative nice), but this seems like an area rife with trouble
        for no real benefit. We'd have to coordinate lowering the nice
        before giving up root permissions, check for errors, probably
        get it wrong sometimes, and it seems so much easier to allow only
        the behavior which the patch intended to add anyway: lower the
        priority.

        The only thing I'm not completely sure about is how to best do
        logging. I have two calls to rprint(FLOG, ...): one is for an
        error condition (providing a negative nice), and the other is
        just an info notice.

        rprintf(FLOG, "WARNING: nice(%d) not allowed (must be positive) on 
module %s\n",
                niceval, name);

        rprintf(FLOG, "rsync set nice(%d) on module %s\n", niceval, name);

        The error should not be fatal, and neither of these should be routed
        to the client.

        This very patch has been in use on a dozen machines (Linux and
        FreeBSD) for more than two months, and we've verified that it really
        does increase the nice as requested.

--- clientserver.c.orig 2007-08-19 07:36:59.000000000 +0000
+++ clientserver.c      2007-08-20 00:47:10.000000000 +0000
@@ -283,6 +283,7 @@
        int ret, pre_exec_fd = -1;
        pid_t pre_exec_pid = 0;
        char *request = NULL;
+       int niceval;
 
        if (!allow_access(addr, host, lp_hosts_allow(i), lp_hosts_deny(i))) {
                rprintf(FLOG, "rsync denied on module %s from %s (%s)\n",
@@ -559,6 +560,29 @@
                am_root = (MY_UID() == 0);
        }
 
+       /* If the user provided a nice increment to lower the priority,
+        * do it here. Negative nice not allowed, and we rely on the OS
+        * to quietly limit the maximum nice (no point in us vetting it).
+        *
+        * The return value from nice(2) varies across operating systems
+        * (linux has 0=success, BSD return new nice value), so there is
+        * no point in checking for errors.
+        */
+       if ( (niceval = lp_nice(i)) > 0 )
+       {
+               rprintf(FLOG, "rsync set nice(%d) on module %s\n", niceval, 
name);
+
+               nice(niceval);
+       }
+       else if ( niceval < 0 )
+       {
+               rprintf(FLOG, "WARNING: nice(%d) not allowed (must be positive) 
on module %s\n",
+                       niceval, name);
+
+               /* but we keep going */
+       }
+
+
        if (lp_temp_dir(i) && *lp_temp_dir(i)) {
                tmpdir = lp_temp_dir(i);
                if (strlen(tmpdir) >= MAXPATHLEN - 10) {
--- loadparm.c.orig     2007-08-19 07:28:25.000000000 +0000
+++ loadparm.c  2007-08-19 07:39:00.000000000 +0000
@@ -149,6 +149,7 @@
        int max_verbosity;
        int syslog_facility;
        int timeout;
+       int niceval;
 
        BOOL ignore_errors;
        BOOL ignore_nonreadable;
@@ -196,6 +197,7 @@
  /* max_verbosity; */          1,
  /* syslog_facility; */                LOG_DAEMON,
  /* timeout; */                        0,
+ /* nice; */                   0,
 
  /* ignore_errors; */          False,
  /* ignore_nonreadable; */     False,
@@ -327,6 +329,7 @@
  {"syslog facility",   P_ENUM,   P_LOCAL, 
&sDefault.syslog_facility,enum_facilities,0},
  {"temp dir",          P_PATH,   P_LOCAL, &sDefault.temp_dir,          NULL,0},
  {"timeout",           P_INTEGER,P_LOCAL, &sDefault.timeout,           NULL,0},
+ {"nice",              P_INTEGER,P_LOCAL, &sDefault.niceval,           NULL,0},
  {"transfer logging",  P_BOOL,   P_LOCAL, &sDefault.transfer_logging,  NULL,0},
  {"uid",               P_STRING, P_LOCAL, &sDefault.uid,               NULL,0},
  {"use chroot",        P_BOOL,   P_LOCAL, &sDefault.use_chroot,        NULL,0},
@@ -411,6 +414,7 @@
 FN_LOCAL_INTEGER(lp_max_connections, max_connections)
 FN_LOCAL_INTEGER(lp_max_verbosity, max_verbosity)
 FN_LOCAL_INTEGER(lp_timeout, timeout)
+FN_LOCAL_INTEGER(lp_nice, niceval)
 
 FN_LOCAL_BOOL(lp_ignore_errors, ignore_errors)
 FN_LOCAL_BOOL(lp_ignore_nonreadable, ignore_nonreadable)
--- proto.h.orig        2007-08-19 07:41:19.000000000 +0000
+++ proto.h     2007-08-19 07:42:12.000000000 +0000
@@ -173,6 +173,7 @@
 int lp_max_connections(int );
 int lp_max_verbosity(int );
 int lp_timeout(int );
+int lp_nice(int );
 BOOL lp_ignore_errors(int );
 BOOL lp_ignore_nonreadable(int );
 BOOL lp_list(int );
--- rsyncd.conf.5.orig  2007-08-19 08:02:16.000000000 +0000
+++ rsyncd.conf.5       2007-08-20 00:31:23.000000000 +0000
@@ -573,6 +573,13 @@
 of the patterns will not be compressed during transfer\&.
 .IP 
 The default setting is \f(CW*\&.gz *\&.tgz *\&.zip *\&.z *\&.rpm *\&.deb 
*\&.iso *\&.bz2 *\&.tbz\fP
+.IP
+.IP "\fBnice\fP
+This provides a positive nice(2) value that lowers the CPU priority of the
+rsyncd process when servicing this module. This is useful for backups across
+the network that are not time critical, and the lowered priority can help
+avoid swamping a busy machine. Negative nice (to increase priority) are 
+specifically disallowed here.
 .IP 
 .IP "\fBpre-xfer exec\fP, \fBpost-xfer exec\fP"
 You may specify a command to be run
@@ -686,6 +693,12 @@
         auth users = tridge, susan
         secrets file = /etc/rsyncd\&.secrets
 
+[fullbackup]
+        path = /
+        read only = yes
+        nice = 5
+        comment = Full system backup
+
 .fi 
 
 .PP 
-- 
To unsubscribe or change options: https://lists.samba.org/mailman/listinfo/rsync
Before posting, read: http://www.catb.org/~esr/faqs/smart-questions.html

Reply via email to