123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- //go:build windows
- package hcs
- import (
- "fmt"
- "sync"
- "syscall"
- "github.com/Microsoft/hcsshim/internal/interop"
- "github.com/Microsoft/hcsshim/internal/logfields"
- "github.com/Microsoft/hcsshim/internal/vmcompute"
- "github.com/sirupsen/logrus"
- )
- var (
- nextCallback uintptr
- callbackMap = map[uintptr]*notificationWatcherContext{}
- callbackMapLock = sync.RWMutex{}
- notificationWatcherCallback = syscall.NewCallback(notificationWatcher)
- // Notifications for HCS_SYSTEM handles
- hcsNotificationSystemExited hcsNotification = 0x00000001
- hcsNotificationSystemCreateCompleted hcsNotification = 0x00000002
- hcsNotificationSystemStartCompleted hcsNotification = 0x00000003
- hcsNotificationSystemPauseCompleted hcsNotification = 0x00000004
- hcsNotificationSystemResumeCompleted hcsNotification = 0x00000005
- hcsNotificationSystemCrashReport hcsNotification = 0x00000006
- hcsNotificationSystemSiloJobCreated hcsNotification = 0x00000007
- hcsNotificationSystemSaveCompleted hcsNotification = 0x00000008
- hcsNotificationSystemRdpEnhancedModeStateChanged hcsNotification = 0x00000009
- hcsNotificationSystemShutdownFailed hcsNotification = 0x0000000A
- hcsNotificationSystemGetPropertiesCompleted hcsNotification = 0x0000000B
- hcsNotificationSystemModifyCompleted hcsNotification = 0x0000000C
- hcsNotificationSystemCrashInitiated hcsNotification = 0x0000000D
- hcsNotificationSystemGuestConnectionClosed hcsNotification = 0x0000000E
- // Notifications for HCS_PROCESS handles
- hcsNotificationProcessExited hcsNotification = 0x00010000
- // Common notifications
- hcsNotificationInvalid hcsNotification = 0x00000000
- hcsNotificationServiceDisconnect hcsNotification = 0x01000000
- )
- type hcsNotification uint32
- func (hn hcsNotification) String() string {
- switch hn {
- case hcsNotificationSystemExited:
- return "SystemExited"
- case hcsNotificationSystemCreateCompleted:
- return "SystemCreateCompleted"
- case hcsNotificationSystemStartCompleted:
- return "SystemStartCompleted"
- case hcsNotificationSystemPauseCompleted:
- return "SystemPauseCompleted"
- case hcsNotificationSystemResumeCompleted:
- return "SystemResumeCompleted"
- case hcsNotificationSystemCrashReport:
- return "SystemCrashReport"
- case hcsNotificationSystemSiloJobCreated:
- return "SystemSiloJobCreated"
- case hcsNotificationSystemSaveCompleted:
- return "SystemSaveCompleted"
- case hcsNotificationSystemRdpEnhancedModeStateChanged:
- return "SystemRdpEnhancedModeStateChanged"
- case hcsNotificationSystemShutdownFailed:
- return "SystemShutdownFailed"
- case hcsNotificationSystemGetPropertiesCompleted:
- return "SystemGetPropertiesCompleted"
- case hcsNotificationSystemModifyCompleted:
- return "SystemModifyCompleted"
- case hcsNotificationSystemCrashInitiated:
- return "SystemCrashInitiated"
- case hcsNotificationSystemGuestConnectionClosed:
- return "SystemGuestConnectionClosed"
- case hcsNotificationProcessExited:
- return "ProcessExited"
- case hcsNotificationInvalid:
- return "Invalid"
- case hcsNotificationServiceDisconnect:
- return "ServiceDisconnect"
- default:
- return fmt.Sprintf("Unknown: %d", hn)
- }
- }
- type notificationChannel chan error
- type notificationWatcherContext struct {
- channels notificationChannels
- handle vmcompute.HcsCallback
- systemID string
- processID int
- }
- type notificationChannels map[hcsNotification]notificationChannel
- func newSystemChannels() notificationChannels {
- channels := make(notificationChannels)
- for _, notif := range []hcsNotification{
- hcsNotificationServiceDisconnect,
- hcsNotificationSystemExited,
- hcsNotificationSystemCreateCompleted,
- hcsNotificationSystemStartCompleted,
- hcsNotificationSystemPauseCompleted,
- hcsNotificationSystemResumeCompleted,
- hcsNotificationSystemSaveCompleted,
- } {
- channels[notif] = make(notificationChannel, 1)
- }
- return channels
- }
- func newProcessChannels() notificationChannels {
- channels := make(notificationChannels)
- for _, notif := range []hcsNotification{
- hcsNotificationServiceDisconnect,
- hcsNotificationProcessExited,
- } {
- channels[notif] = make(notificationChannel, 1)
- }
- return channels
- }
- func closeChannels(channels notificationChannels) {
- for _, c := range channels {
- close(c)
- }
- }
- func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
- var result error
- if int32(notificationStatus) < 0 {
- result = interop.Win32FromHresult(notificationStatus)
- }
- callbackMapLock.RLock()
- context := callbackMap[callbackNumber]
- callbackMapLock.RUnlock()
- if context == nil {
- return 0
- }
- log := logrus.WithFields(logrus.Fields{
- "notification-type": notificationType.String(),
- "system-id": context.systemID,
- })
- if context.processID != 0 {
- log.Data[logfields.ProcessID] = context.processID
- }
- log.Debug("HCS notification")
- if channel, ok := context.channels[notificationType]; ok {
- channel <- result
- }
- return 0
- }
|