@@ -40,8 +40,14 @@ static bool global_keep_tracking = false;
4040#define PCMK_PROCESS_CHECK_INTERVAL 5
4141
4242static crm_trigger_t * shutdown_trigger = NULL ;
43+ static crm_trigger_t * startup_trigger = NULL ;
4344static const char * pid_file = PCMK_RUN_DIR "/pacemaker.pid" ;
4445
46+ static const char * pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_INIT ;
47+ static gboolean running_with_sbd = FALSE;
48+ static uint shutdown_complete_state_reported_to = 0 ;
49+ static gboolean shutdown_complete_state_reported_client_closed = FALSE;
50+
4551typedef struct pcmk_child_s {
4652 pid_t pid ;
4753 long flag ;
@@ -374,21 +380,20 @@ escalate_shutdown(gpointer data)
374380static gboolean
375381pcmk_shutdown_worker (gpointer user_data )
376382{
377- static int phase = 0 ;
383+ static int phase = SIZEOF ( pcmk_children ) ;
378384 static time_t next_log = 0 ;
379- static int max = SIZEOF (pcmk_children );
380385
381386 int lpc = 0 ;
382387
383- if (phase == 0 ) {
388+ if (phase == SIZEOF ( pcmk_children ) ) {
384389 crm_notice ("Shutting down Pacemaker" );
385- phase = max ;
390+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_SHUTTINGDOWN ;
386391 }
387392
388393 for (; phase > 0 ; phase -- ) {
389394 /* Don't stop anything with start_seq < 1 */
390395
391- for (lpc = max - 1 ; lpc >= 0 ; lpc -- ) {
396+ for (lpc = SIZEOF ( pcmk_children ) - 1 ; lpc >= 0 ; lpc -- ) {
392397 pcmk_child_t * child = & (pcmk_children [lpc ]);
393398
394399 if (phase != child -> start_seq ) {
@@ -436,6 +441,11 @@ pcmk_shutdown_worker(gpointer user_data)
436441 }
437442
438443 crm_notice ("Shutdown complete" );
444+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE ;
445+ if (!fatal_error && running_with_sbd &&
446+ !shutdown_complete_state_reported_client_closed ) {
447+ return TRUE;
448+ }
439449
440450 {
441451 const char * delay = pcmk__env_option ("shutdown_delay" );
@@ -489,6 +499,50 @@ pcmk_ipc_accept(qb_ipcs_connection_t * c, uid_t uid, gid_t gid)
489499 return 0 ;
490500}
491501
502+ static void
503+ pcmk_handle_ping_request (pcmk__client_t * c , xmlNode * msg , uint32_t id )
504+ {
505+ const char * value = NULL ;
506+ xmlNode * ping = NULL ;
507+ xmlNode * reply = NULL ;
508+ time_t pinged = time (NULL );
509+ const char * from = crm_element_value (msg , F_CRM_SYS_FROM );
510+
511+ /* Pinged for status */
512+ crm_trace ("Pinged from %s.%s" ,
513+ crm_element_value (msg , F_CRM_ORIGIN ),
514+ from ?from :"unknown" );
515+ ping = create_xml_node (NULL , XML_CRM_TAG_PING );
516+ value = crm_element_value (msg , F_CRM_SYS_TO );
517+ crm_xml_add (ping , XML_PING_ATTR_SYSFROM , value );
518+ crm_xml_add (ping , XML_PING_ATTR_PACEMAKERDSTATE , pacemakerd_state );
519+ crm_xml_add_ll (ping , XML_ATTR_TSTAMP , (long long ) pinged );
520+ crm_xml_add (ping , XML_PING_ATTR_STATUS , "ok" );
521+ reply = create_reply (msg , ping );
522+ free_xml (ping );
523+ if (reply ) {
524+ if (pcmk__ipc_send_xml (c , id , reply , crm_ipc_server_event ) <= 0 ) {
525+ crm_err ("Failed sending ping-reply" );
526+ }
527+ free_xml (reply );
528+ } else {
529+ crm_err ("Failed building ping-reply" );
530+ }
531+ /* just proceed state on sbd pinging us */
532+ if (from && strstr (from , "sbd" )) {
533+ if (crm_str_eq (pacemakerd_state ,
534+ XML_PING_ATTR_PACEMAKERDSTATE_SHUTDOWNCOMPLETE ,
535+ TRUE)) {
536+ shutdown_complete_state_reported_to = c -> pid ;
537+ } else if (crm_str_eq (pacemakerd_state ,
538+ XML_PING_ATTR_PACEMAKERDSTATE_WAITPING ,
539+ TRUE)) {
540+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS ;
541+ mainloop_set_trigger (startup_trigger );
542+ }
543+ }
544+ }
545+
492546/* Exit code means? */
493547static int32_t
494548pcmk_ipc_dispatch (qb_ipcs_connection_t * qbc , void * data , size_t size )
@@ -514,6 +568,9 @@ pcmk_ipc_dispatch(qb_ipcs_connection_t * qbc, void *data, size_t size)
514568 crm_trace ("Ignoring IPC request to purge node "
515569 "because peer cache is not used" );
516570
571+ } else if (crm_str_eq (task , CRM_OP_PING , TRUE)) {
572+ pcmk_handle_ping_request (c , msg , id );
573+
517574 } else {
518575 crm_debug ("Unrecognized IPC command '%s' sent to pacemakerd" ,
519576 crm_str (task ));
@@ -533,6 +590,12 @@ pcmk_ipc_closed(qb_ipcs_connection_t * c)
533590 return 0 ;
534591 }
535592 crm_trace ("Connection %p" , c );
593+ if (shutdown_complete_state_reported_to == client -> pid ) {
594+ shutdown_complete_state_reported_client_closed = TRUE;
595+ if (shutdown_trigger ) {
596+ mainloop_set_trigger (shutdown_trigger );
597+ }
598+ }
536599 pcmk__free_client (client );
537600 return 0 ;
538601}
@@ -924,8 +987,8 @@ find_and_track_existing_processes(void)
924987 return pcmk_rc_ok ;
925988}
926989
927- static void
928- init_children_processes (void )
990+ static gboolean
991+ init_children_processes (void * user_data )
929992{
930993 int start_seq = 1 , lpc = 0 ;
931994 static int max = SIZEOF (pcmk_children );
@@ -951,6 +1014,8 @@ init_children_processes(void)
9511014 * This may be useful for the daemons to know
9521015 */
9531016 setenv ("PCMK_respawned" , "true" , 1 );
1017+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_RUNNING ;
1018+ return TRUE;
9541019}
9551020
9561021static void
@@ -1154,6 +1219,7 @@ main(int argc, char **argv)
11541219
11551220 if (pcmk_locate_sbd () > 0 ) {
11561221 setenv ("PCMK_watchdog" , "true" , 1 );
1222+ running_with_sbd = TRUE;
11571223 } else {
11581224 setenv ("PCMK_watchdog" , "false" , 1 );
11591225 }
@@ -1170,7 +1236,13 @@ main(int argc, char **argv)
11701236 mainloop_add_signal (SIGTERM , pcmk_shutdown );
11711237 mainloop_add_signal (SIGINT , pcmk_shutdown );
11721238
1173- init_children_processes ();
1239+ if (running_with_sbd ) {
1240+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_WAITPING ;
1241+ startup_trigger = mainloop_add_trigger (G_PRIORITY_HIGH , init_children_processes , NULL );
1242+ } else {
1243+ pacemakerd_state = XML_PING_ATTR_PACEMAKERDSTATE_STARTINGDAEMONS ;
1244+ init_children_processes (NULL );
1245+ }
11741246
11751247 crm_notice ("Pacemaker daemon successfully started and accepting connections" );
11761248 g_main_loop_run (mainloop );
0 commit comments