diff --git a/include/InformationManagerDriver.h b/include/InformationManagerDriver.h index 3d7593a234..8a83c64536 100644 --- a/include/InformationManagerDriver.h +++ b/include/InformationManagerDriver.h @@ -61,9 +61,11 @@ public: * Sends a monitor request to the MAD: "MONITOR ID HOSTNAME -" * @param oid the virtual machine id. * @param host the hostname + * @param ds_location DATASTORE_LOCATION for the host * @param update the remotes directory in host */ - void monitor(int oid, const string& host, bool update) const; + void monitor(int oid, const string& host, const string& ds_location, + bool update) const; private: /** diff --git a/include/Nebula.h b/include/Nebula.h index ce98100187..cde48d9c89 100644 --- a/include/Nebula.h +++ b/include/Nebula.h @@ -279,6 +279,33 @@ public: return var_location; }; + /** + * + * + */ + int get_ds_location(int cluster_id, string& dsloc) + { + if ( cluster_id != -1 ) + { + Cluster * cluster = clpool->get(cluster_id, true); + + if ( cluster == 0 ) + { + return -1; + } + + cluster->get_ds_location(dsloc); + + cluster->unlock(); + } + else + { + get_configuration_attribute("DATASTORE_LOCATION", dsloc); + } + + return 0; + } + /** * Returns the default vms location. When ONE_LOCATION is defined this path * points to $ONE_LOCATION/var/vms, otherwise it is /var/lib/one/vms. This diff --git a/src/datastore_mad/remotes/ceph/monitor b/src/datastore_mad/remotes/ceph/monitor index 406cc1c4ab..cf6e7aee18 100755 --- a/src/datastore_mad/remotes/ceph/monitor +++ b/src/datastore_mad/remotes/ceph/monitor @@ -79,6 +79,8 @@ EOF MONITOR_DATA=$(ssh_monitor_and_log $HOST "$MONITOR_SCRIPT" 2>&1) MONITOR_STATUS=$? +MONITOR_DATA="$MONITOR_DATA LN_TARGET=NONE CLONE_TARGET=SELF" + if [ "$MONITOR_STATUS" = "0" ]; then echo "$MONITOR_DATA" | tr ' ' '\n' else diff --git a/src/datastore_mad/remotes/dummy/monitor b/src/datastore_mad/remotes/dummy/monitor index a0bc478062..d8caa01cea 100755 --- a/src/datastore_mad/remotes/dummy/monitor +++ b/src/datastore_mad/remotes/dummy/monitor @@ -19,3 +19,5 @@ echo "USED_MB=9720" echo "TOTAL_MB=20480" echo "FREE_MB=20480" +echo "LN_TARGET=NONE" +echo "CLONE_TARTGET=SYSTEM" diff --git a/src/datastore_mad/remotes/fs/monitor b/src/datastore_mad/remotes/fs/monitor index 0fdcd36bb4..9acdfa2fda 100755 --- a/src/datastore_mad/remotes/fs/monitor +++ b/src/datastore_mad/remotes/fs/monitor @@ -40,13 +40,32 @@ ID=$2 XPATH="${DRIVER_PATH}/../xpath.rb -b $DRV_ACTION" -unset i XPATH_ELEMENTS +unset i j XPATH_ELEMENTS while IFS= read -r -d '' element; do XPATH_ELEMENTS[i++]="$element" -done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH) +done < <($XPATH /DS_DRIVER_ACTION_DATA/DATASTORE/TM_MAD \ + /DS_DRIVER_ACTION_DATA/DATASTORE/BASE_PATH) -BASE_PATH="${XPATH_ELEMENTS[0]}" +TM_MAD="${XPATH_ELEMENTS[j++]}" +BASE_PATH="${XPATH_ELEMENTS[j++]}" + +case $TM_MAD in + "ssh") + LN_TARGET="SYSTEM" + CLONE_TARGET="SYSTEM" + ;; + + "lvm_shared") + LN_TARGET="SYSTEM" + CLONE_TARGET="SYSTEM" + ;; + + *) #shared, qcow2 + LN_TARGET="NONE" + CLONE_TARGET="SYSTEM" + ;; +esac # ------------ Compute datastore usage ------------- @@ -62,6 +81,8 @@ MONITOR_DATA=$(cat <&1) MONITOR_STATUS=$? +MONITOR_DATA="$MONITOR_DATA LN_TARGET=NONE CLONE_TARGET=SELF" + if [ "$MONITOR_STATUS" = "0" ]; then echo "$MONITOR_DATA" | tr ' ' '\n' else diff --git a/src/datastore_mad/remotes/lvm/monitor b/src/datastore_mad/remotes/lvm/monitor index f431e09690..97d2844126 100755 --- a/src/datastore_mad/remotes/lvm/monitor +++ b/src/datastore_mad/remotes/lvm/monitor @@ -77,6 +77,8 @@ EOF MONITOR_DATA=$(ssh_monitor_and_log $HOST "$MONITOR_SCRIPT" 2>&1) MONITOR_STATUS=$? +MONITOR_DATA="$MONITOR_DATA LN_TARGET=NONE CLONE_TARGET=SELF" + if [ "$MONITOR_STATUS" = "0" ]; then echo "$MONITOR_DATA" | tr ' ' '\n' else diff --git a/src/datastore_mad/remotes/vmfs/monitor b/src/datastore_mad/remotes/vmfs/monitor index f88824d3c1..40c7cef011 100755 --- a/src/datastore_mad/remotes/vmfs/monitor +++ b/src/datastore_mad/remotes/vmfs/monitor @@ -78,6 +78,8 @@ EOF MONITOR_DATA=$(ssh_monitor_and_log $HOST "$MONITOR_SCRIPT" 2>&1) MONITOR_STATUS=$? +MONITOR_DATA="$MONITOR_DATA LN_TARGET=NONE CLONE_TARGET=SYSTEM" + if [ "$MONITOR_STATUS" = "0" ]; then echo "$MONITOR_DATA" | tr ' ' '\n' else diff --git a/src/im/InformationManager.cc b/src/im/InformationManager.cc index d29f1d143b..4a3a9d6825 100644 --- a/src/im/InformationManager.cc +++ b/src/im/InformationManager.cc @@ -16,6 +16,8 @@ #include "InformationManager.h" #include "NebulaLog.h" +#include "Cluster.h" +#include "Nebula.h" #include #include @@ -243,17 +245,33 @@ void InformationManager::timer_action() } else { + Nebula& nd = Nebula::instance(); bool update_remotes = false; + string name = host->get_name(); + int oid = host->get_oid(); + int cluster_id = host->get_cluster_id(); + + string dsloc; + //Force remotes update if the host has never been monitored. if (host->get_last_monitored() == 0) { update_remotes = true; } - imd->monitor(host->get_oid(),host->get_name(),update_remotes); - host->set_monitoring_state(); + + hpool->update(host); + + host->unlock(); + + if (nd.get_ds_location(cluster_id, dsloc) == -1) + { + continue; + } + + imd->monitor(oid, name, dsloc, update_remotes); } } else if (!host->isEnabled() && host->get_share_running_vms() == 0 ) @@ -262,12 +280,13 @@ void InformationManager::timer_action() // update the last_mon_time to rotate the Hosts returned by // HostPool::discover. We also update the monitoring values with // 0s - host->touch(true); - hpool->update_monitoring(host); - } - hpool->update(host); - host->unlock(); + hpool->update_monitoring(host); + + hpool->update(host); + + host->unlock(); + } } } diff --git a/src/im/InformationManagerDriver.cc b/src/im/InformationManagerDriver.cc index e6dd17e27e..e8c03afb82 100644 --- a/src/im/InformationManagerDriver.cc +++ b/src/im/InformationManagerDriver.cc @@ -28,11 +28,12 @@ void InformationManagerDriver::monitor(int oid, const string& host, + const string& dsloc, bool update) const { ostringstream os; - os << "MONITOR " << oid << " " << host << " " << update << endl; + os << "MONITOR " << oid << " " << host << " " << dsloc << " " << update << endl; write(os); } diff --git a/src/im_mad/collectd/OpenNebulaDriver.cc b/src/im_mad/collectd/OpenNebulaDriver.cc index 2d539a318a..99f14838ba 100644 --- a/src/im_mad/collectd/OpenNebulaDriver.cc +++ b/src/im_mad/collectd/OpenNebulaDriver.cc @@ -56,7 +56,7 @@ int OpenNebulaDriver::read_one(std::string& message) } while ( rc > 0 && c != '\n' ); - if (rc < 0) + if (rc <= 0) { return -1; } @@ -71,36 +71,42 @@ int OpenNebulaDriver::read_one(std::string& message) void OpenNebulaDriver::driver_loop() { + int rc; + while (true) { std::string message; - if (read_one(message) == 0) + rc = read_one(message); + + if ( rc == -1 ) //Error in select or read from OpenNebula, exit { - std::istringstream is(message); - std::string action; + break; + } - if ( is.good() ) - { - is >> action >> std::ws; - } - else - { - continue; - } + std::istringstream is(message); + std::string action; - if (action == "INIT") - { - write2one("INIT SUCCESS\n",13); - } - else if (action == "FINALIZE") - { - break; - } - else - { - driver_action(action, is); - } + if ( is.good() ) + { + is >> action >> std::ws; + } + else + { + continue; + } + + if (action == "INIT") + { + write2one("INIT SUCCESS\n",13); + } + else if (action == "FINALIZE") + { + break; + } + else + { + driver_action(action, is); } } } diff --git a/src/im_mad/collectd/collectd.cc b/src/im_mad/collectd/collectd.cc index 256392bdaa..c714acb7ab 100644 --- a/src/im_mad/collectd/collectd.cc +++ b/src/im_mad/collectd/collectd.cc @@ -19,6 +19,10 @@ #include #include #include +#include + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- static const char * usage = "\n collectd [-h] [-a address] [-p port] [-t threads] [-f flush]\n\n" @@ -31,8 +35,32 @@ static const char * usage = "\t-f\tInterval in seconds to flush collected information\n" "\t-t\tNumber of threads for the server\n"; +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + +extern "C" void * sig_thread(void *arg) +{ + // Wait for a SIGTERM or SIGINT signal & exit + sigset_t mask; + int signal; + + sigemptyset(&mask); + + sigaddset(&mask, SIGINT); + sigaddset(&mask, SIGTERM); + + sigwait(&mask, &signal); + + _exit(0); +} + +// ----------------------------------------------------------------------------- +// ----------------------------------------------------------------------------- + int main(int argc, char ** argv) { + sigset_t mask; + std::string address = "0.0.0.0"; int port = 4124; int threads = 50; @@ -79,7 +107,29 @@ int main(int argc, char ** argv) break; } + //-------------------------------------------------------------------------- + // Block all signals before creating server threads + //-------------------------------------------------------------------------- + sigfillset(&mask); + pthread_sigmask(SIG_BLOCK, &mask, NULL); + + // ------------------------------------------------------------------------- + //Handle SIGTERM and SIGQUIT in a specific thread + // ------------------------------------------------------------------------- + pthread_attr_t attr; + pthread_t id; + + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + pthread_create(&id, &attr, sig_thread, 0); + + pthread_attr_destroy(&attr); + + // ------------------------------------------------------------------------- + // Start the collector and server threads + // ------------------------------------------------------------------------- IMCollectorDriver collectd(address, port, threads, flush); if ( collectd.init_collector() != 0 ) diff --git a/src/im_mad/dummy/one_im_dummy.rb b/src/im_mad/dummy/one_im_dummy.rb index 60ed2bd1be..36c18a4cbf 100755 --- a/src/im_mad/dummy/one_im_dummy.rb +++ b/src/im_mad/dummy/one_im_dummy.rb @@ -48,7 +48,7 @@ class DummyInformationManager < OpenNebulaDriver end # Execute the sensor array in the remote host - def action_monitor(number, host, not_used) + def action_monitor(number, host, not_used1, not_used2) results = "HYPERVISOR=dummy\n" results << "HOSTNAME=#{host}\n" diff --git a/src/im_mad/im_exec/one_im_exec.rb b/src/im_mad/im_exec/one_im_exec.rb index 457ca09e0b..6fc40bc609 100755 --- a/src/im_mad/im_exec/one_im_exec.rb +++ b/src/im_mad/im_exec/one_im_exec.rb @@ -60,7 +60,7 @@ class InformationManagerDriver < OpenNebulaDriver end # Execute the run_probes in the remote host - def action_monitor(number, host, do_update) + def action_monitor(number, host, ds_location, do_update) if !action_is_local?(:MONITOR) if do_update == "1" || @options[:force_copy] @@ -81,7 +81,7 @@ class InformationManagerDriver < OpenNebulaDriver end end - do_action("#{@hypervisor} #{number} #{@collectd_port}", number, host, + do_action("#{@hypervisor} #{ds_location} #{@collectd_port}", number, host, :MONITOR, :script_name => 'run_probes', :base64 => true) end end diff --git a/src/im_mad/remotes/common.d/collectd-client.rb b/src/im_mad/remotes/common.d/collectd-client.rb index 3ebfb7f636..1dcb4d013c 100644 --- a/src/im_mad/remotes/common.d/collectd-client.rb +++ b/src/im_mad/remotes/common.d/collectd-client.rb @@ -28,7 +28,7 @@ TOTAL_HOSTS = 1000 SLEEP = 1 class CollectdClient - def initialize(hypervisor, number, host, port) + def initialize(hypervisor, number, host, port, probes_args) # Arguments @hypervisor = hypervisor @number = number.to_i @@ -41,7 +41,7 @@ class CollectdClient # Probes run_probes_cmd = File.join(DIRNAME, '..', "run_probes") - @run_probes_cmd = "#{run_probes_cmd} #{@hypervisor}-probes" + @run_probes_cmd = "#{run_probes_cmd} #{@hypervisor}-probes #{probes_args}" # Get last update @last_update = get_last_update @@ -125,11 +125,13 @@ class CollectdClient end end +#Arguments: hypervisor(0) ds_location(1) collectd_port(2) host_id(3) hostname(4) hypervisor = ARGV[0] -number = ARGV[1] +number = ARGV[3] port = ARGV[2] host = ENV['SSH_CLIENT'].split.first +probes_args= ARGV[1..-1].join(" ") -client = CollectdClient.new(hypervisor, number, host, port) +client = CollectdClient.new(hypervisor, number, host, port, probes_args) client.monitor diff --git a/src/im_mad/remotes/common.d/monitor_ds.sh b/src/im_mad/remotes/common.d/monitor_ds.sh index 2dbee75ea5..2c0e9eeb45 100755 --- a/src/im_mad/remotes/common.d/monitor_ds.sh +++ b/src/im_mad/remotes/common.d/monitor_ds.sh @@ -1,11 +1,8 @@ #!/bin/bash +#Arguments: hypervisor ds_location collectd_port host_id hostname HYPERVISOR=$1 - -# Harcoded value while the position of the parameter is not known -#DATASTORE_LOCATION=${2:-"/var/lib/one/datastores"} -DATASTORE_LOCATION="/var/lib/one/datastores" - +DATASTORE_LOCATION=${2:-"/var/lib/one/datastores"} LVM_VG_PREFIX="vg-one-" LVM_SIZE_CMD="sudo vgdisplay --separator : --units m -o vg_size,vg_free --nosuffix --noheadings -C" diff --git a/src/im_mad/remotes/run_probes b/src/im_mad/remotes/run_probes index 02508eedbb..68de615e15 100755 --- a/src/im_mad/remotes/run_probes +++ b/src/im_mad/remotes/run_probes @@ -16,6 +16,8 @@ # limitations under the License. # #--------------------------------------------------------------------------- # +#Arguments: hypervisor(0) ds_location(1) collectd_port(2) host_id(3) hostname(4) + source $(dirname $0)/../scripts_common.sh export LANG=C diff --git a/src/image/ImageManagerDriver.cc b/src/image/ImageManagerDriver.cc index 99248b1ccb..d5d4eedd69 100644 --- a/src/image/ImageManagerDriver.cc +++ b/src/image/ImageManagerDriver.cc @@ -663,12 +663,17 @@ void ImageManagerDriver::process_poll(Datastore* ds, const string &monitor_str) } long long total, free, used; + string ln_tgt, cl_tgt; monitor_data.get("TOTAL_MB", total); monitor_data.get("FREE_MB", free); monitor_data.get("USED_MB", used); + monitor_data.get("LN_TARGET", ln_tgt); + monitor_data.get("CLONE_TARGET", cl_tgt); ds->update_monitor(total, free, used); + ds->replace_template_attribute("LN_TARGET", ln_tgt); + ds->replace_template_attribute("CLONE_TARGET", cl_tgt); dspool->update(ds); diff --git a/src/rm/RequestManagerVirtualMachine.cc b/src/rm/RequestManagerVirtualMachine.cc index 79eb14e10f..321d1c8b62 100644 --- a/src/rm/RequestManagerVirtualMachine.cc +++ b/src/rm/RequestManagerVirtualMachine.cc @@ -351,26 +351,13 @@ int RequestManagerVirtualMachine::get_host_information( host->unlock(); - if ( cluster_id != -1 ) + if (nd.get_ds_location(cluster_id, ds_location) == -1) { - Cluster * cluster = nd.get_clpool()->get(cluster_id, true); + failure_response(NO_EXISTS, + get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), + att); - if ( cluster == 0 ) - { - failure_response(NO_EXISTS, - get_error(object_name(PoolObjectSQL::CLUSTER),cluster_id), - att); - - return -1; - } - - cluster->get_ds_location(ds_location); - - cluster->unlock(); - } - else //Default System DS - { - nd.get_configuration_attribute("DATASTORE_LOCATION", ds_location); + return -1; } return 0; diff --git a/src/vmm_mad/remotes/vmware/vi_driver.rb b/src/vmm_mad/remotes/vmware/vi_driver.rb index 3dad4b58c2..dc0c5f1516 100644 --- a/src/vmm_mad/remotes/vmware/vi_driver.rb +++ b/src/vmm_mad/remotes/vmware/vi_driver.rb @@ -371,7 +371,7 @@ class VIHost @net_tx = 0 if @net_tx.to_i < 0 # Check free datastore space - @free_ds_info = VIDriver::retrieve_free_ds_space(@host) + @free_ds_info = VIDriver::retrieve_free_ds(@host) end ######################################################################## @@ -398,8 +398,10 @@ class VIHost # Datastores @free_ds_info.each{|k,v| - str_info << "DS_#{k}_FREE_MB=" << v[:free_space] << "\n" - str_info << "DS_#{k}_TOTAL_MB=" << v[:capacity] << "\n" + used_space = v[:capacity].to_i - v[:free_space].to_i + str_info << "DS=[ID=#{k},USED_MB=#{used_space}," + str_info << "TOTAL_MB=#{v[:capacity]}," + str_info << "FREE_MB=#{v[:free_space]}]\n" } str_info.strip @@ -473,10 +475,11 @@ def self.retrieve_free_ds(host) free_ds_info=Hash.new hds.datastore.each{|ds| + free_ds_info[datastore_props[ds]['name']]=Hash.new free_ds_info[datastore_props[ds]['name']][:free_space] = - datastore_props[ds]['summary'].freeSpace + datastore_props[ds]['summary'].freeSpace.to_i / 1024 / 1024 free_ds_info[datastore_props[ds]['name']][:capacity] = - datastore_props[ds]['summary'].capacity + datastore_props[ds]['summary'].capacity.to_i / 1024 / 1024 } free_ds_info