What's new

My experience with the RT-AC86U

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

1655417790336.png
 
No. I got this:

Not a single value here. 1 2 3 4 are the iteration numbers.
to be clear this is what I am using
Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /bin/nvram /tmp/_nvram

# create nvram wrapper that calls original nvram executable in /tmp
cat << 'EOF' > /tmp/nvram
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
INTERVAL="100"
MAXCOUNT="3"
run_cmd () {
    local to
    local start
    local child
    # here as the number of tries required increases our usleep increases in case the sleep is not long enough.
    to="$1"
    to="$((to*INTERVAL))"; shift
    $@ & local child="$!" start=0
    usleep "$to"
    while { [ "$(kill -0 $child >/dev/null 2>&1; printf "%s" "$?")" = "0" ] && [ "$start" -le "$to" ]; }; do
        # to account for killing too soon, as the number of tries required increases our count requirement increases before we attempt to kill the process.
        usleep 1
        start="$((start+1))"
        if [ $start -gt $to ]; then
            kill -s 9 $child 2>/dev/null
            return 1
        fi
    done
    return 0
}

# make the new function accessible, on the first run we want to exit right away if successful.
i="1"
if { run_cmd "$i" /tmp/_nvram "$@"; }; then
  exit 0
fi
# here we add an interval check and allow up to 3 retries.
while [ "$i" -le "$MAXCOUNT" ]; do
  logger -t "nvram-override" "Waiting for NVRAM (retry attempt ${i}/${MAXCOUNT})"
  usleep $INTERVAL
  if { run_cmd "$i" /tmp/_nvram "$@"; }; then
    exit 0
  fi
  i="$((i+1))"
done
logger -t "nvram-override" "NVRAM remained locked too long; continuing anyway."
exit 1
EOF
chmod +x /tmp/nvram

# replace nvram in /usr/sbin w/ nvram wrapper in /tmp
mount -o bind /tmp/nvram /bin/nvram

I have edited it a couple of times, so many you got one that had a bad variable in it.

here is my testing script

Bash:
#!/bin/sh
trap '' HUP INT QUIT ABRT TERM
(i="0"
while true; do
  i="$(( i + 1 ))"
  for nv in 1 2 3 4 5; do
  unset "state${nv}";
  eval "state${nv}"="$(/bin/nvram get vpn_client${nv}_state)";
  done
  clear
  echo "$state1" "$state2" "$state3" "$state4" "$state5"
  echo "$i"
done) > /tmp/mynvramerror.log 2>&1 &

exit 0

I am doing tail -f /tmp/mynvramerror.log to observe the logs.
 
Something's unsupported here.
4
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error

5
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
/bin/nvram: line 29: arithmetic syntax error
 
This:
Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /bin/nvram /tmp/_nvram

# create nvram wrapper that calls original nvram executable in /tmp
cat << 'EOF' > /tmp/nvram
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
INTERVAL="100"
MAXCOUNT="3"
run_cmd () {
    local to
    local start
    local child
    # here as the number of tries required increases our usleep increases in case the sleep is not long enough.
    to="$(("$1"*"$INTERVAL"))"; shift
    $@ & local child=$! start=0
    usleep $to
    while { [ "$(kill -0 $child >/dev/null 2>&1; printf "%s" "$?")" = "0" ] && [ $start -le $to ]; }; do
        # to account for killing too soon, as the number of tries required increases our count requirement increases before we attempt to kill the process.
        usleep 1
        start="$((start+1))"
        if [ $start -gt $to ]; then
            kill -s 9 $child 2>/dev/null
            return 1
        fi
    done
    return 0
}

# make the new function accessible, on the first run we want to exit right away if successful.
i=1
if { run_cmd $i /tmp/_nvram $@; }; then
  exit 0
fi
# here we add an interval check and allow up to 3 retries.
while [ $i -le $MAXCOUNT ]; do
  logger -t "nvram-override" "Waiting for NVRAM (attempt ${i}/${MAXCOUNT})"
  usleep $INTERVAL
  if { run_cmd $i /tmp/_nvram $@; }; then
    exit 0
  fi
  i=$((i+1))
done
logger -t "nvram-override" "NVRAM remained locked too long; continuing anyway."
exit 1
EOF
chmod +x /tmp/nvram

# replace nvram in /usr/sbin w/ nvram wrapper in /tmp
mount -o bind /tmp/nvram /bin/nvram
 
This:
Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /bin/nvram /tmp/_nvram

# create nvram wrapper that calls original nvram executable in /tmp
cat << 'EOF' > /tmp/nvram
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
INTERVAL="100"
MAXCOUNT="3"
run_cmd () {
    local to
    local start
    local child
    # here as the number of tries required increases our usleep increases in case the sleep is not long enough.
    to="$(("$1"*"$INTERVAL"))"; shift
    $@ & local child=$! start=0
    usleep $to
    while { [ "$(kill -0 $child >/dev/null 2>&1; printf "%s" "$?")" = "0" ] && [ $start -le $to ]; }; do
        # to account for killing too soon, as the number of tries required increases our count requirement increases before we attempt to kill the process.
        usleep 1
        start="$((start+1))"
        if [ $start -gt $to ]; then
            kill -s 9 $child 2>/dev/null
            return 1
        fi
    done
    return 0
}

# make the new function accessible, on the first run we want to exit right away if successful.
i=1
if { run_cmd $i /tmp/_nvram $@; }; then
  exit 0
fi
# here we add an interval check and allow up to 3 retries.
while [ $i -le $MAXCOUNT ]; do
  logger -t "nvram-override" "Waiting for NVRAM (attempt ${i}/${MAXCOUNT})"
  usleep $INTERVAL
  if { run_cmd $i /tmp/_nvram $@; }; then
    exit 0
  fi
  i=$((i+1))
done
logger -t "nvram-override" "NVRAM remained locked too long; continuing anyway."
exit 1
EOF
chmod +x /tmp/nvram

# replace nvram in /usr/sbin w/ nvram wrapper in /tmp
mount -o bind /tmp/nvram /bin/nvram
You are using the wrong one..... so to speak.

mine is slightly different.

Code:
to="$(("$1"*"$INTERVAL"))"

should be

Code:
to="$1"
to="$((to*INTERVAL))"


so use the one from this post

 
Clocked it. 6:45 min for 3000 iterations.
No missing values.
Only 4 retries, which looks good.
Jun 17 01:38:14 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 01:40:03 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 01:43:28 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 01:43:33 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Previous version took around 4:20 with many retries.
 
Clocked it. 6:45 min for 3000 iterations.
No missing values.
Only 4 retries, which looks good.

Previous version took around 4:20 with many retries.
This might be your solution until the bug is fixed then... The interval can be fined tune to be smaller or larger. However, I suspect your number of retries per run will increase as you decrease the interval. you could even try interval 75 then 50 then 25.
 
Last edited:
It seems to me that usleep takes extra time to execute (beyond its set wait time). We can maybe try some other dummy operation instead.
When running clean nvram test loop, CPU use goes to 100% on one of the cores and high on the other. With the last override version, any core hardly touches 10%.
 
Clocked it. 6:45 min for 3000 iterations.
No missing values.
Only 4 retries, which looks good.

Previous version took around 4:20 with many retries.
Here is a modification for testing at more than one interval.

Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /bin/nvram /tmp/_nvram

# create nvram wrapper that calls original nvram executable in /tmp
cat << 'EOF' > /tmp/nvram
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
#INTERVAL="100"
MAXCOUNT="3"
run_cmd () {
    local to
    local start
    local child
    # here as the number of tries required increases our usleep increases in case the sleep is not long enough.
    to="$1"
    to="$((to*INTERVAL))"; shift
    $@ & local child="$!" start=0
    usleep "$to"
    while { [ "$(kill -0 $child >/dev/null 2>&1; printf "%s" "$?")" = "0" ] && [ "$start" -le "$to" ]; }; do
        # to account for killing too soon, as the number of tries required increases our count requirement increases before we attempt to kill the process.
        usleep 1
        start="$((start+1))"
        if [ $start -gt $to ]; then
            kill -s 9 $child 2>/dev/null
            return 1
        fi
    done
    return 0
}
for INTERVAL in 25 50 75 100; do
# make the new function accessible, on the first run we want to exit right away if successful.
i="1"
if { run_cmd "$i" /tmp/_nvram "$@"; }; then
  exit 0
fi
# here we add an interval check and allow up to 3 retries.
while [ "$i" -le "$MAXCOUNT" ]; do
  logger -t "nvram-override" "Waiting for NVRAM (retry attempt ${i}/${MAXCOUNT})"
  usleep $INTERVAL
  if { run_cmd "$i" /tmp/_nvram "$@"; }; then
    exit 0
  fi
  i="$((i+1))"
done
done
logger -t "nvram-override" "NVRAM remained locked too long; continuing anyway."
exit 1
EOF
chmod +x /tmp/nvram

# replace nvram in /usr/sbin w/ nvram wrapper in /tmp
mount -o bind /tmp/nvram /bin/nvram
 
usleep appears slow to initialize.
3000 iterations, usleep 100: 6:45 min
3000 iterations, usleep 25: 6:42 min
Give or take a second.

I'd also like to have counters how many times this runs and how many errors it captures.
I had some lousy counters in my version and they were growing fast, even when I wasn't testing.
 
I see no difference. Funny but at 25 microsec it did only 1 retry. No empty values found. You know there's a random element to it. Sometimes it would get 2-3 fails in 3000 iterations, sometimes none.
There mere fact that usleep is in the chain, already slows things down.
 
usleep appears slow to initialize.
3000 iterations, usleep 100: 6:45 min
3000 iterations, usleep 25: 6:42 min
Give or take a second.

I'd also like to have counters how many times this runs and how many errors it captures.
I had some lousy counters in my version and they were growing fast, even when I wasn't testing.
I think the biggest problem with usleep is that if it fails it returns a -1 value.
 
I see no difference. Funny but at 25 microsec it did only 1 retry. No empty values found.
There mere fact that usleep is in the chain, already slows things down.
Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /bin/nvram /tmp/_nvram

# create nvram wrapper that calls original nvram executable in /tmp
cat << 'EOF' > /tmp/nvram
#!/bin/sh
#set -x # comment/uncomment to disable/enable debug mode
#INTERVAL="100"
MAXCOUNT="3"
run_cmd () {
    local to
    local start
    local child
    # here as the number of tries required increases our usleep increases in case the sleep is not long enough.
    to="$1"
    to="$((to*INTERVAL))"; shift
    $@ & local child="$!" start=0
    touch /tmp/nvram
    while { [ "$(kill -0 $child >/dev/null 2>&1; printf "%s" "$?")" = "0" ] && [ "$start" -le "$to" ]; }; do
        # to account for killing too soon, as the number of tries required increases our count requirement increases before we attempt to kill the process.
        touch /tmp/nvram
        start="$((start+1))"
        if [ $start -gt $to ]; then
            kill -s 9 $child 2>/dev/null
            wait $child
            return 1
        fi
    done
    return 0
}
for INTERVAL in 25 50 75 100; do
# make the new function accessible, on the first run we want to exit right away if successful.
i="1"
if { run_cmd "$i" /tmp/_nvram "$@"; }; then
  exit 0
fi
# here we add an interval check and allow up to 3 retries.
while [ "$i" -le "$MAXCOUNT" ]; do
  logger -t "nvram-override" "Waiting for NVRAM (retry attempt ${i}/${MAXCOUNT})"
  touch /tmp/nvram
  if { run_cmd "$i" /tmp/_nvram "$@"; }; then
    exit 0
  fi
  i="$((i+1))"
done
done
logger -t "nvram-override" "NVRAM remained locked too long; continuing anyway."
exit 1
EOF
chmod +x /tmp/nvram

# replace nvram in /usr/sbin w/ nvram wrapper in /tmp
mount -o bind /tmp/nvram /bin/nvram

try this mode. I removed usleep and replaced it with touch command.
 
This version produced 6 retries within 3:35 min. Visibly faster (2x) and no empty values.
Jun 17 02:35:24 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 02:35:25 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 02:36:29 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 02:37:35 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 02:38:07 nvram-override: Waiting for NVRAM (retry attempt 1/3)
Jun 17 02:38:40 nvram-override: Waiting for NVRAM (retry attempt 1/3)
 

Similar threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top