1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
| func makeDB(snapdir, dbfile string, commit int) { f, ferr := os.OpenFile(dbfile, os.O_RDONLY, 0600) if ferr != nil { ExitWithError(ExitInvalidInput, ferr) } defer f.Close() if _, err := f.Seek(-sha256.Size, os.SEEK_END); err != nil { ExitWithError(ExitIO, err) } sha := make([]byte, sha256.Size) if _, err := f.Read(sha); err != nil { ExitWithError(ExitIO, err) } if _, err := f.Seek(0, os.SEEK_SET); err != nil { ExitWithError(ExitIO, err) } if err := fileutil.CreateDirAll(snapdir); err != nil { ExitWithError(ExitIO, err) } dbpath := filepath.Join(snapdir, "db") db, dberr := os.OpenFile(dbpath, os.O_RDWR|os.O_CREATE, 0600) if dberr != nil { ExitWithError(ExitIO, dberr) } if _, err := io.Copy(db, f); err != nil { ExitWithError(ExitIO, err) } off, serr := db.Seek(0, os.SEEK_END) if serr != nil { ExitWithError(ExitIO, serr) } hasHash := (off % 512) == sha256.Size if hasHash { if err := db.Truncate(off - sha256.Size); err != nil { ExitWithError(ExitIO, err) } } if !hasHash && !skipHashCheck { err := fmt.Errorf("snapshot missing hash but --skip-hash-check=false") ExitWithError(ExitBadArgs, err) } if hasHash && !skipHashCheck { if _, err := db.Seek(0, os.SEEK_SET); err != nil { ExitWithError(ExitIO, err) } h := sha256.New() if _, err := io.Copy(h, db); err != nil { ExitWithError(ExitIO, err) } dbsha := h.Sum(nil) if !reflect.DeepEqual(sha, dbsha) { err := fmt.Errorf("expected sha256 %v, got %v", sha, dbsha) ExitWithError(ExitInvalidInput, err) } } db.Close() be := backend.NewDefaultBackend(dbpath) lessor := lease.NewLessor(be, math.MaxInt64) s := mvcc.NewStore(be, lessor, (*initIndex)(&commit)) id := s.TxnBegin() btx := be.BatchTx() del := func(k, v []byte) error { _, _, err := s.TxnDeleteRange(id, k, nil) return err } btx.UnsafeForEach([]byte("members"), del) btx.UnsafeForEach([]byte("members_removed"), del) s.TxnEnd(id) s.Commit() s.Close() }
|