criu/test/zdtm/static/sem.c
Adrian Reber 93dd984ca0 Run 'make indent' on all C files
Acked-by: Mike Rapoport <rppt@linux.ibm.com>
Signed-off-by: Adrian Reber <areber@redhat.com>
2021-09-03 10:31:00 -07:00

176 lines
3.3 KiB
C

#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/ipc.h>
#include <sys/sem.h>
#include <signal.h>
#include <errno.h>
#include "zdtmtst.h"
const char *test_doc = "Tests IPC semaphores migrates fine";
const char *test_author = "Stanislav Kinsbursky <skinsbursky@parallels.com>";
static int sem_test(int id, struct sembuf *lock, struct sembuf *unlock, int lock_ops, int unlock_ops)
{
if (semop(id, lock, lock_ops) == -1) {
fail("Failed to lock semaphore");
return -errno;
}
if (semop(id, unlock, unlock_ops) == -1) {
fail("Failed to unlock semaphore");
return -errno;
}
return 0;
}
#define NSEMS 10
static int check_sem_by_key(int key, int num)
{
int id;
struct sembuf lock[2] = {
{
.sem_num = num,
.sem_op = 0,
.sem_flg = 0,
},
{
.sem_num = num,
.sem_op = 1,
.sem_flg = 0,
},
};
struct sembuf unlock[1] = { {
.sem_num = num,
.sem_op = -1,
.sem_flg = 0,
} };
int val;
id = semget(key, NSEMS, 0777);
if (id == -1) {
fail("Can't get sem");
return -errno;
}
val = semctl(id, num, GETVAL);
if (val < 0) {
fail("Failed to get sem value");
return -errno;
}
return sem_test(id, lock, unlock, sizeof(lock) / sizeof(struct sembuf), sizeof(unlock) / sizeof(struct sembuf));
}
static int check_sem_by_id(int id, int num, int val)
{
int curr;
struct sembuf lock[] = {
{
.sem_num = num,
.sem_op = val,
.sem_flg = 0,
},
};
struct sembuf unlock[] = { {
.sem_num = num,
.sem_op = -val * 2,
.sem_flg = 0,
} };
curr = semctl(id, num, GETVAL);
if (curr < 0) {
fail("Failed to get sem value");
return -errno;
}
if (curr != val) {
fail("Sem has wrong value: %d instead of %d", curr, val);
return -EFAULT;
}
return sem_test(id, lock, unlock, sizeof(lock) / sizeof(struct sembuf), sizeof(unlock) / sizeof(struct sembuf));
}
int main(int argc, char **argv)
{
int id, key;
int i;
/* See man semctl */
union semun {
int val;
struct semid_ds *buf;
unsigned short *array;
struct seminfo *__buf;
} val[NSEMS];
int ret, fail_count = 0;
test_init(argc, argv);
key = ftok(argv[0], 89063453);
if (key == -1) {
pr_perror("Can't make key");
return -1;
}
id = semget(key, NSEMS, 0777 | IPC_CREAT | IPC_EXCL);
if (id == -1) {
fail_count++;
pr_perror("Can't get sem array");
goto out;
}
for (i = 0; i < NSEMS; i++) {
val[i].val = lrand48() & 0x7;
if (semctl(id, i, SETVAL, val[i]) == -1) {
fail_count++;
pr_perror("Can't init sem %d", i);
goto out_destroy;
}
}
test_daemon();
test_waitsig();
for (i = 0; i < NSEMS; i++) {
ret = check_sem_by_id(id, i, val[i].val);
if (ret < 0) {
fail_count++;
fail("Check sem %d by id failed", i);
goto out_destroy;
}
if (check_sem_by_key(key, i) < 0) {
fail("Check sem %d by key failed", i);
fail_count++;
goto out_destroy;
}
val[i].val = semctl(id, 0, GETVAL);
if (val[i].val < 0) {
fail("Failed to get sem %d value", i);
fail_count++;
goto out_destroy;
}
if (val[i].val != 0) {
fail("Non-zero sem %d value: %d", i, val[i].val);
fail_count++;
}
}
out_destroy:
ret = semctl(id, 0, IPC_RMID);
if (ret < 0) {
fail("Destroy sem array failed");
fail_count++;
}
out:
if (fail_count == 0)
pass();
return fail_count;
}