25
1
mirror of https://github.com/processone/ejabberd.git synced 2024-11-20 16:15:59 +01:00

Rework temporary node name generation in ejabberdctl

This should limit number of possible node names generated by and with that
prevent atom space exhaustion in ejabberd process.

On R23+ we switch to using native dynamic node features and on older
versions we iterate over small number of possible names and skip those
already in use.
This commit is contained in:
Paweł Chmielowski 2024-02-07 12:10:01 +01:00
parent c81a47a692
commit 95135af6b3
2 changed files with 63 additions and 27 deletions

View File

@ -227,16 +227,27 @@ help()
} }
# dynamic node name helper # dynamic node name helper
uid() uid() {
{ if erl -noinput -boot start_clean -eval 'case erlang:system_info(otp_release) >= "23" of true -> halt(1); _ -> halt(0) end.' ; then
uuid=$(uuidgen 2>/dev/null) N=1
random=$(awk 'BEGIN { srand(); print int(rand()*32768) }' /dev/null) PF=$(( $$ % 97 ))
[ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid) while
[ -z "$uuid" ] && uuid=$(printf "%X" "${random:-$$}$(date +%M%S)") case $# in
uuid=$(printf '%s' $uuid | sed 's/^\(...\).*$/\1/') 0) NN="${PF}-${N}-${ERLANG_NODE}"
[ $# -eq 0 ] && echo "${uuid}-${ERLANG_NODE}" ;;
[ $# -eq 1 ] && echo "${uuid}-${1}-${ERLANG_NODE}" 1) NN="${PF}-${N}-${1}-${ERLANG_NODE}"
[ $# -eq 2 ] && echo "${uuid}-${1}@${2}" ;;
2) NN="${PF}-${N}-${1}@${2}"
;;
esac
N=$(( N + 1 + ( $$ % 5 ) ))
epmd -names 2>/dev/null | grep -q " ${NN%@*} "
do :; done
echo $NN
else
# for R23+ use native dynamic node code
echo undefined
fi
} }
# stop epmd if there is no other running node # stop epmd if there is no other running node
@ -307,7 +318,9 @@ wait_status()
if [ $timeout -eq 0 ] ; then if [ $timeout -eq 0 ] ; then
status="$1" status="$1"
else else
run_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \ run_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s ejabberd_ctl \
-extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null -extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
status="$?" status="$?"
fi fi
@ -350,7 +363,9 @@ case $1 in
;; ;;
etop) etop)
set_dist_client set_dist_client
exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" -s etop \ exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s etop \
-s erlang halt -output text -s erlang halt -output text
;; ;;
iexdebug) iexdebug)
@ -367,7 +382,9 @@ case $1 in
[ "$PEER" = "${PEER%.*}" ] && PS="-s" [ "$PEER" = "${PEER%.*}" ] && PS="-s"
set_dist_client set_dist_client
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \ exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
-noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \ -noinput -hidden \
-eval 'net_kernel:connect_node('"'$PEER'"')' \
-eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
-s erlang halt -output text -s erlang halt -output text
;; ;;
started) started)
@ -383,7 +400,9 @@ case $1 in
;; ;;
*) *)
set_dist_client set_dist_client
run_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \ run_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s ejabberd_ctl \
-extra "$ERLANG_NODE" $NO_TIMEOUT "$@" -extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
result=$? result=$?
case $result in case $result in

View File

@ -248,16 +248,27 @@ help()
} }
# dynamic node name helper # dynamic node name helper
uid() uid() {
{ if erl -noinput -boot start_clean -eval 'case erlang:system_info(otp_release) >= "23" of true -> halt(1); _ -> halt(0) end.' ; then
uuid=$(uuidgen 2>/dev/null) N=1
random=$(awk 'BEGIN { srand(); print int(rand()*32768) }' /dev/null) PF=$(( $$ % 97 ))
[ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid) while
[ -z "$uuid" ] && uuid=$(printf "%X" "${random:-$$}$(date +%M%S)") case $# in
uuid=$(printf '%s' $uuid | sed 's/^\(...\).*$/\1/') 0) NN="${PF}-${N}-${ERLANG_NODE}"
[ $# -eq 0 ] && echo "${uuid}-${ERLANG_NODE}" ;;
[ $# -eq 1 ] && echo "${uuid}-${1}-${ERLANG_NODE}" 1) NN="${PF}-${N}-${1}-${ERLANG_NODE}"
[ $# -eq 2 ] && echo "${uuid}-${1}@${2}" ;;
2) NN="${PF}-${N}-${1}@${2}"
;;
esac
N=$(( N + 1 + ( $$ % 5 ) ))
epmd -names 2>/dev/null | grep -q " ${NN%@*} "
do :; done
echo $NN
else
# for R23+ use native dynamic node code
echo undefined
fi
} }
# stop epmd if there is no other running node # stop epmd if there is no other running node
@ -300,7 +311,9 @@ wait_status()
if [ $timeout -eq 0 ] ; then if [ $timeout -eq 0 ] ; then
status="$1" status="$1"
else else
exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \ exec_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s ejabberd_ctl \
-extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null -extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
status="$?" status="$?"
fi fi
@ -361,7 +374,9 @@ case $1 in
[ "$PEER" = "${PEER%.*}" ] && PS="-s" [ "$PEER" = "${PEER%.*}" ] && PS="-s"
set_dist_client set_dist_client
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \ exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
-noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \ -noinput -hidden \
-eval 'net_kernel:connect_node('"'$PEER'"')' \
-eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
-s erlang halt -output text -s erlang halt -output text
;; ;;
started) started)
@ -374,7 +389,9 @@ case $1 in
;; ;;
*) *)
set_dist_client set_dist_client
exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \ exec_erl "$(uid ctl)" -hidden -noinput \
-eval 'net_kernel:connect_node('"'$ERLANG_NODE'"')' \
-s ejabberd_ctl \
-extra "$ERLANG_NODE" $NO_TIMEOUT "$@" -extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
result=$? result=$?
case $result in case $result in