Skip to content

Commit 7e03462

Browse files
authored
Enhance smartswitch environment variables parsing (#21209)
Fix #20284 In 202405 and above, two extra steps are added before the start of every container which checks NUM_DPU and IS_DPU_DEVICE by parsing the platform.json file using the jq tool. This is only relevant for Smartswitch. However, this is adding some delay during the reconciliation phase of WR/FR resulting How I did it Set the environment variables for systemd by systemd-sonic-generator. Signed-off-by: Ze Gan <ganze718@gmail.com>
1 parent aeae268 commit 7e03462

File tree

3 files changed

+85
-13
lines changed

3 files changed

+85
-13
lines changed

files/build_templates/docker_image_ctl.j2

-12
Original file line numberDiff line numberDiff line change
@@ -372,18 +372,6 @@ start() {
372372
source $PLATFORM_ENV_CONF
373373
fi
374374

375-
# Parse the platform.json file to get the platform specific information
376-
PLATFORM_JSON=/usr/share/sonic/device/$PLATFORM/platform.json
377-
if [ -f "$PLATFORM_JSON" ]; then
378-
NUM_DPU=$(jq -r '.DPUS | length' $PLATFORM_JSON 2>/dev/null)
379-
jq -e '.DPU' $PLATFORM_JSON >/dev/null
380-
if [[ $? -eq 0 ]]; then
381-
IS_DPU_DEVICE="true"
382-
else
383-
IS_DPU_DEVICE="false"
384-
fi
385-
fi
386-
387375
{%- if sonic_asic_platform == "broadcom" %}
388376
{%- if docker_container_name == "syncd" %}
389377
# Set the SYNCD_SHM_SIZE if this variable not defined

src/systemd-sonic-generator/ssg-test.cc

+30-1
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ class SsgMainTest : public SsgFunctionTest {
231231
while (getline(file, line) && !found) {
232232
if (str == line) {
233233
found = true;
234+
break;
234235
}
235236
}
236237
return found;
@@ -364,6 +365,32 @@ class SsgMainTest : public SsgFunctionTest {
364365
"system", !cfg.is_smart_switch_npu && !cfg.is_smart_switch_dpu, cfg.num_dpus, false);
365366
}
366367

368+
void validate_environment_variable(const SsgMainConfig &cfg) {
369+
std::unordered_map<std::string, std::string> env_vars;
370+
env_vars["IS_DPU_DEVICE"] = (cfg.is_smart_switch_dpu ? "true" : "false");
371+
env_vars["NUM_DPU"] = std::to_string(cfg.num_dpus);
372+
373+
std::vector<std::string> checked_service_list;
374+
375+
checked_service_list.insert(checked_service_list.end(), common_service_list.begin(), common_service_list.end());
376+
if (cfg.num_dpus > 0) {
377+
checked_service_list.insert(checked_service_list.end(), npu_service_list.begin(), npu_service_list.end());
378+
}
379+
if (cfg.num_asics > 1) {
380+
checked_service_list.insert(checked_service_list.end(), multi_asic_service_list.begin(), multi_asic_service_list.end());
381+
}
382+
383+
for (const auto &target: checked_service_list) {
384+
if (find_string_in_file("[Service]", target)) {
385+
for (const auto& item : env_vars) {
386+
std::string str = "Environment=\"" + item.first + "=" + item.second + "\"";
387+
EXPECT_EQ(find_string_in_file(str, target), true)
388+
<< "Error validating " + str + " in " + target;
389+
}
390+
}
391+
}
392+
}
393+
367394
/* ssg_main test routine.
368395
* input: num_asics number of asics
369396
*/
@@ -431,6 +458,9 @@ class SsgMainTest : public SsgFunctionTest {
431458

432459
/* Validate Test Unit file for dependency creation. */
433460
validate_depedency_in_unit_file(cfg);
461+
462+
/* Validate environment variables */
463+
validate_environment_variable(cfg);
434464
}
435465

436466
/* Save global variables before running tests */
@@ -719,7 +749,6 @@ TEST_F(SsgMainTest, ssg_main_argv) {
719749
std::vector<std::string> arguments = {
720750
"ssg_main",
721751
};
722-
723752
/* Create argv list for ssg_main. */
724753
for (const auto& arg : arguments) {
725754
argv_.push_back((char*)arg.data());

src/systemd-sonic-generator/systemd-sonic-generator.cpp

+55
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
#include <string>
1212
#include <sstream>
1313
#include <unordered_set>
14+
#include <fstream>
15+
#include <unordered_map>
16+
#include <regex>
1417

1518
#define MAX_NUM_TARGETS 48
1619
#define MAX_NUM_INSTALL_LINES 48
@@ -385,6 +388,56 @@ static void replace_multi_inst_dep(const char *src) {
385388
rename(tmp_file_path, src);
386389
}
387390

391+
static void update_environment(const std::string &src)
392+
{
393+
std::ifstream src_file(src);
394+
std::ofstream tmp_file(src + ".tmp");
395+
bool has_service_section = false;
396+
std::string line;
397+
398+
// locate the [Service] section
399+
while (std::getline(src_file, line)) {
400+
tmp_file << line << std::endl;
401+
if (line.find("[Service]") != std::string::npos) {
402+
has_service_section = true;
403+
break;
404+
}
405+
}
406+
407+
if (!has_service_section) {
408+
tmp_file << "[Service]" << std::endl;
409+
}
410+
411+
std::unordered_map<std::string, std::string> env_vars;
412+
env_vars["IS_DPU_DEVICE"] = (smart_switch_dpu ? "true" : "false");
413+
env_vars["NUM_DPU"] = std::to_string(num_dpus);
414+
415+
for (const auto& [key, value] : env_vars) {
416+
tmp_file << "Environment=\"" << key << "=" << value << "\"" << std::endl;
417+
}
418+
419+
// copy the rest of the file
420+
if (has_service_section) {
421+
const static std::regex env_var_regex("Environment=\"?(\\w+)");
422+
while (std::getline(src_file, line)) {
423+
// skip the existing environment variables
424+
std::smatch match;
425+
if (std::regex_search(line, match, env_var_regex)) {
426+
if (env_vars.find(match[1]) != env_vars.end()) {
427+
continue;
428+
}
429+
}
430+
tmp_file << line << std::endl;
431+
}
432+
}
433+
434+
src_file.close();
435+
tmp_file.close();
436+
// remove the original file and rename the temporary file
437+
remove(src.c_str());
438+
rename((src + ".tmp").c_str(), src.c_str());
439+
}
440+
388441
int get_install_targets(std::string unit_file, char* targets[]) {
389442
/***
390443
Returns install targets for a unit file
@@ -1155,6 +1208,8 @@ int ssg_main(int argc, char **argv) {
11551208
free(targets[j]);
11561209
}
11571210

1211+
update_environment(get_unit_file_prefix() + unit_instance);
1212+
11581213
free(unit_files[i]);
11591214
}
11601215

0 commit comments

Comments
 (0)