Skip to content

Commit

Permalink
scsidump can be used as a filter
Browse files Browse the repository at this point in the history
  • Loading branch information
uweseimet committed Nov 25, 2023
1 parent 4809fab commit 4565652
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 59 deletions.
114 changes: 62 additions & 52 deletions cpp/scsidump/scsidump_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,9 +178,6 @@ int ScsiDump::run(span<char*> args, bool in_process)
spdlog::set_level(level::off);
}

// When dumping to stdout use stderr instead of stdout for console output
ostream &console = to_stdout ? cerr : cout;

if (!Banner(args)) {
return EXIT_SUCCESS;
}
Expand Down Expand Up @@ -229,17 +226,17 @@ int ScsiDump::run(span<char*> args, bool in_process)
}

if (run_bus_scan) {
ScanBus(console);
ScanBus();
}
else if (run_inquiry) {
DisplayBoardId(console);
DisplayBoardId();

if (DisplayInquiry(console, false) && create_properties_file && !filename.empty()) {
inq_info.GeneratePropertiesFile(console, filename + ".properties");
if (DisplayInquiry(false) && create_properties_file && !filename.empty()) {
inq_info.GeneratePropertiesFile(filename + ".properties");
}
}
else {
if (const string error = DumpRestore(console); !error.empty()) {
if (const string error = DumpRestore(); !error.empty()) {
cerr << "Error: " << error << endl;
CleanUp();
return EXIT_FAILURE;
Expand All @@ -251,22 +248,24 @@ int ScsiDump::run(span<char*> args, bool in_process)
return EXIT_SUCCESS;
}

void ScsiDump::DisplayBoardId(ostream &console) const
void ScsiDump::DisplayBoardId() const
{
console << DIVIDER << "\nPiSCSI board ID is " << initiator_id << "\n";
if (!to_stdout) {
cout << DIVIDER << "\nPiSCSI board ID is " << initiator_id << "\n";
}
}

void ScsiDump::ScanBus(ostream &console)
void ScsiDump::ScanBus()
{
DisplayBoardId(console);
DisplayBoardId();

for (target_id = 0; target_id < ControllerManager::GetScsiIdMax(); target_id++) {
if (initiator_id == target_id) {
continue;
}

target_lun = 0;
if (!DisplayInquiry(console, false) || !scan_all_luns) {
if (!DisplayInquiry(false) || !scan_all_luns) {
// Continue with next ID if there is no LUN 0 or only LUN 0 should be scanned
continue;
}
Expand All @@ -277,14 +276,14 @@ void ScsiDump::ScanBus(ostream &console)

for (const auto lun : luns) {
target_lun = lun;
DisplayInquiry(console, false);
DisplayInquiry(false);
}
}
}

bool ScsiDump::DisplayInquiry(ostream &console, bool check_type)
bool ScsiDump::DisplayInquiry(bool check_type)
{
console << DIVIDER << "\nScanning target ID:LUN " << target_id << ":" << target_lun << "\n" << flush;
cout << DIVIDER << "\nScanning target ID:LUN " << target_id << ":" << target_lun << "\n" << flush;

inq_info = { };

Expand All @@ -305,26 +304,26 @@ bool ScsiDump::DisplayInquiry(ostream &console, bool check_type)
array<char, 17> str = { };
memcpy(str.data(), &buf[8], 8);
inq_info.vendor = string(str.data());
console << "Vendor: " << inq_info.vendor << "\n";
cout << "Vendor: " << inq_info.vendor << "\n";

str.fill(0);
memcpy(str.data(), &buf[16], 16);
inq_info.product = string(str.data());
console << "Product: " << inq_info.product << "\n";
cout << "Product: " << inq_info.product << "\n";

str.fill(0);
memcpy(str.data(), &buf[32], 4);
inq_info.revision = string(str.data());
console << "Revision: " << inq_info.revision << "\n" << flush;
cout << "Revision: " << inq_info.revision << "\n" << flush;

if (const auto &t = DEVICE_TYPES.find(type & byte { 0x1f }); t != DEVICE_TYPES.end()) {
console << "Device Type: " << (*t).second << "\n";
cout << "Device Type: " << (*t).second << "\n";
}
else {
console << "Device Type: Unknown\n";
cout << "Device Type: Unknown\n";
}

console << "Removable: " << (((static_cast<byte>(buf[1]) & byte { 0x80 }) == byte { 0x80 }) ? "Yes" : "No")
cout << "Removable: " << (((static_cast<byte>(buf[1]) & byte { 0x80 }) == byte { 0x80 }) ? "Yes" : "No")
<< "\n";

if (check_type && type != static_cast<byte>(device_type::direct_access) &&
Expand All @@ -337,9 +336,9 @@ bool ScsiDump::DisplayInquiry(ostream &console, bool check_type)
return true;
}

string ScsiDump::DumpRestore(ostream &console)
string ScsiDump::DumpRestore()
{
if (!GetDeviceInfo(console)) {
if (!GetDeviceInfo()) {
return "Can't get device information";
}

Expand All @@ -353,17 +352,19 @@ string ScsiDump::DumpRestore(ostream &console)

ostream &out = to_stdout ? cout : fs;

const auto effective_size = CalculateEffectiveSize(console);
const auto effective_size = CalculateEffectiveSize();
if (effective_size < 0) {
return "";
}
if (!effective_size) {
console << "Nothing to do, effective size is 0\n" << flush;
cerr << "Nothing to do, effective size is 0\n" << flush;
return "";
}

console << "Starting " << (restore ? "restore" : "dump") << ", buffer size is " << buffer.size()
<< " bytes\n\n" << flush;
if (!to_stdout) {
cout << "Starting " << (restore ? "restore" : "dump") << ", buffer size is " << buffer.size()
<< " bytes\n\n" << flush;
}

int sector_offset = 0;

Expand Down Expand Up @@ -393,8 +394,10 @@ string ScsiDump::DumpRestore(ostream &console)
sector_offset += sector_count;
remaining -= byte_count;

console << setw(3) << (effective_size - remaining) * 100 / effective_size << "% (" << effective_size - remaining
<< "/" << effective_size << ")\n" << flush;
if (!to_stdout) {
cout << setw(3) << (effective_size - remaining) * 100 / effective_size << "% (" << effective_size - remaining
<< "/" << effective_size << ")\n" << flush;
}
}

auto duration = chrono::duration_cast<chrono::seconds>(chrono::high_resolution_clock::now()
Expand All @@ -408,15 +411,17 @@ string ScsiDump::DumpRestore(ostream &console)
scsi_executor->SynchronizeCache();
}

console << DIVIDER << "\n";
console << "Transferred " << effective_size / 1024 / 1024 << " MiB (" << effective_size << " bytes)\n";
console << "Total time: " << duration << " seconds (" << duration / 60 << " minutes)\n";
console << "Average transfer rate: " << effective_size / duration << " bytes per second ("
<< effective_size / 1024 / duration << " KiB per second)\n";
console << DIVIDER << "\n" << flush;
if (!to_stdout) {
cout << DIVIDER
<< "\nTransferred " << effective_size / 1024 / 1024 << " MiB (" << effective_size << " bytes)"
<< "\nTotal time: " << duration << " seconds (" << duration / 60 << " minutes)"
<< "\nAverage transfer rate: " << effective_size / duration << " bytes per second ("
<< effective_size / 1024 / duration << " KiB per second)\n"
<< DIVIDER << "\n" << flush;
}

if (create_properties_file && !restore) {
inq_info.GeneratePropertiesFile(console, filename + ".properties");
inq_info.GeneratePropertiesFile(filename + ".properties");
}

return "";
Expand Down Expand Up @@ -449,7 +454,7 @@ string ScsiDump::ReadWrite(ostream &out, fstream &fs, int sector_offset, uint32_
return "";
}

long ScsiDump::CalculateEffectiveSize(ostream &console) const
long ScsiDump::CalculateEffectiveSize() const
{
const off_t disk_size = inq_info.capacity * inq_info.sector_size;

Expand All @@ -466,12 +471,15 @@ long ScsiDump::CalculateEffectiveSize(ostream &console) const

effective_size = min(size, disk_size);

console << "Restore image file size: " << size << " bytes\n" << flush;
if (!to_stdout) {
cout << "Restore image file size: " << size << " bytes\n" << flush;
}

if (size > disk_size) {
console << "Warning: Image file size of " << size
cerr << "Warning: Image file size of " << size
<< " byte(s) is larger than disk size of " << disk_size << " bytes(s)\n" << flush;
} else if (size < disk_size) {
console << "Warning: Image file size of " << size
cerr << "Warning: Image file size of " << size
<< " byte(s) is smaller than disk size of " << disk_size << " bytes(s)\n" << flush;
}
} else {
Expand All @@ -481,11 +489,11 @@ long ScsiDump::CalculateEffectiveSize(ostream &console) const
return static_cast<long>(effective_size);
}

bool ScsiDump::GetDeviceInfo(ostream &console)
bool ScsiDump::GetDeviceInfo()
{
DisplayBoardId(console);
DisplayBoardId();

if (!DisplayInquiry(console, true)) {
if (!DisplayInquiry(true)) {
return false;
}

Expand All @@ -501,17 +509,19 @@ bool ScsiDump::GetDeviceInfo(ostream &console)
inq_info.capacity = capacity;
inq_info.sector_size = sector_size;

console << "Sectors: " << capacity << "\n"
<< "Sector size: " << sector_size << " bytes\n"
<< "Capacity: " << sector_size * capacity / 1024 / 1024 << " MiB (" << sector_size * capacity
<< " bytes)\n"
<< DIVIDER << "\n\n"
<< flush;
if (!to_stdout) {
cout << "Sectors: " << capacity << "\n"
<< "Sector size: " << sector_size << " bytes\n"
<< "Capacity: " << sector_size * capacity / 1024 / 1024 << " MiB (" << sector_size * capacity
<< " bytes)\n"
<< DIVIDER << "\n\n"
<< flush;
}

return true;
}

void ScsiDump::inquiry_info::GeneratePropertiesFile(ostream &console, const string &properties_file) const
void ScsiDump::inquiry_info::GeneratePropertiesFile(const string &properties_file) const
{
ofstream prop(properties_file);

Expand All @@ -528,7 +538,7 @@ void ScsiDump::inquiry_info::GeneratePropertiesFile(ostream &console, const stri
cerr << "Error: Can't create properties file '" + properties_file + "': " << strerror(errno) << endl;
}
else {
console << "Created properties file '" + properties_file + "'\n" << flush;
cout << "Created properties file '" + properties_file + "'\n" << flush;
}
}

Expand Down
14 changes: 7 additions & 7 deletions cpp/scsidump/scsidump_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ScsiDump
uint32_t sector_size;
uint64_t capacity;

void GeneratePropertiesFile(ostream&, const string&) const;
void GeneratePropertiesFile(const string&) const;
};
using inquiry_info_t = struct inquiry_info;

Expand All @@ -46,13 +46,13 @@ class ScsiDump
bool Banner(span<char*>) const;
bool Init(bool);
void ParseArguments(span<char*>);
void DisplayBoardId(ostream&) const;
void DisplayBoardId() const;
string ReadWrite(ostream&, fstream&, int, uint32_t, int);
long CalculateEffectiveSize(ostream&) const;
void ScanBus(ostream&);
bool DisplayInquiry(ostream&, bool);
string DumpRestore(ostream&);
bool GetDeviceInfo(ostream&);
long CalculateEffectiveSize() const;
void ScanBus();
bool DisplayInquiry(bool);
string DumpRestore();
bool GetDeviceInfo();

bool SetLogLevel() const;

Expand Down

0 comments on commit 4565652

Please sign in to comment.