From 1f0682ca1b24565ec95796a0fa0774793eafaed7 Mon Sep 17 00:00:00 2001 From: Weisson Date: Fri, 14 Jun 2024 19:30:01 +0800 Subject: [PATCH] Set timeout threshold for alibaba ecs identification to avoid hanging. On Alibaba ECS/EBM, virt-what used to run this tricky shell command: ``` ( { echo -e "GET /latest/meta-datainstance/instance-type HTTP/1.0\r\nHost: 100.100.100.200\r\n\r" >&3; grep -sq 'ebm' <&3 ; } 3<> /dev/tcp/100.100.100.200/80 ) 2>/dev/null ``` which means the host fetches metadata and identifies its flavor. However, the remote server '100.100.100.200' is accessible only within Alibaba Cloud network, which keeps those hosts, not in that condition mentioned above, hanging until syscall 'connect' timeout and get interrupted by kernel, or even worse, hanging forever. This commit set 1 second timeout at most for meta-data fetching process to avoid that kind of hanging. Signed-off-by: Weisson --- tests/alibaba-cloud-arm/sbin/timeout | 11 +++++++++++ tests/alibaba-cloud-x86/sbin/timeout | 11 +++++++++++ virt-what.in | 24 +++++++++++++++++++++--- 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100755 tests/alibaba-cloud-arm/sbin/timeout create mode 100755 tests/alibaba-cloud-x86/sbin/timeout diff --git a/tests/alibaba-cloud-arm/sbin/timeout b/tests/alibaba-cloud-arm/sbin/timeout new file mode 100755 index 0000000..b5eae13 --- /dev/null +++ b/tests/alibaba-cloud-arm/sbin/timeout @@ -0,0 +1,11 @@ +#!/bin/sh - + +if [ $# -ne 0 ]; then + exit 0; +fi + +# fake metadata +echo ecs.xxxxx.large + +# fake timeout behavior +exit 124 diff --git a/tests/alibaba-cloud-x86/sbin/timeout b/tests/alibaba-cloud-x86/sbin/timeout new file mode 100755 index 0000000..b5eae13 --- /dev/null +++ b/tests/alibaba-cloud-x86/sbin/timeout @@ -0,0 +1,11 @@ +#!/bin/sh - + +if [ $# -ne 0 ]; then + exit 0; +fi + +# fake metadata +echo ecs.xxxxx.large + +# fake timeout behavior +exit 124 diff --git a/virt-what.in b/virt-what.in index 5ccf49e..7fd6cce 100644 --- a/virt-what.in +++ b/virt-what.in @@ -115,11 +115,29 @@ arch=$(uname -m | sed -e 's/i.86/i386/' | sed -e 's/arm.*/arm/') # Check for Alibaba Cloud if echo "$dmi" | grep -q 'Manufacturer: Alibaba'; then - # Check for Alibaba Cloud ECS Bare Metal (EBM) Instance - if [ "x$root" = "x" ] && ( { echo -e "GET /latest/meta-datainstance/instance-type HTTP/1.0\r\nHost: 100.100.100.200\r\n\r" >&3; grep -sq 'ebm' <&3 ; } 3<> /dev/tcp/100.100.100.200/80 ) 2>/dev/null ; then - echo "alibaba_cloud-ebm" + if $(timeout --version >/dev/null 2>&1); then + timeout_cmd_prefix="timeout 1s" + timeout_cmp="-eq" + timeout_return_value=124 else + timeout_cmd_prefix="" + timeout_cmp="-ne" + timeout_return_value=0 + fi + + # Check for Alibaba Cloud ECS Bare Metal (EBM) Instance + metadata=$($timeout_cmd_prefix sh -c '( { echo -e "GET /latest/meta-datainstance/instance-type HTTP/1.0\r\nHost: 100.100.100.200\r\n\r" >&3; grep -s 'ebm' <&3 ; } 3<> /dev/tcp/100.100.100.200/80 ) 2>/dev/null') + ret_value=$? + if [ $ret_value $timeout_cmp $timeout_return_value ]; then + # a timeout occurred when fetching metadata, assuming remote host unaccessible + # which means it might be a non-cloud environment, or test environment. echo "alibaba_cloud" + else + if [ -z "$metadata" ] ; then + echo "alibaba_cloud" + else + echo "alibaba_cloud-ebm" + fi fi fi -- 1.8.3.1