diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-03-22 13:24:02 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-03-25 12:46:05 +0200 |
| commit | 2675f920652cc9218b4b3dc513c76b0546a5a5ae (patch) | |
| tree | 8ae9084acf230839d4b7f2eeef2ba4549ee8d35d /pkg/csource | |
| parent | 2e9d905410db5615d2e7d3418979d79249ac74f6 (diff) | |
sys/linux: add cgroup descriptions
Diffstat (limited to 'pkg/csource')
| -rw-r--r-- | pkg/csource/akaros_common.go | 5 | ||||
| -rw-r--r-- | pkg/csource/common.go | 3 | ||||
| -rw-r--r-- | pkg/csource/csource.go | 6 | ||||
| -rw-r--r-- | pkg/csource/csource_test.go | 1 | ||||
| -rw-r--r-- | pkg/csource/freebsd_common.go | 5 | ||||
| -rw-r--r-- | pkg/csource/linux_common.go | 290 | ||||
| -rw-r--r-- | pkg/csource/netbsd_common.go | 5 | ||||
| -rw-r--r-- | pkg/csource/options.go | 52 | ||||
| -rw-r--r-- | pkg/csource/options_test.go | 85 |
9 files changed, 360 insertions, 92 deletions
diff --git a/pkg/csource/akaros_common.go b/pkg/csource/akaros_common.go index 36b674520..d0009cac5 100644 --- a/pkg/csource/akaros_common.go +++ b/pkg/csource/akaros_common.go @@ -78,6 +78,11 @@ typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; +#ifdef SYZ_EXECUTOR +const int kInPipeFd = 250; +const int kOutPipeFd = 251; +#endif + #if defined(__GNUC__) #define SYSCALLAPI #define NORETURN __attribute__((noreturn)) diff --git a/pkg/csource/common.go b/pkg/csource/common.go index f77df3459..27caac40d 100644 --- a/pkg/csource/common.go +++ b/pkg/csource/common.go @@ -89,6 +89,9 @@ func defineList(p *prog.Prog, opts Options) ([]string, error) { if opts.EnableTun { defines = append(defines, "SYZ_TUN_ENABLE") } + if opts.EnableCgroups { + defines = append(defines, "SYZ_ENABLE_CGROUPS") + } if opts.UseTmpDir { defines = append(defines, "SYZ_USE_TMP_DIR") } diff --git a/pkg/csource/csource.go b/pkg/csource/csource.go index 759daa30f..6d20aed50 100644 --- a/pkg/csource/csource.go +++ b/pkg/csource/csource.go @@ -63,8 +63,8 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { } ctx.printf("};\n") } - if opts.Procs > 1 { - ctx.printf("uint64_t procid;\n") + if opts.Procs > 1 || opts.EnableCgroups { + ctx.printf("unsigned long long procid;\n") } if !opts.Repeat { @@ -93,7 +93,7 @@ func Write(p *prog.Prog, opts Options) ([]byte, error) { } ctx.print("\treturn 0;\n}\n") } else { - ctx.generateTestFunc(calls, len(vars) != 0, "test") + ctx.generateTestFunc(calls, len(vars) != 0, "execute_one") if opts.Procs <= 1 { ctx.print("int main()\n{\n") for _, c := range mmapCalls { diff --git a/pkg/csource/csource_test.go b/pkg/csource/csource_test.go index fa5eee58a..c90a5ff0a 100644 --- a/pkg/csource/csource_test.go +++ b/pkg/csource/csource_test.go @@ -89,6 +89,7 @@ func TestGenerateOptions(t *testing.T) { permutations = allPermutations } for i, opts := range permutations { + opts := opts t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { target, rs, iters := initTest(t) t.Logf("opts: %+v", opts) diff --git a/pkg/csource/freebsd_common.go b/pkg/csource/freebsd_common.go index b6aff4706..ef177b325 100644 --- a/pkg/csource/freebsd_common.go +++ b/pkg/csource/freebsd_common.go @@ -69,6 +69,11 @@ typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; +#ifdef SYZ_EXECUTOR +const int kInPipeFd = 250; +const int kOutPipeFd = 251; +#endif + #if defined(__GNUC__) #define SYSCALLAPI #define NORETURN __attribute__((noreturn)) diff --git a/pkg/csource/linux_common.go b/pkg/csource/linux_common.go index 12a2c1cac..8ddced733 100644 --- a/pkg/csource/linux_common.go +++ b/pkg/csource/linux_common.go @@ -44,15 +44,20 @@ var commonHeaderLinux = ` #include <sys/time.h> #include <sys/wait.h> #endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \ + defined(SYZ_ENABLE_CGROUPS) +#include <errno.h> +#include <fcntl.h> +#include <sys/stat.h> +#include <sys/types.h> +#endif #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_SETUID) #include <grp.h> #endif #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) -#include <fcntl.h> #include <linux/capability.h> #include <sys/mman.h> #include <sys/mount.h> -#include <sys/stat.h> #endif #if defined(SYZ_EXECUTOR) || defined(SYZ_TUN_ENABLE) #include <arpa/inet.h> @@ -121,11 +126,15 @@ var commonHeaderLinux = ` #include <unistd.h> #endif #if defined(SYZ_EXECUTOR) || defined(__NR_syz_genetlink_get_family_id) +#include <errno.h> #include <linux/genetlink.h> #include <linux/netlink.h> #include <sys/socket.h> #include <sys/types.h> #endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) +#include <sys/mount.h> +#endif #if defined(SYZ_EXECUTOR) || (defined(SYZ_REPEAT) && defined(SYZ_WAIT_REPEAT)) || \ defined(SYZ_USE_TMP_DIR) || defined(SYZ_HANDLE_SEGV) || defined(SYZ_TUN_ENABLE) || \ @@ -176,6 +185,11 @@ typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; +#ifdef SYZ_EXECUTOR +const int kInPipeFd = 250; +const int kOutPipeFd = 251; +#endif + #if defined(__GNUC__) #define SYSCALLAPI #define NORETURN __attribute__((noreturn)) @@ -1857,6 +1871,74 @@ static uintptr_t syz_kvm_setup_cpu(uintptr_t a0, uintptr_t a1, uintptr_t a2, uin #endif #endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_FAULT_INJECTION) || defined(SYZ_SANDBOX_NAMESPACE) || \ + defined(SYZ_ENABLE_CGROUPS) +static bool write_file(const char* file, const char* what, ...) +{ + char buf[1024]; + va_list args; + va_start(args, what); + vsnprintf(buf, sizeof(buf), what, args); + va_end(args); + buf[sizeof(buf) - 1] = 0; + int len = strlen(buf); + + int fd = open(file, O_WRONLY | O_CLOEXEC); + if (fd == -1) + return false; + if (write(fd, buf, len) != len) { + int err = errno; + close(fd); + errno = err; + return false; + } + close(fd); + return true; +} +#endif + +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) +static void setup_cgroups() +{ + if (mkdir("/syzcgroup", 0777)) { + debug("mkdir(/syzcgroup) failed: %d\n", errno); + } + if (mkdir("/syzcgroup/unified", 0777)) { + debug("mkdir(/syzcgroup/unified) failed: %d\n", errno); + } + if (mount("none", "/syzcgroup/unified", "cgroup2", 0, NULL)) { + debug("mount(cgroup2) failed: %d\n", errno); + } + if (chmod("/syzcgroup/unified", 0777)) { + debug("chmod(/syzcgroup/unified) failed: %d\n", errno); + } + if (!write_file("/syzcgroup/unified/cgroup.subtree_control", "+cpu +memory +io +pids +rdma")) { + debug("write(cgroup.subtree_control) failed: %d\n", errno); + } + if (mkdir("/syzcgroup/cpu", 0777)) { + debug("mkdir(/syzcgroup/cpu) failed: %d\n", errno); + } + if (mount("none", "/syzcgroup/cpu", "cgroup", 0, "cpuset,cpuacct,perf_event,hugetlb")) { + debug("mount(cgroup cpu) failed: %d\n", errno); + } + if (!write_file("/syzcgroup/cpu/cgroup.clone_children", "1")) { + debug("write(/syzcgroup/cpu/cgroup.clone_children) failed: %d\n", errno); + } + if (chmod("/syzcgroup/cpu", 0777)) { + debug("chmod(/syzcgroup/cpu) failed: %d\n", errno); + } + if (mkdir("/syzcgroup/net", 0777)) { + debug("mkdir(/syzcgroup/net) failed: %d\n", errno); + } + if (mount("none", "/syzcgroup/net", "cgroup", 0, "net_cls,net_prio,devices,freezer")) { + debug("mount(cgroup net) failed: %d\n", errno); + } + if (chmod("/syzcgroup/net", 0777)) { + debug("chmod(/syzcgroup/net) failed: %d\n", errno); + } +} +#endif + #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NONE) || defined(SYZ_SANDBOX_SETUID) || defined(SYZ_SANDBOX_NAMESPACE) static void loop(); @@ -1921,6 +2003,9 @@ static int do_sandbox_none(void) if (pid) return pid; +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + setup_cgroups(); +#endif sandbox_common(); if (unshare(CLONE_NEWNET)) { debug("unshare(CLONE_NEWNET): %d\n", errno); @@ -1946,6 +2031,9 @@ static int do_sandbox_setuid(void) if (pid) return pid; +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + setup_cgroups(); +#endif sandbox_common(); if (unshare(CLONE_NEWNET)) fail("unshare(CLONE_NEWNET)"); @@ -1969,29 +2057,6 @@ static int do_sandbox_setuid(void) } #endif -#if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) || defined(SYZ_FAULT_INJECTION) -static bool write_file(const char* file, const char* what, ...) -{ - char buf[1024]; - va_list args; - va_start(args, what); - vsnprintf(buf, sizeof(buf), what, args); - va_end(args); - buf[sizeof(buf) - 1] = 0; - int len = strlen(buf); - - int fd = open(file, O_WRONLY | O_CLOEXEC); - if (fd == -1) - return false; - if (write(fd, buf, len) != len) { - close(fd); - return false; - } - close(fd); - return true; -} -#endif - #if defined(SYZ_EXECUTOR) || defined(SYZ_SANDBOX_NAMESPACE) static int real_uid; static int real_gid; @@ -2038,6 +2103,29 @@ static int namespace_sandbox_proc(void* arg) if (mount("/sys/fs/selinux", selinux_path, NULL, mount_flags, NULL) && errno != ENOENT) fail("mount(/sys/fs/selinux) failed"); } + if (mkdir("./syz-tmp/newroot/sys", 0700)) + fail("mkdir failed"); + if (mount(NULL, "./syz-tmp/newroot/sys", "sysfs", 0, NULL)) + fail("mount(sysfs) failed"); +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + if (mkdir("./syz-tmp/newroot/syzcgroup", 0700)) + fail("mkdir failed"); + if (mkdir("./syz-tmp/newroot/syzcgroup/unified", 0700)) + fail("mkdir failed"); + if (mkdir("./syz-tmp/newroot/syzcgroup/cpu", 0700)) + fail("mkdir failed"); + if (mkdir("./syz-tmp/newroot/syzcgroup/net", 0700)) + fail("mkdir failed"); + if (mount("/syzcgroup/unified", "./syz-tmp/newroot/syzcgroup/unified", NULL, mount_flags, NULL)) { + debug("mount(cgroup2, MS_BIND) failed: %d\n", errno); + } + if (mount("/syzcgroup/cpu", "./syz-tmp/newroot/syzcgroup/cpu", NULL, mount_flags, NULL)) { + debug("mount(cgroup/cpu, MS_BIND) failed: %d\n", errno); + } + if (mount("/syzcgroup/net", "./syz-tmp/newroot/syzcgroup/net", NULL, mount_flags, NULL)) { + debug("mount(cgroup/net, MS_BIND) failed: %d\n", errno); + } +#endif if (mkdir("./syz-tmp/pivot", 0777)) fail("mkdir failed"); if (syscall(SYS_pivot_root, "./syz-tmp", "./syz-tmp/pivot")) { @@ -2076,6 +2164,9 @@ static int do_sandbox_namespace(void) { int pid; +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + setup_cgroups(); +#endif real_uid = getuid(); real_gid = getgid(); mprotect(sandbox_stack, 4096, PROT_NONE); @@ -2577,58 +2668,163 @@ static int fault_injected(int fail_fd) } #endif -#if defined(SYZ_REPEAT) -static void test(); +#if defined(SYZ_EXECUTOR) || defined(SYZ_REPEAT) +static void execute_one(); +extern unsigned long long procid; -#if defined(SYZ_WAIT_REPEAT) -void loop() +#if defined(SYZ_EXECUTOR) +void reply_handshake(); +void receive_execute(bool need_prog); +void reply_execute(int status); +extern uint32* output_data; +extern uint32* output_pos; +#endif + +#if defined(SYZ_EXECUTOR) || defined(SYZ_WAIT_REPEAT) +static void loop() { - int iter; -#if defined(SYZ_RESET_NET_NAMESPACE) +#if defined(SYZ_EXECUTOR) + reply_handshake(); +#endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE) checkpoint_net_namespace(); #endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + char cgroupdir[64]; + snprintf(cgroupdir, sizeof(cgroupdir), "/syzcgroup/unified/syz%llu", procid); + char cgroupdir_cpu[64]; + snprintf(cgroupdir_cpu, sizeof(cgroupdir_cpu), "/syzcgroup/cpu/syz%llu", procid); + char cgroupdir_net[64]; + snprintf(cgroupdir_net, sizeof(cgroupdir_net), "/syzcgroup/net/syz%llu", procid); +#endif + int iter; for (iter = 0;; iter++) { -#ifdef SYZ_USE_TMP_DIR - char cwdbuf[256]; +#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR) + char cwdbuf[32]; sprintf(cwdbuf, "./%d", iter); if (mkdir(cwdbuf, 0777)) fail("failed to mkdir"); #endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + if (mkdir(cgroupdir, 0777)) { + debug("mkdir(%s) failed: %d\n", cgroupdir, errno); + } + if (mkdir(cgroupdir_cpu, 0777)) { + debug("mkdir(%s) failed: %d\n", cgroupdir_cpu, errno); + } + if (mkdir(cgroupdir_net, 0777)) { + debug("mkdir(%s) failed: %d\n", cgroupdir_net, errno); + } +#endif +#if defined(SYZ_EXECUTOR) + receive_execute(false); +#endif int pid = fork(); if (pid < 0) - fail("loop fork failed"); + fail("clone failed"); if (pid == 0) { prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); setpgrp(); -#ifdef SYZ_USE_TMP_DIR +#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR) if (chdir(cwdbuf)) fail("failed to chdir"); #endif -#ifdef SYZ_TUN_ENABLE +#if defined(SYZ_EXECUTOR) + close(kInPipeFd); + close(kOutPipeFd); +#endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + if (symlink(cgroupdir, "./cgroup")) { + debug("symlink(%s, ./cgroup) failed: %d\n", cgroupdir, errno); + } + if (symlink(cgroupdir_cpu, "./cgroup.cpu")) { + debug("symlink(%s, ./cgroup.cpu) failed: %d\n", cgroupdir_cpu, errno); + } + if (symlink(cgroupdir_net, "./cgroup.net")) { + debug("symlink(%s, ./cgroup.net) failed: %d\n", cgroupdir_net, errno); + } + int pid = getpid(); + if (!write_file("./cgroup/cgroup.procs", "%d", pid)) { + debug("write(./cgroup/cgroup.procs) failed: %d\n", errno); + } + if (!write_file("./cgroup.cpu/cgroup.procs", "%d", pid)) { + debug("write(./cgroup.cpu/cgroup.procs) failed: %d\n", errno); + } + if (!write_file("./cgroup.net/cgroup.procs", "%d", pid)) { + debug("write(./cgroup.net/cgroup.procs) failed: %d\n", errno); + } +#endif +#if defined(SYZ_EXECUTOR) + if (flag_enable_tun) { + flush_tun(); + } + output_pos = output_data; +#elif defined(SYZ_TUN_ENABLE) flush_tun(); #endif - test(); + execute_one(); + debug("worker exiting\n"); doexit(0); } + debug("spawned worker pid %d\n", pid); + int status = 0; uint64 start = current_time_ms(); +#if defined(SYZ_EXECUTOR) + uint64 last_executed = start; + uint32 executed_calls = __atomic_load_n(output_data, __ATOMIC_RELAXED); +#endif for (;;) { int res = waitpid(-1, &status, __WALL | WNOHANG); - if (res == pid) + if (res == pid) { + debug("waitpid(%d)=%d\n", pid, res); break; + } usleep(1000); - if (current_time_ms() - start > 5 * 1000) { - kill(-pid, SIGKILL); - kill(pid, SIGKILL); - while (waitpid(-1, &status, __WALL) != pid) { - } - break; +#if defined(SYZ_EXECUTOR) + uint64 now = current_time_ms(); + uint32 now_executed = __atomic_load_n(output_data, __ATOMIC_RELAXED); + if (executed_calls != now_executed) { + executed_calls = now_executed; + last_executed = now; + } + if ((now - start < 3 * 1000) && (now - last_executed < 500)) + continue; +#else + if (current_time_ms() - start < 3 * 1000) + continue; +#endif + debug("waitpid(%d)=%d\n", pid, res); + debug("killing\n"); + kill(-pid, SIGKILL); + kill(pid, SIGKILL); + while (waitpid(-1, &status, __WALL) != pid) { } + break; } -#ifdef SYZ_USE_TMP_DIR +#if defined(SYZ_EXECUTOR) + status = WEXITSTATUS(status); + if (status == kFailStatus) + fail("child failed"); + if (status == kErrorStatus) + error("child errored"); + reply_execute(0); +#endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_USE_TMP_DIR) remove_dir(cwdbuf); #endif -#if defined(SYZ_RESET_NET_NAMESPACE) +#if defined(SYZ_EXECUTOR) || defined(SYZ_ENABLE_CGROUPS) + if (rmdir(cgroupdir)) { + debug("rmdir(%s) failed: %d\n", cgroupdir, errno); + } + if (rmdir(cgroupdir_cpu)) { + debug("rmdir(%s) failed: %d\n", cgroupdir_cpu, errno); + } + if (rmdir(cgroupdir_net)) { + debug("rmdir(%s) failed: %d\n", cgroupdir_net, errno); + } +#endif +#if defined(SYZ_EXECUTOR) || defined(SYZ_RESET_NET_NAMESPACE) reset_net_namespace(); #endif } @@ -2637,7 +2833,7 @@ void loop() void loop() { while (1) { - test(); + execute_one(); } } #endif diff --git a/pkg/csource/netbsd_common.go b/pkg/csource/netbsd_common.go index 1a7e3ee6e..55e424f3e 100644 --- a/pkg/csource/netbsd_common.go +++ b/pkg/csource/netbsd_common.go @@ -69,6 +69,11 @@ typedef unsigned int uint32; typedef unsigned short uint16; typedef unsigned char uint8; +#ifdef SYZ_EXECUTOR +const int kInPipeFd = 250; +const int kOutPipeFd = 251; +#endif + #if defined(__GNUC__) #define SYSCALLAPI #define NORETURN __attribute__((noreturn)) diff --git a/pkg/csource/options.go b/pkg/csource/options.go index 6d5f18fd5..d6fdf4739 100644 --- a/pkg/csource/options.go +++ b/pkg/csource/options.go @@ -23,11 +23,12 @@ type Options struct { FaultNth int // These options allow for a more fine-tuned control over the generated C code. - EnableTun bool - UseTmpDir bool - HandleSegv bool - WaitRepeat bool - Debug bool + EnableTun bool + UseTmpDir bool + EnableCgroups bool + HandleSegv bool + WaitRepeat bool + Debug bool // Generate code for use with repro package to prints log messages, // which allows to distinguish between a hang and an absent crash. @@ -55,6 +56,15 @@ func (opts Options) Check() error { // which will fail if procs>1 and on second run of the program. return errors.New("Sandbox=namespace without UseTmpDir") } + if opts.EnableTun && opts.Sandbox == "" { + return errors.New("EnableTun without sandbox") + } + if opts.EnableCgroups && opts.Sandbox == "" { + return errors.New("EnableCgroups without sandbox") + } + if opts.EnableCgroups && !opts.UseTmpDir { + return errors.New("EnableCgroups without UseTmpDir") + } return nil } @@ -72,14 +82,30 @@ func DeserializeOptions(data []byte) (Options, error) { &opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox, &opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.EnableTun, &opts.UseTmpDir, &opts.HandleSegv, &opts.WaitRepeat, &opts.Debug, &opts.Repro) - if err != nil { - return opts, fmt.Errorf("failed to parse repro options: %v", err) - } - if want := 14; n != want { - return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + if err == nil { + if want := 14; n != want { + return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + } + if opts.Sandbox == "empty" { + opts.Sandbox = "" + } + return opts, nil } - if opts.Sandbox == "empty" { - opts.Sandbox = "" + n, err = fmt.Sscanf(string(data), + "{Threaded:%t Collide:%t Repeat:%t Procs:%d Sandbox:%s"+ + " Fault:%t FaultCall:%d FaultNth:%d EnableTun:%t UseTmpDir:%t"+ + " EnableCgroups:%t HandleSegv:%t WaitRepeat:%t Debug:%t Repro:%t}", + &opts.Threaded, &opts.Collide, &opts.Repeat, &opts.Procs, &opts.Sandbox, + &opts.Fault, &opts.FaultCall, &opts.FaultNth, &opts.EnableTun, &opts.UseTmpDir, + &opts.EnableCgroups, &opts.HandleSegv, &opts.WaitRepeat, &opts.Debug, &opts.Repro) + if err == nil { + if want := 15; n != want { + return opts, fmt.Errorf("failed to parse repro options: got %v fields, want %v", n, want) + } + if opts.Sandbox == "empty" { + opts.Sandbox = "" + } + return opts, nil } - return opts, nil + return opts, err } diff --git a/pkg/csource/options_test.go b/pkg/csource/options_test.go index f3f42a6fc..890bac75f 100644 --- a/pkg/csource/options_test.go +++ b/pkg/csource/options_test.go @@ -29,36 +29,55 @@ func TestParseOptionsCanned(t *testing.T) { // so we need to be able to parse old formats. canned := map[string]Options{ "{Threaded:true Collide:true Repeat:true Procs:1 Sandbox:none Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{ - Threaded: true, - Collide: true, - Repeat: true, - Procs: 1, - Sandbox: "none", - Fault: false, - FaultCall: -1, - FaultNth: 0, - EnableTun: true, - UseTmpDir: true, - HandleSegv: true, - WaitRepeat: true, - Debug: false, - Repro: false, + Threaded: true, + Collide: true, + Repeat: true, + Procs: 1, + Sandbox: "none", + Fault: false, + FaultCall: -1, + FaultNth: 0, + EnableTun: true, + UseTmpDir: true, + EnableCgroups: false, + HandleSegv: true, + WaitRepeat: true, + Debug: false, + Repro: false, }, "{Threaded:true Collide:true Repeat:true Procs:1 Sandbox: Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{ - Threaded: true, - Collide: true, - Repeat: true, - Procs: 1, - Sandbox: "", - Fault: false, - FaultCall: -1, - FaultNth: 0, - EnableTun: true, - UseTmpDir: true, - HandleSegv: true, - WaitRepeat: true, - Debug: false, - Repro: false, + Threaded: true, + Collide: true, + Repeat: true, + Procs: 1, + Sandbox: "", + Fault: false, + FaultCall: -1, + FaultNth: 0, + EnableTun: true, + UseTmpDir: true, + EnableCgroups: false, + HandleSegv: true, + WaitRepeat: true, + Debug: false, + Repro: false, + }, + "{Threaded:false Collide:true Repeat:true Procs:1 Sandbox:namespace Fault:false FaultCall:-1 FaultNth:0 EnableTun:true UseTmpDir:true EnableCgroups:true HandleSegv:true WaitRepeat:true Debug:false Repro:false}": Options{ + Threaded: false, + Collide: true, + Repeat: true, + Procs: 1, + Sandbox: "namespace", + Fault: false, + FaultCall: -1, + FaultNth: 0, + EnableTun: true, + UseTmpDir: true, + EnableCgroups: true, + HandleSegv: true, + WaitRepeat: true, + Debug: false, + Repro: false, }, } for data, want := range canned { @@ -76,7 +95,15 @@ func allOptionsSingle() []Options { var opts []Options fields := reflect.TypeOf(Options{}).NumField() for i := 0; i < fields; i++ { - opts = append(opts, enumerateField(Options{}, i)...) + // Because of constraints on options, we need some defaults + // (e.g. no collide without threaded). + opt := Options{ + Threaded: true, + Repeat: true, + Sandbox: "none", + UseTmpDir: true, + } + opts = append(opts, enumerateField(opt, i)...) } return opts } |
