#include <fcntl.h>
#include <pwd.h>
-#include "dasync.h"
+#include "dasynq.h"
#include "service.h"
#include "control.h"
#include "dinit-log.h"
*/
-using namespace dasync;
+using namespace dasynq;
using EventLoop_t = EventLoop<NullMutex>;
EventLoop_t eventLoop = EventLoop_t();
static void sigint_reboot_cb(EventLoop_t *eloop) noexcept;
static void sigquit_cb(EventLoop_t *eloop) noexcept;
static void sigterm_cb(EventLoop_t *eloop) noexcept;
-static void open_control_socket(EventLoop_t *loop) noexcept;
-static void close_control_socket(EventLoop_t *loop) noexcept;
+static void close_control_socket() noexcept;
static void control_socket_cb(EventLoop_t *loop, int fd);
-class ControlSocketWatcher : public PosixFdWatcher<NullMutex>
+void open_control_socket(bool report_ro_failure = true) noexcept;
+void setup_external_log() noexcept;
+
+
+class ControlSocketWatcher : public EventLoop_t::FdWatcher
{
- Rearm gotEvent(EventLoop_t * loop, int fd, int flags)
+ Rearm fdEvent(EventLoop_t &loop, int fd, int flags) override
{
- control_socket_cb(loop, fd);
+ control_socket_cb(&loop, fd);
return Rearm::REARM;
}
// TODO the fd is already stored, must we really store it again...
int fd;
- void registerWith(EventLoop_t * loop, int fd, int flags)
+ void addWatch(EventLoop_t &loop, int fd, int flags)
{
this->fd = fd;
- PosixFdWatcher<NullMutex>::registerWith(loop, fd, flags);
+ EventLoop_t::FdWatcher::addWatch(loop, fd, flags);
}
};
namespace {
- class CallbackSignalHandler : public PosixSignalWatcher<NullMutex>
+ class CallbackSignalHandler : public EventLoop_t::SignalWatcher
{
public:
typedef void (*cb_func_t)(EventLoop_t *);
this->cb_func = cb_func;
}
- Rearm gotSignal(EventLoop_t * eloop, int signo, SigInfo_p siginfo) override
+ Rearm received(EventLoop_t &eloop, int signo, SigInfo_p siginfo) override
{
service_set->stop_all_services(ShutdownType::REBOOT);
return Rearm::REARM;
}
};
- class ControlSocketWatcher : public PosixFdWatcher<NullMutex>
+ class ControlSocketWatcher : public EventLoop_t::FdWatcher
{
- Rearm gotEvent(EventLoop_t * loop, int fd, int flags)
+ Rearm fdEvent(EventLoop_t &loop, int fd, int flags)
{
- control_socket_cb(loop, fd);
+ control_socket_cb(&loop, fd);
return Rearm::REARM;
}
};
auto sigterm_watcher = CallbackSignalHandler(sigterm_cb);
- sigint_watcher.registerWatch(&eventLoop, SIGINT);
- sigquit_watcher.registerWatch(&eventLoop, SIGQUIT);
- sigterm_watcher.registerWatch(&eventLoop, SIGTERM);
+ sigint_watcher.addWatch(eventLoop, SIGINT);
+ sigquit_watcher.addWatch(eventLoop, SIGQUIT);
+ sigterm_watcher.addWatch(eventLoop, SIGTERM);
// Try to open control socket (may fail due to readonly filesystem)
- open_control_socket(&eventLoop);
+ open_control_socket(false);
#ifdef __linux__
if (am_system_init) {
eventLoop.run();
}
- close_control_socket(&eventLoop);
+ close_control_socket();
if (am_system_init) {
if (shutdown_type == ShutdownType::CONTINUE) {
try {
new ControlConn(loop, service_set, newfd); // will delete itself when it's finished
}
- catch (std::bad_alloc &bad_alloc_exc) {
- log(LogLevel::ERROR, "Accepting control connection: Out of memory");
+ catch (std::exception &exc) {
+ log(LogLevel::ERROR, "Accepting control connection: ", exc.what());
close(newfd);
}
}
}
-static void open_control_socket(EventLoop_t *loop) noexcept
+void open_control_socket(bool report_ro_failure) noexcept
{
if (! control_socket_open) {
const char * saddrname = control_socket_path;
}
if (bind(sockfd, (struct sockaddr *) name, sockaddr_size) == -1) {
- log(LogLevel::ERROR, "Error binding control socket: ", strerror(errno));
+ if (errno != EROFS || report_ro_failure) {
+ log(LogLevel::ERROR, "Error binding control socket: ", strerror(errno));
+ }
close(sockfd);
free(name);
return;
return;
}
- control_socket_open = true;
- control_socket_io.registerWith(&eventLoop, sockfd, in_events);
+ try {
+ control_socket_io.addWatch(eventLoop, sockfd, IN_EVENTS);
+ control_socket_open = true;
+ }
+ catch (std::exception &e)
+ {
+ log(LogLevel::ERROR, "Could not setup I/O on control socket: ", e.what());
+ close(sockfd);
+ }
}
}
-static void close_control_socket(EventLoop_t *loop) noexcept
+static void close_control_socket() noexcept
{
if (control_socket_open) {
int fd = control_socket_io.fd;
- control_socket_io.deregisterWatch(&eventLoop);
+ control_socket_io.deregister(eventLoop);
close(fd);
// Unlink the socket:
}
}
-static void setup_external_log() noexcept
+void setup_external_log() noexcept
{
if (! external_log_open) {
}
}
-// Called from service when the system is "rw ready" (filesystem mounted r/w etc).
-// May be called more than once.
-void system_rw_ready() noexcept
-{
- open_control_socket(&eventLoop);
- setup_external_log();
-}
-
/* handle SIGINT signal (generated by kernel when ctrl+alt+del pressed) */
static void sigint_reboot_cb(EventLoop_t *eloop) noexcept
{
// This allows remounting the filesystem read-only if the dinit binary has been
// unlinked. In that case the kernel holds the binary open, so that it can't be
// properly removed.
- close_control_socket(eloop);
+ close_control_socket();
execl("/sbin/shutdown", "/sbin/shutdown", (char *) 0);
log(LogLevel::ERROR, "Error executing /sbin/shutdown: ", strerror(errno));
}