Browse Source

Improve feedback from dinitctl when service load fails

Distinguish between service not found, service description error, and
other load errors. Suggest running dinitcheck or checking logs where
appropriate.
Davin McCall 1 year ago
parent
commit
3dcbad2832
3 changed files with 49 additions and 19 deletions
  1. 27 17
      src/control.cc
  2. 17 2
      src/dinitctl.cc
  3. 5 0
      src/includes/control-cmds.h

+ 27 - 17
src/control.cc

@@ -148,7 +148,13 @@ bool control_conn_t::process_find_load(int pktType)
     service_record * record = nullptr;
     
     string serviceName = rbuf.extract_string(3, svcSize);
+
+    // Clear the packet from the buffer
+    rbuf.consume(chklen);
+    chklen = 0;
     
+    char fail_code = DINIT_RP_NOSERVICE;
+
     if (pktType == DINIT_CP_LOADSERVICE) {
         // LOADSERVICE
         try {
@@ -156,10 +162,17 @@ bool control_conn_t::process_find_load(int pktType)
         }
         catch (service_description_exc &sdexc) {
             log_service_load_failure(sdexc);
+            fail_code = DINIT_RP_SERVICE_DESC_ERR;
+        }
+        catch (service_not_found &snf) {
+            log(loglevel_t::ERROR, "Could not load service ", snf.service_name, ": ",
+                    snf.exc_description);
+            // fail_code = DINIT_RP_NOSERVICE;   (already set)
         }
         catch (service_load_exc &slexc) {
             log(loglevel_t::ERROR, "Could not load service ", slexc.service_name, ": ",
                     slexc.exc_description);
+            fail_code = DINIT_RP_SERVICE_LOAD_ERR;
         }
     }
     else {
@@ -167,27 +180,24 @@ bool control_conn_t::process_find_load(int pktType)
         record = services->find_service(serviceName.c_str());
     }
     
-    if (record != nullptr) {
-        // Allocate a service handle
-        handle_t handle = allocate_service_handle(record);
-        std::vector<char> rp_buf;
-        rp_buf.reserve(7);
-        rp_buf.push_back(DINIT_RP_SERVICERECORD);
-        rp_buf.push_back(static_cast<char>(record->get_state()));
-        for (int i = 0; i < (int) sizeof(handle); i++) {
-            rp_buf.push_back(*(((char *) &handle) + i));
-        }
-        rp_buf.push_back(static_cast<char>(record->get_target_state()));
+    if (record == nullptr) {
+        std::vector<char> rp_buf = { fail_code };
         if (! queue_packet(std::move(rp_buf))) return false;
+        return true;
     }
-    else {
-        std::vector<char> rp_buf = { DINIT_RP_NOSERVICE };
-        if (! queue_packet(std::move(rp_buf))) return false;
+
+    // Allocate a service handle
+    handle_t handle = allocate_service_handle(record);
+    std::vector<char> rp_buf;
+    rp_buf.reserve(7);
+    rp_buf.push_back(DINIT_RP_SERVICERECORD);
+    rp_buf.push_back(static_cast<char>(record->get_state()));
+    for (int i = 0; i < (int) sizeof(handle); i++) {
+        rp_buf.push_back(*(((char *) &handle) + i));
     }
+    rp_buf.push_back(static_cast<char>(record->get_target_state()));
+    if (! queue_packet(std::move(rp_buf))) return false;
     
-    // Clear the packet from the buffer
-    rbuf.consume(chklen);
-    chklen = 0;
     return true;
 }
 

+ 17 - 2
src/dinitctl.cc

@@ -639,7 +639,7 @@ static int start_stop_service(int socknum, cpbuffer_t &rbuffer, const char *serv
         ignore_unstarted = false;
     }
 
-    if (! load_service(socknum, rbuffer, service_name, &handle, &state, !ignore_unstarted)) {
+    if (!load_service(socknum, rbuffer, service_name, &handle, &state, !ignore_unstarted)) {
         return ignore_unstarted ? 0 : 1;
     }
 
@@ -794,7 +794,22 @@ static int check_load_reply(int socknum, cpbuffer_t &rbuffer, handle_t *handle_p
     }
     else if (rbuffer[0] == DINIT_RP_NOSERVICE) {
         if (write_error) {
-            cerr << "dinitctl: failed to find/load service." << endl;
+            cerr << "dinitctl: failed to find service description.\n";
+            cerr << "dinitctl: check service description file exists / service name spelling.\n";
+        }
+        return 1;
+    }
+    else if (rbuffer[0] == DINIT_RP_SERVICE_DESC_ERR) {
+        if (write_error) {
+            cerr << "dinitctl: error in service description.\n";
+            cerr << "dinitctl: try 'dinitcheck <service-name>' or check log for more information.\n";
+        }
+        return 1;
+    }
+    else if (rbuffer[0] == DINIT_RP_SERVICE_LOAD_ERR) {
+        if (write_error) {
+            cerr << "dinitctl: error loading service.\n";
+            cerr << "dinitctl: try 'dinitcheck <service-name>' or check log for more information.\n";
         }
         return 1;
     }

+ 5 - 0
src/includes/control-cmds.h

@@ -111,6 +111,11 @@ constexpr static int DINIT_RP_SHUTTINGDOWN = 69;
 // Service status:
 constexpr static int DINIT_RP_SERVICESTATUS = 70;
 
+// Service description error:
+constexpr static int DINIT_RP_SERVICE_DESC_ERR = 71;
+// Service load error (general):
+constexpr static int DINIT_RP_SERVICE_LOAD_ERR = 72;
+
 
 // Information (out-of-band):