From 4a1655b22550a215b850b7e1c555919056378d85 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 1 Aug 2021 18:59:43 +0300 Subject: [PATCH 1/4] add lotus-shed splitstore clear command --- cmd/lotus-shed/splitstore.go | 85 ++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index c2363c65583..5e9cebfc209 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -11,6 +11,7 @@ import ( "github.com/dgraph-io/badger/v2" "github.com/urfave/cli/v2" + "go.uber.org/multierr" "golang.org/x/sync/errgroup" "golang.org/x/xerrors" @@ -29,6 +30,7 @@ var splitstoreCmd = &cli.Command{ Description: "splitstore utilities", Subcommands: []*cli.Command{ splitstoreRollbackCmd, + splitstoreClearCmd, splitstoreCheckCmd, splitstoreInfoCmd, }, @@ -118,6 +120,65 @@ var splitstoreRollbackCmd = &cli.Command{ }, } +var splitstoreClearCmd = &cli.Command{ + Name: "clear", + Description: "clears a splitstore installation for restart from snapshot", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Action: func(cctx *cli.Context) error { + r, err := repo.NewFS(cctx.String("repo")) + if err != nil { + return xerrors.Errorf("error opening fs repo: %w", err) + } + + exists, err := r.Exists() + if err != nil { + return err + } + if !exists { + return xerrors.Errorf("lotus repo doesn't exist") + } + + lr, err := r.Lock(repo.FullNode) + if err != nil { + return xerrors.Errorf("error locking repo: %w", err) + } + defer lr.Close() //nolint:errcheck + + cfg, err := lr.Config() + if err != nil { + return xerrors.Errorf("error getting config: %w", err) + } + + fncfg, ok := cfg.(*config.FullNode) + if !ok { + return xerrors.Errorf("wrong config type: %T", cfg) + } + + if !fncfg.Chainstore.EnableSplitstore { + return xerrors.Errorf("splitstore is not enabled") + } + + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } + + fmt.Println("deleting splitstore keys from metadata datastore...") + err = deleteSplitstoreKeys(lr) + if err != nil { + return xerrors.Errorf("error deleting splitstore keys: %w", err) + } + + return nil + }, +} + func copyHotstoreToColdstore(lr repo.LockedRepo, gcColdstore bool) error { repoPath := lr.Path() dataPath := filepath.Join(repoPath, "datastore") @@ -224,6 +285,30 @@ func deleteSplitstoreDir(lr repo.LockedRepo) error { return os.RemoveAll(path) } +func clearSplitstoreDir(lr repo.LockedRepo) error { + path, err := lr.SplitstorePath() + if err != nil { + return xerrors.Errorf("error getting splitstore path: %w", err) + } + + entries, err := os.ReadDir(path) + if err != nil { + return xerrors.Errorf("error reading splitstore directory %s: %W", path, err) + } + + var result error + for _, e := range entries { + target := filepath.Join(path, e.Name()) + err = os.RemoveAll(target) + if err != nil { + log.Errorf("error removing %s: %s", target, err) + result = multierr.Append(result, err) + } + } + + return result +} + func deleteSplitstoreKeys(lr repo.LockedRepo) error { ds, err := lr.Datastore(context.TODO(), "/metadata") if err != nil { From a768dd84faf547557a1e694556da3c76c7ecaf68 Mon Sep 17 00:00:00 2001 From: vyzo Date: Sun, 1 Aug 2021 19:01:09 +0300 Subject: [PATCH 2/4] document splitstore clear shed command --- blockstore/splitstore/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/blockstore/splitstore/README.md b/blockstore/splitstore/README.md index 4efd6f61d1d..f69a056ca43 100644 --- a/blockstore/splitstore/README.md +++ b/blockstore/splitstore/README.md @@ -119,6 +119,7 @@ TBD -- see [#6577](https://github.com/filecoin-project/lotus/issues/6577) It can also optionally compact/gc the coldstore after the copy (with the `--gc-coldstore` flag) and automatically rewrite the lotus config to disable splitstore (with the `--rewrite-config` flag). Note: the node *must be stopped* before running this command. +- `clear` -- clears a splitstore installation for restart from snapshot. - `check` -- asynchronously runs a basic healthcheck on the splitstore. The results are appended to `/datastore/splitstore/check.txt`. - `info` -- prints some basic information about the splitstore. From db6b7b91d8843ce92946d25fe531f527e6a763a6 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 3 Aug 2021 15:32:53 +0300 Subject: [PATCH 3/4] add option to only clear splistore keys --- cmd/lotus-shed/splitstore.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 5e9cebfc209..49d703184c6 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -128,6 +128,10 @@ var splitstoreClearCmd = &cli.Command{ Name: "repo", Value: "~/.lotus", }, + &cli.BoolFlag{ + Name: "keys-only", + Usage: "only delete splitstore keys", + }, }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) @@ -163,10 +167,12 @@ var splitstoreClearCmd = &cli.Command{ return xerrors.Errorf("splitstore is not enabled") } - fmt.Println("clearing splitstore directory...") - err = clearSplitstoreDir(lr) - if err != nil { - return xerrors.Errorf("error clearing splitstore directory: %w", err) + if !cctx.Bool("keys-only") { + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } } fmt.Println("deleting splitstore keys from metadata datastore...") From c9124bd1a94db7f68a1a9db867aa4f2a40eb0d63 Mon Sep 17 00:00:00 2001 From: vyzo Date: Tue, 3 Aug 2021 15:39:48 +0300 Subject: [PATCH 4/4] clear splitstore dir before deleting, only warn if the latter fails to address situations with symlinks --- cmd/lotus-shed/splitstore.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index 49d703184c6..4f668888eaf 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -93,10 +93,16 @@ var splitstoreRollbackCmd = &cli.Command{ return xerrors.Errorf("error copying hotstore to coldstore: %w", err) } + fmt.Println("clearing splitstore directory...") + err = clearSplitstoreDir(lr) + if err != nil { + return xerrors.Errorf("error clearing splitstore directory: %w", err) + } + fmt.Println("deleting splitstore directory...") err = deleteSplitstoreDir(lr) if err != nil { - return xerrors.Errorf("error deleting splitstore directory: %w", err) + log.Warnf("error deleting splitstore directory: %s", err) } fmt.Println("deleting splitstore keys from metadata datastore...")