Clean up PartitionSettings
The PartitionSettings struct contains some data elements that are duplicates of data elements in the TWPartition class that is contained within the PartitionsSettings.Part element. We will eliminate this duplication to help reduce the chances for programming bugs. Specifically, this fixes problems where the current file system does not match the backed up file system. Change-Id: I02f236e72093362050556a2e53a09d1dbb9a269d
This commit is contained in:
+5
-3
@@ -1739,9 +1739,11 @@ int GUIAction::flashimage(std::string arg __unused)
|
||||
|
||||
PartitionSettings part_settings;
|
||||
operation_start("Flash Image");
|
||||
DataManager::GetValue("tw_zip_location", part_settings.Restore_Name);
|
||||
DataManager::GetValue("tw_file", part_settings.Backup_FileName);
|
||||
unsigned long long total_bytes = TWFunc::Get_File_Size(part_settings.Restore_Name + "/" + part_settings.Backup_FileName);
|
||||
string path, filename;
|
||||
DataManager::GetValue("tw_zip_location", path);
|
||||
DataManager::GetValue("tw_file", filename);
|
||||
part_settings.Backup_Folder = path + "/" + filename;
|
||||
unsigned long long total_bytes = TWFunc::Get_File_Size(part_settings.Backup_Folder);
|
||||
ProgressTracking progress(total_bytes);
|
||||
part_settings.progress = &progress;
|
||||
part_settings.adbbackup = false;
|
||||
|
||||
@@ -840,11 +840,10 @@ int OpenRecoveryScript::Restore_ADB_Backup(void) {
|
||||
pos = Restore_Name.find_last_of("/");
|
||||
Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
|
||||
part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
|
||||
part_settings.Restore_Name = path;
|
||||
part_settings.Backup_Folder = path;
|
||||
part_settings.partition_count = partition_count;
|
||||
part_settings.adbbackup = true;
|
||||
part_settings.adb_compression = twimghdr.compressed;
|
||||
part_settings.Backup_FileName = Backup_FileName;
|
||||
part_settings.PM_Method = PM_RESTORE;
|
||||
ProgressTracking progress(part_settings.total_restore_size);
|
||||
part_settings.progress = &progress;
|
||||
@@ -871,7 +870,6 @@ int OpenRecoveryScript::Restore_ADB_Backup(void) {
|
||||
pos = Restore_Name.find_last_of("/");
|
||||
Backup_FileName = Restore_Name.substr(pos + 1, Restore_Name.size());
|
||||
pos = Restore_Name.find_last_of("/");
|
||||
part_settings.Restore_Name = Restore_Name.substr(0, pos);
|
||||
part_settings.Part = PartitionManager.Find_Partition_By_Path(path);
|
||||
|
||||
if (path.compare("/system") == 0) {
|
||||
@@ -893,7 +891,6 @@ int OpenRecoveryScript::Restore_ADB_Backup(void) {
|
||||
part_settings.partition_count = partition_count;
|
||||
part_settings.adbbackup = true;
|
||||
part_settings.adb_compression = twimghdr.compressed;
|
||||
part_settings.Backup_FileName = Backup_FileName;
|
||||
part_settings.total_restore_size += part_settings.Part->Get_Restore_Size(&part_settings);
|
||||
part_settings.PM_Method = PM_RESTORE;
|
||||
ProgressTracking progress(part_settings.total_restore_size);
|
||||
|
||||
+22
-19
@@ -1621,7 +1621,7 @@ bool TWPartition::Check_MD5(PartitionSettings *part_settings) {
|
||||
sync();
|
||||
|
||||
memset(split_filename, 0, sizeof(split_filename));
|
||||
Full_Filename = part_settings->Restore_Name + "/" + part_settings->Backup_FileName;
|
||||
Full_Filename = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
if (!TWFunc::Path_Exists(Full_Filename)) {
|
||||
// This is a split archive, we presume
|
||||
sprintf(split_filename, "%s%03i", Full_Filename.c_str(), index);
|
||||
@@ -1662,7 +1662,7 @@ bool TWPartition::Check_MD5(PartitionSettings *part_settings) {
|
||||
|
||||
bool TWPartition::Restore(PartitionSettings *part_settings) {
|
||||
TWFunc::GUI_Operation_Text(TW_RESTORE_TEXT, Display_Name, gui_parse_text("{@restoring_hdr}"));
|
||||
LOGINFO("Restore filename is: %s/%s\n", part_settings->Restore_Name.c_str(), part_settings->Backup_FileName.c_str());
|
||||
LOGINFO("Restore filename is: %s%s\n", part_settings->Backup_Folder.c_str(), Backup_FileName.c_str());
|
||||
|
||||
string Restore_File_System = Get_Restore_File_System(part_settings);
|
||||
|
||||
@@ -1680,12 +1680,12 @@ string TWPartition::Get_Restore_File_System(PartitionSettings *part_settings) {
|
||||
string Restore_File_System;
|
||||
|
||||
// Parse backup filename to extract the file system before wiping
|
||||
first_period = part_settings->Backup_FileName.find(".");
|
||||
first_period = Backup_FileName.find(".");
|
||||
if (first_period == string::npos) {
|
||||
LOGERR("Unable to find file system (first period).\n");
|
||||
return string();
|
||||
}
|
||||
Restore_File_System = part_settings->Backup_FileName.substr(first_period + 1, part_settings->Backup_FileName.size() - first_period - 1);
|
||||
Restore_File_System = Backup_FileName.substr(first_period + 1, Backup_FileName.size() - first_period - 1);
|
||||
second_period = Restore_File_System.find(".");
|
||||
if (second_period == string::npos) {
|
||||
LOGERR("Unable to find file system (second period).\n");
|
||||
@@ -2167,14 +2167,14 @@ bool TWPartition::Backup_Tar(PartitionSettings *part_settings, pid_t *tar_fork_p
|
||||
#endif
|
||||
|
||||
Backup_FileName = Backup_Name + "." + Current_File_System + ".win";
|
||||
Full_FileName = part_settings->Full_Backup_Path + Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + Backup_FileName;
|
||||
tar.has_data_media = Has_Data_Media;
|
||||
tar.part_settings = part_settings;
|
||||
tar.setdir(Backup_Path);
|
||||
tar.setfn(Full_FileName);
|
||||
tar.setsize(Backup_Size);
|
||||
tar.partition_name = Backup_Name;
|
||||
tar.backup_folder = part_settings->Full_Backup_Path;
|
||||
tar.backup_folder = part_settings->Backup_Folder;
|
||||
if (tar.createTarFork(tar_fork_pid) != 0)
|
||||
return false;
|
||||
return true;
|
||||
@@ -2191,10 +2191,10 @@ bool TWPartition::Backup_Image(PartitionSettings *part_settings) {
|
||||
|
||||
if (part_settings->adbbackup) {
|
||||
Full_FileName = TW_ADB_BACKUP;
|
||||
adb_file_name = part_settings->Full_Backup_Path + "/" + Backup_FileName;
|
||||
adb_file_name = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
}
|
||||
else
|
||||
Full_FileName = part_settings->Full_Backup_Path + "/" + Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
|
||||
part_settings->total_restore_size = Backup_Size;
|
||||
|
||||
@@ -2227,14 +2227,14 @@ bool TWPartition::Raw_Read_Write(PartitionSettings *part_settings) {
|
||||
if (part_settings->adbbackup)
|
||||
destfn = TW_ADB_BACKUP;
|
||||
else
|
||||
destfn = part_settings->Full_Backup_Path + part_settings->Backup_FileName;
|
||||
destfn = part_settings->Backup_Folder + Backup_FileName;
|
||||
}
|
||||
else {
|
||||
destfn = Actual_Block_Device;
|
||||
if (part_settings->adbbackup) {
|
||||
srcfn = TW_ADB_RESTORE;
|
||||
} else {
|
||||
srcfn = part_settings->Restore_Name + "/" + part_settings->Backup_FileName;
|
||||
srcfn = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
Remain = TWFunc::Get_File_Size(srcfn);
|
||||
}
|
||||
}
|
||||
@@ -2315,7 +2315,7 @@ bool TWPartition::Backup_Dump_Image(PartitionSettings *part_settings) {
|
||||
part_settings->progress->SetPartitionSize(Backup_Size);
|
||||
|
||||
Backup_FileName = Backup_Name + "." + Current_File_System + ".win";
|
||||
Full_FileName = part_settings->Full_Backup_Path + "/" + Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
|
||||
Command = "dump_image " + MTD_Name + " '" + Full_FileName + "'";
|
||||
|
||||
@@ -2335,7 +2335,7 @@ bool TWPartition::Backup_Dump_Image(PartitionSettings *part_settings) {
|
||||
|
||||
unsigned long long TWPartition::Get_Restore_Size(PartitionSettings *part_settings) {
|
||||
if (!part_settings->adbbackup) {
|
||||
InfoManager restore_info(part_settings->Restore_Name + "/" + Backup_Name + ".info");
|
||||
InfoManager restore_info(part_settings->Backup_Folder + "/" + Backup_Name + ".info");
|
||||
if (restore_info.LoadValues() == 0) {
|
||||
if (restore_info.GetValue("backup_size", Restore_Size) == 0) {
|
||||
LOGINFO("Read info file, restore size is %llu\n", Restore_Size);
|
||||
@@ -2346,7 +2346,7 @@ unsigned long long TWPartition::Get_Restore_Size(PartitionSettings *part_setting
|
||||
|
||||
string Full_FileName, Restore_File_System = Get_Restore_File_System(part_settings);
|
||||
|
||||
Full_FileName = part_settings->Restore_Name + "/" + Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
if (Is_Image(Restore_File_System)) {
|
||||
Restore_Size = TWFunc::Get_File_Size(Full_FileName);
|
||||
return Restore_Size;
|
||||
@@ -2363,7 +2363,7 @@ unsigned long long TWPartition::Get_Restore_Size(PartitionSettings *part_setting
|
||||
tar.setpassword(Password);
|
||||
#endif
|
||||
tar.partition_name = Backup_Name;
|
||||
tar.backup_folder = part_settings->Restore_Name;
|
||||
tar.backup_folder = part_settings->Backup_Folder;
|
||||
tar.part_settings = part_settings;
|
||||
Restore_Size = tar.get_size();
|
||||
return Restore_Size;
|
||||
@@ -2395,7 +2395,7 @@ bool TWPartition::Restore_Tar(PartitionSettings *part_settings) {
|
||||
if (!ReMount_RW(true))
|
||||
return false;
|
||||
|
||||
Full_FileName = part_settings->Restore_Name + "/" + part_settings->Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
twrpTar tar;
|
||||
tar.part_settings = part_settings;
|
||||
tar.setdir(Backup_Path);
|
||||
@@ -2448,7 +2448,7 @@ bool TWPartition::Restore_Image(PartitionSettings *part_settings) {
|
||||
if (part_settings->adbbackup)
|
||||
Full_FileName = TW_ADB_RESTORE;
|
||||
else
|
||||
Full_FileName = part_settings->Full_Backup_Path + part_settings->Backup_FileName;
|
||||
Full_FileName = part_settings->Backup_Folder + Backup_FileName;
|
||||
|
||||
if (Restore_File_System == "emmc") {
|
||||
if (!part_settings->adbbackup)
|
||||
@@ -2607,9 +2607,12 @@ uint64_t TWPartition::Get_Max_FileSize() {
|
||||
bool TWPartition::Flash_Image(PartitionSettings *part_settings) {
|
||||
string Restore_File_System, full_filename;
|
||||
|
||||
full_filename = part_settings->Restore_Name + "/" + part_settings->Backup_FileName;
|
||||
if (part_settings->Part != NULL)
|
||||
full_filename = part_settings->Backup_Folder + "/" + Backup_FileName;
|
||||
else
|
||||
full_filename = part_settings->Backup_Folder; // Flash image action from GUI
|
||||
|
||||
LOGINFO("Image filename is: %s\n", part_settings->Backup_FileName.c_str());
|
||||
LOGINFO("Image filename is: %s\n", Backup_FileName.c_str());
|
||||
|
||||
if (Backup_Method == BM_FILES) {
|
||||
LOGERR("Cannot flash images to file systems\n");
|
||||
@@ -2625,7 +2628,7 @@ bool TWPartition::Flash_Image(PartitionSettings *part_settings) {
|
||||
unsigned long long image_size = TWFunc::Get_File_Size(full_filename);
|
||||
if (image_size > Size) {
|
||||
LOGINFO("Size (%llu bytes) of image '%s' is larger than target device '%s' (%llu bytes)\n",
|
||||
image_size, part_settings->Backup_FileName.c_str(), Actual_Block_Device.c_str(), Size);
|
||||
image_size, Backup_FileName.c_str(), Actual_Block_Device.c_str(), Size);
|
||||
gui_err("img_size_err=Size of image is larger than target device");
|
||||
return false;
|
||||
}
|
||||
|
||||
+20
-25
@@ -482,9 +482,11 @@ int TWPartitionManager::Check_Backup_Name(bool Display_Error) {
|
||||
|
||||
bool TWPartitionManager::Make_MD5(PartitionSettings *part_settings)
|
||||
{
|
||||
string command;
|
||||
string Full_File = part_settings->Full_Backup_Path + part_settings->Backup_FileName;
|
||||
string result;
|
||||
string command, result;
|
||||
|
||||
if (part_settings->Part == NULL)
|
||||
return false;
|
||||
string Full_File = part_settings->Backup_Folder + part_settings->Part->Backup_FileName;
|
||||
twrpDigest md5sum;
|
||||
|
||||
if (!part_settings->generate_md5)
|
||||
@@ -548,7 +550,6 @@ bool TWPartitionManager::Backup_Partition(PartitionSettings *part_settings) {
|
||||
TWFunc::SetPerformanceMode(true);
|
||||
time(&start);
|
||||
|
||||
part_settings->Backup_FileName = part_settings->Part->Backup_Name + "." + part_settings->Part->Current_File_System + ".win";
|
||||
if (part_settings->Part->Backup(part_settings, &tar_fork_pid)) {
|
||||
bool md5Success = false;
|
||||
if (part_settings->adbbackup) {
|
||||
@@ -563,9 +564,8 @@ bool TWPartitionManager::Backup_Partition(PartitionSettings *part_settings) {
|
||||
TWPartition *parentPart = part_settings->Part;
|
||||
|
||||
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
|
||||
part_settings->Part = *subpart;
|
||||
if ((*subpart)->Can_Be_Backed_Up && (*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == parentPart->Mount_Point) {
|
||||
part_settings->Backup_FileName = part_settings->Part->Backup_Name + "." + part_settings->Part->Current_File_System + ".win";
|
||||
part_settings->Part = *subpart;
|
||||
if (!(*subpart)->Backup(part_settings, &tar_fork_pid)) {
|
||||
TWFunc::SetPerformanceMode(false);
|
||||
Clean_Backup_Folder(part_settings->Backup_Folder);
|
||||
@@ -705,18 +705,18 @@ int TWPartitionManager::Run_Backup(bool adbbackup) {
|
||||
part_settings.generate_md5 = false;
|
||||
|
||||
DataManager::GetValue(TW_BACKUPS_FOLDER_VAR, part_settings.Backup_Folder);
|
||||
DataManager::GetValue(TW_BACKUP_NAME, part_settings.Backup_Name);
|
||||
if (part_settings.Backup_Name == gui_lookup("curr_date", "(Current Date)")) {
|
||||
part_settings.Backup_Name = TWFunc::Get_Current_Date();
|
||||
} else if (part_settings.Backup_Name == gui_lookup("auto_generate", "(Auto Generate)") || part_settings.Backup_Name == "0" || part_settings.Backup_Name.empty()) {
|
||||
DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
|
||||
if (Backup_Name == gui_lookup("curr_date", "(Current Date)")) {
|
||||
Backup_Name = TWFunc::Get_Current_Date();
|
||||
} else if (Backup_Name == gui_lookup("auto_generate", "(Auto Generate)") || Backup_Name == "0" || Backup_Name.empty()) {
|
||||
TWFunc::Auto_Generate_Backup_Name();
|
||||
DataManager::GetValue(TW_BACKUP_NAME, part_settings.Backup_Name);
|
||||
DataManager::GetValue(TW_BACKUP_NAME, Backup_Name);
|
||||
}
|
||||
|
||||
LOGINFO("Backup Name is: '%s'\n", part_settings.Backup_Name.c_str());
|
||||
part_settings.Full_Backup_Path = part_settings.Backup_Folder + "/" + part_settings.Backup_Name + "/";
|
||||
LOGINFO("Backup Name is: '%s'\n", Backup_Name.c_str());
|
||||
part_settings.Backup_Folder = part_settings.Backup_Folder + "/" + Backup_Name + "/";
|
||||
|
||||
LOGINFO("Full_Backup_Path is: '%s'\n", part_settings.Full_Backup_Path.c_str());
|
||||
LOGINFO("Full_Backup_Path is: '%s'\n", part_settings.Backup_Folder.c_str());
|
||||
|
||||
LOGINFO("Calculating backup details...\n");
|
||||
DataManager::GetValue("tw_backup_list", Backup_List);
|
||||
@@ -792,8 +792,8 @@ int TWPartitionManager::Run_Backup(bool adbbackup) {
|
||||
part_settings.file_bytes_remaining = part_settings.file_bytes;
|
||||
|
||||
gui_msg("backup_started=[BACKUP STARTED]");
|
||||
gui_msg(Msg("backup_folder= * Backup Folder: {1}")(part_settings.Full_Backup_Path));
|
||||
if (!TWFunc::Recursive_Mkdir(part_settings.Full_Backup_Path)) {
|
||||
gui_msg(Msg("backup_folder= * Backup Folder: {1}")(part_settings.Backup_Folder));
|
||||
if (!TWFunc::Recursive_Mkdir(part_settings.Backup_Folder)) {
|
||||
gui_err("fail_backup_folder=Failed to make backup folder.");
|
||||
return false;
|
||||
}
|
||||
@@ -836,7 +836,7 @@ int TWPartitionManager::Run_Backup(bool adbbackup) {
|
||||
|
||||
uint64_t actual_backup_size;
|
||||
if (!adbbackup)
|
||||
actual_backup_size = du.Get_Folder_Size(part_settings.Full_Backup_Path);
|
||||
actual_backup_size = du.Get_Folder_Size(part_settings.Backup_Folder);
|
||||
else
|
||||
actual_backup_size = part_settings.file_bytes + part_settings.img_bytes;
|
||||
actual_backup_size /= (1024LLU * 1024LLU);
|
||||
@@ -864,7 +864,7 @@ int TWPartitionManager::Run_Backup(bool adbbackup) {
|
||||
Update_System_Details();
|
||||
UnMount_Main_Partitions();
|
||||
gui_msg(Msg(msg::kHighlight, "backup_completed=[BACKUP COMPLETED IN {1} SECONDS]")(total_time)); // the end
|
||||
string backup_log = part_settings.Full_Backup_Path + "recovery.log";
|
||||
string backup_log = part_settings.Backup_Folder + "recovery.log";
|
||||
TWFunc::copy_file("/tmp/recovery.log", backup_log, 0644);
|
||||
tw_set_default_metadata(backup_log.c_str());
|
||||
|
||||
@@ -898,7 +898,6 @@ bool TWPartitionManager::Restore_Partition(PartitionSettings *part_settings) {
|
||||
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
|
||||
part_settings->Part = *subpart;
|
||||
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == parentPart->Mount_Point) {
|
||||
part_settings->Backup_FileName = (*subpart)->Backup_Name + "." + (*subpart)->Current_File_System + ".win";
|
||||
part_settings->Part = (*subpart);
|
||||
if (!(*subpart)->Restore(part_settings)) {
|
||||
TWFunc::SetPerformanceMode(false);
|
||||
@@ -924,7 +923,7 @@ int TWPartitionManager::Run_Restore(const string& Restore_Name) {
|
||||
string Restore_List, restore_path;
|
||||
size_t start_pos = 0, end_pos;
|
||||
|
||||
part_settings.Restore_Name = Restore_Name;
|
||||
part_settings.Backup_Folder = Restore_Name;
|
||||
part_settings.Part = NULL;
|
||||
part_settings.partition_count = 0;
|
||||
part_settings.total_restore_size = 0;
|
||||
@@ -954,7 +953,6 @@ int TWPartitionManager::Run_Restore(const string& Restore_Name) {
|
||||
restore_path = Restore_List.substr(start_pos, end_pos - start_pos);
|
||||
part_settings.Part = Find_Partition_By_Path(restore_path);
|
||||
if (part_settings.Part != NULL) {
|
||||
part_settings.Backup_FileName = part_settings.Part->Backup_Name + "." + part_settings.Part->Current_File_System + ".win";
|
||||
if (part_settings.Part->Mount_Read_Only) {
|
||||
gui_msg(Msg(msg::kError, "restore_read_only=Cannot restore {1} -- mounted read only.")(part_settings.Part->Backup_Display_Name));
|
||||
return false;
|
||||
@@ -969,7 +967,6 @@ int TWPartitionManager::Run_Restore(const string& Restore_Name) {
|
||||
std::vector<TWPartition*>::iterator subpart;
|
||||
|
||||
for (subpart = Partitions.begin(); subpart != Partitions.end(); subpart++) {
|
||||
part_settings.Backup_FileName = (*subpart)->Backup_Name + "." + (*subpart)->Current_File_System + ".win";
|
||||
part_settings.Part = *subpart;
|
||||
if ((*subpart)->Is_SubPartition && (*subpart)->SubPartition_Of == parentPart->Mount_Point) {
|
||||
if (check_md5 > 0 && !(*subpart)->Check_MD5(&part_settings))
|
||||
@@ -1006,8 +1003,6 @@ int TWPartitionManager::Run_Restore(const string& Restore_Name) {
|
||||
part_settings.Part = Find_Partition_By_Path(restore_path);
|
||||
if (part_settings.Part != NULL) {
|
||||
part_settings.partition_count++;
|
||||
part_settings.Backup_FileName = part_settings.Part->Backup_Name + "." + part_settings.Part->Current_File_System + ".win";
|
||||
part_settings.Full_Backup_Path = part_settings.Backup_Folder + "/" + part_settings.Backup_FileName + "/";
|
||||
if (!Restore_Partition(&part_settings))
|
||||
return false;
|
||||
} else {
|
||||
@@ -2259,7 +2254,7 @@ bool TWPartitionManager::Flash_Image(PartitionSettings *part_settings) {
|
||||
string Flash_List, flash_path, full_filename;
|
||||
size_t start_pos = 0, end_pos = 0;
|
||||
|
||||
full_filename = part_settings->Restore_Name + "/" + part_settings->Backup_FileName;
|
||||
full_filename = part_settings->Backup_Folder;
|
||||
|
||||
gui_msg("image_flash_start=[IMAGE FLASH STARTED]");
|
||||
gui_msg(Msg("img_to_flash=Image to flash: '{1}'")(full_filename));
|
||||
|
||||
+1
-5
@@ -44,11 +44,7 @@ class TWPartition;
|
||||
|
||||
struct PartitionSettings { // Settings for backup session
|
||||
TWPartition* Part; // Partition to pass to the partition backup loop
|
||||
std::string Backup_Folder; // Backup folder to put backup into
|
||||
std::string Full_Backup_Path; // Path to the current backup storage setting
|
||||
std::string Backup_Name; // Name of partition
|
||||
std::string Restore_Name; // Path to restore folder
|
||||
std::string Backup_FileName; // Name of the file to restore
|
||||
std::string Backup_Folder; // Path to restore folder
|
||||
bool adbbackup; // tell the system we are backing up over adb
|
||||
bool adb_compression; // 0 == uncompressed, 1 == compressed
|
||||
bool generate_md5; // tell system to create md5 for partitions
|
||||
|
||||
Reference in New Issue
Block a user