From 6b082447c52f6e2cc469ee9fc32a09403afcf379 Mon Sep 17 00:00:00 2001 From: Uwe Seimet <48174652+uweseimet@users.noreply.github.com> Date: Sun, 19 Sep 2021 23:27:47 +0200 Subject: [PATCH] protobuf interface cleanup (#244) * Repeated field cleanup * Renaming * Added DEVICE_TYPES_INFO * Comment update * Added -y option to rasctl * Updated rasctl help message --- doc/rasctl.1 | 4 + doc/rasctl_man_page.txt | 8 +- src/raspberrypi/rascsi.cpp | 57 ++++--- src/raspberrypi/rascsi_interface.proto | 51 +++--- src/raspberrypi/rasctl.cpp | 223 ++++++++++++++----------- 5 files changed, 200 insertions(+), 143 deletions(-) diff --git a/doc/rasctl.1 b/doc/rasctl.1 index 0afc03dc..f9c80f06 100644 --- a/doc/rasctl.1 +++ b/doc/rasctl.1 @@ -7,6 +7,7 @@ rasctl \- Sends management commands to the rascsi process \fB\-k\fR | \fB\-l\fR | \fB\-s\fR | +\fB\-y\fR | [\fB\-d\fR \fIIMAGE_FOLDER\fR] [\fB\-g\fR \fILOG_LEVEL\fR] [\fB\-h\fR \fIHOST\fR] @@ -64,6 +65,9 @@ Comma-separated list of IDs to reserve. .BR \-s\fI Display server-side settings like available images or supported device types. .TP +.BR \-y\fI +Display all device types and their properties. +.TP .BR \-v\fI " " \fI Display the rascsi version. .TP diff --git a/doc/rasctl_man_page.txt b/doc/rasctl_man_page.txt index 4c729faf..670860d7 100644 --- a/doc/rasctl_man_page.txt +++ b/doc/rasctl_man_page.txt @@ -6,9 +6,9 @@ NAME rasctl - Sends management commands to the rascsi process SYNOPSIS - rasctl -e | -k | -l | -s | [-d IMAGE_FOLDER] [-g LOG_LEVEL] [-h HOST] - [-p PORT] [-r RESERVED_IDS] [-v] -i ID [-c CMD] [-f FILE|PARAM] [-n - NAME] [-t TYPE] [-u UNIT] + rasctl -e | -k | -l | -s | -y | [-d IMAGE_FOLDER] [-g LOG_LEVEL] [-h + HOST] [-p PORT] [-r RESERVED_IDS] [-v] -i ID [-c CMD] [-f FILE|PARAM] + [-n NAME] [-t TYPE] [-u UNIT] DESCRIPTION rasctl Sends commands to the rascsi process to make configuration ad‐ @@ -56,6 +56,8 @@ OPTIONS -s Display server-side settings like available images or supported device types. + -y Display all device types and their properties. + -v Display the rascsi version. -w FILENAME diff --git a/src/raspberrypi/rascsi.cpp b/src/raspberrypi/rascsi.cpp index 2f1595a7..06a7c334 100644 --- a/src/raspberrypi/rascsi.cpp +++ b/src/raspberrypi/rascsi.cpp @@ -506,24 +506,24 @@ PbDeviceProperties *GetDeviceProperties(const Device *device) return properties; } -void GetDeviceTypeProperties(PbServerInfo& server_info, PbDeviceType type) +void GetDeviceTypeProperties(PbDeviceTypesInfo& device_types_info, PbDeviceType type) { - PbDeviceTypeProperties *types_properties = server_info.add_types_properties(); - types_properties->set_type(type); + PbDeviceTypeProperties *type_properties = device_types_info.add_properties(); + type_properties->set_type(type); Device *device = device_factory.CreateDevice(type, "", ""); - types_properties->set_allocated_properties(GetDeviceProperties(device)); + type_properties->set_allocated_properties(GetDeviceProperties(device)); delete device; } -void GetAllDeviceTypeProperties(PbServerInfo& server_info) +void GetAllDeviceTypeProperties(PbDeviceTypesInfo& device_types_info) { - GetDeviceTypeProperties(server_info, SAHD); - GetDeviceTypeProperties(server_info, SCHD); - GetDeviceTypeProperties(server_info, SCRM); - GetDeviceTypeProperties(server_info, SCMO); - GetDeviceTypeProperties(server_info, SCCD); - GetDeviceTypeProperties(server_info, SCBR); - GetDeviceTypeProperties(server_info, SCDP); + GetDeviceTypeProperties(device_types_info, SAHD); + GetDeviceTypeProperties(device_types_info, SCHD); + GetDeviceTypeProperties(device_types_info, SCRM); + GetDeviceTypeProperties(device_types_info, SCMO); + GetDeviceTypeProperties(device_types_info, SCCD); + GetDeviceTypeProperties(device_types_info, SCBR); + GetDeviceTypeProperties(device_types_info, SCDP); } void GetAvailableImages(PbServerInfo& server_info) @@ -608,15 +608,15 @@ void GetDevice(const Device *device, PbDevice *pb_device) void GetDevices(PbServerInfo& serverInfo) { for (const Device *device : devices) { - // skip if unit does not exist or is not assigned + // Skip if unit does not exist or is not assigned if (device) { - PbDevice *pb_device = serverInfo.add_devices(); + PbDevice *pb_device = serverInfo.mutable_devices()->add_devices(); GetDevice(device, pb_device); } } } -void GetDeviceInfo(const PbCommand& command, PbResult& result) +void GetDevicesInfo(const PbCommand& command, PbResult& result) { set id_sets; if (!command.devices_size()) { @@ -650,6 +650,14 @@ void GetDeviceInfo(const PbCommand& command, PbResult& result) } } +void GetDeviceTypesInfo(const PbCommand& command, PbResult& result) +{ + PbDeviceTypesInfo *device_types_info = new PbDeviceTypesInfo(); + GetAllDeviceTypeProperties(*device_types_info); + + result.set_allocated_device_types_info(device_types_info); +} + void GetServerInfo(PbResult& result) { PbServerInfo *server_info = new PbServerInfo(); @@ -659,7 +667,7 @@ void GetServerInfo(PbResult& result) server_info->set_patch_version(rascsi_patch_version); GetLogLevels(*server_info); server_info->set_current_log_level(current_log_level); - GetAllDeviceTypeProperties(*server_info); + GetAllDeviceTypeProperties(*server_info->mutable_device_types_info()); GetAvailableImages(*server_info); PbNetworkInterfacesInfo * network_interfaces_info = new PbNetworkInterfacesInfo(); server_info->set_allocated_network_interfaces_info(network_interfaces_info); @@ -1659,7 +1667,7 @@ bool ParseArgument(int argc, char* argv[], int& port) // Display and log the device list PbServerInfo server_info; GetDevices(server_info); - const list& devices = { server_info.devices().begin(), server_info.devices().end() }; + const list& devices = { server_info.devices().devices().begin(), server_info.devices().devices().end() }; const string device_list = ListDevices(devices); LogDevices(device_list); cout << device_list << endl; @@ -1760,12 +1768,12 @@ static void *MonThread(void *param) break; } - case DEVICE_INFO: { + case DEVICES_INFO: { LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); PbResult result; result.set_status(true); - GetDeviceInfo(command, result); + GetDevicesInfo(command, result); SerializeMessage(fd, result); const list& devices ={ result.device_info().devices().begin(), result.device_info().devices().end() }; @@ -1776,6 +1784,17 @@ static void *MonThread(void *param) break; } + case DEVICE_TYPES_INFO: { + LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); + + PbResult result; + result.set_status(true); + GetDeviceTypesInfo(command, result); + SerializeMessage(fd, result); + break; + } + + case SERVER_INFO: { LOGTRACE(string("Received " + PbOperation_Name(command.operation()) + " command").c_str()); diff --git a/src/raspberrypi/rascsi_interface.proto b/src/raspberrypi/rascsi_interface.proto index d8ddccaa..7edd6822 100644 --- a/src/raspberrypi/rascsi_interface.proto +++ b/src/raspberrypi/rascsi_interface.proto @@ -67,64 +67,67 @@ enum PbOperation { SERVER_INFO = 10; // Gets information on attached devices. Returns data for all attached devices if empty. - DEVICE_INFO = 11; + DEVICES_INFO = 11; + + // Device properties by device type + DEVICE_TYPES_INFO = 12; // Gets information on available image files. A lightweight alternative to getting the complete server info. - IMAGE_FILES_INFO = 12; + IMAGE_FILES_INFO = 13; // Gets the names of the available network interfaces. Only lists interfaces that are up. - NETWORK_INTERFACES_INFO = 13; + NETWORK_INTERFACES_INFO = 14; // Set the default folder for image files. // Parameters: // "folder": The default folder name. - DEFAULT_FOLDER = 14; + DEFAULT_FOLDER = 15; // Set server log level. // Parameters: // "level": The new log level - LOG_LEVEL = 15; + LOG_LEVEL = 16; // Block IDs from being used, usually the IDs of the initiators (computers) in the SCSI chain. // Parameters: // "ids": A comma-separated list of IDs to reserve, or an empty string in order not to reserve any ID. - RESERVE = 16; + RESERVE = 17; // Create an image file. The image file must not yet exist. // Parameters: // "file": The filename, relative to the default image folder. It must not contain a slash. // "size": The file size in bytes, must be a multiple of 512 // "read_only": "true" (case-insensitive) in order to create a read-only file, otherwise "false" - CREATE_IMAGE = 17; + CREATE_IMAGE = 18; // Delete an image file. // Parameters: // "file": The filename, relative to the default image folder. It must not contain a slash. - DELETE_IMAGE = 18; + DELETE_IMAGE = 19; // Rename an image file. // Parameters: // "from": The old filename, relative to the default image folder. It must not contain a slash. // "to": The new filename, relative to the default image folder. It must not contain a slash. // The new filename must not yet exist. - RENAME_IMAGE = 19; + RENAME_IMAGE = 20; // Copy an image file. // Parameters: // "from": The source filename, relative to the default image folder. It must not contain a slash. // "to": The destination filename, relative to the default image folder. It must not contain a slash. // The destination filename must not yet exist. - COPY_IMAGE = 20; + COPY_IMAGE = 21; // Write-protect an image file. // Parameters: - // "file": The filename, relative to the default image folder. It must not contain a slash. - PROTECT_IMAGE = 21; + // "file": The filename, relative to the default image folder. It must not contain a slash. + PROTECT_IMAGE = 22; // Make an image file writable. // Parameters: - // "file": The filename, relative to the default image folder. It must not contain a slash. - UNPROTECT_IMAGE = 22; + // "file": The filename, relative to the default image folder. It must not contain a slash. + UNPROTECT_IMAGE = 23; } // The properties supported by a device @@ -171,6 +174,10 @@ message PbDeviceTypeProperties { PbDeviceProperties properties = 2; } +message PbDeviceTypesInfo { + repeated PbDeviceTypeProperties properties = 1; +} + // The image file data message PbImageFile { string name = 1; @@ -251,10 +258,12 @@ message PbResult { PbServerInfo server_info = 3; // The result of a DEVICE_INFO command PbDevices device_info = 4; + // The result of a DEVICE_TYPES_INFO command + PbDeviceTypesInfo device_types_info = 5; // The result of an IMAGE_FILES_INFO command - PbImageFilesInfo image_files_info = 5; + PbImageFilesInfo image_files_info = 6; // The result of a NETWORK_INTERFACES_INFO command - PbNetworkInterfacesInfo network_interfaces_info = 6; + PbNetworkInterfacesInfo network_interfaces_info = 7; } } @@ -268,12 +277,14 @@ message PbServerInfo { // List of available log levels, ordered by increasing by severity repeated string log_levels = 4; string current_log_level = 5; - // Supported device types and their properties - repeated PbDeviceTypeProperties types_properties = 6; + // Supported device types and their properties, also available separately + PbDeviceTypesInfo device_types_info = 6; + // The image files in the default folder, also available separately PbImageFilesInfo image_files_info = 7; + // The available (up) network interfaces, also available separately PbNetworkInterfacesInfo network_interfaces_info = 8; - // The attached devices - repeated PbDevice devices = 9; + // The attached devices, also available separately + PbDevices devices = 9; // The unsorted list of reserved IDs repeated uint32 reserved_ids = 10; } diff --git a/src/raspberrypi/rasctl.cpp b/src/raspberrypi/rasctl.cpp index ae0008c5..966efe01 100644 --- a/src/raspberrypi/rasctl.cpp +++ b/src/raspberrypi/rasctl.cpp @@ -154,6 +154,104 @@ void DisplayDeviceInfo(const PbDevice& pb_device) cout << endl; } +void DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types_info) +{ + cout << "Supported device types and their properties:" << endl; + for (auto it = device_types_info.properties().begin(); it != device_types_info.properties().end(); ++it) { + cout << " " << PbDeviceType_Name(it->type()); + + const PbDeviceProperties& properties = it->properties(); + + cout << " Supported LUNs: " << properties.luns() << endl; + + if (properties.read_only() || properties.protectable() || properties.stoppable() || properties.read_only() + || properties.lockable()) { + cout << " Properties: "; + bool has_property = false; + if (properties.read_only()) { + cout << "read-only"; + has_property = true; + } + if (properties.protectable()) { + cout << (has_property ? ", " : "") << "protectable"; + has_property = true; + } + if (properties.stoppable()) { + cout << (has_property ? ", " : "") << "stoppable"; + has_property = true; + } + if (properties.removable()) { + cout << (has_property ? ", " : "") << "removable"; + has_property = true; + } + if (properties.lockable()) { + cout << (has_property ? ", " : "") << "lockable"; + } + cout << endl; + } + + if (properties.supports_file()) { + cout << " Image file support" << endl; + } + else if (properties.supports_params()) { + cout << " Parameter support" << endl; + } + + if (properties.supports_params() && properties.default_params_size()) { + map params = { properties.default_params().begin(), properties.default_params().end() }; + + cout << " Default parameters: "; + + bool isFirst = true; + for (const auto& param : params) { + if (!isFirst) { + cout << ", "; + } + cout << param.first << "=" << param.second; + + isFirst = false; + } + cout << endl; + } + + if (properties.block_sizes_size()) { + list block_sizes = { properties.block_sizes().begin(), properties.block_sizes().end() }; + block_sizes.sort([](const auto& a, const auto& b) { return a < b; }); + + cout << " Configurable block sizes in bytes: "; + + bool isFirst = true; + for (const auto& block_size : block_sizes) { + if (!isFirst) { + cout << ", "; + } + cout << block_size; + + isFirst = false; + } + cout << endl; + } + + if (properties.capacities_size()) { + list capacities = { properties.capacities().begin(), properties.capacities().end() }; + capacities.sort([](const auto& a, const auto& b) { return a < b; }); + + cout << " Media capacities in bytes: "; + + bool isFirst = true; + for (const auto& capacity : capacities) { + if (!isFirst) { + cout << ", "; + } + cout << capacity; + + isFirst = false; + } + cout << endl; + } + } +} + void DisplayImageFiles(const list image_files, const string& default_image_folder) { cout << "Default image file folder: " << default_image_folder << endl; @@ -201,7 +299,7 @@ void DisplayNetworkInterfaces(list interfaces) void CommandList(const string& hostname, int port) { PbCommand command; - command.set_operation(DEVICE_INFO); + command.set_operation(DEVICES_INFO); PbResult result; SendCommand(hostname.c_str(), port, command, result); @@ -310,6 +408,14 @@ void CommandDeviceInfo(const PbCommand& command, const string& hostname, int por } } +void CommandDeviceTypesInfo(const PbCommand& command, const string& hostname, int port) +{ + PbResult result; + SendCommand(hostname.c_str(), port, command, result); + + DisplayDeviceTypesInfo(result.device_types_info()); +} + void CommandServerInfo(PbCommand& command, const string& hostname, int port) { PbResult result; @@ -346,100 +452,7 @@ void CommandServerInfo(PbCommand& command, const string& hostname, int port) { server_info.network_interfaces_info().name().begin(), server_info.network_interfaces_info().name().end() }; DisplayNetworkInterfaces(network_interfaces); - cout << "Supported device types and their properties:" << endl; - for (auto it = server_info.types_properties().begin(); it != server_info.types_properties().end(); ++it) { - cout << " " << PbDeviceType_Name(it->type()); - - const PbDeviceProperties& properties = it->properties(); - - cout << " Supported LUNs: " << properties.luns() << endl; - - if (properties.read_only() || properties.protectable() || properties.stoppable() || properties.read_only() - || properties.lockable()) { - cout << " Properties: "; - bool has_property = false; - if (properties.read_only()) { - cout << "read-only"; - has_property = true; - } - if (properties.protectable()) { - cout << (has_property ? ", " : "") << "protectable"; - has_property = true; - } - if (properties.stoppable()) { - cout << (has_property ? ", " : "") << "stoppable"; - has_property = true; - } - if (properties.removable()) { - cout << (has_property ? ", " : "") << "removable"; - has_property = true; - } - if (properties.lockable()) { - cout << (has_property ? ", " : "") << "lockable"; - } - cout << endl; - } - - if (properties.supports_file()) { - cout << " Image file support" << endl; - } - else if (properties.supports_params()) { - cout << " Parameter support" << endl; - } - - if (properties.supports_params() && properties.default_params_size()) { - map params = { properties.default_params().begin(), properties.default_params().end() }; - - cout << " Default parameters: "; - - bool isFirst = true; - for (const auto& param : params) { - if (!isFirst) { - cout << ", "; - } - cout << param.first << "=" << param.second; - - isFirst = false; - } - cout << endl; - } - - if (properties.block_sizes_size()) { - list block_sizes = { properties.block_sizes().begin(), properties.block_sizes().end() }; - block_sizes.sort([](const auto& a, const auto& b) { return a < b; }); - - cout << " Configurable block sizes in bytes: "; - - bool isFirst = true; - for (const auto& block_size : block_sizes) { - if (!isFirst) { - cout << ", "; - } - cout << block_size; - - isFirst = false; - } - cout << endl; - } - - if (properties.capacities_size()) { - list capacities = { properties.capacities().begin(), properties.capacities().end() }; - capacities.sort([](const auto& a, const auto& b) { return a < b; }); - - cout << " Media capacities in bytes: "; - - bool isFirst = true; - for (const auto& capacity : capacities) { - if (!isFirst) { - cout << ", "; - } - cout << capacity; - - isFirst = false; - } - cout << endl; - } - } + DisplayDeviceTypesInfo(server_info.device_types_info()); if (server_info.reserved_ids_size()) { cout << "Reserved device IDs: "; @@ -452,8 +465,8 @@ void CommandServerInfo(PbCommand& command, const string& hostname, int port) cout < sorted_devices = { server_info.devices().begin(), server_info.devices().end() }; + if (server_info.devices().devices_size()) { + list sorted_devices = { server_info.devices().devices().begin(), server_info.devices().devices().end() }; sorted_devices.sort([](const auto& a, const auto& b) { return a.id() < b.id(); }); cout << "Attached devices:" << endl; @@ -506,7 +519,7 @@ PbOperation ParseOperation(const char *optarg) return UNPROTECT; case 's': - return DEVICE_INFO; + return DEVICES_INFO; default: return NONE; @@ -564,7 +577,7 @@ int main(int argc, char* argv[]) cerr << "Usage: " << argv[0] << " -i ID [-u UNIT] [-c CMD] [-t TYPE] [-b BLOCK_SIZE] [-n NAME] [-f FILE|PARAM] "; cerr << "[-d IMAGE_FOLDER] [-g LOG_LEVEL] [-h HOST] [-p PORT] [-r RESERVED_IDS] "; cerr << "[-a FILENAME:FILESIZE] [-w FILENAME] [-m CURRENT_NAME:NEW_NAME] [-x CURRENT_NAME:NEW_NAME] "; - cerr << "[-e] [-k] [-l] [-v]" << endl; + cerr << "[-e] [-k] [-l] [-v] [-y]" << endl; cerr << " where ID := {0-7}" << endl; cerr << " UNIT := {0|1}, default is 0" << endl; cerr << " CMD := {attach|detach|insert|eject|protect|unprotect|show}" << endl; @@ -600,7 +613,7 @@ int main(int argc, char* argv[]) opterr = 1; int opt; - while ((opt = getopt(argc, argv, "a:b:c:d:f:g:h:i:m:n:p:r:t:u:x:w:eklsv")) != -1) { + while ((opt = getopt(argc, argv, "a:b:c:d:f:g:h:i:m:n:p:r:t:u:x:w:eklsvy")) != -1) { switch (opt) { case 'i': device->set_id(optarg[0] - '0'); @@ -730,6 +743,10 @@ int main(int argc, char* argv[]) image_params = optarg; break; + case 'y': + command.set_operation(DEVICE_TYPES_INFO); + break; + case 'w': command.set_operation(DELETE_IMAGE); image_params = optarg; @@ -770,10 +787,14 @@ int main(int argc, char* argv[]) CommandCopyImage(command, hostname, port, image_params); exit(EXIT_SUCCESS); - case DEVICE_INFO: + case DEVICES_INFO: CommandDeviceInfo(command, hostname, port); exit(EXIT_SUCCESS); + case DEVICE_TYPES_INFO: + CommandDeviceTypesInfo(command, hostname, port); + exit(EXIT_SUCCESS); + case SERVER_INFO: CommandServerInfo(command, hostname, port); exit(EXIT_SUCCESS);