[lxc-devel] Working with glibc (PID/TID caches).
Serge Hallyn
serge.hallyn at ubuntu.com
Fri Aug 1 15:32:30 UTC 2014
Hi,
so this is (iiuc) only a problem with unshare(CLONE_NEWPID). Two
programs pasted below. The one using unshare will show the old
pre-unshare pid. The one using clone correctly shows pid 1. Now
it's possible that clone() wrapper is doing something already to
clean the pid, I didn't try syscall(__NR_CLONE) with CLONE_NEWPID
today. But I've seen quite a bit of code using clone(CLONE_NEWPID),
and noone really uses the syscall directly any more.
AFAICT most ppl use clone, not unshare. But so, perhaps glibc sholud
have a unshare() wrapper which clears the pid cache? Or glibc could
export a function which callers would have to explicitly call.
==============================================================
unsharepid.c:
==============================================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <linux/sched.h>
int clone_fn(void)
{
printf("my pid is %d\n", getpid());
exit(0);
}
int main(int argc, char **argv)
{
if (unshare(CLONE_NEWPID) < 0) {
perror("unshare");
exit(1);
}
clone_fn();
}
==============================================================
==============================================================
clonepid.c
==============================================================
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sched.h>
#include <linux/sched.h>
int clone_fn(void *arg)
{
printf("my pid is %d\n", getpid());
exit(0);
}
int main(int argc, char **argv)
{
int pagesize;
void *clone_stack, *page;
int pid, rc, status, cloneflags;
cloneflags = CLONE_NEWPID;
pagesize = 16*getpagesize();
page = malloc(pagesize);
if (!page) {
perror("malloc");
exit(-1);
}
clone_stack = page + pagesize;
pid = clone(clone_fn, clone_stack, cloneflags | SIGCHLD, argv);
if (pid < 0) {
perror("clone");
exit(-1);
}
pid = wait(&status);
if (pid < 0) {
perror("wait");
exit(-1);
}
if (WIFEXITED(status)) {
fprintf(stderr, "Child exited with status %d.\n", WEXITSTATUS(status));
exit(WEXITSTATUS(status));
}
exit(0);
}
==============================================================
-serge
Quoting Carlos O'Donell (carlos at redhat.com):
> There was a complaint a while back from someone working
> on containers about glibc PID caching. I recently received
> another request to provide userspace with a way to reset
> any PID or TID caches to make clone-based sandboxing easier
> (CLONE_NEWPID).
>
> How did lxc workaround the PID cache in glibc? What APIs
> could glibc provide to help the implementation of containers?
>
> Cheers,
> Carlos.
> _______________________________________________
> lxc-devel mailing list
> lxc-devel at lists.linuxcontainers.org
> http://lists.linuxcontainers.org/listinfo/lxc-devel
More information about the lxc-devel
mailing list