This is a delay diff for coreutils-5.97-23.el5_4.2.src.rpm (Scientific Linux 5.4) to add a -D option for rm, chown and chmod so that one can limit the amount of parallel operations in cluster filesystems. All other patches must have been applied before, e.g.: $ quilt -v setup coreutils.spec [...] $ cd coreutils-5.97 $ quilt push -a [...] $ patch -p1 < ~/coreutils-5.97-delay.diff patching file src/chmod.c patching file src/chown.c patching file src/chown-core.c patching file src/chown-core.h patching file src/remove.c patching file src/remove.h patching file src/rm.c $ signed off by Sebastian Krahmer diff -ruN coreutils-5.97/src/chmod.c coreutils-5.97.delay/src/chmod.c --- coreutils-5.97/src/chmod.c 2010-03-10 11:38:18.000000000 +0100 +++ coreutils-5.97.delay/src/chmod.c 2010-03-10 11:34:07.000000000 +0100 @@ -21,6 +21,9 @@ #include #include #include +#include +#include +#include #include "system.h" #include "dev-ino.h" @@ -58,6 +61,8 @@ V_off }; +static uint32_t delay = 0; + /* The name the program was run with. */ char *program_name; @@ -296,6 +301,8 @@ { FTSENT *ent; + if (delay) + usleep(delay); ent = fts_read (fts); if (ent == NULL) { @@ -337,6 +344,7 @@ fputs (_("\ Change the mode of each FILE to MODE.\n\ \n\ + -D delay delay in usec between two operations (default 0)\n\ -c, --changes like verbose but report only when a change is made\n\ "), stdout); fputs (_("\ @@ -385,12 +393,15 @@ recurse = force_silent = diagnose_surprises = false; while ((c = getopt_long (argc, argv, - "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::", + "D:Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::", long_options, NULL)) != -1) { switch (c) { + case 'D': + delay = strtoul(optarg, NULL, 10); + break; case 'r': case 'w': case 'x': diff -ruN coreutils-5.97/src/chown.c coreutils-5.97.delay/src/chown.c --- coreutils-5.97/src/chown.c 2005-05-14 09:58:36.000000000 +0200 +++ coreutils-5.97.delay/src/chown.c 2010-03-10 11:31:17.000000000 +0100 @@ -100,6 +100,7 @@ Change the owner and/or group of each FILE to OWNER and/or GROUP.\n\ With --reference, change the owner and group of each FILE to those of RFILE.\n\ \n\ + -D delay delay in usec between two chown operations (default 0)\n\ -c, --changes like verbose but report only when a change is made\n\ --dereference affect the referent of each symbolic link, rather\n\ than the symbolic link itself (this is the default)\n\ @@ -195,11 +196,14 @@ chopt_init (&chopt); - while ((optc = getopt_long (argc, argv, "HLPRcfhv", long_options, NULL)) + while ((optc = getopt_long (argc, argv, "HLPRcfhvD:", long_options, NULL)) != -1) { switch (optc) { + case 'D': + chopt.delay = strtoul(optarg, NULL, 10); + break; case 'H': /* Traverse command-line symlinks-to-directories. */ bit_flags = FTS_COMFOLLOW | FTS_PHYSICAL; break; diff -ruN coreutils-5.97/src/chown-core.c coreutils-5.97.delay/src/chown-core.c --- coreutils-5.97/src/chown-core.c 2010-03-10 11:38:18.000000000 +0100 +++ coreutils-5.97.delay/src/chown-core.c 2010-03-10 11:40:08.000000000 +0100 @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "system.h" #include "chown-core.h" @@ -57,6 +59,7 @@ chopt->force_silent = false; chopt->user_name = NULL; chopt->group_name = NULL; + chopt->delay = 0; } extern void @@ -463,6 +466,8 @@ { FTSENT *ent; + if (chopt->delay) + usleep(chopt->delay); ent = fts_read (fts); if (ent == NULL) { diff -ruN coreutils-5.97/src/chown-core.h coreutils-5.97.delay/src/chown-core.h --- coreutils-5.97/src/chown-core.h 2005-05-14 09:58:36.000000000 +0200 +++ coreutils-5.97.delay/src/chown-core.h 2010-03-10 11:28:32.000000000 +0100 @@ -21,6 +21,8 @@ # include "dev-ino.h" +#include + enum Change_status { CH_NOT_APPLIED = 1, @@ -64,6 +66,8 @@ /* The name of the group to which ownership of the files is being given. */ char *group_name; + + uint32_t delay; }; void diff -ruN coreutils-5.97/src/remove.c coreutils-5.97.delay/src/remove.c --- coreutils-5.97/src/remove.c 2010-03-10 11:38:17.000000000 +0100 +++ coreutils-5.97.delay/src/remove.c 2010-03-10 11:22:12.000000000 +0100 @@ -697,7 +697,9 @@ #define DO_UNLINK(Filename, X) \ do \ - { \ + { \ + if ((X)->delay) \ + usleep((X)->delay); \ if (unlink (Filename) == 0) \ { \ if ((X)->verbose) \ @@ -712,7 +714,9 @@ #define DO_RMDIR(Filename, X) \ do \ - { \ + { \ + if ((X)->delay) \ + usleep((X)->delay); \ if (rmdir (Filename) == 0) \ { \ if ((X)->verbose) \ diff -ruN coreutils-5.97/src/remove.h coreutils-5.97.delay/src/remove.h --- coreutils-5.97/src/remove.h 2005-05-14 09:58:37.000000000 +0200 +++ coreutils-5.97.delay/src/remove.h 2010-03-10 11:22:12.000000000 +0100 @@ -21,6 +21,7 @@ # define REMOVE_H # include "dev-ino.h" +#include struct rm_options { @@ -55,6 +56,10 @@ restore cwd (e.g., mv) and some others do not (e.g., rm, in many cases). */ bool require_restore_cwd; + + /* Delay between unlink() operations. Usefull for clusterFS' + * to limit amount of parallel operations */ + uint32_t delay; }; enum RM_status diff -ruN coreutils-5.97/src/rm.c coreutils-5.97.delay/src/rm.c --- coreutils-5.97/src/rm.c 2010-03-10 11:38:18.000000000 +0100 +++ coreutils-5.97.delay/src/rm.c 2010-03-10 11:31:05.000000000 +0100 @@ -137,6 +137,7 @@ fputs (_("\ Remove (unlink) the FILE(s).\n\ \n\ + -D delay in usec between two operations (default 0)\n\ -f, --force ignore nonexistent files, never prompt\n\ -i, --interactive prompt before any removal\n\ "), stdout); @@ -187,6 +188,8 @@ /* Since this program exits immediately after calling `rm', rm need not expend unnecessary effort to preserve the initial working directory. */ x->require_restore_cwd = false; + + x->delay = 0; } int @@ -206,10 +209,13 @@ rm_option_init (&x); - while ((c = getopt_long (argc, argv, "dfirvR", long_opts, NULL)) != -1) + while ((c = getopt_long (argc, argv, "dfirvRD:", long_opts, NULL)) != -1) { switch (c) { + case 'D': + x.delay = strtoul(optarg, NULL, 10); + break; case 'd': x.unlink_dirs = true; fprintf( stderr, "Warning: --directory (-d) option is undocumented"