int main(void) { int status; struct mq_attr attr; struct sigaction sa; sigset_t set; siginfo_t info; mqd_t mq; pid_t pid; PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); mq_unlink(MQNAME); sigemptyset(&set); sigaddset(&set, SIGRTMIN); sigprocmask(SIG_BLOCK, &set, NULL); sigemptyset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = (void *) SIG_DFL; sigaction(SIGRTMIN, &sa, NULL); attr.mq_maxmsg = 5; attr.mq_msgsize = 128; mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); if (mq == (mqd_t)-1) err(1, "mq_open()"); status = mq_getattr(mq, &attr); if (status) err(1, "mq_getattr()"); pid = fork(); if (pid == 0) { /* child */ int prio, j, i; char *buf; struct sigevent sigev; signal(SIGALRM, sighandler); sigev.sigev_notify = SIGEV_SIGNAL; sigev.sigev_signo = SIGRTMIN; sigev.sigev_value.sival_int = 2; mq_close(mq); mq = mq_open(MQNAME, O_RDWR | O_NONBLOCK); if (mq == (mqd_t)-1) err(1, "child: mq_open"); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { alarm(3); status = mq_notify(mq, &sigev); if (status) err(1, "child: mq_notify"); status = sigwaitinfo(&set, &info); if (status == -1) err(1, "child: sigwaitinfo"); if (info.si_value.sival_int != 2) err(1, "child: sival_int"); status = mq_receive(mq, buf, attr.mq_msgsize, &prio); if (status == -1) err(2, "child: mq_receive"); for (i = 0; i < attr.mq_msgsize; ++i) if (buf[i] != i) err(3, "child: message data corrupted"); if (prio != PRIO) err(4, "child: priority is incorrect: %d", prio); } alarm(0); free(buf); mq_close(mq); return (0); } else if (pid == -1) { err(1, "fork()"); } else { char *buf; int i, j; signal(SIGALRM, sighandler); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { for (i = 0; i < attr.mq_msgsize; ++i) { buf[i] = i; } alarm(3); status = mq_send(mq, buf, attr.mq_msgsize, PRIO); if (status) { kill(pid, SIGKILL); err(2, "mq_send()"); } } alarm(3); wait(&status); alarm(0); } status = mq_close(mq); if (status) err(1, "mq_close"); mq_unlink(MQNAME); return (0); }
int main(int argc, char **argv) { int create_tap = 1; int num_tests; int ret = 0; int j = 0; int k = -1; int list = 0; int opt; int i; #ifdef __FreeBSD__ PLAIN_REQUIRE_KERNEL_MODULE("if_tap", 0); PLAIN_REQUIRE_KERNEL_MODULE("netmap", 0); #endif memset(&ctx_, 0, sizeof(ctx_)); { struct timespec t; int idx; clock_gettime(CLOCK_REALTIME, &t); srand((unsigned int)t.tv_nsec); idx = rand() % 8000 + 100; snprintf(ctx_.ifname, sizeof(ctx_.ifname), "tap%d", idx); idx = rand() % 800 + 100; snprintf(ctx_.bdgname, sizeof(ctx_.bdgname), "vale%d", idx); } while ((opt = getopt(argc, argv, "hi:j:l")) != -1) { switch (opt) { case 'h': usage(argv[0]); return 0; case 'i': strncpy(ctx_.ifname, optarg, sizeof(ctx_.ifname) - 1); create_tap = 0; break; case 'j': if (parse_interval(optarg, &j, &k) < 0) { usage(argv[0]); return -1; } break; case 'l': list = 1; create_tap = 0; break; default: printf(" Unrecognized option %c\n", opt); usage(argv[0]); return -1; } } num_tests = sizeof(tests) / sizeof(tests[0]); if (j < 0 || j >= num_tests || k > num_tests) { fprintf(stderr, "Test interval %d-%d out of range (%d-%d)\n", j + 1, k, 1, num_tests + 1); return -1; } if (k < 0) k = num_tests; if (list) { printf("Available tests:\n"); for (i = 0; i < num_tests; i++) { printf("#%03d: %s\n", i + 1, tests[i].name); } return 0; } if (create_tap) { struct sigaction sa; const char *av[8]; int ac = 0; #ifdef __FreeBSD__ ARGV_APPEND(av, ac, "ifconfig"); ARGV_APPEND(av, ac, ctx_.ifname); ARGV_APPEND(av, ac, "create"); ARGV_APPEND(av, ac, "up"); #else ARGV_APPEND(av, ac, "ip"); ARGV_APPEND(av, ac, "tuntap"); ARGV_APPEND(av, ac, "add"); ARGV_APPEND(av, ac, "mode"); ARGV_APPEND(av, ac, "tap"); ARGV_APPEND(av, ac, "name"); ARGV_APPEND(av, ac, ctx_.ifname); #endif ARGV_APPEND(av, ac, NULL); if (exec_command(ac, av)) { printf("Failed to create tap interface\n"); return -1; } sa.sa_handler = tap_cleanup; sigemptyset(&sa.sa_mask); sa.sa_flags = SA_RESTART; ret = sigaction(SIGINT, &sa, NULL); if (ret) { perror("sigaction(SIGINT)"); goto out; } ret = sigaction(SIGTERM, &sa, NULL); if (ret) { perror("sigaction(SIGTERM)"); goto out; } } for (i = j; i < k; i++) { struct TestContext ctxcopy; int fd; printf("==> Start of Test #%d [%s]\n", i + 1, tests[i].name); fd = open("/dev/netmap", O_RDWR); if (fd < 0) { perror("open(/dev/netmap)"); ret = fd; goto out; } memcpy(&ctxcopy, &ctx_, sizeof(ctxcopy)); ctxcopy.fd = fd; memcpy(ctxcopy.ifname_ext, ctxcopy.ifname, sizeof(ctxcopy.ifname)); ret = tests[i].test(&ctxcopy); if (ret != 0) { printf("Test #%d [%s] failed\n", i + 1, tests[i].name); goto out; } printf("==> Test #%d [%s] successful\n", i + 1, tests[i].name); context_cleanup(&ctxcopy); } out: tap_cleanup(0); return ret; }
int main(void) { fd_set set; struct mq_attr attr; int status; mqd_t mq; pid_t pid; PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); mq_unlink(MQNAME); attr.mq_maxmsg = 5; attr.mq_msgsize = 128; mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); if (mq == (mqd_t)-1) err(1, "mq_open()"); status = mq_getattr(mq, &attr); if (status) err(1, "mq_getattr()"); pid = fork(); if (pid == 0) { /* child */ char *buf; int j, i; unsigned int prio; mq_close(mq); signal(SIGALRM, sighandler); mq = mq_open(MQNAME, O_RDWR); if (mq == (mqd_t)-1) err(1, "child process: mq_open"); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { FD_ZERO(&set); FD_SET(__mq_oshandle(mq), &set); alarm(3); status = select(__mq_oshandle(mq)+1, &set, NULL, NULL, NULL); if (status != 1) err(1, "child process: select()"); status = mq_receive(mq, buf, attr.mq_msgsize, &prio); if (status == -1) err(2, "child process: mq_receive"); for (i = 0; i < attr.mq_msgsize; ++i) if (buf[i] != i) err(3, "message data corrupted"); if (prio != PRIO) err(4, "priority is incorrect: %d", prio); } alarm(0); free(buf); mq_close(mq); return (0); } else if (pid == -1) { err(1, "fork()"); } else { char *buf; int i, j; signal(SIGALRM, sighandler); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { for (i = 0; i < attr.mq_msgsize; ++i) { buf[i] = i; } alarm(3); FD_ZERO(&set); FD_SET(__mq_oshandle(mq), &set); status = select(__mq_oshandle(mq)+1, NULL, &set, NULL, NULL); if (status != 1) err(1, "select()"); status = mq_send(mq, buf, attr.mq_msgsize, PRIO); if (status) { kill(pid, SIGKILL); err(2, "mq_send()"); } } alarm(3); wait(&status); alarm(0); } status = mq_close(mq); if (status) err(1, "mq_close"); mq_unlink(MQNAME); return (0); }
int main(void) { struct kevent kev; struct mq_attr attr; mqd_t mq; int kq, status; pid_t pid; PLAIN_REQUIRE_KERNEL_MODULE("mqueuefs", 0); mq_unlink(MQNAME); attr.mq_maxmsg = 5; attr.mq_msgsize = 128; mq = mq_open(MQNAME, O_CREAT | O_RDWR | O_EXCL, 0666, &attr); if (mq == (mqd_t) -1) err(1, "mq_open()"); status = mq_getattr(mq, &attr); if (status) err(1, "mq_getattr()"); pid = fork(); if (pid == 0) { /* child */ char *buf; int j, i; unsigned int prio; mq_close(mq); kq = kqueue(); mq = mq_open(MQNAME, O_RDWR); if (mq == (mqd_t)-1) err(1, "child: mq_open"); EV_SET(&kev, __mq_oshandle(mq), EVFILT_READ, EV_ADD, 0, 0, 0); status = kevent(kq, &kev, 1, NULL, 0, NULL); if (status == -1) err(1, "child: kevent"); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { alarm(3); status = kevent(kq, NULL, 0, &kev, 1, NULL); if (status != 1) err(1, "child: kevent 2"); status = mq_receive(mq, buf, attr.mq_msgsize, &prio); if (status == -1) err(2, "child: mq_receive"); for (i = 0; i < attr.mq_msgsize; ++i) if (buf[i] != i) err(3, "child: message data corrupted"); if (prio != PRIO) err(4, "child: priority is incorrect: %d", prio); } alarm(0); free(buf); mq_close(mq); return (0); } else if (pid == -1) { err(1, "fork()"); } else { char *buf; int i, j; signal(SIGALRM, sighandler); kq = kqueue(); EV_SET(&kev, __mq_oshandle(mq), EVFILT_WRITE, EV_ADD, 0, 0, 0); status = kevent(kq, &kev, 1, NULL, 0, NULL); if (status == -1) err(1, "kevent"); buf = malloc(attr.mq_msgsize); for (j = 0; j < LOOPS; ++j) { for (i = 0; i < attr.mq_msgsize; ++i) { buf[i] = i; } alarm(3); status = kevent(kq, NULL, 0, &kev, 1, NULL); if (status != 1) err(1, "child: kevent 2"); status = mq_send(mq, buf, attr.mq_msgsize, PRIO); if (status) { err(2, "mq_send()"); } } free(buf); alarm(3); wait(&status); alarm(0); } status = mq_close(mq); if (status) err(1, "mq_close"); mq_unlink(MQNAME); return (0); }
int main (int argc, char *argv[]) { struct aiocb *iocb[MAX_IOCBS], *kq_iocb; char *file, pathname[sizeof(PATH_TEMPLATE)+1]; struct kevent ke, kq_returned; struct timespec ts; char buffer[32768]; #ifdef DEBUG int cancel, error; #endif int failed = 0, fd, kq, pending, result, run; int tmp_file = 0; unsigned i, j; PLAIN_REQUIRE_KERNEL_MODULE("aio", 0); PLAIN_REQUIRE_UNSAFE_AIO(0); kq = kqueue(); if (kq < 0) { perror("No kqeueue\n"); exit(1); } if (argc == 1) { strcpy(pathname, PATH_TEMPLATE); fd = mkstemp(pathname); file = pathname; tmp_file = 1; } else { file = argv[1]; fd = open(file, O_RDWR|O_CREAT, 0666); } if (fd == -1) err(1, "Can't open %s\n", file); for (run = 0; run < MAX_RUNS; run++){ #ifdef DEBUG printf("Run %d\n", run); #endif for (i = 0; i < nitems(iocb); i++) { iocb[i] = (struct aiocb *)calloc(1, sizeof(struct aiocb)); if (iocb[i] == NULL) err(1, "calloc"); } pending = 0; for (i = 0; i < nitems(iocb); i++) { pending++; iocb[i]->aio_nbytes = sizeof(buffer); iocb[i]->aio_buf = buffer; iocb[i]->aio_fildes = fd; iocb[i]->aio_offset = iocb[i]->aio_nbytes * i * run; iocb[i]->aio_sigevent.sigev_notify_kqueue = kq; iocb[i]->aio_sigevent.sigev_value.sival_ptr = iocb[i]; iocb[i]->aio_sigevent.sigev_notify = SIGEV_KEVENT; result = aio_write(iocb[i]); if (result != 0) { perror("aio_write"); printf("Result %d iteration %d\n", result, i); exit(1); } #ifdef DEBUG printf("WRITE %d is at %p\n", i, iocb[i]); #endif result = rand(); if (result < RAND_MAX/32) { if (result > RAND_MAX/64) { result = aio_cancel(fd, iocb[i]); #ifdef DEBUG printf("Cancel %d %p result %d\n", i, iocb[i], result); #endif if (result == AIO_CANCELED) { aio_return(iocb[i]); iocb[i] = NULL; pending--; } } } } #ifdef DEBUG cancel = nitems(iocb) - pending; #endif i = 0; while (pending) { for (;;) { bzero(&ke, sizeof(ke)); bzero(&kq_returned, sizeof(ke)); ts.tv_sec = 0; ts.tv_nsec = 1; result = kevent(kq, NULL, 0, &kq_returned, 1, &ts); #ifdef DEBUG error = errno; #endif if (result < 0) perror("kevent error: "); kq_iocb = kq_returned.udata; #ifdef DEBUG printf("kevent %d %d errno %d return.ident %p " "return.data %p return.udata %p %p\n", i, result, error, kq_returned.ident, kq_returned.data, kq_returned.udata, kq_iocb); #endif if (kq_iocb) break; #ifdef DEBUG printf("Try again left %d out of %d %d\n", pending, nitems(iocb), cancel); #endif } for (j = 0; j < nitems(iocb) && iocb[j] != kq_iocb; j++) ; #ifdef DEBUG printf("kq_iocb %p\n", kq_iocb); printf("Error Result for %d is %d pending %d\n", j, result, pending); #endif result = aio_return(kq_iocb); #ifdef DEBUG printf("Return Result for %d is %d\n\n", j, result); #endif if (result != sizeof(buffer)) { printf("FAIL: run %d, operation %d, result %d " " (errno=%d) should be %zu\n", run, pending, result, errno, sizeof(buffer)); failed++; } else printf("PASS: run %d, left %d\n", run, pending - 1); free(kq_iocb); iocb[j] = NULL; pending--; i++; } for (i = 0; i < nitems(iocb); i++) free(iocb[i]); } if (tmp_file) unlink(pathname); if (failed != 0) printf("FAIL: %d tests failed\n", failed); else printf("PASS: All tests passed\n"); exit (failed == 0 ? 0 : 1); }