Added DEVICE_INFO to protobuf interface

This commit is contained in:
Uwe Seimet 2021-09-04 00:31:16 +02:00
parent f433999b7d
commit 887508bb56
7 changed files with 150 additions and 90 deletions

View File

@ -53,13 +53,14 @@ Display the rascsi version.
ID is the SCSI ID that you want to control. (0-7)
.TP
.BR \-c\fI " " \fICMD
Command is the operation being requested. options are:
attach: attach disk
detach: detach disk
insert: insert media (removable media devices only)
eject: eject media (removable media devices only)
protect: write protect the media (not for CD-ROMs, which are always read-only)
unprotect: remove write protection from the media (not for CD-ROMs, which are always read-only)
Command is the operation being requested. Options are:
a(ttach): Attach disk
d(etach): Detach disk
i(nsert): Insert media (removable media devices only)
e(ject): Eject media (removable media devices only)
p(rotect): Write protect the medium (not for CD-ROMs, which are always read-only)
u(nprotect): Remove write protection from the medium (not for CD-ROMs, which are always read-only)
s(how): Display device information
.IP
eject, protect and unprotect are idempotent.
.TP

View File

@ -43,15 +43,16 @@ OPTIONS
-i ID ID is the SCSI ID that you want to control. (0-7)
-c CMD Command is the operation being requested. options are:
attach: attach disk
detach: detach disk
insert: insert media (removable media devices only)
eject: eject media (removable media devices only)
protect: write protect the media (not for CD-ROMs, which are
always read-only)
unprotect: remove write protection from the media (not for
-c CMD Command is the operation being requested. Options are:
a(ttach): Attach disk
d(etach): Detach disk
i(nsert): Insert media (removable media devices only)
e(ject): Eject media (removable media devices only)
p(rotect): Write protect the medium (not for CD-ROMs, which
are always read-only)
u(nprotect): Remove write protection from the medium (not for
CD-ROMs, which are always read-only)
s(how): Display device information
eject, protect and unprotect are idempotent.

View File

@ -270,7 +270,7 @@ void SCSIDEV::Execute()
if ((SCSIDEV::scsi_command)ctrl.cmd[0] == eCmdInquiry) {
// SCSI-2 p.104 4.4.3 Incorrect logical unit handling
if (((ctrl.cmd[1] >> 5) & 0x07) != ctrl.device->GetLun()) {
if (((ctrl.cmd[1] >> 5) & 0x07) != (DWORD)ctrl.device->GetLun()) {
ctrl.buffer[0] = 0x7f;
}
}

View File

@ -76,8 +76,8 @@ private:
bool block_size_configurable;
// Device ID and LUN
unsigned int id;
unsigned int lun;
int32_t id;
int32_t lun;
string vendor;
string product;
@ -123,10 +123,10 @@ public:
bool IsLocked() const { return locked; }
void SetLocked(bool locked) { this->locked = locked; }
unsigned int GetId() const { return id; }
void SetId(unsigned int id) { this->id = id; }
unsigned int GetLun() const { return lun; }
void SetLun(unsigned int lun) { this->lun = lun; }
int32_t GetId() const { return id; }
void SetId(int32_t id) { this->id = id; }
int32_t GetLun() const { return lun; }
void SetLun(int32_t lun) { this->lun = lun; }
const string GetVendor() const { return vendor; }
void SetVendor(const string&);

View File

@ -265,52 +265,54 @@ void GetImageFile(PbImageFile *image_file, const string& filename)
}
}
void GetDevice(const Device *device, PbDevice *pb_device)
{
pb_device->set_id(device->GetId());
pb_device->set_unit(device->GetLun());
pb_device->set_vendor(device->GetVendor());
pb_device->set_product(device->GetProduct());
pb_device->set_revision(device->GetRevision());
PbDeviceType type = UNDEFINED;
PbDeviceType_Parse(device->GetType(), &type);
pb_device->set_type(type);
PbDeviceProperties *properties = new PbDeviceProperties();
pb_device->set_allocated_properties(properties);
properties->set_read_only(device->IsReadOnly());
properties->set_protectable(device->IsProtectable());
properties->set_removable(device->IsRemovable());
properties->set_lockable(device->IsLockable());
PbDeviceStatus *status = new PbDeviceStatus();
pb_device->set_allocated_status(status);
status->set_protected_(device->IsProtected());
status->set_removed(device->IsRemoved());
status->set_locked(device->IsLocked());
const Disk *disk = dynamic_cast<const Disk*>(device);
if (disk) {
pb_device->set_block_size(disk->GetSectorSizeInBytes());
}
const FileSupport *file_support = dynamic_cast<const FileSupport *>(device);
if (file_support) {
Filepath filepath;
file_support->GetPath(filepath);
PbImageFile *image_file = new PbImageFile();
GetImageFile(image_file, device->IsRemovable() && !device->IsReady() ? "" : filepath.GetPath());
pb_device->set_allocated_file(image_file);
properties->set_supports_file(true);
}
}
void GetDevices(PbServerInfo& serverInfo)
{
for (size_t i = 0; i < devices.size(); i++) {
// skip if unit does not exist or null disk
Device *device = devices[i];
if (!device) {
continue;
}
PbDevice *pb_device = serverInfo.add_devices();
pb_device->set_id(i / UnitNum);
pb_device->set_unit(i % UnitNum);
pb_device->set_vendor(device->GetVendor());
pb_device->set_product(device->GetProduct());
pb_device->set_revision(device->GetRevision());
PbDeviceType type = UNDEFINED;
PbDeviceType_Parse(device->GetType(), &type);
pb_device->set_type(type);
PbDeviceProperties *properties = new PbDeviceProperties();
pb_device->set_allocated_properties(properties);
properties->set_read_only(device->IsReadOnly());
properties->set_protectable(device->IsProtectable());
properties->set_removable(device->IsRemovable());
properties->set_lockable(device->IsLockable());
PbDeviceStatus *status = new PbDeviceStatus();
pb_device->set_allocated_status(status);
status->set_protected_(device->IsProtected());
status->set_removed(device->IsRemoved());
status->set_locked(device->IsLocked());
const Disk *disk = dynamic_cast<Disk*>(device);
if (disk) {
pb_device->set_block_size(disk->GetSectorSizeInBytes());
}
const FileSupport *file_support = dynamic_cast<FileSupport *>(device);
if (file_support) {
Filepath filepath;
file_support->GetPath(filepath);
PbImageFile *image_file = new PbImageFile();
GetImageFile(image_file, device->IsRemovable() && !device->IsReady() ? "" : filepath.GetPath());
pb_device->set_allocated_file(image_file);
properties->set_supports_file(true);
if (device) {
PbDevice *pb_device = serverInfo.add_devices();
GetDevice(device, pb_device);
}
}
}
@ -1316,6 +1318,20 @@ static void *MonThread(void *param)
break;
}
case DEVICE_INFO: {
PbDevice pb_device;
for (size_t i = 0; i < devices.size(); i++) {
Device *device = devices[i];
if (device && device->GetId() == command.devices(0).id() && device->GetLun() == command.devices(0).unit()) {
GetDevice(device, &pb_device);
break;
}
}
SerializeMessage(fd, pb_device);
break;
}
case SERVER_INFO: {
PbServerInfo server_info;
server_info.set_major_version(rascsi_major_version);

View File

@ -26,32 +26,35 @@ enum PbDeviceType {
SCDP = 7;
}
// rascsi remote operations
// rascsi remote operations. PbResult is returned, except for SERVER_INFO and DEVICE_INFO.
enum PbOperation {
NONE = 0;
// Returns the server information
// Bets the server information. Returns PbServerInfo.
SERVER_INFO = 1;
// Gets information on a particular device. Returns PbDevice.
// If the device does on exist the returned device type is UNDEFINED.
DEVICE_INFO = 2;
// Set the default folder for image files, PbCommand.params contains the folder name
DEFAULT_FOLDER = 2;
DEFAULT_FOLDER = 3;
// Set server log level, PbCommand.params contains the log level
LOG_LEVEL = 3;
LOG_LEVEL = 4;
// Attach new device
ATTACH = 4;
ATTACH = 5;
// Detach device
DETACH = 5;
DETACH = 6;
// Detach all devices, does not require a device list
DETACH_ALL = 6;
DETACH_ALL = 7;
// Insert medium
INSERT = 7;
INSERT = 8;
// Eject medium
EJECT = 8;
EJECT = 9;
// Write-protect medium (not possible for read-only media)
PROTECT = 9;
PROTECT = 10;
// Make medium writable (not possible for read-only media)
UNPROTECT = 10;
UNPROTECT = 11;
// IDs blocked from being used, usually the ID of the initiator (computer) in the SCSI chain.
// The command params field contains the full list of IDs to reserve, or is empty in order to allow all IDs.
RESERVE = 11;
RESERVE = 12;
}
// The properties supported by a device, helping clients to offer a good user experience

View File

@ -103,21 +103,36 @@ bool ReceiveResult(int fd)
return true;
}
void DisplayDeviceInfo(const PbDevice& pb_device)
{
cout << " " << pb_device.id() << ":" << pb_device.unit() << " " << PbDeviceType_Name(pb_device.type())
<< " " << pb_device.vendor() << ":" << pb_device.product() << ":" << pb_device.revision();
if (pb_device.block_size()) {
cout << " " << pb_device.block_size() << " BPS";
}
cout << (pb_device.file().name().empty() ? "" : " " + pb_device.file().name());
if (pb_device.properties().read_only() || pb_device.status().protected_()) {
cout << " read-only";
}
cout <<endl;
}
//---------------------------------------------------------------------------
//
// Command implementations
//
//---------------------------------------------------------------------------
const PbServerInfo GetServerInfo(const string&hostname, int port) {
const PbServerInfo GetServerInfo(const string& hostname, int port)
{
PbCommand command;
command.set_operation(SERVER_INFO);
int fd = SendCommand(hostname.c_str(), port, command);
PbServerInfo serverInfo;
PbServerInfo server_info;
try {
DeserializeMessage(fd, serverInfo);
DeserializeMessage(fd, server_info);
}
catch(const io_exception& e) {
cerr << "Error: " << e.getmsg() << endl;
@ -129,7 +144,7 @@ const PbServerInfo GetServerInfo(const string&hostname, int port) {
close(fd);
return serverInfo;
return server_info;
}
void CommandList(const string& hostname, int port)
@ -177,6 +192,32 @@ void CommandDefaultImageFolder(const string& hostname, int port, const string& f
close(fd);
}
void CommandDeviceInfo(const string& hostname, int port, const PbCommand& command)
{
int fd = SendCommand(hostname.c_str(), port, command);
PbDevice pb_device;
try {
DeserializeMessage(fd, pb_device);
}
catch(const io_exception& e) {
cerr << "Error: " << e.getmsg() << endl;
close(fd);
exit(EXIT_FAILURE);
}
close(fd);
if (pb_device.type() == UNDEFINED) {
cerr << "Error: Unknown device ID or unit" << endl;
}
else {
DisplayDeviceInfo(pb_device);
}
}
void CommandServerInfo(const string& hostname, int port)
{
PbCommand command;
@ -332,16 +373,7 @@ void CommandServerInfo(const string& hostname, int port)
cout << "Attached devices:" << endl;
for (const auto& device : sorted_devices) {
cout << " " << device.id() << ":" << device.unit() << " " << PbDeviceType_Name(device.type())
<< " " << device.vendor() << ":" << device.product() << ":" << device.revision();
if (device.block_size()) {
cout << " " << device.block_size() << " BPS";
}
cout << (device.file().name().empty() ? "" : " " + device.file().name());
if (device.properties().read_only() || device.status().protected_()) {
cout << " read-only";
}
cout <<endl;
DisplayDeviceInfo(device);
}
}
}
@ -367,6 +399,9 @@ PbOperation ParseOperation(const char *optarg)
case 'u':
return UNPROTECT;
case 's':
return DEVICE_INFO;
default:
return NONE;
}
@ -424,7 +459,7 @@ int main(int argc, char* argv[])
cerr << "[-d DEFAULT_IMAGE_FOLDER] [-g LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] [-l] [-v]" << endl;
cerr << " where ID := {0|1|2|3|4|5|6|7}" << endl;
cerr << " UNIT := {0|1}, default setting is 0." << endl;
cerr << " CMD := {attach|detach|insert|eject|protect|unprotect}" << endl;
cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl;
cerr << " TYPE := {sahd|schd|scrm|sccd|scmo|scbr|scdp} or convenience type {hd|rm|mo|cd|bridge|daynaport}" << endl;
cerr << " BLOCK_SIZE := {256|512|1024|2048|4096) bytes per hard disk drive block" << endl;
cerr << " NAME := name of device to attach (VENDOR:PRODUCT:REVISION)" << endl;
@ -577,6 +612,10 @@ int main(int argc, char* argv[])
CommandReserve(hostname, port, reserved_ids);
exit(EXIT_SUCCESS);
case DEVICE_INFO:
CommandDeviceInfo(hostname, port, command);
exit(EXIT_SUCCESS);
case SERVER_INFO:
CommandServerInfo(hostname, port);
exit(EXIT_SUCCESS);