예제 #1
0
파일: lock.c 프로젝트: Open-Party/criu
void task_waiter_init(task_waiter_t *t)
{
    datagen((void *)&t->seed, sizeof(t->seed), NULL);
    t->seed = t->seed % TASK_WAITER_INITIAL;

    if (pipe(t->pipes)) {
        pr_perror("task_waiter_init failed");
        exit(1);
    }
}
예제 #2
0
파일: maps00.c 프로젝트: OSLL/pmover
static int make_map(struct map *map)
{
	uint32_t crc;
	uint8_t buf[ONE_MAP_SIZE];
	static int i = 0;

	if (!(map->flag & MAP_ANONYMOUS)) {
		/* need file */
		if (snprintf(map->filename, sizeof(map->filename),
					 "%s-%02d", filename, i++) >= sizeof(map->filename)) {
			err("filename %s is too long\n", filename);
			return -1;
		}

		map->fd = open(map->filename, O_RDWR | O_CREAT, 0600);
		if (map->fd < 0) {
			err("can't open %s: %m\n", map->filename);
			return -1;
		}

		crc = ~0;
		datagen(buf, sizeof(buf), &crc);
		if (write(map->fd, buf, sizeof(buf)) != sizeof(buf)) {
			err("failed to write %s: %m\n", map->filename);
			return -1;
		}
	}

	map->ptr = mmap(NULL, ONE_MAP_SIZE, map->prot, map->flag, map->fd, 0);
	if (map->ptr == MAP_FAILED) {
		err("can't create mapping: %m\n");
		return -1;
	}

	if ((map->flag & MAP_ANONYMOUS) && (map->prot & PROT_WRITE)) {
		/* can't fill it with data otherwise */
		crc = ~0;
		datagen(map->ptr, ONE_MAP_SIZE, &crc);
	}

	return 0;
}
예제 #3
0
파일: sigpending.c 프로젝트: xemul/criu
int send_siginfo(int signo, pid_t pid, pid_t tid, int group, siginfo_t *info)
{
	static int si_code = -10;
	uint32_t crc = ~0;

	info->si_code = si_code;
	si_code--;
	info->si_signo = signo;
	datagen((uint8_t *) siginf_body(info), _si_fields_sz, &crc);

	sent_sigs++;

	if (group)
		return syscall(SYS_rt_sigqueueinfo, pid, signo, info);
	else
		return syscall(SYS_rt_tgsigqueueinfo, pid, tid, signo, info);
}
예제 #4
0
파일: sigpending.c 프로젝트: huikang/criu
int send_siginfo(int signo, pid_t pid, pid_t tid, int group, siginfo_t *info)
{
	static int si_code = -10;
	uint32_t crc = ~0;

	info->si_code = si_code;
	si_code--;
	info->si_signo = signo;
	datagen((uint8_t *) &info->_sifields,
		    sizeof(siginfo_t) - offsetof(siginfo_t, _sifields), &crc);

	sent_sigs++;

	if (group)
		return syscall(SYS_rt_sigqueueinfo, pid, signo, info);
	else
		return syscall(SYS_rt_tgsigqueueinfo, pid, tid, signo, info);
}
예제 #5
0
파일: shm.c 프로젝트: 0x7f454c46/criu-1
static int fill_shm_seg(int id, size_t size)
{
	uint8_t *mem;
	uint32_t crc = INIT_CRC;

	mem = shmat(id, NULL, 0);
	if (mem == (void *)-1) {
		pr_perror("Can't attach shm: %d", -errno);
		return -1;
	}

	datagen(mem, size, &crc);

	if (shmdt(mem) < 0) {
		pr_perror("Can't detach shm: %d", -errno);
		return -1;
	}
	return 0;
}
예제 #6
0
int main(int argc, char ** argv)
{
	void *m;
	uint32_t crc;
	int i;

	test_init(argc, argv);

	m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ,
				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

	if (m == MAP_FAILED) {
		fail();
		return 1;
	}

	crc = ~0;
	datagen(m, MEM_SIZE, &crc);

	for (i = 0; i < MEM_SIZE / (1<<20); i++)
		if (mprotect(m + (lrand48() * PAGE_SIZE % MEM_SIZE), PAGE_SIZE, PROT_NONE)) {
			err("mprotect");
			return 1;
		}

	test_daemon();
	test_waitsig();

	if (mprotect(m, MEM_SIZE, PROT_READ))
		err("mprotect");

	crc = ~0;
	if (datachk(m, MEM_SIZE, &crc))
		fail("Mem corrupted");
	else
		pass();

	return 0;
}
예제 #7
0
파일: epoll.c 프로젝트: pombredanne/criu
static void run_child(int num)
{
    int fd = fds[num][1];
    uint32_t crc = ~0;
    size_t buf_size=512;
    uint8_t buf[buf_size];
    struct timeval tv;
    struct timespec ts;
    int rv;

    close(fds[num][0]);

    datagen(buf, sizeof(buf), &crc);

    if (gettimeofday(&tv, NULL) < 0) {
        rv = GETTIMEOFDAYERROR;
        goto out;
    }

    srand(tv.tv_sec + tv.tv_usec);

    ts.tv_sec = 0;
    while (!stop) {
        ts.tv_nsec = rand() % 999999999;
        nanosleep(&ts, &ts);
        if (write(fd, buf, buf_size) < 0 &&
                (!stop /* signal SIGUSR2 NOT received */ ||
                 (errno != EINTR && errno != EPIPE))) {
            fail("child write: %m\n");
            rv = WRITEERROR;
            goto out;
        }
    }
    rv = SUCCESS;
out:
    close(fds[num][1]);
    exit(rv);
}
예제 #8
0
파일: ipc.c 프로젝트: huikang/criu
static int child(key_t key)
{
	int sem, shm, ret, res = 0;
	uint8_t *mem;
	uint32_t crc;

	sem = semget(key, 1, 0777);
	if (sem == -1)
		return -1;
	shm = shmget(key, shmem_size, 0777);
	if (shm == -1)
		return -2;
	mem = shmat(shm, NULL, 0);
	if (mem == (uint8_t *)-1)
		return -3;

	while (test_go()) {
		ret = semop(sem, &lock, 1);
		if (ret) {
			if (errno == EINTR)
				continue;
			fail("Error in semop lock");
			res = errno;
			break;
		}
		crc = INIT_CRC;
		datagen(mem, shmem_size, &crc);
		while ((ret = semop(sem, &unlock, 1)) && (errno == EINTR));
		if (ret) {
			fail("Error in semop unlock");
			res = errno;
			break;
		}
	}
	shmdt(mem);
	return res;
}
예제 #9
0
int main(int argc, char **argv)
{
	int ret = 0;
	int readfd, writefd;
	mode_t mode = S_IFIFO | 0600;
	char path[PROCS_DEF][BUF_SIZE];
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int chret;
	char *file_path;

	test_init(argc, argv);

	for (i = 0; i < PROCS_DEF; i++) {
		file_path = path[i];
		if (snprintf(file_path, BUF_SIZE, "%s-%02d", filename, i) >= BUF_SIZE) {
			pr_perror("filename %s is too long", filename);
			exit(1);
		}
		if (mkfifo(file_path, mode)) {
			pr_perror("can't make fifo \"%s\"", file_path);
			exit(1);
		}
	}

	pid = test_fork();
	if (pid < 0) {
		pr_perror("Can't fork");
		kill(0, SIGKILL);
		exit(1);
	}
	if (pid == 0) {
		file_path = path[0];
		readfd = open(file_path, O_RDONLY);
		if (readfd < 0) {
			pr_perror("open(%s, O_RDONLY) Failed", file_path);
			ret = errno;
			return ret;
		}
		file_path = path[1];
		writefd = open(file_path, O_WRONLY);
		if (writefd < 0) {
			pr_perror("open(%s, O_WRONLY) Failed", file_path);
			ret = errno;
			return ret;
		}

		if (pipe_in2out(readfd, writefd, buf, sizeof(buf)) < 0)
			/* pass errno as exit code to the parent */
			if (test_go() /* signal NOT delivered */ ||
					(errno != EINTR && errno != EPIPE))
				ret = errno;
		close(readfd);
		close(writefd);
		exit(ret);
	}
	file_path = path[0];
	writefd = open(file_path, O_WRONLY);
	if (writefd < 0) {
		pr_perror("open(%s, O_WRONLY) Failed", file_path);
		kill(pid, SIGKILL);
		return 1;
	}

	file_path = path[1];
	readfd = open(file_path, O_RDONLY);
	if (readfd < 0) {
		pr_perror("open(%s, O_RDONLY) Failed", file_path);
		kill(pid, SIGKILL);
		return 1;
	}
	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(writefd, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n");
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(readfd, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(writefd);
	test_waitsig();

	wait(&chret);
	chret = WEXITSTATUS(chret);
	if (chret) {
		fail("child exited with non-zero code %d (%s)\n",
			chret, strerror(chret));
		return 1;
	}
	if (!ret)
		pass();
	close(readfd);
	for (i = 0; i < PROCS_DEF; i++)
		unlink(path[i]);
	return 0;
}
예제 #10
0
파일: socket-tcp.c 프로젝트: avagin/crtools
int main(int argc, char **argv)
{
	unsigned char buf[BUF_SIZE];
	int fd, fd_s;
	pid_t extpid;
	uint32_t crc;
	int pfd[2];
	int val;
	socklen_t optlen;

	if (pipe(pfd)) {
		err("pipe() failed");
		return 1;
	}

	extpid = fork();
	if (extpid < 0) {
		err("fork() failed");
		return 1;
	} else if (extpid == 0) {
		test_ext_init(argc, argv);

		close(pfd[1]);
		if (read(pfd[0], &port, sizeof(port)) != sizeof(port)) {
			err("Can't read port\n");
			return 1;
		}

		fd = tcp_init_client(ZDTM_FAMILY, "localhost", port);
		if (fd < 0)
			return 1;

#ifdef STREAM
		while (1) {
			if (read_data(fd, buf, BUF_SIZE)) {
				err("read less then have to");
				return 1;
			}
			if (datachk(buf, BUF_SIZE, &crc))
				return 2;

			datagen(buf, BUF_SIZE, &crc);
			if (write_data(fd, buf, BUF_SIZE)) {
				err("can't write");
				return 1;
			}
		}
#else
		if (read_data(fd, buf, BUF_SIZE)) {
			err("read less then have to");
			return 1;
		}
		if (datachk(buf, BUF_SIZE, &crc))
			return 2;

		datagen(buf, BUF_SIZE, &crc);
		if (write_data(fd, buf, BUF_SIZE)) {
			err("can't write");
			return 1;
		}
#endif
		return 0;
	}

	test_init(argc, argv);

	if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) {
		err("initializing server failed");
		return 1;
	}

	close(pfd[0]);
	if (write(pfd[1], &port, sizeof(port)) != sizeof(port)) {
		err("Can't send port");
		return 1;
	}
	close(pfd[1]);

	/*
	 * parent is server of TCP connection
	 */
	fd = tcp_accept_server(fd_s);
	if (fd < 0) {
		err("can't accept client connection %m");
		return 1;
	}

	val = 1;
	if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val))) {
		err("setsockopt");
		return 1;
	}

	test_daemon();
#ifdef STREAM
	while (test_go()) {
		datagen(buf, BUF_SIZE, &crc);
		if (write_data(fd, buf, BUF_SIZE)) {
			err("can't write");
			return 1;
		}

		if (read_data(fd, buf, BUF_SIZE)) {
			err("read less then have to");
			return 1;
		}
		if (datachk(buf, BUF_SIZE, &crc))
			return 2;
	}
	kill(extpid, SIGKILL);
#else
	test_waitsig();

	datagen(buf, BUF_SIZE, &crc);
	if (write_data(fd, buf, BUF_SIZE)) {
		err("can't write");
		return 1;
	}

	if (read_data(fd, buf, BUF_SIZE)) {
		err("read less then have to");
		return 1;
	}
	if (datachk(buf, BUF_SIZE, &crc))
		return 2;
#endif
	optlen = sizeof(val);
	if (getsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &val, &optlen)) {
		err("getsockopt");
		return 1;
	}
	if (val != 1) {
		fail("SO_REUSEADDR are not set for %d\n", fd);
		return 1;
	}

	pass();
	return 0;
}
예제 #11
0
파일: fifo_loop.c 프로젝트: OSLL/pmover
int main(int argc, char **argv)
{
	int ret = 0;
	int readfd, writefd;
	mode_t mode = S_IFIFO | 0644;
	char path[PROCS_DEF][BUF_SIZE];
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	char *file_path;

	test_init(argc, argv);

	for (i = 0; i < PROCS_DEF; i++) {
		file_path = path[i];
		if (snprintf(file_path, BUF_SIZE, "%s-%02d", filename, i) >= BUF_SIZE) {
			err("filename %s is too long\n", filename);
			exit(1);
		}
		if (mkfifo(file_path, mode)) {
			err("can't make fifo \"%s\": %m\n", file_path);
			exit(1);
		}
	}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}
		if (pid == 0) {
			file_path = path[i - 1];
			readfd = open(file_path, O_RDONLY);
			if (readfd < 0) {
				err("open(%s, O_RDONLY) Failed: %m\n",
					file_path);
				ret = errno;
				return ret;
			}
			file_path = path[i];
			writefd = open(file_path, O_WRONLY);
			if (writefd < 0) {
				err("open(%s, O_WRONLY) Failed: %m\n",
					file_path);
				ret = errno;
				return ret;
			}
			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(readfd, writefd, buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
						(errno != EINTR && errno != EPIPE))
					ret = errno;
			close(readfd);
			close(writefd);
			exit(ret);
		}
		pids[i] = pid;
	}

	file_path = path[0];
	writefd = open(file_path, O_WRONLY);
	if (writefd < 0) {
		err("open(%s, O_WRONLY) Failed: %m\n", file_path);
		kill(0, SIGKILL);
		exit(1);
	}

	file_path = path[i - 1];
	readfd = open(file_path, O_RDONLY);
	if (readfd < 0) {
		err("open(%s, O_RDONLY) Failed: %m\n", file_path);
		kill(0, SIGKILL);
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(writefd, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n");
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(readfd, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(writefd);

	test_waitsig(); /* even if failed, wait for migration to complete */

	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		return 1;	/* shouldn't wait() in this case */
	}
	close(readfd);

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (waitpid(pids[i], &chret, 0) < 0) {
			fail("waitpid error: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
				i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

	for (i = 0; i < PROCS_DEF; i++)
		unlink(path[i]);
	return 0;
}
예제 #12
0
int main(int argc, char ** argv)
{
	int sock, acc_sock, ret;
	char path[256];
	pid_t pid;
	uint32_t crc;
	uint8_t buf[1000];

	test_init(argc, argv);

	if (snprintf(path, sizeof(path), "%s/foo", dirname) >= sizeof(path)) {
		err("directory name \"%s\"is too long", dirname);
		exit(1);
	}

	if (mkdir(dirname, 0700)) {
		err("can't make directory %s: %m\n", dirname);
		exit(1);
	}

	sock = setup_srv_sock(path);
	if (sock < 0)
		goto out;

	pid = fork();
	if (pid < 0) {
		err("can't fork: %m\n");
		goto out;
	}

	if (pid == 0) {	/* child writes to the overmounted socket and returns */
		close(sock);

		sock = setup_clnt_sock(path);
		if (sock < 0)
			_exit(1);

		test_waitsig();

		crc = ~0;
		datagen(buf, sizeof(buf), &crc);
		if (write(sock, buf, sizeof(buf)) != sizeof(buf))
			_exit(errno);

		close(sock);
		_exit(0);
	}

	acc_sock = accept(sock, NULL, NULL);
	if (acc_sock < 0) {
		err("can't accept() the connection on \"%s\": %m", path);
		goto out_kill;
	}

	close(sock);
	sock = acc_sock;

	if (mount("rien", dirname, "tmpfs", 0, 0) < 0) {
		err("can't mount tmpfs over %s: %m", dirname);
		goto out_kill;
	}

	test_daemon();
	test_waitsig();

	if (kill(pid, SIGTERM)) {
		fail("terminating the child failed: %m\n");
		goto out;
	}

	if (wait(&ret) != pid) {
		fail("wait() returned wrong pid %d: %m\n", pid);
		goto out;
	}

	if (WIFEXITED(ret)) {
		ret = WEXITSTATUS(ret);
		if (ret) {
			fail("child exited with nonzero code %d (%s)\n", ret,
				strerror(ret));
			goto out;
		}
	}
	if (WIFSIGNALED(ret)) {
		fail("child exited on unexpected signal %d\n", WTERMSIG(ret));
		goto out;
	}

	if (read(sock, buf, sizeof(buf)) != sizeof(buf)) {
		fail("can't read %s: %m\n", path);
		goto out;
	}

	crc = ~0;
	if (datachk(buf, sizeof(buf), &crc)) {
		fail("CRC mismatch\n");
		goto out;
	}

	if (umount(dirname) < 0) {
		fail("can't umount %s: %m", dirname);
		goto out;
	}

	if (close(sock) < 0) {
		fail("can't close %s: %m", path);
		goto out;
	}

	if (unlink(path) < 0) {
		fail("can't unlink %s: %m", path);
		goto out;
	}

	pass();

out_kill:
	kill(pid, SIGKILL);
out:
	close(sock);
	unlink(path);
	rmdir(dirname);
	return 0;
}
예제 #13
0
int main(int argc, char ** argv)
{
	int fd;
	size_t fsize=1000;
	mode_t mode;
	uid_t uid;
	gid_t gid;
	uint8_t buf[fsize];
	struct stat fst;
	uint32_t crc;
#ifdef UNLINK_FSTAT04
	char filename[PATH_MAX];
#endif

	test_init(argc, argv);

#ifdef UNLINK_FSTAT04
	snprintf(filename, sizeof(filename), "%s/test\\file'\n\"un%%linkfstat00", dirname);

	mkdir(dirname, 0700);
#endif
	fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd < 0) {
		pr_perror("can't open %s", filename);
		exit(1);
	}

#ifdef UNLINK_FSTAT04
	if (chmod(dirname, 0500)) {
		pr_perror("chmod");
		exit(1);
	}
#endif

	if (fstat(fd, &fst) < 0) {
		pr_perror("can't get file info %s before", filename);
		goto failed;
	}

	if (unlink(filename) < 0) {
		pr_perror("can't unlink %s", filename);
		goto failed;
	}
	/* Change file size */
	if (fst.st_size != 0) {
		pr_perror("%s file size eq %d", fst.st_size);
		goto failed;
	}

	crc = ~0;
	datagen(buf, sizeof(buf), &crc);
	if (write(fd, buf, sizeof(buf)) != sizeof(buf)) {
		pr_perror("can't write %s", filename);
		goto failed;
	}
	/* Change file mode */
	if ((fst.st_mode & S_IXOTH) == 0)
		mode = (fst.st_mode | S_IXOTH);
	else
		mode = (fst.st_mode ^ S_IXOTH);

	if (fchmod(fd, mode) < 0) {
		pr_perror("can't chmod %s", filename);
		goto failed;
	}

	if (getuid()) {
		uid = getuid();
		gid = getgid();
	} else {
		/* Change uid, gid */
		if (fchown(fd, (uid = fst.st_uid + 1), (gid = fst.st_gid + 1)) < 0) {
			pr_perror("can't chown %s", filename);
			goto failed;
		}
	}

	if (lseek(fd, 0, SEEK_SET) != 0) {
		pr_perror("can't reposition to 0");
		goto failed;
	}

	test_daemon();
	test_waitsig();

	if (fstat(fd, &fst) < 0) {
		pr_perror("can't get %s file info after", filename);
		goto failed;
	}

	/* Check file size */
	if (fst.st_size != fsize) {
		fail("(via fstat): file size changed to %d", fst.st_size);
		goto failed;
	}
	fst.st_size = lseek(fd, 0, SEEK_END);
	if (fst.st_size != fsize) {
		fail("(via lseek): file size changed to %d", fst.st_size);
		goto failed;
	}
	/* Check mode */
	if (fst.st_mode != mode) {
		fail("mode is changed to %o(%o)", fst.st_mode, mode);
		goto failed;
	}
	/* Check uid, gid */
	if (fst.st_uid != uid || fst.st_gid != gid) {
		fail("u(g)id changed: uid=%d(%d), gid=%d(%d)",
				fst.st_uid, uid, fst.st_gid, gid);
		goto failed;
	}

	if (lseek(fd, 0, SEEK_SET) != 0) {
		pr_perror("can't reposition to 0");
		goto failed;
	}
	if (read(fd, buf, sizeof(buf)) != sizeof(buf)) {
		fail("can't read %s: %m\n", filename);
		goto failed;
	}

	crc = ~0;
	if (datachk(buf, sizeof(buf), &crc)) {
		fail("CRC mismatch\n");
		goto failed;
	}

	close(fd);

	pass();
	return 0;
failed:
	unlink(filename);
	close(fd);
	return 1;
}
예제 #14
0
int main(int argc, char ** argv)
{
    int sock, acc_sock, ret;
    pid_t pid;
    uint32_t crc;
    uint8_t buf[1000];

    test_init(argc, argv);

    sock = setup_srv_sock();
    if (sock < 0)
        exit(1);

    pid = test_fork();
    if (pid < 0) {
        pr_perror("can't fork");
        exit(1);
    }

    if (pid == 0) {	/* child writes to the unlinked socket and returns */
        close(sock);

        sock = setup_clnt_sock();
        if (sock < 0)
            _exit(1);

        test_waitsig();

        crc = ~0;
        datagen(buf, sizeof(buf), &crc);
        if (write(sock, buf, sizeof(buf)) != sizeof(buf)) {
            pr_perror("can't write to socket");
            exit(errno);
        }

        close(sock);
        exit(0);
    }

    acc_sock = accept(sock, NULL, NULL);
    if (acc_sock < 0) {
        pr_perror("can't accept() the connection on \"%s\"", filename);
        goto out_kill;
    }

    close(sock);
    sock = acc_sock;

    if (unlink(filename)) {
        pr_perror("can't unlink %s", filename);
        goto out_kill;
    }

    test_daemon();
    test_waitsig();

    if (kill(pid, SIGTERM)) {
        fail("terminating the child failed: %m\n");
        goto out;
    }

    if (wait(&ret) != pid) {
        fail("wait() returned wrong pid %d: %m\n", pid);
        goto out;
    }

    if (WIFEXITED(ret)) {
        ret = WEXITSTATUS(ret);
        if (ret) {
            fail("child exited with nonzero code %d (%s)\n", ret, strerror(ret));
            goto out;
        }
    }
    if (WIFSIGNALED(ret)) {
        fail("child exited on unexpected signal %d\n", WTERMSIG(ret));
        goto out;
    }

    if (read(sock, buf, sizeof(buf)) != sizeof(buf)) {
        fail("can't read %s: %m\n", filename);
        goto out;
    }

    crc = ~0;
    if (datachk(buf, sizeof(buf), &crc)) {
        fail("CRC mismatch\n");
        goto out;
    }


    if (close(sock)) {
        fail("close failed: %m\n");
        goto out;
    }

    if (unlink(filename) != -1 || errno != ENOENT) {
        fail("file %s should have been deleted before migration: unlink: %m\n", filename);
        goto out;
    }

    pass();

out_kill:
    kill(pid, SIGTERM);
out:
    close(sock);
    return 0;
}
예제 #15
0
파일: maps01.c 프로젝트: OSLL/pmover
int main(int argc, char ** argv)
{
	void *m, *m2;
	char path[PATH_MAX];
	uint32_t crc;
	pid_t pid = -1;
	int status, fd;

	test_init(argc, argv);

	m = mmap(NULL, MEM_SIZE, PROT_WRITE | PROT_READ,
				MAP_SHARED | MAP_ANONYMOUS, -1, 0);

	if (m == MAP_FAILED)
		goto err;

	pid = test_fork();
	if (pid < 0) {
		goto err;
	} else if (pid == 0) {
		crc = ~0;
		datagen(m + MEM_OFFSET, PAGE_SIZE, &crc);
		crc = ~0;
		datagen(m + MEM_OFFSET2, PAGE_SIZE, &crc);

		test_waitsig();

		crc = ~0;
		status = datachk(m + MEM_OFFSET, PAGE_SIZE, &crc);
		if (status)
			return 1;
		crc = ~0;
		status = datachk(m + MEM_OFFSET2, PAGE_SIZE, &crc);
		if (status)
			return 1;
		crc = ~0;
		status = datachk(m + PAGE_SIZE, PAGE_SIZE, &crc);
		if (status)
			return 1;
		return 0;
	}

	snprintf(path, PATH_MAX, "/proc/self/map_files/%lx-%lx",
						(unsigned long) m,
						(unsigned long) m + MEM_SIZE);
	fd = open(path, O_RDWR);
	if (fd == -1) {
		err("Can't open file %s: %m", path);
		goto err;
	}

	m2 = mmap(NULL, PAGE_SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, MEM_OFFSET3);
	if (m2 == MAP_FAILED) {
		err("Can't map file %s", path);
		goto err;
	}
	close(fd);

	munmap(m, PAGE_SIZE);
	munmap(m + PAGE_SIZE * 10, PAGE_SIZE);
	munmap(m + MEM_OFFSET2, PAGE_SIZE);

	crc = ~0;
	datagen(m + PAGE_SIZE, PAGE_SIZE, &crc);

	crc = ~0;
	datagen(m2, PAGE_SIZE, &crc);

	test_daemon();
	test_waitsig();

	kill(pid, SIGTERM);
	wait(&status);
	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status))
			goto err;
	} else
		goto err;

	crc = ~0;
	if (datachk(m + MEM_OFFSET, PAGE_SIZE, &crc))
		goto err;

	crc = ~0;
	if (datachk(m2, PAGE_SIZE, &crc))
		goto err;

	pass();

	return 0;
err:
	if (waitpid(-1, NULL, WNOHANG) == 0) {
		kill(pid, SIGTERM);
		wait(NULL);
	}
	return 1;
}
예제 #16
0
int main(int argc, char **argv)
{
	unsigned char buf[BUF_SIZE];
	int fd, fd_s;
	int status;
	pid_t pid;
	int res;
	uint32_t crc;
	struct sigaction sa = {
		.sa_handler	= sig_hand,
		/* don't set SA_RESTART */
	};

	test_init(argc, argv);

	if ((fd_s = tcp_init_server(ZDTM_FAMILY, &port)) < 0) {
		err("initializing server failed");
		return 1;
	}

	test_daemon();
	test_waitsig();

	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGCHLD, &sa, NULL))
		fprintf(stderr, "Can't set SIGTERM handler: %m\n");

	pid = test_fork();
	if (pid < 0) {
		err("fork failed. Return %d %m", pid);
		return 1;
	}

	if (pid == 0) {
		/*
		 * Chiled is client of TCP connection
		 */
		close(fd_s);
		fd = tcp_init_client(ZDTM_FAMILY, "localhost", port);
		if (fd < 0)
			return 1;

		res = read(fd, buf, BUF_SIZE);
		close(fd);
		if (res != BUF_SIZE) {
			err("read less then have to: %d instead of %d", res, BUF_SIZE);
			return -1;
		}
		if (datachk(buf, BUF_SIZE, &crc))
			return -2;
		return 0;
	}

	/*
	 * parent is server of TCP connection
	 */
	fd = tcp_accept_server(fd_s);
	close(fd_s);
	if (fd < 0) {
		err("can't accept client connection %m");
		goto error;
	}

	datagen(buf, BUF_SIZE, &crc);
	if (write(fd, buf, BUF_SIZE) < BUF_SIZE) {
		err("can't write");
		goto error;
	}
	close(fd);


	if (wait(&status) < 0) {
		err("wait failed %m");
		goto error;
	}

	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		err("chiled failed. Return %d", WEXITSTATUS(status));
		return 1;
	}

	pass();
	return 0;
error:
	kill(pid, SIGKILL);
	wait(&status);
	return -1;
}
예제 #17
0
파일: pipe_loop00.c 프로젝트: OSLL/pmover
int main(int argc, char **argv)
{
	int ret = 0;
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int pipes[PROCS_MAX * 2];
	int in, out;

	test_init(argc, argv);

	if (num_procs > PROCS_MAX) {
		err("%d processes is too many: max = %d\n", num_procs, PROCS_MAX);
		exit(1);
	}

	for (i = 0; i < num_procs; i++)
		if (pipe(pipes + i * 2)) {
			err("Can't create pipes: %m\n");
			exit(1);
		}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}

		if (pid == 0) {
			int j;
			in = i * 2;
			out = in - 1;
			for (j = 0; j < num_procs * 2; j++)
				if (j != in && j != out)
					close(pipes[j]);

			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(pipes[in], pipes[out], buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
						(errno != EINTR && errno != EPIPE))
					ret = errno;

			test_waitsig();	/* even if failed, wait for migration to complete */

			close(pipes[in]);
			close(pipes[out]);
			exit(ret);
		}
	}

	for (i = 1; i < num_procs * 2 - 1; i++)
		close(pipes[i]);
	in = pipes[0];
	out = pipes[num_procs * 2 - 1];

	/* don't block on writing, _do_ block on reading */
	if (set_nonblock(out,1) < 0) {
		err("setting O_NONBLOCK failed: %m");
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(out, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n", i);
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(in, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}

	close(out);

	test_waitsig();	/* even if failed, wait for migration to complete */

	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		goto out;	/* shouldn't wait() in this case */
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (wait(&chret) < 0) {
			fail("can't wait for a child: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
			     i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

out:
	close(in);
	return 0;
}
예제 #18
0
int main(int argc, char ** argv)
{
	int fd;
	struct stat st;
	uint32_t crc;
	bool chk_hole = true;

	test_init(argc, argv);

	fd = open(filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
	if (fd < 0) {
		pr_perror("can't open %s", filename);
		exit(1);
	}

	if (unlink(filename) < 0) {
		pr_perror("can't unlink %s", filename);
		goto failed;
	}

	crc = ~0;
	datagen(buf4k, BUFSIZE, &crc);
	if (pwrite(fd, buf4k, BUFSIZE, DATA1_OFF) != BUFSIZE) {
		pr_perror("can't write data1");
		goto failed;
	}

	crc = ~0;
	datagen(buf4k, BUFSIZE, &crc);
	if (pwrite(fd, buf4k, BUFSIZE, DATA2_OFF) != BUFSIZE) {
		pr_perror("can't write data2");
		goto failed;
	}

	if (ftruncate(fd, FILE_SIZE)) {
		pr_perror("Can't fixup file size");
		goto failed;
	}

	if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) {
		test_msg("Won't check for hole\n");
		chk_hole = false;
	}

	test_daemon();
	test_waitsig();

	if (fstat(fd, &st) < 0) {
		fail("can't stat after");
		goto failed;
	}

	if (st.st_size != FILE_SIZE) {
		fail("file size changed to %ld", (long)st.st_size);
		goto failed;
	}

	test_msg("Blocks %u OK\n", FILE_BLOCKS);

	/* Data 1 */
	if (pread(fd, buf4k, BUFSIZE, DATA1_OFF) != BUFSIZE) {
		fail("pread1 fail");
		goto failed;
	}

	crc = ~0;
	if (datachk(buf4k, BUFSIZE, &crc)) {
		fail("datachk1 fail");
		goto failed;
	}

	test_msg("Data @%u OK\n", DATA1_BLK);

	/* Data 2 */
	if (pread(fd, buf4k, BUFSIZE, DATA2_OFF) != BUFSIZE) {
		fail("pread2 fail");
		goto failed;
	}

	crc = ~0;
	if (datachk(buf4k, BUFSIZE, &crc)) {
		fail("datachk2 fail");
		goto failed;
	}

	test_msg("Data @%u OK\n", DATA2_BLK);

	/* Hole */
	if (chk_hole) {
#ifdef HEAD_HOLE
		if (lseek(fd, 0, SEEK_HOLE) != 0) {
			fail("hh not found");
			goto failed;
		}

		test_msg("Head hole OK\n");
#endif

		if (lseek(fd, DATA1_OFF, SEEK_HOLE) != DATA1_OFF + BUFSIZE) {
			fail("mh not found");
			goto failed;
		}

		test_msg("Mid hole OK\n");

#ifdef TAIL_HOLE
		if (lseek(fd, DATA2_OFF, SEEK_HOLE) != DATA2_OFF + BUFSIZE) {
			fail("tail hole not found");
			goto failed;
		}

		test_msg("Tail hole OK\n");
#endif
	}

	close(fd);
	pass();
	return 0;

failed:
	close(fd);
	return 1;
}
예제 #19
0
파일: socket_loop00.c 프로젝트: OSLL/pmover
int main(int argc, char **argv)
{
	int ret = 0;
	pid_t pid;
	int i;
	uint8_t buf[0x100000];
	int socks[PROCS_MAX * 2];
	int in, out;

	test_init(argc, argv);

	if (num_procs > PROCS_MAX) {
		err("%d processes is too many: max = %d\n", num_procs, PROCS_MAX);
		exit(1);
	}

	for (i = 0; i < num_procs; i++)
		if (socketpair(AF_LOCAL, SOCK_STREAM, 0, socks + i * 2)) {
			err("Can't create socks: %m\n");
			exit(1);
		}

	if (signal(SIGCHLD, inc_num_exited) == SIG_ERR) {
		err("can't set SIGCHLD handler: %m\n");
		exit(1);
	}

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		pid = test_fork();
		if (pid < 0) {
			err("Can't fork: %m\n");
			kill(0, SIGKILL);
			exit(1);
		}

		if (pid == 0) {
			int j;
			in = i * 2;
			out = in - 1;
			for (j = 0; j < num_procs * 2; j++)
				if (j != in && j != out)
					close(socks[j]);

			signal(SIGPIPE, SIG_IGN);
			if (pipe_in2out(socks[in], socks[out], buf, sizeof(buf)) < 0)
				/* pass errno as exit code to the parent */
				if (test_go() /* signal NOT delivered */ ||
					(errno != EINTR && errno != EPIPE
						&& errno != ECONNRESET))
					ret = errno;

			test_waitsig();	/* even if failed, wait for migration to complete */

			close(socks[in]);
			close(socks[out]);
			exit(ret);
		}
	}

	for (i = 1; i < num_procs * 2 - 1; i++)
		close(socks[i]);
	in = socks[0];
	out = socks[num_procs * 2 - 1];

	/* don't block on writing, _do_ block on reading */
	if (set_nonblock(out,1) < 0) {
		err("setting O_NONBLOCK failed: %m");
		exit(1);
	}

	if (num_exited) {
		err("Some children died unexpectedly\n");
		kill(0, SIGKILL);
		exit(1);
	}

	test_daemon();

	while (test_go()) {
		int len, rlen = 0, wlen;
		uint8_t rbuf[sizeof(buf)], *p;

		datagen(buf, sizeof(buf), NULL);
		wlen = write(out, buf, sizeof(buf));
		if (wlen < 0) {
			if (errno == EINTR)
				continue;
			else {
				fail("write failed: %m\n", i);
				ret = 1;
				break;
			}
		}

		for (p = rbuf, len = wlen; len > 0; p += rlen, len -= rlen) {
			rlen = read(in, p, len);
			if (rlen <= 0)
				break;
		}

		if (rlen < 0 && errno == EINTR)
			continue;

		if (len > 0) {
			fail("read failed: %m\n");
			ret = 1;
			break;
		}

		if (memcmp(buf, rbuf, wlen)) {
			fail("data mismatch\n");
			ret = 1;
			break;
		}
	}


	test_waitsig();	/* even if failed, wait for migration to complete */

	/* We expect that write(2) in child may return error only after signal
	 * has been received. Thus, send signal before closing parent fds.
	 */
	if (kill(0, SIGTERM)) {
		fail("failed to send SIGTERM to my process group: %m\n");
		goto out;	/* shouldn't wait() in this case */
	}
	if (close(out))
		fail("Failed to close parent fd 'out': %m\n");
	/* If last child in the chain (from whom we read data) receives signal
	 * after parent has finished reading but before calling write(2), this
	 * child can block forever.  To avoid this, close 'in' fd.
	 */
	if (close(in))
		fail("failed to close parent fd 'in': %m\n");

	for (i = 1; i < num_procs; i++) {	/* i = 0 - parent */
		int chret;
		if (wait(&chret) < 0) {
			fail("can't wait for a child: %m\n");
			ret = 1;
			continue;
		}

		chret = WEXITSTATUS(chret);
		if (chret) {
			fail("child %d exited with non-zero code %d (%s)\n",
			     i, chret, strerror(chret));
			ret = 1;
			continue;
		}
	}

	if (!ret)
		pass();

out:
	return 0;
}