Hi, The following patch adds a test that tries to trigger the race mentioned on debian bug #534879.
I got failures only if using TCP, but maybe the race exists if using sysv, being just harder to reproduce. --- test/Makefile.am | 5 +++ test/checktiming | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++ test/t.timing | 4 ++ test/timedchown.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ test/timedstat.c | 68 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 262 insertions(+), 0 deletions(-) create mode 100755 test/checktiming create mode 100755 test/t.timing create mode 100644 test/timedchown.c create mode 100644 test/timedstat.c diff --git a/test/Makefile.am b/test/Makefile.am index c7448b0..e12b6e9 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -22,4 +22,9 @@ TESTS_ENVIRONMENT = \ CLEANFILES = tmp* tartest.tar.gz hda3 check_SCRIPTS = $(TESTS) echo_arg tartest compare-tar defs +check_PROGRAMS = timedstat timedchown + +timedstat_SOURCES = timedstat.c +timedchown_SOURCES = timedchown.c + EXTRA_DIST = $(check_SCRIPTS) tartest.tar.gz.uue diff --git a/test/checktiming b/test/checktiming new file mode 100755 index 0000000..b7ec131 --- /dev/null +++ b/test/checktiming @@ -0,0 +1,91 @@ +#!/bin/sh +# fakeroot load-test +# +# This test tests if fakeroot breaks under load, especially ordering +# of calls between different processes. +# +# Copyright (c) 2009 Eduardo Habkost <ehabk...@raisama.net> +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +set -e + +tmp="$1" + +chmod_flood() +{ + while :;do + chmod 0777 $tmp/dummy.$1.* + chmod 0600 $tmp/dummy.$1.* + done +} + +create_dummy_files() +{ + echo Creating dummy files: + for t in `seq 1 $threads`;do + for n in `seq 1 $files`;do + touch $tmp/dummy.$t.$n + done + echo -n . + done + echo +} + +start_flooding() +{ + pids= + echo Creating flooder threads: + for t in `seq 1 $threads`;do + chmod_flood $t 2>/dev/null & + pids="$pids $!" + echo -n . + done + echo + trap terminate_threads EXIT INT +} + +terminate_threads() +{ + [ -n "$pids" ] && kill $pids + wait + pids= +} + + +mkdir -p "$tmp" + +threads=2 +files=20 + +create_dummy_files +start_flooding + +set -x + + +touch $tmp/testfile + +mkfifo $tmp/replies + +./timedchown 10 20 $tmp/testfile 1000 1000 $tmp/replies \ + | ./timedstat $tmp/testfile $tmp/replies + +terminate_threads +exit 0 diff --git a/test/t.timing b/test/t.timing new file mode 100755 index 0000000..6cb3c9c --- /dev/null +++ b/test/t.timing @@ -0,0 +1,4 @@ +#!/bin/sh +. ./defs || exit 1 + +run_fakeroot -- ${srcdir}/checktiming $tmp diff --git a/test/timedchown.c b/test/timedchown.c new file mode 100644 index 0000000..4327070 --- /dev/null +++ b/test/timedchown.c @@ -0,0 +1,94 @@ +/* Small utility to test ordering and timing on fakeroot + * + * Copyright (c) 2009 Eduardo Habkost <ehabk...@raisama.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <stdlib.h> + + +FILE *reply_fifo; + +void doit(const char *file, uid_t uid, uid_t uid2, int count) +{ + int i; + char reply[256]; + + fprintf(stderr, "dummy chown requests:\n"); + fflush(stderr); + + /* first, flood faked with other calls */ + for (i = 0; i < count; i++) { + if (chown(file, uid2, -1) < 0) + exit(1); + } + + fprintf(stderr, "real chown request:\n"); + fflush(stderr); + + /* now, send the real chown call: */ + if (chown(file, uid, -1) < 0) + exit(1); + + fprintf(stderr, "uid changed to %d. notifying.\n", (int)uid); + fflush(stderr); + + /* tell the other side we are done */ + printf("%d\n", (int)uid); + fflush(stdout); + + /* wait for the other side to reply */ + if (!fgets(reply, 256, reply_fifo)) + exit(1); + + fprintf(stderr, "got reply: %s\n", reply); + fflush(stderr); + +} + +int main(int argc, const char *argv[]) +{ + const char *file; + uid_t uid1, uid2; + int floodcount, loopcount, i; + + if (argc < 6) + return 1; + + uid1 = atoi(argv[1]); + uid2 = atoi(argv[2]); + file = argv[3]; + floodcount = atoi(argv[4]); + loopcount = atoi(argv[5]); + reply_fifo = fopen(argv[6], "r"); + if (!reply_fifo) + return 1; + + for (i = 0; i < loopcount; i++) { + /* alternate between uid1 and uid2 */ + doit(file, uid1, uid2, floodcount); + doit(file, uid2, uid1, floodcount); + } +} diff --git a/test/timedstat.c b/test/timedstat.c new file mode 100644 index 0000000..135a0bd --- /dev/null +++ b/test/timedstat.c @@ -0,0 +1,68 @@ +/* Small utility to test ordering and timing on fakeroot + * + * Copyright (c) 2009 Eduardo Habkost <ehabk...@raisama.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include <stdio.h> + +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + + +FILE *reply_fifo; + +int main(int argc, const char *argv[]) +{ + const char *filename; + + if (argc < 1) + return 1; + + filename = argv[1]; + reply_fifo = fopen(argv[2], "w"); + if (!reply_fifo) + return 1; + + while (1) { + uid_t uid; + char buf[256]; + + if (!fgets(buf, 256, stdin)) + return 0; + + uid = atoi(buf); + + struct stat st; + if (stat(argv[1], &st) < 0) + return 1; + + printf("expected uid: %d. mode: 0%o, uid: %d\n", (int)uid, (int)st.st_mode, (int)st.st_uid); + + if (uid != st.st_uid) { + fprintf(stderr, "FAIL: %d != %d\n", (int)uid, (int)st.st_uid); + return 1; + } + + fprintf(reply_fifo, "ok\n"); + fflush(reply_fifo); + } +} -- 1.6.4 -- Eduardo -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org