Skip to content

Instantly share code, notes, and snippets.

@sitano
Last active March 15, 2022 04:07
Show Gist options
  • Save sitano/6b3e407d704ef819ccfd7cd03949e110 to your computer and use it in GitHub Desktop.
Save sitano/6b3e407d704ef819ccfd7cd03949e110 to your computer and use it in GitHub Desktop.
test setns
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include <sys/syscall.h> /* Definition of SYS_* constants */
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/wait.h>
#include <time.h>
static int
pidfd_open(pid_t pid, unsigned int flags) {
return syscall(__NR_pidfd_open, pid, flags);
}
int main(int argc, char **argv) {
struct timespec tstart={0,0}, tend={0,0};
pid_t pid, child;
int pidfd, st;
if (argc < 2) {
printf("err: invalid num of arguments");
return 1;
}
pid = (pid_t) strtol(argv[1], (char **)NULL, 10);
printf("moving to: %d\n", pid);
clock_gettime(CLOCK_MONOTONIC, &tstart);
pidfd = pidfd_open(pid, 0);
if (pidfd == -1) {
printf("err: bad open: %s", strerror(errno));
return 1;
}
if (setns(pidfd, CLONE_NEWPID | CLONE_NEWCGROUP | CLONE_NEWIPC | CLONE_NEWNET | CLONE_NEWNS | CLONE_NEWUTS) != 0) {
printf("err: bad setns: %s", strerror(errno));
return 1;
}
child = fork();
if (child > 0) {
clock_gettime(CLOCK_MONOTONIC, &tend);
printf("waiting [fork in %ldns]\n", tend.tv_nsec-tstart.tv_nsec);
if (waitpid(child, &st, 0) == -1) {
printf("err: bad wait: %s", strerror(errno));
return 1;
}
} else {
clock_gettime(CLOCK_MONOTONIC, &tend);
printf("moved in [%ldns]\n", tend.tv_nsec-tstart.tv_nsec);
getchar();
}
close(pidfd);
return 0;
}
@sitano
Copy link
Author

sitano commented Mar 9, 2022

@Yuan-Zhuo how do you run it?

it works for me tho:

$ unshare -U -m -p -f -r bash
root@rabbit:~# sleep 60

-- another terminal

$ ps aux | grep '[s]leep'
user     29536  0.0  0.0   6000   680 pts/1    S+   12:16   0:00 sleep 60

$ sudo ./a.out 29536
moving to: 29536
waiting [fork in 36192ns]
moved in [78651ns]
^C

@Yuan-Zhuo
Copy link

Thank you for reply. I just noticed that fd as a PID file descriptor in setns is a new feature since Linux 5.8, however my pc' current version is 5.4.☹️

@sitano
Copy link
Author

sitano commented Mar 14, 2022

@Yuan-Zhuo do you mean pidfd_open (https://lwn.net/Articles/800379/) (it says 5.3)?

@sitano
Copy link
Author

sitano commented Mar 14, 2022

for setns you can replace pid fd with normal fd

a file descriptor referring to one of the magic links in a /proc/[pid]/ns/ directory (or a bind mount to such a link)`

@Yuan-Zhuo
Copy link

Yes, replace pid fd with normal fd can work. And another reason as follows.
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment