@@ -92,6 +92,7 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
9292static int service_dispatch_watchdog (sd_event_source * source , usec_t usec , void * userdata );
9393
9494static void service_enter_signal (Service * s , ServiceState state , ServiceResult f );
95+ static void service_enter_reload_by_notify (Service * s );
9596
9697static void service_init (Unit * u ) {
9798 Service * s = SERVICE (u );
@@ -473,7 +474,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
473474 "%sGuessMainPID: %s\n"
474475 "%sType: %s\n"
475476 "%sRestart: %s\n"
476- "%sNotifyAccess: %s\n" ,
477+ "%sNotifyAccess: %s\n"
478+ "%sNotifyState: %s\n" ,
477479 prefix , service_state_to_string (s -> state ),
478480 prefix , service_result_to_string (s -> result ),
479481 prefix , service_result_to_string (s -> reload_result ),
@@ -483,7 +485,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
483485 prefix , yes_no (s -> guess_main_pid ),
484486 prefix , service_type_to_string (s -> type ),
485487 prefix , service_restart_to_string (s -> restart ),
486- prefix , notify_access_to_string (s -> notify_access ));
488+ prefix , notify_access_to_string (s -> notify_access ),
489+ prefix , notify_state_to_string (s -> notify_state ));
487490
488491 if (s -> control_pid > 0 )
489492 fprintf (f ,
@@ -1176,6 +1179,17 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
11761179 service_enter_dead (s , SERVICE_FAILURE_RESOURCES , true);
11771180}
11781181
1182+ static void service_enter_stop_by_notify (Service * s ) {
1183+ assert (s );
1184+
1185+ unit_watch_all_pids (UNIT (s ));
1186+
1187+ if (s -> timeout_stop_usec > 0 )
1188+ service_arm_timer (s , s -> timeout_stop_usec );
1189+
1190+ service_set_state (s , SERVICE_STOP );
1191+ }
1192+
11791193static void service_enter_stop (Service * s , ServiceResult f ) {
11801194 int r ;
11811195
@@ -1226,9 +1240,18 @@ static void service_enter_running(Service *s, ServiceResult f) {
12261240 cgroup_ok = cgroup_good (s );
12271241
12281242 if ((main_pid_ok > 0 || (main_pid_ok < 0 && cgroup_ok != 0 )) &&
1229- (s -> bus_name_good || s -> type != SERVICE_DBUS ))
1230- service_set_state (s , SERVICE_RUNNING );
1231- else if (s -> remain_after_exit )
1243+ (s -> bus_name_good || s -> type != SERVICE_DBUS )) {
1244+
1245+ /* If there are any queued up sd_notify()
1246+ * notifications, process them now */
1247+ if (s -> notify_state == NOTIFY_RELOADING )
1248+ service_enter_reload_by_notify (s );
1249+ else if (s -> notify_state == NOTIFY_STOPPING )
1250+ service_enter_stop_by_notify (s );
1251+ else
1252+ service_set_state (s , SERVICE_RUNNING );
1253+
1254+ } else if (s -> remain_after_exit )
12321255 service_set_state (s , SERVICE_EXITED );
12331256 else
12341257 service_enter_stop (s , SERVICE_SUCCESS );
@@ -1433,12 +1456,19 @@ static void service_enter_restart(Service *s) {
14331456 return ;
14341457
14351458fail :
1436- log_warning_unit (UNIT (s )-> id ,
1437- "%s failed to schedule restart job: %s" ,
1438- UNIT (s )-> id , bus_error_message (& error , - r ));
1459+ log_warning_unit (UNIT (s )-> id , "%s failed to schedule restart job: %s" , UNIT (s )-> id , bus_error_message (& error , - r ));
14391460 service_enter_dead (s , SERVICE_FAILURE_RESOURCES , false);
14401461}
14411462
1463+ static void service_enter_reload_by_notify (Service * s ) {
1464+ assert (s );
1465+
1466+ if (s -> timeout_start_usec > 0 )
1467+ service_arm_timer (s , s -> timeout_start_usec );
1468+
1469+ service_set_state (s , SERVICE_RELOAD );
1470+ }
1471+
14421472static void service_enter_reload (Service * s ) {
14431473 int r ;
14441474
@@ -1667,6 +1697,8 @@ static int service_start(Unit *u) {
16671697 s -> status_text = NULL ;
16681698 s -> status_errno = 0 ;
16691699
1700+ s -> notify_state = NOTIFY_UNKNOWN ;
1701+
16701702 service_enter_start_pre (s );
16711703 return 0 ;
16721704}
@@ -2504,13 +2536,15 @@ static int service_dispatch_watchdog(sd_event_source *source, usec_t usec, void
25042536
25052537static void service_notify_message (Unit * u , pid_t pid , char * * tags ) {
25062538 Service * s = SERVICE (u );
2507- const char * e ;
2539+ _cleanup_free_ char * cc = NULL ;
25082540 bool notify_dbus = false;
2541+ const char * e ;
25092542
25102543 assert (u );
25112544
2512- log_debug_unit (u -> id , "%s: Got notification message from PID " PID_FMT " (%s...)" ,
2513- u -> id , pid , tags && * tags ? tags [0 ] : "(empty)" );
2545+ cc = strv_join (tags , ", " );
2546+ log_debug_unit (u -> id , "%s: Got notification message from PID " PID_FMT " (%s)" ,
2547+ u -> id , pid , isempty (cc ) ? "n/a" : cc );
25142548
25152549 if (s -> notify_access == NOTIFY_NONE ) {
25162550 log_warning_unit (u -> id , "%s: Got notification message from PID " PID_FMT ", but reception is disabled." , u -> id , pid );
@@ -2539,10 +2573,46 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
25392573 }
25402574 }
25412575
2576+ /* Interpret RELOADING= */
2577+ if (strv_find (tags , "RELOADING=1" )) {
2578+
2579+ log_debug_unit (u -> id , "%s: got RELOADING=1" , u -> id );
2580+ s -> notify_state = NOTIFY_RELOADING ;
2581+
2582+ if (s -> state == SERVICE_RUNNING )
2583+ service_enter_reload_by_notify (s );
2584+
2585+ notify_dbus = true;
2586+ }
2587+
25422588 /* Interpret READY= */
2543- if (s -> type == SERVICE_NOTIFY && s -> state == SERVICE_START && strv_find (tags , "READY=1" )) {
2589+ if (strv_find (tags , "READY=1" )) {
2590+
25442591 log_debug_unit (u -> id , "%s: got READY=1" , u -> id );
2545- service_enter_start_post (s );
2592+ s -> notify_state = NOTIFY_READY ;
2593+
2594+ /* Type=notify services inform us about completed
2595+ * initialization with READY=1 */
2596+ if (s -> type == SERVICE_NOTIFY && s -> state == SERVICE_START )
2597+ service_enter_start_post (s );
2598+
2599+ /* Sending READY=1 while we are reloading informs us
2600+ * that the reloading is complete */
2601+ if (s -> state == SERVICE_RELOAD && s -> control_pid == 0 )
2602+ service_enter_running (s , SERVICE_SUCCESS );
2603+
2604+ notify_dbus = true;
2605+ }
2606+
2607+ /* Interpret STOPPING= */
2608+ if (strv_find (tags , "STOPPING=1" )) {
2609+
2610+ log_debug_unit (u -> id , "%s: got STOPPING=1" , u -> id );
2611+ s -> notify_state = NOTIFY_STOPPING ;
2612+
2613+ if (s -> state == SERVICE_RUNNING )
2614+ service_enter_stop_by_notify (s );
2615+
25462616 notify_dbus = true;
25472617 }
25482618
@@ -2798,6 +2868,15 @@ static const char* const notify_access_table[_NOTIFY_ACCESS_MAX] = {
27982868
27992869DEFINE_STRING_TABLE_LOOKUP (notify_access , NotifyAccess );
28002870
2871+ static const char * const notify_state_table [_NOTIFY_STATE_MAX ] = {
2872+ [NOTIFY_UNKNOWN ] = "unknown" ,
2873+ [NOTIFY_READY ] = "ready" ,
2874+ [NOTIFY_RELOADING ] = "reloading" ,
2875+ [NOTIFY_STOPPING ] = "stopping" ,
2876+ };
2877+
2878+ DEFINE_STRING_TABLE_LOOKUP (notify_state , NotifyState );
2879+
28012880static const char * const service_result_table [_SERVICE_RESULT_MAX ] = {
28022881 [SERVICE_SUCCESS ] = "success" ,
28032882 [SERVICE_FAILURE_RESOURCES ] = "resources" ,
0 commit comments