greshake / i3status-rust

Very resourcefriendly and feature-rich replacement for i3status, written in pure Rust
GNU General Public License v3.0
2.88k stars 475 forks source link

displaying wireless signal strength breaks the whole statusbar if wifi disconnects #828

Closed Dieterbe closed 4 years ago

Dieterbe commented 4 years ago
Error in block 'net': Signal strength is only available for connected wireless devices.

noooooaeou5554

we probably just need a small error handling tweak.

GladOSkar commented 4 years ago

This actually works on my machine:

[[block]]
block = "net"
device = "wlp2s0"
interval = 10
format = "{signal_strength}"

image

Dieterbe commented 4 years ago

interesting. I have

[[block]]
block = "net"
device = "wlp3s0"
format = "{ssid} {signal_strength} {speed_up} {speed_down}"
interval = 5
use_bits = false

I note you have a signal_strength setting which per https://github.com/greshake/i3status-rust/blob/master/blocks.md#deprecated-options is deprecated.

which version do you use? i have it with latest master.

GladOSkar commented 4 years ago

I also am on latest master, apparently i forgot to remove that entry. It works without it as well. Will edit the comment to avoid confusion

ammgws commented 4 years ago

@Dieterbe What happens if you try with format = "{ssid} {speed_up} {speed_down}"? Does it fail on the SSID?

Dieterbe commented 4 years ago

Hi Jason, with that format string it seems to work fine.

Dieterbe commented 4 years ago

strange, i can't reproduce the issue anymore with format = "{ssid} {signal_strength} {speed_up} {speed_down}" either for both format strings i disconnect from wifi using network manager and it all seems to work fine. when the issue originally appeared it wasn't after simply manually disconnecting, i was having wifi issues where i lost connectivity due to a still undiagnosed issue, that i am not able to easily trigger anymore.

ammgws commented 4 years ago

Must be something in the logic here that only causes it to occur in specific situations: https://github.com/greshake/i3status-rust/blob/d079568c6f627a040934ad96084ea8bba6ae66d0/src/blocks/net.rs#L118-L141

Most likely the operstate/carrier file contents.

ammgws commented 4 years ago

The definitions for operstate and carrier are below. I wonder if in your case the operstate was IF_OPER_DORMANT which caused is_up to return false. I will try test out some stuff next time I am on my laptop. In any case the block shouldn't crash just because the wifi isn't connected, so if I can reproduce I will work on a fix.

/sys/class/net/xxx/carrier

Indicates the current physical link state of the interface. Posssible values are: 0: physical link is down 1: physical link is up

/sys/class/net/xxx/operstate

Indicates the interface RFC2863 operational state as a string. Possible values are: "unknown", "notpresent", "down", "lowerlayerdown", "testing", "dormant", "up".

IF_OPER_UNKNOWN (0): Interface is in unknown state, neither driver nor userspace has set operational state. Interface must be considered for user data as setting operational state has not been implemented in every driver. IF_OPER_NOTPRESENT (1): Unused in current kernel (notpresent interfaces normally disappear), just a numerical placeholder. IF_OPER_DOWN (2): Interface is unable to transfer data on L1, f.e. ethernet is not plugged or interface is ADMIN down. IF_OPER_LOWERLAYERDOWN (3): Interfaces stacked on an interface that is IF_OPER_DOWN show this state (f.e. VLAN). IF_OPER_TESTING (4): Unused in current kernel. IF_OPER_DORMANT (5): Interface is L1 up, but waiting for an external event, f.e. for a protocol to establish. (802.1X) IF_OPER_UP (6): Interface is operational up and can be used.

https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-class-net https://www.kernel.org/doc/Documentation/networking/operstates.txt

ammgws commented 4 years ago

Another possible cause might be due to a race condition here: https://github.com/greshake/i3status-rust/blob/d079568c6f627a040934ad96084ea8bba6ae66d0/src/blocks/net.rs#L840-L869

It returns early if is_up returns false, however if the connection goes down after that check but before getting to the update_ssid and update_signalstrength parts then it would cause an error.

ammgws commented 4 years ago

I was able to run some simple tests on my laptop and confirmed that operstate is "dormant" when in the process of connecting to a WiFi network (only saw it a couple of times but my test script may have just been too slow to catch it the other times)

Will need to think about how to handle that and those other race conditions

ammgws commented 4 years ago

I think the solution is simply not to error out the block when entering the ssid/signal strength update functions and finding that the network is down. #871 should hopefully have fixed this, but the only way to test it is via field tests. Let me know if something goes wrong!

Dieterbe commented 4 years ago

thanks @ammgws ! cheers.

w-jablonski commented 6 months ago

See my comment https://github.com/greshake/i3status-rust/issues/1838#issuecomment-2087882795

The $signal_strength is actually (sometimes) unavailable when that network is up and running. I am getting Placeholder 'signal_strength' not found. Restarting the wifi does not help. Any fix for this or advice?...

Possibly related to system hibernation. Also possibly related to a external (USB) wifi card, but not exclusively. I will investigate further if anyone is interested.

Using Arch, SwayWM, connman, iwd, laptop.