Browse code

Revendor hcsshim

Signed-off-by: Darren Stahl <darst@microsoft.com>

Darren Stahl authored on 2016/06/01 04:51:29
Showing 7 changed files
... ...
@@ -43,7 +43,7 @@ esac
43 43
 
44 44
 # the following lines are in sorted order, FYI
45 45
 clone git github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
46
-clone git github.com/Microsoft/hcsshim v0.3.0
46
+clone git github.com/Microsoft/hcsshim v0.3.1
47 47
 clone git github.com/Microsoft/go-winio v0.3.4
48 48
 clone git github.com/Sirupsen/logrus v0.10.0 # logrus is a common dependency among multiple deps
49 49
 clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
... ...
@@ -6740,3 +6740,18 @@ func (s *DockerSuite) TestBuildLabelsOverride(c *check.C) {
6740 6740
 	}
6741 6741
 
6742 6742
 }
6743
+
6744
+// Test case for #22855
6745
+func (s *DockerSuite) TestBuildDeleteCommittedFile(c *check.C) {
6746
+	name := "test-delete-committed-file"
6747
+
6748
+	_, err := buildImage(name,
6749
+		`FROM busybox
6750
+		RUN echo test > file
6751
+		RUN test -e file
6752
+		RUN rm file
6753
+		RUN sh -c "! test -e file"`, false)
6754
+	if err != nil {
6755
+		c.Fatal(err)
6756
+	}
6757
+}
... ...
@@ -40,39 +40,36 @@ type hcsNotification uint32
40 40
 type notificationChannel chan error
41 41
 
42 42
 type notifcationWatcherContext struct {
43
-	channel              notificationChannel
44
-	expectedNotification hcsNotification
45
-	handle               hcsCallback
43
+	channels notificationChannels
44
+	handle   hcsCallback
45
+}
46
+
47
+type notificationChannels map[hcsNotification]notificationChannel
48
+
49
+func newChannels() notificationChannels {
50
+	channels := make(notificationChannels)
51
+
52
+	channels[hcsNotificationSystemExited] = make(notificationChannel, 1)
53
+	channels[hcsNotificationSystemCreateCompleted] = make(notificationChannel, 1)
54
+	channels[hcsNotificationSystemStartCompleted] = make(notificationChannel, 1)
55
+	channels[hcsNotificationSystemPauseCompleted] = make(notificationChannel, 1)
56
+	channels[hcsNotificationSystemResumeCompleted] = make(notificationChannel, 1)
57
+	channels[hcsNotificationProcessExited] = make(notificationChannel, 1)
58
+	channels[hcsNotificationServiceDisconnect] = make(notificationChannel, 1)
59
+	return channels
46 60
 }
47 61
 
48 62
 func notificationWatcher(notificationType hcsNotification, callbackNumber uintptr, notificationStatus uintptr, notificationData *uint16) uintptr {
49
-	var (
50
-		result       error
51
-		completeWait = false
52
-	)
63
+	var result error
64
+	if int32(notificationStatus) < 0 {
65
+		result = syscall.Errno(win32FromHresult(notificationStatus))
66
+	}
53 67
 
54 68
 	callbackMapLock.RLock()
55
-	context := callbackMap[callbackNumber]
69
+	channels := callbackMap[callbackNumber].channels
56 70
 	callbackMapLock.RUnlock()
57 71
 
58
-	if notificationType == context.expectedNotification {
59
-		if int32(notificationStatus) < 0 {
60
-			result = syscall.Errno(win32FromHresult(notificationStatus))
61
-		} else {
62
-			result = nil
63
-		}
64
-		completeWait = true
65
-	} else if notificationType == hcsNotificationSystemExited {
66
-		result = ErrUnexpectedContainerExit
67
-		completeWait = true
68
-	} else if notificationType == hcsNotificationServiceDisconnect {
69
-		result = ErrUnexpectedProcessAbort
70
-		completeWait = true
71
-	}
72
-
73
-	if completeWait {
74
-		context.channel <- result
75
-	}
72
+	channels[notificationType] <- result
76 73
 
77 74
 	return 0
78 75
 }
... ...
@@ -26,8 +26,9 @@ type ContainerError struct {
26 26
 }
27 27
 
28 28
 type container struct {
29
-	handle hcsSystem
30
-	id     string
29
+	handle         hcsSystem
30
+	id             string
31
+	callbackNumber uintptr
31 32
 }
32 33
 
33 34
 type containerProperties struct {
... ...
@@ -47,7 +48,6 @@ type containerProperties struct {
47 47
 func CreateContainer(id string, c *ContainerConfig) (Container, error) {
48 48
 	operation := "CreateContainer"
49 49
 	title := "HCSShim::" + operation
50
-	logrus.Debugf(title+" id=%s", id)
51 50
 
52 51
 	container := &container{
53 52
 		id: id,
... ...
@@ -59,21 +59,28 @@ func CreateContainer(id string, c *ContainerConfig) (Container, error) {
59 59
 	}
60 60
 
61 61
 	configuration := string(configurationb)
62
+	logrus.Debugf(title+" id=%s config=%s", id, configuration)
62 63
 
63 64
 	var (
64
-		handle      hcsSystem
65 65
 		resultp     *uint16
66 66
 		createError error
67 67
 	)
68 68
 	if hcsCallbacksSupported {
69 69
 		var identity syscall.Handle
70
-		createError = hcsCreateComputeSystem(id, configuration, identity, &handle, &resultp)
70
+		createError = hcsCreateComputeSystem(id, configuration, identity, &container.handle, &resultp)
71
+
72
+		if createError == nil || createError == ErrVmcomputeOperationPending {
73
+			if err := container.registerCallback(); err != nil {
74
+				err := &ContainerError{Container: container, Operation: operation, Err: err}
75
+				logrus.Error(err)
76
+				return nil, err
77
+			}
78
+		}
71 79
 	} else {
72
-		createError = hcsCreateComputeSystemTP5(id, configuration, &handle, &resultp)
80
+		createError = hcsCreateComputeSystemTP5(id, configuration, &container.handle, &resultp)
73 81
 	}
74
-	container.handle = handle
75 82
 
76
-	err = processAsyncHcsResult(container, createError, resultp, hcsNotificationSystemCreateCompleted, &defaultTimeout)
83
+	err = processAsyncHcsResult(createError, resultp, container.callbackNumber, hcsNotificationSystemCreateCompleted, &defaultTimeout)
77 84
 	if err != nil {
78 85
 		err := &ContainerError{Container: container, Operation: operation, ExtraInfo: configuration, Err: err}
79 86
 		logrus.Error(err)
... ...
@@ -122,7 +129,7 @@ func (container *container) Start() error {
122 122
 
123 123
 	var resultp *uint16
124 124
 	err := hcsStartComputeSystemTP5(container.handle, nil, &resultp)
125
-	err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemStartCompleted, &defaultTimeout)
125
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemStartCompleted, &defaultTimeout)
126 126
 	if err != nil {
127 127
 		err := &ContainerError{Container: container, Operation: operation, Err: err}
128 128
 		logrus.Error(err)
... ...
@@ -186,7 +193,7 @@ func (container *container) Wait() error {
186 186
 	logrus.Debugf(title+" id=%s", container.id)
187 187
 
188 188
 	if hcsCallbacksSupported {
189
-		err := registerAndWaitForCallback(container, hcsNotificationSystemExited)
189
+		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, nil)
190 190
 		if err != nil {
191 191
 			err := &ContainerError{Container: container, Operation: operation, Err: err}
192 192
 			logrus.Error(err)
... ...
@@ -217,7 +224,7 @@ func (container *container) WaitTimeout(timeout time.Duration) error {
217 217
 	logrus.Debugf(title+" id=%s", container.id)
218 218
 
219 219
 	if hcsCallbacksSupported {
220
-		err := registerAndWaitForCallbackTimeout(container, hcsNotificationSystemExited, timeout)
220
+		err := waitForNotification(container.callbackNumber, hcsNotificationSystemExited, &timeout)
221 221
 		if err == ErrTimeout {
222 222
 			return ErrTimeout
223 223
 		} else if err != nil {
... ...
@@ -304,7 +311,7 @@ func (container *container) Pause() error {
304 304
 
305 305
 	var resultp *uint16
306 306
 	err := hcsPauseComputeSystemTP5(container.handle, nil, &resultp)
307
-	err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemPauseCompleted, &defaultTimeout)
307
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemPauseCompleted, &defaultTimeout)
308 308
 	if err != nil {
309 309
 		err := &ContainerError{Container: container, Operation: operation, Err: err}
310 310
 		logrus.Error(err)
... ...
@@ -325,7 +332,7 @@ func (container *container) Resume() error {
325 325
 	)
326 326
 
327 327
 	err := hcsResumeComputeSystemTP5(container.handle, nil, &resultp)
328
-	err = processAsyncHcsResult(container, err, resultp, hcsNotificationSystemResumeCompleted, &defaultTimeout)
328
+	err = processAsyncHcsResult(err, resultp, container.callbackNumber, hcsNotificationSystemResumeCompleted, &defaultTimeout)
329 329
 	if err != nil {
330 330
 		err := &ContainerError{Container: container, Operation: operation, Err: err}
331 331
 		logrus.Error(err)
... ...
@@ -340,7 +347,6 @@ func (container *container) Resume() error {
340 340
 func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
341 341
 	operation := "CreateProcess"
342 342
 	title := "HCSShim::Container::" + operation
343
-	logrus.Debugf(title+" id=%s", container.id)
344 343
 	var (
345 344
 		processInfo   hcsProcessInformation
346 345
 		processHandle hcsProcess
... ...
@@ -359,6 +365,7 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
359 359
 	}
360 360
 
361 361
 	configuration := string(configurationb)
362
+	logrus.Debugf(title+" id=%s config=%s", container.id, configuration)
362 363
 
363 364
 	err = hcsCreateProcess(container.handle, configuration, &processInfo, &processHandle, &resultp)
364 365
 	err = processHcsResult(err, resultp)
... ...
@@ -379,6 +386,14 @@ func (container *container) CreateProcess(c *ProcessConfig) (Process, error) {
379 379
 		},
380 380
 	}
381 381
 
382
+	if hcsCallbacksSupported {
383
+		if err := process.registerCallback(); err != nil {
384
+			err = &ContainerError{Container: container, Operation: operation, Err: err}
385
+			logrus.Error(err)
386
+			return nil, err
387
+		}
388
+	}
389
+
382 390
 	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
383 391
 	runtime.SetFinalizer(process, closeProcess)
384 392
 	return process, nil
... ...
@@ -408,6 +423,12 @@ func (container *container) OpenProcess(pid int) (Process, error) {
408 408
 		container: container,
409 409
 	}
410 410
 
411
+	if err := process.registerCallback(); err != nil {
412
+		err = &ContainerError{Container: container, Operation: operation, Err: err}
413
+		logrus.Error(err)
414
+		return nil, err
415
+	}
416
+
411 417
 	logrus.Debugf(title+" succeeded id=%s processid=%s", container.id, process.processID)
412 418
 	runtime.SetFinalizer(process, closeProcess)
413 419
 	return process, nil
... ...
@@ -424,6 +445,14 @@ func (container *container) Close() error {
424 424
 		return nil
425 425
 	}
426 426
 
427
+	if hcsCallbacksSupported {
428
+		if err := container.unregisterCallback(); err != nil {
429
+			err = &ContainerError{Container: container, Operation: operation, Err: err}
430
+			logrus.Error(err)
431
+			return err
432
+		}
433
+	}
434
+
427 435
 	if err := hcsCloseComputeSystem(container.handle); err != nil {
428 436
 		err = &ContainerError{Container: container, Operation: operation, Err: err}
429 437
 		logrus.Error(err)
... ...
@@ -441,7 +470,7 @@ func closeContainer(container *container) {
441 441
 	container.Close()
442 442
 }
443 443
 
444
-func (container *container) registerCallback(expectedNotification hcsNotification) (uintptr, error) {
444
+func (container *container) registerCallback() error {
445 445
 	callbackMapLock.Lock()
446 446
 	defer callbackMapLock.Unlock()
447 447
 
... ...
@@ -449,22 +478,24 @@ func (container *container) registerCallback(expectedNotification hcsNotificatio
449 449
 	nextCallback++
450 450
 
451 451
 	context := &notifcationWatcherContext{
452
-		expectedNotification: expectedNotification,
453
-		channel:              make(chan error, 1),
452
+		channels: newChannels(),
454 453
 	}
455 454
 	callbackMap[callbackNumber] = context
456 455
 
457 456
 	var callbackHandle hcsCallback
458 457
 	err := hcsRegisterComputeSystemCallback(container.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
459 458
 	if err != nil {
460
-		return 0, err
459
+		return err
461 460
 	}
462 461
 	context.handle = callbackHandle
462
+	container.callbackNumber = callbackNumber
463 463
 
464
-	return callbackNumber, nil
464
+	return nil
465 465
 }
466 466
 
467
-func (container *container) unregisterCallback(callbackNumber uintptr) error {
467
+func (container *container) unregisterCallback() error {
468
+	callbackNumber := container.callbackNumber
469
+
468 470
 	callbackMapLock.Lock()
469 471
 	defer callbackMapLock.Unlock()
470 472
 
... ...
@@ -4,6 +4,7 @@ import (
4 4
 	"bufio"
5 5
 	"encoding/binary"
6 6
 	"errors"
7
+	"fmt"
7 8
 	"io"
8 9
 	"os"
9 10
 	"path/filepath"
... ...
@@ -77,7 +78,7 @@ func readTombstones(path string) (map[string]([]string), error) {
77 77
 
78 78
 	ts := make(map[string]([]string))
79 79
 	for s.Scan() {
80
-		t := s.Text()[1:] // skip leading `\`
80
+		t := filepath.Join("Files", s.Text()[1:]) // skip leading `\`
81 81
 		dir := filepath.Dir(t)
82 82
 		ts[dir] = append(ts[dir], t)
83 83
 	}
... ...
@@ -107,6 +108,7 @@ func (r *legacyLayerReader) walkUntilCancelled() error {
107 107
 		if path == r.root || path == filepath.Join(r.root, "tombstones.txt") || strings.HasSuffix(path, ".$wcidirs$") {
108 108
 			return nil
109 109
 		}
110
+
110 111
 		r.result <- &fileEntry{path, info, nil}
111 112
 		if !<-r.proceed {
112 113
 			return errorIterationCanceled
... ...
@@ -120,7 +122,7 @@ func (r *legacyLayerReader) walkUntilCancelled() error {
120 120
 			}
121 121
 			if dts, ok := ts[relPath]; ok {
122 122
 				for _, t := range dts {
123
-					r.result <- &fileEntry{t, nil, nil}
123
+					r.result <- &fileEntry{filepath.Join(r.root, t), nil, nil}
124 124
 					if !<-r.proceed {
125 125
 						return errorIterationCanceled
126 126
 					}
... ...
@@ -397,7 +399,10 @@ func (w *legacyLayerWriter) AddLink(name string, target string) error {
397 397
 }
398 398
 
399 399
 func (w *legacyLayerWriter) Remove(name string) error {
400
-	w.tombstones = append(w.tombstones, name)
400
+	if !strings.HasPrefix(name, `Files\`) {
401
+		return fmt.Errorf("invalid tombstone %s", name)
402
+	}
403
+	w.tombstones = append(w.tombstones, name[len(`Files\`):])
401 404
 	return nil
402 405
 }
403 406
 
... ...
@@ -22,11 +22,11 @@ type ProcessError struct {
22 22
 }
23 23
 
24 24
 type process struct {
25
-	handle             hcsProcess
26
-	processID          int
27
-	container          *container
28
-	cachedPipes        *cachedPipes
29
-	killCallbackNumber uintptr
25
+	handle         hcsProcess
26
+	processID      int
27
+	container      *container
28
+	cachedPipes    *cachedPipes
29
+	callbackNumber uintptr
30 30
 }
31 31
 
32 32
 type cachedPipes struct {
... ...
@@ -101,7 +101,7 @@ func (process *process) Wait() error {
101 101
 	logrus.Debugf(title+" processid=%d", process.processID)
102 102
 
103 103
 	if hcsCallbacksSupported {
104
-		err := registerAndWaitForCallback(process, hcsNotificationProcessExited)
104
+		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, nil)
105 105
 		if err != nil {
106 106
 			err := &ProcessError{Operation: operation, Process: process, Err: err}
107 107
 			logrus.Error(err)
... ...
@@ -128,7 +128,7 @@ func (process *process) WaitTimeout(timeout time.Duration) error {
128 128
 	logrus.Debugf(title+" processid=%d", process.processID)
129 129
 
130 130
 	if hcsCallbacksSupported {
131
-		err := registerAndWaitForCallbackTimeout(process, hcsNotificationProcessExited, timeout)
131
+		err := waitForNotification(process.callbackNumber, hcsNotificationProcessExited, &timeout)
132 132
 		if err == ErrTimeout {
133 133
 			return ErrTimeout
134 134
 		} else if err != nil {
... ...
@@ -344,6 +344,14 @@ func (process *process) Close() error {
344 344
 		return nil
345 345
 	}
346 346
 
347
+	if hcsCallbacksSupported {
348
+		if err := process.unregisterCallback(); err != nil {
349
+			err = &ProcessError{Operation: operation, Process: process, Err: err}
350
+			logrus.Error(err)
351
+			return err
352
+		}
353
+	}
354
+
347 355
 	if err := hcsCloseProcess(process.handle); err != nil {
348 356
 		err = &ProcessError{Operation: operation, Process: process, Err: err}
349 357
 		logrus.Error(err)
... ...
@@ -361,7 +369,7 @@ func closeProcess(process *process) {
361 361
 	process.Close()
362 362
 }
363 363
 
364
-func (process *process) registerCallback(expectedNotification hcsNotification) (uintptr, error) {
364
+func (process *process) registerCallback() error {
365 365
 	callbackMapLock.Lock()
366 366
 	defer callbackMapLock.Unlock()
367 367
 
... ...
@@ -369,22 +377,24 @@ func (process *process) registerCallback(expectedNotification hcsNotification) (
369 369
 	nextCallback++
370 370
 
371 371
 	context := &notifcationWatcherContext{
372
-		expectedNotification: expectedNotification,
373
-		channel:              make(chan error, 1),
372
+		channels: newChannels(),
374 373
 	}
375 374
 	callbackMap[callbackNumber] = context
376 375
 
377 376
 	var callbackHandle hcsCallback
378 377
 	err := hcsRegisterProcessCallback(process.handle, notificationWatcherCallback, callbackNumber, &callbackHandle)
379 378
 	if err != nil {
380
-		return 0, err
379
+		return err
381 380
 	}
382 381
 	context.handle = callbackHandle
382
+	process.callbackNumber = callbackNumber
383 383
 
384
-	return callbackNumber, nil
384
+	return nil
385 385
 }
386 386
 
387
-func (process *process) unregisterCallback(callbackNumber uintptr) error {
387
+func (process *process) unregisterCallback() error {
388
+	callbackNumber := process.callbackNumber
389
+
388 390
 	callbackMapLock.Lock()
389 391
 	defer callbackMapLock.Unlock()
390 392
 	handle := callbackMap[callbackNumber].handle
... ...
@@ -1,6 +1,7 @@
1 1
 package hcsshim
2 2
 
3 3
 import (
4
+	"github.com/Sirupsen/logrus"
4 5
 	"syscall"
5 6
 	"time"
6 7
 )
... ...
@@ -10,11 +11,6 @@ type waitable interface {
10 10
 	hcsWait(timeout uint32) (bool, error)
11 11
 }
12 12
 
13
-type callbackable interface {
14
-	registerCallback(expectedNotification hcsNotification) (uintptr, error)
15
-	unregisterCallback(callbackNumber uintptr) error
16
-}
17
-
18 13
 func waitTimeoutHelper(object waitable, timeout time.Duration) (bool, error) {
19 14
 	var (
20 15
 		millis uint32
... ...
@@ -52,62 +48,62 @@ func waitForSingleObject(handle syscall.Handle, timeout uint32) (bool, error) {
52 52
 	}
53 53
 }
54 54
 
55
-func processAsyncHcsResult(object callbackable, err error, resultp *uint16, expectedNotification hcsNotification, timeout *time.Duration) error {
55
+func processAsyncHcsResult(err error, resultp *uint16, callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
56 56
 	err = processHcsResult(err, resultp)
57 57
 	if err == ErrVmcomputeOperationPending {
58
-		if timeout != nil {
59
-			err = registerAndWaitForCallbackTimeout(object, expectedNotification, *timeout)
60
-		} else {
61
-			err = registerAndWaitForCallback(object, expectedNotification)
62
-		}
58
+		return waitForNotification(callbackNumber, expectedNotification, timeout)
63 59
 	}
64 60
 
65 61
 	return err
66 62
 }
67 63
 
68
-func registerAndWaitForCallbackTimeout(object callbackable, expectedNotification hcsNotification, timeout time.Duration) error {
69
-	callbackNumber, err := object.registerCallback(expectedNotification)
70
-	if err != nil {
71
-		return err
72
-	}
73
-	defer object.unregisterCallback(callbackNumber)
74
-
75
-	return waitForNotificationTimeout(callbackNumber, timeout)
76
-}
77
-
78
-func registerAndWaitForCallback(object callbackable, expectedNotification hcsNotification) error {
79
-	callbackNumber, err := object.registerCallback(expectedNotification)
80
-	if err != nil {
81
-		return err
82
-	}
83
-	defer object.unregisterCallback(callbackNumber)
84
-
85
-	return waitForNotification(callbackNumber)
86
-}
87
-
88
-func waitForNotificationTimeout(callbackNumber uintptr, timeout time.Duration) error {
64
+func waitForNotification(callbackNumber uintptr, expectedNotification hcsNotification, timeout *time.Duration) error {
89 65
 	callbackMapLock.RLock()
90
-	channel := callbackMap[callbackNumber].channel
66
+	channels := callbackMap[callbackNumber].channels
91 67
 	callbackMapLock.RUnlock()
92 68
 
93
-	timer := time.NewTimer(timeout)
94
-	defer timer.Stop()
95
-
96
-	select {
97
-	case err := <-channel:
98
-		return err
99
-	case <-timer.C:
100
-		return ErrTimeout
69
+	expectedChannel := channels[expectedNotification]
70
+	if expectedChannel == nil {
71
+		logrus.Errorf("unknown notification type in waitForNotification %x", expectedNotification)
101 72
 	}
102
-}
103
-
104
-func waitForNotification(callbackNumber uintptr) error {
105
-	callbackMapLock.RLock()
106
-	channel := callbackMap[callbackNumber].channel
107
-	callbackMapLock.RUnlock()
108 73
 
74
+	if timeout != nil {
75
+		timer := time.NewTimer(*timeout)
76
+		defer timer.Stop()
77
+
78
+		select {
79
+		case err := <-expectedChannel:
80
+			return err
81
+		case err := <-channels[hcsNotificationSystemExited]:
82
+			// If the expected notification is hcsNotificationSystemExited which of the two selects
83
+			// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
84
+			if channels[hcsNotificationSystemExited] == expectedChannel {
85
+				return err
86
+			}
87
+			return ErrUnexpectedContainerExit
88
+		case err := <-channels[hcsNotificationServiceDisconnect]:
89
+			// hcsNotificationServiceDisconnect should never be an expected notification
90
+			// it does not need the same handling as hcsNotificationSystemExited
91
+			logrus.Error(err)
92
+			return ErrUnexpectedProcessAbort
93
+		case <-timer.C:
94
+			return ErrTimeout
95
+		}
96
+	}
109 97
 	select {
110
-	case err := <-channel:
98
+	case err := <-expectedChannel:
111 99
 		return err
100
+	case err := <-channels[hcsNotificationSystemExited]:
101
+		// If the expected notification is hcsNotificationSystemExited which of the two selects
102
+		// chosen is random. Return the raw error if hcsNotificationSystemExited is expected
103
+		if channels[hcsNotificationSystemExited] == expectedChannel {
104
+			return err
105
+		}
106
+		return ErrUnexpectedContainerExit
107
+	case err := <-channels[hcsNotificationServiceDisconnect]:
108
+		// hcsNotificationServiceDisconnect should never be an expected notification
109
+		// it does not need the same handling as hcsNotificationSystemExited
110
+		logrus.Error(err)
111
+		return ErrUnexpectedProcessAbort
112 112
 	}
113 113
 }