mirror of
https://github.com/akuker/RASCSI.git
synced 2025-01-03 01:33:14 +00:00
Added DEVICE_INFO to protobuf interface
This commit is contained in:
parent
f433999b7d
commit
887508bb56
15
doc/rasctl.1
15
doc/rasctl.1
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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&);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user