-
Notifications
You must be signed in to change notification settings - Fork 1.8k
[Fix 20284]: Enhance smartswitch environment variables parsing #21209
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,9 @@ | |
| #include <string> | ||
| #include <sstream> | ||
| #include <unordered_set> | ||
| #include <fstream> | ||
| #include <unordered_map> | ||
| #include <regex> | ||
|
|
||
| #define MAX_NUM_TARGETS 48 | ||
| #define MAX_NUM_INSTALL_LINES 48 | ||
|
|
@@ -385,6 +388,56 @@ static void replace_multi_inst_dep(const char *src) { | |
| rename(tmp_file_path, src); | ||
| } | ||
|
|
||
| static void update_environment(const std::string &src) | ||
| { | ||
| std::ifstream src_file(src); | ||
| std::ofstream tmp_file(src + ".tmp"); | ||
| bool has_service_section = false; | ||
| std::string line; | ||
|
|
||
| // locate the [Service] section | ||
| while (std::getline(src_file, line)) { | ||
| tmp_file << line << std::endl; | ||
| if (line.find("[Service]") != std::string::npos) { | ||
| has_service_section = true; | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (!has_service_section) { | ||
| tmp_file << "[Service]" << std::endl; | ||
| } | ||
|
|
||
| std::unordered_map<std::string, std::string> env_vars; | ||
| env_vars["IS_DPU_DEVICE"] = (smart_switch_dpu ? "true" : "false"); | ||
| env_vars["NUM_DPU"] = std::to_string(num_dpus); | ||
|
|
||
| for (const auto& [key, value] : env_vars) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think services files such as database, swss, syncd are enabled at build time.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please also verify the changes on smartswitch platform and make sure multiple database instances are created
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for your comments.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for testing |
||
| tmp_file << "Environment=\"" << key << "=" << value << "\"" << std::endl; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need to add Environment= option if the file doesn't have
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I worry that the
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please make sure, systemd won't throw an error if we add Environment= values after the last section without [Service]
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me |
||
| } | ||
|
|
||
| // copy the rest of the file | ||
| if (has_service_section) { | ||
| const static std::regex env_var_regex("Environment=\"?(\\w+)"); | ||
| while (std::getline(src_file, line)) { | ||
| // skip the existing environment variables | ||
| std::smatch match; | ||
| if (std::regex_search(line, match, env_var_regex)) { | ||
| if (env_vars.find(match[1]) != env_vars.end()) { | ||
| continue; | ||
| } | ||
| } | ||
| tmp_file << line << std::endl; | ||
| } | ||
| } | ||
|
|
||
| src_file.close(); | ||
| tmp_file.close(); | ||
| // remove the original file and rename the temporary file | ||
| remove(src.c_str()); | ||
| rename((src + ".tmp").c_str(), src.c_str()); | ||
| } | ||
|
|
||
| int get_install_targets(std::string unit_file, char* targets[]) { | ||
| /*** | ||
| Returns install targets for a unit file | ||
|
|
@@ -1155,6 +1208,8 @@ int ssg_main(int argc, char **argv) { | |
| free(targets[j]); | ||
| } | ||
|
|
||
| update_environment(get_unit_file_prefix() + unit_instance); | ||
|
|
||
| free(unit_files[i]); | ||
| } | ||
|
|
||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good approach to solve this issue but i see one setback. If we need to add new env variables, ssg code should be updated. which IMO is not very flexible. I have an idea for generic solution, let me know what you think
/etc/sonic/static-env-variablesEnvironmentFile=/etc/sonic/static-env-variablesoption to all the services. making the ssg code minimal and flexible.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea, I can have a try.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried it, but I feel it wasn't easy yet.
/host/machine.confas same as what systemd-sonic-generator did if I would like to get the variable. The SSG has done this by an efficient function, C function, why should I do it again by a shell?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, script couldn't use DB just like SSG
Hmm, difference is we need to run the script once. Since the oneshot service runs before other services are even started, CPU should be fairly free and should be executed quickly. we do need to benchmark this solution to measure impact.
Advantage being load on SSG is less, all it does it to add EnvironmentFIle= and with some optimization we don't even need to edit and write to the .service file after the first
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In any case, i'm okay with the current solution. We might move to the generic oneshot service if required in the future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this PR looks good to you, could you please help to approve it.