Fix writing 'format.json' and make it atomic (#8296)

- Choose a unique uuid such that under situations of duplicate
  mounts we do not append to an existing json entry.
- Avoid AppendFile instead use WriteAll() to write the entire
  byte array atomically.
master
Harshavardhana 5 years ago committed by GitHub
parent be70ef59e7
commit c8fbc94329
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      cmd/format-meta.go
  2. 21
      cmd/format-xl.go
  3. 2
      cmd/xl-sets.go

@ -20,9 +20,6 @@ package cmd
const ( const (
// Format config file carries backend format specific details. // Format config file carries backend format specific details.
formatConfigFile = "format.json" formatConfigFile = "format.json"
// Format config tmp file carries backend format.
formatConfigFileTmp = "format.json.tmp"
) )
const ( const (

@ -17,6 +17,7 @@
package cmd package cmd
import ( import (
"bytes"
"context" "context"
"encoding/json" "encoding/json"
"fmt" "fmt"
@ -291,16 +292,6 @@ func formatXLMigrateV2ToV3(export string) error {
return ioutil.WriteFile(formatPath, b, 0644) return ioutil.WriteFile(formatPath, b, 0644)
} }
// Returns true, if one of the errors is non-nil and is Unformatted disk.
func hasAnyErrorsUnformatted(errs []error) bool {
for _, err := range errs {
if err != nil && err == errUnformattedDisk {
return true
}
}
return false
}
// countErrs - count a specific error. // countErrs - count a specific error.
func countErrs(errs []error, err error) int { func countErrs(errs []error, err error) int {
var i = 0 var i = 0
@ -367,16 +358,18 @@ func saveFormatXL(disk StorageAPI, format interface{}) error {
return err return err
} }
tmpFormatJSON := mustGetUUID() + ".json"
// Purge any existing temporary file, okay to ignore errors here. // Purge any existing temporary file, okay to ignore errors here.
defer disk.DeleteFile(minioMetaBucket, formatConfigFileTmp) defer disk.DeleteFile(minioMetaBucket, tmpFormatJSON)
// Append file `format.json.tmp`. // Append file `format.json.tmp`.
if err = disk.AppendFile(minioMetaBucket, formatConfigFileTmp, formatBytes); err != nil { if err = disk.WriteAll(minioMetaBucket, tmpFormatJSON, bytes.NewReader(formatBytes)); err != nil {
return err return err
} }
// Rename file `format.json.tmp` --> `format.json`. // Rename file `uuid.json` --> `format.json`.
return disk.RenameFile(minioMetaBucket, formatConfigFileTmp, minioMetaBucket, formatConfigFile) return disk.RenameFile(minioMetaBucket, tmpFormatJSON, minioMetaBucket, formatConfigFile)
} }
var ignoredHiddenDirectories = []string{ var ignoredHiddenDirectories = []string{

@ -1492,7 +1492,7 @@ func (s *xlSets) HealFormat(ctx context.Context, dryRun bool) (res madmin.HealRe
} }
} }
if !hasAnyErrorsUnformatted(sErrs) { if countErrs(sErrs, errUnformattedDisk) == 0 {
// No unformatted disks found disks are either offline // No unformatted disks found disks are either offline
// or online, no healing is required. // or online, no healing is required.
return res, errNoHealRequired return res, errNoHealRequired

Loading…
Cancel
Save