This is an automated email from the git hooks/post-receive script. x2go pushed a commit to branch release/4.0.1.x in repository x2goserver. commit aa7adcf32a3f201e9eab9d60f772a275ca8a8077 Author: Oleksandr Shneyder <o.shneyder@phoca-gmbh.de> Date: Fri Jun 27 14:17:04 2014 +0200 x2gostartagent, x2golistsession, x2gosuspend-session and x2goresume-session getting agent state from ~/.x2go/C-$SID/state. This should help to avoid session damage. Remove nxcleanup. --- debian/changelog | 3 + x2goserver/bin/x2golistsessions | 63 +++++++++++++++------ x2goserver/bin/x2goresume-session | 53 +++++++++++++++++ x2goserver/bin/x2gostartagent | 5 +- x2goserver/bin/x2gosuspend-session | 38 +++++++------ x2goserver/bin/x2goterminate-session | 3 - x2goserver/lib/x2gonxcleanup | 82 --------------------------- x2goserver/sbin/x2gocleansessions | 103 ++++++++++++++-------------------- 8 files changed, 169 insertions(+), 181 deletions(-) diff --git a/debian/changelog b/debian/changelog index 2815154..0be0f06 100644 --- a/debian/changelog +++ b/debian/changelog @@ -54,6 +54,9 @@ x2goserver (4.0.1.16-0x2go1) UNRELEASED; urgency=low [ Oleksandr Shneyder ] * Move session file to /tmp/.x2go-$USER. + - x2gostartagent, x2golistsession, x2gosuspend-session and x2goresume-session + getting agent state from ~/.x2go/C-$SID/state. This should help to avoid + session damage. Remove nxcleanup. -- Mike DePaulo <mikedep333@gmail.com> Thu, 23 Apr 2014 17:49:00 -0500 diff --git a/x2goserver/bin/x2golistsessions b/x2goserver/bin/x2golistsessions index 14f48a4..0f5fa8a 100755 --- a/x2goserver/bin/x2golistsessions +++ b/x2goserver/bin/x2golistsessions @@ -48,23 +48,46 @@ if ((hostname eq '(none)') || (hostname eq 'localhost')) { sub is_suspended { - my $sess=shift; - my $log="$ENV{'HOME'}/.x2go/C-${sess}.log"; - my $log_line; - my $log_file = File::ReadBackwards->new( $log ) or return 0; - while( defined( $log_line = $log_file->readline ) ) { - next if ( ! ( $log_line =~ m/^Session:/ ) ); - last; - } - $log_file->close(); - if (($log_line =~ m/Session suspended/) || ($log_line =~ m/Suspending session/) || ($log_line =~ m/Display failure detected/)) - { - return 1; - } - return 0; + my $state=get_agent_state(@_); + if(($state eq 'SUSPENDING')||($state eq 'SUSPENDED')) + { + return 1; + } + return 0; } +sub is_running +{ + my $state=get_agent_state(@_); + if(($state eq 'STARTING')||($state eq 'RESUMING')||($state eq 'RUNNING')) + { + return 1; + } + return 0; +} + +sub get_agent_state +{ + my $sess=@_[0]; + my $user=@_[1]; + my $state; + my $stateFile = "/tmp/.x2go-".$user."/C-".$sess."/state"; + if (! -e $stateFile ) + { + die "state file not exists: $stateFile\n"; + } + else + { + open(F,"<$stateFile"); + $state=<F>; + close(F); + } + return $state; +} + + + my $serv=shift; if( ! $serv) { @@ -94,13 +117,21 @@ for (my $i=0;$i<@outp;$i++) { if (@sinfo[4]eq 'R') { - if(is_suspended(@sinfo[1])) + if(is_suspended(@sinfo[1], @sinfo[11])) { - db_changestatus( 'S', @sinfo[1] ); + db_changestatus( 'S', @sinfo[1]); @outp[$i] =~ s/\|R\|/\|S\|/; system("x2goumount-session", "@sinfo[1]"); } } + elsif (@sinfo[4]eq 'S') + { + if(is_running(@sinfo[1], @sinfo[11])) + { + db_changestatus( 'R', @sinfo[1] ); + @outp[$i] =~ s/\|S\|/\|R\|/; + } + } print "@outp[$i]\n"; } } diff --git a/x2goserver/bin/x2goresume-session b/x2goserver/bin/x2goresume-session index a7c1664..1907707 100755 --- a/x2goserver/bin/x2goresume-session +++ b/x2goserver/bin/x2goresume-session @@ -20,6 +20,12 @@ # Copyright (C) 2007-2014 Oleksandr Shneyder <oleksandr.shneyder@obviously-nice.de> # Copyright (C) 2007-2014 Heinz-Markus Graesing <heinz-m.graesing@obviously-nice.de> + +if [ $# -lt 7 ] +then + echo "not enough arguments" + exit -1 +fi SESSION_NAME="$1" X2GO_GEOMETRY="$2" X2GO_LINK="$3" @@ -35,6 +41,53 @@ X2GO_ROOT="${HOME}/.x2go" X2GO_RESIZE=1 X2GO_FULLSCREEN=0 +STATE=`$X2GO_LIB_PATH/x2gogetagentstate "$SESSION_NAME"` + +# exit if session terminated +if [ "$STATE" == "TERMINATED" ] || [ "$STATE" == "TERMINATING" ] +then + echo "Session terminated" + exit -1 +fi + +i=0 +# wait 15 sec. for starting session +while [ "$STATE" == "RESUMING" ] || [ "$STATE" == "STARTING" ] +do + sleep 1 + i=$(($i+1)) + #if session still not started, try to suspend it + if [ $i -gt 15 ] + then + x2gosuspend-session "$SESSION_NAME" + sleep 2 + i=0 + fi + STATE=`$X2GO_LIB_PATH/x2gogetagentstate "$SESSION_NAME"` +done + +#suspend running session +if [ "$STATE" == "RUNNING" ] +then + x2gosuspend-session "$SESSION_NAME" + sleep 2 + STATE=`$X2GO_LIB_PATH/x2gogetagentstate "$SESSION_NAME"` +fi + +i=0 +# wait 45 sec., while session suspending +while [ "$STATE" == "SUSPENDING" ] +do + sleep 1 + i=$(($i+1)) + if [ $i -gt 45 ] + then + echo "Error: taking too long to suspend session. Possible session is damaged" + exit -1; + fi + STATE=`$X2GO_LIB_PATH/x2gogetagentstate "$SESSION_NAME"` +done + NX_XINERAMA_CONF="$X2GO_ROOT/C-$SESSION_NAME/xinerama.conf" if [ -e "$NX_XINERAMA_CONF" ] then diff --git a/x2goserver/bin/x2gostartagent b/x2goserver/bin/x2gostartagent index a2de31d..fcda6dd 100755 --- a/x2goserver/bin/x2gostartagent +++ b/x2goserver/bin/x2gostartagent @@ -236,6 +236,7 @@ if [ ! -d "$X2GO__TMP_ROOT" ]; then fi SESSION_DIR="${X2GO_TMP_ROOT}/C-${SESSION_NAME}" +STATE_FILE="${X2GO_ROOT}/C-${SESSION_NAME}/state" # do not use $TMP or $TEMP here, the session.log file location has to be accessible by root SESSION_LOG="${SESSION_DIR}/session.log" @@ -268,9 +269,9 @@ if [ -n "$X2GO_GEOMETRY" ] && [ "$X2GO_GEOMETRY" != "fullscreen" ]; then fi if [ "$X2GO_SET_KBD" == "0" ] || [ "$X2GO_KBD_TYPE" == "auto" ];then - X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=null/null,${option_geometry}resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0" + X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=null/null,${option_geometry}resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0,state=${STATE_FILE}" else - X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=${X2GO_KBD_TYPE},${option_geometry}resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0" + X2GO_HOST="nx/nx,link=${X2GO_LINK},pack=${X2GO_PACK},limit=0,root=${SESSION_DIR},cache=8M,images=32M,type=${X2GO_TYPE},id=${SESSION_NAME},cookie=$X2GO_COOKIE,errors=${SESSION_LOG},kbtype=${X2GO_KBD_TYPE},${option_geometry}resize=${X2GO_RESIZE},fullscreen=${X2GO_FULLSCREEN},accept=${REMOTE},listen=${GR_PORT},client=linux,menu=0,state=${STATE_FILE}" fi diff --git a/x2goserver/bin/x2gosuspend-session b/x2goserver/bin/x2gosuspend-session index 9d7f0de..69f6c2b 100755 --- a/x2goserver/bin/x2gosuspend-session +++ b/x2goserver/bin/x2gosuspend-session @@ -45,26 +45,30 @@ x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSI export HOSTNAME x2goumount-session "$SESSION_NAME" -if kill -HUP $X2GO_AGENT_PID &>/dev/null; then - $X2GO_LIB_PATH/x2gosyslog "$0" "notice" "session with ID $SESSION_NAME has been suspended successfully" +STATE=`$X2GO_LIB_PATH/x2gogetagentstate "$SESSION_NAME"` - # run x2goserver-extensions for post-suspend - x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" post-suspend || true +if [ "$STATE" == "RESUMING" ] || [ "$STATE" == "STARTING" ] || [ "$STATE" == "RUNNING" ] +then + if kill -HUP $X2GO_AGENT_PID &>/dev/null; then + $X2GO_LIB_PATH/x2gosyslog "$0" "notice" "session with ID $SESSION_NAME has been suspended successfully" - $X2GO_LIB_PATH/x2gochangestatus 'S' "$SESSION_NAME" > /dev/null + # run x2goserver-extensions for post-suspend + x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" post-suspend || true - # this makes sure that the socket on localhost blocked by NX agent gets released immediately - $X2GO_LIB_PATH/x2gonxcleanup -else - err_msg="ERROR: failed to suspend session with ID $SESSION_NAME" - echo "$err_msg" 1>&2 - $X2GO_LIB_PATH/x2gosyslog "$0" "err" "$err_msg" + $X2GO_LIB_PATH/x2gochangestatus 'S' "$SESSION_NAME" > /dev/null - # run x2goserver-extensions for fail-suspend - x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" fail-suspend || true + else + err_msg="ERROR: failed to suspend session with ID $SESSION_NAME" + echo "$err_msg" 1>&2 + $X2GO_LIB_PATH/x2gosyslog "$0" "err" "$err_msg" - # If we reach here it means that the x2goagent process of the session has vanisshed - # If this happens then we mark the session as finished... - $X2GO_LIB_PATH/x2gochangestatus 'F' "$SESSION_NAME" > /dev/null -fi + # run x2goserver-extensions for fail-suspend + x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" fail-suspend || true + # If we reach here it means that the x2goagent process of the session has vanisshed + # If this happens then we mark the session as finished... + $X2GO_LIB_PATH/x2gochangestatus 'F' "$SESSION_NAME" > /dev/null + fi +else + $X2GO_LIB_PATH/x2gosyslog "$0" "notice" "session with ID $SESSION_NAME is not in running state" +fi diff --git a/x2goserver/bin/x2goterminate-session b/x2goserver/bin/x2goterminate-session index 9328c55..b896475 100755 --- a/x2goserver/bin/x2goterminate-session +++ b/x2goserver/bin/x2goterminate-session @@ -45,9 +45,6 @@ if kill -TERM $X2GO_AGENT_PID &>/dev/null; then # run x2goserver-extensions for post-terminate x2gofeature X2GO_RUN_EXTENSIONS &>/dev/null && x2goserver-run-extensions "$SESSION_NAME" post-terminate || true - # this makes sure that the socket on localhost blocked by NX agent gets released immediately - $X2GO_LIB_PATH/x2gonxcleanup - else err_msg="ERROR: failed to terminate session with ID $SESSION_NAME" diff --git a/x2goserver/lib/x2gonxcleanup b/x2goserver/lib/x2gonxcleanup deleted file mode 100755 index 5657b38..0000000 --- a/x2goserver/lib/x2gonxcleanup +++ /dev/null @@ -1,82 +0,0 @@ -#!/usr/bin/perl - -# Copyright (C) 2014 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) 2014 Guangzhou Nianguan Electronics Technology Co.Ltd. <opensource@gznianguan.com> -# Copyright (C) 2014 Mike Gabriel <mike.gabriel@das-netzwerkteam.de> -# - -use strict; -use Sys::Hostname; -use IO::Socket; -use Sys::Syslog qw( :standard :macros ); - -use lib `x2gopath lib`; -use x2godbwrapper; -use x2gologlevel; -use x2goutils; - -openlog($0,'cons,pid','user'); -setlogmask( LOG_UPTO(x2gologlevel()) ); - - -sub get_session_info { - my $theX2GoSID = $_[0]; - foreach my $sessionLine (db_listsessions(hostname)) { - if ($sessionLine =~ /$theX2GoSID/) { - return split(/\|/,$sessionLine); - } - } - return 0; -} - -sub check_x2go_sessionid { - if (sanitizer("x2gosid",@ARGV[0])) { - return sanitizer("x2gosid",@ARGV[0]); - } elsif (sanitizer("x2gosid",$ENV{'X2GO_SESSION'})) { - return sanitizer("x2gosid",$ENV{'X2GO_SESSION'}); - } else { - die "No X2Go Session ID in ARGV or ENV!\n"; - } -} - -sub test_socket_state { - my $portNum = sanitizer("num",$_[0]) or die "Port number not a number '$_[0]'?"; - my $socket = IO::Socket::INET->new( PeerAddr => 'localhost', PeerPort => $portNum, Proto => 'tcp'); - if (defined $socket) { - print $socket "\n"; - $socket->close; - return 1; - } else { - return 0; - } -} - -my $doRetryCnt = 5; -my $X2GoSID = check_x2go_sessionid; - -my @X2GoSesINFO = get_session_info($X2GoSID); -if (@X2GoSesINFO[1] eq $X2GoSID) { - while ($doRetryCnt > 0) { - $doRetryCnt--; - if (test_socket_state($X2GoSesINFO[8])) { - exit; - } - sleep 1; - } -} diff --git a/x2goserver/sbin/x2gocleansessions b/x2goserver/sbin/x2gocleansessions index 276e2f7..349e1a1 100755 --- a/x2goserver/sbin/x2gocleansessions +++ b/x2goserver/sbin/x2gocleansessions @@ -25,7 +25,6 @@ use Sys::Hostname; use Sys::Syslog qw( :standard :macros ); use POSIX; -use File::ReadBackwards; my $x2go_lib_path=`x2gopath libexec`; use lib `x2gopath lib`; @@ -35,6 +34,7 @@ openlog($0,'cons,pid','user'); setlogmask( LOG_UPTO(x2gologlevel()) ); + sub check_pid { my $pid=shift; @@ -56,76 +56,57 @@ sub check_pid sub has_terminated { - my $sess=shift; - my $user=shift; - my $log; - if ( -d "/tmp-inst/${user}/.x2go-${user}") { - $log="/tmp-inst/${user}/.x2go-${user}/session-C-${sess}.log"; - } else { - $log="/tmp/.x2go-${user}/session-C-${sess}.log"; - } - my $log_line; - my $log_file = File::ReadBackwards->new( $log ) or return 1; - while( defined( $log_line = $log_file->readline ) ) { - next if ( ! ( $log_line =~ m/^Session:/ ) ); - last; - } - $log_file->close(); - if (($log_line =~ m/Session terminated/) || ($log_line =~ m/Terminating session/) || ($log_line =~ m/Aborting session/)) - { - return 1; - } - return 0; + my $state=get_agent_state(@_); + if(($state eq 'TERMINATING')||($state eq 'TERMINATED')) + { + return 1; + } + return 0; } + sub is_suspended { - my $sess=shift; - my $user=shift; - my $log; - if ( -d "/tmp-inst/${user}/.x2go-${user}" ) { - $log="/tmp-inst/${user}/.x2go-${user}/session-C-${sess}.log"; - } else { - $log="/tmp/.x2go-${user}/session-C-${sess}.log"; - } - my $log_line; - my $log_file = File::ReadBackwards->new( $log ) or return 0; - while( defined( $log_line = $log_file->readline ) ) { - next if ( ! ( $log_line =~ m/^Session:/ ) ); - last; - } - $log_file->close(); - if (($log_line =~ m/Session suspended/) || ($log_line =~ m/Suspending session/) || ($log_line =~ m/Display failure detected/)) - { - return 1; - } - return 0; + my $state=get_agent_state(@_); + if(($state eq 'SUSPENDING')||($state eq 'SUSPENDED')) + { + return 1; + } + return 0; } + sub is_running { - my $sess=shift; - my $user=shift; - my $log; - if ( -d "/tmp-inst/${user}/.x2go-${user}" ) { - $log="/tmp-inst/${user}/.x2go-${user}/session-C-${sess}.log"; - } else { - $log="/tmp/.x2go-${user}/session-C-${sess}.log"; - } - my $log_line; - my $log_file = File::ReadBackwards->new( $log ) or return 0; - while( defined( $log_line = $log_file->readline ) ) { - next if ( ! ( $log_line =~ m/^Session:/ ) ); - last; - } - $log_file->close(); - if (($log_line =~ m/Session started/) || ($log_line =~ m/Starting session/) || ($log_line =~ m/Session resumed/) || ($log_line =~ m/Resuming session/)) - { - return 1; - } - return 0; + my $state=get_agent_state(@_); + if(($state eq 'STARTING')||($state eq 'RESUMING')||($state eq 'RUNNING')) + { + return 1; + } + return 0; } +sub get_agent_state +{ + my $sess=@_[0]; + my $user=@_[1]; + my $state; + my $stateFile = "/tmp/.x2go-".$user."/C-".$sess."/state"; + if (! -e $stateFile ) + { + die "state file not exists: $stateFile\n"; + } + else + { + open(F,"<$stateFile"); + $state=<F>; + close(F); + } + return $state; +} + + + sub catch_term { unlink("/var/run/x2goserver.pid"); -- Alioth's /srv/git/_hooks_/post-receive-email on /srv/git/code.x2go.org/x2goserver.git