1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_INSTALLD_RESTORABLE_FILE_H 18 #define ANDROID_INSTALLD_RESTORABLE_FILE_H 19 20 #include <functional> 21 #include <string> 22 23 #include "unique_file.h" 24 25 namespace android { 26 namespace installd { 27 28 // This is a file abstraction which allows restoring to the original file while temporary work 29 // file is updated. 30 // 31 // Typical flow for this API will be: 32 // RestorableFile rf = RestorableFile::CreateWritableFile(...) 33 // write to file using file descriptor acquired from: rf.fd() 34 // Make work file into a regular file with: rf.CommitWorkFile() 35 // Or throw away the work file by destroying the instance without calling CommitWorkFile(). 36 // The temporary work file is closed / removed when an instance is destroyed without calling 37 // CommitWorkFile(). The original file, if CommitWorkFile() is not called, will be kept. 38 // 39 // For safer restoration of original file when commit fails, following 3 steps can be taken: 40 // 1. CreateBackupFile(): This renames an existing regular file into a separate backup file. 41 // 2. CommitWorkFile(): Rename the work file into the regular file. 42 // 3. RemoveBackupFile(): Removes the backup file 43 // If CommitWorkFile fails, client can call RestoreBackupFile() which will restore regular file from 44 // the backup. 45 class RestorableFile { 46 public: 47 // Creates invalid instance with no fd (=-1) and empty path. 48 RestorableFile(); 49 RestorableFile(RestorableFile&& other) = default; 50 ~RestorableFile(); 51 52 // Passes all contents of other file into the current file. 53 // Files kept for the current file will be either deleted or committed depending on 54 // CommitWorkFile() and DisableCleanUp() calls made before this. 55 RestorableFile& operator=(RestorableFile&& other) = default; 56 57 // Gets file descriptor for backing work (=temporary) file. If work file does not exist, it will 58 // return -1. fd()59 int fd() const { return unique_file_.fd(); } 60 61 // Gets the path name for the regular file (not temporary file). path()62 const std::string& path() const { return unique_file_.path(); } 63 64 // Closes work file, deletes it and resets all internal states into default states. 65 void reset(); 66 67 // Closes work file and closes all files including work file, backup file and regular file. 68 void ResetAndRemoveAllFiles(); 69 70 // Creates a backup file by renaming existing regular file. This will return false if renaming 71 // fails. If regular file for renaming does not exist, it will return true. 72 bool CreateBackupFile(); 73 74 // Closes existing work file and makes it a regular file. 75 // Note that the work file is closed and fd() will return -1 after this. path() will still 76 // return the original path. 77 // This will return false when committing fails (=cannot rename). Both the regular file and tmp 78 // file will be deleted when it fails. 79 bool CommitWorkFile(); 80 81 // Cancels the commit and restores the backup file into the regular one. If renaming fails, 82 // it will return false. This returns true if the backup file does not exist. 83 bool RestoreBackupFile(); 84 85 // Removes the backup file. 86 void RemoveBackupFile(); 87 88 // Gets UniqueFile with the same path and fd() pointing to the work file. 89 const UniqueFile& GetUniqueFile() const; 90 91 // Creates writable RestorableFile. This involves creating tmp file for writing. 92 static RestorableFile CreateWritableFile(const std::string& path, int permissions); 93 94 // Removes the specified file together with tmp file generated as RestorableFile. 95 static void RemoveAllFiles(const std::string& path); 96 97 private: 98 RestorableFile(int value, const std::string& path); 99 100 // Used as a storage for work file fd and path string. 101 UniqueFile unique_file_; 102 }; 103 104 } // namespace installd 105 } // namespace android 106 107 #endif // ANDROID_INSTALLD_RESTORABLE_FILE_H 108