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

X2Go dev team git-admin at x2go.org
Tue Nov 5 16:34:09 CET 2013


The branch, master 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 -----------------------------------------------------------------
commit 9ae866256d908d941880720e71864430a6d8ee24
Author: Guangzhou Nianguan Electronics Technology Co.Ltd <opensource at gznianguan.com>
Date:   Tue Nov 5 16:26:10 2013 +0100

    Add SupeReNicer support.

-----------------------------------------------------------------------

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