Skip to content

Commit 7d09265

Browse files
author
Nate Myren
committed
Add logging upon failure to edit SystemSettings
Add more logs about file state and file permission state upon failing to read or write a Settings file. In the case of failing to create a parent directory for the settings file, SettingsState will attempt to create the folder with Files.createDirectories, which throws more informative errors. Bug: 119723324 Test: None Change-Id: Iec8ed903e109558efc3a98906c68d1579b985232
1 parent 3e57701 commit 7d09265

1 file changed

Lines changed: 47 additions & 0 deletions

File tree

packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@
6464
import java.io.IOException;
6565
import java.io.PrintWriter;
6666
import java.nio.charset.StandardCharsets;
67+
import java.nio.file.Files;
68+
import java.nio.file.Path;
6769
import java.util.ArrayList;
6870
import java.util.List;
6971
import java.util.Objects;
@@ -716,6 +718,23 @@ private void doWriteState() {
716718
}
717719
} catch (Throwable t) {
718720
Slog.wtf(LOG_TAG, "Failed to write settings, restoring backup", t);
721+
if (t instanceof IOException) {
722+
// we failed to create a directory, so log the permissions and existence
723+
// state for the settings file and directory
724+
logSettingsDirectoryInformation(destination.getBaseFile());
725+
if (t.getMessage().contains("Couldn't create directory")) {
726+
// attempt to create the directory with Files.createDirectories, which
727+
// throws more informative errors than File.mkdirs.
728+
Path parentPath = destination.getBaseFile().getParentFile().toPath();
729+
try {
730+
Files.createDirectories(parentPath);
731+
Slog.i(LOG_TAG, "Successfully created " + parentPath);
732+
} catch (Throwable t2) {
733+
Slog.e(LOG_TAG, "Failed to write " + parentPath
734+
+ " with Files.writeDirectories", t2);
735+
}
736+
}
737+
}
719738
destination.failWrite(out);
720739
} finally {
721740
IoUtils.closeQuietly(out);
@@ -729,6 +748,33 @@ private void doWriteState() {
729748
}
730749
}
731750

751+
private static void logSettingsDirectoryInformation(File settingsFile) {
752+
File parent = settingsFile.getParentFile();
753+
Slog.i(LOG_TAG, "directory info for directory/file " + settingsFile
754+
+ " with stacktrace ", new Exception());
755+
File ancestorDir = parent;
756+
while (ancestorDir != null) {
757+
if (!ancestorDir.exists()) {
758+
Slog.i(LOG_TAG, "ancestor directory " + ancestorDir
759+
+ " does not exist");
760+
ancestorDir = ancestorDir.getParentFile();
761+
} else {
762+
Slog.i(LOG_TAG, "ancestor directory " + ancestorDir
763+
+ " exists");
764+
Slog.i(LOG_TAG, "ancestor directory " + ancestorDir
765+
+ " permissions: r: " + ancestorDir.canRead() + " w: "
766+
+ ancestorDir.canWrite() + " x: " + ancestorDir.canExecute());
767+
File ancestorParent = ancestorDir.getParentFile();
768+
if (ancestorParent != null) {
769+
Slog.i(LOG_TAG, "ancestor's parent directory " + ancestorParent
770+
+ " permissions: r: " + ancestorParent.canRead() + " w: "
771+
+ ancestorParent.canWrite() + " x: " + ancestorParent.canExecute());
772+
}
773+
break;
774+
}
775+
}
776+
}
777+
732778
static void writeSingleSetting(int version, XmlSerializer serializer, String id,
733779
String name, String value, String defaultValue, String packageName,
734780
String tag, boolean defaultSysSet) throws IOException {
@@ -803,6 +849,7 @@ private void readStateSyncLocked() {
803849
in = new AtomicFile(mStatePersistFile).openRead();
804850
} catch (FileNotFoundException fnfe) {
805851
Slog.i(LOG_TAG, "No settings state " + mStatePersistFile);
852+
logSettingsDirectoryInformation(mStatePersistFile);
806853
addHistoricalOperationLocked(HISTORICAL_OPERATION_INITIALIZE, null);
807854
return;
808855
}

0 commit comments

Comments
 (0)