RecoveryFile::RecoveryFile(const bf::path& path, RequestType type, bool load)
: type_(type), path_(path), backup_done_(false), cleanup_(false) {
+ backup_path_ = path_.string() + ".bck";
if (load) {
if (!ReadFileContent()) {
path_.clear();
RecoveryFile::~RecoveryFile() {
if (Remove(path_))
LOG(DEBUG) << "Recovery file " << path_ << " removed";
+ if (Remove(backup_path_))
+ LOG(DEBUG) << "Recovery file " << backup_path_ << " removed";
}
void RecoveryFile::Detach() {
}
bool RecoveryFile::WriteAndCommitFileContent() {
- Remove(path_);
+ if (bf::exists(path_)) {
+ bs::error_code error;
+ bf::rename(path_, backup_path_, error);
+ if (error) {
+ LOG(ERROR) << "Cannot backup recovery file:" << path_ <<
+ ", error: " << error;
+ return false;
+ }
+ sync();
+ }
+
FILE* handle = fopen(path_.c_str(), "wx");
if (!handle) {
LOG(ERROR) << "Cannot write recovery file";
fputs("\n", handle);
fclose(handle);
sync();
+
+ Remove(backup_path_);
return true;
}
typedef std::pair<std::string, std::string> RecoverEntry;
-const char kRecoveryFilePattern[] = "^(.*)-recovery-(.*)";
+const char kRecoveryFilePattern[] = "^(.*)-recovery-(.){6}$";
+const char kBackupFilePattern[] = "^(.*)-recovery-(.){6}\.bck$";
const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
class PkgRecoveryService {
void Run();
private:
+ void SearchBackupFiles(uid_t uid);
std::vector<RecoverEntry> SearchRecoveryFiles(uid_t uid);
void ProcessRecovery(uid_t uid, const std::vector<RecoverEntry>& entries);
bool RunBackend(uid_t uid, const char* type, const char* file);
void PkgRecoveryService::Run() {
// recover global packages
+ SearchBackupFiles(kGlobalUserUid);
LOG(INFO) << "Searching recovery files for user " << kGlobalUserUid;
std::vector<RecoverEntry> globalentries = SearchRecoveryFiles(kGlobalUserUid);
ProcessRecovery(kGlobalUserUid, globalentries);
for (auto userinfo : list) {
uid_t uid = std::get<0>(userinfo);
LOG(INFO) << "Searching recovery files for user " << std::get<0>(userinfo);
+ SearchBackupFiles(uid);
std::vector<RecoverEntry> entries = SearchRecoveryFiles(uid);
ProcessRecovery(uid, entries);
}
}
+void PkgRecoveryService::SearchBackupFiles(uid_t uid) {
+ const bf::path recovery_dir = ci::GetRootAppPath(false, uid);
+ for (bf::directory_iterator iter(recovery_dir);
+ iter != bf::directory_iterator();
+ ++iter) {
+ try {
+ std::string file = iter->path().filename().string();
+ std::regex backup_regex(kBackupFilePattern);
+ std::smatch match;
+ if (std::regex_search(file, match, backup_regex)) {
+ bf::path orig_file(iter->path().parent_path() / iter->path().stem());
+ if (bf::exists(orig_file))
+ bf::remove(iter->path());
+ else
+ bf::rename(iter->path(), orig_file);
+ }
+ } catch (...) {
+ LOG(WARNING) << "Exception occurred: "
+ << boost::current_exception_diagnostic_information();
+ continue;
+ }
+ }
+}
+
std::vector<RecoverEntry> PkgRecoveryService::SearchRecoveryFiles(uid_t uid) {
std::vector<RecoverEntry> list;
const bf::path recovery_dir = ci::GetRootAppPath(false, uid);