Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 77 additions & 12 deletions opencloud/pkg/command/posixfs.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import (

"github.com/opencloud-eu/opencloud/opencloud/pkg/register"
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
"github.com/rs/zerolog"

"github.com/pkg/xattr"
"github.com/spf13/cobra"
Expand All @@ -28,6 +31,7 @@ const (
var (
spinner *yacspin.Spinner
restartRequired = false
ignorer *ignore.Ignorer
)

// EntryInfo holds information about a directory entry.
Expand Down Expand Up @@ -74,6 +78,12 @@ func checkPosixfsConsistency(cmd *cobra.Command, cfg *config.Config) error {
rootPath, _ := cmd.Flags().GetString("root")
indexesPath := filepath.Join(rootPath, "indexes")

opt, _ := options.New(map[string]interface{}{
"root": rootPath,
})
log := zerolog.Nop()
ignorer = ignore.NewIgnorer(opt, &log)

_, err := os.Stat(indexesPath)
if err != nil {
if os.IsNotExist(err) {
Expand Down Expand Up @@ -130,6 +140,7 @@ func checkSpaces(basePath string) {
}

func checkSpace(spacePath string) {
spinner.Message("")
spinner.Suffix(fmt.Sprintf(" Checking space '%s'", spacePath))

info, err := os.Stat(spacePath)
Expand All @@ -149,10 +160,11 @@ func checkSpace(spacePath string) {
}

checkSpaceID(spacePath)
checkNodeIDs(spacePath)
}

func checkSpaceID(spacePath string) {
spinner.Message("checking space ID uniqueness")
spinner.Message(" - checking space ID uniqueness")

entries, uniqueIDs, oldestEntry, err := gatherAttributes(spacePath)
if err != nil {
Expand All @@ -161,7 +173,6 @@ func checkSpaceID(spacePath string) {
}

if len(entries) == 0 {
logSuccess("(empty space)")
return
}

Expand Down Expand Up @@ -199,8 +210,65 @@ func checkSpaceID(spacePath string) {
}
fixSpaceID(spacePath, obsoleteIDs, targetID, entries)
spinner.Unpause()
} else {
logSuccess("")
}
}

func walkParentIDs(dir string, parentID string) int {
fixes := 0
entries, err := os.ReadDir(dir)
if err != nil {
logFailure("Error reading directory '%s': %v", dir, err)
return 0
}

for _, entry := range entries {
fullPath := filepath.Join(dir, entry.Name())

if ignorer.IsIgnored(fullPath) {
continue
}

actualParentID, err := xattr.Get(fullPath, parentIDAttrName)
if err != nil || string(actualParentID) != parentID {
err = xattr.Set(fullPath, parentIDAttrName, []byte(parentID))
if err != nil {
logFailure("Failed to fix parent ID for '%s': %v", fullPath, err)
} else {
spinner.Pause()
fmt.Printf("\n + Fixed parent ID for '%s'\n", fullPath)
spinner.Unpause()
fixes++
restartRequired = true
}
}

if entry.IsDir() {
nodeID, err := xattr.Get(fullPath, idAttrName)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s', skipping its children", fullPath, idAttrName)
continue
}
walkParentIDs(fullPath, string(nodeID))
}
}
return fixes
}

func checkNodeIDs(spacePath string) {
spinner.Message(" - checking parent IDs")

rootID, err := xattr.Get(spacePath, idAttrName)
if err != nil || len(rootID) == 0 {
logFailure("Space root '%s' missing '%s' attribute", spacePath, idAttrName)
return
}

fixes := walkParentIDs(spacePath, string(rootID))

if fixes > 0 {
spinner.Pause()
fmt.Printf("\n ✓ Fixed %d incorrect parent IDs in %s\n", fixes, filepath.Base(spacePath))
spinner.Unpause()
}
}

Expand Down Expand Up @@ -245,6 +313,9 @@ func gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo,

for _, entry := range dirEntries {
fullPath := filepath.Join(path, entry.Name())
if ignorer.IsIgnored(fullPath) {
continue
}
info, err := os.Stat(fullPath)
if err != nil {
fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err)
Expand Down Expand Up @@ -349,7 +420,7 @@ func updateOwnerIndexFile(basePath string, obsoleteIDs []string) error {
return fmt.Errorf("failed to write updated index file: %w", err)
}

logSuccess("Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
fmt.Printf(" ✓ Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
return nil
}

Expand All @@ -368,13 +439,7 @@ func removeAttributes(path string) error {
}

func logFailure(message string, args ...any) {
spinner.StopFailMessage(fmt.Sprintf(message, args...))
spinner.StopFailMessage(fmt.Sprintf("\n"+message, args...))
spinner.StopFail()
spinner.Start()
}

func logSuccess(message string, args ...any) {
spinner.StopMessage(fmt.Sprintf(message, args...))
spinner.Stop()
spinner.Start()
}