1 /*-*- Mode: C; c-basic-offset: 8 -*-*/
7 #include "load-fragment.h"
8 #include "load-dropin.h"
10 static int service_load_sysv(Service
*s
) {
13 /* Load service data from SysV init scripts, preferably with
19 static int service_load(Name
*n
) {
21 Service
*s
= SERVICE(n
);
25 exec_context_defaults(&s
->exec_context
);
27 /* Load a .service file */
28 r
= name_load_fragment(n
);
30 /* Load a classic init script as a fallback */
32 r
= service_load_sysv(s
);
37 /* Load dropin directory data */
38 if ((r
= name_load_dropin(n
)) < 0)
44 static void service_dump(Name
*n
, FILE *f
, const char *prefix
) {
46 static const char* const state_table
[_SERVICE_STATE_MAX
] = {
47 [SERVICE_DEAD
] = "dead",
48 [SERVICE_START_PRE
] = "start-pre",
49 [SERVICE_START
] = "start",
50 [SERVICE_START_POST
] = "post",
51 [SERVICE_RUNNING
] = "running",
52 [SERVICE_RELOAD_PRE
] = "reload-pre",
53 [SERVICE_RELOAD
] = "reload",
54 [SERVICE_RELOAD_POST
] = "reload-post",
55 [SERVICE_STOP_PRE
] = "stop-pre",
56 [SERVICE_STOP
] = "stop",
57 [SERVICE_SIGTERM
] = "sigterm",
58 [SERVICE_SIGKILL
] = "sigkill",
59 [SERVICE_STOP_POST
] = "stop-post",
60 [SERVICE_MAINTAINANCE
] = "maintainance"
63 static const char* const command_table
[_SERVICE_EXEC_MAX
] = {
64 [SERVICE_EXEC_START_PRE
] = "StartPre",
65 [SERVICE_EXEC_START
] = "Start",
66 [SERVICE_EXEC_START_POST
] = "StartPost",
67 [SERVICE_EXEC_RELOAD_PRE
] = "ReloadPre",
68 [SERVICE_EXEC_RELOAD
] = "Reload",
69 [SERVICE_EXEC_RELOAD_POST
] = "ReloadPost",
70 [SERVICE_EXEC_STOP_PRE
] = "StopPre",
71 [SERVICE_EXEC_STOP
] = "Stop",
72 [SERVICE_EXEC_STOP_POST
] = "StopPost",
76 Service
*s
= SERVICE(n
);
81 "%sService State: %s\n",
82 prefix
, state_table
[s
->state
]);
84 exec_context_dump(&s
->exec_context
, f
, prefix
);
86 for (c
= 0; c
< _SERVICE_EXEC_MAX
; c
++) {
89 LIST_FOREACH(i
, s
->exec_command
[c
])
90 fprintf(f
, "%s%s: %s\n", prefix
, command_table
[c
], i
->path
);
94 static int service_set_state(Service
*s
, ServiceState state
) {
101 static int service_start(Name
*n
) {
102 Service
*s
= SERVICE(n
);
106 /* We cannot fulfill this request right now */
107 if (s
->state
== SERVICE_STOP_PRE
||
108 s
->state
== SERVICE_STOP
||
109 s
->state
== SERVICE_SIGTERM
||
110 s
->state
== SERVICE_SIGKILL
||
111 s
->state
== SERVICE_STOP_POST
)
114 assert(s
->state
== SERVICE_DEAD
|| s
->state
== SERVICE_MAINTAINANCE
);
116 return service_set_state(s
, SERVICE_START_PRE
);
119 static int service_stop(Name
*n
) {
120 Service
*s
= SERVICE(n
);
128 static int service_reload(Name
*n
) {
132 static NameActiveState
service_active_state(Name
*n
) {
134 static const NameActiveState table
[_SERVICE_STATE_MAX
] = {
135 [SERVICE_DEAD
] = NAME_INACTIVE
,
136 [SERVICE_START_PRE
] = NAME_ACTIVATING
,
137 [SERVICE_START
] = NAME_ACTIVATING
,
138 [SERVICE_START_POST
] = NAME_ACTIVATING
,
139 [SERVICE_RUNNING
] = NAME_ACTIVE
,
140 [SERVICE_RELOAD_PRE
] = NAME_ACTIVE_RELOADING
,
141 [SERVICE_RELOAD
] = NAME_ACTIVE_RELOADING
,
142 [SERVICE_RELOAD_POST
] = NAME_ACTIVE_RELOADING
,
143 [SERVICE_STOP_PRE
] = NAME_DEACTIVATING
,
144 [SERVICE_STOP
] = NAME_DEACTIVATING
,
145 [SERVICE_SIGTERM
] = NAME_DEACTIVATING
,
146 [SERVICE_SIGKILL
] = NAME_DEACTIVATING
,
147 [SERVICE_STOP_POST
] = NAME_DEACTIVATING
,
148 [SERVICE_MAINTAINANCE
] = NAME_INACTIVE
,
151 return table
[SERVICE(n
)->state
];
154 static void service_free_hook(Name
*n
) {
155 Service
*s
= SERVICE(n
);
160 exec_context_free(&s
->exec_context
);
162 for (c
= 0; c
< _SERVICE_EXEC_MAX
; c
++)
163 exec_command_free_list(s
->exec_command
[c
]);
166 s
->socket
->service
= NULL
;
169 const NameVTable service_vtable
= {
170 .suffix
= ".service",
172 .load
= service_load
,
173 .dump
= service_dump
,
175 .start
= service_start
,
176 .stop
= service_stop
,
177 .reload
= service_reload
,
179 .active_state
= service_active_state
,
181 .free_hook
= service_free_hook