On Tue, Jun 15, 2010 at 11:05:58PM +0800, Michael Deegan wrote:
> retitle 585804 apt-cacher-cleanup: infinite loop in the face of corrupted gz 
> files
> thanks
> 
> On Mon, Jun 14, 2010 at 08:45:31AM +0100, Mark Hindley wrote:
> > It might be worth creating a lock so only a single instance can run, but
> > I am not sure that will address your root issue.
> 
> Agreed.

Patch for this:

diff --git a/apt-cacher-cleanup.pl b/apt-cacher-cleanup.pl
index 149fcce..5e1c8c7 100755
--- a/apt-cacher-cleanup.pl
+++ b/apt-cacher-cleanup.pl
@@ -83,6 +84,7 @@ if ( $cfg->{clean_cache} ne 1 ) {
     printmsg("Maintenance disallowed by configuration item clean_cache\n");
     exit 0;
 }
+
 # change uid and gid if root
 if ($cfg->{user} && !$> or $cfg->{group} && !$)) {
     printmsg("Invoked as root, changing to $cfg->{user}:$cfg->{group} and 
re-execing.\n");
@@ -543,6 +545,14 @@ if (@db_mode || $db_recover){
 
 # Cache cleaning from here
 
+# Take a lock on the cache dir to ensure only one cleanup script can run at a
+# time as this can take a while on some systems.
+
+open  (my $cleanup_lock, '<', $cfg->{'cache_dir'})
+  or die "Can't open $cfg->{'cache_dir'} for locking!\nError: $!\n";
+flock $cleanup_lock, LOCK_EX|LOCK_NB
+  or die "Another apt-cacher-cleanup is already running. Exiting!\n";
+
 # check offline mode in config
 if (defined $cfg->{offline_mode} && $cfg->{offline_mode}) {
        $offline = 1;

> > > While the machine is not exactly fast, under normal circumstances cleanup
> > > should take "only" 3 or 4 hours. :P
> > 
> > What spec is this? I have a k6 200 that takes only about 20 minutes!
> 
> Dual-PIII 1GHz, 256MB, ST318406LW.
> 
> For me cleanup has always taken hours, and involved considerable amounts of
> disk I/O.
> 
> > How large is the cache? How much free space?
> 
>    mich...@ying:~$ du -skx /var/cache/apt-cacher/*
>    16196   /var/cache/apt-cacher/headers
>    4       /var/cache/apt-cacher/import
>    0       /var/cache/apt-cacher/libcurl.socket
>    3467600 /var/cache/apt-cacher/packages
>    15364   /var/cache/apt-cacher/private
>    28      /var/cache/apt-cacher/temp
> 
>    mich...@ying:~$ df -P / /var/cache/apt-cacher/
>    Filesystem         1024-blocks      Used Available Capacity Mounted on
>    /dev/sda2              3937252    962408   2774836      26% /
>    /dev/mapper/ying-home   4128448   3917760       976     100% /home
> 
> (shortly before I freed up some space (by deleting a half-gigabyte .deb))
> 
> Admittedly the lack of diskspace was hardly an ideal situation, but I was
> kind of hoping for it to keel over with an error rather than just spinning
> quietly. :P
> 
> The cache services five machines, a mixture of Ubuntu/Debian and 32/64 bit
> (yes, I know, cruel and unusual). Different files with the same name are
> usually not a problem.
> 
> > We need to find out if it is just taking more than 24 hours and then the
> > second instance compounds the issue.
> 
> It appears the answer is 'no'.
> 
> > Can you change /etc/cron.daily/apt-cacher and add '-v' to the script
> > invocation. You will get an email with basic information about what it
> > is doing.
> 
> I'm not sure why I didn't think to try that...
> 
> > Is there anything in the logs
> > (/var/log/apt-cacher/{db|access|error}.log?
> 
> error.log naturally has lots of noise complaining about diskspace, eg:
> 
>    Mon Jun 14 15:30:26 2010|info [19753]: return_file 
> /var/cache/apt-cacher/packages/security.debian.org_dists_lenny_updates_main_binary-i386_Packages.diff_Index
>  aborted by timeout at 0 of  bytes
>    Mon Jun 14 15:31:34 2010|info [21203]: ALARM: Insuffient diskspace for 
> Content-Length: 51900 in cache_dir with 36864 freespace
>    Mon Jun 14 15:31:45 2010|warn [21205]: Close 
> /var/cache/apt-cacher/packages/security.debian.org_dists_squeeze_updates_contrib_binary-i386_Packages.diff_Index
>  failed, No space left on device at /usr/sbin/apt-cacher line 1481.
> 
> access.log contains a few dozen CLEANUPREFRESH entries, plus the normal stuff 
> from clients.
> 
> db.log does not exist.
> 
> I think I have found the problem, though. After killing a couple of runs
> with -v, I noticed that it had stopped at the same file. The following test
> script and attached test file will hopefully demonstrate the problem:

Can you try this patch please? Does it help?

diff --git a/apt-cacher-cleanup.pl b/apt-cacher-cleanup.pl
index 149fcce..a90a61c 100755
--- a/apt-cacher-cleanup.pl
+++ b/apt-cacher-cleanup.pl
@@ -236,16 +237,15 @@ sub pdiff {
        
     printmsg "Reading $basename...\n";
     while (<$raw>){
+       last if $AnyUncompressError;
        print $tfh $_;
        $sha1->add($_);
     }
     close($raw);
     flock($lck, LOCK_UN);
     close($lck,);
-    my $rstat =($? >> 8);
-    #    printmsg "Read status $rstat\n";
-    if ($rstat) {
-       warn "$name Read failed, aborting patch\n";
+    if ($AnyUncompressError) {
+       warn "$name Read failed: $AnyUncompressError. Aborting patch\n";
        return;
     }
        
@@ -332,10 +332,15 @@ sub pdiff {
        my $pdfh = new IO::Uncompress::AnyUncompress $pdiff
          or die "Decompression failed: $AnyUncompressError\n";
        while (<$pdfh>) {
+           last if $AnyUncompressError;
            print DIFFS $_;
            $sha1->add($_);
        }
        close($pdfh);
+       if ($AnyUncompressError) {
+           warn "$name Read failed: $AnyUncompressError. Aborting patch\n";
+           return;
+       }
 
        my $pdiffdigest = $sha1->hexdigest;
 #      printmsg "$pdiff SHA1: $pdiffdigest\n";
@@ -356,7 +361,7 @@ sub pdiff {
     print $patchpipe $diffs;
     close($patchpipe);
     chdir $cwd or die "Unable to restore working directory: $!"; # Restore
-    $rstat =($? >> 8);
+    my $rstat =($? >> 8);
     if ($rstat) {
        warn "Patching failed (exit code $rstat), aborting\n";
        return;
diff --git a/apt-cacher-lib-cs.pl b/apt-cacher-lib-cs.pl
index a8746b5..12a6430 100755
--- a/apt-cacher-lib-cs.pl
+++ b/apt-cacher-lib-cs.pl
@@ -196,9 +196,10 @@ sub import_sums {
     my $dbh=${$_[1]};
     my %temp;
     return unless $cfg->{checksum};
-    extract_sums($_[0],\%temp);
-    while (my ($filename,$data) = each %temp){
-       $dbh->db_put($filename,$data) and warn "db_put $filename, $data failed 
with $!" ;
+    if (extract_sums($_[0],\%temp)) {
+        while (my ($filename,$data) = each %temp){
+           $dbh->db_put($filename,$data) and warn "db_put $filename, $data 
failed with $!" ;
+       }
     }
 }
 
diff --git a/apt-cacher-lib.pl b/apt-cacher-lib.pl
index 163b14a..b258a7f 100755
--- a/apt-cacher-lib.pl
+++ b/apt-cacher-lib.pl
@@ -227,6 +227,7 @@ sub extract_sums {
 
    my ($file,$complete,$sha1,$sha256,$md5,$size);
    while(<$raw>) {
+       last if $AnyUncompressError;
        if(/^\s(\w{40})\s+(\d+)\s(\S+)\n/ && $indexbase) { # diff_Index/Release 
SHA1
           $sha1=$1;
           $size =$2;
@@ -284,6 +285,10 @@ sub extract_sums {
           }
        }
    };
+   if ($AnyUncompressError) {
+       warn "$name Read failed: $AnyUncompressError. Aborting read\n";
+       return;
+   }
    return 1;
 }
 
Mark



-- 
To UNSUBSCRIBE, email to [email protected]
with a subject of "unsubscribe". Trouble? Contact [email protected]

Reply via email to