func packIDTester(repo *repository.Repository, inChan <-chan backend.ID, errChan chan<- error, wg *sync.WaitGroup, done <-chan struct{}) { debug.Log("Checker.testPackID", "worker start") defer debug.Log("Checker.testPackID", "worker done") defer wg.Done() for id := range inChan { ok, err := repo.Backend().Test(backend.Data, id.String()) if err != nil { err = PackError{ID: id, Err: err} } else { if !ok { err = PackError{ID: id, Err: errors.New("does not exist")} } } if err != nil { debug.Log("Checker.testPackID", "error checking for pack %s: %v", id.Str(), err) select { case <-done: return case errChan <- err: } continue } debug.Log("Checker.testPackID", "pack %s exists", id.Str()) } }
// FindSnapshot takes a string and tries to find a snapshot whose ID matches // the string as closely as possible. func FindSnapshot(repo *repository.Repository, s string) (backend.ID, error) { // find snapshot id with prefix name, err := backend.Find(repo.Backend(), backend.Snapshot, s) if err != nil { return nil, err } return backend.ParseID(name) }
func TeardownRepo(t testing.TB, repo *repository.Repository) { if !TestCleanup { l := repo.Backend().(*local.Local) t.Logf("leaving local backend at %s\n", l.Location()) return } OK(t, repo.Delete()) }
func TeardownRepo(repo *repository.Repository) { if !TestCleanup { l := repo.Backend().(*local.Local) fmt.Printf("leaving local backend at %s\n", l.Location()) return } err := repo.Delete() if err != nil { panic(err) } }
func (cmd CmdKey) deleteKey(repo *repository.Repository, name string) error { if name == repo.KeyName() { return errors.New("refusing to remove key currently used to access repository") } err := repo.Backend().Remove(backend.Key, name) if err != nil { return err } cmd.global.Verbosef("removed key %v\n", name) return nil }
// RemoveStaleLocks deletes all locks detected as stale from the repository. func RemoveStaleLocks(repo *repository.Repository) error { return eachLock(repo, func(id backend.ID, lock *Lock, err error) error { // ignore locks that cannot be loaded if err != nil { return nil } if lock.Stale() { return repo.Backend().Remove(backend.Lock, id.String()) } return nil }) }
func (cmd CmdKey) changePassword(repo *repository.Repository) error { id, err := repository.AddKey(repo, cmd.getNewPassword(), repo.Key()) if err != nil { return fmt.Errorf("creating new key failed: %v\n", err) } err = repo.Backend().Remove(backend.Key, repo.KeyName()) if err != nil { return err } cmd.global.Verbosef("saved new key as %s\n", id) return nil }
// checkPack reads a pack and checks the integrity of all blobs. func checkPack(r *repository.Repository, id backend.ID) error { debug.Log("Checker.checkPack", "checking pack %v", id.Str()) rd, err := r.Backend().Get(backend.Data, id.String()) if err != nil { return err } buf, err := ioutil.ReadAll(rd) if err != nil { return err } err = rd.Close() if err != nil { return err } unpacker, err := pack.NewUnpacker(r.Key(), bytes.NewReader(buf)) if err != nil { return err } var errs []error for i, blob := range unpacker.Entries { debug.Log("Checker.checkPack", " check blob %d: %v", i, blob.ID.Str()) plainBuf := make([]byte, blob.Length) plainBuf, err = crypto.Decrypt(r.Key(), plainBuf, buf[blob.Offset:blob.Offset+blob.Length]) if err != nil { debug.Log("Checker.checkPack", " error decrypting blob %v: %v", blob.ID.Str(), err) errs = append(errs, fmt.Errorf("blob %v: %v", i, err)) continue } hash := backend.Hash(plainBuf) if !hash.Equal(blob.ID) { debug.Log("Checker.checkPack", " ID does not match, want %v, got %v", blob.ID.Str(), hash.Str()) errs = append(errs, fmt.Errorf("ID does not match, want %v, got %v", blob.ID.Str(), hash.Str())) continue } } if len(errs) > 0 { return fmt.Errorf("pack %v contains %v errors: %v", id.Str(), len(errs), errs) } return nil }
func fsckFile(global CmdFsck, repo *repository.Repository, IDs []backend.ID) (uint64, error) { debug.Log("restic.fsckFile", "checking file %v", IDs) var bytes uint64 for _, id := range IDs { debug.Log("restic.fsck", " checking data blob %v\n", id) // test if blob is in the index packID, tpe, _, length, err := repo.Index().Lookup(id) if err != nil { return 0, fmt.Errorf("storage for blob %v (%v) not found", id, tpe) } bytes += uint64(length - crypto.Extension) debug.Log("restic.fsck", " blob found in pack %v\n", packID) if global.CheckData { // load content _, err := repo.LoadBlob(pack.Data, id) if err != nil { return 0, err } } else { // test if pack for data blob is there ok, err := repo.Backend().Test(backend.Data, packID.String()) if err != nil { return 0, err } if !ok { return 0, fmt.Errorf("data blob %v not found", id) } } // if orphan check is active, record storage id if global.o_data != nil { debug.Log("restic.fsck", " recording blob %v as used\n", id) global.o_data.Insert(id) } } return bytes, nil }
// loadSnapshotTreeIDs loads all snapshots from backend and returns the tree IDs. func loadSnapshotTreeIDs(repo *repository.Repository) (backend.IDs, []error) { var trees struct { IDs backend.IDs sync.Mutex } var errs struct { errs []error sync.Mutex } snapshotWorker := func(strID string, done <-chan struct{}) error { id, err := backend.ParseID(strID) if err != nil { return err } debug.Log("Checker.Snaphots", "load snapshot %v", id.Str()) treeID, err := loadTreeFromSnapshot(repo, id) if err != nil { errs.Lock() errs.errs = append(errs.errs, err) errs.Unlock() return nil } debug.Log("Checker.Snaphots", "snapshot %v has tree %v", id.Str(), treeID.Str()) trees.Lock() trees.IDs = append(trees.IDs, treeID) trees.Unlock() return nil } err := repository.FilesInParallel(repo.Backend(), backend.Snapshot, defaultParallelism, snapshotWorker) if err != nil { errs.errs = append(errs.errs, err) } return trees.IDs, errs.errs }
// Clear removes information from the cache that isn't present in the repository any more. func (c *Cache) Clear(repo *repository.Repository) error { list, err := c.list(backend.Snapshot) if err != nil { return err } for _, entry := range list { debug.Log("Cache.Clear", "found entry %v", entry) if ok, err := repo.Backend().Test(backend.Snapshot, entry.ID.String()); !ok || err != nil { debug.Log("Cache.Clear", "snapshot %v doesn't exist any more, removing %v", entry.ID, entry) err = c.purge(backend.Snapshot, entry.Subtype, entry.ID) if err != nil { return err } } } return nil }
func lockExists(repo *repository.Repository, t testing.TB, id backend.ID) bool { exists, err := repo.Backend().Test(backend.Lock, id.String()) OK(t, err) return exists }
func removeLock(repo *repository.Repository, id backend.ID) error { return repo.Backend().Remove(backend.Lock, id.String()) }
// RemoveAllLocks removes all locks forcefully. func RemoveAllLocks(repo *repository.Repository) error { return eachLock(repo, func(id backend.ID, lock *Lock, err error) error { return repo.Backend().Remove(backend.Lock, id.String()) }) }