void parameters(vm_params_t params);
void setParameters(vm_params_t params);
+ double getRamsize();
/* FIXME: protect me */
simgrid::surf::VirtualMachineImpl* pimpl_vm_ = nullptr;
/******************************* VM simcalls ********************************/
// Create the vm_workstation at the SURF level
-XBT_PUBLIC(void) simcall_vm_start(sg_host_t vm);
-XBT_PUBLIC(void) simcall_vm_set_bound(sg_host_t vm, double bound);
XBT_PUBLIC(void) simcall_vm_resume(sg_host_t vm);
XBT_PUBLIC(void) simcall_vm_save(sg_host_t vm);
-XBT_PUBLIC(void) simcall_vm_restore(sg_host_t vm);
XBT_PUBLIC(void) simcall_vm_suspend(sg_host_t vm);
XBT_PUBLIC(void) simcall_vm_shutdown(sg_host_t vm);
#include "src/plugins/vm/VirtualMachineImpl.hpp"
#include "src/plugins/vm/VmHostExt.hpp"
+#include "src/simix/ActorImpl.hpp"
#include <simgrid/s4u/VirtualMachine.hpp>
#include <simgrid/s4u/host.hpp>
/** @brief Start a vm (i.e., boot the guest operating system)
* @ingroup msg_VMs
*
- * If the VM cannot be started, an exception is generated.
+ * If the VM cannot be started (because of memory overprovisionning), an exception is generated.
*/
void MSG_vm_start(msg_vm_t vm)
{
- simcall_vm_start(vm);
+ simgrid::simix::kernelImmediate([vm]() {
+ simgrid::vm::VmHostExt::ensureVmExtInstalled();
+
+ simgrid::s4u::VirtualMachine* typedVM = static_cast<simgrid::s4u::VirtualMachine*>(vm);
+ simgrid::s4u::Host* pm = typedVM->pimpl_vm_->getPm();
+ if (pm->extension<simgrid::vm::VmHostExt>() == nullptr)
+ pm->extension_set(new simgrid::vm::VmHostExt());
+
+ long pm_ramsize = pm->extension<simgrid::vm::VmHostExt>()->ramsize;
+ int pm_overcommit = pm->extension<simgrid::vm::VmHostExt>()->overcommit;
+ long vm_ramsize = typedVM->getRamsize();
+
+ if (pm_ramsize && !pm_overcommit) { /* Only verify that we don't overcommit on need */
+ /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
+ long total_ramsize_of_vms = 0;
+ for (simgrid::s4u::VirtualMachine* ws_vm : simgrid::surf::VirtualMachineImpl::allVms_)
+ if (pm == ws_vm->pimpl_vm_->getPm())
+ total_ramsize_of_vms += ws_vm->pimpl_vm_->getRamsize();
+
+ 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).",
+ sg_host_get_name(vm), sg_host_get_name(pm), vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize);
+ THROWF(vm_error, 0, "Memory shortage on host '%s', VM '%s' cannot be started", pm->cname(), vm->cname());
+ }
+ }
+
+ typedVM->pimpl_vm_->setState(SURF_VM_STATE_RUNNING);
+ });
if (TRACE_msg_vm_is_enabled()) {
container_t vm_container = PJ_container_get(vm->name().c_str());
*/
void MSG_vm_restore(msg_vm_t vm)
{
- simcall_vm_restore(vm);
+ simgrid::simix::kernelImmediate([vm]() {
+ if (static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->getState() != SURF_VM_STATE_SAVED)
+ THROWF(vm_error, 0, "VM(%s) was not saved", vm->name().c_str());
+
+ XBT_DEBUG("restore VM(%s), where %d processes exist", vm->name().c_str(),
+ xbt_swag_size(sg_host_simix(vm)->process_list));
+
+ /* jump to vm_ws_restore() */
+ static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->restore();
+
+ smx_actor_t smx_process, smx_process_safe;
+ xbt_swag_foreach_safe(smx_process, smx_process_safe, sg_host_simix(vm)->process_list)
+ {
+ XBT_DEBUG("resume %s", smx_process->name.c_str());
+ SIMIX_process_resume(smx_process);
+ }
+ });
if (TRACE_msg_vm_is_enabled()) {
container_t vm_container = PJ_container_get(vm->cname());
*/
void MSG_vm_set_bound(msg_vm_t vm, double bound)
{
- simcall_vm_set_bound(vm, bound);
+ simgrid::simix::kernelImmediate(
+ [vm, bound]() { static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->setBound(bound); });
}
* @details A VM represent a virtual machine
*/
class VirtualMachineImpl : public HostImpl {
+ friend simgrid::s4u::VirtualMachine;
+
public:
explicit VirtualMachineImpl(s4u::VirtualMachine* piface, s4u::Host* host);
~VirtualMachineImpl();
{
return pimpl_vm_->isMigrating;
}
+double VirtualMachine::getRamsize()
+{
+ return pimpl_vm_->params_.ramsize;
+}
/** @brief Retrieve a copy of the parameters of that VM/PM
* @details The ramsize and overcommit fields are used on the PM too */
return (e_smx_state_t) simcall_BODY_execution_wait(execution);
}
-/**
- * \ingroup simix_vm_management
- * \brief Start the given VM to the given physical host
- *
- * \param vm VM
- */
-void simcall_vm_start(sg_host_t vm)
-{
- simgrid::simix::kernelImmediate(std::bind(SIMIX_vm_start, vm));
-}
-
-/**
- * @brief Function to set the CPU bound of the given SIMIX VM host.
- *
- * @param host the vm host (a sg_host_t)
- * @param bound bound (a double)
- */
-void simcall_vm_set_bound(sg_host_t vm, double bound)
-{
- simgrid::simix::kernelImmediate(
- [vm, bound]() { static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->setBound(bound); });
-}
-
/**
* \ingroup simix_vm_management
* \brief Suspend the given VM
simcall_BODY_vm_save(vm);
}
-/**
- * \ingroup simix_vm_management
- * \brief Restore the given VM
- *
- * \param vm VM
- */
-void simcall_vm_restore(sg_host_t vm)
-{
- simgrid::simix::kernelImmediate([vm]() {
- if (static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->getState() != SURF_VM_STATE_SAVED)
- THROWF(vm_error, 0, "VM(%s) was not saved", vm->name().c_str());
-
- XBT_DEBUG("restore VM(%s), where %d processes exist", vm->name().c_str(),
- xbt_swag_size(sg_host_simix(vm)->process_list));
-
- /* jump to vm_ws_restore() */
- static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->restore();
-
- smx_actor_t smx_process, smx_process_safe;
- xbt_swag_foreach_safe(smx_process, smx_process_safe, sg_host_simix(vm)->process_list)
- {
- XBT_DEBUG("resume %s", smx_process->name.c_str());
- SIMIX_process_resume(smx_process);
- }
- });
-}
-
/**
* \ingroup simix_vm_management
* \brief Shutdown the given VM
// --
XBT_PRIVATE void SIMIX_vm_save(sg_host_t ind_vm, smx_actor_t issuer);
-XBT_PRIVATE void SIMIX_vm_start(sg_host_t ind_vm);
-
XBT_PRIVATE void SIMIX_vm_shutdown(sg_host_t ind_vm, smx_actor_t issuer);
// --
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_vm, simix, "Logging specific to SIMIX Virtual Machines");
-/* works for VMs and PMs */
static long host_get_ramsize(sg_host_t vm, int *overcommit)
{
s_vm_params_t params;
return params.ramsize;
}
-/* **** start a VM **** */
-void SIMIX_vm_start(sg_host_t vm)
-{
- sg_host_t pm = static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->getPm();
-
- simgrid::vm::VmHostExt::ensureVmExtInstalled();
- if (pm->extension<simgrid::vm::VmHostExt>() == nullptr)
- pm->extension_set(new simgrid::vm::VmHostExt());
-
- long pm_ramsize = pm->extension<simgrid::vm::VmHostExt>()->ramsize;
- int pm_overcommit = pm->extension<simgrid::vm::VmHostExt>()->overcommit;
- long vm_ramsize = host_get_ramsize(vm, nullptr);
-
- if (pm_ramsize && !pm_overcommit) { /* Only verify that we don't overcommit on need */
- /* Retrieve the memory occupied by the VMs on that host. Yep, we have to traverse all VMs of all hosts for that */
- long total_ramsize_of_vms = 0;
- for (simgrid::s4u::VirtualMachine* ws_vm : simgrid::surf::VirtualMachineImpl::allVms_)
- if (pm == ws_vm->pimpl_vm_->getPm())
- total_ramsize_of_vms += ws_vm->pimpl_vm_->getRamsize();
-
- 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).",
- sg_host_get_name(vm), sg_host_get_name(pm), vm_ramsize, pm_ramsize - total_ramsize_of_vms, pm_ramsize);
- THROWF(vm_error, 0, "The VM %s cannot be started", vm->name().c_str());
- }
- }
-
- static_cast<simgrid::s4u::VirtualMachine*>(vm)->pimpl_vm_->setState(SURF_VM_STATE_RUNNING);
-}
-
/**
* @brief Function to suspend a SIMIX VM host. This function stops the execution of the
* VM. All the processes on this VM will pause. The state of the VM is