mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-05-12 02:18:40 +00:00
tools: acrn-manager: rework acrnd resume flow
This commit reworked the resume flow: - generate RSN_RTC wakeup reason to resume_vm(); - clear timer_list in memory once it's saved to fs; - wakeup the suspended VMs only if wakeup by ignition button. Tracked-On: #927 Signed-off-by: Yan, Like <like.yan@intel.com> Acked-by: Yin Fengwei <fengwei.yin@intel.com>
This commit is contained in:
parent
26b8b3b28b
commit
0ca90ba6be
@ -40,7 +40,7 @@ static pthread_mutex_t work_mutex = PTHREAD_MUTEX_INITIALIZER;
|
|||||||
static pthread_mutex_t acrnd_stop_mutex = PTHREAD_MUTEX_INITIALIZER;
|
static pthread_mutex_t acrnd_stop_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
static unsigned int acrnd_stop_timeout;
|
static unsigned int acrnd_stop_timeout;
|
||||||
/* acrnd_add_work(), add a worker function.
|
/* acrnd_add_work(), add a worker function.
|
||||||
* @func, the worker function.
|
* @func, the worker function, will be called with work_mutex hold.
|
||||||
* @sec, when add a @func(), after @sec seconds @func() will be called.
|
* @sec, when add a @func(), after @sec seconds @func() will be called.
|
||||||
* @arg, a cpoy of @arg will be pass to @func.
|
* @arg, a cpoy of @arg will be pass to @func.
|
||||||
*/
|
*/
|
||||||
@ -93,25 +93,26 @@ static void try_do_works(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pthread_mutex_lock(&work_mutex);
|
||||||
list_foreach_safe(work, &work_head, list, twork) {
|
list_foreach_safe(work, &work_head, list, twork) {
|
||||||
if (current > work->expire) {
|
if (current >= work->expire) {
|
||||||
pthread_mutex_lock(&work_mutex);
|
|
||||||
work->func(&work->arg);
|
work->func(&work->arg);
|
||||||
LIST_REMOVE(work, list);
|
LIST_REMOVE(work, list);
|
||||||
pthread_mutex_unlock(&work_mutex);
|
|
||||||
free(work);
|
free(work);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pthread_mutex_unlock(&work_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void acrnd_run_vm(char *name);
|
static void acrnd_run_vm(char *name);
|
||||||
unsigned get_sos_wakeup_reason(void);
|
unsigned get_sos_wakeup_reason(void);
|
||||||
|
|
||||||
/* Time to run/resume VM */
|
/* Timer callback to run/resume VM.
|
||||||
|
* Will be called with work_mutex hold
|
||||||
|
*/
|
||||||
void acrnd_vm_timer_func(struct work_arg *arg)
|
void acrnd_vm_timer_func(struct work_arg *arg)
|
||||||
{
|
{
|
||||||
struct vmmngr_struct *vm;
|
struct vmmngr_struct *vm;
|
||||||
unsigned reason;
|
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg) {
|
||||||
pdebug();
|
pdebug();
|
||||||
@ -130,8 +131,7 @@ void acrnd_vm_timer_func(struct work_arg *arg)
|
|||||||
acrnd_run_vm(arg->name);
|
acrnd_run_vm(arg->name);
|
||||||
break;
|
break;
|
||||||
case VM_PAUSED:
|
case VM_PAUSED:
|
||||||
reason = get_sos_wakeup_reason();
|
resume_vm(arg->name, CBC_WK_RSN_RTC);
|
||||||
resume_vm(arg->name, reason);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pdebug();
|
pdebug();
|
||||||
@ -261,6 +261,21 @@ static int active_all_vms(void)
|
|||||||
return ret ? -1 : 0;
|
return ret ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int wakeup_suspended_vms(unsigned wakeup_reason)
|
||||||
|
{
|
||||||
|
struct vmmngr_struct *vm;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
vmmngr_update();
|
||||||
|
|
||||||
|
LIST_FOREACH(vm, &vmmngr_head, list) {
|
||||||
|
if (vm->state == VM_PAUSED)
|
||||||
|
ret += resume_vm(vm->name, wakeup_reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret ? -1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define SOS_LCS_SOCK "sos-lcs"
|
#define SOS_LCS_SOCK "sos-lcs"
|
||||||
#define DEFAULT_TIMEOUT 2U
|
#define DEFAULT_TIMEOUT 2U
|
||||||
#define ACRND_NAME "acrnd"
|
#define ACRND_NAME "acrnd"
|
||||||
@ -345,7 +360,7 @@ static int set_sos_timer(time_t due_time)
|
|||||||
RETRY:
|
RETRY:
|
||||||
ret =
|
ret =
|
||||||
mngr_send_msg(client_fd, &req, &ack, DEFAULT_TIMEOUT);
|
mngr_send_msg(client_fd, &req, &ack, DEFAULT_TIMEOUT);
|
||||||
while (ret != 0 && retry < 5) {
|
while (ret <= 0 && retry < 5) {
|
||||||
printf("Fail to set sos wakeup timer(err:%d), retry %d...\n",
|
printf("Fail to set sos wakeup timer(err:%d), retry %d...\n",
|
||||||
ret, retry++);
|
ret, retry++);
|
||||||
goto RETRY;
|
goto RETRY;
|
||||||
@ -359,7 +374,7 @@ static int set_sos_timer(time_t due_time)
|
|||||||
static int store_timer_list(void)
|
static int store_timer_list(void)
|
||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
struct acrnd_work *w;
|
struct acrnd_work *w, *twork;
|
||||||
time_t sys_wakeup = 0;
|
time_t sys_wakeup = 0;
|
||||||
time_t current;
|
time_t current;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -378,7 +393,7 @@ static int store_timer_list(void)
|
|||||||
goto open_file_err;
|
goto open_file_err;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock(&work_mutex);
|
pthread_mutex_lock(&work_mutex);
|
||||||
LIST_FOREACH(w, &work_head, list) {
|
list_foreach_safe(w, &work_head, list, twork) {
|
||||||
if (w->func != acrnd_vm_timer_func)
|
if (w->func != acrnd_vm_timer_func)
|
||||||
continue;
|
continue;
|
||||||
if (!sys_wakeup)
|
if (!sys_wakeup)
|
||||||
@ -386,6 +401,10 @@ static int store_timer_list(void)
|
|||||||
if (w->expire < sys_wakeup)
|
if (w->expire < sys_wakeup)
|
||||||
sys_wakeup = w->expire;
|
sys_wakeup = w->expire;
|
||||||
fprintf(fp, "%s\t%lu\t%lu\n", w->arg.name, w->expire, current);
|
fprintf(fp, "%s\t%lu\t%lu\n", w->arg.name, w->expire, current);
|
||||||
|
|
||||||
|
/* remove work from list after it's saved onto fs */
|
||||||
|
LIST_REMOVE(w, list);
|
||||||
|
free(w);
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&work_mutex);
|
pthread_mutex_unlock(&work_mutex);
|
||||||
|
|
||||||
@ -536,28 +555,31 @@ void handle_acrnd_resume(struct mngr_msg *msg, int client_fd, void *param)
|
|||||||
|
|
||||||
ack.msgid = msg->msgid;
|
ack.msgid = msg->msgid;
|
||||||
ack.timestamp = msg->timestamp;
|
ack.timestamp = msg->timestamp;
|
||||||
ack.data.err = 0;
|
ack.data.err = -1;
|
||||||
|
|
||||||
/* Do we have a timer list file to load? */
|
|
||||||
if (!stat(TIMER_LIST_FILE, &st))
|
|
||||||
if (S_ISREG(st.st_mode)) {
|
|
||||||
ack.data.err = load_timer_list();
|
|
||||||
if (ack.data.err)
|
|
||||||
pdebug();
|
|
||||||
goto reply_ack;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* acrnd get wakeup_reason from sos lcs */
|
/* acrnd get wakeup_reason from sos lcs */
|
||||||
wakeup_reason = get_sos_wakeup_reason();
|
wakeup_reason = get_sos_wakeup_reason();
|
||||||
|
|
||||||
if (wakeup_reason & CBC_WK_RSN_RTC) {
|
if (wakeup_reason & CBC_WK_RSN_RTC) {
|
||||||
/* do nothing, just wait the acrnd_work to expire */
|
/* wakeup by RTC timer */
|
||||||
goto reply_ack;
|
if (!stat(TIMER_LIST_FILE, &st)
|
||||||
|
&& S_ISREG(st.st_mode)) {
|
||||||
|
ack.data.err = load_timer_list();
|
||||||
|
if (ack.data.err == 0) {
|
||||||
|
/* load timers successfully */
|
||||||
|
try_do_works();
|
||||||
|
goto reply_ack;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
perror("Error to load timers, wakeup all VMs");
|
||||||
|
ack.data.err = wakeup_suspended_vms(wakeup_reason);
|
||||||
|
} else {
|
||||||
|
printf("Resumed UOS, by ignition button\n");
|
||||||
|
ack.data.err = wakeup_suspended_vms(wakeup_reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
ack.data.err = active_all_vms();
|
reply_ack:
|
||||||
|
|
||||||
reply_ack:
|
|
||||||
unlink(TIMER_LIST_FILE);
|
unlink(TIMER_LIST_FILE);
|
||||||
|
|
||||||
if (client_fd > 0)
|
if (client_fd > 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user