in gce-containers-startup/volumes/volumes.go [464:515]
func (env Env) checkFilesystemAndFormatIfNeeded(devicePath string, configuredFsType string) error {
// Should be const, but Go can't into map consts.
filesystemCheckerMap := map[string][]string{
ext4FsType: []string{"fsck.ext4", "-p"},
}
filesystemFormatterMap := map[string][]string{
ext4FsType: []string{"mkfs.ext4"},
}
filesystemChecker := filesystemCheckerMap[configuredFsType]
filesystemFormatter := filesystemFormatterMap[configuredFsType]
if filesystemChecker == nil || filesystemFormatter == nil {
return fmt.Errorf("Could not find checker or formatter for filesystem %s.", configuredFsType)
}
const lsblkFsType string = "FSTYPE"
foundFsType, err := env.getSinglePropertyFromDeviceWithLsblk(devicePath, lsblkFsType)
if err != nil {
return err
}
// Unfortunately, lsblk(8) doesn't provide a way to tell apart a
// nonexistent filesystem (e.g. a fresh drive) from device read problem
// - in both cases not reporting any errors and returning an empty
// FSTYPE field. Therefore, care must be taken to compensate for this
// behaviour. The strategy below is deemed safe, because:
//
// - If lsblk(8) lacks privileges to read the filesystem and the
// decision is put forward to format it, mkfs(8) will fail as well.
// - If lsblk(8) had privileges and still didn't detect the filesystem,
// it's OK to format it.
if foundFsType == "" {
// Need to format.
log.Printf("Formatting device %s with filesystem %s...", devicePath, configuredFsType)
output, err := env.OsCommandRunner.Run(append(filesystemFormatter, devicePath)...)
if err != nil {
return fmt.Errorf("Failed to format filesystem: %s", err)
} else {
log.Printf("%s\n", output)
}
} else if foundFsType == configuredFsType {
// Need to fsck.
log.Printf("Running filesystem checker on device %s...", devicePath)
output, err := env.OsCommandRunner.Run(append(filesystemChecker, devicePath)...)
if err != nil {
return fmt.Errorf("Filesystem check failed: %s", err)
} else {
log.Printf("%s\n", output)
}
} else {
return fmt.Errorf("Device %s: found filesystem type %s, expected %s.", devicePath, foundFsType, configuredFsType)
}
return nil
}