[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [OSSTEST PATCH 2/2] mg-allocate: allow alternatives



---
 mg-allocate |  124 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 101 insertions(+), 23 deletions(-)

diff --git a/mg-allocate b/mg-allocate
index 883746b..00182f7 100755
--- a/mg-allocate
+++ b/mg-allocate
@@ -5,6 +5,10 @@
 #                                     type=='S' means 'shared-host'
 #                                     share defaults to *
 #                                     - means deallocate
+#                                     name=option|option|... means
+#                                       any one of those options
+#                                     option={flag,flag...} means anything
+#                                       with all those flags
 
 # This is part of "osstest", an automated testing framework for Xen.
 # Copyright (C) 2009-2013 Citrix Inc.
@@ -58,15 +62,36 @@ sub parse_1res ($) {
     my $shareix= defined($4) ? $4+0 : '*';
     my $shareixcond = $shareix eq '*' ? '' : "AND shareix = $shareix";
 
-    return ($allocate, $restype, $resname, $shareix, $shareixcond);
+    my @resnames;
+    foreach my $option (split /\|/, $resname) {
+       if ($option =~ m/^\{(.*)\}$/) {
+           my $q = "SELECT resname FROM resources r WHERE restype = ?";
+           my @qa = ($restype);
+           die unless $restype eq 'host';
+           foreach my $flag (split /\,/, $1) {
+               $q .= "\n AND EXISTS (SELECT 1 FROM hostflags h".
+                   " WHERE h.hostname = r.resname AND h.hostflag = ?)";
+               push @qa, $flag;
+           }
+           my $hosts = $dbh_tests->selectcol_arrayref($q, {}, @qa);
+           logm("for $option possibilities are: @$hosts");
+           push @resnames, @$hosts;
+       } else {
+           push @resnames, $option;
+       }
+    }
+    logm("for $resname all possibilities are: @resnames") if @resnames!=1;
+    die "nothing for $resname" unless @resnames;
+
+    return [ map {
+               [ $allocate, $restype, $_, $shareix, $shareixcond ]
+            } @resnames ];
 }
 
-sub alloc_1res ($) {
-    my ($res) = @_;
+sub alloc_1rescand ($$) {
+    my ($res, $rescand) = @_;
+    my ($allocate, $restype, $resname, $shareix, $shareixcond) = @$rescand;
 
-    my ($allocate, $restype, $resname, $shareix, $shareixcond) =
-        parse_1res($res);
-    
     my $resq= $dbh_tests->prepare(<<END);
                 SELECT * FROM resources r
                          JOIN tasks t
@@ -184,22 +209,46 @@ END
         $got_shareix= $candrow->{shareix};
         $ok=1; last;
     }
-    return ($ok, $got_shareix);
+    return ($ok, { Allocate => $allocate,
+                  Shareix => $got_shareix,
+                  Info => "$resname ($restype/$resname/$got_shareix)"
+           });
+}
+
+sub alloc_1res ($) {
+    my ($res) = @_;
+
+    my $rescands = parse_1res($res);
+
+    foreach my $rescand (@$rescands) {
+       my @got = alloc_1rescand($res, $rescand);
+       return @got if $got[0];
+    }
+    return (0,undef);
+}
+
+sub loggot {
+    my @got = @_;
+    logm(($_->{Allocate} ? "ALLOCATED" : "DEALLOCATED").": ".$_->{Info})
+       foreach @got;
 }
 
 sub execute () {
+    my @got;
     db_retry($dbh_tests, \@all_lock_tables, sub {
 
         alloc_prep();
 
         my $allok=1;
+       @got = ();
         foreach my $res (@ARGV) {
-            my ($ok, $shareix) = alloc_1res($res);
+            my ($ok, $got) = alloc_1res($res);
             if (!$ok) {
                 logm("nothing available for $res, sorry");
                 $allok=0;
             } else {
-                logm("processed $res (shareix=$shareix)");
+                logm("processed $res (shareix=$got->{Shareix})");
+               push @got, $got;
             }
         }
 
@@ -207,31 +256,58 @@ sub execute () {
             die "allocation/deallocation unsuccessful\n";
         }
     });
+    loggot(@got);
     logm("done.");
 }
 
 our $duration; # seconds, undef means immediate ad-hoc
 
+sub showposs ($) {
+    my ($poss) = @_;
+    join ' + ', map { $_->{Reso} } @$poss;
+}
+
 sub plan () {
+    my @got;
     alloc_resources(sub {
         my ($plan) = @_;
 
-        my @reqlist;
+       @got = ();
+        my @possmatrix = ([]);
 
         foreach my $res (@ARGV) {
-            my ($allocate, $restype, $resname, $shareix, $shareixcond) =
-                parse_1res($res);
-            die "cannot plan deallocation" unless $allocate;
-            die "cannot plan individual shares" unless $shareix eq '*';
-
-            push @reqlist, {
-                Ident => "$res",
-                Reso => "$restype $resname",
-            };
+           my $rescands = parse_1res($res);
+           my @reqlist;
+           foreach my $rescand (@$rescands) {
+               my ($allocate, $restype, $resname, $shareix, $shareixcond) =
+                   @$rescand;
+               die "cannot plan deallocation" unless $allocate;
+               die "cannot plan individual shares" unless $shareix eq '*';
+               push @reqlist, {
+                   Ident => "$res",
+                   Reso => "$restype $resname",
+               };
+           }
+           @possmatrix = map {
+               my $possreqs = $_;
+               map { [ @$possreqs, $_ ] } @reqlist;
+           } @possmatrix;
         }
 
-        my $planned= plan_search
-            ($plan, sub { print " @_\n"; }, $duration, \@reqlist);
+       my $planned;
+       my @reqlist;
+       foreach my $poss (@possmatrix) {
+           my $tplanned= plan_search
+               ($plan, sub { print " @_\n"; }, $duration, $poss);
+           printf " possibility Start=%d %s\n",
+               $tplanned->{Start}, showposs($poss);
+           if (!$planned || $tplanned->{Start} < $planned->{Start}) {
+               $planned = $tplanned;
+               @reqlist = @$poss;
+           }
+       }
+       logm("best at $planned->{Start} is ".showposs(\@reqlist));
+       die unless $planned;
 
         my $allok=0;
         if (!$planned->{Start}) {
@@ -240,12 +316,13 @@ sub plan () {
             alloc_prep();
 
             foreach my $req (@reqlist) {
-                my ($ok, $shareix) = alloc_1res($req->{Ident});
+                my ($ok, $got) = alloc_1res($req->{Ident});
                 if (!$ok) {
                     logm("failed to allocate $req->{Ident}!");
                     $allok=0;
                 } else {
-                    $req->{GotShareix}= $shareix;
+                    $req->{GotShareix}= $got->{Shareix};
+                   push @got, $got;
                 }
             }
         }
@@ -275,6 +352,7 @@ sub plan () {
 
         return ($allok, { Bookings => \@bookings });
     });
+    loggot(@got);
 }
 
 while (@ARGV && $ARGV[0] =~ m/^[-0-9]/) {
-- 
1.7.10.4


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.