+++ /dev/null
-#!/usr/bin/perl -w
-#
-# Garbage collect segments in LBS snapshot directories.
-#
-# Find all segments which are not referenced by any current snapshots and print
-# out a listing of them so that they can be deleted.
-#
-# Takes no command-line arguments, and expects to be invoked from the directory
-# containing the snapshots.
-#
-# Copyright (C) 2007 Michael Vrable
-
-use strict;
-
-my $SEGMENT_PATTERN
- = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}';
-
-# Set of all segments which are used by current snapshots. Value is ignored.
-my %segments_used = ();
-
-# Iterate through all snapshots. Snapshot descriptors should end with a ".lbs"
-# extension. Find all segments which are used.
-foreach (glob "*.lbs") {
- open DESCRIPTOR, "<", $_
- or die "Cannot open backup descriptor file $_: $!";
-
- # Parse the backup descriptor file. We might not need the full parser, but
- # it shouldn't hurt.
- my %descriptor = ();
- my ($line, $last_key);
- while (defined($line = <DESCRIPTOR>)) {
- chomp $line;
-
- if ($line =~ m/^([-\w]+):\s*(.*)$/) {
- $descriptor{$1} = $2;
- $last_key = $1;
- } elsif ($line =~/^\s/ && defined $last_key) {
- $descriptor{$last_key} .= $line;
- } else {
- undef $last_key;
- print STDERR "Ignoring line in backup descriptor: $line\n";
- }
- }
-
- # Extract the list of segments from the parsed descriptor file.
- foreach (split /\s+/, $descriptor{Segments}) {
- next unless $_;
- if (m/^$SEGMENT_PATTERN$/) {
- $segments_used{$_} = 1;
- } else {
- warn "Invalid segment name: '$_'\n";
- }
- }
-
- close DESCRIPTOR;
-}
-
-# Look for all segments in this directory, and match them against the list
-# generated above of segments which are used. Pring out any segments which are
-# not used.
-my %segments_found = ();
-
-foreach (glob "*") {
- if (m/^($SEGMENT_PATTERN)(\.\S+)?$/) {
- $segments_found{$1} = 1;
- if (!exists $segments_used{$1}) {
- print $_, "\n";
- }
- }
-}
-
-# Perform a consistency check: were any segments referenced by snapshot but not
-# found in the directory?
-foreach (sort keys %segments_used) {
- if (!exists $segments_found{$_}) {
- print STDERR "Warning: Segment $_ not found\n";
- }
-}
-
* one block (1 MB) worth of data. If the file doesn't seems like it might
* be larger than that, don't parse the rules in it. */
ssize_t bytes = file_read(fd, block_buf, LBS_BLOCK_SIZE);
+ close(fd);
if (bytes < 0 || bytes >= static_cast<ssize_t>(LBS_BLOCK_SIZE - 1)) {
/* TODO: Add more strict resource limits on merge files? */
fprintf(stderr,
DIR *dir = opendir(path.c_str());
if (dir == NULL) {
- fprintf(stderr, "Error: %m\n");
+ fprintf(stderr, "Error reading directory %s: %m\n",
+ path.c_str());
return;
}