diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f8af91fb7..071cca2620 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ Changelog for NeoFS Node attribute, which is used for container domain name in NNS contracts (#2954) - Save last epoch when metabase was resynchronized (#2966) - `neofs-lens meta last-resync-epoch` command (#2966) +- `neofs-lens fstree cleanup-tmp` command (#2967) ### Fixed - Do not search for tombstones when handling their expiration, use local indexes instead (#2929) @@ -24,7 +25,6 @@ attribute, which is used for container domain name in NNS contracts (#2954) - When an error is returned, no additional help output is displayed in cobra-based programs (#2942) - Use org-wide linter (#2943) - Timestamps are no longer produced in logs if not running with TTY (#2964) -- Default dial timeout to one minute (#2963) ### Removed - Support for node.key configuration (#2959) @@ -43,15 +43,6 @@ introduced in version 0.22.3 and support for binary keys was removed from other components in 0.33.0 and 0.37.0. Please migrate to wallets (see 0.37.0 notes) if you've not done it previously. -Increase default timeout for dialing connections in node: `morph.dial_timeout`, -`apiclient.dial_timout`, `apiclient.stream_timeout` and in inner ring: -`morph.dial_timout`, `morph.consensus.p2p.dial_timout`, `mainnet.dial_timout` -to 1 minute. Can be adjusted for fast networks. - -Using public keys as a rule target in eACL tables was deprecated and will not -be supported in the next releases, use addresses instead. For more information -call `neofs-cli acl extended create -h`. - ## [0.43.0] - 2024-08-20 - Jukdo ### Added diff --git a/cmd/neofs-lens/internal/fstree/cleanup.go b/cmd/neofs-lens/internal/fstree/cleanup.go new file mode 100644 index 0000000000..4a980a5216 --- /dev/null +++ b/cmd/neofs-lens/internal/fstree/cleanup.go @@ -0,0 +1,30 @@ +package fstree + +import ( + common "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal" + "github.com/spf13/cobra" +) + +var cleanupCMD = &cobra.Command{ + Use: "cleanup-tmp", + Short: "Clean up tmp files in FSTree", + Long: "Clean up temporary unused files in FSTree (forcibly interrupted data writes can leave them)", + Args: cobra.NoArgs, + RunE: cleanupFunc, +} + +func init() { + common.AddComponentPathFlag(cleanupCMD, &vPath) +} + +func cleanupFunc(cmd *cobra.Command, _ []string) error { + fst, err := openFSTree() + if err != nil { + return err + } + defer fst.Close() + + cmd.Println("Cleaning up tmp files in FSTree") + + return fst.CleanUpTmp() +} diff --git a/cmd/neofs-lens/internal/fstree/root.go b/cmd/neofs-lens/internal/fstree/root.go new file mode 100644 index 0000000000..1d3b3d9419 --- /dev/null +++ b/cmd/neofs-lens/internal/fstree/root.go @@ -0,0 +1,47 @@ +package fstree + +import ( + "fmt" + + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/compression" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" + "github.com/spf13/cobra" +) + +var ( + vPath string +) + +// Root defines root command for operations with FSTree. +var Root = &cobra.Command{ + Use: "fstree", + Short: "Operations with FSTree storage subsystem", +} + +func init() { + Root.AddCommand(cleanupCMD) +} + +// openFSTree opens and returns fstree.FSTree located in vPath. +func openFSTree() (*fstree.FSTree, error) { + fst := fstree.New( + fstree.WithPath(vPath), + fstree.WithPerm(0600), + ) + + var compressCfg compression.Config + + err := compressCfg.Init() + if err != nil { + return nil, fmt.Errorf("failed to init compression config: %w", err) + } + + fst.SetCompressor(&compressCfg) + + err = fst.Open(false) + if err != nil { + return nil, fmt.Errorf("failed to open FSTree: %w", err) + } + + return fst, nil +} diff --git a/cmd/neofs-lens/root.go b/cmd/neofs-lens/root.go index dc0096b2ce..3a99fb2fc1 100644 --- a/cmd/neofs-lens/root.go +++ b/cmd/neofs-lens/root.go @@ -4,6 +4,7 @@ import ( "os" "github.com/nspcc-dev/neofs-node/cmd/internal/cmderr" + "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/fstree" "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/meta" "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/object" "github.com/nspcc-dev/neofs-node/cmd/neofs-lens/internal/peapod" @@ -44,6 +45,7 @@ func init() { writecache.Root, storage.Root, object.Root, + fstree.Root, gendoc.Command(command), ) } diff --git a/pkg/local_object_storage/blobstor/fstree/fstree.go b/pkg/local_object_storage/blobstor/fstree/fstree.go index 1593af9511..5f39437397 100644 --- a/pkg/local_object_storage/blobstor/fstree/fstree.go +++ b/pkg/local_object_storage/blobstor/fstree/fstree.go @@ -477,3 +477,31 @@ func (t *FSTree) SetCompressor(cc *compression.Config) { func (t *FSTree) SetReportErrorFunc(_ func(string, error)) { // Do nothing, FSTree can encounter only one error which is returned. } + +// CleanUpTmp removes all temporary files garbage. +func (t *FSTree) CleanUpTmp() error { + if t.readOnly { + return common.ErrReadOnly + } + + err := filepath.WalkDir(t.RootPath, + func(path string, d fs.DirEntry, err error) error { + if err != nil { + return err + } + if !d.IsDir() && strings.Contains(d.Name(), "#") { + err = os.RemoveAll(path) + if err != nil { + return err + } + } + + return nil + }, + ) + if err != nil { + return fmt.Errorf("could not walk through %q directory: %w", t.RootPath, err) + } + + return nil +}