From ea553b5beecd938ab24e1493ad76bbc24507b598 Mon Sep 17 00:00:00 2001 From: ellie timoney Date: Wed, 21 Jun 2023 11:59:03 +1000 Subject: [PATCH] Instance: run fakesaslauthd as a wait=y DAEMON not strictly related to this PR, but I've been wanting to do this for ages, and now I can, and it shows that the previous commit works --- cassandane/Cassandane/Cyrus/Info.pm | 5 +++++ cassandane/Cassandane/Instance.pm | 35 ++++++++++++++++++++--------- cassandane/utils/fakesaslauthd | 19 +++++++++++++++- 3 files changed, 47 insertions(+), 12 deletions(-) diff --git a/cassandane/Cassandane/Cyrus/Info.pm b/cassandane/Cassandane/Cyrus/Info.pm index 5e9e512ae1..4047246ba2 100644 --- a/cassandane/Cassandane/Cyrus/Info.pm +++ b/cassandane/Cassandane/Cyrus/Info.pm @@ -88,6 +88,11 @@ sub run_cyr_info my @res = readline(RESULTS); close RESULTS; + if ($args[0] eq 'proc') { + # if we see our fakesaslauthd, no we didn't + @res = grep { $_ !~ m/\bfakesaslauthd\b/ } @res; + } + return @res; } diff --git a/cassandane/Cassandane/Instance.pm b/cassandane/Cassandane/Instance.pm index a9c7f4d98a..00a2964da0 100644 --- a/cassandane/Cassandane/Instance.pm +++ b/cassandane/Cassandane/Instance.pm @@ -1200,16 +1200,31 @@ sub start } # arrange for fakesaslauthd to be started by master - # XXX make this run as a DAEMON rather than a START my $fakesaslauthd_socket = "$self->{basedir}/run/mux"; + my $fakesaslauthd_isdaemon = 1; if ($self->{authdaemon}) { - $self->add_start( - name => 'fakesaslauthd', - argv => [ - abs_path('utils/fakesaslauthd'), - '-p', $fakesaslauthd_socket, - ], - ); + my ($maj, $min) = Cassandane::Instance->get_version( + $self->{installation}); + if ($maj < 3 || ($maj == 3 && $min < 4)) { + $self->add_start( + name => 'fakesaslauthd', + argv => [ + abs_path('utils/fakesaslauthd'), + '-p', $fakesaslauthd_socket, + ], + ); + $fakesaslauthd_isdaemon = 0; + } + elsif (not exists $self->{daemons}->{fakesaslauthd}) { + $self->add_daemon( + name => 'fakesaslauthd', + argv => [ + abs_path('utils/fakesaslauthd'), + '-p', $fakesaslauthd_socket, + ], + wait => 'y', + ); + } } if (!$self->{re_use_dir} || ! -d $self->{basedir}) @@ -1243,9 +1258,7 @@ sub start # give fakesaslauthd a moment (but not more than 2s) to set up its # socket before anything starts trying to connect to services - # XXX if this were a DAEMON with wait=y, this would be unnecessary, - # XXX though those didn't exist until 3.4 - if ($self->{authdaemon}) { + if ($self->{authdaemon} && !$fakesaslauthd_isdaemon) { my $tries = 0; while (not -S $fakesaslauthd_socket && $tries < 2_000_000) { $tries += usleep(10_000); # 10ms as us diff --git a/cassandane/utils/fakesaslauthd b/cassandane/utils/fakesaslauthd index 1cdb1a0277..af64fdc68b 100755 --- a/cassandane/utils/fakesaslauthd +++ b/cassandane/utils/fakesaslauthd @@ -3,6 +3,7 @@ # for any user. Use me for testing! use Getopt::Std; +use IO::Handle; use IO::Socket::UNIX; use Sys::Syslog qw(:standard :macros); @@ -16,13 +17,22 @@ sub get_counted_string return unpack("A$size", $data); } +# support running as a DAEMON with wait=y: +# * if fd 3 is already open, then we will need to write to it later to +# indicate we're ready. +# * we must grab this early, before the number gets used for something +# else, otherwise we won't be able to differentiate between the fd 3 +# we care about or some other thing +# * if fd 3 was not already open, $status_fd will be undef +my $status_fd = IO::Handle->new_from_fd(3, 'w'); + my %opts; getopts("C:dp:v", \%opts); die "need a socket path" if not $opts{p}; -openlog('fakesaslauthd', '', LOG_LOCAL6) +openlog('fakesaslauthd', 'pid', LOG_LOCAL6) or die "Cannot openlog"; # ok, we're good. background ourselves @@ -46,6 +56,13 @@ syslog LOG_INFO, "listening on $opts{p}"; my $shutdown = 0; $SIG{HUP} = sub { $shutdown++; }; +# okay, now we're ready to accept requests. inform our parent, +# if they were waiting to be informed +if ($ENV{CYRUS_ISDAEMON} && $status_fd) { + print $status_fd "ok\r\n"; + undef $status_fd; +} + while (my $client = $sock->accept()) { my $LoginName = get_counted_string($client); my $Password = get_counted_string($client);