(ctx context.Context, path string)
| 66 | } |
| 67 | |
| 68 | func (loopbackHandler) Unmount(ctx context.Context, path string) error { |
| 69 | loopdev, err := os.Readlink(path) |
| 70 | if err != nil { |
| 71 | if os.IsNotExist(err) { |
| 72 | return nil |
| 73 | } |
| 74 | return err |
| 75 | } |
| 76 | loop, err := os.Open(loopdev) |
| 77 | if err != nil { |
| 78 | return err |
| 79 | } |
| 80 | defer loop.Close() |
| 81 | |
| 82 | if err := setLoopAutoclear(loop, true); err != nil { |
| 83 | return fmt.Errorf("failed to set auto clear on loop device %q: %w", loopdev, err) |
| 84 | } |
| 85 | |
| 86 | if err := os.Remove(path); err != nil { |
| 87 | if os.IsNotExist(err) { |
| 88 | return nil |
| 89 | } |
| 90 | |
| 91 | // if removal of the symlink has failed, its possible for the loop device to get cleaned |
| 92 | // up and re-used. Leave the loop device around to prevent re-use and let a retry of |
| 93 | // Unmount clear it.` |
| 94 | if err := setLoopAutoclear(loop, false); err != nil { |
| 95 | // Very unlikely but log to track in case there is a problem with |
| 96 | // the loop being cleared and re-used. |
| 97 | log.G(ctx).WithError(err).Errorf("Failed to unset auto clear flag on symlink removal failure, loopback %q may be cleaned up while still being tracked", loopdev) |
| 98 | } |
| 99 | |
| 100 | return err |
| 101 | } |
| 102 | |
| 103 | return nil |
| 104 | } |
nothing calls this directly
no test coverage detected