summaryrefslogtreecommitdiff
path: root/regress/sys
diff options
context:
space:
mode:
authorArtur Grabowski <art@cvs.openbsd.org>2002-08-17 22:59:00 +0000
committerArtur Grabowski <art@cvs.openbsd.org>2002-08-17 22:59:00 +0000
commit7f2b2a365a362b001f712a8a345f416d49e6d6c7 (patch)
tree17851c809d9c905f2743a7fc7f561d373658c0a6 /regress/sys
parentaaccdca47a058c200f2afff68b3ae39a04aebc77 (diff)
Test for a nasty complication in the exec code.
What happens is that if an executable tries to exec itself (happens all the time on the ramdisk, among others) and needs to page in a page from the data segment (or rodata) it will need to perform a pagein operation on the vnode that's execing right now. exec keeps that vnode locked and fails (no deadlock, that part was fixed a long time ago).
Diffstat (limited to 'regress/sys')
-rw-r--r--regress/sys/kern/exec_self/Makefile5
-rw-r--r--regress/sys/kern/exec_self/exec_self.c44
2 files changed, 49 insertions, 0 deletions
diff --git a/regress/sys/kern/exec_self/Makefile b/regress/sys/kern/exec_self/Makefile
new file mode 100644
index 00000000000..ef8635b6d4d
--- /dev/null
+++ b/regress/sys/kern/exec_self/Makefile
@@ -0,0 +1,5 @@
+# $OpenBSD: Makefile,v 1.1 2002/08/17 22:58:59 art Exp $
+
+PROG= exec_self
+
+.include <bsd.regress.mk>
diff --git a/regress/sys/kern/exec_self/exec_self.c b/regress/sys/kern/exec_self/exec_self.c
new file mode 100644
index 00000000000..4bf39af5f7c
--- /dev/null
+++ b/regress/sys/kern/exec_self/exec_self.c
@@ -0,0 +1,44 @@
+/* $OpenBSD: exec_self.c,v 1.1 2002/08/17 22:58:59 art Exp $ */
+/*
+ * Written by Artur Grabowski <art@openbsd.org> 2002 Public Domain.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <err.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+struct {
+ const char pad1[256*1024]; /* avoid read-ahead. */
+ const char string[256*1024]; /* at least one page */
+ const char pad2[256*1024]; /* avoid read-behind. */
+} const blob = {
+ "padding1",
+ "the_test",
+ "padding2"
+};
+
+int
+main(int argc, char **argv)
+{
+ int pgsz = getpagesize();
+ vaddr_t va, off;
+
+ if (argc > 1) {
+ return (0);
+ }
+ va = (vaddr_t)&blob;
+ off = va & (pgsz - 1);
+
+ /* Make sure that nothing in the "blob" is cached. */
+ if (madvise((void *)(va - off), sizeof(blob) + (off > 0 ? pgsz : 0),
+ MADV_FREE))
+ err(1, "madvise");
+
+ if (execl(argv[0], argv[0], &blob.string, NULL))
+ err(1, "execl");
+
+ /* NOTREACHED */
+ return (1);
+}