|
9 | 9 | "os" |
10 | 10 | "syscall" |
11 | 11 |
|
| 12 | + "github.com/pilebones/go-udev/netlink" |
12 | 13 | "github.com/pojntfx/go-nbd/pkg/ioctl" |
13 | 14 | "github.com/pojntfx/go-nbd/pkg/protocol" |
14 | 15 | "github.com/pojntfx/go-nbd/pkg/server" |
@@ -79,6 +80,45 @@ func Connect(conn net.Conn, device *os.File, options *Options) error { |
79 | 80 | return ErrUnsupportedNetwork |
80 | 81 | } |
81 | 82 |
|
| 83 | + fatal := make(chan error) |
| 84 | + if options.OnConnected != nil { |
| 85 | + udevConn := new(netlink.UEventConn) |
| 86 | + if err := udevConn.Connect(netlink.UdevEvent); err != nil { |
| 87 | + return err |
| 88 | + } |
| 89 | + defer udevConn.Close() |
| 90 | + |
| 91 | + var ( |
| 92 | + udevReadyCh = make(chan netlink.UEvent) |
| 93 | + udevErrCh = make(chan error) |
| 94 | + udevQuit = udevConn.Monitor(udevReadyCh, udevErrCh, &netlink.RuleDefinitions{ |
| 95 | + Rules: []netlink.RuleDefinition{ |
| 96 | + { |
| 97 | + Env: map[string]string{ |
| 98 | + "DEVNAME": device.Name(), |
| 99 | + }, |
| 100 | + }, |
| 101 | + }, |
| 102 | + }) |
| 103 | + ) |
| 104 | + defer close(udevQuit) |
| 105 | + |
| 106 | + go func() { |
| 107 | + select { |
| 108 | + case <-udevReadyCh: |
| 109 | + close(udevQuit) |
| 110 | + |
| 111 | + options.OnConnected() |
| 112 | + |
| 113 | + return |
| 114 | + case err := <-udevErrCh: |
| 115 | + fatal <- err |
| 116 | + |
| 117 | + return |
| 118 | + } |
| 119 | + }() |
| 120 | + } |
| 121 | + |
82 | 122 | if _, _, err := syscall.Syscall( |
83 | 123 | syscall.SYS_IOCTL, |
84 | 124 | device.Fd(), |
|
204 | 244 | return err |
205 | 245 | } |
206 | 246 |
|
207 | | - if options.OnConnected != nil { |
208 | | - options.OnConnected() |
209 | | - } |
| 247 | + go func() { |
| 248 | + if _, _, err := syscall.Syscall( |
| 249 | + syscall.SYS_IOCTL, |
| 250 | + device.Fd(), |
| 251 | + ioctl.NEGOTIATION_IOCTL_DO_IT, |
| 252 | + 0, |
| 253 | + ); err != 0 { |
| 254 | + fatal <- err |
210 | 255 |
|
211 | | - if _, _, err := syscall.Syscall( |
212 | | - syscall.SYS_IOCTL, |
213 | | - device.Fd(), |
214 | | - ioctl.NEGOTIATION_IOCTL_DO_IT, |
215 | | - 0, |
216 | | - ); err != 0 { |
217 | | - return err |
218 | | - } |
| 256 | + return |
| 257 | + } |
| 258 | + }() |
219 | 259 |
|
220 | | - return nil |
| 260 | + return <-fatal |
221 | 261 | } |
222 | 262 |
|
223 | 263 | func Disconnect(device *os.File) error { |
|
0 commit comments