mirror of https://github.com/k3s-io/k3s
Merge pull request #31515 from jsafrane/format-error
Automatic merge from submit-queue (batch tested with PRs 41714, 41510, 42052, 41918, 31515) Show specific error when a volume is formatted by unexpected filesystem. kubelet now detects that e.g. xfs volume is being mounted as ext3 because of wrong volume.Spec. Mount error is left in the error message to diagnose issues with mounting e.g. 'ext3' volume as 'ext4' - they are different filesystems, however kernel should mount ext3 as ext4 without errors. Example kubectl describe pod output: ``` FirstSeen LastSeen Count From SubobjectPath Type Reason Message 41s 3s 7 {kubelet ip-172-18-3-82.ec2.internal} Warning FailedMount MountVolume.MountDevice failed for volume "kubernetes.io/aws-ebs/aws://us-east-1d/vol-ba79c81d" (spec.Name: "pvc-ce175cbb-6b82-11e6-9fe4-0e885cca73d3") pod "3d19cb64-6b83-11e6-9fe4-0e885cca73d3" (UID: "3d19cb64-6b83-11e6-9fe4-0e885cca73d3") with: failed to mount the volume as "ext4", it's already formatted with "xfs". Mount error: mount failed: exit status 32 Mounting arguments: /dev/xvdba /var/lib/kubelet/plugins/kubernetes.io/aws-ebs/mounts/aws/us-east-1d/vol-ba79c81d ext4 [defaults] Output: mount: wrong fs type, bad option, bad superblock on /dev/xvdba, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so. ```pull/6/head
commit
a426904009
|
@ -347,17 +347,22 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
|||
|
||||
// Try to mount the disk
|
||||
glog.V(4).Infof("Attempting to mount disk: %s %s %s", fstype, source, target)
|
||||
err = mounter.Interface.Mount(source, target, fstype, options)
|
||||
if err != nil {
|
||||
// It is possible that this disk is not formatted. Double check using diskLooksUnformatted
|
||||
notFormatted, err := mounter.diskLooksUnformatted(source)
|
||||
if err == nil && notFormatted {
|
||||
args = []string{source}
|
||||
mountErr := mounter.Interface.Mount(source, target, fstype, options)
|
||||
if mountErr != nil {
|
||||
// Mount failed. This indicates either that the disk is unformatted or
|
||||
// it contains an unexpected filesystem.
|
||||
existingFormat, err := mounter.getDiskFormat(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if existingFormat == "" {
|
||||
// Disk is unformatted so format it.
|
||||
args = []string{source}
|
||||
// Use 'ext4' as the default
|
||||
if len(fstype) == 0 {
|
||||
fstype = "ext4"
|
||||
}
|
||||
|
||||
if fstype == "ext4" || fstype == "ext3" {
|
||||
args = []string{"-F", source}
|
||||
}
|
||||
|
@ -371,13 +376,22 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string,
|
|||
}
|
||||
glog.Errorf("format of disk %q failed: type:(%q) target:(%q) options:(%q)error:(%v)", source, fstype, target, options, err)
|
||||
return err
|
||||
} else {
|
||||
// Disk is already formatted and failed to mount
|
||||
if len(fstype) == 0 || fstype == existingFormat {
|
||||
// This is mount error
|
||||
return mountErr
|
||||
} else {
|
||||
// Block device is formatted with unexpected filesystem, let the user know
|
||||
return fmt.Errorf("failed to mount the volume as %q, it's already formatted with %q. Mount error: %v", fstype, existingFormat, mountErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
return err
|
||||
return mountErr
|
||||
}
|
||||
|
||||
// diskLooksUnformatted uses 'lsblk' to see if the given disk is unformated
|
||||
func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, error) {
|
||||
func (mounter *SafeFormatAndMount) getDiskFormat(disk string) (string, error) {
|
||||
args := []string{"-nd", "-o", "FSTYPE", disk}
|
||||
cmd := mounter.Runner.Command("lsblk", args...)
|
||||
glog.V(4).Infof("Attempting to determine if disk %q is formatted using lsblk with args: (%v)", disk, args)
|
||||
|
@ -389,8 +403,8 @@ func (mounter *SafeFormatAndMount) diskLooksUnformatted(disk string) (bool, erro
|
|||
|
||||
if err != nil {
|
||||
glog.Errorf("Could not determine if disk %q is formatted (%v)", disk, err)
|
||||
return false, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
return output == "", nil
|
||||
return strings.TrimSpace(output), nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue