diff options
| -rw-r--r-- | packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java index c05c4cdf72d7..33085a14c65f 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java @@ -64,6 +64,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -716,6 +718,23 @@ final class SettingsState { } } catch (Throwable t) { Slog.wtf(LOG_TAG, "Failed to write settings, restoring backup", t); + if (t instanceof IOException) { + // we failed to create a directory, so log the permissions and existence + // state for the settings file and directory + logSettingsDirectoryInformation(destination.getBaseFile()); + if (t.getMessage().contains("Couldn't create directory")) { + // attempt to create the directory with Files.createDirectories, which + // throws more informative errors than File.mkdirs. + Path parentPath = destination.getBaseFile().getParentFile().toPath(); + try { + Files.createDirectories(parentPath); + Slog.i(LOG_TAG, "Successfully created " + parentPath); + } catch (Throwable t2) { + Slog.e(LOG_TAG, "Failed to write " + parentPath + + " with Files.writeDirectories", t2); + } + } + } destination.failWrite(out); } finally { IoUtils.closeQuietly(out); @@ -729,6 +748,33 @@ final class SettingsState { } } + private static void logSettingsDirectoryInformation(File settingsFile) { + File parent = settingsFile.getParentFile(); + Slog.i(LOG_TAG, "directory info for directory/file " + settingsFile + + " with stacktrace ", new Exception()); + File ancestorDir = parent; + while (ancestorDir != null) { + if (!ancestorDir.exists()) { + Slog.i(LOG_TAG, "ancestor directory " + ancestorDir + + " does not exist"); + ancestorDir = ancestorDir.getParentFile(); + } else { + Slog.i(LOG_TAG, "ancestor directory " + ancestorDir + + " exists"); + Slog.i(LOG_TAG, "ancestor directory " + ancestorDir + + " permissions: r: " + ancestorDir.canRead() + " w: " + + ancestorDir.canWrite() + " x: " + ancestorDir.canExecute()); + File ancestorParent = ancestorDir.getParentFile(); + if (ancestorParent != null) { + Slog.i(LOG_TAG, "ancestor's parent directory " + ancestorParent + + " permissions: r: " + ancestorParent.canRead() + " w: " + + ancestorParent.canWrite() + " x: " + ancestorParent.canExecute()); + } + break; + } + } + } + static void writeSingleSetting(int version, XmlSerializer serializer, String id, String name, String value, String defaultValue, String packageName, String tag, boolean defaultSysSet) throws IOException { @@ -803,6 +849,7 @@ final class SettingsState { in = new AtomicFile(mStatePersistFile).openRead(); } catch (FileNotFoundException fnfe) { Slog.i(LOG_TAG, "No settings state " + mStatePersistFile); + logSettingsDirectoryInformation(mStatePersistFile); addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null); return; } |