1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/auxv.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
static int failed;
static void check(int ok, const char *what) {
printf("[inittest] %s: %s\n", ok ? "ok" : "FAILED", what);
if (!ok)
failed++;
}
static int read_file(const char *path, char *buf, size_t len) {
int fd = open(path, O_RDONLY);
if (fd < 0)
return -1;
int n = read(fd, buf, len - 1);
close(fd);
if (n >= 0)
buf[n] = 0;
return n;
}
static int is_dir(const char *path) {
struct stat st;
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
}
static void contract(int argc, char **argv) {
const char *path = getenv("PATH");
const char *headless = getenv("RUSTBELT_HEADLESS");
printf("[inittest] pid %d, argc %d, argv[0] %s, argv[1] %s, PATH=%s, RUSTBELT_HEADLESS=%s\n", getpid(), argc,
argv[0], argc > 1 ? argv[1] : "-", path ? path : "-", headless ? headless : "-");
check(getpid() == 1, "I am pid 1");
check(strcmp(argv[0], "init") == 0, "argv[0] is \"init\"");
check(!headless || (argc > 1 && strcmp(argv[1], "selftest") == 0), "headless: argv[1] is \"selftest\"");
check(path && strcmp(path, "/sbin:/bin:/usr/bin:/mnt/disk0/bin") == 0, "PATH=/sbin:/bin:/usr/bin:/mnt/disk0/bin");
char buf[256];
check(read_file("/etc/rootfs-v2", buf, sizeof buf) > 0 && strstr(buf, "ext2 root"), "/ is the ext2 root partition");
check(is_dir("/tmp") && is_dir("/dev") && is_dir("/proc") && is_dir("/mnt/disk0"), "/tmp /dev /proc /mnt/disk0 are there");
int fd = open("/tmp/inittest.tmp", O_CREAT | O_WRONLY | O_TRUNC, 0644);
check(fd >= 0 && write(fd, "x", 1) == 1, "/tmp is writable");
close(fd);
unlink("/tmp/inittest.tmp");
check(read_file("/mnt/share/hello.txt", buf, sizeof buf) > 0 && strcmp(buf, "Hello from the exFAT share!\n") == 0,
"/mnt/share/hello.txt reads back");
fd = open("/mnt/share/from-init.txt", O_CREAT | O_WRONLY | O_TRUNC, 0644);
check(fd >= 0 && write(fd, "written by init\n", 16) == 16, "/mnt/share is writable");
close(fd);
check(read_file("/mnt/share/from-init.txt", buf, sizeof buf) == 16 && strcmp(buf, "written by init\n") == 0,
"...and the new file reads back");
long pg = 4096;
char *anon = mmap(0, 2 * pg, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
check(anon != MAP_FAILED, "mmap MAP_SHARED|MAP_ANONYMOUS");
anon[0] = 1;
check(msync(anon, 2 * pg, MS_SYNC) == 0, "msync(MS_SYNC) = 0");
check(msync(anon, 1, MS_ASYNC | MS_INVALIDATE) == 0, "msync(MS_ASYNC|MS_INVALIDATE), partial page = 0");
check(msync(anon, 0, MS_SYNC) == 0, "msync(len 0) = 0");
check(msync(anon + 1, pg, MS_SYNC) == -1 && errno == EINVAL, "msync(unaligned) = EINVAL");
check(msync(anon, pg, 8) == -1 && errno == EINVAL, "msync(bad flags) = EINVAL");
check(msync(anon, pg, MS_SYNC | MS_ASYNC) == -1 && errno == EINVAL, "msync(MS_SYNC|MS_ASYNC) = EINVAL");
munmap(anon + pg, pg);
check(msync(anon, 2 * pg, MS_SYNC) == -1 && errno == ENOMEM, "msync over an unmapped page = ENOMEM");
munmap(anon, pg);
check(msync(anon, pg, MS_SYNC) == -1 && errno == ENOMEM, "msync(unmapped) = ENOMEM");
char *priv = mmap(0, pg, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
check(priv != MAP_FAILED && msync(priv, pg, MS_ASYNC) == 0, "msync(private mapping) = 0");
}
int main(int argc, char **argv) {
const char *execfn = (const char *)getauxval(AT_EXECFN);
printf("[inittest] started as %s\n", execfn ? execfn : "?");
if (execfn && strcmp(execfn, "/bin/init") == 0)
return 21;
if (execfn && strcmp(execfn, "/bin/sh") == 0)
return 22;
contract(argc, argv);
char buf[16];
int status = read_file("/etc/init-status", buf, sizeof buf) > 0 ? atoi(buf) : 0;
printf("[inittest] %d failed\n", failed);
fflush(stdout);
return failed ? 1 : status;
}
|