From ba921164960e317a5abe7d54af203c57d6464bf6 Mon Sep 17 00:00:00 2001 From: "Ruben S. Montero" Date: Thu, 31 Oct 2013 14:59:37 +0100 Subject: [PATCH] fix dead-lock when deleting a host --- src/host/HostPool.cc | 6 ++---- src/im/InformationManager.cc | 34 ++++++++++++------------------ src/im/InformationManagerDriver.cc | 9 -------- src/rm/RequestManagerDelete.cc | 18 +++++++++++++++- 4 files changed, 33 insertions(+), 34 deletions(-) diff --git a/src/host/HostPool.cc b/src/host/HostPool.cc index 30da51da49..acfc064856 100644 --- a/src/host/HostPool.cc +++ b/src/host/HostPool.cc @@ -235,16 +235,14 @@ error_common: int HostPool::drop(int hid, string& error_msg) { - - Host * host; - - host = get(hid,true); + Host * host = get(hid,true); if (host == 0) { ostringstream oss; oss << "Could not get host " << hid; error_msg = oss.str(); + return -1; } diff --git a/src/im/InformationManager.cc b/src/im/InformationManager.cc index 8cb2ab2801..bc12c01d8d 100644 --- a/src/im/InformationManager.cc +++ b/src/im/InformationManager.cc @@ -176,36 +176,30 @@ void InformationManager::do_action(const string &action, void * arg) void InformationManager::stop_monitor(int hid) { - Host * host; - - const InformationManagerDriver * imd; - - ostringstream oss; - - host = hpool->get(hid,true); + Host * host = hpool->get(hid,true); if (host == 0) //Already deleted silently return { return; } - imd = get(host->get_im_mad()); + const InformationManagerDriver * imd = get(host->get_im_mad()); - if (imd == 0) + if (imd == 0) //No IM Driver to call, delete host. { - oss.str(""); - oss << "Could not find information driver " << host->get_im_mad(); - NebulaLog::log("InM",Log::ERROR,oss); + string error_str; - host->unlock(); - return; + hpool->drop(host, error_str); + + if (!error_str.empty()) + { + NebulaLog::log("InM", Log::ERROR, error_str); + } + } + else + { + imd->stop_monitor(hid, host->get_name()); } - - host->disable(); - - imd->stop_monitor(hid, host->get_name()); - - hpool->update(host); host->unlock(); } diff --git a/src/im/InformationManagerDriver.cc b/src/im/InformationManagerDriver.cc index 3509e3b368..a79cbe8fd0 100644 --- a/src/im/InformationManagerDriver.cc +++ b/src/im/InformationManagerDriver.cc @@ -295,13 +295,6 @@ void InformationManagerDriver::protocol(const string& message) const int rc; string error; - host = hpool->get(id,true); - - if ( host == 0 ) - { - goto error_host; - } - if (result != "SUCCESS") { ostringstream oss; @@ -315,8 +308,6 @@ void InformationManagerDriver::protocol(const string& message) const rc = hpool->drop(id, error); - host->unlock(); - if (rc != 0) { ostringstream oss; diff --git a/src/rm/RequestManagerDelete.cc b/src/rm/RequestManagerDelete.cc index a419f2ce86..bcd46047c0 100644 --- a/src/rm/RequestManagerDelete.cc +++ b/src/rm/RequestManagerDelete.cc @@ -146,9 +146,25 @@ int RequestManagerDelete::drop( int HostDelete::drop(int oid, PoolObjectSQL * object, string& error_msg) { - Nebula& nd = Nebula::instance(); + Nebula& nd = Nebula::instance(); InformationManager * im = nd.get_im(); + HostPool * hpool = nd.get_hpool(); + + Host* host = static_cast(object); + + if ( host->get_share_running_vms() > 0 ) + { + error_msg = "Can not remove a host with running VMs"; + return -1; + } + + host->disable(); + + hpool->update(host); + + host->unlock(); + im->trigger(InformationManager::STOPMONITOR, oid); return 0;