update
This commit is contained in:
@@ -94,7 +94,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-gnb:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
container_name: oai-gnb
|
||||
cap_drop:
|
||||
- ALL
|
||||
@@ -105,6 +105,7 @@ services:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.140
|
||||
volumes:
|
||||
# - ../../conf_files/gnb.sa.band78.273prb.rfsim.2x2.conf:/opt/oai-gnb/etc/gnb.conf
|
||||
- ../../conf_files/gnb.sa.band78.106prb.rfsim.yaml:/opt/oai-gnb/etc/gnb.yaml
|
||||
healthcheck:
|
||||
test: /bin/bash -c "pgrep nr-softmodem"
|
||||
@@ -115,7 +116,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-flexric:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
container_name: oai-flexric
|
||||
command: ["-c", "stdbuf -o0 /oai-ran/openair2/E2AP/flexric/build/examples/ric/nearRT-RIC"]
|
||||
networks:
|
||||
@@ -130,8 +131,14 @@ services:
|
||||
timeout: 5s
|
||||
|
||||
xapp-chatgpt:
|
||||
image: nakaolab:oct1
|
||||
command: ["-c", "XAPP_DURATION=20 stdbuf -oL /oai-ran/openair2/E2AP/flexric/build/examples/xApp/c/monitor/xapp_chatgpt"]
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "XAPP_DURATION=3600 /oai-ran/openair2/E2AP/flexric/build/examples/xApp/c/monitor/xapp_chatgpt"]
|
||||
# command: ["-lc","ulimit -c unlimited; export XAPP_DURATION=3600; gdb -q -batch \
|
||||
# -ex 'set pagination off' \
|
||||
# -ex run \
|
||||
# -ex 'bt full' \
|
||||
# -ex 'thread apply all bt full' \
|
||||
# --args /oai-ran/openair2/E2AP/flexric/build/examples/xApp/c/monitor/xapp_chatgpt"]
|
||||
container_name: xapp-chatgpt
|
||||
environment:
|
||||
- TZ=Asia/Tokyo
|
||||
@@ -147,7 +154,7 @@ services:
|
||||
timeout: 5s
|
||||
|
||||
oai-nr-ue1:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue1
|
||||
cap_drop:
|
||||
@@ -155,8 +162,6 @@ services:
|
||||
cap_add:
|
||||
- NET_ADMIN # for interface bringup
|
||||
- NET_RAW # for ping
|
||||
# environment:
|
||||
# USE_ADDITIONAL_OPTIONS: -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001100 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
@@ -175,7 +180,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue2:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001101 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue2
|
||||
cap_drop:
|
||||
@@ -201,7 +206,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue3:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001102 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue3
|
||||
cap_drop:
|
||||
@@ -227,7 +232,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue4:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001103 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue4
|
||||
cap_drop:
|
||||
@@ -253,7 +258,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue5:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001104 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue5
|
||||
cap_drop:
|
||||
@@ -279,7 +284,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue6:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001105 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue6
|
||||
cap_drop:
|
||||
@@ -305,7 +310,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue7:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001106 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue7
|
||||
cap_drop:
|
||||
@@ -331,7 +336,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue8:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001107 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue8
|
||||
cap_drop:
|
||||
@@ -357,7 +362,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue9:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001108 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue9
|
||||
cap_drop:
|
||||
@@ -365,12 +370,6 @@ services:
|
||||
cap_add:
|
||||
- NET_ADMIN # for interface bringup
|
||||
- NET_RAW # for ping
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
- SYS_NICE
|
||||
environment:
|
||||
USE_ADDITIONAL_OPTIONS: -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001109 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time
|
||||
>>>>>>> 2025.w42
|
||||
depends_on:
|
||||
- oai-gnb
|
||||
networks:
|
||||
@@ -389,7 +388,7 @@ services:
|
||||
retries: 5
|
||||
|
||||
oai-nr-ue10:
|
||||
image: nakaolab:oct1
|
||||
image: nakaolab:oct29
|
||||
command: ["-c", "stdbuf -oL /oai-ran/cmake_targets/ran_build/build/nr-uesoftmodem -E --rfsim -r 106 --numerology 1 --uicc0.imsi 208990100001109 -C 3319680000 --rfsimulator.serveraddr 192.168.71.140 --log_config.global_log_options level,nocolor,time"]
|
||||
container_name: oai-nr-ue10
|
||||
cap_drop:
|
||||
@@ -411,25 +410,36 @@ services:
|
||||
interval: 10s
|
||||
timeout: 5s
|
||||
retries: 5
|
||||
|
||||
# iperf:
|
||||
# image: phlak/iperf
|
||||
# container_name: iperf
|
||||
|
||||
# iperf3:
|
||||
# image: networkstatic/iperf3:latest
|
||||
# container_name: iperf3
|
||||
# command: ["-c 'for p in $(seq 5201 5210); do iperf3 -s -p $$p & done;'"]
|
||||
# ports:
|
||||
# - "5201:5201/tcp"
|
||||
# - "5201:5201/udp"
|
||||
# - "5201-5210:5201-5210/tcp"
|
||||
# - "5201-5210:5201-5210/udp"
|
||||
# networks:
|
||||
# traffic_net:
|
||||
# ipv4_address: 192.168.72.130
|
||||
# public_net:
|
||||
# ipv4_address: 192.168.71.130
|
||||
# restart: unless-stopped
|
||||
|
||||
iperf:
|
||||
|
||||
iperf_udp:
|
||||
image: mlabbe/iperf
|
||||
container_name: iperf
|
||||
command: ["-s", "-p 5201"]
|
||||
container_name: iperf_udp
|
||||
command: ["-u -s -p 5201"]
|
||||
ports:
|
||||
- "5201:5201/tcp"
|
||||
- "5201:5201/udp"
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.129
|
||||
restart: unless-stopped
|
||||
|
||||
iperf_tcp:
|
||||
image: mlabbe/iperf
|
||||
container_name: iperf_tcp
|
||||
command: ["-s -p 5202"]
|
||||
ports:
|
||||
- "5202:5202/tcp"
|
||||
networks:
|
||||
public_net:
|
||||
ipv4_address: 192.168.71.130
|
||||
|
||||
@@ -1,28 +1,21 @@
|
||||
#!/bin/bash
|
||||
# Examples:
|
||||
# ./exp-35.sh
|
||||
# UE_MIN=2 UE_MAX=12 UE_PEAK_HOUR=14 UE_NOISE_FRAC=0.15 ./exp-35.sh
|
||||
# TEST_UE=oai-nr-ue1 TEST_PROFILE=browsing TEST_DURATION_SEC=120 ./exp-35.sh
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# --- UE profile map (index 0..10). 0-index kept for convenience ---
|
||||
# Initialize with "0" to denote no profile chosen.
|
||||
declare -a UE_PROFILE_MAP
|
||||
for i in {0..10}; do UE_PROFILE_MAP[$i]=0; done
|
||||
|
||||
# ---------------------------[ Random Burst Mode ]----------------------------
|
||||
# ---------------------------[ Random / diurnal Mode ]----------------------------
|
||||
# UE scaler mode: 'random' (rapid random targets) or 'diurnal' (legacy cosine)
|
||||
UE_SCALER_MODE="${UE_SCALER_MODE:-random}"
|
||||
# Interval (sec) for scaler ticks
|
||||
UE_SCALER_INTERVAL_SEC="${UE_SCALER_INTERVAL_SEC:-30}"
|
||||
|
||||
# Rapid/random system-level bursts: every few minutes trigger a short, global burst
|
||||
# that nudges all UEs to start/extend a session at once. UE-side script watches
|
||||
# /tmp/system_burst and reacts (see traffic_runner --profile random).
|
||||
RANDOM_BURST_MODE="${RANDOM_BURST_MODE:-1}" # 1=enabled, 0=disabled
|
||||
BURST_MIN_GAP_SEC="${BURST_MIN_GAP_SEC:-180}" # 3 minutes
|
||||
BURST_MAX_GAP_SEC="${BURST_MAX_GAP_SEC:-600}" # 10 minutes
|
||||
BURST_MARK_FILE="${BURST_MARK_FILE:-/tmp/system_burst}"
|
||||
# -------------------------------[ Config ]------------------------------------
|
||||
|
||||
ARTIFACT_DIR="/home/nakaolab-go/OAI/research-main/artifacts/"
|
||||
ARTIFACT_DIR="/media/nakaolab-go/2nd/artifacts"
|
||||
mkdir -p "$ARTIFACT_DIR"
|
||||
|
||||
POWER_LOG_FILE="${POWER_LOG_FILE:-$ARTIFACT_DIR/power_usage.csv}"
|
||||
@@ -30,19 +23,19 @@ CPU_PROXY_LOG_FILE="${CPU_PROXY_LOG_FILE:-$ARTIFACT_DIR/cpu_proxy.csv}"
|
||||
RRC_SINCE_STATE="${RRC_SINCE_STATE:-$ARTIFACT_DIR/.rrc_since}"
|
||||
|
||||
# xApp (mac stats) container + path inside container
|
||||
MAC_STATS_CONTAINER="${MAC_STATS_CONTAINER:-xapp-chatgpt}"
|
||||
STATS_CONTAINER="${STATS_CONTAINER:-xapp-chatgpt}"
|
||||
MAC_STATS_FILE_IN_CONTAINER="${MAC_STATS_FILE_IN_CONTAINER:-/tmp/mac_stats.log}"
|
||||
PDCP_STATS_FILE_IN_CONTAINER="${PDCP_STATS_FILE_IN_CONTAINER:-/tmp/pdcp_stats.log}"
|
||||
|
||||
# Intervals (seconds)
|
||||
RRC_LOG_INTERVAL_SEC="${RRC_LOG_INTERVAL_SEC:-10}"
|
||||
POWER_LOG_INTERVAL_SEC="${POWER_LOG_INTERVAL_SEC:-5}"
|
||||
CPU_PROXY_INTERVAL_SEC="${CPU_PROXY_INTERVAL_SEC:-5}"
|
||||
UE_SCALER_INTERVAL_SEC="${UE_SCALER_INTERVAL_SEC:-60}"
|
||||
|
||||
# Docker compose helper
|
||||
DC_BIN=(docker compose)
|
||||
dc() { command "${DC_BIN[@]}" "$@"; }
|
||||
dc down -v
|
||||
dc down -v --remove-orphans
|
||||
|
||||
# Service names (override if your compose uses different ones)
|
||||
AMF_SERVICE="${AMF_SERVICE:-oai-amf}"
|
||||
@@ -54,14 +47,14 @@ XAPP_SERVICE="${XAPP_SERVICE:-xapp-chatgpt}"
|
||||
UE_NAME_REGEX="${UE_NAME_REGEX:-^oai-nr-ue}"
|
||||
|
||||
# Test controls
|
||||
TEST_UE="${TEST_UE:-}" # e.g. oai-nr-ue1
|
||||
TEST_MODE="${TEST_MODE:-0}" # 1=manual profiles allowed (TEST_* honored); 0=auto
|
||||
TEST_UES="${TEST_UES:-}"
|
||||
TEST_PROFILES="${TEST_PROFILES:-}" # profile name
|
||||
TEST_DURATION_SEC="${TEST_DURATION_SEC:-0}" # 0 = run indefinitely
|
||||
|
||||
# Diurnal scaling controls (normal mode only; ignored if TEST_UE is set)
|
||||
UE_MIN="${UE_MIN:-1}" # Minimum number of UEs to keep connected
|
||||
# UE_MAX="${UE_MAX:-}" # Max UEs; default = total UEs in compose
|
||||
UE_MAX=10
|
||||
UE_MAX="${UE_MAX:-10}"
|
||||
UE_PEAK_HOUR="${UE_PEAK_HOUR:-17}" # Local hour with peak load (0..23)
|
||||
UE_NOISE_FRAC="${UE_NOISE_FRAC:-0.15}" # ±fractional noise applied to target
|
||||
|
||||
@@ -74,6 +67,7 @@ declare -A PWR_MW_PROFILE=(
|
||||
[voip]=520 # steady uplink/downlink small packets
|
||||
[video]=850 # continuous DL; 720–1080p
|
||||
[gaming]=950 # bursty DL + UL keepalives
|
||||
[boring]=500 # for single PRB testing
|
||||
[bulk_download]=1100 # sustained UL/DL at MCS ceiling
|
||||
)
|
||||
|
||||
@@ -101,14 +95,8 @@ get_core_services() {
|
||||
}
|
||||
|
||||
get_running_ues() {
|
||||
# Running UEs by service name (include TEST_UE name if custom)
|
||||
if [[ -n "${TEST_UE:-}" ]]; then
|
||||
dc ps --services --filter "status=running" \
|
||||
| grep -E "${UE_NAME_REGEX}|^${TEST_UE}$" || true
|
||||
else
|
||||
dc ps --services --filter "status=running" \
|
||||
| grep -E "${UE_NAME_REGEX}" || true
|
||||
fi
|
||||
dc ps --services --filter "status=running" \
|
||||
| grep -E "${UE_NAME_REGEX}" || true
|
||||
}
|
||||
|
||||
# -------------------------[ Readiness helpers ]-------------------------------
|
||||
@@ -153,7 +141,6 @@ wait_log() {
|
||||
local start; start="$(ts_now)"
|
||||
while :; do
|
||||
if dc logs "$svc" --since=2m 2>&1 | grep -Eiq -- "$pat"; then
|
||||
log "wait_log: detected '$pat' in '$svc'."
|
||||
return 0
|
||||
fi
|
||||
if (( $(ts_now) - start > timeout )); then
|
||||
@@ -174,15 +161,14 @@ get_container_ip() {
|
||||
|
||||
start_services_list() {
|
||||
[[ $# -eq 0 ]] && return 0
|
||||
dc up -d "$@"
|
||||
dc up -d "$@" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
start_ue_list() {
|
||||
[[ $# -eq 0 ]] && return 0
|
||||
for svc in "$@"; do
|
||||
log "Starting: $svc"
|
||||
dc up -d "$svc"
|
||||
sleep 10
|
||||
dc up -d "$svc" >/dev/null 2>&1
|
||||
done
|
||||
}
|
||||
|
||||
@@ -200,11 +186,28 @@ start_in_stages() {
|
||||
wait_healthy "${AMF_SERVICE}" 15
|
||||
wait_healthy "${UPF_SERVICE}" 15
|
||||
exec_safe "${UPF_SERVICE}" 'bash -lc "
|
||||
GW=192.168.72.129
|
||||
DEV=\$(ip -4 route get \$GW 2>/dev/null | awk '\''/ dev /{for(i=1;i<=NF;i++) if(\$i==\"dev\"){print \$(i+1); exit}}'\''); DEV=\${DEV:-eth0}
|
||||
ip -4 route replace \$GW/32 dev \$DEV
|
||||
ip -4 route replace default via \$GW dev \$DEV onlink
|
||||
"'
|
||||
set -e
|
||||
sysctl -w net.ipv4.ip_forward=1
|
||||
sysctl -w net.ipv4.conf.all.rp_filter=2
|
||||
sysctl -w net.ipv4.conf.eth0.rp_filter=2
|
||||
sysctl -w net.ipv4.conf.eth1.rp_filter=2
|
||||
sysctl -w net.ipv4.conf.tun0.rp_filter=2
|
||||
|
||||
ip rule add pref 100 iif tun0 to 192.168.71.0/24 lookup 201 || true
|
||||
ip route replace 192.168.71.0/24 dev eth0 table 201
|
||||
|
||||
ip rule add pref 200 iif tun0 lookup 200 || true
|
||||
ip route replace 12.1.1.0/24 dev tun0 table 200
|
||||
ip route replace default via 192.168.72.129 dev eth1 table 200
|
||||
|
||||
# UE -> DN (192.168.72.128/26) via eth1
|
||||
iptables -t nat -C POSTROUTING -s 12.1.1.0/24 -d 192.168.72.128/26 -o eth1 -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -s 12.1.1.0/24 -d 192.168.72.128/26 -o eth1 -j MASQUERADE
|
||||
|
||||
# UE -> 192.168.71.0/24 via eth0
|
||||
iptables -t nat -C POSTROUTING -s 12.1.1.0/24 -d 192.168.71.0/24 -o eth0 -j MASQUERADE 2>/dev/null || \
|
||||
iptables -t nat -A POSTROUTING -s 12.1.1.0/24 -d 192.168.71.0/24 -o eth0 -j MASQUERADE
|
||||
"'
|
||||
wait_healthy oai-flexric 15
|
||||
|
||||
# 2) gNB
|
||||
@@ -272,17 +275,6 @@ calc_target_ue_count() {
|
||||
}'
|
||||
}
|
||||
|
||||
wait_oaitun() {
|
||||
local ue="$1" timeout="${2:-20}"
|
||||
for ((i=1; i<=timeout; i++)); do
|
||||
if exec_safe "$ue" 'ip link show oaitun_ue1 >/dev/null 2>&1'; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
}
|
||||
|
||||
ensure_ue_count() {
|
||||
local target="$1"
|
||||
|
||||
@@ -312,7 +304,12 @@ ensure_ue_count() {
|
||||
if (( cur < target )); then
|
||||
local need=$(( target - cur ))
|
||||
log "UE scaler: need +${need} UEs (cur=${cur}, target=${target})."
|
||||
# Choose candidates (prefer random if shuf available)
|
||||
|
||||
if (( ${#not_running[@]} == 0 )); then
|
||||
log "UE scaler: no available UEs to start."
|
||||
return 0
|
||||
fi
|
||||
|
||||
local to_start=()
|
||||
if command -v shuf >/dev/null 2>&1; then
|
||||
mapfile -t to_start < <(printf '%s\n' "${not_running[@]}" | shuf -n "$need" || true)
|
||||
@@ -321,16 +318,15 @@ ensure_ue_count() {
|
||||
fi
|
||||
if (( ${#to_start[@]} > 0 )); then
|
||||
start_ue_list "${to_start[@]}"
|
||||
# kick traffic + (best-effort) readiness
|
||||
for ue in "${to_start[@]}"; do
|
||||
if wait_oaitun "$ue" 20; then
|
||||
if wait_log "$ue" "oaitun_ue1 successfully configured"; then
|
||||
exec_safe "$ue" 'ip route replace default dev oaitun_ue1'
|
||||
run_traffic_profile "$ue" "random" "0"
|
||||
# run_traffic_profile "$ue" "$(choose_random_profile)" "0"
|
||||
run_traffic_profile "$ue" "boring"
|
||||
else
|
||||
dc restart "$ue"
|
||||
to_start+="$ue"
|
||||
dc rm -fv "$ue" >/dev/null 2>&1
|
||||
fi
|
||||
done
|
||||
done
|
||||
fi
|
||||
return 0
|
||||
fi
|
||||
@@ -346,46 +342,57 @@ ensure_ue_count() {
|
||||
fi
|
||||
for ue in "${to_stop[@]}"; do
|
||||
log "Stopping UE ${ue}"
|
||||
dc stop "$ue" || true
|
||||
dc rm -f "$ue" || true
|
||||
dc stop "$ue" >/dev/null 2>&1 &
|
||||
done
|
||||
wait
|
||||
for ue in "${to_stop[@]}"; do
|
||||
dc rm -fv "$ue" >/dev/null 2>&1 &
|
||||
done
|
||||
wait
|
||||
}
|
||||
|
||||
# --------------------------[ UE traffic helpers ]-----------------------------
|
||||
|
||||
pick_profile() {
|
||||
local r=$((RANDOM % 100))
|
||||
if (( r < 30 )); then echo browsing # 45%
|
||||
elif (( r < 70 )); then echo video # 35%
|
||||
elif (( r < 90 )); then echo bulk_download # 12%
|
||||
else echo iot_chatty # 8%
|
||||
fi
|
||||
PROFILES=(boring browsing video bulk_download voip iot_chatty gaming)
|
||||
choose_random_profile() {
|
||||
if command -v shuf >/dev/null 2>&1; then
|
||||
shuf -e "${PROFILES[@]}" -n1
|
||||
else
|
||||
idx=$(( RANDOM % ${#PROFILES[@]} ))
|
||||
echo "${PROFILES[$idx]}"
|
||||
fi
|
||||
}
|
||||
|
||||
run_traffic_profile() {
|
||||
local ue="$1" profile="$2" duration="${3:-0}"
|
||||
exec_safe "$ue" "echo 'traffic runner ready for $ue. profile: $profile'"
|
||||
local ue="$1" profile="$2"
|
||||
|
||||
# Record selected profile for this UE into UE_PROFILE_MAP
|
||||
if [[ "$ue" =~ ([0-9]+)$ ]]; then
|
||||
__idx="${BASH_REMATCH[1]}"
|
||||
UE_PROFILE_MAP[$__idx]="$profile"
|
||||
fi
|
||||
dc cp /home/nakaolab-go/OAI/openairinterface5g/tools/scripts/traffic_runner.sh "$ue":/tmp/traffic_runner.sh >/dev/null 2>&1
|
||||
exec_safe "$ue" "bash -lc '
|
||||
if [ ! -f /tmp/traffic_profile.lock ]; then
|
||||
prof=\$1; dur=\$2
|
||||
/usr/local/bin/traffic_runner --profile \$prof --duration \$dur >/tmp/traffic_runner.log 2>&1 &
|
||||
printf \"%s %s\n\" \"\$prof\" \"\$dur\" > /tmp/traffic_profile.lock
|
||||
fi
|
||||
' -- $profile $duration"
|
||||
prof=\$1;
|
||||
/tmp/traffic_runner.sh --profile \$prof &
|
||||
' -- $profile"
|
||||
}
|
||||
|
||||
# --------------------------[ RRC / MAC scraping ]-----------------------------
|
||||
|
||||
rotate_mac_capture() {
|
||||
rotate_stats_capture() {
|
||||
local tag="${1:-}"
|
||||
[[ -z "$tag" ]] && tag="$(ts_tag)"
|
||||
if dc ps --services --filter "status=running" | grep -q "^${MAC_STATS_CONTAINER}$"; then
|
||||
log "Rotating mac_stats from ${MAC_STATS_CONTAINER}"
|
||||
dc cp "${MAC_STATS_CONTAINER}:${MAC_STATS_FILE_IN_CONTAINER}" \
|
||||
if dc ps --services --filter "status=running" | grep -q "^${STATS_CONTAINER}$"; then
|
||||
log "Rotating stats from ${STATS_CONTAINER}"
|
||||
dc cp "${STATS_CONTAINER}:${MAC_STATS_FILE_IN_CONTAINER}" \
|
||||
"${ARTIFACT_DIR}/mac_stats_${tag}.log" || true
|
||||
exec_safe "$MAC_STATS_CONTAINER" "> '${MAC_STATS_FILE_IN_CONTAINER}'"
|
||||
dc cp "${STATS_CONTAINER}:${PDCP_STATS_FILE_IN_CONTAINER}" \
|
||||
"${ARTIFACT_DIR}/pdcp_stats_${tag}.log" || true
|
||||
# exec_safe "$STATS_CONTAINER" "> '${MAC_STATS_FILE_IN_CONTAINER}'"
|
||||
# exec_safe "$STATS_CONTAINER" "> '${PDCP_STATS_FILE_IN_CONTAINER}'"
|
||||
else
|
||||
log "mac_stats container ${MAC_STATS_CONTAINER} not running; skipping rotate"
|
||||
log "stats container ${STATS_CONTAINER} not running; skipping rotate"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -400,10 +407,10 @@ _since_arg_from_file() {
|
||||
fi
|
||||
}
|
||||
|
||||
dump_gnb_rrc_logs() {
|
||||
dump_gnb_logs() {
|
||||
local tag="$1"
|
||||
dc logs "${GNB_SERVICE}" 2>&1 | grep -E "NR_RRC" \
|
||||
> "${ARTIFACT_DIR}/gnb_rrc_${tag}.log" || true
|
||||
dc logs "${GNB_SERVICE}" 2>&1 | grep -E "NR_RRC" > "${ARTIFACT_DIR}/gnb_rrc_${tag}.log"
|
||||
dc logs "${GNB_SERVICE}" 2>&1 | grep -E "\[NR_MAC\] I Frame\.Slot|MAC:" > "${ARTIFACT_DIR}/gnb_${tag}.log"
|
||||
}
|
||||
|
||||
# -----------------------------[ Power / CPU ]---------------------------------
|
||||
@@ -428,14 +435,16 @@ sample_power_once() {
|
||||
|
||||
while IFS= read -r ue; do
|
||||
[[ -z "$ue" ]] && continue
|
||||
local lock
|
||||
lock="$(exec_safe "$ue" 'bash -lc "cat /tmp/traffic_profile.lock 2>/dev/null || true"')"
|
||||
# Determine profile without container lock by consulting UE_PROFILE_MAP
|
||||
local picked_profile picked_duration
|
||||
picked_profile="$(awk "{print \$1}" <<<"$lock")"
|
||||
picked_duration="$(awk "{print \$2}" <<<"$lock")"
|
||||
if [[ "$ue" =~ ([0-9]+)$ ]]; then
|
||||
__idx="${BASH_REMATCH[1]}"
|
||||
picked_profile="${UE_PROFILE_MAP[$__idx]}"
|
||||
fi
|
||||
picked_duration=""
|
||||
|
||||
if [[ -z "$picked_profile" ]]; then
|
||||
picked_profile="${TEST_PROFILE:-idle}"
|
||||
if [[ "${TEST_MODE}" -eq 1 ]]; then picked_profile="${TEST_PROFILE}"; else picked_profile="idle"; fi
|
||||
fi
|
||||
|
||||
while [[ "$picked_profile" == -* ]]; do
|
||||
@@ -499,8 +508,8 @@ rotate_csv_if_any() {
|
||||
|
||||
finalize_and_rotate_artifacts() {
|
||||
local tag; tag="$(ts_tag)"
|
||||
rotate_mac_capture "$tag" || true
|
||||
dump_gnb_rrc_logs "$tag" || true
|
||||
rotate_stats_capture "$tag" || true
|
||||
dump_gnb_logs "$tag" || true
|
||||
rotate_csv_if_any "$POWER_LOG_FILE" "power_usage" "$tag"
|
||||
rotate_csv_if_any "$CPU_PROXY_LOG_FILE" "cpu_proxy" "$tag"
|
||||
}
|
||||
@@ -530,40 +539,40 @@ cleanup() {
|
||||
while IFS= read -r ue; do
|
||||
[[ -z "$ue" ]] && continue
|
||||
dc stop "$ue" || true
|
||||
dc rm -f "$ue" || true
|
||||
dc rm -fv "$ue" >/dev/null 2>&1 &
|
||||
done < <(dc ps --services | grep -E "${UE_NAME_REGEX}" || true)
|
||||
}
|
||||
|
||||
# ---------------------------------[ Main ]------------------------------------
|
||||
|
||||
|
||||
trigger_system_burst() {
|
||||
mapfile -t running < <(get_running_ues)
|
||||
if (( ${#running[@]} == 0 )); then
|
||||
return 0
|
||||
fi
|
||||
log "Triggering system-wide burst for ${#running[@]} UE(s)…"
|
||||
for ue in "${running[@]}"; do
|
||||
exec_safe "$ue" "bash -lc 'date +%s > ${BURST_MARK_FILE}'" || true
|
||||
done
|
||||
}
|
||||
|
||||
random_target_ue_count() {
|
||||
local total_ues="${UE_MAX:-}"
|
||||
if [[ -z "$total_ues" ]]; then
|
||||
total_ues="$(get_all_ue_services | wc -l | tr -d ' ')"
|
||||
local cur="$(get_running_ues | wc -l | tr -d ' ')"
|
||||
bias=$((RANDOM % 100)) # 0–99
|
||||
if (( cur <= UE_MIN )); then
|
||||
if (( bias < 70 )); then
|
||||
delta=$(( (RANDOM % 3) + 1 )) # +1..+3
|
||||
else
|
||||
delta=$(( RANDOM % 7 - 3 )) # -3..+3
|
||||
fi
|
||||
elif (( cur >= UE_MAX )); then
|
||||
if (( bias < 70 )); then
|
||||
delta=$(( -((RANDOM % 3) + 1) )) # -1..-3
|
||||
else
|
||||
delta=$(( RANDOM % 7 - 3 )) # -3..+3
|
||||
fi
|
||||
else # normal
|
||||
delta=$(( RANDOM % 7 - 3 )) # -3..+3
|
||||
fi
|
||||
local min="${UE_MIN:-1}"
|
||||
if (( total_ues < min )); then total_ues="$min"; fi
|
||||
local val
|
||||
if command -v shuf >/dev/null 2>&1; then
|
||||
val="$(shuf -i "${min}-${total_ues}" -n 1)"
|
||||
else
|
||||
local span=$(( total_ues - min + 1 ))
|
||||
val=$(( min + (RANDOM % span) ))
|
||||
local target=$((cur + delta))
|
||||
if (( target < UE_MIN )); then
|
||||
target="${UE_MIN}"
|
||||
elif (( target > UE_MAX )); then
|
||||
target="${UE_MAX}"
|
||||
fi
|
||||
echo "$val"
|
||||
|
||||
echo "$target"
|
||||
}
|
||||
|
||||
main() {
|
||||
trap on_interrupt INT TERM
|
||||
|
||||
@@ -572,24 +581,18 @@ main() {
|
||||
# Staged bring-up with readiness checks for both normal and TEST modes
|
||||
start_in_stages
|
||||
|
||||
# Initialize next system-burst time
|
||||
if (( RANDOM_BURST_MODE )); then
|
||||
local next_burst_ts
|
||||
next_burst_ts="$(($(ts_now) + BURST_MIN_GAP_SEC + RANDOM % (BURST_MAX_GAP_SEC - BURST_MIN_GAP_SEC + 1)))"
|
||||
fi
|
||||
|
||||
# Kick off traffic workload(s)
|
||||
if [[ -n "${TEST_UE:-}" ]]; then
|
||||
if [[ "${TEST_MODE}" -eq 1 ]]; then
|
||||
log "TEST UE(S) ENABLED"
|
||||
# Support multiple UEs (comma/space/newline separated)
|
||||
read -r -a _ue_list <<< "$(tr ',\n' ' ' <<< "${TEST_UE}")"
|
||||
read -r -a _ue_list <<< "$(tr ',\n' ' ' <<< "${TEST_UES}")"
|
||||
read -r -a _ue_profiles <<< "$(tr ',\n' ' ' <<< "${TEST_PROFILES}")"
|
||||
start_ue_list "${_ue_list[@]}"
|
||||
for i in "${!_ue_list[@]}"; do
|
||||
ue="${_ue_list[$i]}"
|
||||
prof="${_ue_profiles[$i]}"
|
||||
[[ -z "$ue" ]] && continue
|
||||
if wait_oaitun "$ue" 20; then
|
||||
if wait_log "$ue" "oaitun_ue1 successfully configured"; then
|
||||
exec_safe "$ue" "ip route replace default dev oaitun_ue1"
|
||||
run_traffic_profile "$ue" "$prof"
|
||||
else
|
||||
@@ -599,7 +602,7 @@ main() {
|
||||
fi
|
||||
|
||||
# Optional finite duration for TEST mode
|
||||
if [[ -n "${TEST_UE:-}" && "${TEST_DURATION_SEC:-0}" -gt 0 ]]; then
|
||||
if [[ "${TEST_MODE}" -eq 1 && -n "${TEST_UE:-}" && "${TEST_DURATION_SEC:-0}" -gt 0 ]]; then
|
||||
RUN_STOP_TS=$(( $(ts_now) + TEST_DURATION_SEC ))
|
||||
fi
|
||||
|
||||
@@ -612,14 +615,6 @@ main() {
|
||||
log "Entering main loop (sampling + diurnal scaler)…"
|
||||
while :; do
|
||||
local now; now="$(ts_now)"
|
||||
# System-wide random burst scheduler
|
||||
if (( RANDOM_BURST_MODE )); then
|
||||
if (( now >= next_burst_ts )); then
|
||||
trigger_system_burst || true
|
||||
next_burst_ts="$(( now + BURST_MIN_GAP_SEC + RANDOM % (BURST_MAX_GAP_SEC - BURST_MIN_GAP_SEC + 1) ))"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if (( now - last_power >= POWER_LOG_INTERVAL_SEC )); then
|
||||
sample_power_once || true
|
||||
@@ -632,9 +627,14 @@ main() {
|
||||
fi
|
||||
|
||||
# Re-evaluate diurnal target (normal mode only)
|
||||
if [[ -z "${TEST_UE:-}" ]] && (( now - last_scale >= UE_SCALER_INTERVAL_SEC )); then
|
||||
local target; if [[ "${UE_SCALER_MODE}" == "diurnal" ]]; then target="$(calc_target_ue_count)"; else target="$(random_target_ue_count)"; fi
|
||||
log "Diurnal scaler tick: target = ${target}"
|
||||
if [[ "${TEST_MODE}" -eq 0 ]] && (( now - last_scale >= UE_SCALER_INTERVAL_SEC )); then
|
||||
local target;
|
||||
if [[ "${UE_SCALER_MODE}" == "diurnal" ]]; then
|
||||
target="$(calc_target_ue_count)";
|
||||
else
|
||||
target="$(random_target_ue_count)";
|
||||
fi
|
||||
log "Scaler tick: target = ${target}"
|
||||
ensure_ue_count "$target"
|
||||
last_scale="$now"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user