Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve fsck handling #249

Open
r0l1 opened this issue Dec 1, 2023 · 0 comments
Open

Improve fsck handling #249

r0l1 opened this issue Dec 1, 2023 · 0 comments

Comments

@r0l1
Copy link

r0l1 commented Dec 1, 2023

Quote from fsck man:

The exit code returned by fsck is the sum of the following conditions:
0 - No errors
1 - File system errors corrected
2 - System should be rebooted
4 - File system errors left uncorrected
8 - Operational error
16 - Usage or syntax error
32 - Fsck canceled by user request
128 - Shared library error
The exit code returned when multiple file systems are checked is the bit-wise OR of the exit codes for each file system that is checked.

Current code:

func fsck(dev string) error {
	if _, err := os.Stat("/usr/bin/fsck"); !os.IsNotExist(err) {
		cmd := exec.Command("/usr/bin/fsck", "-y", dev)
		if verbosityLevel >= levelDebug {
			cmd.Stdout = os.Stdout
		}
		if err := cmd.Run(); err != nil {
			if err, ok := err.(*exec.ExitError); ok {
				if err.ExitCode()&^0x1 != 0 {
					// bit 1 means errors were corrected successfully which is good
					return unwrapExitError(err)
				}
				return nil
			}

			return fmt.Errorf("fsck for %s: unknown error %v", dev, err)
		}
	}

	return nil
}

My personal improved code

  • Use fsck.ext4, because otherwise the incompatible busybox fsck will be used.
  • Bitwise checking should not be required, because we do not check multiple devices at once.
  • Ensure to check for exit code 2 and reboot
  • Hint: I enforce a fsck operation and removed the file exists check.
// TODO: check which filesystem type it is and select the correct fsck utility.
func fsck(dev string) (err error) {
	output, err := exec.Command("/usr/bin/fsck.ext4", "-y", dev).CombinedOutput()
	if err == nil {
		debug("fsck output: %s", string(output))
		return
	}

	if err, ok := err.(*exec.ExitError); ok {
		switch err.ExitCode() {
		case 0:
			return nil
		case 1: // File system errors corrected
			severe("fsck corrected filesystem errors: %s", string(output))
			return nil
		case 2: // File system errors corrected, system should be rebooted
			severe("fsck corrected filesystem errors: %s", string(output))
			syscall.Sync()
			fmt.Println("Reboot required")
			time.Sleep(3 * time.Second)
			return syscall.Reboot(syscall.LINUX_REBOOT_CMD_RESTART)
		}
	}
	return fmt.Errorf("fsck for %s: unknown error %v\n%s", dev, err, string(output))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant