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!

What is your reasoning for this? Just curious…..
the RT-AX88U is undervalued by 14 percent. The RT-AX86U (although newer) is only under valued by 11 percent. For the BANG in your BUCK, the deal arguably resides with the RT-AX88U. In light of the firmware issues of the AX86U and the long term stability of the AX88U, my cards reside with the AX88U.

References:

 
Ha ha, how is the 'undervaluing' calculated?

When I sold my RT-AX88U for the RT-AX86U it was because the newer router was much better than the router I sold, the hit to that cost, and the hit to the newer routers (because by then, I wanted two of them).

Nothing is undervalued or overvalued. It is worth the price paid if it works for your needs. :)
 
Ha ha, how is the 'undervaluing' calculated?

When I sold my RT-AX88U for the RT-AX86U it was because the newer router was much better than the router I sold, the hit to that cost, and the hit to the newer routers (because by then, I wanted two of them).

Nothing is undervalued or overvalued. It is worth the price paid if it works for your needs. :)
Hope it pans out in the long run. Remember the gold rush didn't hit all that were looking for it.
 
Hope what pans out??? :confused:
 
Sorry, this is over my head. :(

How is this related to how you calculate the undervaluing of the routers you mention?
 
Sorry, this is over my head. :(

How is this related to how you calculate the undervaluing of the routers you mention?
At least by undervalue, you cut your loss when the gold doesn't pan out. Here is an interesting read for you:
 
I know that definition of undervalued. I don't know how you're calculating yours though.

As I've stated, I put my money where my mouth was, and bought the superior RT-AX86U over the RT-AX88U. Even the price of a second RT-AX86U didn't put me off of the 'value' I was getting and still enjoying almost 18 months later.

And proven superior even to the much-vaunted GT-AX6000 too, in my network, with my network loads, and with the limited (2) units I tested with.

RT-AX86U vs. RT-AX88U

2x GT-AX6000 Woes
 
I know that definition of undervalued. I don't know how you're calculating yours though.

As I've stated, I put my money where my mouth was, and bought the superior RT-AX86U over the RT-AX88U. Even the price of a second RT-AX86U didn't put me off of the 'value' I was getting and still enjoying almost 18 months later.

And proven superior even to the much-vaunted GT-AX6000 too, in my network, with my network loads, and with the limited (2) units I tested with.

RT-AX86U vs. RT-AX88U
Hey, Your niche is your niche. Not even an article can properly articulate your personal experience. Similar to mine.
 
@L&LD I am not dissing the router for what it has built in, but I am not throwing caution to the wind because of Asus recent endeavors. That is the true analogy I wish for others to take.
 
Here's an example of an nvram wrapper. Realize I quite literally threw this together a few minutes ago. So it might need some refinement. But I just wanted to provide a quick-n-dirty example.

Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /usr/sbin/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

# required for serialization when reentry is possible
LOCK="/tmp/$(basename $0).lock"
acquire_lock() { until mkdir $LOCK &>/dev/null; do sleep 2; done; }
release_lock() { rmdir $LOCK &>/dev/null; }

# one instance at a time
acquire_lock

# catch premature exit and cleanup
trap 'release_lock; exit 1' SIGHUP SIGINT SIGTERM

/tmp/_nvram $@

rc=$?

# any concurrent instance(s) may now run
release_lock

exit $rc
EOF
chmod +x /tmp/nvram

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

The idea is to FORCE every reference to the nvram executable threw the above script, which enforces one-at-a-time semantics.
I would replace the sleep 2 with something a lot shorter, e.g. usleep 1000 (1 millisecond). Or 10 ms.

Overall, I don't quite get it though. How would this solve the problem, rather than just moving it upstream?

Don't we need proper serialization instead? E.g. create a big enough buffer and enqueue any nvram command to the buffer, so that they execute neatly after one another, rather than concurrently.
 
I would replace the sleep 2 with something a lot shorter, e.g. usleep 1000 (1 millisecond). Or 10 ms.

Use whatever you like. That's a minor detail.

Overall, I don't quite get it though. How would this solve the problem, rather than just moving it upstream?

Don't we need proper serialization instead? E.g. create a big enough buffer and enqueue any nvram command to the buffer, so that they execute neatly after one another, rather than concurrently.

That's effectively what it does.

Access to the nvram command *is* serialized/queued. Every access of nvram has, as a prerequisite, that you obtain exclusive control of one and only one token (i.e., the ability to create a specific directory, which is an atomic operation) before you can continue. In the meantime, you queue up (i.e., sleep). When it's your turn and have the token (i.e., can create the specific directory) and you've completed the access, you turn over the token (i.e., delete the directory) for whoever is next in the queue (i.e., woken from sleep).

Of course, ideally (assuming this is the source of the problem) the nvram command itself would properly serialize access to whatever resource(s) are causing the problem. But in the meantime, better to serialize access to the entire command than have these continuous deadlocks.

P.S. I only threw that code out there so those experiencing the problem had something to test. As I said at the time, it might need refinement. If it works, then I'll formalize it and probably turn it into an init-start script and post it on PasteBin. But I need to know if it's even going to solve the problem before taking it any farther. I personally haven't been able to reproduce the problem.
 
Last edited:
Here's an example of an nvram wrapper. Realize I quite literally threw this together a few minutes ago. So it might need some refinement. But I just wanted to provide a quick-n-dirty example.

Bash:
#!/bin/sh

# copy original nvram executable to /tmp
cp /usr/sbin/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

# required for serialization when reentry is possible
LOCK="/tmp/$(basename $0).lock"
acquire_lock() { until mkdir $LOCK &>/dev/null; do sleep 2; done; }
release_lock() { rmdir $LOCK &>/dev/null; }

# one instance at a time
acquire_lock

# catch premature exit and cleanup
trap 'release_lock; exit 1' SIGHUP SIGINT SIGTERM

/tmp/_nvram $@

rc=$?

# any concurrent instance(s) may now run
release_lock

exit $rc
EOF
chmod +x /tmp/nvram

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

The idea is to FORCE every reference to the nvram executable threw the above script, which enforces one-at-a-time semantics.
I remember your lock implementation in openvpn sync route script. I am still using this script.

Earlier I also realized my firewall-start script run twice during boot up from another thread. I add a simple lock like yours and managed to stop the second instance from running while the first instance is still running.
 
Hung one.
Code:
Every 0s: strace -r nvram get wan0_enable                                                                  2022-06-14 19:15:30
....
     0.000000 execve("/bin/nvram", ["nvram", "get", "wan0_enable"], 0x7fea378f88 /* 18 vars */ <unfinished ...>
     0.000698 [ Process PID=1098 runs in 32 bit mode. ]
strace: WARNING: Proper structure decoding for this personality is not supported, please consider building strace with mpers support enabled.
     0.000061 rt_sigaction(SIGRTMIN, {sa_handler=0xf6e8e278, sa_mask=[], sa_flags=SA_RESTORER|SA_SIGINFO, sa_restorer=0xf6fe4b10}, NULL, 8) = 0
     0.000064 rt_sigaction(SIGRT_1, {sa_handler=0xf6e8e35c, sa_mask=[], sa_flags=SA_RESTORER|SA_RESTART|SA_SIGINFO, sa_restorer=0xf6fe4b10}, NULL, 8) = 0
     0.000063 rt_sigprocmask(SIG_UNBLOCK, [RTMIN RT_1], NULL, 8) = 0
     0.000055 ugetrlimit(RLIMIT_STACK, {rlim_cur=2048*1024, rlim_max=RLIM_INFINITY}) = 0
     0.000210 mmap2(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xf6e69000
     0.000084 stat64("/jffs", 0xffb8e7a0) = 0
     0.000055 stat64("/jffs/nvram_war", 0xffb8e7a0) = 0
     0.000117 socket(AF_NETLINK, SOCK_RAW, 0x1f /* NETLINK_??? */) = 3
     0.000078 bind(3, {sa_family=AF_NETLINK, nl_pid=1098, nl_groups=00000000}, 12) = -1 EADDRINUSE (Address already in use)
[/QUOTE]
I tried digging into this a bit.  It feels like it might be a similar problem to a [URL='https://bugs.chromium.org/p/chromium/issues/detail?id=1224428']Chromium bug[/URL] which was related to calling bind() with a pre-filled PID for the AF_NETLINK socket, rather than setting it to zero and letting the kernel fill in the parameter.

I don't have my own asuswrt build to debug with at the moment, but it looks like there are some binary blobs in the tree which implement jffs_nvram_get() and friends. I can't tell if that is where this is coming from, but I suspect it might be. I did find some code in shared/rtstate.c which looks to be doing a similar socket/bind sequence and which is filling in the nl_pid field, but I couldn't track down any calls to that function.

I haven't done any AF_NETLINK socket programming before, but the [URL='https://github.com/pilebones/go-udev/issues/3#issuecomment-478353905']docs I found[/URL] seem to indicate that the nl_pid should typically be set to zero to allow the kernel to fill it in rather than filling it with the result of getpid().
 
Trying again since my prior attempt got mis-formatted. This time I'll try using the Preview button first.

I tried digging into this a bit. It feels like it might be a similar problem to a Chromium bug which was related to calling bind() with a pre-filled PID for the AF_NETLINK socket, rather than setting it to zero and letting the kernel fill in the parameter.

I don't have my own asuswrt build to debug with at the moment, but it looks like there are some binary blobs in the tree which implement jffs_nvram_get() and friends. I can't tell if that is where this is coming from, but I suspect it might be. I did find some code in shared/rtstate.c which looks to be doing a similar socket/bind sequence and which is filling in the nl_pid field, but I couldn't track down any calls to that function.

I haven't done any AF_NETLINK socket programming before, but the docs I found seem to indicate that the nl_pid should typically be set to zero to allow the kernel to fill it in rather than filling it with the result of getpid().
 
@eibgrad Thanks!
I'll give it a try. Now, before I do, could you guide me how to switch this on and off for testing purposes?
This is the part that redirects the nvram commands to your script, right?
mount -o bind /tmp/nvram /usr/sbin/nvram
 

Latest threads

Sign Up For SNBForums Daily Digest

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