• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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