Exemplo n.º 1
0
/*
 *  stress_userfaultfd_child()
 *	generate page faults for parent to handle
 */
static int stress_userfaultfd_child(void *arg)
{
	context_t *c = (context_t *)arg;
	const args_t *args = c->args;

	(void)setpgid(0, g_pgrp);
	stress_parent_died_alarm();
	if (stress_sighandler(args->name, SIGALRM, stress_child_alarm_handler, NULL) < 0)
		return EXIT_NO_RESOURCE;

	do {
		uint8_t *ptr, *end = c->data + c->sz;

		/* hint we don't need these pages */
		if (shim_madvise(c->data, c->sz, MADV_DONTNEED) < 0) {
			pr_fail_err("userfaultfd madvise failed");
			(void)kill(c->parent, SIGALRM);
			return -1;
		}
		/* and trigger some page faults */
		for (ptr = c->data; ptr < end; ptr += c->page_size)
			*ptr = 0xff;
	} while (keep_stressing());

	return 0;
}
Exemplo n.º 2
0
/*
 *  stress_sigq
 *	stress by heavy sigqueue message sending
 */
static int stress_sigq(const args_t *args)
{
	pid_t pid;

	if (stress_sighandler(args->name, SIGUSR1, stress_sigqhandler, NULL) < 0)
		return EXIT_FAILURE;

again:
	pid = fork();
	if (pid < 0) {
		if (g_keep_stressing_flag && (errno == EAGAIN))
			goto again;
		pr_fail_dbg("fork");
		return EXIT_FAILURE;
	} else if (pid == 0) {
		sigset_t mask;

		(void)setpgid(0, g_pgrp);
		stress_parent_died_alarm();

		(void)sigemptyset(&mask);
		(void)sigaddset(&mask, SIGUSR1);

		while (g_keep_stressing_flag) {
			siginfo_t info;
			if (sigwaitinfo(&mask, &info) < 0)
				break;
			if (info.si_value.sival_int)
				break;
		}
		pr_dbg("%s: child got termination notice\n", args->name);
		pr_dbg("%s: exited on pid [%d] (instance %" PRIu32 ")\n",
			args->name, (int)getpid(), args->instance);
		_exit(0);
	} else {
		/* Parent */
		union sigval s;
		int status;

		do {
			(void)memset(&s, 0, sizeof(s));
			s.sival_int = 0;
			(void)sigqueue(pid, SIGUSR1, s);
			inc_counter(args);
		} while (keep_stressing());

		pr_dbg("%s: parent sent termination notice\n", args->name);
		(void)memset(&s, 0, sizeof(s));
		s.sival_int = 1;
		(void)sigqueue(pid, SIGUSR1, s);
		(void)shim_usleep(250);
		/* And ensure child is really dead */
		(void)kill(pid, SIGKILL);
		(void)shim_waitpid(pid, &status, 0);
	}

	return EXIT_SUCCESS;
}
Exemplo n.º 3
0
/*
 *  stress_timer
 *	stress timers
 */
static int stress_timer(const args_t *args)
{
	struct sigevent sev;
	struct itimerspec timer;
	sigset_t mask;
	uint64_t timer_freq = DEFAULT_TIMER_FREQ;

	(void)sigemptyset(&mask);
	(void)sigaddset(&mask, SIGINT);
	(void)sigprocmask(SIG_SETMASK, &mask, NULL);

	max_ops = args->max_ops;
	start = time_now();

	if (!get_setting("timer-freq", &timer_freq)) {
		if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
			timer_freq = MAX_TIMER_FREQ;
		if (g_opt_flags & OPT_FLAGS_MINIMIZE)
			timer_freq = MIN_TIMER_FREQ;
	}
	rate_ns = timer_freq ? 1000000000.0 / timer_freq : 1000000000.0;

	if (stress_sighandler(args->name, SIGRTMIN, stress_timer_handler, NULL) < 0)
		return EXIT_FAILURE;

	sev.sigev_notify = SIGEV_SIGNAL;
	sev.sigev_signo = SIGRTMIN;
	sev.sigev_value.sival_ptr = &timerid;
	if (timer_create(CLOCK_REALTIME, &sev, &timerid) < 0) {
		pr_fail_err("timer_create");
		return EXIT_FAILURE;
	}

	stress_timer_set(&timer);
	if (timer_settime(timerid, 0, &timer, NULL) < 0) {
		pr_fail_err("timer_settime");
		return EXIT_FAILURE;
	}

	do {
		struct timespec req;

		req.tv_sec = 0;
		req.tv_nsec = 10000000;
		(void)nanosleep(&req, NULL);
		set_counter(args, timer_counter);
	} while (keep_stressing());

	if (timer_delete(timerid) < 0) {
		pr_fail_err("timer_delete");
		return EXIT_FAILURE;
	}
	pr_dbg("%s: %" PRIu64 " timer overruns (instance %" PRIu32 ")\n",
		args->name, overruns, args->instance);

	return EXIT_SUCCESS;
}
Exemplo n.º 4
0
/*
 *  stress_msync()
 *	stress msync
 */
int stress_msync(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name)
{
	uint8_t *buf = NULL;
	const size_t page_size = stress_get_pagesize();
	const size_t min_size = 2 * page_size;
	size_t sz = min_size;
	ssize_t ret, rc = EXIT_SUCCESS;

	const pid_t pid = getpid();
	int fd = -1;
	char filename[PATH_MAX];

	ret = sigsetjmp(jmp_env, 1);
	if (ret) {
		pr_fail_err(name, "sigsetjmp");
		return EXIT_FAILURE;
	}
	if (stress_sighandler(name, SIGBUS, stress_sigbus_handler, NULL) < 0)
		return EXIT_FAILURE;

	if (!set_msync_bytes) {
		if (opt_flags & OPT_FLAGS_MAXIMIZE)
			opt_msync_bytes = MAX_MSYNC_BYTES;
		if (opt_flags & OPT_FLAGS_MINIMIZE)
			opt_msync_bytes = MIN_MSYNC_BYTES;
	}
	sz = opt_msync_bytes & ~(page_size - 1);
	if (sz < min_size)
		sz = min_size;

	/* Make sure this is killable by OOM killer */
	set_oom_adjustment(name, true);

	rc = stress_temp_dir_mk(name, pid, instance);
	if (rc < 0)
		return exit_status(-rc);

	(void)stress_temp_filename(filename, sizeof(filename),
		name, pid, instance, mwc32());

	(void)umask(0077);
	if ((fd = open(filename, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) {
		rc = exit_status(errno);
		pr_fail_err(name, "open");
		(void)unlink(filename);
		(void)stress_temp_dir_rm(name, pid, instance);

		return rc;
	}
	(void)unlink(filename);

	if (ftruncate(fd, sz) < 0) {
		pr_err(stderr, "%s: ftruncate failed, errno=%d (%s)\n",
			name, errno, strerror(errno));
		(void)close(fd);
		(void)stress_temp_dir_rm(name, pid, instance);

		return EXIT_FAILURE;
	}

	buf = (uint8_t *)mmap(NULL, sz,
		PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
	if (buf == MAP_FAILED) {
		pr_err(stderr, "%s: failed to mmap memory, errno=%d (%s)\n",
			name, errno, strerror(errno));
		rc = EXIT_NO_RESOURCE;
		goto err;
	}

	do {
		off_t offset;
		uint8_t val, data[page_size];

		ret = sigsetjmp(jmp_env, 1);
		if (ret) {
			/* Try again */
			continue;
		}
		/*
		 *  Change data in memory, msync to disk
		 */
		offset = (mwc64() % (sz - page_size)) & ~(page_size - 1);
		val = mwc8();

		memset(buf + offset, val, page_size);
		ret = msync(buf + offset, page_size, MS_SYNC);
		if (ret < 0) {
			pr_fail(stderr, "%s: msync MS_SYNC on "
				"offset %jd failed, errno=%d (%s)",
				name, (intmax_t)offset, errno, strerror(errno));
			goto do_invalidate;
		}
		ret = lseek(fd, offset, SEEK_SET);
		if (ret == (off_t)-1) {
			pr_err(stderr, "%s: cannot seet to offset %jd, "
				"errno=%d (%s)\n",
				name, (intmax_t)offset, errno, strerror(errno));
			rc = EXIT_NO_RESOURCE;
			break;
		}
		ret = read(fd, data, sizeof(data));
		if (ret < (ssize_t)sizeof(data)) {
			pr_fail(stderr, "%s: read failed, errno=%d (%s)\n",
				name, errno, strerror(errno));
			goto do_invalidate;
		}
		if (stress_page_check(data, val, sizeof(data)) < 0) {
			pr_fail(stderr, "%s: msync'd data in file different "
				"to data in memory\n", name);
		}

do_invalidate:
		/*
		 *  Now change data on disc, msync invalidate
		 */
		offset = (mwc64() % (sz - page_size)) & ~(page_size - 1);
		val = mwc8();

		memset(buf + offset, val, page_size);

		ret = lseek(fd, offset, SEEK_SET);
		if (ret == (off_t)-1) {
			pr_err(stderr, "%s: cannot seet to offset %jd, errno=%d (%s)\n",
				name, (intmax_t)offset, errno, strerror(errno));
			rc = EXIT_NO_RESOURCE;
			break;
		}
		ret = read(fd, data, sizeof(data));
		if (ret < (ssize_t)sizeof(data)) {
			pr_fail(stderr, "%s: read failed, errno=%d (%s)\n",
				name, errno, strerror(errno));
			goto do_next;
		}
		ret = msync(buf + offset, page_size, MS_INVALIDATE);
		if (ret < 0) {
			pr_fail(stderr, "%s: msync MS_INVALIDATE on "
				"offset %jd failed, errno=%d (%s)",
				name, (intmax_t)offset, errno, strerror(errno));
			goto do_next;
		}
		if (stress_page_check(buf + offset, val, sizeof(data)) < 0) {
			pr_fail(stderr, "%s: msync'd data in memory "
				"different to data in file\n", name);
		}
do_next:

		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

	(void)munmap((void *)buf, sz);
err:
	(void)close(fd);
	(void)stress_temp_dir_rm(name, pid, instance);

	if (sigbus_count)
		pr_inf(stdout, "%s: caught %" PRIu64 " SIGBUS signals\n",
			name, sigbus_count);
	return rc;
}
Exemplo n.º 5
0
/*
 *  stress_fault()
 *	stress min and max page faulting
 */
static int stress_fault(const args_t *args)
{
#if !defined(__HAIKU__)
	struct rusage usage;
#endif
	char filename[PATH_MAX];
	int ret;
	NOCLOBBER int i;

	ret = stress_temp_dir_mk_args(args);
	if (ret < 0)
		return exit_status(-ret);

	(void)stress_temp_filename_args(args,
		filename, sizeof(filename), mwc32());
	i = 0;

	if (stress_sighandler(args->name, SIGSEGV, stress_segvhandler, NULL) < 0)
		return EXIT_FAILURE;
	if (stress_sighandler(args->name, SIGBUS, stress_segvhandler, NULL) < 0)
		return EXIT_FAILURE;

	do {
		char *ptr;
		int fd;

		ret = sigsetjmp(jmp_env, 1);
		if (ret) {
			do_jmp = false;
			pr_err("%s: unexpected segmentation fault\n",
				args->name);
			break;
		}

		fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
		if (fd < 0) {
			if ((errno == ENOSPC) || (errno == ENOMEM))
				continue;	/* Try again */
			pr_fail_err("open");
			break;
		}
#if defined(HAVE_POSIX_FALLOCATE)
		if (posix_fallocate(fd, 0, 1) < 0) {
			if (errno == ENOSPC) {
				(void)close(fd);
				continue;	/* Try again */
			}
			(void)close(fd);
			pr_fail_err("posix_fallocate");
			break;
		}
#else
		{
			char buffer[1];

redo:
			if (g_keep_stressing_flag &&
			    (write(fd, buffer, sizeof(buffer)) < 0)) {
				if ((errno == EAGAIN) || (errno == EINTR))
					goto redo;
				if (errno == ENOSPC) {
					(void)close(fd);
					continue;
				}
				(void)close(fd);
				pr_fail_err("write");
				break;
			}
		}
#endif
		ret = sigsetjmp(jmp_env, 1);
		if (ret) {
			if (!keep_stressing())
				do_jmp = false;
			if (fd != -1)
				(void)close(fd);
			goto next;
		}

		/*
		 * Removing file here causes major fault when we touch
		 * ptr later
		 */
		if (i & 1)
			(void)unlink(filename);

		ptr = mmap(NULL, 1, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, 0);
		(void)close(fd);
		fd = -1;
		(void)fd;

		if (ptr == MAP_FAILED) {
			if ((errno == EAGAIN) ||
			    (errno == ENOMEM) ||
			    (errno == ENFILE))
				goto next;
			pr_err("%s: mmap failed: errno=%d (%s)\n",
				args->name, errno, strerror(errno));
			break;

		}
		*ptr = 0;	/* Cause the page fault */

		if (munmap(ptr, 1) < 0) {
			pr_err("%s: munmap failed: errno=%d (%s)\n",
				args->name, errno, strerror(errno));
			break;
		}

next:
		/* Remove file on-non major fault case */
		if (!(i & 1))
			(void)unlink(filename);

		i++;
		inc_counter(args);
	} while (keep_stressing());
	/* Clean up, most times this is redundant */
	(void)unlink(filename);
	(void)stress_temp_dir_rm_args(args);

#if !defined(__HAIKU__)
	if (!getrusage(RUSAGE_SELF, &usage)) {
		pr_dbg("%s: page faults: minor: %lu, major: %lu\n",
			args->name, usage.ru_minflt, usage.ru_majflt);
	}
#endif

	return EXIT_SUCCESS;
}
Exemplo n.º 6
0
/*
 *  stress_mergesort()
 *	stress mergesort
 */
static int stress_mergesort(const args_t *args)
{
	uint64_t mergesort_size = DEFAULT_MERGESORT_SIZE;
	int32_t *data, *ptr;
	size_t n, i;
	struct sigaction old_action;
	int ret;

	if (!get_setting("mergesort-size", &mergesort_size)) {
		if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
			mergesort_size = MAX_MERGESORT_SIZE;
		if (g_opt_flags & OPT_FLAGS_MINIMIZE)
			mergesort_size = MIN_MERGESORT_SIZE;
	}
	n = (size_t)mergesort_size;

	if ((data = calloc(n, sizeof(*data))) == NULL) {
		pr_fail_dbg("malloc");
		return EXIT_NO_RESOURCE;
	}

	if (stress_sighandler(args->name, SIGALRM, stress_mergesort_handler, &old_action) < 0) {
		free(data);
		return EXIT_FAILURE;
	}

	ret = sigsetjmp(jmp_env, 1);
	if (ret) {
		/*
		 * We return here if SIGALRM jmp'd back
		 */
		(void)stress_sigrestore(args->name, SIGALRM, &old_action);
		goto tidy;
	}

	/* This is expensive, do it once */
	for (ptr = data, i = 0; i < n; i++)
		*ptr++ = mwc32();

	do {
		/* Sort "random" data */
		if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_1) < 0) {
			pr_fail("%s: mergesort of random data failed: %d (%s)\n",
				args->name, errno, strerror(errno));
		} else {
			if (g_opt_flags & OPT_FLAGS_VERIFY) {
				for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
					if (*ptr > *(ptr+1)) {
						pr_fail("%s: sort error "
							"detected, incorrect ordering "
							"found\n", args->name);
						break;
					}
				}
			}
		}
		if (!g_keep_stressing_flag)
			break;

		/* Reverse sort */
		if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) {
			pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n",
                                args->name, errno, strerror(errno));
		} else {
			if (g_opt_flags & OPT_FLAGS_VERIFY) {
				for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
					if (*ptr < *(ptr+1)) {
						pr_fail("%s: reverse sort "
							"error detected, incorrect "
							"ordering found\n", args->name);
						break;
					}
				}
			}
		}
		if (!g_keep_stressing_flag)
			break;
		/* And re-order by random compare to remix the data */
		if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_3) < 0) {
			pr_fail("%s: mergesort failed: %d (%s)\n",
				args->name, errno, strerror(errno));
		}

		/* Reverse sort this again */
		if (mergesort(data, n, sizeof(*data), stress_mergesort_cmp_2) < 0) {
			pr_fail("%s: reversed mergesort of random data failed: %d (%s)\n",
				args->name, errno, strerror(errno));
		}
		if (g_opt_flags & OPT_FLAGS_VERIFY) {
			for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
				if (*ptr < *(ptr+1)) {
					pr_fail("%s: reverse sort "
						"error detected, incorrect "
						"ordering found\n", args->name);
					break;
				}
			}
		}
		if (!g_keep_stressing_flag)
			break;

		inc_counter(args);
	} while (keep_stressing());

	do_jmp = false;
	(void)stress_sigrestore(args->name, SIGALRM, &old_action);
tidy:
	free(data);

	return EXIT_SUCCESS;
}
Exemplo n.º 7
0
/*
 *  epoll_server()
 *	wait on connections and read data
 */
static void epoll_server(
	const int child,
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name,
	const pid_t ppid)
{
	int efd = -1, sfd = -1, rc = EXIT_SUCCESS;
	int so_reuseaddr = 1;
	int port = opt_epoll_port + child + (max_servers * instance);
	struct epoll_event *events = NULL;
	struct sockaddr *addr = NULL;
	socklen_t addr_len = 0;

	if (stress_sighandler(name, SIGALRM, handle_socket_sigalrm, NULL) < 0) {
		rc = EXIT_FAILURE;
		goto die;
	}
	if ((sfd = socket(opt_epoll_domain, SOCK_STREAM, 0)) < 0) {
		pr_fail_err(name, "socket");
		rc = EXIT_FAILURE;
		goto die;
	}
	if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr)) < 0) {
		pr_fail_err(name, "setsockopt");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	stress_set_sockaddr(name, instance, ppid,
		opt_epoll_domain, port, &addr, &addr_len);

	if (bind(sfd, addr, addr_len) < 0) {
		pr_fail_err(name, "bind");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (epoll_set_fd_nonblock(sfd) < 0) {
		pr_fail_err(name, "setting socket to non-blocking");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (listen(sfd, SOMAXCONN) < 0) {
		pr_fail_err(name, "listen");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if ((efd = epoll_create1(0)) < 0) {
		pr_fail_err(name, "epoll_create1");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if (epoll_ctl_add(efd, sfd) < 0) {
		pr_fail_err(name, "epoll ctl add");
		rc = EXIT_FAILURE;
		goto die_close;
	}
	if ((events = calloc(MAX_EPOLL_EVENTS, sizeof(struct epoll_event))) == NULL) {
		pr_fail_err(name, "epoll ctl add");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	do {
		int n, i;

		memset(events, 0, MAX_EPOLL_EVENTS * sizeof(struct epoll_event));
		errno = 0;

		/*
		 * Wait for 100ms for an event, allowing us to
		 * to break out if opt_do_run has been changed
		 */
		n = epoll_wait(efd, events, MAX_EPOLL_EVENTS, 100);
		if (n < 0) {
			if (errno != EINTR) {
				pr_fail_err(name, "epoll_wait");
				rc = EXIT_FAILURE;
				goto die_close;
			}
			break;
		}

		for (i = 0; i < n; i++) {
			if ((events[i].events & EPOLLERR) ||
			    (events[i].events & EPOLLHUP) ||
			    (!(events[i].events & EPOLLIN))) {
				/*
				 *  Error has occurred or fd is not
				 *  for reading anymore.. so reap fd
				 */
				(void)close(events[i].data.fd);
			} else if (sfd == events[i].data.fd) {
				/*
				 *  The listening socket has notification(s)
				 *  pending, so handle incoming connections
				 */
				if (epoll_notification(name, efd, sfd) < 0)
					break;
			} else {
				/*
				 *  The fd has data available, so read it
				 */
				epoll_recv_data(events[i].data.fd);
			}
		}
	} while (opt_do_run && (!max_ops || *counter < max_ops));

die_close:
	if (efd != -1)
		(void)close(efd);
	if (sfd != -1)
		(void)close(sfd);
die:
#ifdef AF_UNIX
	if (addr && (opt_epoll_domain == AF_UNIX)) {
		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
		(void)unlink(addr_un->sun_path);
	}
#endif
	free(events);

	exit(rc);
}
Exemplo n.º 8
0
/*
 *  stress_socket_server()
 *	server writer
 */
static int stress_socket_server(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name,
	const pid_t pid,
	const pid_t ppid)
{
	char buf[SOCKET_BUF];
	int fd, status;
	int so_reuseaddr = 1;
	socklen_t addr_len = 0;
	struct sockaddr *addr;
	uint64_t msgs = 0;
	int rc = EXIT_SUCCESS;

	setpgid(pid, pgrp);

	if (stress_sighandler(name, SIGALRM, handle_socket_sigalrm, NULL) < 0) {
		rc = EXIT_FAILURE;
		goto die;
	}
	if ((fd = socket(opt_socket_domain, SOCK_STREAM, 0)) < 0) {
		rc = exit_status(errno);
		pr_fail_dbg(name, "socket");
		goto die;
	}
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR,
		&so_reuseaddr, sizeof(so_reuseaddr)) < 0) {
		pr_fail_dbg(name, "setsockopt");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	stress_set_sockaddr(name, instance, ppid,
		opt_socket_domain, opt_socket_port, &addr, &addr_len);
	if (bind(fd, addr, addr_len) < 0) {
		rc = exit_status(errno);
		pr_fail_dbg(name, "bind");
		goto die_close;
	}
	if (listen(fd, 10) < 0) {
		pr_fail_dbg(name, "listen");
		rc = EXIT_FAILURE;
		goto die_close;
	}

	do {
		int sfd = accept(fd, (struct sockaddr *)NULL, NULL);
		if (sfd >= 0) {
			size_t i, j;
			struct sockaddr addr;
			socklen_t len;
			int sndbuf;
			struct msghdr msg;
			struct iovec vec[sizeof(buf)/16];
#if defined(HAVE_SENDMMSG)
			struct mmsghdr msgvec[MSGVEC_SIZE];
			unsigned int msg_len = 0;
#endif
#if defined(SOCKET_NODELAY)
			int one = 1;
#endif

			len = sizeof(addr);
			if (getsockname(fd, &addr, &len) < 0) {
				pr_fail_dbg(name, "getsockname");
				(void)close(sfd);
				break;
			}
			len = sizeof(sndbuf);
			if (getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &sndbuf, &len) < 0) {
				pr_fail_dbg(name, "getsockopt");
				(void)close(sfd);
				break;
			}
#if defined(SOCKET_NODELAY)
			if (opt_flags & OPT_FLAGS_SOCKET_NODELAY) {
				if (setsockopt(fd, SOL_TCP, TCP_NODELAY, &one, sizeof(one)) < 0) {
					pr_inf(stderr, "%s: setsockopt TCP_NODELAY "
						"failed and disabled, errno=%d (%s)\n",
						name, errno, strerror(errno));
					opt_flags &= ~OPT_FLAGS_SOCKET_NODELAY;
				}
			}
#endif
			memset(buf, 'A' + (*counter % 26), sizeof(buf));
			switch (opt_socket_opts) {
			case SOCKET_OPT_SEND:
				for (i = 16; i < sizeof(buf); i += 16) {
					ssize_t ret = send(sfd, buf, i, 0);
					if (ret < 0) {
						if (errno != EINTR)
							pr_fail_dbg(name, "send");
						break;
					} else
						msgs++;
				}
				break;
			case SOCKET_OPT_SENDMSG:
				for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) {
					vec[j].iov_base = buf;
					vec[j].iov_len = i;
				}
				memset(&msg, 0, sizeof(msg));
				msg.msg_iov = vec;
				msg.msg_iovlen = j;
				if (sendmsg(sfd, &msg, 0) < 0) {
					if (errno != EINTR)
						pr_fail_dbg(name, "sendmsg");
				} else
					msgs += j;
				break;
#if defined(HAVE_SENDMMSG)
			case SOCKET_OPT_SENDMMSG:
				memset(msgvec, 0, sizeof(msgvec));
				for (j = 0, i = 16; i < sizeof(buf); i += 16, j++) {
					vec[j].iov_base = buf;
					vec[j].iov_len = i;
					msg_len += i;
				}
				for (i = 0; i < MSGVEC_SIZE; i++) {
					msgvec[i].msg_hdr.msg_iov = vec;
					msgvec[i].msg_hdr.msg_iovlen = j;
				}
				if (sendmmsg(sfd, msgvec, MSGVEC_SIZE, 0) < 0) {
					if (errno != EINTR)
						pr_fail_dbg(name, "sendmmsg");
				} else
					msgs += (MSGVEC_SIZE * j);
				break;
#endif
			default:
				/* Should never happen */
				pr_err(stderr, "%s: bad option %d\n", name, opt_socket_opts);
				(void)close(sfd);
				goto die_close;
			}
			if (getpeername(sfd, &addr, &len) < 0) {
				pr_fail_dbg(name, "getpeername");
			}
			(void)close(sfd);
		}
		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

die_close:
	(void)close(fd);
die:
#ifdef AF_UNIX
	if (opt_socket_domain == AF_UNIX) {
		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
		(void)unlink(addr_un->sun_path);
	}
#endif
	if (pid) {
		(void)kill(pid, SIGKILL);
		(void)waitpid(pid, &status, 0);
	}
	pr_dbg(stderr, "%s: %" PRIu64 " messages sent\n", name, msgs);

	return rc;
}
Exemplo n.º 9
0
/*
 *  epoll_client()
 *	rapidly try to connect to server(s) and
 *	send a relatively short message
 */
static int epoll_client(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name,
	const pid_t ppid)
{
	int port_counter = 0;
	uint64_t connect_timeouts = 0;
	struct sigevent sev;
	struct itimerspec timer;
	struct sockaddr *addr = NULL;

	if (stress_sighandler(name, SIGRTMIN, epoll_timer_handler, NULL) < 0)
		return -1;

	do {
		char buf[4096];
		int fd, saved_errno;
		int retries = 0;
		int ret = -1;
		int port = opt_epoll_port + port_counter + (max_servers * instance);
		socklen_t addr_len = 0;

		/* Cycle through the servers */
		port_counter = (port_counter + 1) % max_servers;
retry:
		if (!opt_do_run)
			break;

		if ((fd = socket(opt_epoll_domain, SOCK_STREAM, 0)) < 0) {
			pr_fail_dbg(name, "socket");
			return -1;
		}

		sev.sigev_notify = SIGEV_SIGNAL;
		sev.sigev_signo = SIGRTMIN;
		sev.sigev_value.sival_ptr = &epoll_timerid;
		if (timer_create(CLOCK_REALTIME, &sev, &epoll_timerid) < 0) {
			pr_fail_err(name, "timer_create");
			(void)close(fd);
			return -1;
		}

		/*
		 * Allow 1 second for connection to occur,
		 * connect can block if the connection table
		 * fills up because we're waiting for TIME-OUTs
		 * to occur on previously closed connections
		 */
		timer.it_value.tv_sec = 0;
		timer.it_value.tv_nsec = 250000000;
		timer.it_interval.tv_sec = timer.it_value.tv_sec;
		timer.it_interval.tv_nsec = timer.it_value.tv_nsec;
		if (timer_settime(epoll_timerid, 0, &timer, NULL) < 0) {
			pr_fail_err(name, "timer_settime");
			(void)close(fd);
			return -1;
		}

		stress_set_sockaddr(name, instance, ppid,
			opt_epoll_domain, port, &addr, &addr_len);

		errno = 0;
		ret = connect(fd, addr, addr_len);
		saved_errno = errno;

		/* No longer need timer */
		if (timer_delete(epoll_timerid) < 0) {
			pr_fail_err(name, "timer_delete");
			(void)close(fd);
			return -1;
		}

		if (ret < 0) {
			switch (saved_errno) {
			case EINTR:
				connect_timeouts++;
				break;
			case ECONNREFUSED:	/* No servers yet running */
			case ENOENT:		/* unix domain not yet created */
				break;
			default:
				pr_dbg(stderr, "%s: connect failed: %d (%s)\n",
					name, saved_errno, strerror(saved_errno));
				break;
			}
			(void)close(fd);
			usleep(100000);		/* Twiddle fingers for a moment */

			retries++;
			if (retries > 1000) {
				/* Sigh, give up.. */
				errno = saved_errno;
				pr_fail_dbg(name, "too many connects");
				return -1;
			}
			goto retry;
		}

		memset(buf, 'A' + (*counter % 26), sizeof(buf));
		if (send(fd, buf, sizeof(buf), 0) < 0) {
			(void)close(fd);
			pr_fail_dbg(name, "send");
			break;
		}
		(void)close(fd);
#if defined(_POSIX_PRIORITY_SCHEDULING)
		sched_yield();
#endif
		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

#ifdef AF_UNIX
	if (addr && (opt_epoll_domain == AF_UNIX)) {
		struct sockaddr_un *addr_un = (struct sockaddr_un *)addr;
		(void)unlink(addr_un->sun_path);
	}
#endif
	if (connect_timeouts)
		pr_dbg(stderr, "%s: %" PRIu64 " x 0.25 second connect timeouts, "
			"connection table full (instance %" PRIu32 ")\n",
			name, connect_timeouts, instance);
	return EXIT_SUCCESS;
}
Exemplo n.º 10
0
/*
 *  stress_sigq
 *	stress by heavy sigqueue message sending
 */
int stress_sigq(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name)
{
	pid_t pid;

	if (stress_sighandler(name, SIGUSR1, stress_sigqhandler, NULL) < 0)
		return EXIT_FAILURE;

again:
	pid = fork();
	if (pid < 0) {
		if (opt_do_run && (errno == EAGAIN))
			goto again;
		pr_fail_dbg(name, "fork");
		return EXIT_FAILURE;
	} else if (pid == 0) {
		sigset_t mask;

		setpgid(0, pgrp);
		stress_parent_died_alarm();

		sigemptyset(&mask);
		sigaddset(&mask, SIGUSR1);

		while (opt_do_run) {
			siginfo_t info;
			sigwaitinfo(&mask, &info);
			if (info.si_value.sival_int)
				break;
		}
		pr_dbg(stderr, "%s: child got termination notice\n", name);
		pr_dbg(stderr, "%s: exited on pid [%d] (instance %" PRIu32 ")\n",
			name, getpid(), instance);
		_exit(0);
	} else {
		/* Parent */
		union sigval s;
		int status;

		do {
			memset(&s, 0, sizeof(s));
			s.sival_int = 0;
			sigqueue(pid, SIGUSR1, s);
			(*counter)++;
		} while (opt_do_run && (!max_ops || *counter < max_ops));

		pr_dbg(stderr, "%s: parent sent termination notice\n", name);
		memset(&s, 0, sizeof(s));
		s.sival_int = 1;
		sigqueue(pid, SIGUSR1, s);
		usleep(250);
		/* And ensure child is really dead */
		(void)kill(pid, SIGKILL);
		(void)waitpid(pid, &status, 0);
	}

	return EXIT_SUCCESS;
}
Exemplo n.º 11
0
/*
 *  stress_lease
 *	stress by fcntl lease activity
 */
static int stress_lease(const args_t *args)
{
	char filename[PATH_MAX];
	int ret, fd, status;
	pid_t l_pids[MAX_LEASE_BREAKERS];
	uint64_t i, lease_breakers = DEFAULT_LEASE_BREAKERS;

	if (!get_setting("lease-breakers", &lease_breakers)) {
		if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
			lease_breakers = MAX_LEASE_BREAKERS;
		if (g_opt_flags & OPT_FLAGS_MINIMIZE)
			lease_breakers = MIN_LEASE_BREAKERS;
	}

	(void)memset(l_pids, 0, sizeof(l_pids));

	if (stress_sighandler(args->name, SIGIO, stress_lease_handler, NULL) < 0)
		return EXIT_FAILURE;

	ret = stress_temp_dir_mk_args(args);
	if (ret < 0)
		return exit_status(-ret);
	(void)stress_temp_filename_args(args,
		filename, sizeof(filename), mwc32());

	fd = creat(filename, S_IRUSR | S_IWUSR);
	if (fd < 0) {
		ret = exit_status(errno);
		pr_err("%s: creat failed: errno=%d: (%s)\n",
			args->name, errno, strerror(errno));
		(void)stress_temp_dir_rm_args(args);
		return ret;
	}
	(void)close(fd);

	for (i = 0; i < lease_breakers; i++) {
		l_pids[i] = stress_lease_spawn(args, filename);
		if (l_pids[i] < 0) {
			pr_err("%s: failed to start all the lease breaker processes\n", args->name);
			goto reap;
		}
	}

	do {
		fd = open(filename, O_WRONLY | O_APPEND, S_IRUSR | S_IWUSR);
		if (fd < 0) {
			ret = exit_status(errno);
			pr_err("%s: open failed (parent): errno=%d: (%s)\n",
				args->name, errno, strerror(errno));
			goto reap;
		}
		while (fcntl(fd, F_SETLEASE, F_WRLCK) < 0) {
			if (!g_keep_stressing_flag) {
				(void)close(fd);
				goto reap;
			}
		}
		inc_counter(args);
		(void)shim_sched_yield();
		if (fcntl(fd, F_SETLEASE, F_UNLCK) < 0) {
			pr_err("%s: fcntl failed: errno=%d: (%s)\n",
				args->name, errno, strerror(errno));
			(void)close(fd);
			break;
		}
		(void)close(fd);
	} while (keep_stressing());

	ret = EXIT_SUCCESS;

reap:
	for (i = 0; i < lease_breakers; i++) {
		if (l_pids[i]) {
			(void)kill(l_pids[i], SIGKILL);
			(void)shim_waitpid(l_pids[i], &status, 0);
		}
	}

	(void)unlink(filename);
	(void)stress_temp_dir_rm_args(args);

	pr_dbg("%s: %" PRIu64 " lease sigio interrupts caught\n", args->name, lease_sigio);

	return ret;
}
Exemplo n.º 12
0
/*
 *  stress_mergesort()
 *	stress mergesort
 */
int stress_mergesort(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name)
{
	int32_t *data, *ptr;
	size_t n, i;
	struct sigaction old_action;
	int ret;

	(void)instance;

	if (!set_mergesort_size) {
		if (opt_flags & OPT_FLAGS_MAXIMIZE)
			opt_mergesort_size = MAX_MERGESORT_SIZE;
		if (opt_flags & OPT_FLAGS_MINIMIZE)
			opt_mergesort_size = MIN_MERGESORT_SIZE;
	}
	n = (size_t)opt_mergesort_size;

	if ((data = calloc(n, sizeof(int32_t))) == NULL) {
		pr_fail_dbg(name, "malloc");
		return EXIT_FAILURE;
	}

	if (stress_sighandler(name, SIGALRM, stress_mergesort_handler, &old_action) < 0) {
		free(data);
		return EXIT_FAILURE;
	}

	ret = sigsetjmp(jmp_env, 1);
	if (ret) {
		/*
		 * We return here if SIGALRM jmp'd back
		 */
		(void)stress_sigrestore(name, SIGALRM, &old_action);
		goto tidy;
	}

	/* This is expensive, do it once */
	for (ptr = data, i = 0; i < n; i++)
		*ptr++ = mwc32();

	do {
		/* Sort "random" data */
		mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_1);
		if (opt_flags & OPT_FLAGS_VERIFY) {
			for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
				if (*ptr > *(ptr+1)) {
					pr_fail(stderr, "%s: sort error "
						"detected, incorrect ordering "
						"found\n", name);
					break;
				}
			}
		}
		if (!opt_do_run)
			break;

		/* Reverse sort */
		mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_2);
		if (opt_flags & OPT_FLAGS_VERIFY) {
			for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
				if (*ptr < *(ptr+1)) {
					pr_fail(stderr, "%s: reverse sort "
						"error detected, incorrect "
						"ordering found\n", name);
					break;
				}
			}
		}
		if (!opt_do_run)
			break;
		/* And re-order by byte compare */
		mergesort(data, n * 4, sizeof(uint8_t), stress_mergesort_cmp_3);

		/* Reverse sort this again */
		mergesort(data, n, sizeof(uint32_t), stress_mergesort_cmp_2);
		if (opt_flags & OPT_FLAGS_VERIFY) {
			for (ptr = data, i = 0; i < n - 1; i++, ptr++) {
				if (*ptr < *(ptr+1)) {
					pr_fail(stderr, "%s: reverse sort "
						"error detected, incorrect "
						"ordering found\n", name);
					break;
				}
			}
		}
		if (!opt_do_run)
			break;

		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));

	do_jmp = false;
	(void)stress_sigrestore(name, SIGALRM, &old_action);
tidy:
	free(data);

	return EXIT_SUCCESS;
}
Exemplo n.º 13
0
/*
 *  stress_fault()
 *	stress min and max page faulting
 */
int stress_fault(
	uint64_t *const counter,
	const uint32_t instance,
	const uint64_t max_ops,
	const char *name)
{
	struct rusage usage;
	char filename[PATH_MAX];
	int ret, i;
	const pid_t pid = getpid();

	ret = stress_temp_dir_mk(name, pid, instance);
	if (ret < 0)
		return exit_status(-ret);

	(void)stress_temp_filename(filename, sizeof(filename),
		name, pid, instance, mwc32());
	(void)umask(0077);

	i = 0;

	if (stress_sighandler(name, SIGSEGV, stress_segvhandler, NULL) < 0)
		return EXIT_FAILURE;

	do {
		char *ptr;
		int fd;

		ret = sigsetjmp(jmp_env, 1);
		if (ret) {
			do_jmp = false;
			pr_err(stderr, "%s: unexpected segmentation fault\n", name);
			break;
		}

		fd = open(filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
		if (fd < 0) {
			if ((errno == ENOSPC) || (errno == ENOMEM))
				continue;	/* Try again */
			pr_err(stderr, "%s: open failed: errno=%d (%s)\n",
				name, errno, strerror(errno));
			break;
		}
#if _XOPEN_SOURCE >= 600 || _POSIX_C_SOURCE >= 200112L
		if (posix_fallocate(fd, 0, 1) < 0) {
			if (errno == ENOSPC) {
				(void)close(fd);
				continue;	/* Try again */
			}
			(void)close(fd);
			pr_err(stderr, "%s: posix_fallocate failed: errno=%d (%s)\n",
				name, errno, strerror(errno));
			break;
		}
#else
		{
			char buffer[1];

redo:
			if (opt_do_run && (write(fd, buffer, sizeof(buffer)) < 0)) {
				if ((errno == EAGAIN) || (errno == EINTR))
					goto redo;
				if (errno == ENOSPC) {
					(void)close(fd);
					continue;
				}
				(void)close(fd);
				pr_err(stderr, "%s: write failed: errno=%d (%s)\n",
					name, errno, strerror(errno));
				break;
			}
		}
#endif
		ret = sigsetjmp(jmp_env, 1);
		if (ret) {
			if (!opt_do_run || (max_ops && *counter >= max_ops))
				do_jmp = false;
			if (fd != -1)
				(void)close(fd);
			goto next;
		}

		/*
		 * Removing file here causes major fault when we touch
		 * ptr later
		 */
		if (i & 1)
			(void)unlink(filename);

		ptr = mmap(NULL, 1, PROT_READ | PROT_WRITE,
			MAP_SHARED, fd, 0);
		(void)close(fd);
		fd = -1;

		if (ptr == MAP_FAILED) {
			pr_err(stderr, "%s: mmap failed: errno=%d (%s)\n",
				name, errno, strerror(errno));
			break;

		}
		*ptr = 0;	/* Cause the page fault */

		if (munmap(ptr, 1) < 0) {
			pr_err(stderr, "%s: munmap failed: errno=%d (%s)\n",
				name, errno, strerror(errno));
			break;
		}

next:
		/* Remove file on-non major fault case */
		if (!(i & 1))
			(void)unlink(filename);

		i++;
		(*counter)++;
	} while (opt_do_run && (!max_ops || *counter < max_ops));
	/* Clean up, most times this is redundant */
	(void)unlink(filename);
	(void)stress_temp_dir_rm(name, pid, instance);

	if (!getrusage(RUSAGE_SELF, &usage)) {
		pr_dbg(stderr, "%s: page faults: minor: %lu, major: %lu\n",
			name, usage.ru_minflt, usage.ru_majflt);
	}

	return EXIT_SUCCESS;
}