@@ -1179,6 +1179,25 @@ static int service_collect_fds(Service *s, int **fds, char ***fd_names) {
1179
1179
return rn_fds ;
1180
1180
}
1181
1181
1182
+ static bool service_exec_needs_notify_socket (Service * s , ExecFlags flags ) {
1183
+ assert (s );
1184
+
1185
+ /* Notifications are accepted depending on the process and
1186
+ * the access setting of the service:
1187
+ * process: \ access: NONE MAIN EXEC ALL
1188
+ * main no yes yes yes
1189
+ * control no no yes yes
1190
+ * other (forked) no no no yes */
1191
+
1192
+ if (flags & EXEC_IS_CONTROL )
1193
+ /* A control process */
1194
+ return IN_SET (s -> notify_access , NOTIFY_EXEC , NOTIFY_ALL );
1195
+
1196
+ /* We only spawn main processes and control processes, so any
1197
+ * process that is not a control process is a main process */
1198
+ return s -> notify_access != NOTIFY_NONE ;
1199
+ }
1200
+
1182
1201
static int service_spawn (
1183
1202
Service * s ,
1184
1203
ExecCommand * c ,
@@ -1252,7 +1271,7 @@ static int service_spawn(
1252
1271
if (!our_env )
1253
1272
return - ENOMEM ;
1254
1273
1255
- if (( flags & EXEC_IS_CONTROL ) ? s -> notify_access == NOTIFY_ALL : s -> notify_access != NOTIFY_NONE )
1274
+ if (service_exec_needs_notify_socket ( s , flags ) )
1256
1275
if (asprintf (our_env + n_env ++ , "NOTIFY_SOCKET=%s" , UNIT (s )-> manager -> notify_socket ) < 0 )
1257
1276
return - ENOMEM ;
1258
1277
@@ -2579,11 +2598,16 @@ static void service_notify_cgroup_empty_event(Unit *u) {
2579
2598
* SIGCHLD for. */
2580
2599
2581
2600
case SERVICE_START :
2582
- case SERVICE_START_POST :
2583
- if (s -> type == SERVICE_NOTIFY )
2601
+ if (s -> type == SERVICE_NOTIFY ) {
2584
2602
/* No chance of getting a ready notification anymore */
2585
2603
service_enter_signal (s , SERVICE_FINAL_SIGTERM , SERVICE_FAILURE_PROTOCOL );
2586
- else if (s -> pid_file_pathspec ) {
2604
+ break ;
2605
+ }
2606
+
2607
+ /* Fall through */
2608
+
2609
+ case SERVICE_START_POST :
2610
+ if (s -> pid_file_pathspec ) {
2587
2611
/* Give up hoping for the daemon to write its PID file */
2588
2612
log_unit_warning (u , "Daemon never wrote its PID file. Failing." );
2589
2613
@@ -3056,7 +3080,18 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
3056
3080
if (s -> main_pid != 0 )
3057
3081
log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID " PID_FMT , pid , s -> main_pid );
3058
3082
else
3059
- log_unit_debug (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID which is currently not known" , pid );
3083
+ log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID which is currently not known" , pid );
3084
+ return ;
3085
+ } else if (s -> notify_access == NOTIFY_EXEC && pid != s -> main_pid && pid != s -> control_pid ) {
3086
+ if (s -> main_pid != 0 && s -> control_pid != 0 )
3087
+ log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID " PID_FMT " and control PID " PID_FMT ,
3088
+ pid , s -> main_pid , s -> control_pid );
3089
+ else if (s -> main_pid != 0 )
3090
+ log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID " PID_FMT , pid , s -> main_pid );
3091
+ else if (s -> control_pid != 0 )
3092
+ log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for control PID " PID_FMT , pid , s -> control_pid );
3093
+ else
3094
+ log_unit_warning (u , "Got notification message from PID " PID_FMT ", but reception only permitted for main PID and control PID which are currently not known" , pid );
3060
3095
return ;
3061
3096
} else
3062
3097
log_unit_debug (u , "Got notification message from PID " PID_FMT " (%s)" , pid , isempty (cc ) ? "n/a" : cc );
@@ -3066,6 +3101,8 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
3066
3101
if (e && IN_SET (s -> state , SERVICE_START , SERVICE_START_POST , SERVICE_RUNNING , SERVICE_RELOAD )) {
3067
3102
if (parse_pid (e , & pid ) < 0 )
3068
3103
log_unit_warning (u , "Failed to parse MAINPID= field in notification message: %s" , e );
3104
+ else if (pid == s -> control_pid )
3105
+ log_unit_warning (u , "A control process cannot also be the main process" );
3069
3106
else {
3070
3107
service_set_main_pid (s , pid );
3071
3108
unit_watch_pid (UNIT (s ), pid );
@@ -3381,6 +3418,7 @@ DEFINE_STRING_TABLE_LOOKUP(service_exec_command, ServiceExecCommand);
3381
3418
static const char * const notify_access_table [_NOTIFY_ACCESS_MAX ] = {
3382
3419
[NOTIFY_NONE ] = "none" ,
3383
3420
[NOTIFY_MAIN ] = "main" ,
3421
+ [NOTIFY_EXEC ] = "exec" ,
3384
3422
[NOTIFY_ALL ] = "all"
3385
3423
};
3386
3424
0 commit comments