ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Linux-Clone/Clone.pm
Revision: 1.7
Committed: Sat Sep 3 23:48:17 2022 UTC (20 months, 2 weeks ago) by root
Branch: MAIN
Changes since 1.6: +5 -0 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 root 1.1 =head1 NAME
2    
3 root 1.3 Linux::Clone - an interface to the linux clone, unshare, setns, pivot_root and kcmp syscalls
4 root 1.1
5     =head1 SYNOPSIS
6    
7     use Linux::Clone;
8    
9     =head1 DESCRIPTION
10    
11 root 1.6 This module exposes the linux clone(2), unshare(2) and some related
12     syscalls to Perl.
13 root 1.1
14     =over 4
15    
16     =item $retval = unshare $flags
17    
18     The following CLONE_ flag values (without CLONE_ prefix) are supported for
19     unshare, if found, in this release. See the documentation for unshare(2)
20     for more info on what they do:
21    
22     Linux::Clone::FILES
23     Linux::Clone::FS
24     Linux::Clone::NEWNS (in unshare, implies FS)
25     Linux::Clone::VM (in unshare, implies SIGHAND)
26     Linux::Clone::THREAD (in unshare, implies VM, SIGHAND)
27     Linux::Clone::SIGHAND
28     Linux::Clone::SYSVSEM
29 root 1.2 Linux::Clone::NEWUSER (in unshare, implies CLONE_THREAD)
30     Linux::Clone::NEWPID
31 root 1.1 Linux::Clone::NEWUTS
32     Linux::Clone::NEWIPC
33     Linux::Clone::NEWNET
34 root 1.2 Linux::Clone::NEWCGROUP
35 root 1.1
36     Example: unshare the network namespace and prove that by calling ifconfig,
37 root 1.6 showing only the unconfigured lo interface.
38 root 1.1
39     Linux::Clone::unshare Linux::Clone::NEWNET
40     and "unshare: $!";
41 root 1.6 Linux::Clone::configure_loopback;
42     system "ifconfig";
43 root 1.1
44     Example: unshare the network namespace, initialise the loopback interface,
45     create a veth interface pair, put one interface into the parent processes
46     namespace (use ifconfig -a from another shell), configure the other
47     interface with 192.168.99.2 -> 192.168.99.1 and start a shell.
48    
49     use Linux::Clone;
50    
51     # unshare our network namespace
52     Linux::Clone::unshare Linux::Clone::NEWNET
53     and "unshare: $!";
54    
55 root 1.6 Linux::Clone::configure_loopback;
56    
57 root 1.1 my $ppid = getppid;
58    
59     system "
60     # create veth pair
61     ip link add name veth_master type veth peer name veth_slave
62    
63     # move veth_master to our parent process' namespace
64     ip link set veth_master netns $ppid
65    
66     # configure the local interface
67     ip link set veth_slave up
68     ip addr add 192.168.99.2/32 dev veth_slave
69     ip route add 192.168.99.1/32 dev veth_slave
70     ";
71    
72     print <<EOF;
73     say hi to your new network namespace, use exit to return.
74    
75     try this from another shell to get networking up:
76    
77     ip link set veth_master up
78     ip addr add 192.168.99.1/32 dev veth_master
79     ip route add 192.168.99.2/32 dev veth_master
80    
81     EOF
82     system "bash";
83    
84     Example: unshare the filesystem namespace and make a confusing bind mount
85     only visible to the current process.
86    
87     use Linux::Clone;
88    
89     Linux::Clone::unshare Linux::Clone::NEWNS
90     and die "unshare: $!";
91    
92 root 1.6 # now bind-mount /lib over /etc and ls -l /etc - looks scary
93 root 1.1 system "mount -n --bind /lib /etc";
94     system "ls -l /etc";
95    
96     =item $retval = Linux::Clone::clone $coderef, $stacksize, $flags[, $ptid, $tls, $ctid]
97    
98     Clones a new process as specified via C<$flags> and calls C<$coderef>
99     without any arguments (a closure might help you if you need to pass
100     arguments without global variables). The return value from coderef is
101     returned to the system.
102    
103     The C<$stacksize> specifies how large a stack to allocate for the
104     child. If it is C<0>, then a default stack size (currently 4MB) will be
105     allocated. There is currently no way to free this area again in the child.
106    
107     C<$ptid>, if specified, will receive the thread id, C<$tls>, if specified,
108     must contain a C<struct user_desc> and C<$ctid> is currently totally
109     unsupported and must not be specified.
110    
111     Since this call basically bypasses both perl and your libc (for example,
112     C<$$> might reflect the parent I<or> child pid in the child), you need to
113     be very careful when using this call, which means you should probably have
114     a very good understanding of perl memory management and how fork and clone
115     work.
116    
117     The following flags are supported for clone, in addition to all flags
118     supported by C<unshare>, above, and a signal number. When in doubt, refer
119     to the clone(2) manual page.
120    
121     Linux::Clone::PTRACE
122     Linux::Clone::VFORK
123     Linux::Clone::SETTLS (not yet implemented)
124     Linux::Clone::PARENT_SETTID (not yet implemented)
125     Linux::Clone::CHILD_SETTID (not yet implemented)
126     Linux::Clone::CHILD_CLEARTID (not yet implemented)
127 root 1.6 Linux::Clone::PIDFD (not yet implemented)
128 root 1.1 Linux::Clone::DETACHED
129     Linux::Clone::UNTRACED
130     Linux::Clone::IO
131 root 1.6 Linux::Clone::CSIGNAL exit signal mask
132 root 1.1
133     Note that for practical reasons you basically must not use
134     C<Linux::Clone::VM> or C<Linux::Clone::VFORK>, as perl is unlikely to cope
135     with that.
136    
137     This is the glibc clone call, it cannot be used to emulate fork.
138    
139     Example: do a fork-like clone, sharing nothing, slightly confusing perl
140     and your libc, and exit immediately.
141    
142     my $pid = Linux::Clone::clone sub { warn "in child"; 77 }, 0, POSIX::SIGCHLD;
143    
144 root 1.2 =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 root 1.3 The argument C<$nstype> can be C<0>, C<Linux::Clone::NEWIPC>,
150 root 1.5 C<Linux::Clone::NEWNET>, C<Linux::Clone::NEWUTS>, C<Linux::Clone::NEWCGROUP>,
151 root 1.2 C<Linux::Clone::NEWNS>, C<Linux::Clone::NEWPID> or C<Linux::Clone::NEWUSER>.
152    
153 root 1.3 =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 root 1.6 =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 root 1.3
176 root 1.1 =back
177    
178     =cut
179    
180     package Linux::Clone;
181    
182     # use common::sense;
183    
184     BEGIN {
185 root 1.6 our $VERSION = '1.3';
186 root 1.1
187     require XSLoader;
188     XSLoader::load (__PACKAGE__, $VERSION);
189     }
190    
191 root 1.6 sub configure_loopback() {
192     siocsifflags "lo"
193     and die "Linux::Clone::configure_looopback: unable to bring up loopback interface: $!\n";
194     }
195    
196 root 1.1 1;
197    
198 root 1.7 =head1 SEE ALSO
199    
200     L<IO::AIO> has some related functions, such as C<pidfd_send_signal>, and
201     some unrelated fucntions that might be useful.
202    
203 root 1.1 =head1 AUTHOR
204    
205     Marc Lehmann <schmorp@schmorp.de>
206     http://home.schmorp.de/
207    
208     =cut
209