1 | =head1 NAME |
1 | =head1 NAME |
2 | |
2 | |
3 | Linux::Clone - an interface to the linux clone(2) and unshare(2) syscalls |
3 | Linux::Clone - an interface to the linux clone, unshare, setns, pivot_root and kcmp syscalls |
4 | |
4 | |
5 | =head1 SYNOPSIS |
5 | =head1 SYNOPSIS |
6 | |
6 | |
7 | use Linux::Clone; |
7 | use Linux::Clone; |
8 | |
8 | |
9 | =head1 DESCRIPTION |
9 | =head1 DESCRIPTION |
10 | |
10 | |
11 | This module exposes the linux clone(2) and unshare(2) syscalls to |
11 | This module exposes the linux clone(2), unshare(2) and some related |
12 | Perl. |
12 | syscalls to Perl. |
13 | |
13 | |
14 | =over 4 |
14 | =over 4 |
15 | |
15 | |
16 | =item $retval = unshare $flags |
16 | =item $retval = unshare $flags |
17 | |
17 | |
… | |
… | |
24 | Linux::Clone::NEWNS (in unshare, implies FS) |
24 | Linux::Clone::NEWNS (in unshare, implies FS) |
25 | Linux::Clone::VM (in unshare, implies SIGHAND) |
25 | Linux::Clone::VM (in unshare, implies SIGHAND) |
26 | Linux::Clone::THREAD (in unshare, implies VM, SIGHAND) |
26 | Linux::Clone::THREAD (in unshare, implies VM, SIGHAND) |
27 | Linux::Clone::SIGHAND |
27 | Linux::Clone::SIGHAND |
28 | Linux::Clone::SYSVSEM |
28 | Linux::Clone::SYSVSEM |
|
|
29 | Linux::Clone::NEWUSER (in unshare, implies CLONE_THREAD) |
|
|
30 | Linux::Clone::NEWPID |
29 | Linux::Clone::NEWUTS |
31 | Linux::Clone::NEWUTS |
30 | Linux::Clone::NEWIPC |
32 | Linux::Clone::NEWIPC |
31 | Linux::Clone::NEWNET |
33 | Linux::Clone::NEWNET |
|
|
34 | Linux::Clone::NEWCGROUP |
32 | |
35 | |
33 | Example: unshare the network namespace and prove that by calling ifconfig, |
36 | Example: unshare the network namespace and prove that by calling ifconfig, |
34 | showing only an unconfigured lo interface. |
37 | showing only the unconfigured lo interface. |
35 | |
38 | |
36 | Linux::Clone::unshare Linux::Clone::NEWNET |
39 | Linux::Clone::unshare Linux::Clone::NEWNET |
37 | and "unshare: $!"; |
40 | and "unshare: $!"; |
|
|
41 | Linux::Clone::configure_loopback; |
38 | system "ifconfig -a"; |
42 | system "ifconfig"; |
39 | |
43 | |
40 | Example: unshare the network namespace, initialise the loopback interface, |
44 | Example: unshare the network namespace, initialise the loopback interface, |
41 | create a veth interface pair, put one interface into the parent processes |
45 | create a veth interface pair, put one interface into the parent processes |
42 | namespace (use ifconfig -a from another shell), configure the other |
46 | namespace (use ifconfig -a from another shell), configure the other |
43 | interface with 192.168.99.2 -> 192.168.99.1 and start a shell. |
47 | interface with 192.168.99.2 -> 192.168.99.1 and start a shell. |
… | |
… | |
46 | |
50 | |
47 | # unshare our network namespace |
51 | # unshare our network namespace |
48 | Linux::Clone::unshare Linux::Clone::NEWNET |
52 | Linux::Clone::unshare Linux::Clone::NEWNET |
49 | and "unshare: $!"; |
53 | and "unshare: $!"; |
50 | |
54 | |
|
|
55 | Linux::Clone::configure_loopback; |
|
|
56 | |
51 | my $ppid = getppid; |
57 | my $ppid = getppid; |
52 | |
58 | |
53 | system " |
59 | system " |
54 | # configure loopback interface |
|
|
55 | ip link set lo up |
|
|
56 | ip route add 127.0.0.0/8 dev lo |
|
|
57 | |
|
|
58 | # create veth pair |
60 | # create veth pair |
59 | ip link add name veth_master type veth peer name veth_slave |
61 | ip link add name veth_master type veth peer name veth_slave |
60 | |
62 | |
61 | # move veth_master to our parent process' namespace |
63 | # move veth_master to our parent process' namespace |
62 | ip link set veth_master netns $ppid |
64 | ip link set veth_master netns $ppid |
… | |
… | |
85 | use Linux::Clone; |
87 | use Linux::Clone; |
86 | |
88 | |
87 | Linux::Clone::unshare Linux::Clone::NEWNS |
89 | Linux::Clone::unshare Linux::Clone::NEWNS |
88 | and die "unshare: $!"; |
90 | and die "unshare: $!"; |
89 | |
91 | |
90 | # now bind-mount /lib over /etc and ls -l /etc - scary |
92 | # now bind-mount /lib over /etc and ls -l /etc - looks scary |
91 | system "mount -n --bind /lib /etc"; |
93 | system "mount -n --bind /lib /etc"; |
92 | system "ls -l /etc"; |
94 | system "ls -l /etc"; |
93 | |
95 | |
94 | =item $retval = Linux::Clone::clone $coderef, $stacksize, $flags[, $ptid, $tls, $ctid] |
96 | =item $retval = Linux::Clone::clone $coderef, $stacksize, $flags[, $ptid, $tls, $ctid] |
95 | |
97 | |
… | |
… | |
120 | Linux::Clone::VFORK |
122 | Linux::Clone::VFORK |
121 | Linux::Clone::SETTLS (not yet implemented) |
123 | Linux::Clone::SETTLS (not yet implemented) |
122 | Linux::Clone::PARENT_SETTID (not yet implemented) |
124 | Linux::Clone::PARENT_SETTID (not yet implemented) |
123 | Linux::Clone::CHILD_SETTID (not yet implemented) |
125 | Linux::Clone::CHILD_SETTID (not yet implemented) |
124 | Linux::Clone::CHILD_CLEARTID (not yet implemented) |
126 | Linux::Clone::CHILD_CLEARTID (not yet implemented) |
|
|
127 | Linux::Clone::PIDFD (not yet implemented) |
125 | Linux::Clone::DETACHED |
128 | Linux::Clone::DETACHED |
126 | Linux::Clone::UNTRACED |
129 | Linux::Clone::UNTRACED |
127 | Linux::Clone::NEWUSER |
|
|
128 | Linux::Clone::NEWPID |
|
|
129 | Linux::Clone::IO |
130 | Linux::Clone::IO |
|
|
131 | Linux::Clone::CSIGNAL exit signal mask |
130 | |
132 | |
131 | Note that for practical reasons you basically must not use |
133 | Note that for practical reasons you basically must not use |
132 | C<Linux::Clone::VM> or C<Linux::Clone::VFORK>, as perl is unlikely to cope |
134 | C<Linux::Clone::VM> or C<Linux::Clone::VFORK>, as perl is unlikely to cope |
133 | with that. |
135 | with that. |
134 | |
136 | |
… | |
… | |
137 | Example: do a fork-like clone, sharing nothing, slightly confusing perl |
139 | Example: do a fork-like clone, sharing nothing, slightly confusing perl |
138 | and your libc, and exit immediately. |
140 | and your libc, and exit immediately. |
139 | |
141 | |
140 | my $pid = Linux::Clone::clone sub { warn "in child"; 77 }, 0, POSIX::SIGCHLD; |
142 | my $pid = Linux::Clone::clone sub { warn "in child"; 77 }, 0, POSIX::SIGCHLD; |
141 | |
143 | |
|
|
144 | =item Linux::Clone::setns $fh_or_fd[, $nstype] |
|
|
145 | |
|
|
146 | Calls setns(2) on the file descriptor (or file handle) C<$fh_or_fd>. If |
|
|
147 | C<$nstype> is missing, then C<0> is used. |
|
|
148 | |
|
|
149 | The argument C<$nstype> can be C<0>, C<Linux::Clone::NEWIPC>, |
|
|
150 | C<Linux::Clone::NEWNET>, C<Linux::Clone::NEWUTS>, C<Linux::Clone::NEWCGROUP>, |
|
|
151 | C<Linux::Clone::NEWNS>, C<Linux::Clone::NEWPID> or C<Linux::Clone::NEWUSER>. |
|
|
152 | |
|
|
153 | =item Linux::Clone::pivot_root $new_root, $old_root |
|
|
154 | |
|
|
155 | Calls pivot_root(2) - refer to its manpage for details. |
|
|
156 | |
|
|
157 | =item Linux::Clone::kcmp $pid1, $pid2, $type[, $idx1, $idx2] |
|
|
158 | |
|
|
159 | Calls kcmp(2) - refer to its manpage for details on operations. |
|
|
160 | |
|
|
161 | The following C<$type> constants are available if the kcmp syscall number |
|
|
162 | was available during compilation: |
|
|
163 | |
|
|
164 | C<Linux::Clone::KCMP_FILE>, C<Linux::Clone::KCMP_VM>, C<Linux::Clone::KCMP_FILES>, |
|
|
165 | C<Linux::Clone::KCMP_FS>, C<Linux::Clone::KCMP_SIGHAND>, C<Linux::Clone::KCMP_IO> and |
|
|
166 | C<Linux::Clone::KCMP_SYSVSEM>. |
|
|
167 | |
|
|
168 | =item Linux::Clone::configure_loopback |
|
|
169 | |
|
|
170 | Configures a working loopback interface (basically, does the equivalent of |
|
|
171 | "ifconfig lo up" which automatically adds ipv4/ipv6 addresses and routes), |
|
|
172 | which can be useful to get a network namespace going. |
|
|
173 | |
|
|
174 | Dies on error and returns nothing. |
|
|
175 | |
142 | =back |
176 | =back |
143 | |
177 | |
144 | =cut |
178 | =cut |
145 | |
179 | |
146 | package Linux::Clone; |
180 | package Linux::Clone; |
147 | |
181 | |
148 | # use common::sense; |
182 | # use common::sense; |
149 | |
183 | |
150 | BEGIN { |
184 | BEGIN { |
151 | our $VERSION = '0.01'; |
185 | our $VERSION = '1.3'; |
152 | |
186 | |
153 | require XSLoader; |
187 | require XSLoader; |
154 | XSLoader::load (__PACKAGE__, $VERSION); |
188 | XSLoader::load (__PACKAGE__, $VERSION); |
155 | } |
189 | } |
156 | |
190 | |
|
|
191 | sub configure_loopback() { |
|
|
192 | siocsifflags "lo" |
|
|
193 | and die "Linux::Clone::configure_looopback: unable to bring up loopback interface: $!\n"; |
|
|
194 | } |
|
|
195 | |
157 | 1; |
196 | 1; |
158 | |
197 | |
159 | =head1 AUTHOR |
198 | =head1 AUTHOR |
160 | |
199 | |
161 | Marc Lehmann <schmorp@schmorp.de> |
200 | Marc Lehmann <schmorp@schmorp.de> |