From 5136938ff6eef20adbccc6385b019daf66fd994b Mon Sep 17 00:00:00 2001 From: Yecheng Fu Date: Fri, 2 Feb 2018 18:47:24 +0800 Subject: [PATCH] Use `blkid` to get fs type of device. If a parition table type is detected, returns a special non-empty string as filesystem type. --- pkg/util/mount/mount_linux.go | 33 +++++++++++++++++--- pkg/util/mount/safe_format_and_mount_test.go | 16 +++++----- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/pkg/util/mount/mount_linux.go b/pkg/util/mount/mount_linux.go index a8d99963ff..78a48c4a78 100644 --- a/pkg/util/mount/mount_linux.go +++ b/pkg/util/mount/mount_linux.go @@ -538,7 +538,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, // GetDiskFormat uses 'blkid' to see if the given disk is unformated func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) { - args := []string{"-p", "-s", "TYPE", "-o", "value", disk} + args := []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", disk} glog.V(4).Infof("Attempting to determine if disk %q is formatted using blkid with args: (%v)", disk, args) dataOut, err := mounter.Exec.Run("blkid", args...) output := string(dataOut) @@ -549,12 +549,35 @@ func (mounter *SafeFormatAndMount) GetDiskFormat(disk string) (string, error) { return "", err } - if len(output) <= 0 { - // no fs type - return "", nil + var fstype, pttype string + + lines := strings.Split(output, "\n") + for _, l := range lines { + if len(l) <= 0 { + // Ignore empty line. + continue + } + cs := strings.Split(l, "=") + if len(cs) != 2 { + return "", fmt.Errorf("blkid returns invalid output: %s", output) + } + // TYPE is filesystem type, and PTTYPE is partition table type, according + // to https://www.kernel.org/pub/linux/utils/util-linux/v2.21/libblkid-docs/. + if cs[0] == "TYPE" { + fstype = cs[1] + } else if cs[0] == "PTTYPE" { + pttype = cs[1] + } } - return strings.TrimSpace(output), nil + if len(pttype) > 0 { + glog.V(4).Infof("Disk %s detected partition table type: %s", pttype) + // Returns a special non-empty string as filesystem type, then kubelet + // will not format it. + return "unknown data, probably partitions", nil + } + + return fstype, nil } // isShared returns true, if given path is on a mount point that has shared diff --git a/pkg/util/mount/safe_format_and_mount_test.go b/pkg/util/mount/safe_format_and_mount_test.go index 0e505622c6..e09af825c9 100644 --- a/pkg/util/mount/safe_format_and_mount_test.go +++ b/pkg/util/mount/safe_format_and_mount_test.go @@ -105,7 +105,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "ext4\n", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "DEVNAME=/dev/foo\nTYPE=ext4\n", nil}, }, expectedError: fmt.Errorf("unknown filesystem type '(null)'"), }, @@ -115,7 +115,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-F", "/dev/foo"}, "", fmt.Errorf("formatting failed")}, }, expectedError: fmt.Errorf("formatting failed"), @@ -126,7 +126,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), fmt.Errorf("Still cannot mount")}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-F", "/dev/foo"}, "", nil}, }, expectedError: fmt.Errorf("Still cannot mount"), @@ -137,7 +137,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", nil}, {"mkfs.ext4", []string{"-F", "/dev/foo"}, "", nil}, }, expectedError: nil, @@ -148,7 +148,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", nil}, {"mkfs.ext3", []string{"-F", "/dev/foo"}, "", nil}, }, expectedError: nil, @@ -159,7 +159,7 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'"), nil}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "", nil}, {"mkfs.xfs", []string{"/dev/foo"}, "", nil}, }, expectedError: nil, @@ -170,9 +170,9 @@ func TestSafeFormatAndMount(t *testing.T) { mountErrs: []error{fmt.Errorf("unknown filesystem type '(null)'")}, execScripts: []ExecArgs{ {"fsck", []string{"-a", "/dev/foo"}, "", nil}, - {"blkid", []string{"-p", "-s", "TYPE", "-o", "value", "/dev/foo"}, "LVM2_member\n", nil}, + {"blkid", []string{"-p", "-s", "TYPE", "-s", "PTTYPE", "-o", "export", "/dev/foo"}, "DEVNAME=/dev/foo\nPTTYPE=dos\n", nil}, }, - expectedError: fmt.Errorf("failed to mount the volume as \"ext3\", it already contains LVM2_member. Mount error: unknown filesystem type '(null)'"), + expectedError: fmt.Errorf("failed to mount the volume as \"ext3\", it already contains unknown data, probably partitions. Mount error: unknown filesystem type '(null)'"), }, }