ServiceSet to service_set, etc.
#include "control.h"
#include "service.h"
-bool ControlConn::processPacket()
+bool control_conn_t::processPacket()
{
using std::string;
return true;
}
- auto sd_type = static_cast<ShutdownType>(rbuf[1]);
+ auto sd_type = static_cast<shutdown_type_t>(rbuf[1]);
- service_set->stop_all_services(sd_type);
+ services->stop_all_services(sd_type);
char ackBuf[] = { DINIT_RP_ACK };
if (! queuePacket(ackBuf, 1)) return false;
return true;
}
-bool ControlConn::processFindLoad(int pktType)
+bool control_conn_t::processFindLoad(int pktType)
{
using std::string;
if (pktType == DINIT_CP_LOADSERVICE) {
// LOADSERVICE
try {
- record = service_set->loadService(serviceName);
+ record = services->loadService(serviceName);
}
- catch (ServiceLoadExc &slexc) {
+ catch (service_load_exc &slexc) {
log(LogLevel::ERROR, "Could not load service ", slexc.serviceName, ": ", slexc.excDescription);
}
}
else {
// FINDSERVICE
- record = service_set->find_service(serviceName.c_str());
+ record = services->find_service(serviceName.c_str());
}
if (record != nullptr) {
return true;
}
-bool ControlConn::processStartStop(int pktType)
+bool control_conn_t::processStartStop(int pktType)
{
using std::string;
// start service, mark as required
if (do_pin) service->pinStart();
service->start();
- service_set->processQueues(true);
+ services->processQueues(true);
already_there = service->getState() == ServiceState::STARTED;
break;
case DINIT_CP_STOPSERVICE:
if (do_pin) service->pinStop();
service->stop(true);
service->forceStop();
- service_set->processQueues(false);
+ services->processQueues(false);
already_there = service->getState() == ServiceState::STOPPED;
break;
case DINIT_CP_WAKESERVICE:
// re-start a stopped service (do not mark as required)
if (do_pin) service->pinStart();
service->start(false);
- service_set->processQueues(true);
+ services->processQueues(true);
already_there = service->getState() == ServiceState::STARTED;
break;
case DINIT_CP_RELEASESERVICE:
// remove required mark, stop if not required by dependents
if (do_pin) service->pinStop();
service->stop(false);
- service_set->processQueues(false);
+ services->processQueues(false);
already_there = service->getState() == ServiceState::STOPPED;
break;
}
return true;
}
-bool ControlConn::processUnpinService()
+bool control_conn_t::processUnpinService()
{
using std::string;
}
else {
service->unpin();
- service_set->processQueues(true);
+ services->processQueues(true);
char ack_buf[] = { (char) DINIT_RP_ACK };
if (! queuePacket(ack_buf, 1)) return false;
}
return true;
}
-bool ControlConn::listServices()
+bool control_conn_t::listServices()
{
rbuf.consume(1); // clear request packet
chklen = 0;
try {
- auto slist = service_set->listServices();
+ auto slist = services->listServices();
for (auto sptr : slist) {
std::vector<char> pkt_buf;
}
}
-ControlConn::handle_t ControlConn::allocateServiceHandle(service_record *record)
+control_conn_t::handle_t control_conn_t::allocateServiceHandle(service_record *record)
{
bool is_unique = true;
handle_t largest_seen = 0;
}
-bool ControlConn::queuePacket(const char *pkt, unsigned size) noexcept
+bool control_conn_t::queuePacket(const char *pkt, unsigned size) noexcept
{
int in_flag = bad_conn_close ? 0 : IN_EVENTS;
bool was_empty = outbuf.empty();
// This queuePacket method is frustratingly similar to the one above, but the subtle differences
// make them extraordinary difficult to combine into a single method.
-bool ControlConn::queuePacket(std::vector<char> &&pkt) noexcept
+bool control_conn_t::queuePacket(std::vector<char> &&pkt) noexcept
{
int in_flag = bad_conn_close ? 0 : IN_EVENTS;
bool was_empty = outbuf.empty();
}
}
-bool ControlConn::rollbackComplete() noexcept
+bool control_conn_t::rollbackComplete() noexcept
{
char ackBuf[2] = { DINIT_ROLLBACK_COMPLETED, 2 };
return queuePacket(ackBuf, 2);
}
-bool ControlConn::dataReady() noexcept
+bool control_conn_t::dataReady() noexcept
{
int fd = iob.get_watched_fd();
return false;
}
-bool ControlConn::sendData() noexcept
+bool control_conn_t::sendData() noexcept
{
if (outbuf.empty() && bad_conn_close) {
if (oom_close) {
return false;
}
-ControlConn::~ControlConn() noexcept
+control_conn_t::~control_conn_t() noexcept
{
close(iob.get_watched_fd());
iob.deregister(*loop);
// Control connection for dinit
using namespace dasynq;
-using EventLoop_t = event_loop<null_mutex>;
+using eventloop_t = event_loop<null_mutex>;
-class ControlConn;
-class ControlConnWatcher;
+class control_conn_t;
+class control_conn_watcher;
// forward-declaration of callback:
-static rearm control_conn_cb(EventLoop_t *loop, ControlConnWatcher *watcher, int revents);
+static rearm control_conn_cb(eventloop_t *loop, control_conn_watcher *watcher, int revents);
// Pointer to the control connection that is listening for rollback completion
-extern ControlConn * rollback_handler_conn;
+extern control_conn_t * rollback_handler_conn;
extern int active_control_conns;
// (1 byte) packet length (including all fields)
// N bytes: packet data (N = (length - 2))
-class ServiceSet;
+class service_set;
class service_record;
-class ControlConnWatcher : public EventLoop_t::bidi_fd_watcher_impl<ControlConnWatcher>
+class control_conn_watcher : public eventloop_t::bidi_fd_watcher_impl<control_conn_watcher>
{
- inline rearm receiveEvent(EventLoop_t &loop, int fd, int flags) noexcept;
+ inline rearm receiveEvent(eventloop_t &loop, int fd, int flags) noexcept;
public:
- rearm read_ready(EventLoop_t &loop, int fd) noexcept
+ rearm read_ready(eventloop_t &loop, int fd) noexcept
{
return receiveEvent(loop, fd, IN_EVENTS);
}
- rearm write_ready(EventLoop_t &loop, int fd) noexcept
+ rearm write_ready(eventloop_t &loop, int fd) noexcept
{
return receiveEvent(loop, fd, OUT_EVENTS);
}
- EventLoop_t * eventLoop;
+ eventloop_t * eventLoop;
void set_watches(int flags)
{
- EventLoop_t::bidi_fd_watcher::set_watches(*eventLoop, flags);
+ eventloop_t::bidi_fd_watcher::set_watches(*eventLoop, flags);
}
- void registerWith(EventLoop_t &loop, int fd, int flags)
+ void registerWith(eventloop_t &loop, int fd, int flags)
{
this->eventLoop = &loop;
- bidi_fd_watcher<EventLoop_t>::add_watch(loop, fd, flags);
+ bidi_fd_watcher<eventloop_t>::add_watch(loop, fd, flags);
}
};
-inline rearm ControlConnWatcher::receiveEvent(EventLoop_t &loop, int fd, int flags) noexcept
+inline rearm control_conn_watcher::receiveEvent(eventloop_t &loop, int fd, int flags) noexcept
{
return control_conn_cb(&loop, this, flags);
}
-class ControlConn : private ServiceListener
+class control_conn_t : private service_listener
{
- friend rearm control_conn_cb(EventLoop_t *loop, ControlConnWatcher *watcher, int revents);
+ friend rearm control_conn_cb(eventloop_t *loop, control_conn_watcher *watcher, int revents);
- ControlConnWatcher iob;
- EventLoop_t *loop;
- ServiceSet *service_set;
+ control_conn_watcher iob;
+ eventloop_t *loop;
+ service_set *services;
bool bad_conn_close = false; // close when finished output?
bool oom_close = false; // send final 'out of memory' indicator
int chklen;
// Receive buffer
- CPBuffer<1024> rbuf;
+ cpbuffer<1024> rbuf;
template <typename T> using list = std::list<T>;
template <typename T> using vector = std::vector<T>;
// Process service event broadcast.
// Note that this can potentially be called during packet processing (upon issuing
// service start/stop orders etc).
- void serviceEvent(service_record * service, ServiceEvent event) noexcept final override
+ void serviceEvent(service_record * service, service_event event) noexcept final override
{
// For each service handle corresponding to the event, send an information packet.
auto range = serviceKeyMap.equal_range(service);
}
public:
- ControlConn(EventLoop_t * loop, ServiceSet * service_set, int fd) : loop(loop), service_set(service_set), chklen(0)
+ control_conn_t(eventloop_t * loop, service_set * services_p, int fd) : loop(loop), services(services_p), chklen(0)
{
iob.registerWith(*loop, fd, IN_EVENTS);
active_control_conns++;
bool rollbackComplete() noexcept;
- virtual ~ControlConn() noexcept;
+ virtual ~control_conn_t() noexcept;
};
-static rearm control_conn_cb(EventLoop_t * loop, ControlConnWatcher * watcher, int revents)
+static rearm control_conn_cb(eventloop_t * loop, control_conn_watcher * watcher, int revents)
{
- char * cc_addr = (reinterpret_cast<char *>(watcher)) - offsetof(ControlConn, iob);
- ControlConn *conn = reinterpret_cast<ControlConn *>(cc_addr);
+ char * cc_addr = (reinterpret_cast<char *>(watcher)) - offsetof(control_conn_t, iob);
+ control_conn_t *conn = reinterpret_cast<control_conn_t *>(cc_addr);
if (revents & IN_EVENTS) {
if (conn->dataReady()) {
delete conn;
#include <cstring>
// control protocol buffer, a circular buffer with 1024-byte capacity.
-template <int SIZE> class CPBuffer
+template <int SIZE> class cpbuffer
{
char buf[SIZE];
int cur_idx = 0;
#include "dinit-log.h"
#include "cpbuffer.h"
-extern EventLoop_t eventLoop;
+extern eventloop_t eventLoop;
static bool log_current_line[2]; // Whether the current line is being logged (for console, main log)
LogLevel log_level[2] = { LogLevel::WARN, LogLevel::WARN };
-static ServiceSet *service_set = nullptr; // Reference to service set
+static service_set *services = nullptr; // Reference to service set
namespace {
-class BufferedLogStream : public EventLoop_t::fd_watcher_impl<BufferedLogStream>
+class BufferedLogStream : public eventloop_t::fd_watcher_impl<BufferedLogStream>
{
private:
const char *special_buf; // buffer containing special message
int msg_index; // index into special message
- CPBuffer<4096> log_buffer;
+ cpbuffer<4096> log_buffer;
public:
release = false;
}
- rearm fd_event(EventLoop_t &loop, int fd, int flags) noexcept;
+ rearm fd_event(eventloop_t &loop, int fd, int flags) noexcept;
// Check whether the console can be released.
void flushForRelease();
if (release) {
int flags = fcntl(1, F_GETFL, 0);
fcntl(1, F_SETFL, flags & ~O_NONBLOCK);
- service_set->pull_console_queue();
+ services->pull_console_queue();
}
}
// release when it's finished.
}
-rearm BufferedLogStream::fd_event(EventLoop_t &loop, int fd, int flags) noexcept
+rearm BufferedLogStream::fd_event(eventloop_t &loop, int fd, int flags) noexcept
{
if ((! partway) && (! special) && discarded) {
special_buf = "dinit: *** message discarded due to full buffer ****\n";
// Initialise the logging subsystem
// Potentially throws std::bad_alloc or std::system_error
-void init_log(ServiceSet *sset)
+void init_log(service_set *sset)
{
- service_set = sset;
+ services = sset;
log_stream[DLOG_CONS].add_watch(eventLoop, STDOUT_FILENO, OUT_EVENTS, false);
enable_console_log(true);
}
#include <cstdio>
#include <climits>
-class ServiceSet;
+class service_set;
enum class LogLevel {
DEBUG,
extern LogLevel log_level[2];
void enable_console_log(bool do_enable) noexcept;
-void init_log(ServiceSet *sset);
+void init_log(service_set *sset);
void setup_main_log(int fd);
bool is_log_flushed() noexcept;
void discard_console_log_buffer() noexcept;
using namespace dasynq;
-using EventLoop_t = event_loop<null_mutex>;
+using eventloop_t = event_loop<null_mutex>;
-EventLoop_t eventLoop = EventLoop_t();
+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 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 close_control_socket() noexcept;
static void wait_for_user_input() noexcept;
-static void control_socket_cb(EventLoop_t *loop, int fd);
+static void control_socket_cb(eventloop_t *loop, int fd);
void open_control_socket(bool report_ro_failure = true) noexcept;
void setup_external_log() noexcept;
-class ControlSocketWatcher : public EventLoop_t::fd_watcher_impl<ControlSocketWatcher>
-{
- public:
- rearm fd_event(EventLoop_t &loop, int fd, int flags) noexcept
- {
- control_socket_cb(&loop, fd);
- return rearm::REARM;
- }
-};
-
-ControlSocketWatcher control_socket_io;
-
-
// Variables
-static ServiceSet *service_set;
+static service_set *services;
static bool am_system_init = false; // true if we are the system init process
namespace {
- class CallbackSignalHandler : public EventLoop_t::signal_watcher_impl<CallbackSignalHandler>
+ class callback_signal_handler : public eventloop_t::signal_watcher_impl<callback_signal_handler>
{
public:
- typedef void (*cb_func_t)(EventLoop_t &);
+ typedef void (*cb_func_t)(eventloop_t &);
private:
cb_func_t cb_func;
public:
- CallbackSignalHandler() : cb_func(nullptr) { }
- CallbackSignalHandler(cb_func_t pcb_func) : cb_func(pcb_func) { }
+ callback_signal_handler() : cb_func(nullptr) { }
+ callback_signal_handler(cb_func_t pcb_func) : cb_func(pcb_func) { }
void setCbFunc(cb_func_t cb_func)
{
this->cb_func = cb_func;
}
- rearm received(EventLoop_t &eloop, int signo, siginfo_p siginfo)
+ rearm received(eventloop_t &eloop, int signo, siginfo_p siginfo)
{
cb_func(eloop);
return rearm::REARM;
}
};
- class ControlSocketWatcher : public EventLoop_t::fd_watcher_impl<ControlSocketWatcher>
+ class control_socket_watcher : public eventloop_t::fd_watcher_impl<control_socket_watcher>
{
- rearm fd_event(EventLoop_t &loop, int fd, int flags)
+ public:
+ rearm fd_event(eventloop_t &loop, int fd, int flags) noexcept
{
control_socket_cb(&loop, fd);
return rearm::REARM;
}
};
+
+ control_socket_watcher control_socket_io;
}
static int dinit_main(int argc, char **argv)
}
// Set up signal handlers
- CallbackSignalHandler sigterm_watcher {sigterm_cb};
- CallbackSignalHandler sigint_watcher;
- CallbackSignalHandler sigquit_watcher;
+ callback_signal_handler sigterm_watcher {sigterm_cb};
+ callback_signal_handler sigint_watcher;
+ callback_signal_handler sigquit_watcher;
if (am_system_init) {
sigint_watcher.setCbFunc(sigint_reboot_cb);
#endif
/* start requested services */
- service_set = new ServiceSet(service_dir);
+ services = new service_set(service_dir);
- init_log(service_set);
+ init_log(services);
for (auto svc : services_to_start) {
try {
- service_set->startService(svc);
+ services->startService(svc);
// Note in general if we fail to start a service we don't need any special error handling,
// since we either leave other services running or, if it was the only service, then no
// services will be running and we will process normally (reboot if system process,
// exit if user process).
}
- catch (ServiceNotFound &snf) {
+ catch (service_not_found &snf) {
log(LogLevel::ERROR, snf.serviceName, ": Could not find service description.");
}
- catch (ServiceLoadExc &sle) {
+ catch (service_load_exc &sle) {
log(LogLevel::ERROR, sle.serviceName, ": ", sle.excDescription);
}
catch (std::bad_alloc &badalloce) {
event_loop:
// Process events until all services have terminated.
- while (service_set->count_active_services() != 0) {
+ while (services->count_active_services() != 0) {
eventLoop.run();
}
- ShutdownType shutdown_type = service_set->getShutdownType();
+ shutdown_type_t shutdown_type = services->getShutdownType();
if (am_system_init) {
logMsgBegin(LogLevel::INFO, "No more active services.");
- if (shutdown_type == ShutdownType::REBOOT) {
+ if (shutdown_type == shutdown_type_t::REBOOT) {
logMsgEnd(" Will reboot.");
}
- else if (shutdown_type == ShutdownType::HALT) {
+ else if (shutdown_type == shutdown_type_t::HALT) {
logMsgEnd(" Will halt.");
}
- else if (shutdown_type == ShutdownType::POWEROFF) {
+ else if (shutdown_type == shutdown_type_t::POWEROFF) {
logMsgEnd(" Will power down.");
}
else {
close_control_socket();
if (am_system_init) {
- if (shutdown_type == ShutdownType::CONTINUE) {
+ if (shutdown_type == shutdown_type_t::CONTINUE) {
// It could be that we started in single user mode, and the
// user has now exited the shell. We'll try and re-start the
// boot process...
try {
- service_set->startService("boot");
+ services->startService("boot");
goto event_loop; // yes, the "evil" goto
}
catch (...) {
// Now what do we do? try to reboot, but wait for user ack to avoid boot loop.
log(LogLevel::ERROR, "Could not start 'boot' service. Will attempt reboot.");
wait_for_user_input();
- shutdown_type = ShutdownType::REBOOT;
+ shutdown_type = shutdown_type_t::REBOOT;
}
}
const char * cmd_arg;
- if (shutdown_type == ShutdownType::HALT) {
+ if (shutdown_type == shutdown_type_t::HALT) {
cmd_arg = "-h";
}
- else if (shutdown_type == ShutdownType::REBOOT) {
+ else if (shutdown_type == shutdown_type_t::REBOOT) {
cmd_arg = "-r";
}
else {
eventLoop.run();
}
}
- else if (shutdown_type == ShutdownType::REBOOT) {
+ else if (shutdown_type == shutdown_type_t::REBOOT) {
// Non-system-process. If we got SIGINT, let's die due to it:
sigset_t sigwait_set;
sigemptyset(&sigwait_set);
}
// Callback for control socket
-static void control_socket_cb(EventLoop_t *loop, int sockfd)
+static void control_socket_cb(eventloop_t *loop, int sockfd)
{
// TODO limit the number of active connections. Keep a tally, and disable the
// control connection listening socket watcher if it gets high, and re-enable
if (newfd != -1) {
try {
- new ControlConn(loop, service_set, newfd); // will delete itself when it's finished
+ new control_conn_t(loop, services, newfd); // will delete itself when it's finished
}
catch (std::exception &exc) {
log(LogLevel::ERROR, "Accepting control connection: ", exc.what());
}
/* handle SIGINT signal (generated by Linux kernel when ctrl+alt+del pressed) */
-static void sigint_reboot_cb(EventLoop_t &eloop) noexcept
+static void sigint_reboot_cb(eventloop_t &eloop) noexcept
{
- service_set->stop_all_services(ShutdownType::REBOOT);
+ services->stop_all_services(shutdown_type_t::REBOOT);
}
/* handle SIGQUIT (if we are system init) */
-static void sigquit_cb(EventLoop_t &eloop) noexcept
+static void sigquit_cb(eventloop_t &eloop) noexcept
{
// This performs an immediate shutdown, without service rollback.
close_control_socket();
}
/* handle SIGTERM/SIGQUIT(non-system-daemon) - stop all services and shut down */
-static void sigterm_cb(EventLoop_t &eloop) noexcept
+static void sigterm_cb(eventloop_t &eloop) noexcept
{
- service_set->stop_all_services();
+ services->stop_all_services();
}
enum class Command;
static int issueLoadService(int socknum, const char *service_name);
-static int checkLoadReply(int socknum, CPBuffer<1024> &rbuffer, handle_t *handle_p, ServiceState *state_p);
+static int checkLoadReply(int socknum, cpbuffer<1024> &rbuffer, handle_t *handle_p, ServiceState *state_p);
static int startStopService(int socknum, const char *service_name, Command command, bool do_pin, bool wait_for_service, bool verbose);
static int unpinService(int socknum, const char *service_name, bool verbose);
static int listServices(int socknum);
// errcode = 0 if end of stream (remote end closed)
// errcode = errno if another error occurred
// Note that EINTR is ignored (i.e. the read will be re-tried).
-static void fillBufferTo(CPBuffer<1024> *buf, int fd, int rlength)
+static void fillBufferTo(cpbuffer<1024> *buf, int fd, int rlength)
{
do {
int r = buf->fill_to(fd, rlength);
// Wait for a reply packet, skipping over any information packets
// that are received in the meantime.
-static void wait_for_reply(CPBuffer<1024> &rbuffer, int fd)
+static void wait_for_reply(cpbuffer<1024> &rbuffer, int fd)
{
fillBufferTo(&rbuffer, fd, 1);
// Now we expect a reply:
try {
- CPBuffer<1024> rbuffer;
+ cpbuffer<1024> rbuffer;
wait_for_reply(rbuffer, socknum);
ServiceState state;
return 0;
}
- ServiceEvent completionEvent;
- ServiceEvent cancelledEvent;
+ service_event completionEvent;
+ service_event cancelledEvent;
if (do_stop) {
- completionEvent = ServiceEvent::STOPPED;
- cancelledEvent = ServiceEvent::STOPCANCELLED;
+ completionEvent = service_event::STOPPED;
+ cancelledEvent = service_event::STOPCANCELLED;
}
else {
- completionEvent = ServiceEvent::STARTED;
- cancelledEvent = ServiceEvent::STARTCANCELLED;
+ completionEvent = service_event::STARTED;
+ cancelledEvent = service_event::STARTCANCELLED;
}
// Wait until service started:
if (rbuffer[0] == DINIT_IP_SERVICEEVENT) {
handle_t ev_handle;
rbuffer.extract((char *) &ev_handle, 2, sizeof(ev_handle));
- ServiceEvent event = static_cast<ServiceEvent>(rbuffer[2 + sizeof(ev_handle)]);
+ service_event event = static_cast<service_event>(rbuffer[2 + sizeof(ev_handle)]);
if (ev_handle == handle) {
if (event == completionEvent) {
if (verbose) {
}
return 1;
}
- else if (! do_stop && event == ServiceEvent::FAILEDSTART) {
+ else if (! do_stop && event == service_event::FAILEDSTART) {
if (verbose) {
cout << "Service failed to start." << endl;
}
}
// Check that a "load service" reply was received, and that the requested service was found.
-static int checkLoadReply(int socknum, CPBuffer<1024> &rbuffer, handle_t *handle_p, ServiceState *state_p)
+static int checkLoadReply(int socknum, cpbuffer<1024> &rbuffer, handle_t *handle_p, ServiceState *state_p)
{
using namespace std;
// Now we expect a reply:
try {
- CPBuffer<1024> rbuffer;
+ cpbuffer<1024> rbuffer;
wait_for_reply(rbuffer, socknum);
handle_t handle;
return 1;
}
- CPBuffer<1024> rbuffer;
+ cpbuffer<1024> rbuffer;
wait_for_reply(rbuffer, socknum);
while (rbuffer[0] == DINIT_RP_SVCINFO) {
fillBufferTo(&rbuffer, socknum, 8);
static_assert((uintmax_t)std::numeric_limits<uid_t>::max() <= (uintmax_t)std::numeric_limits<unsigned long long>::max(), "uid_t is too large");
unsigned long long v = std::stoull(param, &ind, 0);
if (v > static_cast<unsigned long long>(std::numeric_limits<uid_t>::max()) || ind != param.length()) {
- throw ServiceDescriptionExc(service_name, uid_err_msg);
+ throw service_description_exc(service_name, uid_err_msg);
}
return v;
}
catch (std::out_of_range &exc) {
- throw ServiceDescriptionExc(service_name, uid_err_msg);
+ throw service_description_exc(service_name, uid_err_msg);
}
catch (std::invalid_argument &exc) {
// Ok, so it doesn't look like a number: proceed...
if (pwent == nullptr) {
// Maybe an error, maybe just no entry.
if (errno == 0) {
- throw ServiceDescriptionExc(service_name, "Specified user \"" + param + "\" does not exist in system database.");
+ throw service_description_exc(service_name, "Specified user \"" + param + "\" does not exist in system database.");
}
else {
- throw ServiceDescriptionExc(service_name, std::string("Error accessing user database: ") + strerror(errno));
+ throw service_description_exc(service_name, std::string("Error accessing user database: ") + strerror(errno));
}
}
try {
unsigned long long v = std::stoull(param, &ind, 0);
if (v > max || ind != param.length()) {
- throw ServiceDescriptionExc(service_name, num_err_msg);
+ throw service_description_exc(service_name, num_err_msg);
}
return v;
}
catch (std::out_of_range &exc) {
- throw ServiceDescriptionExc(service_name, num_err_msg);
+ throw service_description_exc(service_name, num_err_msg);
}
catch (std::invalid_argument &exc) {
- throw ServiceDescriptionExc(service_name, num_err_msg);
+ throw service_description_exc(service_name, num_err_msg);
}
}
// functions accept a leading minus sign...
unsigned long long v = std::stoull(param, &ind, 0);
if (v > static_cast<unsigned long long>(std::numeric_limits<gid_t>::max()) || ind != param.length()) {
- throw ServiceDescriptionExc(service_name, gid_err_msg);
+ throw service_description_exc(service_name, gid_err_msg);
}
return v;
}
catch (std::out_of_range &exc) {
- throw ServiceDescriptionExc(service_name, gid_err_msg);
+ throw service_description_exc(service_name, gid_err_msg);
}
catch (std::invalid_argument &exc) {
// Ok, so it doesn't look like a number: proceed...
if (grent == nullptr) {
// Maybe an error, maybe just no entry.
if (errno == 0) {
- throw ServiceDescriptionExc(service_name, "Specified group \"" + param + "\" does not exist in system database.");
+ throw service_description_exc(service_name, "Specified group \"" + param + "\" does not exist in system database.");
}
else {
- throw ServiceDescriptionExc(service_name, std::string("Error accessing group database: ") + strerror(errno));
+ throw service_description_exc(service_name, std::string("Error accessing group database: ") + strerror(errno));
}
}
break;
}
if (ch < '0' || ch > '9') {
- throw ServiceDescriptionExc(servicename, std::string("Bad value for ") + paramname);
+ throw service_description_exc(servicename, std::string("Bad value for ") + paramname);
}
// check for overflow
if (isec >= max_secs) {
- throw ServiceDescriptionExc(servicename, std::string("Too-large value for ") + paramname);
+ throw service_description_exc(servicename, std::string("Too-large value for ") + paramname);
}
isec *= 10;
isec += ch - '0';
for ( ; i < len; i++) {
char ch = paramval[i];
if (ch < '0' || ch > '9') {
- throw ServiceDescriptionExc(servicename, std::string("Bad value for ") + paramname);
+ throw service_description_exc(servicename, std::string("Bad value for ") + paramname);
}
insec += (ch - '0') * insec_m;
insec_m /= 10;
// Might throw a ServiceLoadExc exception if a dependency cycle is found or if another
// problem occurs (I/O error, service description not found etc). Throws std::bad_alloc
// if a memory allocation failure occurs.
-service_record * ServiceSet::loadServiceRecord(const char * name)
+service_record * service_set::loadServiceRecord(const char * name)
{
using std::string;
using std::ifstream;
service_record * rval = find_service(string(name));
if (rval != 0) {
if (rval->isDummy()) {
- throw ServiceCyclicDependency(name);
+ throw service_cyclic_dependency(name);
}
return rval;
}
list<pair<unsigned,unsigned>> stop_command_offsets;
string pid_file;
- ServiceType service_type = ServiceType::PROCESS;
+ service_type service_type = service_type::PROCESS;
std::list<service_record *> depends_on;
std::list<service_record *> depends_soft;
string logfile;
- OnstartFlags onstart_flags;
+ onstart_flags_t onstart_flags;
int term_signal = -1; // additional termination signal
bool auto_restart = false;
bool smooth_recovery = false;
service_file.open(service_filename.c_str(), ios::in);
}
catch (std::ios_base::failure &exc) {
- throw ServiceNotFound(name);
+ throw service_not_found(name);
}
// Add a dummy service record now to prevent infinite recursion in case of cyclic dependency
string setting = read_setting_name(i, end);
i = skipws(i, end);
if (i == end || (*i != '=' && *i != ':')) {
- throw ServiceDescriptionExc(name, "Badly formed line.");
+ throw service_description_exc(name, "Badly formed line.");
}
i = skipws(++i, end);
}
}
catch (std::logic_error &exc) {
- throw ServiceDescriptionExc(name, "socket-permissions: Badly-formed or out-of-range numeric value");
+ throw service_description_exc(name, "socket-permissions: Badly-formed or out-of-range numeric value");
}
}
else if (setting == "socket-uid") {
else if (setting == "type") {
string type_str = read_setting_value(i, end);
if (type_str == "scripted") {
- service_type = ServiceType::SCRIPTED;
+ service_type = service_type::SCRIPTED;
}
else if (type_str == "process") {
- service_type = ServiceType::PROCESS;
+ service_type = service_type::PROCESS;
}
else if (type_str == "bgprocess") {
- service_type = ServiceType::BGPROCESS;
+ service_type = service_type::BGPROCESS;
}
else if (type_str == "internal") {
- service_type = ServiceType::INTERNAL;
+ service_type = service_type::INTERNAL;
}
else {
- throw ServiceDescriptionExc(name, "Service type must be one of: \"scripted\","
+ throw service_description_exc(name, "Service type must be one of: \"scripted\","
" \"process\", \"bgprocess\" or \"internal\"");
}
}
onstart_flags.pass_cs_fd = true;
}
else {
- throw ServiceDescriptionExc(name, "Unknown option: " + option_txt);
+ throw service_description_exc(name, "Unknown option: " + option_txt);
}
}
}
string signame = read_setting_value(i, end, nullptr);
int signo = signalNameToNumber(signame);
if (signo == -1) {
- throw ServiceDescriptionExc(name, "Unknown/unsupported termination signal: " + signame);
+ throw service_description_exc(name, "Unknown/unsupported termination signal: " + signame);
}
else {
term_signal = signo;
max_restarts = parse_unum_param(limit_str, name, std::numeric_limits<int>::max());
}
else {
- throw ServiceDescriptionExc(name, "Unknown setting: " + setting);
+ throw service_description_exc(name, "Unknown setting: " + setting);
}
}
}
service_file.close();
- if (service_type == ServiceType::PROCESS || service_type == ServiceType::BGPROCESS || service_type == ServiceType::SCRIPTED) {
+ if (service_type == service_type::PROCESS || service_type == service_type::BGPROCESS || service_type == service_type::SCRIPTED) {
if (command.length() == 0) {
- throw ServiceDescriptionExc(name, "Service command not specified");
+ throw service_description_exc(name, "Service command not specified");
}
}
if (*iter == rval) {
// We've found the dummy record
delete rval;
- if (service_type == ServiceType::PROCESS) {
+ if (service_type == service_type::PROCESS) {
auto rvalps = new process_service(this, string(name), std::move(command),
command_offsets, &depends_on, &depends_soft);
rvalps->set_restart_interval(restart_interval, max_restarts);
rvalps->set_restart_delay(restart_delay);
rval = rvalps;
}
- else if (service_type == ServiceType::BGPROCESS) {
+ else if (service_type == service_type::BGPROCESS) {
auto rvalps = new bgproc_service(this, string(name), std::move(command),
command_offsets, &depends_on, &depends_soft);
rvalps->set_pid_file(std::move(pid_file));
rvalps->set_restart_delay(restart_delay);
rval = rvalps;
}
- else if (service_type == ServiceType::SCRIPTED) {
+ else if (service_type == service_type::SCRIPTED) {
rval = new scripted_service(this, string(name), std::move(command),
command_offsets, &depends_on, &depends_soft);
rval->setStopCommand(stop_command, stop_command_offsets);
// Must remove the dummy service record.
std::remove(records.begin(), records.end(), rval);
delete rval;
- throw ServiceDescriptionExc(name, std::move(setting_exc.getInfo()));
+ throw service_description_exc(name, std::move(setting_exc.getInfo()));
}
catch (...) {
// Must remove the dummy service record.
};
/* Service types */
-enum class ServiceType {
+enum class service_type {
DUMMY, // Dummy service, used to detect cyclice dependencies
PROCESS, // Service runs as a process, and can be stopped by
// sending the process a signal (usually SIGTERM)
};
/* Service events */
-enum class ServiceEvent {
+enum class service_event {
STARTED, // Service was started (reached STARTED state)
STOPPED, // Service was stopped (reached STOPPED state)
FAILEDSTART, // Service failed to start (possibly due to dependency failing)
};
/* Shutdown types */
-enum class ShutdownType {
+enum class shutdown_type_t {
CONTINUE, // Continue normal boot sequence (used after single-user shell)
HALT, // Halt system without powering down
POWEROFF, // Power off system
class service_record;
// Interface for listening to services
-class ServiceListener
+class service_listener
{
public:
// An event occurred on the service being observed.
// Listeners must not be added or removed during event notification.
- virtual void serviceEvent(service_record * service, ServiceEvent event) noexcept = 0;
+ virtual void serviceEvent(service_record * service, service_event event) noexcept = 0;
};
#endif
// from dinit.cc:
void open_control_socket(bool report_ro_failure = true) noexcept;
void setup_external_log() noexcept;
-extern EventLoop_t eventLoop;
+extern eventloop_t eventLoop;
// Find the requested service by name
static service_record * find_service(const std::list<service_record *> & records,
return (service_record *)0;
}
-service_record * ServiceSet::find_service(const std::string &name) noexcept
+service_record * service_set::find_service(const std::string &name) noexcept
{
return ::find_service(records, name.c_str());
}
-void ServiceSet::startService(const char *name)
+void service_set::startService(const char *name)
{
using namespace std;
service_record *record = loadServiceRecord(name);
processQueues(true);
}
-void ServiceSet::stopService(const std::string & name) noexcept
+void service_set::stopService(const std::string & name) noexcept
{
service_record *record = find_service(name);
if (record != nullptr) {
}
bool will_restart = (desired_state == ServiceState::STARTED)
- && service_set->get_auto_restart();
+ && services->get_auto_restart();
for (auto dependency : depends_on) {
// we signal dependencies in case they are waiting for us to stop:
release();
}
else if (required_by == 0) {
- service_set->service_inactive(this);
+ services->service_inactive(this);
}
}
logServiceStopped(service_name);
- notifyListeners(ServiceEvent::STOPPED);
+ notifyListeners(service_event::STOPPED);
}
-dasynq::rearm ServiceChildWatcher::status_change(EventLoop_t &loop, pid_t child, int status) noexcept
+dasynq::rearm service_child_watcher::status_change(eventloop_t &loop, pid_t child, int status) noexcept
{
base_process_service *sr = service;
bool service_record::do_auto_restart() noexcept
{
if (auto_restart) {
- return service_set->get_auto_restart();
+ return services->get_auto_restart();
}
return false;
}
// service process.
if (! restart_ps_process()) {
emergency_stop();
- service_set->processQueues(false);
+ services->processQueues(false);
}
return;
}
else {
emergency_stop();
}
- service_set->processQueues(false);
+ services->processQueues(false);
}
void bgproc_service::handle_exit_status(int exit_status) noexcept
if (need_stop) {
// Failed startup: no auto-restart.
emergency_stop();
- service_set->processQueues(false);
+ services->processQueues(false);
}
return;
doing_recovery = true;
if (! restart_ps_process()) {
emergency_stop();
- service_set->processQueues();
+ services->processQueues();
}
return;
}
stopDependents();
stopped();
}
- service_set->processQueues(false);
+ services->processQueues(false);
}
void scripted_service::handle_exit_status(int exit_status) noexcept
// can be stopped:
stopped();
}
- service_set->processQueues(false);
+ services->processQueues(false);
}
else { // STARTING
if (exit_status == 0) {
}
failed_to_start();
}
- service_set->processQueues(true);
+ services->processQueues(true);
}
}
-rearm ServiceIoWatcher::fd_event(EventLoop_t &loop, int fd, int flags) noexcept
+rearm ServiceIoWatcher::fd_event(eventloop_t &loop, int fd, int flags) noexcept
{
base_process_service *sr = service;
sr->waiting_for_execstat = false;
}
else {
// exec() succeeded.
- if (sr->service_type == ServiceType::PROCESS) {
+ if (sr->record_type == service_type::PROCESS) {
// This could be a smooth recovery (state already STARTED). Even more, the process
// might be stopped (and killed via a signal) during smooth recovery. We don't to
// process startup again in either case, so we check for state STARTING:
}
}
- sr->service_set->processQueues(true);
+ sr->services->processQueues(true);
return rearm::REMOVED;
}
if (required_by++ == 0) {
prop_require = !prop_release;
prop_release = false;
- service_set->addToPropQueue(this);
+ services->addToPropQueue(this);
}
}
// the require was pending though:
prop_release = !prop_require;
prop_require = false;
- service_set->addToPropQueue(this);
+ services->addToPropQueue(this);
if (service_state == ServiceState::STOPPED) {
- service_set->service_inactive(this);
+ services->service_inactive(this);
}
else {
do_stop();
// We're STOPPING, and that can be interrupted. Our dependencies might be STOPPING,
// but if so they are waiting (for us), so they too can be instantly returned to
// STARTING state.
- notifyListeners(ServiceEvent::STOPCANCELLED);
+ notifyListeners(service_event::STOPCANCELLED);
}
else if (! was_active) {
- service_set->service_active(this);
+ services->service_active(this);
}
service_state = ServiceState::STARTING;
waiting_for_deps = true;
if (startCheckDependencies(true)) {
- service_set->addToStartQueue(this);
+ services->addToStartQueue(this);
}
}
void service_record::dependencyStarted() noexcept
{
if (service_state == ServiceState::STARTING && waiting_for_deps) {
- service_set->addToStartQueue(this);
+ services->addToStartQueue(this);
}
}
if (start_deps) {
all_deps_started = false;
(*i)->prop_start = true;
- service_set->addToPropQueue(*i);
+ services->addToPropQueue(*i);
}
else {
return false;
if (start_deps) {
if (to->service_state != ServiceState::STARTED) {
to->prop_start = true;
- service_set->addToPropQueue(to);
+ services->addToPropQueue(to);
i->waiting_on = true;
all_deps_started = false;
}
logServiceStarted(service_name);
service_state = ServiceState::STARTED;
- notifyListeners(ServiceEvent::STARTED);
+ notifyListeners(service_event::STARTED);
if (onstart_flags.rw_ready) {
open_control_socket();
start_explicit = false;
release();
}
- notifyListeners(ServiceEvent::FAILEDSTART);
+ notifyListeners(service_event::FAILEDSTART);
// Cancel start of dependents:
for (sr_iter i = dependents.begin(); i != dependents.end(); i++) {
if ((*i)->service_state == ServiceState::STARTING) {
(*i)->prop_failure = true;
- service_set->addToPropQueue(*i);
+ services->addToPropQueue(*i);
}
}
for (auto i = soft_dpts.begin(); i != soft_dpts.end(); i++) {
}
bool child_status_registered = false;
- ControlConn *control_conn = nullptr;
+ control_conn_t *control_conn = nullptr;
int control_socket[2] = {-1, -1};
if (onstart_flags.pass_cs_fd) {
fcntl(control_socket[0], F_SETFD, fdflags | FD_CLOEXEC);
try {
- control_conn = new ControlConn(&eventLoop, service_set, control_socket[0]);
+ control_conn = new control_conn_t(&eventLoop, services, control_socket[0]);
}
catch (std::exception &exc) {
log(LogLevel::ERROR, service_name, ": can't launch process; out of memory");
{
if (service_state != ServiceState::STOPPED) {
force_stop = true;
- service_set->addToStopQueue(this);
+ services->addToStopQueue(this);
}
}
void service_record::dependentStopped() noexcept
{
if (service_state == ServiceState::STOPPING && waiting_for_deps) {
- service_set->addToStopQueue(this);
+ services->addToStopQueue(this);
}
}
}
// We must have had desired_state == STARTED.
- notifyListeners(ServiceEvent::STARTCANCELLED);
+ notifyListeners(service_event::STARTCANCELLED);
interrupt_start();
service_state = ServiceState::STOPPING;
waiting_for_deps = true;
if (stopDependents()) {
- service_set->addToStopQueue(this);
+ services->addToStopQueue(this);
}
}
}
(*i)->prop_stop = true;
- service_set->addToPropQueue(*i);
+ services->addToPropQueue(*i);
}
return all_deps_stopped;
// In most cases, the rest is done in handle_exit_status.
// If we are a BGPROCESS and the process is not our immediate child, however, that
// won't work - check for this now:
- if (service_type == ServiceType::BGPROCESS) {
+ if (record_type == service_type::BGPROCESS) {
int status;
pid_t r = waitpid(pid, &status, WNOHANG);
if (r == -1 && errno == ECHILD) {
pinned_started = false;
if (desired_state == ServiceState::STOPPED) {
do_stop();
- service_set->processQueues(false);
+ services->processQueues(false);
}
}
if (pinned_stopped) {
pinned_stopped = false;
if (desired_state == ServiceState::STARTED) {
do_start();
- service_set->processQueues(true);
+ services->processQueues(true);
}
}
}
void service_record::queue_for_console() noexcept
{
- service_set->append_console_queue(this);
+ services->append_console_queue(this);
}
void service_record::release_console() noexcept
{
- service_set->pull_console_queue();
+ services->pull_console_queue();
}
void service_record::interrupt_start() noexcept
{
- service_set->unqueue_console(this);
+ services->unqueue_console(this);
}
-void ServiceSet::service_active(service_record *sr) noexcept
+void service_set::service_active(service_record *sr) noexcept
{
active_services++;
}
-void ServiceSet::service_inactive(service_record *sr) noexcept
+void service_set::service_inactive(service_record *sr) noexcept
{
active_services--;
}
-base_process_service::base_process_service(ServiceSet *sset, string name, ServiceType service_type, string &&command,
+base_process_service::base_process_service(service_set *sset, string name, service_type service_type_p, string &&command,
std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft)
- : service_record(sset, name, service_type, std::move(command), command_offsets,
+ : service_record(sset, name, service_type_p, std::move(command), command_offsets,
pdepends_on, pdepends_soft), child_listener(this), child_status_listener(this)
{
restart_interval_count = 0;
desired_state = ServiceState::STOPPED;
forceStop();
}
- service_set->processQueues();
+ services->processQueues();
}
}
bool base_process_service::restart_ps_process() noexcept
{
- using time_val = EventLoop_t::time_val;
+ using time_val = eventloop_t::time_val;
time_val current_time;
eventLoop.get_time(current_time, clock_type::MONOTONIC);
service_record::interrupt_start();
}
-dasynq::rearm process_restart_timer::timer_expiry(EventLoop_t &, int expiry_count)
+dasynq::rearm process_restart_timer::timer_expiry(eventloop_t &, int expiry_count)
{
service->do_restart();
return dasynq::rearm::DISARM;
#include "dinit-ll.h"
/*
- * This header defines ServiceRecord, a data record maintaining information about a service,
- * and ServiceSet, a set of interdependent service records. It also defines some associated
+ * This header defines service_record, a data record maintaining information about a service,
+ * and service_set, a set of interdependent service records. It also defines some associated
* types and exceptions.
*
* Service states
* transition stage, at the latest.
*/
-struct OnstartFlags {
+struct onstart_flags_t {
bool rw_ready : 1;
bool log_ready : 1;
bool starts_on_console : 1; // starts in the foreground
bool pass_cs_fd : 1; // pass this service a control socket connection via fd
- OnstartFlags() noexcept : rw_ready(false), log_ready(false),
+ onstart_flags_t() noexcept : rw_ready(false), log_ready(false),
no_sigterm(false), runs_on_console(false), starts_on_console(false), pass_cs_fd(false)
{
}
};
// Exception while loading a service
-class ServiceLoadExc
+class service_load_exc
{
public:
std::string serviceName;
std::string excDescription;
protected:
- ServiceLoadExc(std::string serviceName, std::string &&desc) noexcept
+ service_load_exc(std::string serviceName, std::string &&desc) noexcept
: serviceName(serviceName), excDescription(std::move(desc))
{
}
};
-class ServiceNotFound : public ServiceLoadExc
+class service_not_found : public service_load_exc
{
public:
- ServiceNotFound(std::string serviceName) noexcept
- : ServiceLoadExc(serviceName, "Service description not found.")
+ service_not_found(std::string serviceName) noexcept
+ : service_load_exc(serviceName, "Service description not found.")
{
}
};
-class ServiceCyclicDependency : public ServiceLoadExc
+class service_cyclic_dependency : public service_load_exc
{
public:
- ServiceCyclicDependency(std::string serviceName) noexcept
- : ServiceLoadExc(serviceName, "Has cyclic dependency.")
+ service_cyclic_dependency(std::string serviceName) noexcept
+ : service_load_exc(serviceName, "Has cyclic dependency.")
{
}
};
-class ServiceDescriptionExc : public ServiceLoadExc
+class service_description_exc : public service_load_exc
{
public:
- ServiceDescriptionExc(std::string serviceName, std::string &&extraInfo) noexcept
- : ServiceLoadExc(serviceName, std::move(extraInfo))
+ service_description_exc(std::string serviceName, std::string &&extraInfo) noexcept
+ : service_load_exc(serviceName, std::move(extraInfo))
{
}
};
class service_record;
-class ServiceSet;
+class service_set;
class base_process_service;
/* Service dependency record */
-class ServiceDep
+class service_dep
{
service_record * from;
service_record * to;
/* Whether the 'from' service is holding an acquire on the 'to' service */
bool holding_acq;
- ServiceDep(service_record * from, service_record * to) noexcept : from(from), to(to), waiting_on(false), holding_acq(false)
+ service_dep(service_record * from, service_record * to) noexcept : from(from), to(to), waiting_on(false), holding_acq(false)
{ }
service_record * getFrom() noexcept
return r;
}
-class ServiceChildWatcher : public EventLoop_t::child_proc_watcher_impl<ServiceChildWatcher>
+class service_child_watcher : public eventloop_t::child_proc_watcher_impl<service_child_watcher>
{
public:
base_process_service * service;
- rearm status_change(EventLoop_t &eloop, pid_t child, int status) noexcept;
+ rearm status_change(eventloop_t &eloop, pid_t child, int status) noexcept;
- ServiceChildWatcher(base_process_service * sr) noexcept : service(sr) { }
+ service_child_watcher(base_process_service * sr) noexcept : service(sr) { }
};
-class ServiceIoWatcher : public EventLoop_t::fd_watcher_impl<ServiceIoWatcher>
+class ServiceIoWatcher : public eventloop_t::fd_watcher_impl<ServiceIoWatcher>
{
public:
base_process_service * service;
- rearm fd_event(EventLoop_t &eloop, int fd, int flags) noexcept;
+ rearm fd_event(eventloop_t &eloop, int fd, int flags) noexcept;
ServiceIoWatcher(base_process_service * sr) noexcept : service(sr) { }
};
typedef std::string string;
string service_name;
- ServiceType service_type; /* ServiceType::DUMMY, PROCESS, SCRIPTED, INTERNAL */
+ service_type record_type; /* ServiceType::DUMMY, PROCESS, SCRIPTED, INTERNAL */
ServiceState service_state = ServiceState::STOPPED; /* ServiceState::STOPPED, STARTING, STARTED, STOPPING */
ServiceState desired_state = ServiceState::STOPPED; /* ServiceState::STOPPED / STARTED */
string pid_file;
- OnstartFlags onstart_flags;
+ onstart_flags_t onstart_flags;
string logfile; // log file name, empty string specifies /dev/null
typedef sr_list::iterator sr_iter;
// list of soft dependencies
- typedef std::list<ServiceDep> softdep_list;
+ typedef std::list<service_dep> softdep_list;
// list of soft dependents
- typedef std::list<ServiceDep *> softdpt_list;
+ typedef std::list<service_dep *> softdpt_list;
sr_list depends_on; // services this one depends on
sr_list dependents; // services depending on this one
// unsigned wait_count; /* if we are waiting for dependents/dependencies to
// start/stop, this is how many we're waiting for */
- ServiceSet *service_set; // the set this service belongs to
+ service_set *services; // the set this service belongs to
- std::unordered_set<ServiceListener *> listeners;
+ std::unordered_set<service_listener *> listeners;
// Process services:
bool force_stop; // true if the service must actually stop. This is the
// descriptor for the socket.
- // Data for use by ServiceSet
+ // Data for use by service_set
public:
// Console queue.
|| (service_state == ServiceState::STARTING && waiting_for_deps);
}
- void notifyListeners(ServiceEvent event) noexcept
+ void notifyListeners(service_event event) noexcept
{
for (auto l : listeners) {
l->serviceEvent(this, event);
public:
- service_record(ServiceSet *set, string name)
+ service_record(service_set *set, string name)
: service_state(ServiceState::STOPPED), desired_state(ServiceState::STOPPED),
auto_restart(false), smooth_recovery(false),
pinned_stopped(false), pinned_started(false), waiting_for_deps(false),
prop_require(false), prop_release(false), prop_failure(false),
prop_start(false), prop_stop(false), restarting(false), force_stop(false)
{
- service_set = set;
+ services = set;
service_name = name;
- service_type = ServiceType::DUMMY;
+ record_type = service_type::DUMMY;
}
- service_record(ServiceSet *set, string name, ServiceType service_type, string &&command, std::list<std::pair<unsigned,unsigned>> &command_offsets,
+ service_record(service_set *set, string name, service_type record_type_p, string &&command, std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft)
: service_record(set, name)
{
- service_set = set;
+ services = set;
service_name = name;
- this->service_type = service_type;
+ this->record_type = record_type_p;
this->depends_on = std::move(*pdepends_on);
program_name = std::move(command);
}
// Set "on start" flags (commands)
- void setOnstartFlags(OnstartFlags flags) noexcept
+ void setOnstartFlags(onstart_flags_t flags) noexcept
{
this->onstart_flags = flags;
}
bool isDummy() noexcept
{
- return service_type == ServiceType::DUMMY;
+ return record_type == service_type::DUMMY;
}
// Add a listener. A listener must only be added once. May throw std::bad_alloc.
- void addListener(ServiceListener * listener)
+ void addListener(service_listener * listener)
{
listeners.insert(listener);
}
// Remove a listener.
- void removeListener(ServiceListener * listener) noexcept
+ void removeListener(service_listener * listener) noexcept
{
listeners.erase(listener);
}
// A timer for process restarting. Used to ensure a minimum delay between
// process restarts.
-class process_restart_timer : public EventLoop_t::timer_impl<process_restart_timer>
+class process_restart_timer : public eventloop_t::timer_impl<process_restart_timer>
{
public:
base_process_service * service;
{
}
- rearm timer_expiry(EventLoop_t &, int expiry_count);
+ rearm timer_expiry(eventloop_t &, int expiry_count);
};
class base_process_service : public service_record
{
- friend class ServiceChildWatcher;
+ friend class service_child_watcher;
friend class ServiceIoWatcher;
friend class process_restart_timer;
void do_restart() noexcept;
protected:
- ServiceChildWatcher child_listener;
+ service_child_watcher child_listener;
ServiceIoWatcher child_status_listener;
process_restart_timer restart_timer;
timespec last_start_time;
virtual void interrupt_start() noexcept override;
public:
- base_process_service(ServiceSet *sset, string name, ServiceType service_type, string &&command,
+ base_process_service(service_set *sset, string name, service_type record_type_p, string &&command,
std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft);
virtual void handle_exit_status(int exit_status) noexcept override;
public:
- process_service(ServiceSet *sset, string name, string &&command,
+ process_service(service_set *sset, string name, string &&command,
std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft)
- : base_process_service(sset, name, ServiceType::PROCESS, std::move(command), command_offsets,
+ : base_process_service(sset, name, service_type::PROCESS, std::move(command), command_offsets,
pdepends_on, pdepends_soft)
{
}
bool read_pid_file() noexcept;
public:
- bgproc_service(ServiceSet *sset, string name, string &&command,
+ bgproc_service(service_set *sset, string name, string &&command,
std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft)
- : base_process_service(sset, name, ServiceType::BGPROCESS, std::move(command), command_offsets,
+ : base_process_service(sset, name, service_type::BGPROCESS, std::move(command), command_offsets,
pdepends_on, pdepends_soft)
{
doing_recovery = false;
virtual void handle_exit_status(int exit_status) noexcept override;
public:
- scripted_service(ServiceSet *sset, string name, string &&command,
+ scripted_service(service_set *sset, string name, string &&command,
std::list<std::pair<unsigned,unsigned>> &command_offsets,
sr_list * pdepends_on, sr_list * pdepends_soft)
- : base_process_service(sset, name, ServiceType::SCRIPTED, std::move(command), command_offsets,
+ : base_process_service(sset, name, service_type::SCRIPTED, std::move(command), command_offsets,
pdepends_on, pdepends_soft)
{
}
}
/*
- * A ServiceSet, as the name suggests, manages a set of services.
+ * A service_set, as the name suggests, manages a set of services.
*
* Other than the ability to find services by name, the service set manages various queues.
* One is the queue for processes wishing to acquire the console. There is also a set of
* process is finite because starting a service can never cause services to stop, unless they
* fail to start, which should cause them to stop semi-permanently.
*/
-class ServiceSet
+class service_set
{
int active_services;
std::list<service_record *> records;
const char *service_dir; // directory containing service descriptions
bool restart_enabled; // whether automatic restart is enabled (allowed)
- ShutdownType shutdown_type = ShutdownType::CONTINUE; // Shutdown type, if stopping
+ shutdown_type_t shutdown_type = shutdown_type_t::CONTINUE; // Shutdown type, if stopping
// Services waiting for exclusive access to the console
dlist<service_record, extract_console_queue> console_queue;
// Public
public:
- ServiceSet(const char *service_dir)
+ service_set(const char *service_dir)
{
this->service_dir = service_dir;
active_services = 0;
return active_services;
}
- void stop_all_services(ShutdownType type = ShutdownType::HALT) noexcept
+ void stop_all_services(shutdown_type_t type = shutdown_type_t::HALT) noexcept
{
restart_enabled = false;
shutdown_type = type;
return restart_enabled;
}
- ShutdownType getShutdownType() noexcept
+ shutdown_type_t getShutdownType() noexcept
{
return shutdown_type;
}
// shutdown: shut down the system
// This utility communicates with the dinit daemon via a unix socket (/dev/initctl).
-void do_system_shutdown(ShutdownType shutdown_type);
+void do_system_shutdown(shutdown_type_t shutdown_type);
static void unmount_disks();
static void swap_off();
-static void wait_for_reply(CPBuffer<1024> &rbuffer, int fd);
+static void wait_for_reply(cpbuffer<1024> &rbuffer, int fd);
class ReadCPException
bool sys_shutdown = false;
bool use_passed_cfd = false;
- auto shutdown_type = ShutdownType::POWEROFF;
+ auto shutdown_type = shutdown_type_t::POWEROFF;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
sys_shutdown = true;
}
else if (strcmp(argv[i], "-r") == 0) {
- shutdown_type = ShutdownType::REBOOT;
+ shutdown_type = shutdown_type_t::REBOOT;
}
else if (strcmp(argv[i], "-h") == 0) {
- shutdown_type = ShutdownType::HALT;
+ shutdown_type = shutdown_type_t::HALT;
}
else if (strcmp(argv[i], "-p") == 0) {
- shutdown_type = ShutdownType::POWEROFF;
+ shutdown_type = shutdown_type_t::POWEROFF;
}
else if (strcmp(argv[i], "--use-passed-cfd") == 0) {
use_passed_cfd = true;
// cout << "Received acknowledgement. System should now shut down." << endl;
//}
- CPBuffer<1024> rbuffer;
+ cpbuffer<1024> rbuffer;
try {
wait_for_reply(rbuffer, socknum);
// errcode = 0 if end of stream (remote end closed)
// errcode = errno if another error occurred
// Note that EINTR is ignored (i.e. the read will be re-tried).
-static void fillBufferTo(CPBuffer<1024> *buf, int fd, int rlength)
+static void fillBufferTo(cpbuffer<1024> *buf, int fd, int rlength)
{
do {
int r = buf->fill_to(fd, rlength);
// Wait for a reply packet, skipping over any information packets
// that are received in the meantime.
-static void wait_for_reply(CPBuffer<1024> &rbuffer, int fd)
+static void wait_for_reply(cpbuffer<1024> &rbuffer, int fd)
{
fillBufferTo(&rbuffer, fd, 1);
}
// Actually shut down the system.
-void do_system_shutdown(ShutdownType shutdown_type)
+void do_system_shutdown(shutdown_type_t shutdown_type)
{
using namespace std;
sigprocmask(SIG_SETMASK, &allsigs, nullptr);
int reboot_type = 0;
- if (shutdown_type == ShutdownType::REBOOT) reboot_type = RB_AUTOBOOT;
- else if (shutdown_type == ShutdownType::POWEROFF) reboot_type = RB_POWER_OFF;
+ if (shutdown_type == shutdown_type_t::REBOOT) reboot_type = RB_AUTOBOOT;
+ else if (shutdown_type == shutdown_type_t::POWEROFF) reboot_type = RB_POWER_OFF;
else reboot_type = RB_HALT_SYSTEM;
// Write to console rather than any terminal, since we lose the terminal it seems: