diff --git a/src/router/routerVMs.go b/src/router/routerVMs.go
index b989a0df814cca9353a63987b12e20650beebc29..1eb1b09b871f2c5a2cfccad9580f87e11b6e0dc6 100644
--- a/src/router/routerVMs.go
+++ b/src/router/routerVMs.go
@@ -101,7 +101,7 @@ func (r *RouterVMs)GetRebootableVMs(c echo.Context) error {
 // curl --cacert ca.pem -X GET https://localhost:1077/vms/edit -H "Authorization: Bearer <AccessToken>"
 func (r *RouterVMs)GetEditableVMs(c echo.Context) error {
     return r.performVMsList(c, caps.CAP_VM_EDIT_ANY, caps.CAP_VM_EDIT, func(vm vms.VM) bool {
-        return true
+        return !vm.IsRunning()
     })
 }
 
@@ -121,7 +121,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
         func(vm vms.VM) bool {
             // First, checks if the user is the VM's owner
             if vm.IsOwner(user.Email) {
-                return true
+                return !vm.IsRunning()
             } else {
                 // Then, checks that user has CAP_VM_SET_ACCESS and also that
                 // VM access has CAP_VM_SET_ACCESS set for the user
@@ -129,7 +129,7 @@ func (r *RouterVMs)GetEditableVMAccessVMs(c echo.Context) error {
                     capabilities, exists := vm.Access[user.Email]
                     if exists {
                         _, visible := capabilities[caps.CAP_VM_SET_ACCESS]
-                        return visible
+                        return visible && !vm.IsRunning()
                     } else {
                         return false
                     }
diff --git a/src/vms/vms.go b/src/vms/vms.go
index 68938686eee2516f6a34412692804c6f697a35e8..72d2891eddf7b65332f7051ff1437289167352a1 100644
--- a/src/vms/vms.go
+++ b/src/vms/vms.go
@@ -22,9 +22,9 @@ type (
     VMs struct {
         m map[string]VM
         dir string             // Base directory where VMs are stored
-        rwlock *sync.RWMutex   // RWlock to ensure the coherency of the map (m) of VMs
-        usedPorts [65536]bool  // Indicates which ports are used by the VMs
-        usedRAM int            // Used RAM by running VMs (in MB)
+        rwlock *sync.RWMutex   // RWlock to ensure the VMs' map (m) coherency
+        usedPorts [65536]bool  // Ports used by VMs
+        usedRAM int            // RAM used by running VMs (in MB)
     }
 )
 
@@ -129,13 +129,21 @@ func (vms *VMs)DeleteVM(vmID uuid.UUID) error {
         return err
     }
 
-    // Deletes the VM's files (and directories).
     vm.mutex.Lock()
+
+    if vm.IsRunning() {
+        vm.mutex.Unlock()
+        return errors.New("VM must be stopped")
+    }
+
+    // Deletes the VM's files (and directories).
     if err := vm.delete(); err != nil {
         vm.mutex.Unlock()
         return err
     }
+
     vm.mutex.Unlock()
+
     // Removes the VM from the map.
     delete(vms.m, vmID.String())
     return nil
@@ -172,6 +180,10 @@ func (vms *VMs)StartVM(vmID uuid.UUID) (int, string, error) {
         return 0, "", err
     }
 
+    if vm.IsRunning() {
+        return 0, "", errors.New("VM must be stopped")
+    }
+
     totalRAM, availRAM, err := utils.GetRAM()
     if err != nil {
         return -1, "", errors.New("Failed obtaining memory info: "+err.Error())
@@ -233,8 +245,13 @@ func (vms *VMs)KillVM(vmID uuid.UUID) error {
     }
 
     vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    if !vm.IsRunning() {
+        return errors.New("VM must be running")
+    }
+
     err = vm.kill()
-    vm.mutex.Unlock()
     return err
 }
 
@@ -249,8 +266,13 @@ func (vms *VMs)ShutdownVM(vmID uuid.UUID) error {
     }
 
     vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    if !vm.IsRunning() {
+        return errors.New("VM must be running")
+    }
+
     err = vm.shutdown()
-    vm.mutex.Unlock()
     return err
 }
 
@@ -265,8 +287,13 @@ func (vms *VMs)RebootVM(vmID uuid.UUID) error {
     }
 
     vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    if !vm.IsRunning() {
+        return errors.New("VM must be running")
+    }
+
     err = vm.reboot()
-    vm.mutex.Unlock()
     return err
 }
 
@@ -285,11 +312,21 @@ func (vms *VMs)IsTemplateUsed(templateID string) bool {
 
 // Edit a VM' specs: name, cpus, ram, nic
 func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, usbDevs []string) error {
+    vms.rwlock.Lock()
+    defer vms.rwlock.Unlock()
+
     vm, err := vms.getVMUnsafe(vmID)
     if err != nil {
         return err
     }
 
+    vm.mutex.Lock()
+    defer vm.mutex.Unlock()
+
+    if vm.IsRunning() {
+        return errors.New("VM must be stopped")
+    }
+
     // Only updates fields that have changed.
     if name != "" {
         vm.Name = name
@@ -311,11 +348,6 @@ func (vms *VMs)EditVM(vmID uuid.UUID, name string, cpus, ram int, nic NicType, u
         return err
     }
 
-    vm.mutex.Lock()
-    defer vm.mutex.Unlock()
-    vms.rwlock.Lock()
-    defer vms.rwlock.Unlock()
-
     if err = vms.updateVM(&vm); err != nil {
         return err
     }
@@ -343,6 +375,10 @@ func (vms *VMs)SetVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string, ne
     vm.mutex.Lock()
     defer vm.mutex.Unlock()
 
+    if vm.IsRunning() {
+        return errors.New("VM must be stopped")
+    }
+
     // First, check that the logged user is the VM's owner.
     if !vm.IsOwner(loggedUserEmail) {
         // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
@@ -378,6 +414,10 @@ func (vms *VMs)DeleteVMAccess(vmID uuid.UUID, loggedUserEmail, userEmail string)
     vm.mutex.Lock()
     defer vm.mutex.Unlock()
 
+    if vm.IsRunning() {
+        return errors.New("VM must be stopped")
+    }
+
     // First, check that the logged user is the VM's owner.
     if !vm.IsOwner(loggedUserEmail) {
         // Next, checks the logged user has VM_SET_ACCESS set in her/his VM access.
@@ -410,6 +450,10 @@ func (vms *VMs)ExportVMFiles(vm *VM, vmDir, tarGzFile string) error {
 
 // Imports files from a tar.gz archive into a VM's filesystem, in a specified directory.
 func (vms *VMs)ImportFilesToVM(vm *VM, tarGzFile, vmDir string) error {
+    if vm.IsRunning() {
+        return errors.New("VM must be stopped")
+    }
+
     // Marks the VM to copy from as being busy.
     if err := vms.setDiskBusy(vm); err != nil {
         return errors.New("Failed setting disk busy flag during VM files import: "+err.Error())