mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-22 13:37:10 +00:00
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>
This commit is contained in:
parent
331300d8b9
commit
6cd6e3d3cc
@ -37,6 +37,8 @@ struct acrnd_work {
|
||||
static LIST_HEAD(acrnd_work_list, acrnd_work) work_head;
|
||||
static pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static pthread_mutex_t acrnd_stop_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static unsigned int acrnd_stop_timeout;
|
||||
/* acrnd_add_work(), add a worker function.
|
||||
* @func, the worker function.
|
||||
* @sec, when add a @func(), after @sec seconds @func() will be called.
|
||||
@ -412,7 +414,7 @@ static int check_vms_status(unsigned int status)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _handle_acrnd_stop(unsigned int timeout)
|
||||
static int wait_for_stop(unsigned int timeout)
|
||||
{
|
||||
unsigned long t = timeout;
|
||||
|
||||
@ -421,7 +423,11 @@ static int _handle_acrnd_stop(unsigned int timeout)
|
||||
/* list and update the vm status */
|
||||
do {
|
||||
if (check_vms_status(VM_CREATED) == 0)
|
||||
return 0;
|
||||
return SHUTDOWN;
|
||||
|
||||
if (check_vms_status(VM_PAUSED) == 0)
|
||||
return SUSPEND;
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
while (t--);
|
||||
@ -429,18 +435,95 @@ static int _handle_acrnd_stop(unsigned int timeout)
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void* notify_stop_state(void *arg)
|
||||
{
|
||||
int lcs_fd;
|
||||
int rc;
|
||||
struct mngr_msg req;
|
||||
|
||||
req.magic = MNGR_MSG_MAGIC;
|
||||
|
||||
rc = wait_for_stop(acrnd_stop_timeout);
|
||||
if (rc < 0) {
|
||||
fprintf(stderr, "cannot get VMs stop state\n");
|
||||
req.msgid = SUSPEND;
|
||||
req.data.err = -1;
|
||||
} else {
|
||||
req.msgid = rc;
|
||||
req.data.err = 0;
|
||||
}
|
||||
|
||||
store_timer_list();
|
||||
|
||||
lcs_fd = mngr_open_un(SOS_LCS_SOCK, MNGR_CLIENT);
|
||||
if (lcs_fd < 0) {
|
||||
fprintf(stderr, "cannot open sos-lcs.socket\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
mngr_send_msg(lcs_fd, &req, NULL, 0);
|
||||
mngr_close(lcs_fd);
|
||||
exit:
|
||||
pthread_mutex_unlock(&acrnd_stop_mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void _handle_acrnd_stop(unsigned int timeout)
|
||||
{
|
||||
int rc;
|
||||
pthread_t tid;
|
||||
pthread_attr_t attr;
|
||||
|
||||
/*
|
||||
* Only one acrnd stop thread at a time
|
||||
* if failed to lock the acrnd_stop_mutex, then return directly
|
||||
* if creating thread success, then unlock in the thread exit
|
||||
* if failed to create thread, then unlock immediately.
|
||||
*/
|
||||
if (pthread_mutex_trylock(&acrnd_stop_mutex) == 0) {
|
||||
|
||||
acrnd_stop_timeout = timeout;
|
||||
|
||||
/*
|
||||
* Due to acrnd only has one main thread, and acrnd stop flow
|
||||
* probably blocks main thread, so a detached thread is created
|
||||
* to avoid this.
|
||||
*/
|
||||
rc = pthread_attr_init(&attr);
|
||||
if (rc < 0)
|
||||
goto fail_init;
|
||||
rc = pthread_attr_setdetachstate(&attr,
|
||||
PTHREAD_CREATE_DETACHED);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
rc = pthread_create(&tid, &attr, notify_stop_state, NULL);
|
||||
if (rc < 0)
|
||||
goto fail;
|
||||
|
||||
pthread_attr_destroy(&attr);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
pthread_attr_destroy(&attr);
|
||||
|
||||
fail_init:
|
||||
pthread_mutex_unlock(&acrnd_stop_mutex);
|
||||
fprintf(stderr, "Failed to invoke handle_acrnd_stop \n");
|
||||
}
|
||||
|
||||
static void handle_acrnd_stop(struct mngr_msg *msg, int client_fd, void *param)
|
||||
{
|
||||
struct mngr_msg ack;
|
||||
|
||||
ack.msgid = msg->msgid;
|
||||
ack.timestamp = msg->timestamp;
|
||||
ack.data.err = _handle_acrnd_stop(msg->data.acrnd_stop.timeout);
|
||||
|
||||
store_timer_list();
|
||||
|
||||
ack.data.err = 0;
|
||||
if (client_fd > 0)
|
||||
mngr_send_msg(client_fd, &ack, NULL, 0);
|
||||
|
||||
_handle_acrnd_stop(msg->data.acrnd_stop.timeout);
|
||||
}
|
||||
|
||||
void handle_acrnd_resume(struct mngr_msg *msg, int client_fd, void *param)
|
||||
|
Loading…
Reference in New Issue
Block a user