Skip to content

Commit

Permalink
feat: Monitor netlink events to correctly report connected state of d…
Browse files Browse the repository at this point in the history
…evices managed by the client
  • Loading branch information
pojntfx committed May 8, 2023
1 parent 264e7d6 commit 409496b
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 12 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/pojntfx/go-nbd

go 1.20

require github.com/pilebones/go-udev v0.9.0
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pilebones/go-udev v0.9.0 h1:N1uEO/SxUwtIctc0WLU0t69JeBxIYEYnj8lT/Nabl9Q=
github.com/pilebones/go-udev v0.9.0/go.mod h1:T2eI2tUSK0hA2WS5QLjXJUfQkluZQu+18Cqvem3CaXI=
64 changes: 52 additions & 12 deletions pkg/client/nbd.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"syscall"

"github.com/pilebones/go-udev/netlink"
"github.com/pojntfx/go-nbd/pkg/ioctl"
"github.com/pojntfx/go-nbd/pkg/protocol"
"github.com/pojntfx/go-nbd/pkg/server"
Expand Down Expand Up @@ -79,6 +80,45 @@ func Connect(conn net.Conn, device *os.File, options *Options) error {
return ErrUnsupportedNetwork
}

fatal := make(chan error)
if options.OnConnected != nil {
udevConn := new(netlink.UEventConn)
if err := udevConn.Connect(netlink.UdevEvent); err != nil {
return err
}
defer udevConn.Close()

var (
udevReadyCh = make(chan netlink.UEvent)
udevErrCh = make(chan error)
udevQuit = udevConn.Monitor(udevReadyCh, udevErrCh, &netlink.RuleDefinitions{
Rules: []netlink.RuleDefinition{
{
Env: map[string]string{
"DEVNAME": device.Name(),
},
},
},
})
)
defer close(udevQuit)

go func() {
select {
case <-udevReadyCh:
close(udevQuit)

options.OnConnected()

return
case err := <-udevErrCh:
fatal <- err

return
}
}()
}

if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
device.Fd(),
Expand Down Expand Up @@ -204,20 +244,20 @@ n:
return err
}

if options.OnConnected != nil {
options.OnConnected()
}
go func() {
if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
device.Fd(),
ioctl.NEGOTIATION_IOCTL_DO_IT,
0,
); err != 0 {
fatal <- err

if _, _, err := syscall.Syscall(
syscall.SYS_IOCTL,
device.Fd(),
ioctl.NEGOTIATION_IOCTL_DO_IT,
0,
); err != 0 {
return err
}
return
}
}()

return nil
return <-fatal
}

func Disconnect(device *os.File) error {
Expand Down

0 comments on commit 409496b

Please sign in to comment.