aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/geth
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2019-05-16 19:30:11 +0800
committerPéter Szilágyi <peterke@gmail.com>2019-05-16 22:01:56 +0800
commit9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f (patch)
treef788ecf46bb04e54adedd3dde919c60c03d80a21 /cmd/geth
parent536b3b416c6ff53ea11a0d29dcc351a6d7919901 (diff)
downloadgo-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar.gz
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar.bz2
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar.lz
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar.xz
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.tar.zst
go-tangerine-9eba3a9fff2f47f5e094c36a7c905380b0ac8b1f.zip
cmd/geth, core/rawdb: seamless freezer consistency, friendly removedb
Diffstat (limited to 'cmd/geth')
-rw-r--r--cmd/geth/chaincmd.go232
-rw-r--r--cmd/geth/main.go1
-rw-r--r--cmd/geth/os_unix.go51
-rw-r--r--cmd/geth/os_windows.go43
4 files changed, 52 insertions, 275 deletions
diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go
index 70164f82b..c91545c7f 100644
--- a/cmd/geth/chaincmd.go
+++ b/cmd/geth/chaincmd.go
@@ -18,10 +18,7 @@ package main
import (
"encoding/json"
- "errors"
"fmt"
- "io"
- "io/ioutil"
"os"
"path/filepath"
"runtime"
@@ -171,21 +168,6 @@ Remove blockchain and state databases`,
The arguments are interpreted as block numbers or hashes.
Use "ethereum dump 0" to dump the genesis block.`,
}
- migrateAncientCommand = cli.Command{
- Action: utils.MigrateFlags(migrateAncient),
- Name: "migrate-ancient",
- Usage: "migrate ancient database forcibly",
- ArgsUsage: " ",
- Flags: []cli.Flag{
- utils.DataDirFlag,
- utils.AncientFlag,
- utils.CacheFlag,
- utils.TestnetFlag,
- utils.RinkebyFlag,
- utils.GoerliFlag,
- },
- Category: "BLOCKCHAIN COMMANDS",
- }
inspectCommand = cli.Command{
Action: utils.MigrateFlags(inspect),
Name: "inspect",
@@ -460,49 +442,61 @@ func copyDb(ctx *cli.Context) error {
func removeDB(ctx *cli.Context) error {
stack, config := makeConfigNode(ctx)
- for i, name := range []string{"chaindata", "lightchaindata"} {
- // Ensure the database exists in the first place
- logger := log.New("database", name)
-
- var (
- dbdirs []string
- freezer string
- )
- dbdir := stack.ResolvePath(name)
- if !common.FileExist(dbdir) {
- logger.Info("Database doesn't exist, skipping", "path", dbdir)
- continue
- }
- dbdirs = append(dbdirs, dbdir)
- if i == 0 {
- freezer = config.Eth.DatabaseFreezer
- switch {
- case freezer == "":
- freezer = filepath.Join(dbdir, "ancient")
- case !filepath.IsAbs(freezer):
- freezer = config.Node.ResolvePath(freezer)
- }
- if common.FileExist(freezer) {
- dbdirs = append(dbdirs, freezer)
+ // Remove the full node state database
+ path := stack.ResolvePath("chaindata")
+ if common.FileExist(path) {
+ confirmAndRemoveDB(path, "full node state database")
+ } else {
+ log.Info("Full node state database missing", "path", path)
+ }
+ // Remove the full node ancient database
+ path = config.Eth.DatabaseFreezer
+ switch {
+ case path == "":
+ path = filepath.Join(stack.ResolvePath("chaindata"), "ancient")
+ case !filepath.IsAbs(path):
+ path = config.Node.ResolvePath(path)
+ }
+ if common.FileExist(path) {
+ confirmAndRemoveDB(path, "full node ancient database")
+ } else {
+ log.Info("Full node ancient database missing", "path", path)
+ }
+ // Remove the light node database
+ path = stack.ResolvePath("lightchaindata")
+ if common.FileExist(path) {
+ confirmAndRemoveDB(path, "light node database")
+ } else {
+ log.Info("Light node database missing", "path", path)
+ }
+ return nil
+}
+
+// confirmAndRemoveDB prompts the user for a last confirmation and removes the
+// folder if accepted.
+func confirmAndRemoveDB(database string, kind string) {
+ confirm, err := console.Stdin.PromptConfirm(fmt.Sprintf("Remove %s (%s)?", kind, database))
+ switch {
+ case err != nil:
+ utils.Fatalf("%v", err)
+ case !confirm:
+ log.Info("Database deletion skipped", "path", database)
+ default:
+ start := time.Now()
+ filepath.Walk(database, func(path string, info os.FileInfo, err error) error {
+ // If we're at the top level folder, recurse into
+ if path == database {
+ return nil
}
- }
- for i := len(dbdirs) - 1; i >= 0; i-- {
- // Confirm removal and execute
- fmt.Println(dbdirs[i])
- confirm, err := console.Stdin.PromptConfirm("Remove this database?")
- switch {
- case err != nil:
- utils.Fatalf("%v", err)
- case !confirm:
- logger.Warn("Database deletion aborted")
- default:
- start := time.Now()
- os.RemoveAll(dbdirs[i])
- logger.Info("Database successfully deleted", "elapsed", common.PrettyDuration(time.Since(start)))
+ // Delete all the files, but not subfolders
+ if !info.IsDir() {
+ os.Remove(path)
+ return nil
}
- }
+ return filepath.SkipDir
+ })
+ log.Info("Database successfully deleted", "path", database, "elapsed", common.PrettyDuration(time.Since(start)))
}
- return nil
}
func dump(ctx *cli.Context) error {
@@ -533,47 +527,6 @@ func dump(ctx *cli.Context) error {
return nil
}
-func migrateAncient(ctx *cli.Context) error {
- node, config := makeConfigNode(ctx)
- defer node.Close()
-
- dbdir := config.Node.ResolvePath("chaindata")
- kvdb, err := rawdb.NewLevelDBDatabase(dbdir, 128, 1024, "")
- if err != nil {
- return err
- }
- defer kvdb.Close()
-
- freezer := config.Eth.DatabaseFreezer
- switch {
- case freezer == "":
- freezer = filepath.Join(dbdir, "ancient")
- case !filepath.IsAbs(freezer):
- freezer = config.Node.ResolvePath(freezer)
- }
- stored := rawdb.ReadAncientPath(kvdb)
- if stored != freezer && stored != "" {
- confirm, err := console.Stdin.PromptConfirm(fmt.Sprintf("Are you sure to migrate ancient database from %s to %s?", stored, freezer))
- switch {
- case err != nil:
- utils.Fatalf("%v", err)
- case !confirm:
- log.Warn("Ancient database migration aborted")
- default:
- if err := rename(stored, freezer); err != nil {
- // Renaming a file can fail if the source and destination
- // are on different file systems.
- if err := moveAncient(stored, freezer); err != nil {
- utils.Fatalf("Migrate ancient database failed, %v", err)
- }
- }
- rawdb.WriteAncientPath(kvdb, freezer)
- log.Info("Ancient database successfully migrated")
- }
- }
- return nil
-}
-
func inspect(ctx *cli.Context) error {
node, _ := makeConfigNode(ctx)
defer node.Close()
@@ -589,84 +542,3 @@ func hashish(x string) bool {
_, err := strconv.Atoi(x)
return err != nil
}
-
-// copyFileSynced copies data from source file to destination
-// and synces the dest file forcibly.
-func copyFileSynced(src string, dest string, info os.FileInfo) error {
- srcf, err := os.Open(src)
- if err != nil {
- return err
- }
- defer srcf.Close()
-
- destf, err := os.OpenFile(dest, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, info.Mode().Perm())
- if err != nil {
- return err
- }
- // The maximum size of ancient file is 2GB, 4MB buffer is suitable here.
- buff := make([]byte, 4*1024*1024)
- for {
- rn, err := srcf.Read(buff)
- if err != nil && err != io.EOF {
- return err
- }
- if rn == 0 {
- break
- }
- if wn, err := destf.Write(buff[:rn]); err != nil || wn != rn {
- return err
- }
- }
- if err1 := destf.Sync(); err == nil {
- err = err1
- }
- if err1 := destf.Close(); err == nil {
- err = err1
- }
- return err
-}
-
-// copyDirSynced recursively copies files under the specified dir
-// to dest and synces the dest dir forcibly.
-func copyDirSynced(src string, dest string, info os.FileInfo) error {
- if err := os.MkdirAll(dest, os.ModePerm); err != nil {
- return err
- }
- defer os.Chmod(dest, info.Mode())
-
- objects, err := ioutil.ReadDir(src)
- if err != nil {
- return err
- }
- for _, obj := range objects {
- // All files in ancient database should be flatten files.
- if !obj.Mode().IsRegular() {
- continue
- }
- subsrc, subdest := filepath.Join(src, obj.Name()), filepath.Join(dest, obj.Name())
- if err := copyFileSynced(subsrc, subdest, obj); err != nil {
- return err
- }
- }
- return syncDir(dest)
-}
-
-// moveAncient migrates ancient database from source to destination.
-func moveAncient(src string, dest string) error {
- srcinfo, err := os.Stat(src)
- if err != nil {
- return err
- }
- if !srcinfo.IsDir() {
- return errors.New("ancient directory expected")
- }
- if destinfo, err := os.Lstat(dest); !os.IsNotExist(err) {
- if destinfo.Mode()&os.ModeSymlink != 0 {
- return errors.New("symbolic link datadir is not supported")
- }
- }
- if err := copyDirSynced(src, dest, srcinfo); err != nil {
- return err
- }
- return os.RemoveAll(src)
-}
diff --git a/cmd/geth/main.go b/cmd/geth/main.go
index afa39bf93..1b23cbd9f 100644
--- a/cmd/geth/main.go
+++ b/cmd/geth/main.go
@@ -204,7 +204,6 @@ func init() {
copydbCommand,
removedbCommand,
dumpCommand,
- migrateAncientCommand,
inspectCommand,
// See accountcmd.go:
accountCommand,
diff --git a/cmd/geth/os_unix.go b/cmd/geth/os_unix.go
deleted file mode 100644
index 6722ec9cb..000000000
--- a/cmd/geth/os_unix.go
+++ /dev/null
@@ -1,51 +0,0 @@
-// Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license.
-//
-// +build darwin dragonfly freebsd linux netbsd openbsd solaris
-
-package main
-
-import (
- "os"
- "syscall"
-)
-
-func rename(oldpath, newpath string) error {
- return os.Rename(oldpath, newpath)
-}
-
-func isErrInvalid(err error) bool {
- if err == os.ErrInvalid {
- return true
- }
- // Go < 1.8
- if syserr, ok := err.(*os.SyscallError); ok && syserr.Err == syscall.EINVAL {
- return true
- }
- // Go >= 1.8 returns *os.PathError instead
- if patherr, ok := err.(*os.PathError); ok && patherr.Err == syscall.EINVAL {
- return true
- }
- return false
-}
-
-func syncDir(name string) error {
- // As per fsync manpage, Linux seems to expect fsync on directory, however
- // some system don't support this, so we will ignore syscall.EINVAL.
- //
- // From fsync(2):
- // Calling fsync() does not necessarily ensure that the entry in the
- // directory containing the file has also reached disk. For that an
- // explicit fsync() on a file descriptor for the directory is also needed.
- f, err := os.Open(name)
- if err != nil {
- return err
- }
- defer f.Close()
- if err := f.Sync(); err != nil && !isErrInvalid(err) {
- return err
- }
- return nil
-}
diff --git a/cmd/geth/os_windows.go b/cmd/geth/os_windows.go
deleted file mode 100644
index f2406ec9b..000000000
--- a/cmd/geth/os_windows.go
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright (c) 2013, Suryandaru Triandana <syndtr@gmail.com>
-// All rights reserved.
-//
-// Use of this source code is governed by a BSD-style license.
-
-package main
-
-import (
- "syscall"
- "unsafe"
-)
-
-var (
- modkernel32 = syscall.NewLazyDLL("kernel32.dll")
- procMoveFileExW = modkernel32.NewProc("MoveFileExW")
-)
-
-const _MOVEFILE_REPLACE_EXISTING = 1
-
-func moveFileEx(from *uint16, to *uint16, flags uint32) error {
- r1, _, e1 := syscall.Syscall(procMoveFileExW.Addr(), 3, uintptr(unsafe.Pointer(from)), uintptr(unsafe.Pointer(to)), uintptr(flags))
- if r1 == 0 {
- if e1 != 0 {
- return error(e1)
- }
- return syscall.EINVAL
- }
- return nil
-}
-
-func rename(oldpath, newpath string) error {
- from, err := syscall.UTF16PtrFromString(oldpath)
- if err != nil {
- return err
- }
- to, err := syscall.UTF16PtrFromString(newpath)
- if err != nil {
- return err
- }
- return moveFileEx(from, to, _MOVEFILE_REPLACE_EXISTING)
-}
-
-func syncDir(name string) error { return nil }