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
// 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
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 \
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 */
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
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);
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;
}