Revision 4697f1ee src/scheduler/src/sched/Scheduler.cc

View differences:

src/scheduler/src/sched/Scheduler.cc
472 472
    }
473 473

  
474 474
    //--------------------------------------------------------------------------
475
    //Add to each host the corresponding cluster template
476
    //--------------------------------------------------------------------------
477

  
478
    hpool->merge_clusters(clpool);
479

  
480
    //--------------------------------------------------------------------------
481 475
    //Cleans the cache and get the ACLs
482 476
    //--------------------------------------------------------------------------
483 477

  
......
513 507
 *  @param n_error number of requirement errors, incremented if needed
514 508
 *  @param n_fits number of hosts with capacity that fits the VM requirements
515 509
 *  @param n_matched number of hosts that fullfil VM sched_requirements
510
 *  @param n_cluster_matched number of hosts that fulfill VM sched_cluster_requirements
516 511
 *  @param error, string describing why the host is not valid
517 512
 *  @return true for a positive match
518 513
 */
519 514
static bool match_host(AclXML * acls, UserPoolXML * upool, VirtualMachineXML* vm,
520 515
    int vmem, int vcpu, vector<VectorAttribute *>& vpci, HostXML * host,
521
    int &n_auth, int& n_error, int &n_fits, int &n_matched, string &error)
516
    int &n_auth, int& n_error, int &n_fits, int &n_matched,
517
    int &n_cluster_matched, string &error)
522 518
{
523 519
    // -------------------------------------------------------------------------
524 520
    // Filter current Hosts for resched VMs
......
571 567
    n_auth++;
572 568

  
573 569
    // -------------------------------------------------------------------------
570
    // Check host clusters
571
    // -------------------------------------------------------------------------
572

  
573
    if (host->is_in_cluster(vm->get_match_clusters()) != true)
574
    {
575
        error = "Host is not in any of the filtered Clusters.";
576
        return false;
577
    }
578

  
579
    n_cluster_matched++;
580

  
581
    // -------------------------------------------------------------------------
574 582
    // Check host capacity
575 583
    // -------------------------------------------------------------------------
576 584
    if (host->test_capacity(vcpu, vmem, vpci, error) != true)
......
635 643
 *  @param n_error number of requirement errors, incremented if needed
636 644
 *  @param n_matched number of system ds that fullfil VM sched_requirements
637 645
 *  @param n_fits number of system ds with capacity that fits the VM requirements
646
 *  @param n_cluster_matched number of system ds that fulfill VM sched_cluster_requirements
638 647
 *  @param error, string describing why the host is not valid
639 648
 *  @return true for a positive match
640 649
 */
641 650
static bool match_system_ds(AclXML * acls, UserPoolXML * upool,
642 651
    VirtualMachineXML* vm, long long vdisk, DatastoreXML * ds, int& n_auth,
643
    int& n_error, int& n_fits, int &n_matched, string &error)
652
    int& n_error, int& n_fits, int &n_matched,
653
    int &n_cluster_matched, string &error)
644 654
{
645 655
    // -------------------------------------------------------------------------
646 656
    // Check if user is authorized
......
673 683
    n_auth++;
674 684

  
675 685
    // -------------------------------------------------------------------------
686
    // Check host clusters
687
    // -------------------------------------------------------------------------
688

  
689
    if (ds->is_in_cluster(vm->get_match_clusters()) != true)
690
    {
691
        error = "System DS is not in any of the filtered Clusters.";
692
        return false;
693
    }
694

  
695
    n_cluster_matched++;
696

  
697
    // -------------------------------------------------------------------------
676 698
    // Check datastore capacity for shared systems DS (non-shared will be
677 699
    // checked in a per host basis during dispatch). Resume actions do not
678 700
    // add to shared system DS usage, and are skipped also
......
720 742
}
721 743

  
722 744
/* -------------------------------------------------------------------------- */
745
/* -------------------------------------------------------------------------- */
746

  
747
/**
748
 *  Match clusters for this VM that:
749
 *    1. Meet user/automatic requirements
750
 *
751
 *  @param vm the virtual machine
752
 *  @param cluster to evaluate vm assignment
753
 *  @param n_error number of requirement errors
754
 *  @param n_matched number of clusters that fulfill VM sched_cluster_requirements
755
 *  @param error, string describing why the cluster is not valid
756
 *  @return true for a positive match
757
 */
758
static bool match_cluster(VirtualMachineXML* vm, ClusterXML * cluster,
759
        int& n_error, int &n_matched, string &error)
760
{
761
    // -------------------------------------------------------------------------
762
    // Evaluate VM requirements
763
    // -------------------------------------------------------------------------
764
    if (!vm->get_cluster_requirements().empty())
765
    {
766
        char * estr;
767
        bool   matched;
768

  
769
        if ( cluster->eval_bool(vm->get_cluster_requirements(), matched, &estr) != 0 )
770
        {
771
            ostringstream oss;
772

  
773
            n_error++;
774

  
775
            oss << "Error in SCHED_CLUSTER_REQUIREMENTS: '"
776
                << vm->get_cluster_requirements() << "', error: " << error;
777

  
778
            vm->log(oss.str());
779

  
780
            free(estr);
781
        }
782

  
783
        if (matched == false)
784
        {
785
            ostringstream oss;
786

  
787
            oss << "It does not fulfill SCHED_CLUSTER_REQUIREMENTS: "
788
                << vm->get_cluster_requirements();
789
            error = oss.str();
790

  
791
            return false;
792
        }
793
    }
794

  
795
    n_matched++;
796

  
797
    return true;
798
}
799

  
800
/* -------------------------------------------------------------------------- */
723 801

  
724 802
static void log_match(int vid, const string& msg)
725 803
{
......
747 825
    int n_auth;
748 826
    int n_error;
749 827
    int n_fits;
828
    int n_cluster_matched;
750 829

  
830
    ClusterXML * cluster;
751 831
    HostXML * host;
752 832
    DatastoreXML *ds;
753 833

  
754 834
    string m_error;
755 835

  
756 836
    map<int, ObjectXML*>::const_iterator  vm_it;
757
    map<int, ObjectXML*>::const_iterator  h_it;
837
    map<int, ObjectXML*>::const_iterator  obj_it;
758 838

  
759 839
    vector<SchedulerPolicy *>::iterator it;
760 840

  
761 841
    const map<int, ObjectXML*> pending_vms = vmpool->get_objects();
842
    const map<int, ObjectXML*> clusters    = clpool->get_objects();
762 843
    const map<int, ObjectXML*> hosts       = hpool->get_objects();
763 844
    const map<int, ObjectXML*> datastores  = dspool->get_objects();
764 845
    const map<int, ObjectXML*> users       = upool->get_objects();
765 846

  
766
    double total_match_time = 0;
767
    double total_rank_time = 0;
847
    double total_cl_match_time = 0;
848
    double total_host_match_time = 0;
849
    double total_host_rank_time = 0;
850
    double total_ds_match_time = 0;
851
    double total_ds_rank_time = 0;
768 852

  
769 853
    time_t stime = time(0);
770 854

  
......
804 888
        }
805 889

  
806 890
        // ---------------------------------------------------------------------
891
        // Match clusters for this VM.
892
        // ---------------------------------------------------------------------
893
        profile(true);
894

  
895
        for (obj_it=clusters.begin(); obj_it != clusters.end(); obj_it++)
896
        {
897
            cluster = static_cast<ClusterXML *>(obj_it->second);
898

  
899
            if (match_cluster(vm, cluster, n_error, n_matched, m_error))
900
            {
901
                vm->add_match_cluster(cluster->get_oid());
902

  
903
                n_resources++;
904
            }
905
            else
906
            {
907
                if ( n_error > 0 )
908
                {
909
                    log_match(vm->get_oid(), "Cannot schedule VM. " + m_error);
910
                    break;
911
                }
912
                else if (NebulaLog::log_level() >= Log::DDEBUG)
913
                {
914
                    ostringstream oss;
915
                    oss << "Hosts and System DS in Cluster "
916
                        << cluster->get_oid() << " discarded for VM "
917
                        << vm->get_oid() << ". " << m_error;
918

  
919
                    NebulaLog::log("SCHED", Log::DDEBUG, oss);
920
                }
921
            }
922
        }
923

  
924
        total_cl_match_time += profile(false);
925

  
926
        // ---------------------------------------------------------------------
927
        // Log scheduling errors to VM user if any
928
        // ---------------------------------------------------------------------
929

  
930
        if (n_resources == 0) //No clusters assigned, let's see why
931
        {
932
            // TODO
933
        }
934

  
935
        // ---------------------------------------------------------------------
807 936
        // Match hosts for this VM.
808 937
        // ---------------------------------------------------------------------
809 938
        profile(true);
810 939

  
811
        for (h_it=hosts.begin(); h_it != hosts.end(); h_it++)
940
        for (obj_it=hosts.begin(); obj_it != hosts.end(); obj_it++)
812 941
        {
813
            host = static_cast<HostXML *>(h_it->second);
942
            host = static_cast<HostXML *>(obj_it->second);
814 943

  
815 944
            if (match_host(acls, upool, vm, vm_memory, vm_cpu, vm_pci, host,
816
                    n_auth, n_error, n_fits, n_matched, m_error))
945
                    n_auth, n_error, n_fits, n_matched, n_cluster_matched, m_error))
817 946
            {
818 947
                vm->add_match_host(host->get_hid());
819 948

  
......
837 966
            }
838 967
        }
839 968

  
840
        total_match_time += profile(false);
969
        total_host_match_time += profile(false);
841 970

  
842 971
        // ---------------------------------------------------------------------
843 972
        // Log scheduling errors to VM user if any
......
855 984
                {
856 985
                    vm->log("User is not authorized to use any host");
857 986
                }
987
                else if (n_cluster_matched == 0)
988
                {
989
                    ostringstream oss;
990

  
991
                    oss << "No host meets capacity and SCHED_CLUSTER_REQUIREMENTS: "
992
                        << vm->get_cluster_requirements();
993

  
994
                    vm->log(oss.str());
995
                }
858 996
                else if (n_fits == 0)
859 997
                {
860 998
                    ostringstream oss;
......
893 1031

  
894 1032
        vm->sort_match_hosts();
895 1033

  
896
        total_rank_time += profile(false);
1034
        total_host_rank_time += profile(false);
897 1035

  
898 1036
        if (vm->is_resched())//Will use same system DS for migrations
899 1037
        {
......
906 1044
        // Match datastores for this VM
907 1045
        // ---------------------------------------------------------------------
908 1046

  
1047
        profile(true);
1048

  
909 1049
        n_resources = 0;
910 1050
        n_auth    = 0;
911 1051
        n_matched = 0;
912 1052
        n_error   = 0;
913 1053
        n_fits    = 0;
914 1054

  
915
        for (h_it=datastores.begin(); h_it != datastores.end(); h_it++)
1055
        for (obj_it=datastores.begin(); obj_it != datastores.end(); obj_it++)
916 1056
        {
917
            ds = static_cast<DatastoreXML *>(h_it->second);
1057
            ds = static_cast<DatastoreXML *>(obj_it->second);
918 1058

  
919 1059
            if (match_system_ds(acls, upool, vm, vm_disk, ds, n_auth, n_error,
920
                        n_fits, n_matched, m_error))
1060
                        n_fits, n_matched, n_cluster_matched, m_error))
921 1061
            {
922 1062
                vm->add_match_datastore(ds->get_oid());
923 1063

  
......
941 1081
            }
942 1082
        }
943 1083

  
1084
        total_ds_match_time += profile(false);
1085

  
944 1086
        // ---------------------------------------------------------------------
945 1087
        // Log scheduling errors to VM user if any
946 1088
        // ---------------------------------------------------------------------
......
965 1107
                    {
966 1108
                        vm->log("User is not authorized to use any system datastore");
967 1109
                    }
1110
                    else if (n_cluster_matched == 0)
1111
                    {
1112
                        ostringstream oss;
1113

  
1114
                        oss << "No system datastore meets capacity and "
1115
                            << "SCHED_CLUSTER_REQUIREMENTS: "
1116
                            << vm->get_cluster_requirements();
1117

  
1118
                        vm->log(oss.str());
1119
                    }
968 1120
                    else if (n_fits == 0)
969 1121
                    {
970 1122
                        ostringstream oss;
......
999 1151
        // Schedule matched datastores
1000 1152
        // ---------------------------------------------------------------------
1001 1153

  
1154
        profile(true);
1155

  
1002 1156
        for (it=ds_policies.begin() ; it != ds_policies.end() ; it++)
1003 1157
        {
1004 1158
            (*it)->schedule(vm);
1005 1159
        }
1006 1160

  
1007 1161
        vm->sort_match_datastores();
1162

  
1163
        total_ds_rank_time += profile(false);
1008 1164
    }
1009 1165

  
1010
    ostringstream oss;
1166
    if (NebulaLog::log_level() >= Log::DDEBUG)
1167
    {
1168
        ostringstream oss;
1011 1169

  
1012
    oss << "Match Making statistics:\n"
1013
        << "\tNumber of VMs: \t\t" << pending_vms.size() << endl
1014
        << "\tTotal time: \t\t" << one_util::float_to_str(time(0) - stime) << "s" << endl
1015
        << "\tTotal Match time: \t" << one_util::float_to_str(total_match_time) << "s" << endl
1016
        << "\tTotal Ranking time: \t" << one_util::float_to_str(total_rank_time) << "s";
1170
        oss << "Match Making statistics:\n"
1171
            << "\tNumber of VMs:            " << pending_vms.size() << endl
1172
            << "\tTotal time:               " << one_util::float_to_str(time(0) - stime) << "s" << endl
1173
            << "\tTotal Cluster Match time: " << one_util::float_to_str(total_cl_match_time) << "s" << endl
1174
            << "\tTotal Host Match time:    " << one_util::float_to_str(total_host_match_time) << "s" << endl
1175
            << "\tTotal Host Ranking time:  " << one_util::float_to_str(total_host_rank_time) << "s" << endl
1176
            << "\tTotal DS Match time:      " << one_util::float_to_str(total_ds_match_time) << "s" << endl
1177
            << "\tTotal DS Ranking time:    " << one_util::float_to_str(total_ds_rank_time) << "s" << endl;
1017 1178

  
1018
    NebulaLog::log("SCHED", Log::DDEBUG, oss);
1179
        NebulaLog::log("SCHED", Log::DDEBUG, oss);
1180
    }
1019 1181

  
1020 1182
    if (NebulaLog::log_level() >= Log::DDDEBUG)
1021 1183
    {

Also available in: Unified diff