mirror of
https://github.com/kopia/kopia.git
synced 2026-03-14 04:06:44 -04:00
extracted packIndex interface and implemented protoPackIndex to wrap all index data manipulation
68 lines
1.8 KiB
Go
68 lines
1.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/kopia/kopia/block"
|
|
|
|
"github.com/kopia/kopia/repo"
|
|
"github.com/kopia/kopia/storage"
|
|
)
|
|
|
|
var (
|
|
storageSweepCommand = storageCommands.Command("sweep", "Remove unused storage blocks")
|
|
storageSweepAgeThreshold = storageSweepCommand.Flag("min-age", "Minimum age of storage block to delete").Default("24h").Duration()
|
|
storageSweepPrintUnused = storageSweepCommand.Flag("print", "Do not delete blocks, but print which ones would be deleted").Short('n').Bool()
|
|
)
|
|
|
|
func runStorageSweepAction(ctx context.Context, rep *repo.Repository) error {
|
|
indexBlocks, err := rep.Blocks.ActiveIndexBlocks(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
inUseIndexBlocks := map[block.PhysicalBlockID]bool{}
|
|
for _, ib := range indexBlocks {
|
|
inUseIndexBlocks[ib.BlockID] = true
|
|
}
|
|
|
|
ctx, cancel := context.WithCancel(ctx)
|
|
defer cancel()
|
|
ch := rep.Storage.ListBlocks(ctx, "")
|
|
|
|
for bm := range ch {
|
|
if bm.Error != nil {
|
|
return bm.Error
|
|
}
|
|
|
|
if err = sweepBlock(ctx, rep, bm, inUseIndexBlocks); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func sweepBlock(ctx context.Context, rep *repo.Repository, bm storage.BlockMetadata, inUseIndexBlocks map[block.PhysicalBlockID]bool) error {
|
|
age := time.Since(bm.TimeStamp)
|
|
inUse := rep.Blocks.IsStorageBlockInUse(block.PhysicalBlockID(bm.BlockID)) || inUseIndexBlocks[block.PhysicalBlockID(bm.BlockID)] || bm.BlockID == repo.FormatBlockID
|
|
keep := inUse || age < *storageSweepAgeThreshold
|
|
if keep {
|
|
return nil
|
|
}
|
|
|
|
if *storageSweepPrintUnused {
|
|
fmt.Printf("unused block %v age %v\n", bm.BlockID, age)
|
|
return nil
|
|
}
|
|
|
|
fmt.Printf("deleting unused block %v age %v\n", bm.BlockID, age)
|
|
return rep.Storage.DeleteBlock(ctx, bm.BlockID)
|
|
}
|
|
|
|
func init() {
|
|
storageSweepCommand.Action(repositoryAction(runStorageSweepAction))
|
|
}
|