This is an automated email from the git hooks/post-receive script.

x2go pushed a commit to branch master
in repository x2goserver.

commit 6cb9bb10b8d476572a7d47dc5e1b0987c49aaea8
Author: Mihai Moldovan <[email protected]>
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.
    
    Cherry-picked from release/4.0.1.x branch.
---
 debian/changelog                  |   5 ++
 x2goserver/bin/x2goresume-session |  85 ++++++++++-----------
 x2goserver/bin/x2gostartagent     | 151 +++++++++++++-------------------------
 3 files changed, 99 insertions(+), 142 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index f247d8e..55854d1 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -310,6 +310,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 5cac4e1..b624c97 100755
--- a/x2goserver/bin/x2goresume-session
+++ b/x2goserver/bin/x2goresume-session
@@ -170,12 +170,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
@@ -223,44 +217,51 @@ 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" == "" ] 
|| [ "$TEKICTRL_PORT" == "" ] || [ "$TEKIDATA_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}" ] || 
[ -z "${TEKICTRL_PORT}" ] || [ -z "${TEKIDATA_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"
-       elif [ "$FS_PORT" == "" ]; then
-               FS_PORT="$SSH_PORT"
-       elif [ "$TEKICTRL_PORT" == "" ]; then
-               TEKICTRL_PORT="$SSH_PORT"
-       elif [ "$TEKIDATA_PORT" == "" ]; then
-               TEKIDATA_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}"
+       elif [ -z "${FS_PORT}" ]; then
+               FS_PORT="${SSH_PORT}"
+       elif [ -z "${TEKICTRL_PORT}" ]; then
+               TEKICTRL_PORT="${SSH_PORT}"
+       elif [ -z "${TEKIDATA_PORT}" ]; then
+               TEKIDATA_PORT="${SSH_PORT}"
        fi
 done
 
diff --git a/x2goserver/bin/x2gostartagent b/x2goserver/bin/x2gostartagent
index bf9bf41..c209044 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
@@ -216,53 +216,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
                if [ -n "${SHADREQ_USER}" ]; then
                        SESSION_NAME="${SHADREQ_USER}-${X2GO_PORT}-$(date 
"+%s")"
                else
@@ -278,36 +239,31 @@ while [ "${OUTPUT}" != "inserted" ]; do
 
                if [ -n "${SHADREQ_USER}" ]; then
                        "${X2GO_LIB_PATH}/x2gosyslog" "${0}" 'debug' 
"initializing new shadow session with ID ${SESSION_NAME}"
-                       OUTPUT="$("${X2GO_LIB_PATH}/x2goinsertshadowsession" 
"${X2GO_PORT}" "${current_host_name}" "${SESSION_NAME}" "${SHADREQ_USER}")"
-
-                       # 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}), 
session name (${SESSION_NAME}) and user requesting desktop sharing permissions 
(${SHADREQ_USER})."
-                       #       "${X2GO_LIB_PATH}/x2gosyslog" "${0}" "err" 
"${msg}"
-                       #
-                       #       # Make x2goclient fail.
-                       #       echo "${msg}" >&2
-                       #       exit 1
-                       #fi
+                       output="$("${X2GO_LIB_PATH}/x2goinsertshadowsession" 
"${X2GO_PORT}" "${current_host_name}" "${SESSION_NAME}" "${SHADREQ_USER}")"
                else
                        "${X2GO_LIB_PATH}/x2gosyslog" "${0}" 'debug' 
"initializing new session with ID ${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 1
-                       #fi
+                       output="$("${X2GO_LIB_PATH}/x2goinsertsession" 
"${X2GO_PORT}" "${current_host_name}" "${SESSION_NAME}")"
+               fi
+
+               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
+
 if [ "x$X2GO_TELEKINESIS_ENABLED" == "x0" ] || [ "x$X2GO_STYPE" = "xS" ] || ! 
type -p telekinesis-server 1>/dev/null; then
        TEKICTRL_PORT="-1"
        TEKIDATA_PORT="-1"
@@ -315,38 +271,33 @@ if [ "x$X2GO_TELEKINESIS_ENABLED" == "x0" ] || [ 
"x$X2GO_STYPE" = "xS" ] || ! ty
 fi
 
 while [ -z "${GR_PORT}" ] || [ -z "${SOUND_PORT}" ] || [ -z "${FS_PORT}" ] || 
[ -z "${TEKICTRL_PORT}" ] || [ -z "${TEKIDATA_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
_______________________________________________
x2go-commits mailing list
[email protected]
https://lists.x2go.org/listinfo/x2go-commits

Reply via email to