diff --git a/snapshots/devmapper/losetup/losetup.go b/snapshots/devmapper/losetup/losetup.go index 89faebf81..b9e9bf980 100644 --- a/snapshots/devmapper/losetup/losetup.go +++ b/snapshots/devmapper/losetup/losetup.go @@ -23,6 +23,7 @@ import ( "strings" "github.com/pkg/errors" + "golang.org/x/sys/unix" ) // FindAssociatedLoopDevices returns a list of loop devices attached to a given image @@ -65,7 +66,7 @@ func RemoveLoopDevicesAssociatedWithImage(imagePath string) error { } for _, loopDevice := range loopDevices { - if err = DetachLoopDevice(loopDevice); err != nil { + if err = DetachLoopDevice(loopDevice); err != nil && err != unix.ENOENT { return err } } @@ -75,9 +76,15 @@ func RemoveLoopDevicesAssociatedWithImage(imagePath string) error { // losetup is a wrapper around losetup command line tool func losetup(args ...string) (string, error) { - data, err := exec.Command("losetup", args...).CombinedOutput() + cmd := exec.Command("losetup", args...) + cmd.Env = append(cmd.Env, "LANG=C") + data, err := cmd.CombinedOutput() output := string(data) if err != nil { + if strings.Contains(output, "No such file or directory") || strings.Contains(output, "No such device") { + return "", unix.ENOENT + } + return "", errors.Wrapf(err, "losetup %s\nerror: %s\n", strings.Join(args, " "), output) } diff --git a/snapshots/devmapper/losetup/losetup_test.go b/snapshots/devmapper/losetup/losetup_test.go index 9eb4da558..773ee59ca 100644 --- a/snapshots/devmapper/losetup/losetup_test.go +++ b/snapshots/devmapper/losetup/losetup_test.go @@ -23,10 +23,12 @@ import ( "os" "testing" - "github.com/containerd/containerd/pkg/testutil" "github.com/docker/go-units" + "golang.org/x/sys/unix" "gotest.tools/assert" is "gotest.tools/assert/cmp" + + "github.com/containerd/containerd/pkg/testutil" ) func TestLosetup(t *testing.T) { @@ -98,6 +100,11 @@ func TestLosetup(t *testing.T) { err := RemoveLoopDevicesAssociatedWithImage("") assert.NilError(t, err) }) + + t.Run("DetachInvalidDevice", func(t *testing.T) { + err := DetachLoopDevice("/dev/loop_invalid_idx") + assert.Equal(t, unix.ENOENT, err) + }) } func createSparseImage(t *testing.T) string {