X-Git-Url: http://bilbo.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/55ff61a313ebbe8195ca80dcb61697b47f59d98f..17c819afc4ceda4000eec137c8fee35168253b4d:/src/plugins/vm/s4u_VirtualMachine.cpp diff --git a/src/plugins/vm/s4u_VirtualMachine.cpp b/src/plugins/vm/s4u_VirtualMachine.cpp index 3ca10336ca..6f436a5459 100644 --- a/src/plugins/vm/s4u_VirtualMachine.cpp +++ b/src/plugins/vm/s4u_VirtualMachine.cpp @@ -1,4 +1,4 @@ -/* Copyright (c) 2015-2017. The SimGrid Team. All rights reserved. */ +/* Copyright (c) 2015-2018. The SimGrid Team. All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ @@ -9,10 +9,11 @@ #include "src/plugins/vm/VmHostExt.hpp" #include "src/simix/smx_host_private.hpp" #include "src/surf/cpu_cas01.hpp" -#include XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_vm, "S4U virtual machines"); +simgrid::xbt::signal simgrid::s4u::VirtualMachine::onVmShutdown; + namespace simgrid { namespace s4u { @@ -38,11 +39,13 @@ VirtualMachine::VirtualMachine(const char* name, s4u::Host* pm, int coreAmount, /* Make a process container */ extension_set(new simgrid::simix::Host()); - if (TRACE_msg_vm_is_enabled()) { - container_t host_container = instr::Container::byName(pm->getName()); + if (TRACE_vm_is_enabled()) { + container_t host_container = instr::Container::byName(pm->get_name()); new instr::Container(name, "MSG_VM", host_container); - instr::Container::byName(getName())->getState("MSG_VM_STATE")->addEntityValue("start", "0 0 1"); // start is blue - instr::Container::byName(getName())->getState("MSG_VM_STATE")->addEntityValue("suspend", "1 0 0"); // suspend is red + instr::Container::byName(get_name())->getState("MSG_VM_STATE")->addEntityValue("start", "0 0 1"); // start is blue + instr::Container::byName(get_name()) + ->getState("MSG_VM_STATE") + ->addEntityValue("suspend", "1 0 0"); // suspend is red } } @@ -50,7 +53,7 @@ VirtualMachine::~VirtualMachine() { onDestruction(*this); - XBT_DEBUG("destroy %s", getCname()); + XBT_DEBUG("destroy %s", get_cname()); /* FIXME: this is really strange that everything fails if the next line is removed. * This is as if we shared these data with the PM, which definitely should not be the case... @@ -63,17 +66,14 @@ VirtualMachine::~VirtualMachine() /* Don't free these things twice: they are the ones of my physical host */ pimpl_netpoint = nullptr; - if (TRACE_msg_vm_is_enabled()) { - container_t container = simgrid::instr::Container::byName(getName()); - container->removeFromParent(); - delete container; - } + if (TRACE_vm_is_enabled()) + simgrid::instr::Container::byName(get_name())->removeFromParent(); } void VirtualMachine::start() { - if (TRACE_msg_vm_is_enabled()) - simgrid::instr::Container::byName(getName())->getState("MSG_VM_STATE")->pushEvent("start"); + if (TRACE_vm_is_enabled()) + simgrid::instr::Container::byName(get_name())->getState("MSG_VM_STATE")->pushEvent("start"); simgrid::simix::kernelImmediate([this]() { simgrid::vm::VmHostExt::ensureVmExtInstalled(); @@ -95,46 +95,44 @@ void VirtualMachine::start() 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).", - this->getCname(), pm->getCname(), 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->getCname(), - this->getCname()); + this->get_cname(), pm->get_cname(), 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->get_cname(), + this->get_cname()); } } this->pimpl_vm_->setState(SURF_VM_STATE_RUNNING); }); - if (TRACE_msg_vm_is_enabled()) - simgrid::instr::Container::byName(getName())->getState("MSG_VM_STATE")->popEvent(); + if (TRACE_vm_is_enabled()) + simgrid::instr::Container::byName(get_name())->getState("MSG_VM_STATE")->popEvent(); } void VirtualMachine::suspend() { smx_actor_t issuer = SIMIX_process_self(); simgrid::simix::kernelImmediate([this, issuer]() { pimpl_vm_->suspend(issuer); }); - if (TRACE_msg_vm_is_enabled()) - simgrid::instr::Container::byName(getName())->getState("MSG_VM_STATE")->pushEvent("suspend"); + if (TRACE_vm_is_enabled()) + simgrid::instr::Container::byName(get_name())->getState("MSG_VM_STATE")->pushEvent("suspend"); XBT_DEBUG("vm_suspend done"); } void VirtualMachine::resume() { pimpl_vm_->resume(); - if (TRACE_msg_vm_is_enabled()) - simgrid::instr::Container::byName(getName())->getState("MSG_VM_STATE")->popEvent(); + if (TRACE_vm_is_enabled()) + simgrid::instr::Container::byName(get_name())->getState("MSG_VM_STATE")->popEvent(); } void VirtualMachine::shutdown() { smx_actor_t issuer = SIMIX_process_self(); simgrid::simix::kernelImmediate([this, issuer]() { pimpl_vm_->shutdown(issuer); }); + onVmShutdown(this); } void VirtualMachine::destroy() { - if (isMigrating()) - THROWF(vm_error, 0, "Cannot destroy VM '%s', which is migrating.", getCname()); - /* First, terminate all processes on the VM if necessary */ shutdown(); @@ -142,11 +140,6 @@ void VirtualMachine::destroy() Host::destroy(); } -bool VirtualMachine::isMigrating() -{ - return pimpl_vm_ && pimpl_vm_->isMigrating; -} - simgrid::s4u::Host* VirtualMachine::getPm() { return pimpl_vm_->getPm(); @@ -204,3 +197,111 @@ void VirtualMachine::setBound(double bound) } // namespace simgrid } // namespace s4u + +/* **************************** Public C interface *************************** */ + +/** @brief Create a new VM object with the default parameters + * A VM is treated as a host. The name of the VM must be unique among all hosts. + */ +sg_vm_t sg_vm_create_core(sg_host_t pm, const char* name) +{ + return sg_vm_create_multicore(pm, name, 1); +} +/** @brief Create a new VM object with the default parameters, but with a specified amount of cores + * A VM is treated as a host. The name of the VM must be unique among all hosts. + */ +sg_vm_t sg_vm_create_multicore(sg_host_t pm, const char* name, int coreAmount) +{ + xbt_assert(sg_host_by_name(name) == nullptr, + "Cannot create a VM named %s: this name is already used by an host or a VM", name); + + return new simgrid::s4u::VirtualMachine(name, pm, coreAmount); +} + +const char* sg_vm_get_name(sg_vm_t vm) +{ + return vm->get_cname(); +} + +/** @brief Get the physical host of a given VM. */ +sg_host_t sg_vm_get_pm(sg_vm_t vm) +{ + return vm->getPm(); +} + +void sg_vm_set_ramsize(sg_vm_t vm, size_t size) +{ + vm->setRamsize(size); +} + +size_t sg_vm_get_ramsize(sg_vm_t vm) +{ + return vm->getRamsize(); +} + +void sg_vm_set_bound(sg_vm_t vm, double bound) +{ + vm->setBound(bound); +} + +/** @brief Returns whether the given VM has just created, not running. */ +int sg_vm_is_created(sg_vm_t vm) +{ + return vm->getState() == SURF_VM_STATE_CREATED; +} + +/** @brief Returns whether the given VM is currently running */ +int sg_vm_is_running(sg_vm_t vm) +{ + return vm->getState() == SURF_VM_STATE_RUNNING; +} + +/** @brief Returns whether the given VM is currently suspended, not running. */ +int sg_vm_is_suspended(sg_vm_t vm) +{ + return vm->getState() == SURF_VM_STATE_SUSPENDED; +} + +/** @brief Start a vm (i.e., boot the guest operating system) + * If the VM cannot be started (because of memory over-provisioning), an exception is generated. + */ +void sg_vm_start(sg_vm_t vm) +{ + vm->start(); +} + +/** @brief Immediately suspend the execution of all processes within the given VM. + * + * This function stops the execution of the VM. All the processes on this VM + * will pause. The state of the VM is preserved. We can later resume it again. + * + * No suspension cost occurs. + */ +void sg_vm_suspend(sg_vm_t vm) +{ + vm->suspend(); +} + +/** @brief Resume the execution of the VM. All processes on the VM run again. + * No resume cost occurs. + */ +void sg_vm_resume(sg_vm_t vm) +{ + vm->resume(); +} + +/** @brief Immediately kills all processes within the given VM. + * Any memory that they allocated will be leaked, unless you used #MSG_process_on_exit(). + * + * No extra delay occurs. If you want to simulate this too, you want to use a #MSG_process_sleep(). + */ +void sg_vm_shutdown(sg_vm_t vm) +{ + vm->shutdown(); +} + +/** @brief Destroy a VM. Destroy the VM object from the simulation. */ +void sg_vm_destroy(sg_vm_t vm) +{ + vm->destroy(); +}