Beispiel #1
0
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())
	}
}
Beispiel #2
0
// 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)
}
Beispiel #3
0
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())
}
Beispiel #4
0
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)
	}
}
Beispiel #5
0
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
}
Beispiel #6
0
// 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
	})
}
Beispiel #7
0
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
}
Beispiel #8
0
// 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
}
Beispiel #9
0
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
}
Beispiel #10
0
// 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
}
Beispiel #11
0
// 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
}
Beispiel #12
0
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
}
Beispiel #13
0
func removeLock(repo *repository.Repository, id backend.ID) error {
	return repo.Backend().Remove(backend.Lock, id.String())
}
Beispiel #14
0
// 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())
	})
}