Skip to content

Commit 6cd6e3d

Browse files
yliu80lijinxia
authored andcommitted
tools: fix an issue acrnd does not notify the vm stop state to cbc lifecycle service
This patch resolves acrnd does not notify vm stop state(suspend/shutdown) to cbc_lifecycle after SOS enters suspend/shutdown, that causes cbc_lifecycle cannot trigger SOS suspend/shutdown flow. Signed-off-by: Yuan Liu <yuan1.liu@intel.com> Reviewed-by: Like Yan <like.yan@intel.com>
1 parent 331300d commit 6cd6e3d

File tree

1 file changed

+89
-6
lines changed

1 file changed

+89
-6
lines changed

tools/acrn-manager/acrnd.c

Lines changed: 89 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ struct acrnd_work {
3737
static LIST_HEAD(acrnd_work_list, acrnd_work) work_head;
3838
static pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER;
3939

40+
static pthread_mutex_t acrnd_stop_mutex = PTHREAD_MUTEX_INITIALIZER;
41+
static unsigned int acrnd_stop_timeout;
4042
/* acrnd_add_work(), add a worker function.
4143
* @func, the worker function.
4244
* @sec, when add a @func(), after @sec seconds @func() will be called.
@@ -412,7 +414,7 @@ static int check_vms_status(unsigned int status)
412414
return 0;
413415
}
414416

415-
static int _handle_acrnd_stop(unsigned int timeout)
417+
static int wait_for_stop(unsigned int timeout)
416418
{
417419
unsigned long t = timeout;
418420

@@ -421,26 +423,107 @@ static int _handle_acrnd_stop(unsigned int timeout)
421423
/* list and update the vm status */
422424
do {
423425
if (check_vms_status(VM_CREATED) == 0)
424-
return 0;
426+
return SHUTDOWN;
427+
428+
if (check_vms_status(VM_PAUSED) == 0)
429+
return SUSPEND;
430+
425431
sleep(1);
426432
}
427433
while (t--);
428434

429435
return -1;
430436
}
431437

438+
static void* notify_stop_state(void *arg)
439+
{
440+
int lcs_fd;
441+
int rc;
442+
struct mngr_msg req;
443+
444+
req.magic = MNGR_MSG_MAGIC;
445+
446+
rc = wait_for_stop(acrnd_stop_timeout);
447+
if (rc < 0) {
448+
fprintf(stderr, "cannot get VMs stop state\n");
449+
req.msgid = SUSPEND;
450+
req.data.err = -1;
451+
} else {
452+
req.msgid = rc;
453+
req.data.err = 0;
454+
}
455+
456+
store_timer_list();
457+
458+
lcs_fd = mngr_open_un(SOS_LCS_SOCK, MNGR_CLIENT);
459+
if (lcs_fd < 0) {
460+
fprintf(stderr, "cannot open sos-lcs.socket\n");
461+
goto exit;
462+
}
463+
464+
mngr_send_msg(lcs_fd, &req, NULL, 0);
465+
mngr_close(lcs_fd);
466+
exit:
467+
pthread_mutex_unlock(&acrnd_stop_mutex);
468+
return NULL;
469+
}
470+
471+
static void _handle_acrnd_stop(unsigned int timeout)
472+
{
473+
int rc;
474+
pthread_t tid;
475+
pthread_attr_t attr;
476+
477+
/*
478+
* Only one acrnd stop thread at a time
479+
* if failed to lock the acrnd_stop_mutex, then return directly
480+
* if creating thread success, then unlock in the thread exit
481+
* if failed to create thread, then unlock immediately.
482+
*/
483+
if (pthread_mutex_trylock(&acrnd_stop_mutex) == 0) {
484+
485+
acrnd_stop_timeout = timeout;
486+
487+
/*
488+
* Due to acrnd only has one main thread, and acrnd stop flow
489+
* probably blocks main thread, so a detached thread is created
490+
* to avoid this.
491+
*/
492+
rc = pthread_attr_init(&attr);
493+
if (rc < 0)
494+
goto fail_init;
495+
rc = pthread_attr_setdetachstate(&attr,
496+
PTHREAD_CREATE_DETACHED);
497+
if (rc < 0)
498+
goto fail;
499+
rc = pthread_create(&tid, &attr, notify_stop_state, NULL);
500+
if (rc < 0)
501+
goto fail;
502+
503+
pthread_attr_destroy(&attr);
504+
}
505+
506+
return;
507+
508+
fail:
509+
pthread_attr_destroy(&attr);
510+
511+
fail_init:
512+
pthread_mutex_unlock(&acrnd_stop_mutex);
513+
fprintf(stderr, "Failed to invoke handle_acrnd_stop \n");
514+
}
515+
432516
static void handle_acrnd_stop(struct mngr_msg *msg, int client_fd, void *param)
433517
{
434518
struct mngr_msg ack;
435519

436520
ack.msgid = msg->msgid;
437521
ack.timestamp = msg->timestamp;
438-
ack.data.err = _handle_acrnd_stop(msg->data.acrnd_stop.timeout);
439-
440-
store_timer_list();
441-
522+
ack.data.err = 0;
442523
if (client_fd > 0)
443524
mngr_send_msg(client_fd, &ack, NULL, 0);
525+
526+
_handle_acrnd_stop(msg->data.acrnd_stop.timeout);
444527
}
445528

446529
void handle_acrnd_resume(struct mngr_msg *msg, int client_fd, void *param)

0 commit comments

Comments
 (0)