[X2Go-Commits] x2goserver.git - build-baikal (branch) updated: 3.1.1.3-223-g9ae8662

X2Go dev team git-admin at x2go.org
Fri Jan 3 20:51:49 CET 2014


The branch, build-baikal has been updated
       via  9ae866256d908d941880720e71864430a6d8ee24 (commit)
      from  05a7500abbff09c469962b0518d29c400aed4756 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
-----------------------------------------------------------------------

Summary of changes:
 X2Go/{Utils.pm => Config.pm}          |   45 ++++---
 X2Go/SupeReNicer.pm                   |  226 +++++++++++++++++++++++++++++++++
 X2Go/Utils.pm                         |   48 ++++++-
 debian/changelog                      |    4 +
 x2goserver-common/etc/x2goserver.conf |   21 +++
 x2goserver/sbin/x2gocleansessions     |   42 +++++-
 6 files changed, 361 insertions(+), 25 deletions(-)
 copy X2Go/{Utils.pm => Config.pm} (66%)
 create mode 100644 X2Go/SupeReNicer.pm

The diff of changes is:
diff --git a/X2Go/Utils.pm b/X2Go/Config.pm
similarity index 66%
copy from X2Go/Utils.pm
copy to X2Go/Config.pm
index f5e4cf6..d058753 100644
--- a/X2Go/Utils.pm
+++ b/X2Go/Config.pm
@@ -20,42 +20,41 @@
 # Copyright (C) 2007-2013  Oleksandr Shneyder <oleksandr.shneyder at obviously-nice.de>
 # Copyright (C) 2007-2013  Heinz-Markus Graesing <heinz-m.graesing at obviously-nice.de>
 
-package X2Go::Utils;
+package X2Go::Config;
 
 =head1 NAME
 
-X2Go::Utils - X2Go utilities and helper functions for Perl
+X2Go::Config - X2Go Config package for Perl
 
 =head1 DESCRIPTION
 
-X2Go::Utils Perl package.
+X2Go::Config Perl package for X2Go components.
 
 =cut
 
 use strict;
+use Config::Simple;
+
 use base 'Exporter';
+our @EXPORT = ( 'get_config', 'get_sqlconfig', );
+
+my $Config;
+my $SqlConfig;
+
+sub get_config {
+	if (! defined $Config) {
+		$Config = new Config::Simple(syntax=>'ini');
+		$Config->read('/etc/x2go/x2goserver.conf' );
+	}
+	return $Config;
+}
 
-our @EXPORT = ('source_environment');
-
-sub source_environment {
-	my $name = shift;
-
-	open my $fh, "<", $name
-	     or return -1;
-
-	while (<$fh>) {
-		chomp;
-		my $line = $_;
-		if ( $line =~ m/^#.*/ )
-		{
-			next;
-		}
-		my ($k, $v) = split /=/, $line, 2;
-		$v =~ s/^(['"])(.*)\1/$2/; #' fix highlighter
-		$v =~ s/\$([a-zA-Z]\w*)/$ENV{$1}/g;
-		$v =~ s/`(.*?)`/`$1`/ge; #dangerous
-		$ENV{$k} = $v;
+sub get_sqlconfig {
+	if (! defined $SqlConfig) {
+		$SqlConfig = new Config::Simple(syntax=>'ini');
+		$SqlConfig->read('/etc/x2go/x2gosql/sql' );
 	}
+	return $SqlConfig;
 }
 
 1;
diff --git a/X2Go/SupeReNicer.pm b/X2Go/SupeReNicer.pm
new file mode 100644
index 0000000..e08f3ed
--- /dev/null
+++ b/X2Go/SupeReNicer.pm
@@ -0,0 +1,226 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2013 X2Go Project - http://wiki.x2go.org
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the
+# Free Software Foundation, Inc.,
+# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Copyright (C) 2013 Guangzhou Nianguan Electronics Technology Co.Ltd. <opensource at gznianguan.com>
+# Copyright (C) 2013 Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+package X2Go::SuperRenicer;
+
+=head1 NAME
+
+X2Go::SuperRenicer- X2Go SuperRenicer package for Perl
+
+=head1 DESCRIPTION
+
+X2Go::SuperRenicer Perl package.
+
+=cut
+
+use strict;
+use Sys::Syslog qw( :standard :macros );
+use X2Go::Utils qw( sanitizer clups );
+
+use base 'Exporter';
+
+our @EXPORT=('superenice');
+
+
+sub checkPID {
+	my $pid = sanitizer("num",$_[0]);
+	open(PS,"/bin/ps --no-headers -o %u,%p,%n,%c -p $pid|");
+	my ($pidInf,undef) = <PS>;
+	close(PS);
+	my ($user,$pid,$nice,$cmd)  = split(/\,/,clups($pidInf));
+	$pid =~ s/\D//g;
+	return ($pid,$user,$nice,$cmd)
+}
+
+
+sub sanitizeNL {
+	my $NL = shift;
+	my $fallbackNL = shift;
+	if ($NL =~ m/^(-|\+|)\d+$/) {
+		$NL = int $NL;
+		if ($NL > 19) { $NL = 19; }
+		elsif ($NL < -19) { $NL = -19; }
+	} else {
+	    $NL = $fallbackNL;
+	}
+	return $NL;
+}
+
+
+sub superrenice {
+	# Normal: Nice LEVEL?
+	my $normalNL = shift; $normalNL = 0 unless defined $normalNL;
+	$normalNL = sanitizeNL($normalNL, 0);
+	# Idle: Nice LEVEL?
+	my $idleNL = shift; $idleNL = 19 unless defined $idleNL;
+	$idleNL = sanitizeNL($idleNL, 19);
+	# Ignore these users (comma separated list as string)
+	my $ignore_users = shift; $ignore_users = "" unless defined $ignore_users;
+	# if set to "1" we will force renicing of entire user, even on systems with "/proc"
+	my $forceUSERrenice = shift; $forceUSERrenice = 0 unless defined $forceUSERrenice;
+	#Path to the "x2golistsessions_root" perl script...
+
+	my $x2golsrpath = `x2gopath base` . "/sbin/x2golistsessions_root";
+
+	###########################################################################################
+	# Load list of users to "ignore". These users will never be reniced...
+	my %ignore;
+	while (split(",", $ignore_users)) {my $iu = clups($_);if (length($iu) > 0) {$ignore{$iu} = 1;}}
+	# Load list of users to "ignore". These users will never be reniced...
+	###########################################################################################
+
+	if ((-f "/proc/$$/environ") and ($forceUSERrenice ne 1)) {
+		###########################################################################################
+		# Great! We're on a system with "/proc" so we're able to do this on individual sessions!
+		# Basicaly we're checking the users /proc/<$PID>/environ files for the "X2GO_SESSION" env...
+		my @x2goSessions;
+		# Read the current list of X2Go sessions and their running state
+		open(XGOLS,"$x2golsrpath|");
+		while (<XGOLS>) {
+			my $line = clups($_);
+			my ($agentPid,$x2gosid,undef,undef,$x2goState,undef,undef,undef,undef,undef,undef,$userID,undef,undef) = split(/\|/,$line);
+			#syslog('debug', "$agentPid,$x2gosid,$x2goState,$userID");
+			unless ($ignore{$userID} eq 1) {
+				push @x2goSessions, "$x2goState:$agentPid:$x2gosid:$userID";
+			}
+		}
+		close(XGOLS);
+
+		foreach my $x2goSInf (@x2goSessions) {
+			my ($x2goState,$agentPid,$x2gosid,$userID,undef) = split(/\:/,$x2goSInf);
+			$agentPid = sanitizer("num",$agentPid);
+
+			# We're only working with "portable" unix usernames.
+			$userID = sanitizer("anumazcsdaus",$userID);
+
+			# So if the sanitizer returns something we'll do this....
+			if ($userID) {
+
+				# Using the NICE value of the agent to figgure out the current nice state...
+				my ($psP,$psU,$psN,$psC) = checkPID($agentPid);
+
+				if ($x2goState eq "R") {
+
+					# State is R (Running?)...
+					if ($psN ne $normalNL) {
+						# If nice level is not normal, renice to normal...
+						syslog('notice', "ReNicing \"$userID\" to level $normalNL for session \"$x2gosid\"");
+						# For the sake of getting a user back to normal ASAP...  We'll renice the entire user not just individual sessions...
+						system("renice -n $normalNL -u $userID 1>/dev/null 2>/dev/null");
+					}
+
+				} elsif ($x2goState eq "S") {
+
+					# State is S (suspended)
+					if ($psN ne $idleNL) {
+
+						# Did we renice this?
+						open(AUPS,"/bin/ps --no-headers -o %u,%p,%n,%c -u $userID|"); # use PS to fetch a list of the users current processes
+						while (<AUPS>) {
+							my ($user,$pid,$nice,$cmd)  = split(/\,/,clups($_));
+							$pid  = sanitizer("num",$pid);
+
+							if (-f "/proc/$pid/environ") {
+								open(ENVIRON,"/proc/$pid/environ");my ($Environ,undef) = <ENVIRON>;close(ENVIRON);
+								if ($Environ =~ m/X2GO_SESSION=$x2gosid/) {       # If the x2go Session ID is in environ... renice the pid...
+									#syslog('debug', "$pid: X2GO_SESSION=$x2gosid");
+									system("renice -n $idleNL -p $pid 1>/dev/null 2>/dev/null");
+								}
+							}
+
+						}
+						close(AUPS);
+
+						# Renice the AGENT so that we'll know that this one is already reniced.
+						system("renice -n $idleNL -p $agentPid 1>/dev/null 2>/dev/null");
+						syslog('notice', "ReNicing \"$userID\" to level $idleNL for session \"$x2gosid\"");
+
+					}
+				}
+			}
+		}
+
+		# Great! We're on a system with "/proc" so we're able to do this on individual sessions!
+		############################################################################################
+
+	} else {
+
+		###########################################################################################
+		# Oh no.... No "/proc"?  Lets do this on a per user basis instead then...  
+		# If a user have more than one session, both need to be suspended before we renice....
+		# Resuming any of that users sessions would return them all to normal priority.
+
+		my %niceUsers;
+		# Read the current list of X2Go sessions and their running state
+		open(XGOLS,"$x2golsrpath|");
+		while (<XGOLS>) {
+			my $line = clups($_);
+			my ($agentPid,$x2gosid,undef,undef,$x2goState,undef,undef,undef,undef,undef,undef,$userID,undef,undef) = split(/\|/,$line);
+			syslog('debug', "$agentPid,$x2gosid,,$x2goState,$userID");
+
+			# If user is in ignore list... we're not going a damn thing..
+			unless ($ignore{$userID} eq 1) {
+				unless ($niceUsers{$userID} =~ /^R:/) {   # Basically if we got an R we're sticking with it...
+					$niceUsers{$userID} = "$x2goState:$agentPid";
+				}
+			}
+		}
+		close(XGOLS);
+
+		foreach my $nUser (keys %niceUsers) {
+			$nUser = sanitizer("anumazcsdaus",$nUser);
+
+			# We're only working with "portable" unix usernames..  
+			if ($nUser) {
+
+				# So if the sanitizer return something we'll do this....
+				my ($x2goState,$agentPid) = split(/\:/, $niceUsers{$nUser});
+
+				# Using the NICE value of the agent to figgure out the current nice state...
+				my ($psP,$psU,$psN,$psC) = checkPID($agentPid);
+				syslog('debug', "$nUser:$x2goState,$agentPid:$psP,$psU,$psN,$psC");
+				# State is R (Running?)...
+				if ($x2goState eq "R") {
+
+					# If nice level is not normal, renice to normal...
+					if ($psN ne $normalNL) {
+						syslog('debug', "ReNicing \"$nUser\" to level $normalNL");
+						system("renice -n $normalNL -u $nUser 1>/dev/null 2>/dev/null");
+					}
+
+				# State is S (suspended)
+				} elsif ($x2goState eq "S") {
+
+					# Did we renice this?
+					if ($psN ne $idleNL) {
+						syslog('debug', "ReNicing \"$nUser\" to level $idleNL");
+						system("renice -n $idleNL -u $nUser 1>/dev/null 2>/dev/null");
+					}
+				}
+			}
+		}
+		# Oh no.... No "/proc"?  Lets do this on a per user basis instead then...  
+		###########################################################################################
+	}
+}
+
+1;
diff --git a/X2Go/Utils.pm b/X2Go/Utils.pm
index f5e4cf6..928eb67 100644
--- a/X2Go/Utils.pm
+++ b/X2Go/Utils.pm
@@ -19,6 +19,8 @@
 #
 # Copyright (C) 2007-2013  Oleksandr Shneyder <oleksandr.shneyder at obviously-nice.de>
 # Copyright (C) 2007-2013  Heinz-Markus Graesing <heinz-m.graesing at obviously-nice.de>
+# Copyright (C) 2013 Guangzhou Nianguan Electronics Technology Co.Ltd. <opensource at gznianguan.com>
+# Copyright (C) 2013 Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
 
 package X2Go::Utils;
 
@@ -35,7 +37,7 @@ X2Go::Utils Perl package.
 use strict;
 use base 'Exporter';
 
-our @EXPORT = ('source_environment');
+our @EXPORT = ('source_environment', 'clups', 'sanitizer', );
 
 sub source_environment {
 	my $name = shift;
@@ -58,4 +60,48 @@ sub source_environment {
 	}
 }
 
+# Over-zealous string sanitizer that makes perl strict and  perl -T happy...
+sub sanitizer {
+	my $type   = $_[0];
+	my $string = $_[1];
+	if ($type eq "anumazcs") {
+		$string =~ s/[^a-zA-Z0-9]//g;
+		if ($string =~ /^([a-zA-Z0-9]*)$/) {
+			$string = $1;
+			return $string;
+		} else {return 0;}
+	} elsif ($type eq "anumazlc") {
+		$string = lc($string);
+		$string =~ s/[^a-z0-9]//g;
+		if ($string =~ /^([a-z0-9]*)$/) {
+			$string = $1;
+			return $string;
+		} else {return 0;}
+	} elsif ($type eq "num") {
+		$string =~ s/\D//g;
+		if ($string =~ /^([0-9]*)$/) {
+			$string = $1;
+			return $string;
+		} else {return 0;}
+	} elsif ($type eq "anumazcsdaus") {
+		$string =~ s/[^a-zA-Z0-9\_\-]//g;
+		if ($string =~ /^([a-zA-Z0-9\_\-]*)$/) {
+			$string = $1;
+			return $string;
+		} else {return 0;}
+	} elsif ($type eq "SOMETHINGELSE") {
+		return 0;
+	} else {
+		return 0;
+	}
+}
+
+sub clups {
+	my $string = "@_";
+	$string =~ s/\n//g;
+	$string =~ s/\ //g;
+	$string =~ s/\s//g;
+	return $string;
+}
+
 1;
diff --git a/debian/changelog b/debian/changelog
index 6401701..0328845 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -40,6 +40,10 @@ x2goserver (4.1.0.0-0~x2go1) UNRELEASED; urgency=low
     not set. (Fixes: #82).
   * Make x2goruncommand aware of the Cinnamon desktop shell. (Fixes: #117).
 
+  [ Guangzhou Nianguan Electronics Technology Co.Ltd. ]
+  * New upstream version (4.1.0.0):
+    - Add SupeReNicer support.
+
   [ Otto Kjell ]
   * New upstream version (4.1.0.0):
     - Add markdown files for most of the X2Go Server project folders. (Fixes:
diff --git a/x2goserver-common/etc/x2goserver.conf b/x2goserver-common/etc/x2goserver.conf
index 5fa6baf..fc98c90 100644
--- a/x2goserver-common/etc/x2goserver.conf
+++ b/x2goserver-common/etc/x2goserver.conf
@@ -4,6 +4,27 @@
 [limit groups]
 #bar-group=1
 
+[security]
+# SSHFS umask for client-side folder sharing. Leave uncommented to keep the server's default umask
+#umask="0117"
+
+[superenicer]
+# enable the superrenicer code in x2gocleansessions, this will renice suspended sessions to nice level 19
+# and renice them to level 0 if the session becomes marked as running again...
+enable=yes
+
+# list of users that shall never be reniced
+#ignored_users=
+
+# force renicing of the complete user, don't set it to 'yes' unless you know what you are doing
+#force-user-renice=no
+
+# the normal nice level (for running sessions)
+#normal-nice-level=0
+
+# the idle nice level (for suspended sessions)
+#idle-nice-level=19
+
 [log]
 # possible levels are: emerg, alert, crit, err, warning, notice, info, debug
 loglevel=notice
diff --git a/x2goserver/sbin/x2gocleansessions b/x2goserver/sbin/x2gocleansessions
index 3c9bbf0..728ead3 100755
--- a/x2goserver/sbin/x2gocleansessions
+++ b/x2goserver/sbin/x2gocleansessions
@@ -21,11 +21,16 @@
 # Copyright (C) 2007-2013  Heinz-Markus Graesing <heinz-m.graesing at obviously-nice.de>
 
 use strict;
+
+$ENV{'PATH'} = "/bin:/sbin:/usr/bin:/usr/sbin";
+
 use Sys::Hostname;
 use Sys::Syslog qw( :standard :macros );
 
 my $x2go_lib_path = `x2gopath libexec`;
-use X2Go::Log qw(loglevel);
+use X2Go::Config qw( get_config );
+use X2Go::Log qw( loglevel );
+use X2Go::SupeReNicer qw( superenice );
 
 openlog($0,'cons,pid','user');
 setlogmask( LOG_UPTO(loglevel()) );
@@ -107,6 +112,30 @@ elsif ($pid != 0)
 }
 elsif ($pid == 0 )
 {
+
+	# check if we are to use the superenicer script for throttling does the nice level
+        # of suspended sessions...
+	my $Config = get_config();
+
+	my $superenice_enable=$Config->param("superenicer.enable");
+	my $superenice_forceuser=$Config->param("superenicer.force-user-renice");
+	my $superenice_normal=$Config->param("superenicer.normal-nice-level");
+	my $superenice_idle=$Config->param("superenicer.idle-nice-level");
+	my $superenice_ignoredusers=$Config->param("superenicer.ignored-users");
+
+	if ($superenice_enable =~ m/(1|yes|Yes|YES|on|On|ON|True|true|TRUE)/ )
+	{
+		$superenice_enable=1;
+	} else {
+		$superenice_enable=0;
+	}
+	if ($superenice_forceuser =~ m/(1|yes|Yes|YES|on|On|ON|True|true|TRUE)/ )
+	{
+		$superenice_forceuser=1;
+	} else {
+		$superenice_forceuser=0;
+	}
+
 	# close any open file descriptor left open by our parent before the fork
 	for (glob "/proc/$$/fd/*") { POSIX::close($1) if m{/(\d+)$}; }
 
@@ -115,6 +144,7 @@ elsif ($pid == 0 )
 
 	my %remembered_sessions_status = ();
 	my %remembered_sessions_since = ();
+	my $last_reniced = 0;
 
 	while(sleep 2)
 	{
@@ -201,5 +231,15 @@ elsif ($pid == 0 )
 				}
 			}
 		}
+
+		# call superenicer script if requested through x2goserver.conf every six seconds
+		if ( $superenice_enable ) {
+			$last_reniced += 2;
+			if ( $last_reniced ge 4 ) {
+				superenice($superenice_normal, $superenice_idle, $superenice_ignoredusers, $superenice_forceuser);
+				$last_reniced = 0;
+			}
+		}
+
 	}
 }


hooks/post-receive
-- 
x2goserver.git (X2Go Server)

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "x2goserver.git" (X2Go Server).




More information about the x2go-commits mailing list