From 9d8ccd61c81ec706d4b8fa6d6ba68f19738e357d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn?= <cmartins@fdi.ucm.es>
Date: Wed, 27 Jun 2012 18:50:19 +0200
Subject: [PATCH] Bug #1316: Clean files when a stopped VM is deleted. Previous
 commit:dbefe6f only worked with shared DS

---
 include/DispatchManager.h        |  7 ++++
 include/TransferManager.h        | 19 +++++++++-
 src/dm/DispatchManagerActions.cc | 65 ++++++++++++++++++++------------
 src/tm/TransferManager.cc        | 62 ++++++++++++++++++++++--------
 4 files changed, 112 insertions(+), 41 deletions(-)

diff --git a/include/DispatchManager.h b/include/DispatchManager.h
index 9ac342c59d..54631501ff 100644
--- a/include/DispatchManager.h
+++ b/include/DispatchManager.h
@@ -302,6 +302,13 @@ private:
         const string &  action,
         void *          arg);
 
+    /**
+     * Called from finalize(). Releases the images and networks acquired by this
+     * vm, and unlocks it.
+     *   @param vm the VM
+     */
+    void finalize_cleanup(VirtualMachine * vm);
+
     //--------------------------------------------------------------------------
     // DM Actions associated with a VM state transition
     //--------------------------------------------------------------------------
diff --git a/include/TransferManager.h b/include/TransferManager.h
index 1b33323690..6b08f3d73b 100644
--- a/include/TransferManager.h
+++ b/include/TransferManager.h
@@ -53,6 +53,7 @@ public:
         EPILOG_STOP,
         EPILOG_DELETE,
         EPILOG_DELETE_PREVIOUS,
+        EPILOG_DELETE_STOP,
         CHECKPOINT,
         DRIVER_CANCEL,
         FINALIZE
@@ -239,7 +240,23 @@ private:
     /**
      *  This function starts the epilog_delete sequence
      */
-    void epilog_delete_action(int vid);
+    void epilog_delete_action(int vid)
+    {
+        epilog_delete_action(false, vid);
+    }
+
+    /**
+     *  This function starts the epilog_delete_stop sequence on the local host
+     */
+    void epilog_delete_stop_action(int vid)
+    {
+        epilog_delete_action(true, vid);
+    }
+
+    /**
+     *  This function starts the epilog_delete sequence
+     */
+    void epilog_delete_action(bool local, int vid);
 
     /**
      *  This function starts the epilog_delete sequence on the previous host
diff --git a/src/dm/DispatchManagerActions.cc b/src/dm/DispatchManagerActions.cc
index 4b5a1dd6bc..7484b1bb92 100644
--- a/src/dm/DispatchManagerActions.cc
+++ b/src/dm/DispatchManagerActions.cc
@@ -680,15 +680,43 @@ error:
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
+void DispatchManager::finalize_cleanup(VirtualMachine * vm)
+{
+    Template *    tmpl;
+
+    int uid;
+    int gid;
+
+    vm->release_network_leases();
+    vm->release_disk_images();
+
+    vm->set_exit_time(time(0));
+
+    vm->set_state(VirtualMachine::LCM_INIT);
+    vm->set_state(VirtualMachine::DONE);
+    vmpool->update(vm);
+
+    vm->log("DiM", Log::INFO, "New VM state is DONE.");
+
+    uid  = vm->get_uid();
+    gid  = vm->get_gid();
+    tmpl = vm->clone_template();
+
+    vm->unlock();
+
+    Quotas::vm_del(uid, gid, tmpl);
+
+    delete tmpl;
+}
+
+/* -------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+
 int DispatchManager::finalize(
     int vid)
 {
     VirtualMachine * vm;
     ostringstream oss;
-    Template *    tmpl;
-
-    int uid;
-    int gid;
 
     VirtualMachine::VmState state;
 
@@ -711,33 +739,20 @@ int DispatchManager::finalize(
     switch (state)
     {
         case VirtualMachine::SUSPENDED:
-        case VirtualMachine::STOPPED:
         case VirtualMachine::FAILED:
             tm->trigger(TransferManager::EPILOG_DELETE,vid);
+            finalize_cleanup(vm);
+        break;
+
+        case VirtualMachine::STOPPED:
+            tm->trigger(TransferManager::EPILOG_DELETE_STOP,vid);
+            finalize_cleanup(vm);
+        break;
 
         case VirtualMachine::INIT:
         case VirtualMachine::PENDING:
         case VirtualMachine::HOLD:
-            vm->release_network_leases();
-            vm->release_disk_images();
-
-            vm->set_exit_time(time(0));
-
-            vm->set_state(VirtualMachine::LCM_INIT);
-            vm->set_state(VirtualMachine::DONE);
-            vmpool->update(vm);
-
-            vm->log("DiM", Log::INFO, "New VM state is DONE.");
-
-            uid  = vm->get_uid();
-            gid  = vm->get_gid();
-            tmpl = vm->clone_template();
-
-            vm->unlock();
-
-            Quotas::vm_del(uid, gid, tmpl);
-
-            delete tmpl;
+            finalize_cleanup(vm);
         break;
 
         case VirtualMachine::ACTIVE:
diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc
index 2a40fb38ba..1862dbaf3b 100644
--- a/src/tm/TransferManager.cc
+++ b/src/tm/TransferManager.cc
@@ -107,6 +107,10 @@ void TransferManager::trigger(Actions action, int _vid)
         aname = "EPILOG_DELETE";
         break;
 
+    case EPILOG_DELETE_STOP:
+        aname = "EPILOG_DELETE_STOP";
+        break;
+
     case EPILOG_DELETE_PREVIOUS:
         aname = "EPILOG_DELETE_PREVIOUS";
         break;
@@ -171,6 +175,10 @@ void TransferManager::do_action(const string &action, void * arg)
     {
         epilog_delete_action(vid);
     }
+    else if (action == "EPILOG_DELETE_STOP")
+    {
+        epilog_delete_stop_action(vid);
+    }
     else if (action == "EPILOG_DELETE_PREVIOUS")
     {
         epilog_delete_previous_action(vid);
@@ -1033,11 +1041,10 @@ error_common:
     return;
 }
 
-
 /* -------------------------------------------------------------------------- */
 /* -------------------------------------------------------------------------- */
 
-void TransferManager::epilog_delete_action(int vid)
+void TransferManager::epilog_delete_action(bool local, int vid)
 {
     ofstream      xfr;
     ostringstream os;
@@ -1113,21 +1120,46 @@ void TransferManager::epilog_delete_action(int vid)
             continue;
         }
 
-        //DELETE tm_mad host:remote_system_dir/disk.i vmid dsid
-        xfr << "DELETE "
-            << tm_mad << " "
-            << vm->get_hostname() << ":"
-            << vm->get_remote_system_dir() << "/disk." << disk_id << " "
-            << vm->get_oid() << " "
-            << ds_id << endl;
+        if ( local )
+        {
+            //DELETE tm_mad fe:system_dir/disk.i vmid dsid
+            xfr << "DELETE "
+                << tm_mad << " "
+                << nd.get_nebula_hostname() << ":"
+                << vm->get_system_dir() << "/disk." << disk_id << " "
+                << vm->get_oid() << " "
+                << ds_id << endl;
+        }
+        else
+        {
+            //DELETE tm_mad host:remote_system_dir/disk.i vmid dsid
+            xfr << "DELETE "
+                << tm_mad << " "
+                << vm->get_hostname() << ":"
+                << vm->get_remote_system_dir() << "/disk." << disk_id << " "
+                << vm->get_oid() << " "
+                << ds_id << endl;
+        }
     }
 
-    //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0)
-    xfr << "DELETE " 
-        << system_tm_mad << " "
-        << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " "
-        << vm->get_oid() << " "
-        << "0";
+    if ( local )
+    {
+        //DELETE system_tm_mad fe:system_dir vmid dsid(=0)
+        xfr << "DELETE "
+            << system_tm_mad << " "
+            << nd.get_nebula_hostname() <<":"<< vm->get_system_dir() << " "
+            << vm->get_oid() << " "
+            << "0";
+    }
+    else
+    {
+        //DELETE system_tm_mad hostname:remote_system_dir vmid dsid(=0)
+        xfr << "DELETE "
+            << system_tm_mad << " "
+            << vm->get_hostname() <<":"<< vm->get_remote_system_dir() << " "
+            << vm->get_oid() << " "
+            << "0";
+    }
 
     xfr.close();