blob: eda229241ac0a5cb8a0818d17721aada59f92b3b [file] [log] [blame]
Keun young Parkb7342262021-10-25 08:09:27 -07001/*
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
25namespace android {
26namespace 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.
45class RestorableFile {
46public:
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.
59 int fd() const { return unique_file_.fd(); }
60
61 // Gets the path name for the regular file (not temporary file).
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
97private:
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