[LON-CAPA-cvs] cvs: loncom /auth lonacc.pm lonauth.pm /interface domainprefs.pm /lonnet/perl lonnet.pm

raeburn raeburn at source.lon-capa.org
Mon Aug 8 21:35:31 EDT 2011


raeburn		Tue Aug  9 01:35:31 2011 EDT

  Modified files:              
    /loncom/interface	domainprefs.pm 
    /loncom/lonnet/perl	lonnet.pm 
    /loncom/auth	lonauth.pm lonacc.pm 
  Log:
  - Bug 6371.
    - Use of lonBalancer in Apache config file superceded by setting 
      loadbalancing in domain configuration.
    - More granularity available in load balancing:
       - Rules can be defined for users in domain, based on institutional
         affiliation (e.g., Faculty, Staff, Student etc.).
       - Rules for advanced user or author trump rules based on affiliation
       - Rules can also be set for users from other domain hosted by
         institution (i.e., multi-domain server set-ups)
       - Rules can also be set for users from other institutions.    
  
  
-------------- next part --------------
Index: loncom/interface/domainprefs.pm
diff -u loncom/interface/domainprefs.pm:1.149 loncom/interface/domainprefs.pm:1.150
--- loncom/interface/domainprefs.pm:1.149	Tue Aug  9 00:54:43 2011
+++ loncom/interface/domainprefs.pm	Tue Aug  9 01:35:18 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Handler to set domain-wide configuration settings
 #
-# $Id: domainprefs.pm,v 1.149 2011/08/09 00:54:43 raeburn Exp $
+# $Id: domainprefs.pm,v 1.150 2011/08/09 01:35:18 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -197,18 +197,22 @@
     if ( exists($env{'form.phase'}) ) {
         $phase = $env{'form.phase'};
     }
+    my %servers = &Apache::lonnet::internet_dom_servers($dom);
     my %domconfig =
       &Apache::lonnet::get_dom('configuration',['login','rolecolors',
                 'quotas','autoenroll','autoupdate','autocreate',
                 'directorysrch','usercreation','usermodification',
                 'contacts','defaults','scantron','coursecategories',
                 'serverstatuses','requestcourses','helpsettings',
-                'coursedefaults','usersessions'],$dom);
+                'coursedefaults','usersessions','loadbalancing'],$dom);
     my @prefs_order = ('rolecolors','login','defaults','quotas','autoenroll',
                        'autoupdate','autocreate','directorysrch','contacts',
                        'usercreation','usermodification','scantron',
                        'requestcourses','coursecategories','serverstatuses','helpsettings',
                        'coursedefaults','usersessions');
+    if (keys(%servers) > 1) {
+        push(@prefs_order,'loadbalancing');
+    }
     my %prefs = (
         'rolecolors' =>
                    { text => 'Default color schemes',
@@ -361,8 +365,17 @@
                              {col1 => "Hosting domain's own users elsewhere",
                               col2 => 'Rules'}],
                  },
+         'loadbalancing' =>
+                 {text  => 'Dedicated Load Balancer',
+                  help  => 'Domain_Configuration_Load_Balancing',
+                  header => [{col1 => 'Server',
+                              col2 => 'Default destinations',
+                              col3 => 'User affliation',
+                              col4 => 'Overrides'},
+                            ],
+                 },
     );
-    my %servers = &Apache::lonnet::internet_dom_servers($dom);
+    my $js;
     if (keys(%servers) > 1) {
         $prefs{'login'}  = { text   => 'Log-in page options',
                              help   => 'Domain_Configuration_Login_Page',
@@ -371,6 +384,10 @@
                                        {col1 => 'Log-in Page Items',
                                         col2 => ''}],
                            };
+        my ($othertitle,$usertypes,$types) =
+            &Apache::loncommon::sorted_inst_types($dom);
+
+        $js = &lonbalance_targets_js($dom,$types,\%servers); 
     }
     my @roles = ('student','coordinator','author','admin');
     my @actions = &Apache::loncommon::get_env_multiple('form.actions');
@@ -381,7 +398,7 @@
     if ($phase eq 'process') {
         &Apache::lonconfigsettings::make_changes($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,\@roles);
     } elsif ($phase eq 'display') {
-        &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname);
+        &Apache::lonconfigsettings::display_settings($r,$dom,$phase,$context,\@prefs_order,\%prefs,\%domconfig,$confname,$js);
     } else {
         if (keys(%domconfig) == 0) {
             my $primarylibserv = &Apache::lonnet::domain($dom,'primary');
@@ -465,6 +482,8 @@
         $output = &modify_coursedefaults($dom,%domconfig);
     } elsif ($action eq 'usersessions') {
         $output = &modify_usersessions($dom,%domconfig);
+    } elsif ($action eq 'loadbalancing') {
+        $output = &modify_loadbalancing($dom,%domconfig);
     }
     return $output;
 }
@@ -661,13 +680,22 @@
         }
         $output .= '</td>';
         if ($item->{'header'}->[0]->{'col3'}) {
-            $output .= '<td class="LC_right_item" valign="top">'.
-                       &mt($item->{'header'}->[0]->{'col3'});
+            if (defined($item->{'header'}->[0]->{'col4'})) {
+                $output .= '<td class="LC_left_item" valign="top">'.
+                            &mt($item->{'header'}->[0]->{'col3'});
+            } else {
+                $output .= '<td class="LC_right_item" valign="top">'.
+                           &mt($item->{'header'}->[0]->{'col3'});
+            }
             if ($action eq 'serverstatuses') {
                 $output .= '<br />(<tt>'.&mt('IP1,IP2 etc.').'</tt>)';
             }
             $output .= '</td>';
         }
+        if ($item->{'header'}->[0]->{'col4'}) {
+            $output .= '<td class="LC_right_item" valign="top">'.
+                       &mt($item->{'header'}->[0]->{'col4'});
+        }
         $output .= '</tr>';
         $rowtotal ++;
         if ($action eq 'login') {
@@ -691,6 +719,8 @@
             $output .= &print_serverstatuses($dom,$settings,\$rowtotal);
         } elsif ($action eq 'helpsettings') {
             $output .= &print_helpsettings('top',$dom,$confname,$settings,\$rowtotal);
+        } elsif ($action eq 'loadbalancing') {
+            $output .= &print_loadbalancing($dom,$settings,\$rowtotal);
         }
     }
     $output .= '
@@ -2315,12 +2345,12 @@
             $datatable .= &spares_row(\%servers,\%spareid,\%uniques,$rowtotal);
         } else {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.
-                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains this server.');
+                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains one server.');
         }
     } else {
         if (keys(%by_location) == 0) {
             $datatable .= '<tr'.$css_class.'><td colspan="2">'.
-                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains this institution.');
+                          &mt('Nothing to set here, as the cluster to which this domain belongs only contains one institution.');
         } else {
             my %lt = &usersession_titles();
             my $numinrow = 5;
@@ -2538,13 +2568,18 @@
                         $spareid{$lonhost}{'primary'} = $Apache::lonnet::spareid{'primary'};
                         $spareid{$lonhost}{'default'} = $Apache::lonnet::spareid{'default'};
                     } else {
-                        my %requested;
-                        $requested{'spareid'} = 'HASH';
-                        my %returnhash = &Apache::lonnet::get_remote_globals($lonhost,\%requested);
-                        my $spareshash = $returnhash{'spareid'};
-                        if (ref($spareshash) eq 'HASH') {
-                            $spareid{$lonhost}{'primary'} = $spareshash->{'primary'};
-                            $spareid{$lonhost}{'default'} = $spareshash->{'default'};
+                        my %what = (
+                             spareid => 1,
+                        );
+                        my ($result,$returnhash) = 
+                            &Apache::lonnet::get_remote_globals($lonhost,\%what);
+                        if ($result eq 'ok') { 
+                            if (ref($returnhash) eq 'HASH') {
+                                if (ref($returnhash->{'spareid'}) eq 'HASH') {
+                                    $spareid{$lonhost}{'primary'} = $returnhash->{'spareid'}->{'primary'};
+                                    $spareid{$lonhost}{'default'} = $returnhash->{'spareid'}->{'default'};
+                                }
+                            }
                         }
                     }
                 }
@@ -2585,8 +2620,17 @@
                                                    $spareid->{$server}{$type}[$i].
                                                    '</label></td>';
                             }
-                            $current{$type} .= '</tr></table>';
+                            my $rem = @spares%($numinrow);
+                            my $colsleft = $numinrow - $rem;
+                            if ($colsleft > 1 ) {
+                                $current{$type} .= '<td colspan="'.$colsleft.
+                                                   '" class="LC_left_item">'.
+                                                   ' </td>';
+                            } elsif ($colsleft == 1) {
+                                $current{$type} .= '<td class="LC_left_item"> </td>';
+                            }
                         }
+                        $current{$type} .= '</tr></table>';
                     }
                     if ($current{$type} eq '') {
                         $current{$type} = &mt('None specified');
@@ -2632,6 +2676,243 @@
     return $output;
 }
 
+sub print_loadbalancing {
+    my ($dom,$settings,$rowtotal) = @_;
+    my $primary_id = &Apache::lonnet::domain($dom,'primary');
+    my $intdom = &Apache::lonnet::internet_dom($primary_id);
+    my $numinrow = 1;
+    my $datatable;
+    my %servers = &Apache::lonnet::internet_dom_servers($dom);
+    my ($currbalancer,$currtargets,$currrules);
+    if (keys(%servers) > 1) {
+        if (ref($settings) eq 'HASH') {
+            $currbalancer = $settings->{'lonhost'};
+            $currtargets = $settings->{'targets'};
+            $currrules = $settings->{'rules'};
+        } else {
+            ($currbalancer,$currtargets) = 
+                &Apache::lonnet::get_lonbalancer_config(\%servers);
+        }
+    } else {
+        return;
+    }
+    my ($othertitle,$usertypes,$types) =
+        &Apache::loncommon::sorted_inst_types($dom);
+    my $rownum = 6;
+    if (ref($types) eq 'ARRAY') {
+        $rownum += scalar(@{$types});
+    }
+    my $css_class = 'class="LC_odd_row"';
+    my $targets_div_style = 'display: none';
+    my $disabled_div_style = 'display: block';
+    my $homedom_div_style = 'display: none';
+    $datatable = '<tr'.$css_class.'>'.
+                 '<td rowspan="'.$rownum.'" valign="top">'.
+                 '<p><select name="loadbalancing_lonhost" onchange="toggleTargets();">'."\n".
+                 '<option value=""';
+    if (($currbalancer eq '') || (!grep(/^\Q$currbalancer\E$/,keys(%servers)))) {
+        $datatable .= ' selected="selected"';
+    } else {
+        $targets_div_style = 'display: block';
+        $disabled_div_style = 'display: none';
+        if ($dom eq &Apache::lonnet::host_domain($currbalancer)) {
+            $homedom_div_style = 'display: block'; 
+        }
+    }
+    $datatable .= '>'.&mt('None').'</option>'."\n";
+    foreach my $lonhost (sort(keys(%servers))) {
+        my $selected;
+        if ($lonhost eq $currbalancer) {
+            $selected .= ' selected="selected"';
+        }
+        $datatable .= '<option value="'.$lonhost.'"'.$selected.'>'.$lonhost.'</option>'."\n";
+    }
+    $datatable .= '</select></p></td><td rowspan="'.$rownum.'" valign="top">'.
+                  '<div id="loadbalancing_disabled" style="'.$disabled_div_style.'">'.&mt('No dedicated Load Balancer').'</div>'."\n".
+                  '<div id="loadbalancing_targets" style="'.$targets_div_style.'">'.&mt('Offloads to:').'<br />';
+    my ($numspares, at spares) = &count_servers($currbalancer,%servers);
+    my @sparestypes = ('primary','default');
+    my %typetitles = &sparestype_titles();
+    foreach my $sparetype (@sparestypes) {
+        my $targettable;
+        for (my $i=0; $i<$numspares; $i++) {
+            my $checked;
+            if (ref($currtargets) eq 'HASH') {
+                if (ref($currtargets->{$sparetype}) eq 'ARRAY') {
+                    if (grep(/^\Q$spares[$i]\E$/,@{$currtargets->{$sparetype}})) {
+                        $checked = ' checked="checked"';
+                    }
+                }
+            }
+            my $chkboxval;
+            if (($currbalancer ne '') && (grep((/^\Q$currbalancer\E$/,keys(%servers))))) {
+                $chkboxval = $spares[$i];
+            }
+            $targettable .= '<td><label><input type="checkbox" name="loadbalancing_target_'.$sparetype.'"'.
+                      $checked.' value="'.$chkboxval.'" id="loadbalancing_target_'.$sparetype.'_'.$i.'" onclick="checkOffloads('."this,'$sparetype'".');" /><span id="loadbalancing_targettxt_'.$sparetype.'_'.$i.'"> '.$chkboxval.
+                      '</span></label></td>';
+            my $rem = $i%($numinrow);
+            if ($rem == 0) {
+                if ($i > 0) {
+                    $targettable .= '</tr>';
+                }
+                $targettable .= '<tr>';
+            }
+        }
+        if ($targettable ne '') {
+            my $rem = $numspares%($numinrow);
+            my $colsleft = $numinrow - $rem;
+            if ($colsleft > 1 ) {
+                $targettable .= '<td colspan="'.$colsleft.'" class="LC_left_item">'.
+                                ' </td>';
+            } elsif ($colsleft == 1) {
+                $targettable .= '<td class="LC_left_item"> </td>';
+            }
+            $datatable .=  '<i>'.$typetitles{$sparetype}.'</i><br />'.
+                           '<table><tr>'.$targettable.'</table><br />';
+        }
+    }
+    $datatable .= '</div></td></tr>'.
+                  &loadbalancing_rules($dom,$intdom,$currrules,$othertitle,
+                                       $usertypes,$types,\%servers,$currbalancer,
+                                       $targets_div_style,$homedom_div_style);
+    $$rowtotal += $rownum;
+    return $datatable;
+}
+
+sub loadbalancing_rules {
+    my ($dom,$intdom,$currrules,$othertitle,$usertypes,$types,$servers,
+        $currbalancer,$targets_div_style,$homedom_div_style) = @_;
+    my $output;
+    my ($alltypes,$othertypes,$titles) = 
+        &loadbalancing_titles($dom,$intdom,$usertypes,$types);
+    if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH'))  {
+        foreach my $type (@{$alltypes}) {
+            my $current;
+            if (ref($currrules) eq 'HASH') {
+                $current = $currrules->{$type};
+            }
+            if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
+                if ($dom ne &Apache::lonnet::host_domain($currbalancer)) {
+                    $current = '';
+                }
+            }
+            $output .= &loadbalance_rule_row($type,$titles->{$type},$current,
+                                             $servers,$currbalancer,$dom,
+                                             $targets_div_style,$homedom_div_style);
+        }
+    }
+    return $output;
+}
+
+sub loadbalancing_titles {
+    my ($dom,$intdom,$usertypes,$types) = @_;
+    my %othertypes = (
+           '_LC_adv'         => &mt('Advanced users from [_1]',$dom),
+           '_LC_author'      => &mt('Users from [_1] with author role',$dom),
+           '_LC_internetdom' => &mt('Users not from [_1], but from [_2]',$dom,$intdom),
+           '_LC_external'    => &mt('Users not from [_1]',$intdom),
+                     );
+    my @alltypes = ('_LC_adv','_LC_author','_LC_internetdom','_LC_external');
+    if (ref($types) eq 'ARRAY') {
+        unshift(@alltypes,@{$types},'default');
+    }
+    my %titles;
+    foreach my $type (@alltypes) {
+        if ($type =~ /^_LC_/) {
+            $titles{$type} = $othertypes{$type};
+        } elsif ($type eq 'default') {
+            $titles{$type} = &mt('All users from [_1]',$dom);
+            if (ref($types) eq 'ARRAY') {
+                if (@{$types} > 0) {
+                    $titles{$type} = &mt('Other users from [_1]',$dom);
+                }
+            }
+        } elsif (ref($usertypes) eq 'HASH') {
+            $titles{$type} = $usertypes->{$type};
+        }
+    }
+    return (\@alltypes,\%othertypes,\%titles);
+}
+
+sub loadbalance_rule_row {
+    my ($type,$title,$current,$servers,$currbalancer,$dom,$targets_div_style,
+        $homedom_div_style) = @_;
+    my @rulenames = ('default','homeserver');
+    my %ruletitles = &offloadtype_text();
+    if ($type eq '_LC_external') {
+        push(@rulenames,'externalbalancer');
+    } else {
+        push(@rulenames,'specific');
+    }
+    my $style = $targets_div_style;
+    if (($type eq '_LC_external') || ($type eq '_LC_internetdom')) {
+        $style = $homedom_div_style;
+    }
+    my $output = 
+        '<tr><td valign="top"><div id="balanceruletitle_'.$type.'" style="'.$style.'">'.$title.'</div></td>'."\n".
+        '<td><div id="balancerule_'.$type.'" style="'.$style.'">'."\n";
+    for (my $i=0; $i<@rulenames; $i++) {
+        my $rule = $rulenames[$i];
+        my ($checked,$extra);
+        if ($rulenames[$i] eq 'default') {
+            $rule = '';
+        }
+        if ($rulenames[$i] eq 'specific') {
+            if (ref($servers) eq 'HASH') {
+                my $default;
+                if (($current ne '') && (exists($servers->{$current}))) {
+                    $checked = ' checked="checked"';
+                }
+                unless ($checked) {
+                    $default = ' selected="selected"';
+                }
+                $extra = ': <select name="loadbalancing_singleserver_'.$type.
+                         '" id="loadbalancing_singleserver_'.$type.
+                         '" onchange="singleServerToggle('."'$type'".')">'."\n".
+                         '<option value=""'.$default.'></option>'."\n";
+                foreach my $lonhost (sort(keys(%{$servers}))) {
+                    next if ($lonhost eq $currbalancer);
+                    my $selected;
+                    if ($lonhost eq $current) {
+                        $selected = ' selected="selected"';
+                    }
+                    $extra .= '<option value="'.$lonhost.'"'.$selected.'>'.$lonhost.'</option>';
+                }
+                $extra .= '</select>';
+            }
+        } elsif ($rule eq $current) {
+            $checked = ' checked="checked"';
+        }
+        $output .= '<span class="LC_nobreak"><label>'.
+                   '<input type="radio" name="loadbalancing_rules_'.$type.
+                   '" id="loadbalancing_rules_'.$type.'_'.$i.'" value="'.
+                   $rule.'" onclick="balanceruleChange('."this.form,'$type'".
+                   ')"'.$checked.' /> '.$ruletitles{$rulenames[$i]}.
+                   '</label>'.$extra.'</span><br />'."\n";
+    }
+    $output .= '</div></td></tr>'."\n";
+    return $output;
+}
+
+sub offloadtype_text {
+    my %ruletitles = &Apache::lonlocal::texthash (
+           'default'          => 'Offloads to default destinations',
+           'homeserver'       => "Offloads to user's home server",
+           'externalbalancer' => "Offloads to Load Balancer in user's domain",
+           'specific'         => 'Offloads to specific server',
+    );
+    return %ruletitles;
+}
+
+sub sparestype_titles {
+    my %typestitles = &Apache::lonlocal::texthash (
+                          'primary' => 'primary',
+                          'default' => 'default',
+                      );
+    return %typestitles;
+}
+
 sub contact_titles {
     my %titles = &Apache::lonlocal::texthash (
                    'supportemail' => 'Support E-mail address',
@@ -7214,6 +7495,200 @@
     return $resulttext;
 }
 
+sub modify_loadbalancing {
+    my ($dom,%domconfig) = @_;
+    my $primary_id = &Apache::lonnet::domain($dom,'primary');
+    my $intdom = &Apache::lonnet::internet_dom($primary_id);
+    my ($othertitle,$usertypes,$types) =
+        &Apache::loncommon::sorted_inst_types($dom);
+    my %servers = &Apache::lonnet::internet_dom_servers($dom);
+    my @sparestypes = ('primary','default');
+    my %typetitles = &sparestype_titles();
+    my $resulttext;
+    if (keys(%servers) > 1) {
+        my ($currbalancer,$currtargets,$currrules);
+        if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+            $currbalancer = $domconfig{'loadbalancing'}{'lonhost'};
+            $currtargets = $domconfig{'loadbalancing'}{'targets'};
+            $currrules = $domconfig{'loadbalancing'}{'rules'};
+        } else {
+            ($currbalancer,$currtargets) = 
+                &Apache::lonnet::get_lonbalancer_config(\%servers);
+        }
+        my ($saveloadbalancing,%defaultshash,%changes);
+        my ($alltypes,$othertypes,$titles) =
+            &loadbalancing_titles($dom,$intdom,$usertypes,$types);
+        my %ruletitles = &offloadtype_text();
+        my $balancer = $env{'form.loadbalancing_lonhost'};
+        if (!$servers{$balancer}) {
+            undef($balancer);
+        }
+        if ($currbalancer ne $balancer) {
+            $changes{'lonhost'} = 1;
+        }
+        $defaultshash{'loadbalancing'}{'lonhost'} = $balancer;
+        if ($balancer ne '') {
+            unless (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+                $saveloadbalancing = 1;
+            }
+            foreach my $sparetype (@sparestypes) {
+                my @targets = &Apache::loncommon::get_env_multiple('form.loadbalancing_target_'.$sparetype);
+                foreach my $target (@targets) {
+                    my @offloadto;
+                    if (($servers{$target}) && ($target ne $balancer)) {
+                        if ($sparetype eq 'default') {
+                            if (ref($defaultshash{'loadbalancing'}{'targets'}{'primary'}) eq 'ARRAY') {
+                                next if (grep(/^\Q$target\E$/,@{$defaultshash{'loadbalancing'}{'targets'}{'primary'}}));
+                            }
+                        }
+                        unless(grep(/^\Q$target\E$/, at offloadto)) {
+                            push(@offloadto,$target);
+                        }
+                    }
+                    $defaultshash{'loadbalancing'}{'targets'}{$sparetype} = \@offloadto;
+                }
+            }
+        } else {
+            foreach my $sparetype (@sparestypes) {
+                $defaultshash{'loadbalancing'}{'targets'}{$sparetype} = [];
+            }
+        }
+        if (ref($currtargets) eq 'HASH') {
+            foreach my $sparetype (@sparestypes) {
+                if (ref($currtargets->{$sparetype}) eq 'ARRAY') {
+                    my @targetdiffs = &Apache::loncommon::compare_arrays($currtargets->{$sparetype},$defaultshash{'loadbalancing'}{'targets'}{$sparetype});
+                    if (@targetdiffs > 0) {
+                        $changes{'targets'} = 1;
+                    }
+                } elsif (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
+                    if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
+                        $changes{'targets'} = 1;
+                    }
+                }
+            }
+        } else {
+            foreach my $sparetype (@sparestypes) {
+                if (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
+                    if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
+                        $changes{'targets'} = 1;  
+                    }
+                }
+            }  
+        }
+        my $ishomedom;
+        if ($balancer ne '') {
+            if (&Apache::lonnet::host_domain($balancer) eq $dom) {
+                $ishomedom = 1;
+            }
+        }
+        if (ref($alltypes) eq 'ARRAY') {
+            foreach my $type (@{$alltypes}) {
+                my $rule;
+                if ($balancer ne '') {
+                    unless ((($type eq '_LC_external') || ($type eq '_LC_internetdom')) && 
+                         (!$ishomedom)) {
+                        $rule = $env{'form.loadbalancing_rules_'.$type};
+                    }
+                    if ($rule eq 'specific') {
+                        $rule = $env{'form.loadbalancing_singleserver_'.$type};
+                    }
+                }
+                $defaultshash{'loadbalancing'}{'rules'}{$type} = $rule;
+                if (ref($currrules) eq 'HASH') {
+                    if ($rule ne $currrules->{$type}) {
+                        $changes{'rules'}{$type} = 1;
+                    }
+                } elsif ($rule ne '') {
+                    $changes{'rules'}{$type} = 1;
+                }
+            }
+        }
+        my $nochgmsg = &mt('No changes made to Load Balancer settings.');
+        if ((keys(%changes) > 0) || ($saveloadbalancing)) {
+            my $putresult = &Apache::lonnet::put_dom('configuration',
+                                                     \%defaultshash,$dom);
+            if ($putresult eq 'ok') {
+                if (keys(%changes) > 0) {
+                    if ($changes{'lonhost'}) {
+                        if ($currbalancer ne '') {
+                            &Apache::lonnet::remote_devalidate_cache($currbalancer,'loadbalancing',$dom);
+                        }
+                        if ($balancer eq '') {
+                            $resulttext .= '<li>'.&mt('Load Balancing with dedicated server discontinued').'</li>'; 
+                        } else {
+                            &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
+                            $resulttext .= '<li>'.&mt('Dedicated Load Balancer server set to [_1]',$balancer);
+                        }
+                    } else {
+                        &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
+                    }
+                    if (($changes{'targets'}) && ($balancer ne '')) {
+                        my %offloadstr;
+                        foreach my $sparetype (@sparestypes) {
+                            if (ref($defaultshash{'loadbalancing'}{'targets'}{$sparetype}) eq 'ARRAY') {
+                                if (@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}} > 0) {
+                                    $offloadstr{$sparetype} = join(', ',@{$defaultshash{'loadbalancing'}{'targets'}{$sparetype}});
+                                }
+                            }
+                        }
+                        if (keys(%offloadstr) == 0) {
+                            $resulttext .= '<li>'.&mt("Servers to which Load Balance server offloads set to 'None', by default").'</li>';
+                        } else {
+                            my $showoffload;
+                            foreach my $sparetype (@sparestypes) {
+                                $showoffload .= '<i>'.$typetitles{$sparetype}.'</i>: ';
+                                if (defined($offloadstr{$sparetype})) {
+                                    $showoffload .= $offloadstr{$sparetype};
+                                } else {
+                                    $showoffload .= &mt('None');
+                                }
+                                $showoffload .= (' 'x3);
+                            }
+                            $resulttext .= '<li>'.&mt('By default, Load Balancer server set to offload to: [_1]',$showoffload).'</li>';
+                        }
+                    }
+                    if ((ref($changes{'rules'}) eq 'HASH') && ($balancer ne '')) {
+                        if ((ref($alltypes) eq 'ARRAY') && (ref($titles) eq 'HASH')) {
+                            foreach my $type (@{$alltypes}) {
+                                if ($changes{'rules'}{$type}) {
+                                    my $rule = $defaultshash{'loadbalancing'}{'rules'}{$type};
+                                    my $balancetext;
+                                    if ($rule eq '') {
+                                        $balancetext =  $ruletitles{'default'};
+                                    } elsif (($rule eq 'homeserver') || ($rule eq 'externalbalancer')) {
+                                        $balancetext =  $ruletitles{$rule};
+                                    } else {
+                                        $balancetext = &mt('offload to [_1]',$defaultshash{'loadbalancing'}{'rules'}{$type});
+                                    }
+                                    $resulttext .= '<li>'.&mt('Load Balancing for [_1] set to: [_2]',$titles->{$type},$balancetext).'</li>';     
+                                }
+                            }
+                        }
+                    }
+                    if ($resulttext ne '') {
+                        $resulttext = &mt('Changes made:').'<ul>'.$resulttext.'</ul>';
+                    } else {
+                        $resulttext = $nochgmsg;
+                    }
+                } else {
+                    $resulttext = $nochgmsg;
+                    if ($balancer ne '') {
+                        &Apache::lonnet::remote_devalidate_cache($balancer,'loadbalancing',$dom);
+                    }
+                }
+            } else {
+                $resulttext = '<span class="LC_error">'.
+                              &mt('An error occurred: [_1]',$putresult).'</span>';
+            }
+        } else {
+            $resulttext = $nochgmsg;
+        }
+    } else {
+        $resulttext =  &mt('Load Balancing unavailable as this domain only has one server.');
+    }
+    return $resulttext;
+}
+
 sub recurse_check {
     my ($chkcats,$categories,$depth,$name) = @_;
     if (ref($chkcats->[$depth]{$name}) eq 'ARRAY') {
@@ -7338,4 +7813,201 @@
            );
 }
 
+sub count_servers {
+    my ($currbalancer,%servers) = @_;
+    my (@spares,$numspares);
+    foreach my $lonhost (sort(keys(%servers))) {
+        next if ($currbalancer eq $lonhost);
+        push(@spares,$lonhost);
+    }
+    if ($currbalancer) {
+        $numspares = scalar(@spares);
+    } else {
+        $numspares = scalar(@spares) - 1;
+    }
+    return ($numspares, at spares);
+}
+
+sub lonbalance_targets_js {
+    my ($dom,$types,$servers) = @_;
+    my $select = &mt('Select');
+    my ($alltargets,$allishome,$allinsttypes, at alltypes);
+    if (ref($servers) eq 'HASH') {
+        $alltargets = join("','",sort(keys(%{$servers})));
+        my @homedoms;
+        foreach my $server (sort(keys(%{$servers}))) {
+            if (&Apache::lonnet::host_domain($server) eq $dom) {
+                push(@homedoms,'1');
+            } else {
+                push(@homedoms,'0');
+            }
+        }
+        $allishome = join("','", at homedoms);
+    }
+    if (ref($types) eq 'ARRAY') {
+        if (@{$types} > 0) {
+            @alltypes = @{$types};
+        }
+    }
+    push(@alltypes,'default','_LC_adv','_LC_author','_LC_internetdom','_LC_external');
+    $allinsttypes = join("','", at alltypes);
+    return <<"END";
+
+<script type="text/javascript">
+// <![CDATA[
+
+function toggleTargets() {
+    var balancer = document.display.loadbalancing_lonhost.options[document.display.loadbalancing_lonhost.selectedIndex].value;
+    if (balancer == '') {
+        hideSpares();
+    } else {
+        var homedoms = new Array('$allishome');
+        var ishomedom = homedoms[document.display.loadbalancing_lonhost.selectedIndex];
+        showSpares(balancer,ishomedom);
+    }
+    return;
+}
+
+function showSpares(balancer,ishomedom) {
+    var alltargets = new Array('$alltargets');
+    var insttypes = new Array('$allinsttypes');
+    document.getElementById('loadbalancing_targets').style.display='block';
+    document.getElementById('loadbalancing_disabled').style.display='none';
+    var count = 0;
+    for (var i=0; i<alltargets.length; i++) {
+        if (alltargets[i] != balancer) {
+
+            document.getElementById('loadbalancing_target_'+count).value = alltargets[i];
+            document.getElementById('loadbalancing_targettxt_'+count).style.textAlign='left';
+            document.getElementById('loadbalancing_targettxt_'+count).style.textFace='normal';
+            document.getElementById('loadbalancing_targettxt_'+count).innerHTML = alltargets[i];
+
+            count ++;
+        }
+    }
+    for (var j=0; j<insttypes.length; j++) {
+        if ((insttypes[j] == '_LC_external') || (insttypes[j] == '_LC_internetdom')) {
+            if (ishomedom == 1) {
+                document.getElementById('balanceruletitle_'+insttypes[j]).style.display='block';
+                document.getElementById('balancerule_'+insttypes[j]).style.display='block';
+            } else {
+                document.getElementById('balanceruletitle_'+insttypes[j]).style.display='none';
+                document.getElementById('balancerule_'+insttypes[j]).style.display='none';
+
+            }
+        } else {
+            document.getElementById('balanceruletitle_'+insttypes[j]).style.display='block';
+            document.getElementById('balancerule_'+insttypes[j]).style.display='block';
+        }
+        if ((insttypes[j] != '_LC_external') && 
+            ((insttypes[j] != '_LC_internetdom') ||
+             ((insttypes[j] == '_LC_internetdom') && (homedom == 1)))) {
+            document.getElementById('loadbalancing_singleserver_'+insttypes[j]).options[0] = new Option("","",true,true);
+            for (var k=0; k<alltargets.length; k++) {
+                var idx = k+1;
+                if (alltargets[k] != balancer) {
+                    document.getElementById('loadbalancing_singleserver_'+insttypes[j]).options[idx] = new Option(alltargets[k],alltargets[k],false,false);
+                }
+            }
+        }
+    }
+    return;
+}
+
+function hideSpares() {
+    var alltargets = new Array('$alltargets');
+    var insttypes = new Array('$allinsttypes');
+    var offloadtypes = new Array('primary','default');
+
+    document.getElementById('loadbalancing_targets').style.display='none';
+    document.getElementById('loadbalancing_disabled').style.display='block';
+
+    var total = alltargets.length - 1;
+    for (var i=0; i<offloadtypes; i++) {
+        for (var j=0; j<total; j++) {
+           document.getElementById('loadbalancing_target_'+offloadtypes[i]+'_'+j).checked = false;
+           document.getElementById('loadbalancing_target_'+offloadtypes[i]+'_'+j).value = '';
+           document.getElementById('loadbalancing_targettxt_'+offloadtypes[i]+'_'+j).innerHTML = '';
+    }
+    for (var k=0; k<insttypes.length; k++) {
+        document.getElementById('balanceruletitle_'+insttypes[j]).style.display='none';
+        document.getElementById('balancerule_'+insttypes[j]).style.display='none';
+        if (insttypes[j] != '_LC_external') {
+            document.getElementById('loadbalancing_singleserver_'+insttypes[j]).length = 0;
+            document.getElementById('loadbalancing_singleserver_'+insttypes[j]).options[0] = new Option("","",true,true);
+        }
+    }
+    return;
+}
+
+function checkOffloads(item,type) {
+    var alltargets = new Array('$alltargets');
+    var offloadtypes = new Array('primary','default');
+    if (item.checked) {
+        var total = alltargets.length - 1;
+        var other;
+        if (type == offloadtypes[0]) {
+            other = offoadtypes[1];
+        } else {
+            other = offoadtypes[0];
+        }
+        for (var i=0; i<total; i++) {
+            var server = document.getElementById('loadbalancing_target_'+other+'_'+i).value;
+            if (server == item.value) {
+                if (document.getElementById('loadbalancing_target_'+other+'_'+i).checked) {
+                    document.getElementById('loadbalancing_target_'+other+'_'+i).checked = false;
+                }
+            }
+        }
+    }
+    return;
+}
+
+function singleServerToggle(type) {
+    var offloadtoSelIdx = document.getElementById('loadbalancing_singleserver_'+type).selectedIndex;
+    if (offloadtoSelIdx == 0) {
+        document.getElementById('loadbalancing_rules_'+type+'_0').checked = true;
+        document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '';
+
+    } else {
+        document.getElementById('loadbalancing_rules_'+type+'_2').checked = true;
+        document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '$select';
+    }
+    return;
+}
+
+function balanceruleChange(formname,type) {
+    if (type == '_LC_external') {
+        return; 
+    }
+    var typesRules = getIndicesByName(formname,'loadbalancing_rules_'+type);
+    for (var i=0; i<typesRules.length; i++) {
+        if (formname.elements[typesRules[i]].checked) {
+            if (formname.elements[typesRules[i]].value != 'specific') {
+                document.getElementById('loadbalancing_singleserver_'+type).selectedIndex = 0;
+                document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '';
+            } else {
+                document.getElementById('loadbalancing_singleserver_'+type).options[0].text = '$select';
+            }
+        }
+    }
+    return;
+}
+
+function getIndicesByName(formname,item) {
+    var radiogroup = new Array(); 
+    for (var i=0;i<formname.elements.length;i++) {
+        if (formname.elements[i].name == item) {
+            radiogroup.push(formname.elements[i].id);
+        }
+    }
+    return radiogroup; 
+}
+
+// ]]>
+</script>
+
+END
+}
+
 1;
Index: loncom/lonnet/perl/lonnet.pm
diff -u loncom/lonnet/perl/lonnet.pm:1.1128 loncom/lonnet/perl/lonnet.pm:1.1129
--- loncom/lonnet/perl/lonnet.pm:1.1128	Tue Aug  9 01:06:33 2011
+++ loncom/lonnet/perl/lonnet.pm	Tue Aug  9 01:35:24 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # TCP networking package
 #
-# $Id: lonnet.pm,v 1.1128 2011/08/09 01:06:33 raeburn Exp $
+# $Id: lonnet.pm,v 1.1129 2011/08/09 01:35:24 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -1185,6 +1185,224 @@
     return;
 }
 
+sub get_lonbalancer_config {
+    my ($servers) = @_;
+    my ($currbalancer,$currtargets);
+    if (ref($servers) eq 'HASH') {
+        foreach my $server (keys(%{$servers})) {
+            my %what = (
+                         spareid => 1,
+                         perlvar => 1,
+                       );
+            my ($result,$returnhash) = &get_remote_globals($server,\%what);
+            if ($result eq 'ok') {
+                if (ref($returnhash) eq 'HASH') {
+                    if (ref($returnhash->{'perlvar'}) eq 'HASH') {
+                        if ($returnhash->{'perlvar'}->{'lonBalancer'} eq 'yes') {
+                            $currbalancer = $server;
+                            $currtargets = {};
+                            if (ref($returnhash->{'spareid'}) eq 'HASH') {
+                                if (ref($returnhash->{'spareid'}->{'primary'}) eq 'ARRAY') {
+                                    $currtargets->{'primary'} = $returnhash->{'spareid'}->{'primary'};
+                                }
+                                if (ref($returnhash->{'spareid'}->{'default'}) eq 'ARRAY') {
+                                    $currtargets->{'default'} = $returnhash->{'spareid'}->{'default'};
+                                }
+                            }
+                            last;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return ($currbalancer,$currtargets);
+}
+
+sub check_loadbalancing {
+    my ($uname,$udom) = @_;
+    my ($is_balancer,$dom_in_use,$homeintdom,$rule_in_effect,
+        $offloadto,$otherserver);
+    my $lonhost = $perlvar{'lonHostID'};
+    my $uprimary_id = &Apache::lonnet::domain($udom,'primary');
+    my $uintdom = &Apache::lonnet::internet_dom($uprimary_id);
+    my $intdom = &Apache::lonnet::internet_dom($lonhost);
+    my $serverhomedom = &host_domain($lonhost);
+
+    my $cachetime = 60*60*24;
+
+    if (($uintdom ne '') && ($uintdom eq $intdom)) {
+        $dom_in_use = $udom;
+        $homeintdom = 1;
+    } else {
+        $dom_in_use = $serverhomedom;
+    }
+    my ($result,$cached)=&is_cached_new('loadbalancing',$dom_in_use);
+    unless (defined($cached)) {
+        my %domconfig =
+            &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use);
+        if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+            $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'usersessions'}{'loadbalancing'},$cachetime);
+        }
+    }
+    if (ref($result) eq 'HASH') {
+        my $currbalancer = $result->{'lonhost'};
+        my $currtargets = $result->{'targets'};
+        my $currrules = $result->{'rules'};
+        if ($currbalancer ne '') {
+            my @hosts = &current_machine_ids();
+            if (grep(/^\Q$currbalancer\E$/, at hosts)) {
+                $is_balancer = 1;
+            }
+        }
+        if ($is_balancer) {
+            if (ref($currrules) eq 'HASH') {
+                if ($homeintdom) {
+                    if ($uname ne '') {
+                        if (($currrules->{'_LC_adv'} ne '') || ($currrules->{'_LC_author'} ne '')) {
+                            my ($is_adv,$is_author) = &is_advanced_user($udom,$uname);
+                            if (($currrules->{'_LC_author'} ne '') && ($is_author)) {
+                                $rule_in_effect = $currrules->{'_LC_author'};
+                            } elsif (($currrules->{'_LC_adv'} ne '') && ($is_adv)) {
+                                $rule_in_effect = $currrules->{'_LC_adv'}
+                            }
+                        }
+                        if ($rule_in_effect eq '') {
+                            my %userenv = &userenvironment($udom,$uname,'inststatus');
+                            if ($userenv{'inststatus'} ne '') {
+                                my @statuses = map { &unescape($_); } split(/:/,$userenv{'inststatus'});
+                                my ($othertitle,$usertypes,$types) =
+                                    &Apache::loncommon::sorted_inst_types($udom);
+                                if (ref($types) eq 'ARRAY') {
+                                    foreach my $type (@{$types}) {
+                                        if (grep(/^\Q$type\E$/, at statuses)) {
+                                            if (exists($currrules->{$type})) {
+                                                $rule_in_effect = $currrules->{$type};
+                                            }
+                                        }
+                                    }
+                                }
+                            } else {
+                                if (exists($currrules->{'default'})) {
+                                    $rule_in_effect = $currrules->{'default'};
+                                }
+                            }
+                        }
+                    } else {
+                        if (exists($currrules->{'default'})) {
+                            $rule_in_effect = $currrules->{'default'};
+                        }
+                    }
+                } else {
+                    if ($currrules->{'_LC_external'} ne '') {
+                        $rule_in_effect = $currrules->{'_LC_external'};
+                    }
+                }
+                $offloadto = &get_loadbalancer_targets($rule_in_effect,$currtargets,
+                                                       $uname,$udom);
+            }
+        }
+    } elsif (($homeintdom) && ($udom ne $serverhomedom)) {
+        my ($result,$cached)=&is_cached_new('loadbalancing',$serverhomedom);
+        unless (defined($cached)) {
+            my %domconfig =
+                &Apache::lonnet::get_dom('configuration',['loadbalancing'],$serverhomedom);
+            if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+                $result = &do_cache_new('loadbalancing',$dom_in_use,$domconfig{'usersessions'}{'loadbalancing'},$cachetime);
+            }
+        }
+        if (ref($result) eq 'HASH') {
+            my $currbalancer = $result->{'lonhost'};
+            my $currtargets = $result->{'targets'};
+            my $currrules = $result->{'rules'};
+
+            if ($currbalancer eq $lonhost) {
+                $is_balancer = 1;
+                if (ref($currrules) eq 'HASH') {
+                    if ($currrules->{'_LC_internetdom'} ne '') {
+                        $rule_in_effect = $currrules->{'_LC_internetdom'};
+                    }
+                }
+                $offloadto = &get_loadbalancer_targets($rule_in_effect,$currtargets,
+                                                       $uname,$udom);
+            }
+        } else {
+            if ($perlvar{'lonBalancer'} eq 'yes') {
+                $is_balancer = 1;
+                $offloadto = &this_host_spares($dom_in_use);
+            }
+        }
+    } else {
+        if ($perlvar{'lonBalancer'} eq 'yes') {
+            $is_balancer = 1;
+            $offloadto = &this_host_spares($dom_in_use);
+        }
+    }
+    my $lowest_load = 30000;
+    if (ref($offloadto) eq 'HASH') {
+        if (ref($offloadto->{'primary'}) eq 'ARRAY') {
+            foreach my $try_server (@{$offloadto->{'primary'}}) {
+                ($otherserver,$lowest_load) =
+                    &compare_server_load($try_server,$otherserver,$lowest_load);
+            }
+        }
+        my $found_server = ($otherserver ne '' && $lowest_load < 100);
+
+        if (!$found_server) {
+            if (ref($offloadto->{'default'}) eq 'ARRAY') {
+                foreach my $try_server (@{$offloadto->{'default'}}) {
+                    ($otherserver,$lowest_load) =
+                        &compare_server_load($try_server,$otherserver,$lowest_load);
+                }
+            }
+        }
+    } elsif (ref($offloadto) eq 'ARRAY') {
+        if (@{$offloadto} == 1) {
+            $otherserver = $offloadto->[0];
+        } elsif (@{$offloadto} > 1) {
+            foreach my $try_server (@{$offloadto}) {
+                ($otherserver,$lowest_load) =
+                    &compare_server_load($try_server,$otherserver,$lowest_load);
+            }
+        }
+    }
+    return ($is_balancer,$otherserver);
+}
+
+sub get_loadbalancer_targets {
+    my ($rule_in_effect,$currtargets,$uname,$udom) = @_;
+    my $offloadto;
+    if ($rule_in_effect eq '') {
+        $offloadto = $currtargets;
+    } else {
+        if ($rule_in_effect eq 'homeserver') {
+            my $homeserver = &homeserver($uname,$udom);
+            if ($homeserver ne 'no_host') {
+                $offloadto = [$homeserver];
+            }
+        } elsif ($rule_in_effect eq 'externalbalancer') {
+            my %domconfig =
+                &Apache::lonnet::get_dom('configuration',['loadbalancing'],$udom);
+            if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
+                if ($domconfig{'loadbalancing'}{'lonhost'} ne '') {
+                    if (&hostname($domconfig{'loadbalancing'}{'lonhost'}) ne '') {
+                        $offloadto = [$domconfig{'loadbalancing'}{'lonhost'}];
+                    }
+                }
+            } else {
+                my %servers = &dom_servers($udom);
+                my ($remotebalancer,$remotetargets) = &get_lonbalancer_config(\%servers);
+                if (&hostname($remotebalancer) ne '') {
+                    $offloadto = [$remotebalancer];
+                }
+            }
+        } elsif (&hostname($rule_in_effect) ne '') {
+            $offloadto = [$rule_in_effect];
+        }
+    }
+    return $offloadto;
+}
+
 sub internet_dom_servers {
     my ($dom) = @_;
     my (%uniqservers,%servers);
Index: loncom/auth/lonauth.pm
diff -u loncom/auth/lonauth.pm:1.116 loncom/auth/lonauth.pm:1.117
--- loncom/auth/lonauth.pm:1.116	Tue Aug  9 01:27:42 2011
+++ loncom/auth/lonauth.pm	Tue Aug  9 01:35:31 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # User Authentication Module
 #
-# $Id: lonauth.pm,v 1.116 2011/08/09 01:27:42 raeburn Exp $
+# $Id: lonauth.pm,v 1.117 2011/08/09 01:35:31 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -415,8 +415,10 @@
 	}
     }
 
-    if ($r->dir_config("lonBalancer") eq 'yes') {
-        my $otherserver = &Apache::lonnet::spareserver(30000,undef,1,$form{'udom'});
+    my ($is_balancer,$otherserver) = 
+        &Apache::lonnet::check_loadbalancing($form{'uname'},$form{'udom'});
+
+    if ($is_balancer) {
         if (!$otherserver) { 
             ($otherserver) = &Apache::lonnet::choose_server($form{'udom'});
         }
Index: loncom/auth/lonacc.pm
diff -u loncom/auth/lonacc.pm:1.136 loncom/auth/lonacc.pm:1.137
--- loncom/auth/lonacc.pm:1.136	Mon Jun 13 02:44:36 2011
+++ loncom/auth/lonacc.pm	Tue Aug  9 01:35:31 2011
@@ -1,7 +1,7 @@
 # The LearningOnline Network
 # Cookie Based Access Handler
 #
-# $Id: lonacc.pm,v 1.136 2011/06/13 02:44:36 raeburn Exp $
+# $Id: lonacc.pm,v 1.137 2011/08/09 01:35:31 raeburn Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -297,7 +297,9 @@
     my $home=&Apache::lonnet::homeserver($user,$domain);
     if ($home !~ /(con_lost|no_host|no_such_host)/) {
 	&Apache::lonnet::logthis(" SSO authorized user $user ");
-	if ($r->dir_config("lonBalancer") eq 'yes') {
+        my ($is_balancer,$otherserver) =
+            &Apache::lonnet::check_loadbalancing($user,$domain);
+	if ($is_balancer) {
 	    # login but immediately go to switch server to find us a new 
 	    # machine
 	    &Apache::lonauth::success($r,$user,$domain,$home,'noredirect');
@@ -306,7 +308,11 @@
                 $env{'request.sso.reloginserver'} =
                     $r->dir_config('lonSSOReloginServer');
             }
-	    $r->internal_redirect('/adm/switchserver');
+            my $redirecturl = '/adm/switchserver';
+            if ($otherserver ne '') {
+                $redirecturl .= '?otherserver='.$otherserver;
+            }
+	    $r->internal_redirect($redirecturl);
 	    $r->set_handlers('PerlHandler'=> undef);
 	} else {
 	    # need to login them in, so generate the need data that
@@ -383,11 +389,7 @@
 	return $result;
     }
 
-
-    if ($r->dir_config("lonBalancer") eq 'yes') {
-	$r->set_handlers('PerlResponseHandler'=>
-			 [\&Apache::switchserver::handler]);
-    }
+    my ($is_balancer,$otherserver);
     
     if ($handle eq '') {
 	$r->log_reason("Cookie $handle not valid", $r->filename); 
@@ -434,6 +436,19 @@
 
 	&Apache::lonacc::get_posted_cgi($r);
 
+# ------------------------------------------------------ Check if load balancer 
+
+        ($is_balancer,$otherserver) =
+            &Apache::lonnet::check_loadbalancing($env{'user.name'},
+                                                 $env{'user.domain'});
+        if ($is_balancer) {
+            $r->set_handlers('PerlResponseHandler'=>
+                             [\&Apache::switchserver::handler]);
+            if ($otherserver ne '') {
+                $env{'form.otherserver'} = $otherserver;
+            }
+        }
+
 # ---------------------------------------------------------------- Check access
 	my $now = time;
 	if ($requrl !~ m{^/(?:adm|public|prtspool)/}
@@ -577,6 +592,17 @@
             }
 	}
 	return OK;
+    } else {
+        my $defdom=$r->dir_config('lonDefDomain');
+        ($is_balancer,$otherserver) =
+            &Apache::lonnet::check_loadbalancing(undef,$defdom);
+        if ($is_balancer) {
+            $r->set_handlers('PerlResponseHandler'=>
+                             [\&Apache::switchserver::handler]);
+            if ($otherserver ne '') {
+                $env{'form.otherserver'} = $otherserver;
+            }
+        }
     }
 # -------------------------------------------- See if this is a public resource
     if ($requrl=~m|^/+adm/+help/+|) {


More information about the LON-CAPA-cvs mailing list