tools: acrn-manager: fix a race condition on updating VM state

For a running or suspended VM, its state is updated in 2 steps.
It is first set to VM_CREATED, then set to VM_STARTED/VM_PAUSED. IF
one thread check a running/suspend VM, it may get wrong state VM_CREATED,
while another thread is updating the VMs state.

Tracked-On: #2716
Signed-off-by: Tao Yuhong <yuhong.tao@intel.com>
Acked-by: Yan, Like <like.yan@intel.com>
This commit is contained in:
yuhong.tao@intel.com 2019-01-08 15:01:19 +00:00 committed by wenlingz
parent d5ec844f86
commit 5d6f6ab798
2 changed files with 9 additions and 6 deletions

View File

@ -171,19 +171,19 @@ static void _scan_alive_vm(void)
if (ret < 0)
/* unsupport query */
vm->state = VM_STARTED;
vm->state_tmp = VM_STARTED;
else
switch (ret) {
case VM_SUSPEND_NONE:
vm->state = VM_STARTED;
vm->state_tmp = VM_STARTED;
break;
case VM_SUSPEND_SUSPEND:
vm->state = VM_SUSPENDED;
vm->state_tmp = VM_SUSPENDED;
break;
default:
fprintf(stderr, "Warnning: unknow vm state:0x%lx\n",
vm->state);
vm->state = VM_STATE_UNKNOWN;
vm->state_tmp = VM_STATE_UNKNOWN;
}
vm->update = update_count;
}
@ -271,7 +271,7 @@ static void _scan_added_vm(void)
LIST_INSERT_HEAD(&vmmngr_head, vm, list);
}
vm->state = VM_CREATED;
vm->state_tmp = VM_CREATED;
vm->update = update_count;
}
@ -283,8 +283,10 @@ static void _remove_dead_vm(void)
struct vmmngr_struct *vm, *tvm;
list_foreach_safe(vm, &vmmngr_head, list, tvm) {
if (vm->update == update_count)
if (vm->update == update_count) {
vm->state = vm->state_tmp;
continue;
}
LIST_REMOVE(vm, list);
printf("%s: Removed dead %s\n", __func__, vm->name);
free(vm);

View File

@ -38,6 +38,7 @@ struct vmmngr_struct *vmmngr_find(const char *vmname);
struct vmmngr_struct {
char name[MAX_NAME_LEN];
unsigned long state;
unsigned long state_tmp;
unsigned long update; /* update count, remove a vm if no update for it */
LIST_ENTRY(vmmngr_struct) list;
};