mirror of
https://github.com/troglobit/finit.git
synced 2026-11-08 16:11:10 +00:00
Wait for post:script and cleanup:script before returning OK
This change introduces two new states for the big Finit state machine: runlevel-clean and reload-clean. Here Finit now waits for any post or cleanup script to finish before returning OK to the initctl command. Additionally, the service state machine has been updated to ensure a run/task/sysv/service calls any post or cleanup script before they are removed. A new 'dead' state for svc_t is introduced which any removed svc_t ends up in now instead of becing collected from 'halted' state. Signed-off-by: Joachim Wiberg <troglobit@gmail.com> Add cleanup:script support, runs at service removal Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
7 files changed
+124
-26
No files matched your search
Binary file not shown.
|
Before Width: | Height: | Size: 230 KiB After Width: | Height: | Size: 410 KiB |
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!-- Do not edit this file with editors other than diagrams.net -->
|
<!-- Do not edit this file with editors other than draw.io -->
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" style="background-color: rgb(255, 255, 255);" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="732px" height="888px" viewBox="-0.5 -0.5 732 888" content="<mxfile host="app.diagrams.net" modified="2022-08-23T13:29:07.417Z" agent="5.0 (X11)" version="20.2.4" etag="2-w-AmAkF4Yj3b3JyTHu" type="google"><diagram id="2QNQ_rVyMpIu31uE8ppT">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</diagram></mxfile>"><defs><style type="text/css">@font-face { font-family: "Architects Daughter"; src: url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAAMAIAAAwBAT1MvMoWwV7IAAGWAAAAAYGNtYXDPBugkAABl4AAAARxnYXNwAAAAEAAAkvgAAAAIZ2x5Zv2v7C0AAADMAABb/GhlYWQC0dksAABfqAAAADZoaGVhCEMEFgAAZVwAAAAkaG10eN2yH1kAAF/gAAAFfGxvY2GKxKMcAABc6AAAAsBtYXhwAa4AzAAAXMgAAAAgbmFtZUarZSoAAGcEAAAlEHBvc3QANIw5AACMFAAABuNwcmVwaAaMhQAAZvwAAAAHAAIAFv/5AHwDhQAKABMAADcyFhUGBwYiJicmEwYQByM0NxI1PyoTCyUGDhUFC1sGD0MIDkMQCSgIAQgKGQNhGv2rLWebAS1pAAIANgHqANcC+wALABcAABM3JzQ3FxUXDgEjIic3JzQ3FxUXDgEjIpIBASQREAMZBSRcAQEkEBEEGAUkAlIcKVMREMciAw1XHSpTERDHIgQNAAACADgAxgKdApgAQwBQAAATNDMyFjM1Ii4BJyY0Nz4BNzYzNTQ2MzIWHQE3NTMXMxQjIiYjFTI2MxUUBw4BBw4BBwYjNSYiDgEeAQYHIyInJicuASQmIgYHBh0BMjc2NTRWKhIlAwLine truncated
|
<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="732px" height="1006px" viewBox="-0.5 -0.5 732 1006" content="<mxfile host="app.diagrams.net" agent="Mozilla/5.0 (X11; Linux x86_64; rv:135.0) Gecko/20100101 Firefox/135.0" version="26.0.15" scale="1" border="0">
 <diagram name="Page-1" id="FNw5HM3Bq2xN372-o7V3">
 <mxGraphModel dx="2049" dy="1094" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
 <root>
 <mxCell id="0" />
 <mxCell id="1" parent="0" />
 <mxCell id="2" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=14;" edge="1" source="4" target="7" parent="1">
 <mxGeometry relative="1" as="geometry" />
 </mxCell>
 <mxCell id="3" style="edgeStyle=orthogonalEdgeStyle;rounded=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=14;" edge="1" source="4" target="19" parent="1">
 <mxGeometry relative="1" as="geometry">
 <Array as="points">
 <mxPoint x="421" y="328" />
 <mxPoint x="265" y="328" />
 <mxPoint x="183" y="329" />
 </Array>
 </mxGeometry>
 </mxCell>
 <mxCell id="4" value="&lt;font style=&quot;font-size: 16px&quot;&gt;&lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Architects+Daughter&quot; style=&quot;font-size: 16px&quot; face=&quot;Architects Daughter&quot;&gt;STOPPING&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;sketch=1;" vertex="1" parent="1">
 <mxGeometry x="360.89" y="226" width="120" height="60" as="geometry" />
 </mxCell>
 <mxCell id="5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.25;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" source="10" target="21" parent="1">
 <mxGeometry relative="1" as="geometry">
 <Array as="points">
 <mxPoint x="390.89" y="729" />
 <mxPoint x="264.89" y="729" />
 </Array>
 </mxGeometry>
 </mxCell>
 <mxCell id="6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;sketch=1;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.25;entryY=0;entryDx=0;entryDy=0;fontFamily=Architects Daughter;fontSource=https%3A%2F%2Ffonts.googleapis.com%2Fcss%3Ffamily%3DArchitects%2BDaughter;fontSize=14;exitX=0.25;exitY=1;exitDx=0;exitDy=0;" edge="1" source="7" target="10" parent="1">
 <mxGeometry relative="1" as="geometry" />
 </mxCell>
 <mxCell id="7" value="&lt;font style=&quot;font-size: 16px&quot;&gt;&lt;b&gt;&lt;font data-font-src=&quot;https://fonts.googleapis.com/css?family=Architects+Daughter&quot; style=&quot;font-size: 16px&quot; face=&quot;Architects Daughter&quot;&gt;HALTED&lt;/font&gt;&lt;/b&gt;&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;sketch=1;" vertex="1" parent="1">
 <mxGeometry x="360.89" y="526" width="120" height="Line truncated
|
||||||
|
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 814 KiB |
+30
-16
@@ -2483,16 +2483,13 @@ restart:
|
|||||||
condstr(cond_get_agg(svc->cond)));
|
condstr(cond_get_agg(svc->cond)));
|
||||||
|
|
||||||
switch (svc->state) {
|
switch (svc->state) {
|
||||||
case SVC_CLEANUP_STATE:
|
|
||||||
if (!svc->pid)
|
|
||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SVC_HALTED_STATE:
|
case SVC_HALTED_STATE:
|
||||||
if (enabled)
|
if (enabled)
|
||||||
svc_set_state(svc, SVC_WAITING_STATE);
|
svc_set_state(svc, SVC_WAITING_STATE);
|
||||||
else {
|
else {
|
||||||
if (svc_is_conflict(svc)) {
|
if (svc_is_removed(svc)) {
|
||||||
|
svc_set_state(svc, SVC_DEAD_STATE);
|
||||||
|
} else if (svc_is_conflict(svc)) {
|
||||||
#if 0
|
#if 0
|
||||||
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
|
logit(svc->nowarn ? LOG_DEBUG : LOG_INFO,
|
||||||
"%s in conflict with %s, checking again ...",
|
"%s in conflict with %s, checking again ...",
|
||||||
@@ -2504,6 +2501,30 @@ restart:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case SVC_TEARDOWN_STATE:
|
||||||
|
if (!svc->pid) {
|
||||||
|
dbg("%s: post script done.", svc_ident(svc, NULL, 0));
|
||||||
|
service_timeout_cancel(svc);
|
||||||
|
|
||||||
|
if (svc_is_removed(svc) && svc_has_cleanup(svc)) {
|
||||||
|
svc_set_state(svc, SVC_CLEANUP_STATE);
|
||||||
|
service_cleanup_script(svc);
|
||||||
|
} else
|
||||||
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SVC_CLEANUP_STATE:
|
||||||
|
if (!svc->pid) {
|
||||||
|
dbg("%s: cleanup script done.", svc_ident(svc, NULL, 0));
|
||||||
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SVC_DEAD_STATE:
|
||||||
|
/* End of the line ☠ */
|
||||||
|
break;
|
||||||
|
|
||||||
case SVC_DONE_STATE:
|
case SVC_DONE_STATE:
|
||||||
if (svc_is_changed(svc))
|
if (svc_is_changed(svc))
|
||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
@@ -2528,6 +2549,9 @@ restart:
|
|||||||
if (svc_has_post(svc)) {
|
if (svc_has_post(svc)) {
|
||||||
svc_set_state(svc, SVC_TEARDOWN_STATE);
|
svc_set_state(svc, SVC_TEARDOWN_STATE);
|
||||||
service_post_script(svc);
|
service_post_script(svc);
|
||||||
|
} else if (svc_is_removed(svc) && svc_has_cleanup(svc)) {
|
||||||
|
svc_set_state(svc, SVC_CLEANUP_STATE);
|
||||||
|
service_cleanup_script(svc);
|
||||||
} else
|
} else
|
||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
svc_set_state(svc, SVC_HALTED_STATE);
|
||||||
break;
|
break;
|
||||||
@@ -2546,16 +2570,6 @@ restart:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SVC_TEARDOWN_STATE:
|
|
||||||
if (!svc->pid) {
|
|
||||||
if (svc_is_removed(svc) && svc_has_cleanup(svc)) {
|
|
||||||
svc_set_state(svc, SVC_CLEANUP_STATE);
|
|
||||||
service_cleanup_script(svc);
|
|
||||||
} else
|
|
||||||
svc_set_state(svc, SVC_HALTED_STATE);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SVC_SETUP_STATE:
|
case SVC_SETUP_STATE:
|
||||||
if (!svc->pid) {
|
if (!svc->pid) {
|
||||||
int rc = WEXITSTATUS(svc->status);
|
int rc = WEXITSTATUS(svc->status);
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ static char *sm_status(sm_state_t state)
|
|||||||
case SM_BOOTSTRAP_STATE:
|
case SM_BOOTSTRAP_STATE:
|
||||||
return "bootstrap";
|
return "bootstrap";
|
||||||
|
|
||||||
|
case SM_BOOTSTRAP_WAIT_STATE:
|
||||||
|
return "bootstrap/wait";
|
||||||
|
|
||||||
case SM_RUNNING_STATE:
|
case SM_RUNNING_STATE:
|
||||||
return "running";
|
return "running";
|
||||||
|
|
||||||
@@ -116,15 +119,20 @@ static char *sm_status(sm_state_t state)
|
|||||||
case SM_RUNLEVEL_WAIT_STATE:
|
case SM_RUNLEVEL_WAIT_STATE:
|
||||||
return "runlevel/wait";
|
return "runlevel/wait";
|
||||||
|
|
||||||
|
case SM_RUNLEVEL_CLEAN_STATE:
|
||||||
|
return "runlevel/clean";
|
||||||
|
|
||||||
case SM_RELOAD_CHANGE_STATE:
|
case SM_RELOAD_CHANGE_STATE:
|
||||||
return "reload/change";
|
return "reload/change";
|
||||||
|
|
||||||
case SM_RELOAD_WAIT_STATE:
|
case SM_RELOAD_WAIT_STATE:
|
||||||
return "reload/wait";
|
return "reload/wait";
|
||||||
|
|
||||||
default:
|
case SM_RELOAD_CLEAN_STATE:
|
||||||
return "unknown";
|
return "reload/clean";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
static char sm_runlevel(int lvl)
|
static char sm_runlevel(int lvl)
|
||||||
@@ -319,6 +327,22 @@ restart:
|
|||||||
sm->in_teardown = 0;
|
sm->in_teardown = 0;
|
||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
|
sm->state = SM_RUNLEVEL_CLEAN_STATE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_RUNLEVEL_CLEAN_STATE:
|
||||||
|
/*
|
||||||
|
* Wait for post:script or cleanup:script to be collected,
|
||||||
|
* which moves the svc to HALTED or DEAD state. We will
|
||||||
|
* be called by the service_monitor() on collect.
|
||||||
|
*/
|
||||||
|
svc = svc_clean_completed();
|
||||||
|
if (svc) {
|
||||||
|
dbg("Waiting to collect post/cleanup script for %s, cmd %s(%d) ...",
|
||||||
|
svc_ident(svc, NULL, 0), svc->cmd, svc->pid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cleanup stale services */
|
/* Cleanup stale services */
|
||||||
svc_clean_dynamic(service_unregister);
|
svc_clean_dynamic(service_unregister);
|
||||||
|
|
||||||
@@ -372,6 +396,22 @@ restart:
|
|||||||
dbg("Starting services after reconf ...");
|
dbg("Starting services after reconf ...");
|
||||||
service_step_all(SVC_TYPE_ANY);
|
service_step_all(SVC_TYPE_ANY);
|
||||||
|
|
||||||
|
sm->state = SM_RELOAD_CLEAN_STATE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SM_RELOAD_CLEAN_STATE:
|
||||||
|
/*
|
||||||
|
* Wait for post:script or cleanup:script to be collected,
|
||||||
|
* which moves the svc to HALTED or DEAD state. We will
|
||||||
|
* be called by the service_monitor() on collect.
|
||||||
|
*/
|
||||||
|
svc = svc_clean_completed();
|
||||||
|
if (svc) {
|
||||||
|
dbg("Waiting to collect post/cleanup script for %s, cmd %s(%d) ...",
|
||||||
|
svc_ident(svc, NULL, 0), svc->cmd, svc->pid);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cleanup stale services */
|
/* Cleanup stale services */
|
||||||
svc_clean_dynamic(service_unregister);
|
svc_clean_dynamic(service_unregister);
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,11 @@ typedef enum {
|
|||||||
SM_BOOTSTRAP_WAIT_STATE, /* Waiting for bootstrap to complete */
|
SM_BOOTSTRAP_WAIT_STATE, /* Waiting for bootstrap to complete */
|
||||||
SM_RUNNING_STATE, /* Normal state, services running */
|
SM_RUNNING_STATE, /* Normal state, services running */
|
||||||
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occurred */
|
SM_RUNLEVEL_CHANGE_STATE, /* A runlevel change has occurred */
|
||||||
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped runlevel processes to be halted */
|
SM_RUNLEVEL_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||||
|
SM_RUNLEVEL_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||||
SM_RELOAD_CHANGE_STATE, /* A reload event has occurred */
|
SM_RELOAD_CHANGE_STATE, /* A reload event has occurred */
|
||||||
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped reload processes to be halted */
|
SM_RELOAD_WAIT_STATE, /* Waiting for all stopped processes to halt */
|
||||||
|
SM_RELOAD_CLEAN_STATE, /* Wait for post:scripts and cleanup:scripts */
|
||||||
} sm_state_t;
|
} sm_state_t;
|
||||||
|
|
||||||
typedef struct sm {
|
typedef struct sm {
|
||||||
|
|||||||
@@ -348,6 +348,43 @@ svc_t *svc_stop_completed(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* svc_clean_completed - Have post: and cleanup: scripts finished?
|
||||||
|
*
|
||||||
|
* Called late in runlevel and reload transitions to check if all post: and
|
||||||
|
* cleanup:scripts have completed. A removed service should end up in the
|
||||||
|
* DEAD state, while a service with a post:script ends up in HALTED.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* %NULL if post: and cleanup: scripts have run, otherwise a pointer to
|
||||||
|
* the first found svc_t waiting for post: or cleanup:script.
|
||||||
|
*/
|
||||||
|
svc_t *svc_clean_completed(void)
|
||||||
|
{
|
||||||
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
|
if (svc_enabled(svc))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (svc_is_runtask(svc) && svc->state == SVC_DONE_STATE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (svc_is_removed(svc)) {
|
||||||
|
if (svc->state == SVC_DEAD_STATE)
|
||||||
|
continue; /* any cleanup:script done */
|
||||||
|
} else {
|
||||||
|
if (svc->state == SVC_HALTED_STATE)
|
||||||
|
continue; /* any post:script done */
|
||||||
|
}
|
||||||
|
|
||||||
|
return svc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* svc_find - Find a service object by its full path name
|
* svc_find - Find a service object by its full path name
|
||||||
* @name: Full path name, e.g., /sbin/syslogd
|
* @name: Full path name, e.g., /sbin/syslogd
|
||||||
@@ -580,7 +617,7 @@ void svc_clean_dynamic(void (*cb)(svc_t *))
|
|||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
if (svc->removed && cb)
|
if (svc_is_removed(svc) && cb)
|
||||||
cb(svc);
|
cb(svc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,10 +58,11 @@ typedef enum {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
SVC_HALTED_STATE = 0, /* Not allowed in runlevel, or not enabled. */
|
SVC_HALTED_STATE = 0, /* Not allowed in runlevel, or not enabled. */
|
||||||
SVC_DONE_STATE, /* Task/Run job has been run */
|
SVC_DONE_STATE, /* Task/Run job has been run */
|
||||||
|
SVC_DEAD_STATE, /* Process is dead and scheduled for removal */
|
||||||
|
SVC_CLEANUP_STATE, /* Running cleanup: script */
|
||||||
|
SVC_TEARDOWN_STATE, /* Running post: script */
|
||||||
SVC_STOPPING_STATE, /* Waiting to collect the child process */
|
SVC_STOPPING_STATE, /* Waiting to collect the child process */
|
||||||
SVC_SETUP_STATE, /* Running pre: script */
|
SVC_SETUP_STATE, /* Running pre: script */
|
||||||
SVC_TEARDOWN_STATE, /* Running post: script */
|
|
||||||
SVC_CLEANUP_STATE, /* Running cleanup: script */
|
|
||||||
SVC_PAUSED_STATE, /* Condition is in flux, process SIGSTOPed */
|
SVC_PAUSED_STATE, /* Condition is in flux, process SIGSTOPed */
|
||||||
SVC_WAITING_STATE, /* Enabled but condition not satisfied */
|
SVC_WAITING_STATE, /* Enabled but condition not satisfied */
|
||||||
SVC_STARTING_STATE, /* Conditions OK and pre: script done, start */
|
SVC_STARTING_STATE, /* Conditions OK and pre: script done, start */
|
||||||
@@ -247,6 +248,7 @@ void svc_foreach (int (*cb)(svc_t *));
|
|||||||
void svc_foreach_type (int types, int (*cb)(svc_t *));
|
void svc_foreach_type (int types, int (*cb)(svc_t *));
|
||||||
|
|
||||||
svc_t *svc_stop_completed (void);
|
svc_t *svc_stop_completed (void);
|
||||||
|
svc_t *svc_clean_completed (void);
|
||||||
|
|
||||||
void svc_mark (svc_t *svc);
|
void svc_mark (svc_t *svc);
|
||||||
void svc_mark_dynamic (void);
|
void svc_mark_dynamic (void);
|
||||||
@@ -405,7 +407,7 @@ static inline char *svc_status(svc_t *svc)
|
|||||||
return "setup";
|
return "setup";
|
||||||
|
|
||||||
case SVC_CLEANUP_STATE:
|
case SVC_CLEANUP_STATE:
|
||||||
return "setup";
|
return "cleanup";
|
||||||
|
|
||||||
case SVC_PAUSED_STATE:
|
case SVC_PAUSED_STATE:
|
||||||
return "paused";
|
return "paused";
|
||||||
@@ -419,6 +421,9 @@ static inline char *svc_status(svc_t *svc)
|
|||||||
case SVC_RUNNING_STATE:
|
case SVC_RUNNING_STATE:
|
||||||
return "running";
|
return "running";
|
||||||
|
|
||||||
|
case SVC_DEAD_STATE:
|
||||||
|
return "dead";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user