From 3d945368250958f5ebf3b4053e07c816adafba33 Mon Sep 17 00:00:00 2001
From: "fu.lin" <fulin10@huawei.com>
Date: Fri, 21 Jan 2022 17:20:05 +0800
Subject: [PATCH 62/72] zdtm: add host ns sysvshm ipc case

---
 test/zdtm/Makefile               |   2 +-
 test/zdtm/customization/Makefile |  53 ++++++++
 test/zdtm/customization/ipc.c    | 202 +++++++++++++++++++++++++++++++
 test/zdtm/customization/ipc.desc |   1 +
 4 files changed, 257 insertions(+), 1 deletion(-)
 create mode 100644 test/zdtm/customization/Makefile
 create mode 100644 test/zdtm/customization/ipc.c
 create mode 100644 test/zdtm/customization/ipc.desc

diff --git a/test/zdtm/Makefile b/test/zdtm/Makefile
index 24a33f2..8f9857b 100644
--- a/test/zdtm/Makefile
+++ b/test/zdtm/Makefile
@@ -1,4 +1,4 @@
-SUBDIRS	:=	lib static transition
+SUBDIRS	:=	lib static transition customization
 
 all: $(SUBDIRS)
 .PHONY: all $(SUBDIRS)
diff --git a/test/zdtm/customization/Makefile b/test/zdtm/customization/Makefile
new file mode 100644
index 0000000..563b7b1
--- /dev/null
+++ b/test/zdtm/customization/Makefile
@@ -0,0 +1,53 @@
+LIBDIR	:= ../lib
+LIB	:= $(LIBDIR)/libzdtmtst.a
+LDLIBS	+= $(LIB)
+CPPFLAGS += -I$(LIBDIR)
+
+TST	=	\
+		ipc
+
+SRC	= $(TST:%=%.c)
+OBJ	= $(SRC:%.c=%.o)
+DEP	= $(SRC:%.c=%.d)
+PID	= $(TST:%=%.pid)
+OUT	= $(TST:%=%.out)
+
+include ../Makefile.inc
+
+all:	$(TST)
+install: all
+.PHONY: all install
+
+$(TST:%=%.pid):	%.pid:	%
+	$(<D)/$(<F) --pidfile=$@ --outfile=$<.out
+
+%.out:	%.pid %
+	-kill -TERM `cat $<`
+
+start:	$(PID)
+
+%.is_running:	%.pid
+	kill -0 `cat $<`
+
+check_start:	$(PID:%.pid=%.is_running)
+
+stop:
+	-kill -TERM `awk '{print}' *.pid`
+
+WAIT_TIME=10
+wait_stop:
+	-for i in `seq 1 $(WAIT_TIME)`; do \
+		kill -0 `awk '{print}' *.pid 2>/dev/null` 2>/dev/null || break; \
+		sleep 1; \
+	done
+
+$(TST):	| $(LIB)
+
+%: %.sh
+	cp $< $@
+	chmod +x $@
+
+$(LIB):	force
+	$(Q) $(MAKE) -C $(LIBDIR)
+
+.PHONY:	force start check_start stop wait_stop
diff --git a/test/zdtm/customization/ipc.c b/test/zdtm/customization/ipc.c
new file mode 100644
index 0000000..2b3c2b1
--- /dev/null
+++ b/test/zdtm/customization/ipc.c
@@ -0,0 +1,202 @@
+#include <sched.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/sem.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc="Tests ipc sems and shmems migrate fine";
+const char *test_author="Pavel Emelianov <xemul@parallels.com>";
+
+static struct sembuf unlock = {
+	.sem_op = 1,
+	.sem_num = 0,
+	.sem_flg = 0,
+};
+
+static struct sembuf lock = {
+	.sem_op = -1,
+	.sem_num = 0,
+	.sem_flg = 0,
+};
+
+#define DEF_MEM_SIZE	(40960)
+unsigned int shmem_size = DEF_MEM_SIZE;
+TEST_OPTION(shmem_size, uint, "Size of shared memory segment", 0);
+
+#define INIT_CRC	(~0)
+
+#define POISON		0xac
+static inline void poison_area(int *mem)
+{
+	memset(mem, POISON, shmem_size);
+}
+
+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;
+}
+
+int main(int argc, char **argv)
+{
+	key_t key;
+	int sem, shm, pid1, pid2;
+	int fail_count = 0;
+	uint8_t *mem;
+	uint32_t crc;
+	int ret;
+
+	test_init(argc, argv);
+
+	/* using the large number to fill string length */
+	key = ftok(argv[0], 1822155650);
+	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;
+}
diff --git a/test/zdtm/customization/ipc.desc b/test/zdtm/customization/ipc.desc
new file mode 100644
index 0000000..63df42a
--- /dev/null
+++ b/test/zdtm/customization/ipc.desc
@@ -0,0 +1 @@
+{'flavor': 'h'}
-- 
2.34.1

