Create devices after bus creation (#954)

This commit is contained in:
akuker 2022-11-02 08:58:59 -05:00 committed by GitHub
parent 621cc7d5a2
commit 31dd063611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 116 additions and 88 deletions

3
.gitignore vendored
View File

@ -27,6 +27,9 @@ s.sh
# temporary kicad files
*-backups
# VSCode temp file
settings.json
# submodules
hfdisk*
mac-hard-disk-drivers

View File

@ -1,16 +0,0 @@
{
"files.associations": {
"cstddef": "cpp",
"array": "cpp",
"chrono": "cpp",
"functional": "cpp",
"istream": "cpp",
"ostream": "cpp",
"ratio": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"cstdint": "cpp",
"stdexcept": "cpp"
}
}

View File

@ -39,6 +39,7 @@
#include <fstream>
#include <list>
#include <map>
#include <deque>
using namespace std;
using namespace spdlog;
@ -71,6 +72,9 @@ shared_ptr<RascsiResponse> rascsi_response;
shared_ptr<RascsiExecutor> executor;
const ProtobufSerializer serializer;
using optarg_value_type = std::pair<int,string>;
using optarg_queue_type = std::deque<optarg_value_type>;
void Banner(int argc, char* argv[])
{
cout << Banner("Reloaded");
@ -204,40 +208,32 @@ bool ProcessId(const string& id_spec, int& id, int& unit)
return true;
}
bool ParseArgument(int argc, char* argv[], int& port)
bool ParseArgument(int argc, char* argv[], int& port, optarg_queue_type& post_process)
{
PbCommand command;
int id = -1;
int unit = -1;
PbDeviceType type = UNDEFINED;
int block_size = 0;
string name;
string log_level;
const char *locale = setlocale(LC_MESSAGES, "");
if (locale == nullptr || !strcmp(locale, "C")) {
locale = "en";
}
opterr = 1;
int opt;
while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:")) != -1) {
while ((opt = getopt(argc, argv, "-Iib:d:n:p:r:t:z:D:F:L:P:R:C:v")) != -1) {
switch (opt) {
// The two options below are kind of a compound option with two letters
// The following options can not be processed until AFTER
// the 'bus' object is created and configured
case 'i':
case 'I':
id = -1;
unit = -1;
continue;
case 'd':
case 'D': {
if (!ProcessId(optarg, id, unit)) {
return false;
}
case 'D':
case 'R':
case 'n':
case 'r':
case 't':
case 'F':
case 'z':
{
string optarg_str = (optarg == nullptr) ? "" : string(optarg);
post_process.push_back(optarg_value_type(opt,optarg_str));
continue;
}
case 'b': {
if (!GetAsInt(optarg, block_size)) {
cerr << "Invalid block size " << optarg << endl;
@ -246,33 +242,8 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue;
}
case 'z':
locale = optarg;
continue;
case 'F': {
if (const string result = rascsi_image.SetDefaultFolder(optarg); !result.empty()) {
cerr << result << endl;
return false;
}
continue;
}
case 'L':
log_level = optarg;
continue;
case 'R':
int depth;
if (!GetAsInt(optarg, depth) || depth < 0) {
cerr << "Invalid image file scan depth " << optarg << endl;
return false;
}
rascsi_image.SetDepth(depth);
continue;
case 'n':
name = optarg;
current_log_level = optarg;
continue;
case 'p':
@ -287,9 +258,91 @@ bool ParseArgument(int argc, char* argv[], int& port)
return false;
}
continue;
case 'v':
cout << rascsi_get_version_string() << endl;
exit(0);
case 1:
{
// Encountered filename
string optarg_str = (optarg == nullptr) ? "" : string(optarg);
post_process.push_back(optarg_value_type(opt,optarg_str));
continue;
}
default:
return false;
}
if (optopt) {
return false;
}
}
return true;
}
static bool CreateInitialDevices(optarg_queue_type& optarg_queue){
PbCommand command;
int id = -1;
int unit = -1;
PbDeviceType type = UNDEFINED;
int block_size = 0;
string name;
string log_level;
const char *locale = setlocale(LC_MESSAGES, "");
if (locale == nullptr || !strcmp(locale, "C")) {
locale = "en";
}
opterr = 1;
for(auto current_arg : optarg_queue){
switch (current_arg.first) {
// The two options below are kind of a compound option with two letters
case 'i':
case 'I':
id = -1;
unit = -1;
continue;
case 'd':
case 'D': {
if (!ProcessId(current_arg.second, id, unit)) {
return false;
}
continue;
}
case 'z':
locale = current_arg.second.c_str();
continue;
case 'F': {
if (const string result = rascsi_image.SetDefaultFolder(current_arg.second); !result.empty()) {
cerr << result << endl;
return false;
}
continue;
}
case 'R':
int depth;
if (!GetAsInt(current_arg.second, depth) || depth < 0) {
cerr << "Invalid image file scan depth " << current_arg.second << endl;
return false;
}
rascsi_image.SetDepth(depth);
continue;
case 'n':
name = current_arg.second;
continue;
case 'r': {
string error = executor->SetReservedIds(optarg);
string error = executor->SetReservedIds(current_arg.second);
if (!error.empty()) {
cerr << error << endl;
return false;
@ -298,10 +351,10 @@ bool ParseArgument(int argc, char* argv[], int& port)
continue;
case 't': {
string t = optarg;
string t = current_arg.second;
transform(t.begin(), t.end(), t.begin(), ::toupper);
if (!PbDeviceType_Parse(t, &type)) {
cerr << "Illegal device type '" << optarg << "'" << endl;
cerr << "Illegal device type '" << current_arg.second << "'" << endl;
return false;
}
}
@ -310,13 +363,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
case 1:
// Encountered filename
break;
default:
return false;
}
if (optopt) {
return false;
}
// Set up the device data
@ -326,7 +372,7 @@ bool ParseArgument(int argc, char* argv[], int& port)
device->set_type(type);
device->set_block_size(block_size);
ParseParameters(*device, optarg);
ParseParameters(*device, current_arg.second);
if (size_t separator_pos = name.find(COMPONENT_SEPARATOR); separator_pos != string::npos) {
device->set_vendor(name.substr(0, separator_pos));
@ -350,10 +396,6 @@ bool ParseArgument(int argc, char* argv[], int& port)
name = "";
}
if (!log_level.empty() && executor->SetLogLevel(log_level)) {
current_log_level = log_level;
}
// Attach all specified devices
command.set_operation(ATTACH);
@ -522,6 +564,7 @@ static bool ExecuteCommand(const CommandContext& context, PbCommand& command)
int main(int argc, char* argv[])
{
optarg_queue_type optarg_queue;
GOOGLE_PROTOBUF_VERIFY_VERSION;
// added setvbuf to override stdout buffering, so logs are written immediately and not when the process exits.
@ -530,15 +573,12 @@ int main(int argc, char* argv[])
// Output the Banner
Banner(argc, argv);
// ParseArgument() requires the bus to have been initialized first, which requires the root user.
// The -v option should be available for any user, which requires special handling.
for (int i = 1 ; i < argc; i++) {
if (!strcasecmp(argv[i], "-v")) {
cout << rascsi_get_version_string() << endl;
return 0;
}
int port = DEFAULT_PORT;
if (!ParseArgument(argc, argv, port, optarg_queue)) {
return -1;
}
// Note that current_log_level may have been modified by ParseArgument()
executor->SetLogLevel(current_log_level);
// Create a thread-safe stdout logger to process the log messages
@ -548,12 +588,13 @@ int main(int argc, char* argv[])
return EPERM;
}
int port = DEFAULT_PORT;
if (!service.Init(&ExecuteCommand, port)) {
return EPERM;
}
if (!ParseArgument(argc, argv, port)) {
// We need to wait to create the devices until after the bus/controller/etc
// objects have been created.
if (!CreateInitialDevices(optarg_queue)) {
Cleanup();
return -1;
}