コード例 #1
0
ファイル: sigpending.c プロジェクト: huikang/criu
static void sig_handler(int signal, siginfo_t *info, void *data)
{
	uint32_t crc;

	test_msg("signo=%d si_code=%x\n", signal, info->si_code);

	if (test_go()) {
		pr_perror("The signal is received before unlocking");
		return;
	}

	switch (signal) {
	case SIGCHLD:
		if ((info->si_code & CLD_EXITED) &&
		    (info->si_pid == child) &&
		    (info->si_status == 5))
			numsig++;
		else {
			fail("Wrong siginfo");
			exit(1);
		}
		return;
	}

	if (TESTSIG == signal || THREADSIG == signal) {
		siginfo_t *src;

		if (signal == TESTSIG) {
			src = &share_infos[share_nr];
			share_nr++;
		} else if (getpid() == syscall(SYS_gettid)) {
			src = &self_infos[self_nr];
			self_nr++;
		} else {
			src = &thread_infos[thread_nr];
			thread_nr++;
		}

		crc = ~0;
		if (datachk((uint8_t *) &info->_sifields,
			    sizeof(siginfo_t) - offsetof(siginfo_t, _sifields), &crc)) {
			fail("CRC mismatch\n");
			return;
		}

		 if (memcmp(info, src, sizeof(siginfo_t))) {
			fail("Source and received info are differ\n");
			return;
		}

		numsig++;
		return;
	}

	pr_perror("Unexpected signal");
	exit(1);
}
コード例 #2
0
ファイル: shm.c プロジェクト: 0x7f454c46/criu-1
static int check_shm_id(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;
	}
	crc = INIT_CRC;
	if (datachk(mem, size, &crc)) {
		fail("shmem data are corrupted");
		return -1;
	}
	if (shmdt(mem) < 0) {
		pr_perror("Can't detach shm: %d", -errno);
		return -1;
	}
	return 0;
}
コード例 #3
0
ファイル: maps04.c プロジェクト: kunalkushwaha/crtools
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;
}
コード例 #4
0
ファイル: ghost_holes00.c プロジェクト: 0x7f454c46/criu
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;
}
コード例 #5
0
ファイル: socket_listen.c プロジェクト: avagin/crtools
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;
}
コード例 #6
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;
}
コード例 #7
0
ファイル: unlink_fstat00.c プロジェクト: 0x7f454c46/criu-1
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;
}
コード例 #8
0
ファイル: maps00.c プロジェクト: OSLL/pmover
static int check_map(struct map *map)
{
	int prot = PROT_WRITE | PROT_READ | PROT_EXEC;

	if (signal(SIGSEGV, segfault) == SIG_ERR)
	{
		fail("setting SIGSEGV handler failed: %m\n");
		return -1;
	}
	if (!sigsetjmp(segv_ret, 1))
	{
		uint32_t crc = ~0;
		if (datachk(map->ptr, ONE_MAP_SIZE, &crc))	/* perform read access */
			if (!(map->flag & MAP_ANONYMOUS) ||
					(map->prot & PROT_WRITE)) {	/* anon maps could only be filled when r/w */
				fail("CRC mismatch\n");
				return -1;
			}
		/* prot |= PROT_READ// 	need barrier before this line,
					because compiler change order commands.
					I finded one method: look at next lines*/
	} else
		prot &= PROT_WRITE | !PROT_READ | PROT_EXEC;

	if (signal(SIGSEGV, segfault) == SIG_ERR)
	{
		fail("setting SIGSEGV handler failed: %m\n");
		return -1;
	}

	if (!sigsetjmp(segv_ret, 1))
	{
		* (int *) (map->ptr) = 1234;	/* perform write access */
	} else
		prot &= !PROT_WRITE | PROT_READ | PROT_EXEC;

	if (signal(SIGSEGV, segfault) == SIG_ERR)
	{
		fail("restoring SIGSEGV handler failed: %m\n");
		return -1;
	}

	if (!sigsetjmp(segv_ret, 1))
	{
		if (map->prot & PROT_WRITE) {
			memcpy(map->ptr,test_func, getpagesize());
		} else {
			if (!(map->flag & MAP_ANONYMOUS)) {
				lseek(map->fd,0,SEEK_SET);
				if (write(map->fd,test_func,check_map - test_func)<check_map - test_func) {
					err("failed to write %s: %m\n", map->filename);
					return -1;
				}
			}
		}
		if (!(map->flag & MAP_ANONYMOUS) || map->prot & PROT_WRITE)
			/* Function body has been copied into the mapping */
			((int (*)())map->ptr)();	/* perform exec access */
		else
			/* No way to copy function body into mapping,
			 * clear exec bit from effective protection
			 */
			prot &= PROT_WRITE | PROT_READ | !PROT_EXEC;
	} else
		prot &= PROT_WRITE | PROT_READ | !PROT_EXEC;

	if (signal(SIGSEGV, SIG_DFL) == SIG_ERR)
	{
		fail("restoring SIGSEGV handler failed: %m\n");
		return -1;
	}

	return prot;
}
コード例 #9
0
ファイル: deleted_unix_sock.c プロジェクト: eabatalov/criu
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;
}
コード例 #10
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;
}
コード例 #11
0
ファイル: ipc.c プロジェクト: huikang/criu
static int test_fn(int argc, char **argv)
{
	key_t key;
	int sem, shm, pid1, pid2;
	int fail_count = 0;
	uint8_t *mem;
	uint32_t crc;
	int ret;

	key = ftok(argv[0], 822155650);
	if (key == -1) {
		pr_perror("Can't make key");
		goto out;
	}

	sem = semget(key, 1, 0777 | IPC_CREAT | IPC_EXCL);
	if (sem  == -1) {
		pr_perror("Can't get sem");
		goto out;
	}

	if (semctl(sem, 0, SETVAL, 1) == -1) {
		pr_perror("Can't init sem");
		fail_count++;
		goto out_sem;
	}

	shm = shmget(key, shmem_size, 0777 | IPC_CREAT | IPC_EXCL);
	if (shm == -1) {
		pr_perror("Can't get shm");
		fail_count++;
		goto out_sem;
	}

	mem = shmat(shm, NULL, 0);
	if (mem == (void *)-1) {
		pr_perror("Can't attach shm");
		fail_count++;
		goto out_shm;
	}

	poison_area((int *)mem);

	pid1 = test_fork();
	if (pid1 == -1) {
		pr_perror("Can't fork 1st time");
		goto out_shdt;
	} else if (pid1 == 0)
		exit(child(key));

	pid2 = test_fork();
	if (pid2 == -1) {
		pr_perror("Can't fork 2nd time");
		fail_count++;
		goto out_child;
	} else if (pid2 == 0)
		exit(child(key));

	test_daemon();
	while (test_go()) {
		ret = semop(sem, &lock, 1);
		if (ret) {
			if (errno == EINTR)
				continue;
			fail_count++;
			fail("Error in semop lock");
			break;
		}
		if (mem[0] != POISON) {
			crc = INIT_CRC;
			if (datachk(mem, shmem_size, &crc)) {
				fail_count++;
				fail("Semaphore protection is broken or "
						"shmem pages are messed");
				semop(sem, &unlock, 1);
				break;
			}
			poison_area((int *)mem);
		}
		while ((ret = semop(sem, &unlock, 1)) && (errno == EINTR));
		if (ret) {
			fail_count++;
			fail("Error in semop unlock");
			break;
		}
	}
	test_waitsig();

	kill(pid2, SIGTERM);
	waitpid(pid2, &ret, 0);
	if (!WIFEXITED(ret)) {
		fail_count++;
		pr_perror("Child 2 was killed");
	} else if (WEXITSTATUS(ret)) {
		fail_count++;
		pr_perror("Child 2 couldn't inititalise");
	}
out_child:
	kill(pid1, SIGTERM);
	waitpid(pid1, &ret, 0);
	if (!WIFEXITED(ret)) {
		fail_count++;
		pr_perror("Child 1 was killed");
	} else if (WEXITSTATUS(ret)) {
		fail_count++;
		pr_perror("Child 1 couldn't inititalise");
	}
out_shdt:
	shmdt(mem);
out_shm:
	shmctl(shm, IPC_RMID, NULL);
out_sem:
	semctl(sem, 1, IPC_RMID);
	if (fail_count == 0)
		pass();
out:
	return 0;
}
コード例 #12
0
ファイル: overmount_sock.c プロジェクト: OSLL/pmover
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
ファイル: shm.c プロジェクト: 0x7f454c46/criu-1
int main(int argc, char **argv)
{
	key_t key;
	int shm;
	int fail_count = 0;
	int ret = -1;

	void *mem;
	uint32_t crc = INIT_CRC;

	test_init(argc, argv);

	key = ftok(argv[0], 822155666);
	if (key == -1) {
		pr_perror("Can't make key");
		goto out;
	}

	shm = prepare_shm(key, shmem_size);
	if (shm == -1) {
		pr_perror("Can't prepare shm (1)");
		goto out;
	}

	mem = shmat(shm, NULL, 0);
	if (mem == (void *)-1) {
		pr_perror("Can't shmat");
		goto out;
	}

	test_daemon();
	test_waitsig();

	ret = check_shm_id(shm, shmem_size);
	if (ret < 0) {
		fail("ID check (1) failed\n");
		fail_count++;
		goto out_shm;
	}

	ret = check_shm_key(key, shmem_size);
	if (ret < 0) {
		fail("KEY check failed\n");
		fail_count++;
		goto out_shm;
	}

	if (datachk(mem, shmem_size, &crc)) {
		fail("shmem data is corrupted");
		return -1;
	}

	if (shmdt(mem) < 0) {
		pr_perror("Can't detach shm");
		return -1;
	}

	ret = shmctl(shm, IPC_RMID, NULL);
	if (ret < 0) {
		fail("Failed (1) to destroy segment: %d\n", -errno);
		fail_count++;
		goto out_shm;
	}
	/*
	 * Code below checks that it's still possible to create new IPC SHM
	 * segments
	 */
	shm = prepare_shm(key, shmem_size);
	if (shm == -1) {
		fail("Can't prepare shm (2)");
		fail_count++;
		goto out;
	}

	ret = check_shm_id(shm, shmem_size);
	if (ret < 0) {
		fail("ID check (2) failed\n");
		fail_count++;
		goto out_shm;
	}

out_shm:
	ret = shmctl(shm, IPC_RMID, NULL);
	if (ret < 0) {
		fail("Failed (2) to destroy segment: %d\n", -errno);
		fail_count++;
	}
	if (fail_count == 0)
		pass();
out:
	return ret;
}