[X2Go-Commits] [x2goserver] 16/27: x2goserver/bin/x2go{startagent, resume-session}: use x2gogetfreeport instead of duplicating the same code everywhere. Fixes: #1230.

git-admin at x2go.org git-admin at x2go.org
Wed Jan 10 00:17:58 CET 2018


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 7a76b291ed589775ee5d84c34b677fd621ce6d11
Author: Mihai Moldovan <ionic at ionic.de>
Date:   Thu Jan 4 06:16:51 2018 +0100

    x2goserver/bin/x2go{startagent,resume-session}: use x2gogetfreeport instead of duplicating the same code everywhere. Fixes: #1230.
    
    Also, rely on it returning a valid value and try at most 10 times to
    fetch a usable port value, then error out and make the session startup
    or resumption fail.
---
 debian/changelog                  |   5 ++
 x2goserver/bin/x2goresume-session |  75 ++++++++++-----------
 x2goserver/bin/x2gostartagent     | 136 ++++++++++++++------------------------
 3 files changed, 92 insertions(+), 124 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 818e823..f8582d4 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -51,6 +51,11 @@ x2goserver (4.0.1.23-0x2go1) UNRELEASED; urgency=medium
       quotes on the lib path line.
     - x2goserver/bin/x2goresume-session: properly randomize first port, just
       like in x2gostartagent.
+    - x2goserver/bin/x2go{startagent,resume-session}: use x2gogetfreeport
+      instead of duplicating the same code everywhere. Fixes: #1230. Also,
+      rely on it returning a valid value and try at most 10 times to fetch a
+      usable port value, then error out and make the session startup or
+      resumption fail.
   * x2goserver.spec:
     - RPMify x2goserver-xsession description.
     - Remove qt4 stuff, we're not using the framework here.
diff --git a/x2goserver/bin/x2goresume-session b/x2goserver/bin/x2goresume-session
index 34b8f2d..0d2d8ce 100755
--- a/x2goserver/bin/x2goresume-session
+++ b/x2goserver/bin/x2goresume-session
@@ -162,12 +162,6 @@ SERVER=`echo "$SESSIONINFO" | awk -F, {'print $4'}`
 
 $X2GO_LIB_PATH/x2gosyslog "$0" "debug" "old ports: $GR_PORT, $SOUND_PORT, $FS_PORT"
 
-#Get all used in system ports from ss output
-ss=$(PATH="$PATH:/usr/sbin:/sbin" type -P ss);
-USED_PORTS=$(
-	"$ss" -nt -all |
-	awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }';
-);
 
 #check if saved in DB ports free
 if grep -q "|${GR_PORT}|" <<<$SYSTEM_PORTS ; then
@@ -195,40 +189,47 @@ if ! SSH_PORT="$("${X2GO_LIB_PATH}/x2gogetrandomport")"; then
 	exit "1"
 fi
 
-#Get all used in system ports from X2Go database and netstat output
-USED_PORTS="$("${X2GO_LIB_PATH}/x2gogetports" "${current_host_name}"; netstat -nt -all | awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }')"
-
-while [ "$GR_PORT" == "" ] || [ "$SOUND_PORT" == "" ] || [ "$FS_PORT" == "" ]; do
-	OUTPUT=""
-	while [ "$OUTPUT"  != "inserted" ]; do
-		SSH_PORT=$(($SSH_PORT + 1))
-
-		#get free port
-		SSH_PORT=`echo "for(\\$i=$SSH_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_PORTS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl`
-
-		#check if port in /etc/services
-		SERV=`grep $SSH_PORT /etc/services`
-		if [ "$SERV" == "" ]; then
-			OUTPUT="$("${X2GO_LIB_PATH}/x2goinsertport" "${current_host_name}" "$SESSION_NAME" "$SSH_PORT")"
-
-			# Catching errors here would be nice, but the current layout doesn't allow this.
-			# Keep this in mind as a FIXME.
-			#if [[ "${?}" -ne "0" ]]; then
-			#	typeset msg="Unable to insert new port into database; parameters: hostname (${current_host_name}), session name (${SESSION_NAME}) and port (${SSH_PORT})."
-			#	"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
-			#
-			#	# Make x2goclient fail.
-			#	echo "${msg}" >&2
-			#	exit 1
-			#fi
+# define the full path to the ss utility
+typeset ss="$(PATH="${PATH}:/usr/sbin:/sbin" type -P 'ss')"
+
+typeset -i retry='0'
+typeset -i max_retry='10'
+typeset -i free_port='0'
+typeset output=''
+while [ -z "${GR_PORT}" ] || [ -z "${SOUND_PORT}" ] || [ -z "${FS_PORT}" ]; do
+	output=''
+	for ((retry = 0; retry < max_retry; ++retry)); do
+		free_port='0'
+		if free_port="$("${X2GO_LIB_PATH}/x2gogetfreeport" "${ss}" 'lowlevel' "${SSH_PORT}")"; then
+			SSH_PORT="${free_port}"
+
+			output="$("${X2GO_LIB_PATH}/x2goinsertport" "${current_host_name}" "${SESSION_NAME}" "${SSH_PORT}")"
+
+			if [[ "${output}" = "inserted" ]]; then
+				break
+			else
+				"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "unable to insert port into database. Retrying (run $((retry + 1)))."
+			fi
+		else
+			"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "no free port available, cannot start new session. Retrying (run $((retry + 1)))."
 		fi
 	done
-	if [ "$GR_PORT" == "" ]; then
-		GR_PORT="$SSH_PORT"
-	elif [ "$SOUND_PORT" == "" ]; then
-		SOUND_PORT="$SSH_PORT"
+
+	if [[ "${output}" != "inserted" ]]; then
+		typeset msg="Unable to find free port or insert new session into database; parameters: hostname (${current_host_name}), session name (${SESSION_NAME}) and port (${SSH_PORT})."
+		"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
+
+		# Make x2goclient fail.
+		echo "${msg}" >&2
+		exit "12"
+	fi
+
+	if [ -z "${GR_PORT}" ]; then
+		GR_PORT="${SSH_PORT}"
+	elif [ -z "${SOUND_PORT}" ]; then
+		SOUND_PORT="${SSH_PORT}"
 	else
-		FS_PORT="$SSH_PORT"
+		FS_PORT="${SSH_PORT}"
 	fi
 done
 
diff --git a/x2goserver/bin/x2gostartagent b/x2goserver/bin/x2gostartagent
index 033ad68..d11221a 100755
--- a/x2goserver/bin/x2gostartagent
+++ b/x2goserver/bin/x2gostartagent
@@ -33,7 +33,7 @@ if ! SSH_PORT="$("${X2GO_LIB_PATH}/x2gogetrandomport")"; then
 	exit "1"
 fi
 
-X2GO_PORT="49" #First port for X2GO=50
+X2GO_PORT="50"
 
 # some sanity checks before session startup...
 if grep -E "^backend[ ]*=[ ]*postgres" "/etc/x2go/x2gosql/sql" 1>"/dev/null" 2>"/dev/null" && [ "x${USER}" = "xroot" ]; then
@@ -213,53 +213,14 @@ fi
 # define the full path to the ss utility
 ss="$(PATH="${PATH}:/usr/sbin:/sbin" type -P "ss")"
 
-while [ "${OUTPUT}" != "inserted" ]; do
+typeset -i retry='0'
+typeset -i max_retry='10'
+typeset -i output=''
+for ((retry = 0; retry < max_retry; ++retry)); do
+	typeset -i free_port="${X2GO_PORT}"
+	if free_port="$("${X2GO_LIB_PATH}/x2gogetfreeport" "${ss}" 'display' "${X2GO_PORT}")"; then
+		X2GO_PORT="${free_port}"
 
-	typeset -a used_displays
-	IFS='' read -ar used_displays < <("${X2GO_LIB_PATH}/x2gogetdisplays" "${current_host_name}")
-
-	# Get all used in system ports from X2Go database and ss output
-	USED_PORTS="$(
-	    "${X2GO_LIB_PATH}/x2gogetports" "${current_host_name}";
-	    "${ss}" -nt -all |
-	    awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }';
-	)"
-
-	X2GO_PORT="$((X2GO_PORT + 1))"
-
-	typeset -i search_x2go_port="0"
-
-	# Find the next free port number.
-	for ((search_x2go_port = X2GO_PORT; i <= 59535; ++search_x2go_port)); do
-		typeset -i i="0"
-		typeset -i value_found="0"
-
-		for ((i = 0; i < ${#used_displays[@]}; ++i)); do
-			if [[ "${used_displays[i]}" =~ /|${search_x2go_port}|/ ]]; then
-				# We need to continue with the next port number,
-				# this one is taken.
-				value_found="1"
-				break
-			fi
-		done
-
-		# Searched the array and got nothing? Great, grab that port number!
-		[[ "${value_found}" -eq "0" ]] && break
-	done
-
-	if [[ "${search_x2go_port}" -gt "59535" ]]; then
-		"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "no free display number available, cannot start new session"
-		exit "10"
-	fi
-
-	X2GO_PORT="${search_x2go_port}"
-
-	# Test if the session is already in use. nxagent uses 6000+DISPLAY to open a port. Therefore this must be tested, too.
-	NX_PORT="$((X2GO_PORT + 6000))"
-	if "${ss}" -lxs 2>"/dev/null" | grep -E "(@|)/tmp/.X11-unix/X${X2GO_PORT}(|-lock) " >"/dev/null" ||
-		grep -q "|${NX_PORT}|" <<< "${USED_PORTS}"; then
-		OUTPUT="XXX"
-	else
 		SESSION_NAME="${USER}-${X2GO_PORT}-$(date "+%s")"
 		if [ "${COLORDEPTH}" != "" ]; then
 			SESSION_NAME="${SESSION_NAME}_st${SESSION_TYPE}${X2GO_CMD}_dp${COLORDEPTH}"
@@ -269,54 +230,55 @@ while [ "${OUTPUT}" != "inserted" ]; do
 		# sanitize session name
 		SESSION_NAME="$(perl -pe "s/[^a-zA-Z0-9\.\_\-\@]//g" <<< "${SESSION_NAME}")"
 
-		OUTPUT="$("${X2GO_LIB_PATH}/x2goinsertsession" "${X2GO_PORT}" "${current_host_name}" "${SESSION_NAME}")"
-		# Catching errors here would be nice, but the current layout doesn't allow this.
-		# Keep this in mind as a FIXME.
-		#if [[ "${?}" -ne "0" ]]; then
-		#	typeset msg="Unable to insert new session into database; parameters: port (${X2GO_PORT}), hostname (${current_host_name}) and session name (${SESSION_NAME})."
-		#	"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
-		#
-		#	# Make x2goclient fail.
-		#	echo "${msg}" >&2
-		#	exit "11"
-		#fi
+		output="$("${X2GO_LIB_PATH}/x2goinsertsession" "${X2GO_PORT}" "${current_host_name}" "${SESSION_NAME}")"
+
+		if [[ "${output}" = "inserted" ]]; then
+			break
+		else
+			"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "unable to insert display port into database. Retrying (run $((retry + 1)))."
+		fi
+	else
+		"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "no free display number available, cannot start new session. Retrying (run $((retry + 1)))."
 	fi
 done
 
+if [[ "${output}" != "inserted" ]]; then
+	typeset msg="Unable to find free display port or insert new session into database; parameters: port (${X2GO_PORT}), hostname (${current_host_name}) and session name (${SESSION_NAME})."
+	"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
+
+	# Make x2goclient fail.
+	echo "${msg}" >&2
+	exit "11"
+fi
 
 while [ -z "${GR_PORT}" ] || [ -z "${SOUND_PORT}" ] || [ -z "${FS_PORT}" ]; do
-	OUTPUT=""
-	while [ "${OUTPUT}" != "inserted" ]; do
-		SSH_PORT="$((SSH_PORT + 1))"
-
-		# Get all used in system ports from X2Go database and ss output
-		USED_PORTS="$(
-		    "$X2GO_LIB_PATH/x2gogetports" "${current_host_name}";
-		    "${ss}" -nt -all |
-		    awk '{ n=split($0,lines,"\n"); for(i=1;i<=n;i++){split (lines[i],words," ");delim=split(words[4],ports,":"); if(delim>1)printf ("|%s|\n",ports[delim])} }';
-		)"
-
-		# get free port
-		SSH_PORT=`echo "for(\\$i=$SSH_PORT;\\$br ne \"true\";\\$i++){ if(\"$USED_PORTS\" =~ m/\\|\\$i\\|/){\\$br=\"false\";}else{\\$br=\"true\";print \\$i;}}"|perl`
-
-		# check if port in /etc/services
-		SERV="$(grep "${SSH_PORT}" "/etc/services")"
-		if [ "${SERV}" == "" ]; then
-			OUTPUT="$("${X2GO_LIB_PATH}/x2goinsertport" "${current_host_name}" "${SESSION_NAME}" "${SSH_PORT}")"
-
-			# Catching errors here would be nice, but the current layout doesn't allow this.
-			# Keep this in mind as a FIXME.
-			#if [[ "${?}" -ne "0" ]]; then
-			#	typeset msg="Unable to insert new port into database; parameters: hostname (${current_host_name}), session name (${SESSION_NAME}) and port (${SSH_PORT})."
-			#	"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
-			#
-			#	# Make x2goclient fail.
-			#	echo "${msg}" >&2
-			#	exit "12"
-			#fi
+	output=''
+	for ((retry = 0; retry < max_retry; ++retry)); do
+		free_port='0'
+		if free_port="$("${X2GO_LIB_PATH}/x2gogetfreeport" "${ss}" 'lowlevel' "${SSH_PORT}")"; then
+			SSH_PORT="${free_port}"
+
+			output="$("${X2GO_LIB_PATH}/x2goinsertport" "${current_host_name}" "${SESSION_NAME}" "${SSH_PORT}")"
+
+			if [[ "${output}" = "inserted" ]]; then
+				break
+			else
+				"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "unable to insert port into database. Retrying (run $((retry + 1)))."
+			fi
+		else
+			"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "warning" "no free port available, cannot start new session. Retrying (run $((retry + 1)))."
 		fi
 	done
 
+	if [[ "${output}" != "inserted" ]]; then
+		typeset msg="Unable to find free port or insert new session into database; parameters: hostname (${current_host_name}), session name (${SESSION_NAME}) and port (${SSH_PORT})."
+		"${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" "${msg}"
+
+		# Make x2goclient fail.
+		echo "${msg}" >&2
+		exit "12"
+	fi
+
 	if [ -z "${GR_PORT}" ]; then
 		GR_PORT="${SSH_PORT}"
 	elif [ -z "${SOUND_PORT}" ]; then

--
Alioth's /home/x2go-admin/maintenancescripts/git/hooks/post-receive-email on /srv/git/code.x2go.org/x2goserver.git


More information about the x2go-commits mailing list