Я работаю над приложением C, используя пространства имен Linux, и одна вещь, которая возникла, — это необходимость сигнализировать дочернему пространству имен от родителя с помощью семафора (или чего-то подобного). Вот что я пытаюсь сделать в данный момент:
#define _GNU_SOURCE
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <string.h>
#include <semaphore.h>
//A stack for the container
#define STACK_SIZE (1024 * 1024)
static char stack[STACK_SIZE];
//The semaphore
sem_t semaphore;
int child(void* arg){
int semval;
//Print the semaphore state as read from the new namespace
for(int i=0;i<6;i++){
sem_getvalue(&semaphore, &semval);
printf("Semaphore state: %d.\n", semval);
sleep(1);
}
return 1;
}
int main(){
//Init a shared POSIX semaphore with the value zero
sem_init(&semaphore, 1, 0);
//Create the child namespace
pid_t pid = clone(child, stack+STACK_SIZE, CLONE_NEWNET | CLONE_NEWUTS | CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, NULL);
//Wait, then post the semaphore
sleep(3);
printf("Posting semaphore\n");
sem_post(&semaphore);
//Wait for it to return
waitpid(pid, NULL, 0);
return 0;
}
Насколько я понимаю, это должно запустить child
в новом пространстве имен, где он несколько раз выдаст значение семафора. Мы должны иметь возможность видеть, когда родительский процесс в родительском пространстве имен публикует его, однако мы этого не делаем:
Semaphore state: 0.
Semaphore state: 0.
Semaphore state: 0.
Posting semaphore
Semaphore state: 0.
Semaphore state: 0.
Semaphore state: 0.
Семафор инициализируется как общий, и удаление CLONE_NEWIPC
из вызова клона также не исправляет этого (насколько я понимаю, это в любом случае касается только изоляции SysV IPC, а не этого семафора POSIX).
Еще одна особенность этого заключается в том, что если мы инициализируем семафор другим значением (например, sem_init(&semaphore, 1, 3);
), дочернее пространство имен будет читать это начальное значение:
Semaphore state: 3.
Semaphore state: 3.
Semaphore state: 3.
Posting semaphore
Semaphore state: 3.
Semaphore state: 3.
Semaphore state: 3.
Таким образом, он, по-видимому, не полностью не может получить доступ к семафору — он просто не видит, когда он опубликован. Как вы должны это сделать? Есть ли какой-то особый трюк с общей памятью, который мне нужно настроить, чтобы заставить его работать между пространствами имен, или я просто делаю что-то не так?