From 458365ff86f7085f8d5081f4bad873bdb7339171 Mon Sep 17 00:00:00 2001 From: Takahiro Hirofuchi Date: Fri, 1 Feb 2013 15:47:11 +0100 Subject: [PATCH] add vm_migration with no overhead --- src/include/surf/surf.h | 7 ++-- src/msg/msg_vm.c | 74 ++++++++++++++++++++++++----------- src/simix/smx_smurf_private.h | 1 + src/simix/smx_user.c | 6 +++ src/simix/smx_vm.c | 24 ++++++++++++ src/surf/vm_workstation.c | 18 ++++++++- 6 files changed, 102 insertions(+), 28 deletions(-) diff --git a/src/include/surf/surf.h b/src/include/surf/surf.h index 441070fc92..fe18a39bf2 100644 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@ -280,9 +280,10 @@ typedef struct surf_vm_workstation_model_extension_public { s_surf_model_extension_workstation_t basic; void* (*create) (const char *name, void *ind_phys_workstation); // First operation of the VM model // start does not appear here as it corresponds to turn the state from created to running (see smx_vm.c) - int (*get_state) (void *ind_phys_workstation); - void (*set_state) (void *ind_phys_workstation, int state); - void (*destroy) (void *ind_phys_workstation); // will be vm_ws_destroy(), which destroies the vm-specific data + int (*get_state) (void *ind_vm_workstation); + void (*set_state) (void *ind_vms_workstation, int state); + void (*migrate) (void *ind_vm_workstation, void *ind_dest_phys_workstation); // will be vm_ws_migrate() + void (*destroy) (void *ind_vm_workstation); // will be vm_ws_destroy(), which destroies the vm-workstation-specific data } s_surf_model_extension_vm_workstation_t; /** \ingroup SURF_models diff --git a/src/msg/msg_vm.c b/src/msg/msg_vm.c index e9db0531b2..ec1fd3d99a 100644 --- a/src/msg/msg_vm.c +++ b/src/msg/msg_vm.c @@ -213,29 +213,57 @@ void MSG_vm_shutdown(msg_vm_t vm) // MSG_process_kill(process); //} // -///** @brief Immediately change the host on which all processes are running. -// * @ingroup msg_VMs -// * -// * No migration cost occurs. If you want to simulate this too, you want to use a -// * MSG_task_send() before or after, depending on whether you want to do cold or hot -// * migration. -// */ -//void MSG_vm_migrate(msg_vm_t vm, msg_host_t destination) { -// unsigned int cpt; -// msg_process_t process; -// xbt_dynar_foreach(vm->processes,cpt,process) { -// MSG_process_migrate(process,destination); -// } -// xbt_swag_remove(vm, MSG_host_priv(vm->location)->vms); -// xbt_swag_insert_at_tail(vm, MSG_host_priv(destination)->vms); -// -// #ifdef HAVE_TRACING -// TRACE_msg_vm_change_host(vm,vm->location,destination); -// #endif -// -// vm->location = destination; -//} -// + +/** @brief Migrate the VM to the given host. + * @ingroup msg_VMs + * + * FIXME: update comments. + * No migration cost occurs. If you want to simulate this too, you want to use a + * MSG_task_send() before or after, depending on whether you want to do cold or hot + * migration. + */ +void MSG_vm_migrate(msg_vm_t vm, msg_host_t destination) +{ + /* some thoughts: + * - One approach is ... + * We first create a new VM (i.e., destination VM) on the destination + * physical host. The destination VM will receive the state of the source + * VM over network. We will finally destroy the source VM. + * - This behavior is similar to the way of migration in the real world. + * Even before a migration is completed, we will see a destination VM, + * consuming resources. + * - We have to relocate all processes. The existing process migraion code + * will work for this? + * - The name of the VM is a somewhat unique ID in the code. It is tricky + * for the destination VM? + * + * - Another one is ... + * We update the information of the given VM to place it to the destination + * physical host. + * + * The second one would be easier. + * + */ + + simcall_vm_migrate(vm, destination); + + #ifdef HAVE_TRACING + TRACE_msg_vm_change_host(vm,vm->location,destination); + #endif + +#if 0 + unsigned int cpt; + msg_process_t process; + xbt_dynar_foreach(vm->processes,cpt,process) { + MSG_process_migrate(process,destination); + } + xbt_swag_remove(vm, MSG_host_priv(vm->location)->vms); + xbt_swag_insert_at_tail(vm, MSG_host_priv(destination)->vms); + + vm->location = destination; +#endif +} + /** @brief Immediately suspend the execution of all processes within the given VM. * @ingroup msg_VMs diff --git a/src/simix/smx_smurf_private.h b/src/simix/smx_smurf_private.h index bddcc3e0cb..f639f1616c 100644 --- a/src/simix/smx_smurf_private.h +++ b/src/simix/smx_smurf_private.h @@ -278,6 +278,7 @@ ACTION(SIMCALL_VM_WS_CREATE, vm_ws_create, WITH_ANSWER, TPTR(result), TSTRING(na ACTION(SIMCALL_VM_START, vm_start, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_phys_host, smx_host_t)) sep \ ACTION(SIMCALL_VM_SET_STATE, vm_set_state, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TINT(state)) sep \ ACTION(SIMCALL_VM_GET_STATE, vm_get_state, WITH_ANSWER, TINT(result), TSPEC(ind_vm, smx_host_t)) sep \ +ACTION(SIMCALL_VM_MIGRATE, vm_migrate, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t), TSPEC(ind_dst_pm, smx_host_t)) sep \ ACTION(SIMCALL_VM_DESTROY, vm_destroy, WITHOUT_ANSWER, TVOID(result), TSPEC(ind_vm, smx_host_t)) sep \ ACTION(SIMCALL_VM_SUSPEND, vm_suspend, WITHOUT_ANSWER, TVOID(result), TSPEC(vm, smx_host_t)) sep \ ACTION(SIMCALL_VM_RESUME, vm_resume, WITHOUT_ANSWER, TVOID(result), TSPEC(vm, smx_host_t)) sep \ diff --git a/src/simix/smx_user.c b/src/simix/smx_user.c index 9a8e06fa37..7c93b7248d 100644 --- a/src/simix/smx_user.c +++ b/src/simix/smx_user.c @@ -290,6 +290,12 @@ void simcall_vm_start(smx_host_t vm) { simcall_BODY_set_vm_state(vm, msg_vm_state_running); } +void simcall_vm_migrate(smx_host_t vm) +{ + /* will jump to SIMIX_pre_vm_migrate */ + simcall_BODY_vm_migrate(vm); +} + void simcall_vm_suspend(smx_host_t vm) { /* will jump to SIMIX_pre_vm_suspend */ diff --git a/src/simix/smx_vm.c b/src/simix/smx_vm.c index b5688cc1d0..0ee891868b 100644 --- a/src/simix/smx_vm.c +++ b/src/simix/smx_vm.c @@ -82,6 +82,30 @@ int SIMIX_pre_vm_state(smx_host_t ind_vm){ return SIMIX_get_vm_state(ind_vm); } +/** + * \brief Function to migrate a SIMIX VM host. This function stops the exection of the + * VM. All the processes on this VM will pause. The state of the VM is + * perserved. We can later resume it again. + * + * \param host the vm host to migrate (a smx_host_t) + */ +void SIMIX_vm_migrate(smx_host_t ind_vm, smx_host_t ind_dst_pm) +{ + /* TODO: check state */ + + /* TODO: Using the variable of the MSG layer is not clean. */ + SIMIX_set_vm_state(ind_vm, msg_vm_state_migrating); + + /* jump to vm_ws_destroy(). this will update the vm location. */ + surf_vm_workstation_model->extension.vm_workstation.migrate(ind_vm, ind_dst); + + SIMIX_set_vm_state(ind_vm, msg_vm_state_running); +} + +void SIMIX_pre_vm_migrate(smx_simcall_t simcall, smx_host_t ind_vm, smx_host_t ind_dst_pm){ + SIMIX_vm_migrate(ind_vm, ind_dst_pm); +} + /** * \brief Function to suspend a SIMIX VM host. This function stops the exection of the * VM. All the processes on this VM will pause. The state of the VM is diff --git a/src/surf/vm_workstation.c b/src/surf/vm_workstation.c index 94933ebd1e..23a287b516 100644 --- a/src/surf/vm_workstation.c +++ b/src/surf/vm_workstation.c @@ -34,15 +34,28 @@ static void vm_ws_create(const char *name, void *ind_phys_workstation) xbt_lib_set(host_lib, name, SURF_WKS_LEVEL, vm_ws); } +/* + * Update the physical host of the given VM + */ +static void vm_ws_migrate(void *ind_vm_workstation, void *ind_dest_phys_workstation) +{ + /* ind_phys_workstation equals to smx_host_t */ + workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_workstation); + xbt_assert(vm_ws); + + /* do something */ + + vm_ws->physical_workstation = surf_workstation_resource_priv(ind_dest_phys_workstation); +} /* * A physical host does not disapper in the current SimGrid code, but a VM may * disapper during a simulation. */ -static void vm_ws_destroy(void *ind_phys_workstation) +static void vm_ws_destroy(void *ind_vm_workstation) { /* ind_phys_workstation equals to smx_host_t */ - workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_phys_workstation); + workstation_VM2013_t vm_ws = surf_workstation_resource_priv(ind_vm_workstation); xbt_assert(vm_ws); xbt_assert(vm_ws->generic_resource.model == surf_vm_workstation_model); @@ -70,6 +83,7 @@ static void surf_vm_workstation_model_init_internal(void) surf_vm_workstation_model->extension.vm_workstation.create = vm_ws_create; surf_vm_workstation_model->extension.vm_workstation.set_state = vm_ws_set_state; surf_vm_workstation_model->extension.vm_workstation.get_state = vm_ws_get_state; + surf_vm_workstation_model->extension.vm_workstation.migrate = vm_ws_migrate; surf_vm_workstation_model->extension.vm_workstation.destroy = vm_ws_destroy; } -- 2.20.1