//备份日志文件 void LogReader::backup() throw(BackupException) { cout << "备份日志文件开始..." << endl; //获取系统当前时间 time_t now = time(0); struct tm* local = localtime(&now); ostringstream oss; oss << m_logFile << "." << setfill('0') << setw(4) << local->tm_year+1900 << setw(2) << local->tm_mon+1 << setw(2) << local->tm_mday << setw(2) << local->tm_hour << setw(2) << local->tm_min << setw(2) << local->tm_sec; m_backupFile = oss.str(); //拼接要执行备份命令的字符串 string cmd("./backup.sh "); cmd += m_logFile; cmd += " "; cmd += m_backupFile; //调用system函数执行命令 int status = system(cmd.c_str()); //获取脚本文件执行的退出码 if(1 == WEXITSTATUS(status)) { throw BackupException("拷贝错误"); } if(2 == WEXITSTATUS(status)) { throw BackupException("清空错误"); } cout << "备份日志文件结束" << endl; }
void Backup::get_source_snapshots_file() { LOG_INFO(__FUNCTION__); VERIFY(file_pool); LOG_INFO("Setting up connection Manager"); source_connection_manager = backend::BackendConnectionManager::create(source_ptree, RegisterComponent::F); const std::string source_namespace = source_ptree.get<std::string>("namespace"); LOG_INFO("Reading the snapshots file from the source " << source_namespace); BackendInterfacePtr source_bi = source_connection_manager->newBackendInterface(backend::Namespace(source_namespace)); const fs::path snapshots_file_path = file_pool->newFile("snapshots.xml"); source_bi->read(snapshots_file_path, snapshotFilename(), InsistOnLatestVersion::T); source_snapshot_persistor.reset(new SnapshotPersistor(snapshots_file_path)); if(not source_snapshot_persistor->hasUUIDSpecified()) { LOG_FATAL("Could not find GUIDS in source " << source_namespace << " snapshots file " << snapshots_file_path); throw BackupException("No GUID's in the snapshots file, update volumedriver first"); } nsid.set(0, std::move(source_bi)); }
void Backup::figure_out_end_snapshot() { LOG_INFO(__FUNCTION__); VERIFY(source_snapshot_persistor); VERIFY(not start_snapshot_); const boost::optional<SnapshotName> optional_end_snapshot(source_ptree.get_optional<SnapshotName>("end_snapshot")); if(optional_end_snapshot) { if(not source_snapshot_persistor->snapshotExists(*optional_end_snapshot)) { LOG_FATAL("Could not find end snapshot " << *optional_end_snapshot << " in source"); throw BackupException("Could not find snapshot"); } end_snapshot_name = *optional_end_snapshot; end_snapshot_number = source_snapshot_persistor->getSnapshotNum(end_snapshot_name); } else { std::vector<SnapshotNum> snapshots; source_snapshot_persistor->getAllSnapshots(snapshots); if(snapshots.empty()) { LOG_FATAL("Cannot backup a volume that doesn't have snapshots"); throw BackupException("No snapshots on source"); } end_snapshot_number = snapshots.back(); end_snapshot_name = source_snapshot_persistor->getSnapshotName(end_snapshot_number); } VERIFY(not end_snapshot_name.empty()); LOG_INFO("end snapshot is " << end_snapshot_name); status_.end_snapshot(end_snapshot_name); }
void Backup::figure_out_start_snapshot() { LOG_INFO(__FUNCTION__); VERIFY(source_snapshot_persistor); start_snapshot_ = source_ptree.get_optional<SnapshotName>("start_snapshot"); if(start_snapshot_ and not source_snapshot_persistor->snapshotExists(*start_snapshot_)) { LOG_FATAL("Could not find start snapshot " << *start_snapshot_ << " in source"); throw BackupException("Could not find snapshot"); } }
//给外界提供的公开接口函数 list<MLogRec>& LogReader::readLog() throw(ReadException) { cout << "读取日志记录开始..." << endl; try { //备份日志文件 backup(); //读取未匹配的记录 readLoginsFile(); //读取备份文件 readBackupFile(); //匹配 match(); //保存未匹配的记录 saveLoginsFile(); } catch(BackupException& ex) { throw BackupException("备份错误"); } catch(ReadException& ex) { throw ReadException("读取错误"); } catch(SaveException& ex) { throw SaveException("存储错误"); } //表示可以捕获任何异常 catch(...) { throw ReadException("未知错误"); } cout << "读取日志记录结束" << endl; return m_logs; }
bool Backup::preexisting_volume_checks() { LOG_INFO(__FUNCTION__); VERIFY(source_snapshot_persistor); VERIFY(target_volume_); api::getManagementMutex().assertLocked(); if(start_snapshot_) { const SnapshotName& start_snapshot_name = *start_snapshot_; const SnapshotNum start_snapshot_num = source_snapshot_persistor->getSnapshotNum(*start_snapshot_); const UUID start_snapshot_uuid = source_snapshot_persistor->getUUID(start_snapshot_num); LOG_INFO("Backup target volume existed, figuring out if we need to do work"); // We are going to apply an incremental with snapshot matching //const SnapshotNum start_snapshot_num = source_snapshot_persistor.getSnapshotNum(*start_snapshot); if(not api::checkSnapshotUUID(target_volume_.get(), start_snapshot_name, start_snapshot_uuid)) { LOG_FATAL("Snapshot with name " << start_snapshot_name << " has non matching guids, exiting"); throw BackupException("Non matching guids"); } else if(api::snapshotExists(target_volume_.get(), end_snapshot_name)) { const UUID end_snapshot_uuid = source_snapshot_persistor->getUUID(end_snapshot_number); if(api::checkSnapshotUUID(target_volume_.get(), end_snapshot_name, end_snapshot_uuid)) { LOG_INFO("Start and end are already on target and guids match, lovely!"); LOG_INFO("Exiting early"); { status_.finish(); } return false; } else { LOG_INFO("Start snapshot was on target but end snapshot had different guid"); boost::this_thread::interruption_point(); api::restoreSnapshot(target_volume_.get(), start_snapshot_name); } } else { LOG_INFO("Start snapshot was on target but end snapshot not"); boost::this_thread::interruption_point(); api::restoreSnapshot(target_volume_.get(), start_snapshot_name); } } else { LOG_INFO("Backup volume existed but no start snapshot was given... trying to find the best place to backup from"); LOG_INFO("Getting the list of snapshots from the target"); std::list<SnapshotName> snapshots_list; api::showSnapshots(target_volume_.get(), snapshots_list); if(snapshots_list.empty()) { LOG_WARN("No snapshots in backed up volume, something went wrong??"); LOG_WARN("Checking for a failed first backup because the snapshots list is empty"); get_target_volume_info(); if(source_volume_config->getNS().str() != target_volume_config->id_) { LOG_FATAL("No snapshot on the volume and volume names don't match: " << source_volume_config->getNS() << " vs. " << std::string(target_volume_config->id_)); throw BackupException("Volume on backup had no snapshots and wrong volume name"); } if(target_volume_config->wan_backup_volume_role_ != VolumeConfig::WanBackupVolumeRole::WanBackupBase) { LOG_FATAL("Target volume exists, has not snapshot and names match but has the wrong role"); throw BackupException("Volume on backup had no snapshots and wrong role"); } LOG_WARN("Seems to have been a botched backup, cleaning up"); BackendInterfacePtr bip = VolManager::get()->createBackendInterface(target_namespace); std::list<std::string> objects; bip->listObjects(objects); BackendNamesFilter is_vd_object; for (const auto& o : objects) { if (is_vd_object(o)) { LOG_INFO("Removing " << o); bip->remove(o); } } throw RetryCreateVolume(); } SnapshotName snapshot_to_be_restored; LOG_INFO("Looping of target snapshotshots to find latest that can be matched"); for(std::list<SnapshotName>::const_reverse_iterator i = snapshots_list.rbegin(); i != snapshots_list.rend(); ++i) { const SnapshotName& snap_name = *i; if(source_snapshot_persistor->snapshotExists(snap_name)) { SnapshotNum num = source_snapshot_persistor->getSnapshotNum(snap_name); UUID snap_uuid = source_snapshot_persistor->getUUID(num); if(api::checkSnapshotUUID(target_volume_.get(), snap_name, snap_uuid)) { snapshot_to_be_restored = snap_name; break; } else { LOG_FATAL("Snapshot with the same name but different guid found, " << snap_name); throw BackupException("Guid confusion"); } } } if(snapshot_to_be_restored.empty()) { LOG_FATAL("Could not find a matching snapshot "); throw BackupException("Could not find a matching snapshot"); } else if(snapshot_to_be_restored == end_snapshot_name) { LOG_INFO("snapshot to be restored == end snapshot, exiting early"); { status_.finish(); } return false; } // Y42 we might be a lot smarter here LOG_INFO("Connecting snapshot found as " << snapshot_to_be_restored); LOG_INFO("Doing a restore to that snapshot on the target volume"); boost::this_thread::interruption_point(); api::restoreSnapshot(target_volume_.get(), snapshot_to_be_restored); start_snapshot_ = snapshot_to_be_restored; } status_.start_snapshot(start_snapshot_.get_value_or(SnapshotName())); return true; }