refactor worker function to remove code duplication

Thanks: Guillem Jover <guillem@debian.org>
main
parent d244f4f1de
commit 113532b3e1
Signed by: josch
GPG Key ID: F2CBA5C78FBD83E1

@ -5963,8 +5963,6 @@ sub main() {
my $sigset = POSIX::SigSet->new(SIGINT, SIGHUP, SIGPIPE, SIGTERM); my $sigset = POSIX::SigSet->new(SIGINT, SIGHUP, SIGPIPE, SIGTERM);
POSIX::sigprocmask(SIG_BLOCK, $sigset) or error "Can't block signals: $!"; POSIX::sigprocmask(SIG_BLOCK, $sigset) or error "Can't block signals: $!";
my $pid;
# a pipe to transfer the final tarball from the child to the parent # a pipe to transfer the final tarball from the child to the parent
pipe my $rfh, my $wfh; pipe my $rfh, my $wfh;
@ -5979,163 +5977,107 @@ sub main() {
# b) it puts code writing the protocol outside of the helper/listener # b) it puts code writing the protocol outside of the helper/listener
# c) the forked listener process cannot communicate to its parent # c) the forked listener process cannot communicate to its parent
pipe my $nblkreader, my $nblkwriter or error "pipe failed: $!"; pipe my $nblkreader, my $nblkwriter or error "pipe failed: $!";
if ($options->{mode} eq 'unshare') {
$pid = get_unshare_cmd(
sub {
# child
local $SIG{'INT'} = 'DEFAULT';
local $SIG{'HUP'} = 'DEFAULT';
local $SIG{'PIPE'} = 'DEFAULT';
local $SIG{'TERM'} = 'DEFAULT';
# unblock all delayed signals (and possibly handle them)
POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
or error "Can't unblock signals: $!";
close $rfh;
close $parentsock;
open(STDOUT, '>&', STDERR) or error "cannot open STDOUT: $!";
setup($options);
print $childsock (pack('n', 0) . 'adios'); my $worker = sub {
$childsock->flush(); # child
local $SIG{'INT'} = 'DEFAULT';
close $childsock; local $SIG{'HUP'} = 'DEFAULT';
local $SIG{'PIPE'} = 'DEFAULT';
close $nblkreader; local $SIG{'TERM'} = 'DEFAULT';
if (!$options->{dryrun} && $options->{format} eq 'ext2') {
my $numblocks = approx_disk_usage($options->{root});
print $nblkwriter "$numblocks\n";
$nblkwriter->flush();
}
close $nblkwriter;
if ($options->{dryrun}) {
info "simulate creating tarball...";
} elsif (any { $_ eq $options->{format} }
('tar', 'squashfs', 'ext2')) {
info "creating tarball...";
# redirect tar output to the writing end of the pipe so
# that the parent process can capture the output
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
# Add ./dev as the first entries of the tar file.
# We cannot add them after calling tar, because there is no
# way to prevent tar from writing NULL entries at the end.
if (any { $_ eq 'output/dev' } @{ $options->{skip} }) {
info "skipping output/dev as requested";
} else {
print $devtar;
}
# pack everything except ./dev # unblock all delayed signals (and possibly handle them)
0 == system('tar', @taropts, '-C', $options->{root}, '.') POSIX::sigprocmask(SIG_UNBLOCK, $sigset)
or error "tar failed: $?"; or error "Can't unblock signals: $!";
info "done"; close $rfh;
} elsif (any { $_ eq $options->{format} } close $parentsock;
('directory', 'null')) { open(STDOUT, '>&', STDERR) or error "cannot open STDOUT: $!";
# nothing to do
} else {
error "unknown format: $options->{format}";
}
exit 0; setup($options);
},
\@idmap
);
} elsif (any { $_ eq $options->{mode} }
('root', 'fakechroot', 'chrootless')) {
$pid = fork() // error "fork() failed: $!";
if ($pid == 0) {
local $SIG{'INT'} = 'DEFAULT';
local $SIG{'HUP'} = 'DEFAULT';
local $SIG{'PIPE'} = 'DEFAULT';
local $SIG{'TERM'} = 'DEFAULT';
# unblock all delayed signals (and possibly handle them) print $childsock (pack('n', 0) . 'adios');
POSIX::sigprocmask(SIG_UNBLOCK, $sigset) $childsock->flush();
or error "Can't unblock signals: $!";
close $rfh; close $childsock;
close $parentsock;
open(STDOUT, '>&', STDERR) or error "cannot open STDOUT: $!";
setup($options); close $nblkreader;
if (!$options->{dryrun} && $options->{format} eq 'ext2') {
my $numblocks = approx_disk_usage($options->{root});
print $nblkwriter "$numblocks\n";
$nblkwriter->flush();
}
close $nblkwriter;
print $childsock (pack('n', 0) . 'adios'); if ($options->{dryrun}) {
$childsock->flush(); info "simulate creating tarball...";
} elsif (any { $_ eq $options->{format} } ('tar', 'squashfs', 'ext2'))
{
info "creating tarball...";
close $childsock; # redirect tar output to the writing end of the pipe so
# that the parent process can capture the output
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
close $nblkreader; # Add ./dev as the first entries of the tar file.
if (!$options->{dryrun} && $options->{format} eq 'ext2') { # We cannot add them after calling tar, because there is no
my $numblocks = approx_disk_usage($options->{root}); # way to prevent tar from writing NULL entries at the end.
print $nblkwriter $numblocks; if (any { $_ eq 'output/dev' } @{ $options->{skip} }) {
$nblkwriter->flush(); info "skipping output/dev as requested";
} else {
print $devtar;
} }
close $nblkwriter;
if ($options->{dryrun}) {
info "simulate creating tarball...";
} elsif (any { $_ eq $options->{format} }
('tar', 'squashfs', 'ext2')) {
info "creating tarball...";
# redirect tar output to the writing end of the pipe so that
# the parent process can capture the output
open(STDOUT, '>&', $wfh) or error "cannot open STDOUT: $!";
# Add ./dev as the first entries of the tar file.
# We cannot add them after calling tar, because there is no way
# to prevent tar from writing NULL entries at the end.
if (any { $_ eq 'output/dev' } @{ $options->{skip} }) {
info "skipping output/dev as requested";
} else {
print $devtar;
}
if ($options->{mode} eq 'fakechroot') { if ($options->{mode} eq 'unshare') {
# By default, FAKECHROOT_EXCLUDE_PATH includes /proc and # pack everything except ./dev
# /sys which means that the resulting tarball will contain 0 == system('tar', @taropts, '-C', $options->{root}, '.')
# the permission and ownership information of /proc and or error "tar failed: $?";
# /sys from the outside, which we want to avoid. } elsif ($options->{mode} eq 'fakechroot') {
## no critic (Variables::RequireLocalizedPunctuationVars) # By default, FAKECHROOT_EXCLUDE_PATH includes /proc and /sys
$ENV{FAKECHROOT_EXCLUDE_PATH} = "/dev"; # which means that the resulting tarball will contain the
# Fakechroot requires tar to run inside the chroot or # permission and ownership information of /proc and /sys from
# otherwise absolute symlinks will include the path to the # the outside, which we want to avoid.
# root directory ## no critic (Variables::RequireLocalizedPunctuationVars)
0 == system('chroot', $options->{root}, 'tar', $ENV{FAKECHROOT_EXCLUDE_PATH} = "/dev";
@taropts, '-C', '/', '.') # Fakechroot requires tar to run inside the chroot or otherwise
or error "tar failed: $?"; # absolute symlinks will include the path to the root directory
} elsif (any { $_ eq $options->{mode} } ('root', 'chrootless')) 0 == system('chroot', $options->{root}, 'tar',
{ @taropts, '-C', '/', '.')
# If the chroot directory is not owned by the root user, or error "tar failed: $?";
# then we assume that no measure was taken to fake root } elsif (any { $_ eq $options->{mode} } ('root', 'chrootless')) {
# permissions. Since the final tarball should contain # If the chroot directory is not owned by the root user, then
# entries with root ownership, we instruct tar to do so. # we assume that no measure was taken to fake root permissions.
my @owneropts = (); # Since the final tarball should contain entries with root
if ((stat $options->{root})[4] != 0) { # ownership, we instruct tar to do so.
push @owneropts, '--owner=0', '--group=0', my @owneropts = ();
'--numeric-owner'; if ((stat $options->{root})[4] != 0) {
} push @owneropts, '--owner=0', '--group=0',
0 == system('tar', @taropts, @owneropts, '-C', '--numeric-owner';
$options->{root}, '.')
or error "tar failed: $?";
} else {
error "unknown mode: $options->{mode}";
} }
0 == system('tar', @taropts, @owneropts, '-C',
info "done"; $options->{root}, '.')
} elsif (any { $_ eq $options->{format} } ('directory', 'null')) { or error "tar failed: $?";
# nothing to do
} else { } else {
error "unknown format: $options->{format}"; error "unknown mode: $options->{mode}";
} }
exit 0; info "done";
} elsif (any { $_ eq $options->{format} } ('directory', 'null')) {
# nothing to do
} else {
error "unknown format: $options->{format}";
}
exit 0;
};
my $pid;
if ($options->{mode} eq 'unshare') {
$pid = get_unshare_cmd($worker, \@idmap);
} elsif (any { $_ eq $options->{mode} }
('root', 'fakechroot', 'chrootless')) {
$pid = fork() // error "fork() failed: $!";
if ($pid == 0) {
$worker->();
} }
} else { } else {
error "unknown mode: $options->{mode}"; error "unknown mode: $options->{mode}";

Loading…
Cancel
Save