Skip to content

hcsshim panics over an exception when destroying the base layer of a mounted layer #961

@TBBle

Description

@TBBle

See containerd/containerd#4924 for where we've seen this in the wild, on RS5 using MS-provided base layers rather than the hand-made one in the below reproduction case.

Reproduction using wclayer from #901 (with the "hive" fix mentioned there, as I'm WIndows 10 20H2.)

mkdir tm
cd tm
mkdir base\Files
wclayer makebaselayer base
wclayer create child -l base
wclayer mount child -l base
wclayer remove base

Output of wclayer remove base

Exception 0xc0000420 0x0 0x0 0x7ffaf8cc4aa2
PC=0x7ffaf8cc4aa2

syscall.Syscall(0x7ffb16ac0170, 0x2, 0x1079aa0, 0xc00000ca40, 0x0, 0x0, 0x0, 0x0)
        C:/Program Files/Go/src/runtime/syscall_windows.go:330 +0xe9
github.com/Microsoft/hcsshim/internal/wclayer._destroyLayer(0x1079aa0, 0xc00000ca40, 0xc00000ca40, 0x1a)
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go:236 +0xea
github.com/Microsoft/hcsshim/internal/wclayer.destroyLayer(0x1079aa0, 0xc000010720, 0x19, 0x1, 0x0)
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/internal/wclayer/zsyscall_windows.go:229 +0x8c
github.com/Microsoft/hcsshim/internal/wclayer.DestroyLayer(0xe7b418, 0xc0000120b8, 0xc000010720, 0x19, 0x0, 0x0)
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/internal/wclayer/destroylayer.go:20 +0x1c6
github.com/Microsoft/hcsshim.DestroyLayer(0x0, 0x0, 0x0, 0xc000010720, 0x19, 0x0, 0xdf6801)
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/layer.go:34 +0xbd
main.glob..func7(0xc0001aec60, 0xc0001d0a30, 0xc000006098)
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/cmd/wclayer/remove.go:29 +0x14d
github.com/urfave/cli.HandleAction(0xd8d160, 0xe1bab0, 0xc0001aec60, 0xc0001aec60, 0x0)
        C:/Users/paulh/go/pkg/mod/github.com/urfave/[email protected]/app.go:523 +0x110
github.com/urfave/cli.Command.Run(0xdf79be, 0x6, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe0fe7b, 0x35, 0x0, ...)
        C:/Users/paulh/go/pkg/mod/github.com/urfave/[email protected]/command.go:174 +0x579
github.com/urfave/cli.(*App).Run(0xc0001c4380, 0xc000022080, 0x3, 0x4, 0x0, 0x0)
        C:/Users/paulh/go/pkg/mod/github.com/urfave/[email protected]/app.go:276 +0x808
main.main()
        C:/Users/paulh/go/src/github.com/Microsoft/hcsshim/cmd/wclayer/wclayer.go:42 +0x28c
rax     0x20
rbx     0x0
rcx     0xc000002c
rdi     0x20
rsi     0x2899b7ffc80
rbp     0xe716fff0c9
rsp     0xe716fff060
r8      0x58
r9      0x59
r10     0x17
r11     0x246
r12     0x0
r13     0x0
r14     0x0
r15     0x0
rip     0x7ffaf8cc4aa2
rflags  0x246
cs      0x33
fs      0x53
gs      0x2b

That exception is 0xc0000420 STATUS_ASSERTION_FAILURE.

To clean up after the repro

wclayer unmount child
wclayer remove base
wclayer remove child

If I create create an intermediate layer

mkdir base\Files
wclayer makebaselayer base
wclayer create child -l base
wclayer export child -l base -o child.tar
wclayer import child -l base -i child.tar
wclayer create childchild -l child -l base
wclayer mount childchild -l child -l base

wclayer remove base fails with the same panic, but wclayer remove child actually succeeds. This might be because it was an empty layer, so there was actually nothing in childchild that was referencing child.

Technically, panic with "Assertion failure" isn't wrong for "you tried to destroy a layer that is in-use", but it would be nice to get an actual Win32 error that we can detect and recover from, as we would if we try to remove a mounted sandbox layer, e.g.

hcsshim::DestroyLayer - failed failed in Win32: The process cannot access the file because it is being used by another process. (0x20)

So I guess really it'd be better to have HCS not throw an exception here, but perhaps it's possible to catch and wrap that exception in hcsshim? I'd give it a burl, but I'd appreciate advice first as to whether that's a reasonable approach, or if it should just be, like the old Doctor Doctor joke, "Well, don't do that and it won't hurt".

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions