@@ -16,6 +16,7 @@ import (
16
16
"time"
17
17
"unsafe"
18
18
19
+ infinity "github.com/Code-Hex/go-infinity-channel"
19
20
"github.com/Code-Hex/vz/v3/internal/objc"
20
21
)
21
22
@@ -210,12 +211,6 @@ func NewVirtioBlockDeviceConfiguration(attachment StorageDeviceAttachment) (*Vir
210
211
return config , nil
211
212
}
212
213
213
- func newVirtioBlockDeviceConfiguration (ptr unsafe.Pointer ) * VirtioBlockDeviceConfiguration {
214
- return & VirtioBlockDeviceConfiguration {
215
- pointer : objc .NewPointer (ptr ),
216
- }
217
- }
218
-
219
214
// BlockDeviceIdentifier returns the device identifier is a string identifying the Virtio block device.
220
215
// Empty string by default.
221
216
//
@@ -425,17 +420,8 @@ type NetworkBlockDeviceStorageDeviceAttachment struct {
425
420
426
421
* baseStorageDeviceAttachment
427
422
428
- attachmentStatusCh chan networkBlockDeviceStorageDeviceAttachmentStatusData
429
- }
430
-
431
- type NetworkBlockDeviceStorageDeviceAttachmentStatus interface {
432
- IsConnected () bool
433
- Error () error
434
- }
435
-
436
- type networkBlockDeviceStorageDeviceAttachmentStatusData struct {
437
- connected bool
438
- err error
423
+ didEncounterError * infinity.Channel [error ]
424
+ connected * infinity.Channel [struct {}]
439
425
}
440
426
441
427
var _ StorageDeviceAttachment = (* NetworkBlockDeviceStorageDeviceAttachment )(nil )
@@ -459,14 +445,15 @@ func NewNetworkBlockDeviceStorageDeviceAttachment(url string, timeout time.Durat
459
445
return nil , err
460
446
}
461
447
462
- ch := make (chan networkBlockDeviceStorageDeviceAttachmentStatusData )
448
+ didEncounterError := infinity .NewChannel [error ]()
449
+ connected := infinity .NewChannel [struct {}]()
463
450
464
451
handle := cgo .NewHandle (func (err error ) {
465
- connected := true
466
452
if err != nil {
467
- connected = false
453
+ didEncounterError .In () <- err
454
+ return
468
455
}
469
- ch <- networkBlockDeviceStorageDeviceAttachmentStatusData { connected , err }
456
+ connected . In () <- struct {}{ }
470
457
})
471
458
472
459
nserrPtr := newNSErrorAsNil ()
@@ -484,7 +471,8 @@ func NewNetworkBlockDeviceStorageDeviceAttachment(url string, timeout time.Durat
484
471
C .uintptr_t (handle ),
485
472
),
486
473
),
487
- attachmentStatusCh : ch ,
474
+ didEncounterError : didEncounterError ,
475
+ connected : connected ,
488
476
}
489
477
if err := newNSError (nserrPtr ); err != nil {
490
478
return nil , err
@@ -495,41 +483,48 @@ func NewNetworkBlockDeviceStorageDeviceAttachment(url string, timeout time.Durat
495
483
return attachment , nil
496
484
}
497
485
498
- // Returns the connected value. It is true if the NBD client successfully connected to the server. False if there was an error that prevented the connection
499
- func ( n * networkBlockDeviceStorageDeviceAttachmentStatusData ) IsConnected () bool {
500
- return n . connected
501
- }
502
-
503
- // Returns the error associated to the failed connection of the NBD client to the server
504
- func (n * networkBlockDeviceStorageDeviceAttachmentStatusData ) Error () error {
505
- return n .err
486
+ // Connected receive the signal via channel when the NBD client successfully connects or reconnects with the server.
487
+ //
488
+ // The NBD connection with the server takes place when the VM is first started, and reconnection attempts take place when the connection
489
+ // times out or when the NBD client has encountered a recoverable error, such as an I/O error from the server.
490
+ //
491
+ // Note that the Virtualization framework may call this method multiple times during a VM’s life cycle. Reconnections are transparent to the guest.
492
+ func (n * NetworkBlockDeviceStorageDeviceAttachment ) Connected () <- chan struct {} {
493
+ return n .connected . Out ()
506
494
}
507
495
508
- // It allows the caller to subscribe to the attachmentStatus channel to listen to changes of the network block device attachment
509
- // This way it can be informed if the NBD client successfully connects/reconnects to the server or it encounter an error
510
- func (n * NetworkBlockDeviceStorageDeviceAttachment ) Listen (statusCh chan NetworkBlockDeviceStorageDeviceAttachmentStatus ) {
511
- go func () {
512
- for {
513
- status := <- n .attachmentStatusCh
514
- statusCh <- & status
515
- }
516
- }()
496
+ // The DidEncounterError is triggered via the channel when the NBD client encounters an error that cannot be resolved on the client side.
497
+ // In this state, the client will continue attempting to reconnect, but recovery depends entirely on the server's availability.
498
+ // If the server resumes operation, the connection will recover automatically; however, until the server is restored, the client will continue to experience errors.
499
+ func (n * NetworkBlockDeviceStorageDeviceAttachment ) DidEncounterError () <- chan error {
500
+ return n .didEncounterError .Out ()
517
501
}
518
502
519
- //export attachmentHandler
520
- func attachmentHandler (cgoHandleUintptr C.uintptr_t , errorPtr unsafe.Pointer ) {
503
+ // attachmentDidEncounterErrorHandler function is called when the NBD client encounters a nonrecoverable error.
504
+ // After the attachment object calls this method, the NBD client is in a nonfunctional state.
505
+ //
506
+ //export attachmentDidEncounterErrorHandler
507
+ func attachmentDidEncounterErrorHandler (cgoHandleUintptr C.uintptr_t , errorPtr unsafe.Pointer ) {
521
508
cgoHandle := cgo .Handle (cgoHandleUintptr )
522
509
handler := cgoHandle .Value ().(func (error ))
523
510
524
511
err := newNSError (errorPtr )
525
512
526
- go handler (err )
513
+ handler (err )
527
514
}
528
515
516
+ // attachmentWasConnectedHandler function is called when a connection to the server is first established as the VM starts,
517
+ // and during any reconnection attempts triggered by connection timeouts or recoverable errors encountered by the NBD client,
518
+ // such as server-side I/O errors.
519
+ //
520
+ // Note that the Virtualization framework may invoke this method multiple times throughout the VM’s lifecycle,
521
+ // ensuring reconnection processes remain seamless and transparent to the guest.
522
+ // For more details, see: https://developer.apple.com/documentation/virtualization/vznetworkblockdevicestoragedeviceattachmentdelegate/4168511-attachmentwasconnected?language=objc
523
+ //
529
524
//export attachmentWasConnectedHandler
530
525
func attachmentWasConnectedHandler (cgoHandleUintptr C.uintptr_t ) {
531
526
cgoHandle := cgo .Handle (cgoHandleUintptr )
532
527
handler := cgoHandle .Value ().(func (error ))
533
528
534
- go handler (nil )
529
+ handler (nil )
535
530
}
0 commit comments