summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2012-05-09 13:33:52 -0700
committerJeff Sharkey <jsharkey@android.com>2012-05-09 13:43:19 -0700
commit6de357e4d10fa5977ab9a6c665dc858765e95d34 (patch)
treef5a0ce10d0d665dd5dda2afcd4b4656b7a6dc8a3 /core
parent6704c233390743890d23338a2329dcda5709b810 (diff)
downloadframeworks_base-6de357e4d10fa5977ab9a6c665dc858765e95d34.zip
frameworks_base-6de357e4d10fa5977ab9a6c665dc858765e95d34.tar.gz
frameworks_base-6de357e4d10fa5977ab9a6c665dc858765e95d34.tar.bz2
Recover from Throwable in FileRotator, dump.
In rewriteSingle(), catch Throwable to rollback to backup file, instead of just IOException. Also add dumpAll() to pack up contents for later debugging, and use it when encountering bad stats. Bug: 6467868 Change-Id: Ic8e287cf5a235706811a304a88d71d11d3a79cd4
Diffstat (limited to 'core')
-rw-r--r--core/java/com/android/internal/util/FileRotator.java63
-rw-r--r--core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java4
2 files changed, 52 insertions, 15 deletions
diff --git a/core/java/com/android/internal/util/FileRotator.java b/core/java/com/android/internal/util/FileRotator.java
index 6cfb97d..26235f1 100644
--- a/core/java/com/android/internal/util/FileRotator.java
+++ b/core/java/com/android/internal/util/FileRotator.java
@@ -19,8 +19,6 @@ package com.android.internal.util;
import android.os.FileUtils;
import android.util.Slog;
-import com.android.internal.util.FileRotator.Rewriter;
-
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
@@ -29,8 +27,11 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
import libcore.io.IoUtils;
+import libcore.io.Streams;
/**
* Utility that rotates files over time, similar to {@code logrotate}. There is
@@ -137,10 +138,38 @@ public class FileRotator {
public void deleteAll() {
final FileInfo info = new FileInfo(mPrefix);
for (String name : mBasePath.list()) {
- if (!info.parse(name)) continue;
+ if (info.parse(name)) {
+ // delete each file that matches parser
+ new File(mBasePath, name).delete();
+ }
+ }
+ }
+
+ /**
+ * Dump all files managed by this rotator for debugging purposes.
+ */
+ public void dumpAll(OutputStream os) throws IOException {
+ final ZipOutputStream zos = new ZipOutputStream(os);
+ try {
+ final FileInfo info = new FileInfo(mPrefix);
+ for (String name : mBasePath.list()) {
+ if (info.parse(name)) {
+ final ZipEntry entry = new ZipEntry(name);
+ zos.putNextEntry(entry);
- // delete each file that matches parser
- new File(mBasePath, name).delete();
+ final File file = new File(mBasePath, name);
+ final FileInputStream is = new FileInputStream(file);
+ try {
+ Streams.copy(is, zos);
+ } finally {
+ IoUtils.closeQuietly(is);
+ }
+
+ zos.closeEntry();
+ }
+ }
+ } finally {
+ IoUtils.closeQuietly(zos);
}
}
@@ -159,22 +188,22 @@ public class FileRotator {
public void combineActive(final Reader reader, final Writer writer, long currentTimeMillis)
throws IOException {
rewriteActive(new Rewriter() {
- /** {@inheritDoc} */
+ @Override
public void reset() {
// ignored
}
- /** {@inheritDoc} */
+ @Override
public void read(InputStream in) throws IOException {
reader.read(in);
}
- /** {@inheritDoc} */
+ @Override
public boolean shouldWrite() {
return true;
}
- /** {@inheritDoc} */
+ @Override
public void write(OutputStream out) throws IOException {
writer.write(out);
}
@@ -224,11 +253,11 @@ public class FileRotator {
// write success, delete backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and restore backup
file.delete();
backupFile.renameTo(file);
- throw e;
+ throw rethrowAsIoException(t);
}
} else {
@@ -241,11 +270,11 @@ public class FileRotator {
// write success, delete empty backup
backupFile.delete();
- } catch (IOException e) {
+ } catch (Throwable t) {
// write failed, delete file and empty backup
file.delete();
backupFile.delete();
- throw e;
+ throw rethrowAsIoException(t);
}
}
}
@@ -353,6 +382,14 @@ public class FileRotator {
}
}
+ private static IOException rethrowAsIoException(Throwable t) throws IOException {
+ if (t instanceof IOException) {
+ throw (IOException) t;
+ } else {
+ throw new IOException(t.getMessage(), t);
+ }
+ }
+
/**
* Details for a rotated file, either parsed from an existing filename, or
* ready to be built into a new filename.
diff --git a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
index 94d1cb6..95f0e67 100644
--- a/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FileRotatorTest.java
@@ -187,12 +187,12 @@ public class FileRotatorTest extends AndroidTestCase {
rotate.combineActive(reader, new Writer() {
public void write(OutputStream out) throws IOException {
new DataOutputStream(out).writeUTF("bar");
- throw new ProtocolException("yikes");
+ throw new NullPointerException("yikes");
}
}, currentTime);
fail("woah, somehow able to write exception");
- } catch (ProtocolException e) {
+ } catch (IOException e) {
// expected from above
}