Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

consrv does not gracefully handle disappearing / re-appearing serial device #3

Open
stapelberg opened this issue Aug 13, 2022 · 1 comment

Comments

@stapelberg
Copy link
Contributor

stapelberg commented Aug 13, 2022

In my setup, for whichever reason, the USB-to-serial adapter occasionally drops off the USB bus and comes back as ttyUSB1 instead of ttyUSB0:

[776891.671139] cp210x ttyUSB1: usb_serial_generic_read_bulk_callback - urb stopped: -32
[776891.680238] cp210x ttyUSB1: usb_serial_generic_read_bulk_callback - urb stopped: -32
[776891.764819] usb 1-1-port3: disabled by hub (EMI?), re-enabling...
[776891.772885] usb 1-1.3: USB disconnect, device number 6
[776891.779671] cp210x ttyUSB1: failed set request 0x12 status: -19
[776891.786843] cp210x ttyUSB1: failed set request 0x0 status: -19
[776891.794229] cp210x ttyUSB1: cp210x converter now disconnected from ttyUSB1
[776891.802492] cp210x 1-1.3:1.0: device disconnected
[776892.031977] usb 1-1.3: new full-speed USB device number 7 using dwc2
[776892.143732] cp210x 1-1.3:1.0: cp210x converter detected
[776892.151568] usb 1-1.3: cp210x converter now attached to ttyUSB0

I don’t know yet if this correlates to any specific trigger (perhaps rebooting my router?), but it happens frequently enough to be noticeable.

This behavior can be reproduced by physically un-plugging the USB-to-serial adapter and plugging it back in.

On the Go side, the symptom is that Read() returns an io.EOF error.

Currently, consrv connections just hang indefinitely until you send a byte, which triggers a write to the ttyUSB0 device, which triggers a write /dev/ttyUSB1: input/output error that then closes the SSH session.

There are a number of things subtly wrong that result in the silent swallowing of the error. I can send a PR that addresses enough of them to make the SSH session close immediately when un-plugging the adapter.

What’s still left to be done is closing the mux device and underlying serial port, and then re-opening it on the next connection.

stapelberg added a commit to stapelberg/consrv that referenced this issue Aug 13, 2022
stapelberg added a commit to stapelberg/consrv that referenced this issue Aug 14, 2022
mdlayher pushed a commit that referenced this issue Aug 14, 2022
@stapelberg
Copy link
Contributor Author

What’s still left to be done is closing the mux device and underlying serial port, and then re-opening it on the next connection.

A pragmatic workaround for this is to enable logtostdout (see PR #5) and make consrv log.Fatalf when reading EOF:

diff --git i/cmd/consrv/main.go w/cmd/consrv/main.go
index da918a0..18cef58 100644
--- i/cmd/consrv/main.go
+++ w/cmd/consrv/main.go
@@ -119,6 +119,10 @@ func main() {
 				if err := scanner.Err(); err != nil {
 					ll.Printf("copying serial to stdout: %v", err)
 				}
+				// io.EOF (not considered an error by scanner.Err()) is
+				// unexpected here, as we expect an infinite serial
+				// stream. Encountering io.EOF means the device has disappeared.
+				log.Fatalf("device disappeared: %s", d.Name)
 			}()
 		}
 	}

When unplugging the serial adapter, consrv starts crashlooping until the adapter is plugged back in.

Obviously this is only doable when you have precisely 1 serial adapter you care about, otherwise the failure of one results in all other adapters being unavailable, too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant