diff --git a/mount.go b/mount.go index 821cc875345..0e7d1087044 100644 --- a/mount.go +++ b/mount.go @@ -20,6 +20,7 @@ limitations under the License. package mount import ( + "fmt" "os" "path/filepath" "strings" @@ -76,6 +77,36 @@ type MountPoint struct { Pass int } +type MountErrorType string + +const ( + FilesystemMismatch MountErrorType = "FilesystemMismatch" + HasFilesystemErrors MountErrorType = "HasFilesystemErrors" + UnformattedReadOnly MountErrorType = "UnformattedReadOnly" + FormatFailed MountErrorType = "FormatFailed" +) + +type MountError struct { + Type MountErrorType + Message string +} + +func (mountError *MountError) String() string { + return mountError.Message +} + +func (mountError *MountError) Error() string { + return mountError.Message +} + +func NewMountError(mountErrorValue MountErrorType, format string, args ...interface{}) error { + mountError := &MountError{ + Type: mountErrorValue, + Message: fmt.Sprintf(format, args...), + } + return mountError +} + // SafeFormatAndMount probes a device to see if it is formatted. // Namely it checks to see if a file system is present. If so it // mounts it otherwise the device is formatted first then mounted. diff --git a/mount_linux.go b/mount_linux.go index 2e87f7169fd..77d01e78bd5 100644 --- a/mount_linux.go +++ b/mount_linux.go @@ -267,6 +267,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, } options = append(options, "defaults") + var mountErrorValue MountErrorType if !readOnly { // Run fsck on the disk to fix repairable issues, only do this for volumes requested as rw. @@ -281,7 +282,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, case isExitError && ee.ExitStatus() == fsckErrorsCorrected: klog.Infof("Device %s has errors which were corrected by fsck.", source) case isExitError && ee.ExitStatus() == fsckErrorsUncorrected: - return fmt.Errorf("'fsck' found errors on device %s but could not correct them: %s", source, string(out)) + return NewMountError(HasFilesystemErrors, "'fsck' found errors on device %s but could not correct them: %s", source, string(out)) case isExitError && ee.ExitStatus() > fsckErrorsUncorrected: klog.Infof("`fsck` error %s", string(out)) } @@ -302,7 +303,7 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, if existingFormat == "" { // Do not attempt to format the disk if mounting as readonly, return an error to reflect this. if readOnly { - return fmt.Errorf("cannot mount unformatted disk %s as we are manipulating it in read-only mode", source) + return NewMountError(UnformattedReadOnly, "cannot mount unformatted disk %s as we are manipulating it in read-only mode", source) } // Disk is unformatted so format it. @@ -319,19 +320,20 @@ func (mounter *SafeFormatAndMount) formatAndMount(source string, target string, _, err := mounter.Exec.Command("mkfs."+fstype, args...).CombinedOutput() if err != nil { klog.Errorf("format of disk %q failed: type:(%q) target:(%q) options:(%q)error:(%v)", source, fstype, target, options, err) - return err + return NewMountError(FormatFailed, err.Error()) } klog.Infof("Disk successfully formatted (mkfs): %s - %s %s", fstype, source, target) } else if fstype != existingFormat { // Verify that the disk is formatted with filesystem type we are expecting + mountErrorValue = FilesystemMismatch klog.Warningf("Configured to mount disk %s as %s but current format is %s, things might break", source, existingFormat, fstype) } // Mount the disk klog.V(4).Infof("Attempting to mount disk %s in %s format at %s", source, fstype, target) if err := mounter.Interface.Mount(source, target, fstype, options); err != nil { - return err + return NewMountError(mountErrorValue, err.Error()) } return nil