mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
selftest: Add common fork_and_exec() function
Now the code has been refactored, we can move it into a common function. This reduces code duplication and means we have a common place where we start samba daemons from. Note that some daemons behave slightly different, but the $daemon_ctx allows us to customize their behaviour a bit. Signed-off-by: Tim Beale <timbeale@catalyst.net.nz> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
This commit is contained in:
parent
746e137777
commit
b976502d49
@ -620,6 +620,66 @@ sub get_env_for_process
|
|||||||
return $proc_envs;
|
return $proc_envs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sub fork_and_exec
|
||||||
|
{
|
||||||
|
my ($self, $env_vars, $daemon_ctx, $STDIN_READER) = @_;
|
||||||
|
|
||||||
|
unlink($daemon_ctx->{LOG_FILE});
|
||||||
|
print "STARTING $daemon_ctx->{NAME} for $ENV{ENVNAME}...";
|
||||||
|
|
||||||
|
my $pid = fork();
|
||||||
|
|
||||||
|
# exec the daemon in the child process
|
||||||
|
if ($pid == 0) {
|
||||||
|
# redirect the daemon's stdout/stderr to a log file
|
||||||
|
if (defined($daemon_ctx->{TEE_STDOUT})) {
|
||||||
|
# in some cases, we want out from samba to go to the log file,
|
||||||
|
# but also to the users terminal when running 'make test' on the
|
||||||
|
# command line. This puts it on stderr on the terminal
|
||||||
|
open STDOUT, "| tee $daemon_ctx->{LOG_FILE} 1>&2";
|
||||||
|
} else {
|
||||||
|
open STDOUT, ">$daemon_ctx->{LOG_FILE}";
|
||||||
|
}
|
||||||
|
open STDERR, '>&STDOUT';
|
||||||
|
|
||||||
|
SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
||||||
|
if (defined($daemon_ctx->{PCAP_FILE})) {
|
||||||
|
SocketWrapper::setup_pcap($daemon_ctx->{PCAP_FILE});
|
||||||
|
}
|
||||||
|
|
||||||
|
# setup ENV variables in the child process
|
||||||
|
set_env_for_process($daemon_ctx->{NAME}, $env_vars,
|
||||||
|
$daemon_ctx->{ENV_VARS});
|
||||||
|
|
||||||
|
# not all s3 daemons run in all testenvs (e.g. fileserver doesn't
|
||||||
|
# run winbindd). In which case, the child process just sleeps
|
||||||
|
if (defined($daemon_ctx->{SKIP_DAEMON})) {
|
||||||
|
$SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
|
||||||
|
my $signame = shift;
|
||||||
|
print("Skip $daemon_ctx->{NAME} received signal $signame");
|
||||||
|
exit 0;
|
||||||
|
};
|
||||||
|
sleep($self->{server_maxtime});
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
$ENV{MAKE_TEST_BINARY} = $daemon_ctx->{BINARY_PATH};
|
||||||
|
|
||||||
|
# we close the child's write-end of the pipe and redirect the read-end
|
||||||
|
# to its stdin. That way the daemon will receive an EOF on stdin when
|
||||||
|
# parent selftest process closes its write-end.
|
||||||
|
close($env_vars->{STDIN_PIPE});
|
||||||
|
open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
||||||
|
|
||||||
|
# the command args are stored as an array reference (because...Perl),
|
||||||
|
# so convert the reference back to an array
|
||||||
|
my @full_cmd = @{ $daemon_ctx->{FULL_CMD} };
|
||||||
|
exec(@full_cmd) or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
|
||||||
|
}
|
||||||
|
print "DONE ($pid)\n";
|
||||||
|
return $pid;
|
||||||
|
}
|
||||||
|
|
||||||
my @exported_envvars = (
|
my @exported_envvars = (
|
||||||
# domain stuff
|
# domain stuff
|
||||||
"DOMAIN",
|
"DOMAIN",
|
||||||
|
@ -1260,11 +1260,12 @@ sub make_bin_cmd
|
|||||||
|
|
||||||
sub check_or_start($$$$$) {
|
sub check_or_start($$$$$) {
|
||||||
my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_;
|
my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_;
|
||||||
|
my $STDIN_READER;
|
||||||
|
|
||||||
# use a pipe for stdin in the child processes. This allows
|
# use a pipe for stdin in the child processes. This allows
|
||||||
# those processes to monitor the pipe for EOF to ensure they
|
# those processes to monitor the pipe for EOF to ensure they
|
||||||
# exit when the test script exits
|
# exit when the test script exits
|
||||||
pipe(STDIN_READER, $env_vars->{STDIN_PIPE});
|
pipe($STDIN_READER, $env_vars->{STDIN_PIPE});
|
||||||
|
|
||||||
my $binary = Samba::bindir_path($self, "nmbd");
|
my $binary = Samba::bindir_path($self, "nmbd");
|
||||||
my @full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
my @full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
||||||
@ -1273,6 +1274,8 @@ sub check_or_start($$$$$) {
|
|||||||
my $nmbd_envs = Samba::get_env_for_process("nmbd", $env_vars);
|
my $nmbd_envs = Samba::get_env_for_process("nmbd", $env_vars);
|
||||||
delete $nmbd_envs->{RESOLV_WRAPPER_CONF};
|
delete $nmbd_envs->{RESOLV_WRAPPER_CONF};
|
||||||
delete $nmbd_envs->{RESOLV_WRAPPER_HOSTS};
|
delete $nmbd_envs->{RESOLV_WRAPPER_HOSTS};
|
||||||
|
|
||||||
|
# fork and exec() nmbd in the child process
|
||||||
my %daemon_ctx = (
|
my %daemon_ctx = (
|
||||||
NAME => "nmbd",
|
NAME => "nmbd",
|
||||||
BINARY_PATH => $binary,
|
BINARY_PATH => $binary,
|
||||||
@ -1283,39 +1286,10 @@ sub check_or_start($$$$$) {
|
|||||||
if ($nmbd ne "yes") {
|
if ($nmbd ne "yes") {
|
||||||
$daemon_ctx{SKIP_DAEMON} = 1;
|
$daemon_ctx{SKIP_DAEMON} = 1;
|
||||||
}
|
}
|
||||||
|
my $pid = Samba::fork_and_exec($self, $env_vars, \%daemon_ctx, $STDIN_READER);
|
||||||
|
|
||||||
unlink($daemon_ctx{LOG_FILE});
|
|
||||||
print "STARTING NMBD...";
|
|
||||||
my $pid = fork();
|
|
||||||
if ($pid == 0) {
|
|
||||||
open STDOUT, ">$daemon_ctx{LOG_FILE}";
|
|
||||||
open STDERR, '>&STDOUT';
|
|
||||||
|
|
||||||
SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
|
||||||
|
|
||||||
Samba::set_env_for_process($daemon_ctx{NAME}, $env_vars, $daemon_ctx{ENV_VARS});
|
|
||||||
|
|
||||||
if (defined($daemon_ctx{SKIP_DAEMON})) {
|
|
||||||
$SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
|
|
||||||
my $signame = shift;
|
|
||||||
print("Skip $daemon_ctx{NAME} received signal $signame");
|
|
||||||
exit 0;
|
|
||||||
};
|
|
||||||
sleep($self->{server_maxtime});
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ENV{MAKE_TEST_BINARY} = $daemon_ctx{BINARY_PATH};
|
|
||||||
|
|
||||||
close($env_vars->{STDIN_PIPE});
|
|
||||||
open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
|
||||||
|
|
||||||
exec(@{ $daemon_ctx{FULL_CMD} })
|
|
||||||
or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
|
|
||||||
}
|
|
||||||
$env_vars->{NMBD_TL_PID} = $pid;
|
$env_vars->{NMBD_TL_PID} = $pid;
|
||||||
write_pid($env_vars, "nmbd", $pid);
|
write_pid($env_vars, "nmbd", $pid);
|
||||||
print "DONE\n";
|
|
||||||
|
|
||||||
$binary = Samba::bindir_path($self, "winbindd");
|
$binary = Samba::bindir_path($self, "winbindd");
|
||||||
@full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
@full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
||||||
@ -1324,6 +1298,8 @@ sub check_or_start($$$$$) {
|
|||||||
if (not defined($ENV{WINBINDD_DONT_LOG_STDOUT})) {
|
if (not defined($ENV{WINBINDD_DONT_LOG_STDOUT})) {
|
||||||
push(@full_cmd, "--stdout");
|
push(@full_cmd, "--stdout");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fork and exec() winbindd in the child process
|
||||||
%daemon_ctx = (
|
%daemon_ctx = (
|
||||||
NAME => "winbindd",
|
NAME => "winbindd",
|
||||||
BINARY_PATH => $binary,
|
BINARY_PATH => $binary,
|
||||||
@ -1333,44 +1309,17 @@ sub check_or_start($$$$$) {
|
|||||||
if ($winbindd ne "yes") {
|
if ($winbindd ne "yes") {
|
||||||
$daemon_ctx{SKIP_DAEMON} = 1;
|
$daemon_ctx{SKIP_DAEMON} = 1;
|
||||||
}
|
}
|
||||||
|
my $pid = Samba::fork_and_exec($self, $env_vars, \%daemon_ctx, $STDIN_READER);
|
||||||
|
|
||||||
unlink($daemon_ctx{LOG_FILE});
|
|
||||||
print "STARTING WINBINDD...";
|
|
||||||
$pid = fork();
|
|
||||||
if ($pid == 0) {
|
|
||||||
open STDOUT, ">$daemon_ctx{LOG_FILE}";
|
|
||||||
open STDERR, '>&STDOUT';
|
|
||||||
|
|
||||||
SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
|
||||||
|
|
||||||
Samba::set_env_for_process($daemon_ctx{NAME}, $env_vars, $daemon_ctx{ENV_VARS});
|
|
||||||
|
|
||||||
if (defined($daemon_ctx{SKIP_DAEMON})) {
|
|
||||||
$SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
|
|
||||||
my $signame = shift;
|
|
||||||
print("Skip $daemon_ctx{NAME} received signal $signame");
|
|
||||||
exit 0;
|
|
||||||
};
|
|
||||||
sleep($self->{server_maxtime});
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ENV{MAKE_TEST_BINARY} = $daemon_ctx{BINARY_PATH};
|
|
||||||
|
|
||||||
close($env_vars->{STDIN_PIPE});
|
|
||||||
open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
|
||||||
|
|
||||||
exec(@{ $daemon_ctx{FULL_CMD} })
|
|
||||||
or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
|
|
||||||
}
|
|
||||||
$env_vars->{WINBINDD_TL_PID} = $pid;
|
$env_vars->{WINBINDD_TL_PID} = $pid;
|
||||||
write_pid($env_vars, "winbindd", $pid);
|
write_pid($env_vars, "winbindd", $pid);
|
||||||
print "DONE\n";
|
|
||||||
|
|
||||||
$binary = Samba::bindir_path($self, "smbd");
|
$binary = Samba::bindir_path($self, "smbd");
|
||||||
@full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
@full_cmd = $self->make_bin_cmd($binary, $env_vars,
|
||||||
$ENV{SMBD_OPTIONS}, $ENV{SMBD_VALGRIND},
|
$ENV{SMBD_OPTIONS}, $ENV{SMBD_VALGRIND},
|
||||||
$ENV{SMBD_DONT_LOG_STDOUT});
|
$ENV{SMBD_DONT_LOG_STDOUT});
|
||||||
|
|
||||||
|
# fork and exec() smbd in the child process
|
||||||
%daemon_ctx = (
|
%daemon_ctx = (
|
||||||
NAME => "smbd",
|
NAME => "smbd",
|
||||||
BINARY_PATH => $binary,
|
BINARY_PATH => $binary,
|
||||||
@ -1381,39 +1330,12 @@ sub check_or_start($$$$$) {
|
|||||||
$daemon_ctx{SKIP_DAEMON} = 1;
|
$daemon_ctx{SKIP_DAEMON} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
unlink($daemon_ctx{LOG_FILE});
|
my $pid = Samba::fork_and_exec($self, $env_vars, \%daemon_ctx, $STDIN_READER);
|
||||||
print "STARTING SMBD...";
|
|
||||||
$pid = fork();
|
|
||||||
if ($pid == 0) {
|
|
||||||
open STDOUT, ">$daemon_ctx{LOG_FILE}";
|
|
||||||
open STDERR, '>&STDOUT';
|
|
||||||
|
|
||||||
SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
|
||||||
|
|
||||||
Samba::set_env_for_process($daemon_ctx{NAME}, $env_vars, $daemon_ctx{ENV_VARS});
|
|
||||||
|
|
||||||
if (defined($daemon_ctx{SKIP_DAEMON})) {
|
|
||||||
$SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
|
|
||||||
my $signame = shift;
|
|
||||||
print("Skip $daemon_ctx{NAME} received signal $signame");
|
|
||||||
exit 0;
|
|
||||||
};
|
|
||||||
sleep($self->{server_maxtime});
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ENV{MAKE_TEST_BINARY} = $daemon_ctx{BINARY_PATH};
|
|
||||||
|
|
||||||
close($env_vars->{STDIN_PIPE});
|
|
||||||
open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
|
||||||
|
|
||||||
exec(@{ $daemon_ctx{FULL_CMD} })
|
|
||||||
or die("Unable to start $ENV{MAKE_TEST_BINARY}: $!");
|
|
||||||
}
|
|
||||||
$env_vars->{SMBD_TL_PID} = $pid;
|
$env_vars->{SMBD_TL_PID} = $pid;
|
||||||
write_pid($env_vars, "smbd", $pid);
|
write_pid($env_vars, "smbd", $pid);
|
||||||
print "DONE\n";
|
|
||||||
|
|
||||||
|
# close the parent's read-end of the pipe
|
||||||
close(STDIN_READER);
|
close(STDIN_READER);
|
||||||
|
|
||||||
return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd);
|
return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd);
|
||||||
|
@ -141,6 +141,7 @@ sub check_or_start($$$)
|
|||||||
$samba_envs->{KRB5_KDC_PROFILE} = $env_vars->{MITKDC_CONFIG};
|
$samba_envs->{KRB5_KDC_PROFILE} = $env_vars->{MITKDC_CONFIG};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# fork a child process and exec() samba
|
||||||
my %daemon_ctx = (
|
my %daemon_ctx = (
|
||||||
NAME => "samba",
|
NAME => "samba",
|
||||||
BINARY_PATH => $binary,
|
BINARY_PATH => $binary,
|
||||||
@ -149,30 +150,11 @@ sub check_or_start($$$)
|
|||||||
TEE_STDOUT => 1,
|
TEE_STDOUT => 1,
|
||||||
ENV_VARS => $samba_envs,
|
ENV_VARS => $samba_envs,
|
||||||
);
|
);
|
||||||
|
my $pid = Samba::fork_and_exec($self, $env_vars, \%daemon_ctx, $STDIN_READER);
|
||||||
|
|
||||||
print "STARTING SAMBA...\n";
|
|
||||||
my $pid = fork();
|
|
||||||
if ($pid == 0) {
|
|
||||||
# we want out from samba to go to the log file, but also
|
|
||||||
# to the users terminal when running 'make test' on the command
|
|
||||||
# line. This puts it on stderr on the terminal
|
|
||||||
open STDOUT, "| tee $daemon_ctx{LOG_FILE} 1>&2";
|
|
||||||
open STDERR, '>&STDOUT';
|
|
||||||
|
|
||||||
SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
|
||||||
|
|
||||||
Samba::set_env_for_process($daemon_ctx{NAME}, $env_vars, $daemon_ctx{ENV_VARS});
|
|
||||||
|
|
||||||
$ENV{MAKE_TEST_BINARY} = $daemon_ctx{BINARY_PATH};
|
|
||||||
|
|
||||||
close($env_vars->{STDIN_PIPE});
|
|
||||||
open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
|
||||||
|
|
||||||
exec(@{ $daemon_ctx{FULL_CMD} }) or die("Unable to start $daemon_ctx{BINARY_NAME}: $!");
|
|
||||||
}
|
|
||||||
$env_vars->{SAMBA_PID} = $pid;
|
$env_vars->{SAMBA_PID} = $pid;
|
||||||
print "DONE ($pid)\n";
|
|
||||||
|
|
||||||
|
# close the parent's read-end of the pipe
|
||||||
close($STDIN_READER);
|
close($STDIN_READER);
|
||||||
|
|
||||||
if ($self->wait_for_start($env_vars) != 0) {
|
if ($self->wait_for_start($env_vars) != 0) {
|
||||||
@ -415,6 +397,7 @@ sub setup_dns_hub_internal($$$)
|
|||||||
push (@args, "$env->{SERVER_IP}");
|
push (@args, "$env->{SERVER_IP}");
|
||||||
push (@args, Samba::realm_to_ip_mappings());
|
push (@args, Samba::realm_to_ip_mappings());
|
||||||
my @full_cmd = (@preargs, $binary, @args);
|
my @full_cmd = (@preargs, $binary, @args);
|
||||||
|
|
||||||
my %daemon_ctx = (
|
my %daemon_ctx = (
|
||||||
NAME => "dnshub",
|
NAME => "dnshub",
|
||||||
BINARY_PATH => $binary,
|
BINARY_PATH => $binary,
|
||||||
@ -430,33 +413,14 @@ sub setup_dns_hub_internal($$$)
|
|||||||
# exit when the test script exits
|
# exit when the test script exits
|
||||||
pipe($STDIN_READER, $env->{STDIN_PIPE});
|
pipe($STDIN_READER, $env->{STDIN_PIPE});
|
||||||
|
|
||||||
print "STARTING rootdnsforwarder...\n";
|
my $pid = Samba::fork_and_exec($self, $env, \%daemon_ctx, $STDIN_READER);
|
||||||
my $pid = fork();
|
|
||||||
if ($pid == 0) {
|
|
||||||
# we want out from samba to go to the log file, but also
|
|
||||||
# to the users terminal when running 'make test' on the command
|
|
||||||
# line. This puts it on stderr on the terminal
|
|
||||||
open STDOUT, "| tee $daemon_ctx{LOG_FILE} 1>&2";
|
|
||||||
open STDERR, '>&STDOUT';
|
|
||||||
|
|
||||||
SocketWrapper::set_default_iface($env->{SOCKET_WRAPPER_DEFAULT_IFACE});
|
|
||||||
SocketWrapper::setup_pcap($daemon_ctx{PCAP_FILE});
|
|
||||||
|
|
||||||
Samba::set_env_for_process($daemon_ctx{NAME}, $env, $daemon_ctx{ENV_VARS});
|
|
||||||
|
|
||||||
$ENV{MAKE_TEST_BINARY} = $daemon_ctx{BINARY_PATH};
|
|
||||||
|
|
||||||
close($env->{STDIN_PIPE});
|
|
||||||
open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
|
|
||||||
|
|
||||||
exec(@{ $daemon_ctx{FULL_CMD} })
|
|
||||||
or die("Unable to start $daemon_ctx{NAME}: $!");
|
|
||||||
}
|
|
||||||
$env->{SAMBA_PID} = $pid;
|
$env->{SAMBA_PID} = $pid;
|
||||||
$env->{KRB5_CONFIG} = "$prefix_abs/no_krb5.conf";
|
$env->{KRB5_CONFIG} = "$prefix_abs/no_krb5.conf";
|
||||||
|
|
||||||
|
# close the parent's read-end of the pipe
|
||||||
close($STDIN_READER);
|
close($STDIN_READER);
|
||||||
|
|
||||||
print "DONE\n";
|
|
||||||
return $env;
|
return $env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user