From: Takahiro Hirofuchi Date: Mon, 11 Mar 2013 14:44:54 +0000 (+0100) Subject: Add the ramsize check when launching a VM X-Git-Tag: v3_11_beta~297^2^2~47 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/5bdb31bdfb7418aef268f3857d86308acee33ba9 Add the ramsize check when launching a VM --- diff --git a/src/include/surf/surf.h b/src/include/surf/surf.h index d3e2ecc595..c5b183ccec 100644 --- a/src/include/surf/surf.h +++ b/src/include/surf/surf.h @@ -290,6 +290,7 @@ typedef struct surf_workstation_model_extension_public { void (*get_params) (void *ind_vm_ws, ws_params_t param); void (*set_params) (void *ind_vm_ws, ws_params_t param); + xbt_dynar_t (*get_vms) (void *ind_vm_ws); } s_surf_model_extension_workstation_t; diff --git a/src/simix/smx_vm.c b/src/simix/smx_vm.c index 194d658c0f..f898ad4142 100644 --- a/src/simix/smx_vm.c +++ b/src/simix/smx_vm.c @@ -40,44 +40,69 @@ smx_host_t SIMIX_pre_vm_create(smx_simcall_t simcall, const char *name, smx_host } -static int get_host_property_as_integer(smx_host_t host, const char *name) +/* works for VMs and PMs */ +static long host_get_ramsize(smx_host_t vm, int *overcommit) { - xbt_dict_t dict = SIMIX_host_get_properties(host); - - char *value = xbt_dict_get_or_null(dict, name); - return atoi(value); -} + s_ws_params_t params; + surf_workstation_model->extension.workstation.get_params(vm, ¶ms); + if (overcommit) + *overcommit = params.overcommit; + return params.ramsize; +} /* **** start a VM **** */ static int __can_be_started(smx_host_t vm) { - // TODO add checking code related to overcommitment or not. + smx_host_t pm = surf_vm_workstation_model->extension.vm_workstation.get_pm(vm); -#if 0 - int overcommit = get_host_property_as_integer(vm, "OverCommit"); - int core_nb = get_host_property_as_integer(vm, "CORE_NB"); - int mem_cap = get_host_property_as_integer(vm, "MEM_CAP"); - int net_cap = get_host_property_as_integer(vm, "NET_CAP"); -#endif + int pm_overcommit = 0; + long pm_ramsize = host_get_ramsize(pm, &pm_overcommit); + long vm_ramsize = host_get_ramsize(vm, NULL); + + if (!pm_ramsize) { + /* We assume users do not want to care about ramsize. */ + return 1; + } - /* we need to get other VM objects on this physical host. */ + if (pm_overcommit) { + XBT_INFO("%s allows memory overcommit.", pm->key); + return 1; + } + long total_ramsize_of_vms = 0; + xbt_dynar_t dyn_vms = surf_workstation_model->extension.workstation.get_vms(pm); + { + int cursor = 0; + smx_host_t another_vm; + xbt_dynar_foreach(dyn_vms, cursor, another_vm) { + long another_vm_ramsize = host_get_ramsize(vm, NULL); + total_ramsize_of_vms += another_vm_ramsize; + } + } + if (vm_ramsize > pm_ramsize - total_ramsize_of_vms) { + XBT_WARN("cannnot start %s@%s due to memory shortage: vm_ramsize %ld, free %ld, pm_ramsize %ld (bytes).", + vm->key, pm->key, vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize); + xbt_dynar_free(&dyn_vms); + return 0; + } + xbt_dynar_free(&dyn_vms); return 1; } void SIMIX_vm_start(smx_host_t ind_vm) { - //TODO only start the VM if you can if (__can_be_started(ind_vm)) SIMIX_vm_set_state(ind_vm, SURF_VM_STATE_RUNNING); else THROWF(vm_error, 0, "The VM %s cannot be started", SIMIX_host_get_name(ind_vm)); } + + void SIMIX_pre_vm_start(smx_simcall_t simcall, smx_host_t ind_vm) { SIMIX_vm_start(ind_vm); diff --git a/src/surf/workstation.c b/src/surf/workstation.c index 6003226215..62b36e266b 100644 --- a/src/surf/workstation.c +++ b/src/surf/workstation.c @@ -485,6 +485,32 @@ void ws_set_params(void *ws, ws_params_t params) memcpy(&ws_clm03->params, params, sizeof(s_ws_params_t)); } +static xbt_dynar_t ws_get_vms(void *pm) +{ + xbt_dynar_t dyn = xbt_dynar_new(sizeof(smx_host_t), NULL); + + /* iterate for all hosts including virtual machines */ + xbt_lib_cursor_t cursor; + char *key; + void **ind_host; + xbt_lib_foreach(host_lib, cursor, key, ind_host) { + workstation_CLM03_t ws_clm03 = ind_host[SURF_WKS_LEVEL]; + if (!ws_clm03) + continue; + /* skip if it is not a virtual machine */ + if (ws_clm03->generic_resource.model != surf_vm_workstation_model) + continue; + + /* It is a virtual machine, so we can cast it to workstation_VM2013_t */ + workstation_VM2013_t ws_vm2013 = (workstation_VM2013_t) ws_clm03; + if (pm == ws_vm2013->sub_ws) + xbt_dynar_push(dyn, &ws_vm2013->sub_ws); + } + + return dyn; +} + + static void surf_workstation_model_init_internal(void) { surf_model_t model = surf_model_init(); @@ -544,6 +570,7 @@ static void surf_workstation_model_init_internal(void) model->extension.workstation.get_params = ws_get_params; model->extension.workstation.set_params = ws_set_params; + model->extension.workstation.get_vms = ws_get_vms; surf_workstation_model = model; }