@@ -27,6 +27,7 @@ import (
2727 "syscall"
2828 "unsafe"
2929
30+ "github.com/Microsoft/go-winio/vhd"
3031 "github.com/Microsoft/hcsshim"
3132 "github.com/containerd/containerd/errdefs"
3233 "github.com/containerd/containerd/log"
@@ -206,9 +207,20 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
206207
207208 path := s .getSnapshotDir (id )
208209 renamedID := "rm-" + id
209- renamed := filepath . Join ( s . root , "snapshots" , renamedID )
210+ renamed := s . getSnapshotDir ( renamedID )
210211 if err := os .Rename (path , renamed ); err != nil && ! os .IsNotExist (err ) {
211- return err
212+ if ! os .IsPermission (err ) {
213+ return err
214+ }
215+ // If permission denied, it's possible that the scratch is still mounted, an
216+ // artifact after a hard daemon crash for example. Worth a shot to try detaching it
217+ // before retrying the rename.
218+ if detachErr := vhd .DetachVhd (filepath .Join (path , "sandbox.vhdx" )); detachErr != nil {
219+ return errors .Wrapf (err , "failed to detach VHD: %s" , detachErr )
220+ }
221+ if renameErr := os .Rename (path , renamed ); renameErr != nil && ! os .IsNotExist (renameErr ) {
222+ return errors .Wrapf (err , "second rename attempt following detach failed: %s" , renameErr )
223+ }
212224 }
213225
214226 if err := t .Commit (); err != nil {
0 commit comments