size_t num_depts = 0;
for (service_dep *dep : service->get_dependents()) {
- if (dep->dep_type == dependency_type::REGULAR) {
+ if (dep->dep_type == dependency_type::REGULAR && dep->holding_acq) {
num_depts++;
// find or allocate a service handle
handle_t dept_handle = allocate_service_handle(dep->get_from());
}
// 1 byte: packet type
- // 1 byte: pin in requested state (0 = no pin, 1 = pin)
+ // 1 byte: flags eg pin in requested state (0 = no pin, 1 = pin)
// 4 bytes: service handle
bool do_pin = ((rbuf[1] & 1) == 1);
{
// force service to stop
bool gentle = ((rbuf[1] & 2) == 2);
+ bool do_restart = ((rbuf[1] & 4) == 4);
+ bool is_active = service->is_marked_active();
+ if (do_restart && services->is_shutting_down()) {
+ ack_buf[0] = DINIT_RP_NAK;
+ break;
+ }
if (gentle) {
// Check dependents; return appropriate response if any will be affected
bool has_dependents;
service->stop(true);
service->forced_stop();
services->process_queues();
- if (service->get_state() == service_state_t::STOPPED) ack_buf[0] = DINIT_RP_ALREADYSS;
+ service_state_t wanted_state = service_state_t::STOPPED;
+ if (do_restart) {
+ service->start(is_active);
+ wanted_state = service_state_t::STARTED;
+ services->process_queues();
+ }
+ if (service->get_state() == wanted_state) ack_buf[0] = DINIT_RP_ALREADYSS;
break;
}
case DINIT_CP_WAKESERVICE:
START_SERVICE,
WAKE_SERVICE,
STOP_SERVICE,
+ RESTART_SERVICE,
RELEASE_SERVICE,
UNPIN_SERVICE,
UNLOAD_SERVICE,
}
service_name = argv[i];
}
- else if ((command == command_t::STOP_SERVICE)
+ else if ((command == command_t::STOP_SERVICE || command == command_t::RESTART_SERVICE)
&& (strcmp(argv[i], "--force") == 0 || strcmp(argv[i], "-f") == 0)) {
do_force = true;
}
else if (strcmp(argv[i], "stop") == 0) {
command = command_t::STOP_SERVICE;
}
+ else if (strcmp(argv[i], "restart") == 0) {
+ command = command_t::RESTART_SERVICE;
+ }
else if (strcmp(argv[i], "release") == 0) {
command = command_t::RELEASE_SERVICE;
}
int pcommand = 0;
switch (command) {
case command_t::STOP_SERVICE:
+ case command_t::RESTART_SERVICE: // stop, and then start
pcommand = DINIT_CP_STOPSERVICE;
break;
case command_t::RELEASE_SERVICE:
char buf[2 + sizeof(handle)];
buf[0] = pcommand;
buf[1] = (do_pin ? 1 : 0) | ((pcommand == DINIT_CP_STOPSERVICE && !do_force) ? 2 : 0);
+ if (command == command_t::RESTART_SERVICE) {
+ buf[1] |= 4;
+ }
memcpy(buf + 2, &handle, sizeof(handle));
write_all_x(socknum, buf, 2 + sizeof(handle));
wait_for_reply(rbuffer, socknum);
- if (rbuffer[0] == DINIT_RP_ALREADYSS) {
+ auto reply_pkt_h = rbuffer[0];
+ rbuffer.consume(1); // consume header
+ if (reply_pkt_h == DINIT_RP_ALREADYSS) {
bool already = (state == wanted_state);
if (verbose) {
cout << "Service " << (already ? "(already) " : "")
}
return 0; // success!
}
- if (rbuffer[0] == DINIT_RP_DEPENDENTS && pcommand == DINIT_CP_STOPSERVICE) {
+ if (reply_pkt_h == DINIT_RP_DEPENDENTS && pcommand == DINIT_CP_STOPSERVICE) {
cerr << "dinitctl: Cannot stop service due to the following dependents:\n"
"(Only direct dependents are listed. Exercise caution before using '--force' !!)\n";
// size_t number, N * handle_t handles
- rbuffer.consume(1); // packet header
size_t number;
rbuffer.fill_to(socknum, sizeof(number));
rbuffer.extract(&number, 0, sizeof(number));
cerr << "\n";
return 1;
}
- if (rbuffer[0] != DINIT_RP_ACK) {
- cerr << "dinitctl: Protocol error." << endl;
+ if (reply_pkt_h != DINIT_RP_ACK && reply_pkt_h != DINIT_RP_ALREADYSS) {
+ cerr << "dinitctl: protocol error." << endl;
return 1;
}
- rbuffer.consume(1);
}
if (! wait_for_service) {