[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1432917024-3899-8-git-send-email-acme@kernel.org>
Date: Fri, 29 May 2015 13:30:17 -0300
From: Arnaldo Carvalho de Melo <acme@...nel.org>
To: Ingo Molnar <mingo@...nel.org>
Cc: linux-kernel@...r.kernel.org, Riku Voipio <riku.voipio@...aro.org>,
Peter Zijlstra <a.p.zijlstra@...llo.nl>,
Arnaldo Carvalho de Melo <acme@...hat.com>
Subject: [PATCH 07/14] perf tests: Aename open*.c to openat*.c
From: Riku Voipio <riku.voipio@...aro.org>
Since the test being tested is now openat rather than open, rename the
files to make it explicit. The patch is separeted from the first to make
it simpler to deal with any potential conflicts in the Makefile
Signed-off-by: Riku Voipio <riku.voipio@...aro.org>
Reviewed-by: Ingo Molnar <mingo@...nel.org>
Cc: Peter Zijlstra <a.p.zijlstra@...llo.nl>
Link: http://lkml.kernel.org/r/1429192375-13706-3-git-send-email-riku.voipio@linaro.org
[ Fixed it up wrt Build files ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@...hat.com>
---
tools/perf/tests/Build | 6 +-
tools/perf/tests/open-syscall-all-cpus.c | 115 --------------------------
tools/perf/tests/open-syscall-tp-fields.c | 121 ----------------------------
tools/perf/tests/open-syscall.c | 61 --------------
tools/perf/tests/openat-syscall-all-cpus.c | 115 ++++++++++++++++++++++++++
tools/perf/tests/openat-syscall-tp-fields.c | 121 ++++++++++++++++++++++++++++
tools/perf/tests/openat-syscall.c | 61 ++++++++++++++
7 files changed, 300 insertions(+), 300 deletions(-)
delete mode 100644 tools/perf/tests/open-syscall-all-cpus.c
delete mode 100644 tools/perf/tests/open-syscall-tp-fields.c
delete mode 100644 tools/perf/tests/open-syscall.c
create mode 100644 tools/perf/tests/openat-syscall-all-cpus.c
create mode 100644 tools/perf/tests/openat-syscall-tp-fields.c
create mode 100644 tools/perf/tests/openat-syscall.c
diff --git a/tools/perf/tests/Build b/tools/perf/tests/Build
index 67f48e6620e1..ee41e705b2eb 100644
--- a/tools/perf/tests/Build
+++ b/tools/perf/tests/Build
@@ -3,9 +3,9 @@ perf-y += parse-events.o
perf-y += dso-data.o
perf-y += attr.o
perf-y += vmlinux-kallsyms.o
-perf-y += open-syscall.o
-perf-y += open-syscall-all-cpus.o
-perf-y += open-syscall-tp-fields.o
+perf-y += openat-syscall.o
+perf-y += openat-syscall-all-cpus.o
+perf-y += openat-syscall-tp-fields.o
perf-y += mmap-basic.o
perf-y += perf-record.o
perf-y += rdpmc.o
diff --git a/tools/perf/tests/open-syscall-all-cpus.c b/tools/perf/tests/open-syscall-all-cpus.c
deleted file mode 100644
index e34dfdf96b5a..000000000000
--- a/tools/perf/tests/open-syscall-all-cpus.c
+++ /dev/null
@@ -1,115 +0,0 @@
-#include "evsel.h"
-#include "tests.h"
-#include "thread_map.h"
-#include "cpumap.h"
-#include "debug.h"
-
-int test__openat_syscall_event_on_all_cpus(void)
-{
- int err = -1, fd, cpu;
- struct cpu_map *cpus;
- struct perf_evsel *evsel;
- unsigned int nr_openat_calls = 111, i;
- cpu_set_t cpu_set;
- struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
- char sbuf[STRERR_BUFSIZE];
-
- if (threads == NULL) {
- pr_debug("thread_map__new\n");
- return -1;
- }
-
- cpus = cpu_map__new(NULL);
- if (cpus == NULL) {
- pr_debug("cpu_map__new\n");
- goto out_thread_map_delete;
- }
-
- CPU_ZERO(&cpu_set);
-
- evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
- if (evsel == NULL) {
- if (tracefs_configured())
- pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
- else if (debugfs_configured())
- pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
- else
- pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
- goto out_thread_map_delete;
- }
-
- if (perf_evsel__open(evsel, cpus, threads) < 0) {
- pr_debug("failed to open counter: %s, "
- "tweak /proc/sys/kernel/perf_event_paranoid?\n",
- strerror_r(errno, sbuf, sizeof(sbuf)));
- goto out_evsel_delete;
- }
-
- for (cpu = 0; cpu < cpus->nr; ++cpu) {
- unsigned int ncalls = nr_openat_calls + cpu;
- /*
- * XXX eventually lift this restriction in a way that
- * keeps perf building on older glibc installations
- * without CPU_ALLOC. 1024 cpus in 2010 still seems
- * a reasonable upper limit tho :-)
- */
- if (cpus->map[cpu] >= CPU_SETSIZE) {
- pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
- continue;
- }
-
- CPU_SET(cpus->map[cpu], &cpu_set);
- if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
- pr_debug("sched_setaffinity() failed on CPU %d: %s ",
- cpus->map[cpu],
- strerror_r(errno, sbuf, sizeof(sbuf)));
- goto out_close_fd;
- }
- for (i = 0; i < ncalls; ++i) {
- fd = openat(0, "/etc/passwd", O_RDONLY);
- close(fd);
- }
- CPU_CLR(cpus->map[cpu], &cpu_set);
- }
-
- /*
- * Here we need to explicitely preallocate the counts, as if
- * we use the auto allocation it will allocate just for 1 cpu,
- * as we start by cpu 0.
- */
- if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
- pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
- goto out_close_fd;
- }
-
- err = 0;
-
- for (cpu = 0; cpu < cpus->nr; ++cpu) {
- unsigned int expected;
-
- if (cpus->map[cpu] >= CPU_SETSIZE)
- continue;
-
- if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
- pr_debug("perf_evsel__read_on_cpu\n");
- err = -1;
- break;
- }
-
- expected = nr_openat_calls + cpu;
- if (evsel->counts->cpu[cpu].val != expected) {
- pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
- expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
- err = -1;
- }
- }
-
- perf_evsel__free_counts(evsel);
-out_close_fd:
- perf_evsel__close_fd(evsel, 1, threads->nr);
-out_evsel_delete:
- perf_evsel__delete(evsel);
-out_thread_map_delete:
- thread_map__delete(threads);
- return err;
-}
diff --git a/tools/perf/tests/open-syscall-tp-fields.c b/tools/perf/tests/open-syscall-tp-fields.c
deleted file mode 100644
index 6245221479d7..000000000000
--- a/tools/perf/tests/open-syscall-tp-fields.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "perf.h"
-#include "evlist.h"
-#include "evsel.h"
-#include "thread_map.h"
-#include "tests.h"
-#include "debug.h"
-
-int test__syscall_openat_tp_fields(void)
-{
- struct record_opts opts = {
- .target = {
- .uid = UINT_MAX,
- .uses_mmap = true,
- },
- .no_buffering = true,
- .freq = 1,
- .mmap_pages = 256,
- .raw_samples = true,
- };
- const char *filename = "/etc/passwd";
- int flags = O_RDONLY | O_DIRECTORY;
- struct perf_evlist *evlist = perf_evlist__new();
- struct perf_evsel *evsel;
- int err = -1, i, nr_events = 0, nr_polls = 0;
- char sbuf[STRERR_BUFSIZE];
-
- if (evlist == NULL) {
- pr_debug("%s: perf_evlist__new\n", __func__);
- goto out;
- }
-
- evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
- if (evsel == NULL) {
- pr_debug("%s: perf_evsel__newtp\n", __func__);
- goto out_delete_evlist;
- }
-
- perf_evlist__add(evlist, evsel);
-
- err = perf_evlist__create_maps(evlist, &opts.target);
- if (err < 0) {
- pr_debug("%s: perf_evlist__create_maps\n", __func__);
- goto out_delete_evlist;
- }
-
- perf_evsel__config(evsel, &opts);
-
- evlist->threads->map[0] = getpid();
-
- err = perf_evlist__open(evlist);
- if (err < 0) {
- pr_debug("perf_evlist__open: %s\n",
- strerror_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
- }
-
- err = perf_evlist__mmap(evlist, UINT_MAX, false);
- if (err < 0) {
- pr_debug("perf_evlist__mmap: %s\n",
- strerror_r(errno, sbuf, sizeof(sbuf)));
- goto out_delete_evlist;
- }
-
- perf_evlist__enable(evlist);
-
- /*
- * Generate the event:
- */
- openat(AT_FDCWD, filename, flags);
-
- while (1) {
- int before = nr_events;
-
- for (i = 0; i < evlist->nr_mmaps; i++) {
- union perf_event *event;
-
- while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
- const u32 type = event->header.type;
- int tp_flags;
- struct perf_sample sample;
-
- ++nr_events;
-
- if (type != PERF_RECORD_SAMPLE) {
- perf_evlist__mmap_consume(evlist, i);
- continue;
- }
-
- err = perf_evsel__parse_sample(evsel, event, &sample);
- if (err) {
- pr_err("Can't parse sample, err = %d\n", err);
- goto out_delete_evlist;
- }
-
- tp_flags = perf_evsel__intval(evsel, &sample, "flags");
-
- if (flags != tp_flags) {
- pr_debug("%s: Expected flags=%#x, got %#x\n",
- __func__, flags, tp_flags);
- goto out_delete_evlist;
- }
-
- goto out_ok;
- }
- }
-
- if (nr_events == before)
- perf_evlist__poll(evlist, 10);
-
- if (++nr_polls > 5) {
- pr_debug("%s: no events!\n", __func__);
- goto out_delete_evlist;
- }
- }
-out_ok:
- err = 0;
-out_delete_evlist:
- perf_evlist__delete(evlist);
-out:
- return err;
-}
diff --git a/tools/perf/tests/open-syscall.c b/tools/perf/tests/open-syscall.c
deleted file mode 100644
index 9f9491bb8e48..000000000000
--- a/tools/perf/tests/open-syscall.c
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "thread_map.h"
-#include "evsel.h"
-#include "debug.h"
-#include "tests.h"
-
-int test__openat_syscall_event(void)
-{
- int err = -1, fd;
- struct perf_evsel *evsel;
- unsigned int nr_openat_calls = 111, i;
- struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
- char sbuf[STRERR_BUFSIZE];
-
- if (threads == NULL) {
- pr_debug("thread_map__new\n");
- return -1;
- }
-
- evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
- if (evsel == NULL) {
- if (tracefs_configured())
- pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
- else if (debugfs_configured())
- pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
- else
- pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
- goto out_thread_map_delete;
- }
-
- if (perf_evsel__open_per_thread(evsel, threads) < 0) {
- pr_debug("failed to open counter: %s, "
- "tweak /proc/sys/kernel/perf_event_paranoid?\n",
- strerror_r(errno, sbuf, sizeof(sbuf)));
- goto out_evsel_delete;
- }
-
- for (i = 0; i < nr_openat_calls; ++i) {
- fd = openat(0, "/etc/passwd", O_RDONLY);
- close(fd);
- }
-
- if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
- pr_debug("perf_evsel__read_on_cpu\n");
- goto out_close_fd;
- }
-
- if (evsel->counts->cpu[0].val != nr_openat_calls) {
- pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
- nr_openat_calls, evsel->counts->cpu[0].val);
- goto out_close_fd;
- }
-
- err = 0;
-out_close_fd:
- perf_evsel__close_fd(evsel, 1, threads->nr);
-out_evsel_delete:
- perf_evsel__delete(evsel);
-out_thread_map_delete:
- thread_map__delete(threads);
- return err;
-}
diff --git a/tools/perf/tests/openat-syscall-all-cpus.c b/tools/perf/tests/openat-syscall-all-cpus.c
new file mode 100644
index 000000000000..e34dfdf96b5a
--- /dev/null
+++ b/tools/perf/tests/openat-syscall-all-cpus.c
@@ -0,0 +1,115 @@
+#include "evsel.h"
+#include "tests.h"
+#include "thread_map.h"
+#include "cpumap.h"
+#include "debug.h"
+
+int test__openat_syscall_event_on_all_cpus(void)
+{
+ int err = -1, fd, cpu;
+ struct cpu_map *cpus;
+ struct perf_evsel *evsel;
+ unsigned int nr_openat_calls = 111, i;
+ cpu_set_t cpu_set;
+ struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
+ char sbuf[STRERR_BUFSIZE];
+
+ if (threads == NULL) {
+ pr_debug("thread_map__new\n");
+ return -1;
+ }
+
+ cpus = cpu_map__new(NULL);
+ if (cpus == NULL) {
+ pr_debug("cpu_map__new\n");
+ goto out_thread_map_delete;
+ }
+
+ CPU_ZERO(&cpu_set);
+
+ evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
+ if (evsel == NULL) {
+ if (tracefs_configured())
+ pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
+ else if (debugfs_configured())
+ pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+ else
+ pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
+ goto out_thread_map_delete;
+ }
+
+ if (perf_evsel__open(evsel, cpus, threads) < 0) {
+ pr_debug("failed to open counter: %s, "
+ "tweak /proc/sys/kernel/perf_event_paranoid?\n",
+ strerror_r(errno, sbuf, sizeof(sbuf)));
+ goto out_evsel_delete;
+ }
+
+ for (cpu = 0; cpu < cpus->nr; ++cpu) {
+ unsigned int ncalls = nr_openat_calls + cpu;
+ /*
+ * XXX eventually lift this restriction in a way that
+ * keeps perf building on older glibc installations
+ * without CPU_ALLOC. 1024 cpus in 2010 still seems
+ * a reasonable upper limit tho :-)
+ */
+ if (cpus->map[cpu] >= CPU_SETSIZE) {
+ pr_debug("Ignoring CPU %d\n", cpus->map[cpu]);
+ continue;
+ }
+
+ CPU_SET(cpus->map[cpu], &cpu_set);
+ if (sched_setaffinity(0, sizeof(cpu_set), &cpu_set) < 0) {
+ pr_debug("sched_setaffinity() failed on CPU %d: %s ",
+ cpus->map[cpu],
+ strerror_r(errno, sbuf, sizeof(sbuf)));
+ goto out_close_fd;
+ }
+ for (i = 0; i < ncalls; ++i) {
+ fd = openat(0, "/etc/passwd", O_RDONLY);
+ close(fd);
+ }
+ CPU_CLR(cpus->map[cpu], &cpu_set);
+ }
+
+ /*
+ * Here we need to explicitely preallocate the counts, as if
+ * we use the auto allocation it will allocate just for 1 cpu,
+ * as we start by cpu 0.
+ */
+ if (perf_evsel__alloc_counts(evsel, cpus->nr) < 0) {
+ pr_debug("perf_evsel__alloc_counts(ncpus=%d)\n", cpus->nr);
+ goto out_close_fd;
+ }
+
+ err = 0;
+
+ for (cpu = 0; cpu < cpus->nr; ++cpu) {
+ unsigned int expected;
+
+ if (cpus->map[cpu] >= CPU_SETSIZE)
+ continue;
+
+ if (perf_evsel__read_on_cpu(evsel, cpu, 0) < 0) {
+ pr_debug("perf_evsel__read_on_cpu\n");
+ err = -1;
+ break;
+ }
+
+ expected = nr_openat_calls + cpu;
+ if (evsel->counts->cpu[cpu].val != expected) {
+ pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls on cpu %d, got %" PRIu64 "\n",
+ expected, cpus->map[cpu], evsel->counts->cpu[cpu].val);
+ err = -1;
+ }
+ }
+
+ perf_evsel__free_counts(evsel);
+out_close_fd:
+ perf_evsel__close_fd(evsel, 1, threads->nr);
+out_evsel_delete:
+ perf_evsel__delete(evsel);
+out_thread_map_delete:
+ thread_map__delete(threads);
+ return err;
+}
diff --git a/tools/perf/tests/openat-syscall-tp-fields.c b/tools/perf/tests/openat-syscall-tp-fields.c
new file mode 100644
index 000000000000..6245221479d7
--- /dev/null
+++ b/tools/perf/tests/openat-syscall-tp-fields.c
@@ -0,0 +1,121 @@
+#include "perf.h"
+#include "evlist.h"
+#include "evsel.h"
+#include "thread_map.h"
+#include "tests.h"
+#include "debug.h"
+
+int test__syscall_openat_tp_fields(void)
+{
+ struct record_opts opts = {
+ .target = {
+ .uid = UINT_MAX,
+ .uses_mmap = true,
+ },
+ .no_buffering = true,
+ .freq = 1,
+ .mmap_pages = 256,
+ .raw_samples = true,
+ };
+ const char *filename = "/etc/passwd";
+ int flags = O_RDONLY | O_DIRECTORY;
+ struct perf_evlist *evlist = perf_evlist__new();
+ struct perf_evsel *evsel;
+ int err = -1, i, nr_events = 0, nr_polls = 0;
+ char sbuf[STRERR_BUFSIZE];
+
+ if (evlist == NULL) {
+ pr_debug("%s: perf_evlist__new\n", __func__);
+ goto out;
+ }
+
+ evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
+ if (evsel == NULL) {
+ pr_debug("%s: perf_evsel__newtp\n", __func__);
+ goto out_delete_evlist;
+ }
+
+ perf_evlist__add(evlist, evsel);
+
+ err = perf_evlist__create_maps(evlist, &opts.target);
+ if (err < 0) {
+ pr_debug("%s: perf_evlist__create_maps\n", __func__);
+ goto out_delete_evlist;
+ }
+
+ perf_evsel__config(evsel, &opts);
+
+ evlist->threads->map[0] = getpid();
+
+ err = perf_evlist__open(evlist);
+ if (err < 0) {
+ pr_debug("perf_evlist__open: %s\n",
+ strerror_r(errno, sbuf, sizeof(sbuf)));
+ goto out_delete_evlist;
+ }
+
+ err = perf_evlist__mmap(evlist, UINT_MAX, false);
+ if (err < 0) {
+ pr_debug("perf_evlist__mmap: %s\n",
+ strerror_r(errno, sbuf, sizeof(sbuf)));
+ goto out_delete_evlist;
+ }
+
+ perf_evlist__enable(evlist);
+
+ /*
+ * Generate the event:
+ */
+ openat(AT_FDCWD, filename, flags);
+
+ while (1) {
+ int before = nr_events;
+
+ for (i = 0; i < evlist->nr_mmaps; i++) {
+ union perf_event *event;
+
+ while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
+ const u32 type = event->header.type;
+ int tp_flags;
+ struct perf_sample sample;
+
+ ++nr_events;
+
+ if (type != PERF_RECORD_SAMPLE) {
+ perf_evlist__mmap_consume(evlist, i);
+ continue;
+ }
+
+ err = perf_evsel__parse_sample(evsel, event, &sample);
+ if (err) {
+ pr_err("Can't parse sample, err = %d\n", err);
+ goto out_delete_evlist;
+ }
+
+ tp_flags = perf_evsel__intval(evsel, &sample, "flags");
+
+ if (flags != tp_flags) {
+ pr_debug("%s: Expected flags=%#x, got %#x\n",
+ __func__, flags, tp_flags);
+ goto out_delete_evlist;
+ }
+
+ goto out_ok;
+ }
+ }
+
+ if (nr_events == before)
+ perf_evlist__poll(evlist, 10);
+
+ if (++nr_polls > 5) {
+ pr_debug("%s: no events!\n", __func__);
+ goto out_delete_evlist;
+ }
+ }
+out_ok:
+ err = 0;
+out_delete_evlist:
+ perf_evlist__delete(evlist);
+out:
+ return err;
+}
diff --git a/tools/perf/tests/openat-syscall.c b/tools/perf/tests/openat-syscall.c
new file mode 100644
index 000000000000..9f9491bb8e48
--- /dev/null
+++ b/tools/perf/tests/openat-syscall.c
@@ -0,0 +1,61 @@
+#include "thread_map.h"
+#include "evsel.h"
+#include "debug.h"
+#include "tests.h"
+
+int test__openat_syscall_event(void)
+{
+ int err = -1, fd;
+ struct perf_evsel *evsel;
+ unsigned int nr_openat_calls = 111, i;
+ struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX);
+ char sbuf[STRERR_BUFSIZE];
+
+ if (threads == NULL) {
+ pr_debug("thread_map__new\n");
+ return -1;
+ }
+
+ evsel = perf_evsel__newtp("syscalls", "sys_enter_openat");
+ if (evsel == NULL) {
+ if (tracefs_configured())
+ pr_debug("is tracefs mounted on /sys/kernel/tracing?\n");
+ else if (debugfs_configured())
+ pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
+ else
+ pr_debug("Neither tracefs or debugfs is enabled in this kernel\n");
+ goto out_thread_map_delete;
+ }
+
+ if (perf_evsel__open_per_thread(evsel, threads) < 0) {
+ pr_debug("failed to open counter: %s, "
+ "tweak /proc/sys/kernel/perf_event_paranoid?\n",
+ strerror_r(errno, sbuf, sizeof(sbuf)));
+ goto out_evsel_delete;
+ }
+
+ for (i = 0; i < nr_openat_calls; ++i) {
+ fd = openat(0, "/etc/passwd", O_RDONLY);
+ close(fd);
+ }
+
+ if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
+ pr_debug("perf_evsel__read_on_cpu\n");
+ goto out_close_fd;
+ }
+
+ if (evsel->counts->cpu[0].val != nr_openat_calls) {
+ pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n",
+ nr_openat_calls, evsel->counts->cpu[0].val);
+ goto out_close_fd;
+ }
+
+ err = 0;
+out_close_fd:
+ perf_evsel__close_fd(evsel, 1, threads->nr);
+out_evsel_delete:
+ perf_evsel__delete(evsel);
+out_thread_map_delete:
+ thread_map__delete(threads);
+ return err;
+}
--
2.1.0
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists