From c7bc0f0fa21da7be47db40a0f113158898d7f357 Mon Sep 17 00:00:00 2001 From: Guohan Lu Date: Wed, 9 Jun 2021 08:20:23 -0700 Subject: [PATCH] Revert "[multi-asic] Fixed systemd-sonic-generator for multi-asic (#7633)" This reverts commit 4f8dec9a6f7a97c1c41fc5544eb5b137b57dfaaf. --- src/systemd-sonic-generator/.gitignore | 1 - src/systemd-sonic-generator/Makefile | 22 +- src/systemd-sonic-generator/debian/rules | 1 + src/systemd-sonic-generator/ssg-test.cc | 550 ------------------ .../systemd-sonic-generator.c | 133 ++--- .../systemd-sonic-generator.h | 35 -- .../tests/testfiles/multi_inst_a.service | 9 - .../tests/testfiles/multi_inst_a@.service | 13 - .../tests/testfiles/multi_inst_b.service | 13 - .../tests/testfiles/multi_inst_b@.service | 12 - .../tests/testfiles/single_inst.service | 11 - .../tests/testfiles/test.service | 10 - .../tests/testfiles/test.timer | 10 - 13 files changed, 59 insertions(+), 761 deletions(-) delete mode 100644 src/systemd-sonic-generator/ssg-test.cc delete mode 100644 src/systemd-sonic-generator/systemd-sonic-generator.h delete mode 100644 src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/single_inst.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/test.service delete mode 100644 src/systemd-sonic-generator/tests/testfiles/test.timer diff --git a/src/systemd-sonic-generator/.gitignore b/src/systemd-sonic-generator/.gitignore index e81dafbbcb..06e13f381b 100644 --- a/src/systemd-sonic-generator/.gitignore +++ b/src/systemd-sonic-generator/.gitignore @@ -1,5 +1,4 @@ systemd-sonic-generator -ssg_test debian/* !debian/changelog !debian/compat diff --git a/src/systemd-sonic-generator/Makefile b/src/systemd-sonic-generator/Makefile index 87c6d00e1b..0f911ed8a4 100644 --- a/src/systemd-sonic-generator/Makefile +++ b/src/systemd-sonic-generator/Makefile @@ -1,10 +1,5 @@ CC=gcc -CFLAGS=-std=gnu99 -D_GNU_SOURCE - -CPP=g++ -CPPFLAGS=-std=c++11 -D_GNU_SOURCE -LFLAGS=-lpthread -lboost_filesystem -lboost_system -GTEST=/usr/lib/x86_64-linux-gnu/libgtest.a +CFLAGS=-std=gnu99 BINARY = systemd-sonic-generator MAIN_TARGET = $(BINARY)_1.0.0_$(CONFIGURED_ARCH).deb @@ -25,18 +20,3 @@ install: $(BINARY) mkdir -p $(DESTDIR)/lib/systemd mkdir -p $(DESTDIR)/lib/systemd/system-generators cp ./systemd-sonic-generator $(DESTDIR)/lib/systemd/system-generators - -.PHONY: test -test: ssg_test - ./ssg_test - -ssg_test: ssg-test.cc systemd-sonic-generator.o - $(CPP) $(CPPFLAGS) -o $@ $^ $(GTEST) $(LFLAGS) - -systemd-sonic-generator.o: systemd-sonic-generator.c - $(CC) $(CFLAGS) -D_SSG_UNITTEST -o $@ -c $^ - -clean: - rm -f ./systemd-sonic-generator - rm -f ./systemd-sonic-generator.o - rm -f ./ssg_test diff --git a/src/systemd-sonic-generator/debian/rules b/src/systemd-sonic-generator/debian/rules index a482e044c8..945fcf9d99 100755 --- a/src/systemd-sonic-generator/debian/rules +++ b/src/systemd-sonic-generator/debian/rules @@ -8,6 +8,7 @@ PACKAGEVERSION = $(VERSION) dh $@ override_dh_auto_clean: +override_dh_auto_test: override_dh_auto_build: override_dh_auto_install: make systemd-sonic-generator diff --git a/src/systemd-sonic-generator/ssg-test.cc b/src/systemd-sonic-generator/ssg-test.cc deleted file mode 100644 index 1d0f33d54b..0000000000 --- a/src/systemd-sonic-generator/ssg-test.cc +++ /dev/null @@ -1,550 +0,0 @@ -/*------------------------------------------------------------------ - * ssg-test.cc - systemd-sonic-generator Unit Test - * - * Initial: Apr 2021 - * - * Copyright (c) 2021 by Cisco Systems, Inc. - *------------------------------------------------------------------ - */ -#include -#include -#include -#include -#include -#include -#include "systemd-sonic-generator.h" - -namespace fs = boost::filesystem; - -namespace SSGTest { -#define IS_MULTI_ASIC(x) ((x) > 1) -#define IS_SINGLE_ASIC(x) ((x) <= 1) -#define NUM_UNIT_FILES 6 - -/* - * This test class uses following directory hierarchy for input and output - * data for systemd-sonic-generator. - * - * tests/ssg-test/ --- Test data directory - * | - * |---generated_services.conf - * |---machine.conf (systemd-sonic-generator fetch platform from here) - * |---systemd/ - * | |--- *.service (Test unit files are copied from - * | tests/testfiles/ to here) - * |----test_platform/ (test platform) - * | |---asic.conf - * | - * |----generator/ (Output Directory) - * - */ -const std::string TEST_ROOT_DIR = "tests/ssg-test/"; -const std::string TEST_UNIT_FILE_PREFIX = TEST_ROOT_DIR + "systemd/"; -const std::string TEST_ASIC_CONF_FORMAT = TEST_ROOT_DIR + "%s/asic.conf"; -const std::string TEST_MACHINE_CONF = TEST_ROOT_DIR + "machine.conf"; - -const std::string TEST_PLATFORM_DIR = TEST_ROOT_DIR + "test_platform/"; -const std::string TEST_ASIC_CONF = TEST_PLATFORM_DIR + "asic.conf"; - -const std::string TEST_OUTPUT_DIR = TEST_ROOT_DIR + "generator/"; - -const std::string TEST_CONFIG_FILE = TEST_ROOT_DIR + "generated_services.conf"; - -const std::string TEST_UNIT_FILES = "tests/testfiles/"; - -/* Input data for generated_services.conf */ -const std::vector generated_services = { - "multi_inst_a.service", /* Single instance of a multi asic service a */ - "multi_inst_a@.service", /* Multi-instance of a multi asic service a */ - "multi_inst_b@.service", /* Multi-instance of a multi asic service b */ - "single_inst.service", /* A single instance service */ - "test.service", /* A single instance test service - to test dependency creation */ - "test.timer", /* A timer service */ -}; - -static std::mutex g_ssg_test_mutex; - -class SystemdSonicGeneratorFixture : public testing::Test { - protected: - /* Save global variables before running tests */ - virtual void SetUp() { - /* one test runs at a time */ - g_ssg_test_mutex.lock(); - - unit_file_prefix_ = g_unit_file_prefix; - config_file_ = g_config_file; - machine_config_file_ = g_machine_config_file; - asic_conf_format_ = g_asic_conf_format; - } - - /* Restore global vars */ - virtual void TearDown() { - g_unit_file_prefix = unit_file_prefix_; - g_config_file = config_file_; - g_machine_config_file = machine_config_file_; - g_asic_conf_format = asic_conf_format_; - - g_ssg_test_mutex.unlock(); - } - - private: - const char* unit_file_prefix_; - const char* config_file_; - const char* machine_config_file_; - const char* asic_conf_format_; -}; - -/* - * class SsgFunctionTest - * Implements functions to execute functional level tests. - */ -class SsgFunctionTest : public SystemdSonicGeneratorFixture { - protected: - /* This function generates the generated_services.conf file */ - void generate_generated_services_conf() { - FILE* fp = fopen(TEST_CONFIG_FILE.c_str(), "w"); - ASSERT_NE(fp, nullptr); - for (std::string str : generated_services) { - fputs(str.c_str(), fp); - fputs("\n", fp); - } - fclose(fp); - } - - /* copy files from src_dir to dest_dir */ - void copyfiles(const char* src_dir, const char* dest_dir) { - // Iterate through the source directory - for (fs::directory_iterator file(src_dir); - file != fs::directory_iterator(); ++file) { - try { - fs::path current(file->path()); - if(!fs::is_directory(current)) { - /* Copy file */ - fs::copy_file( current, dest_dir / current.filename()); - } - } - catch(fs::filesystem_error const & e) { - std:: cerr << e.what() << '\n'; - } - } - } - - /* Save global variables before running tests */ - virtual void SetUp() { - FILE* fp; - SystemdSonicGeneratorFixture::SetUp(); - - /* Setup Input and Output directories and files */ - fs::path path{TEST_UNIT_FILE_PREFIX.c_str()}; - fs::create_directories(path); - path = fs::path(TEST_OUTPUT_DIR.c_str()); - fs::create_directories(path); - path = fs::path(TEST_PLATFORM_DIR.c_str()); - fs::create_directories(path); - fp = fopen(TEST_MACHINE_CONF.c_str(), "w"); - ASSERT_NE(fp, nullptr); - fputs("onie_platform=test_platform", fp); - fclose(fp); - generate_generated_services_conf(); - copyfiles(TEST_UNIT_FILES.c_str(), TEST_UNIT_FILE_PREFIX.c_str()); - } - - /* Restore global vars */ - virtual void TearDown() { - /* Delete ssg_test directory */ - EXPECT_TRUE(fs::exists(TEST_ROOT_DIR.c_str())); - fs::path path{TEST_ROOT_DIR.c_str()}; - fs::remove_all(path); - - SystemdSonicGeneratorFixture::TearDown(); - } - - private: -}; - -/* - * class SsgMainTest - * Implements functions to test ssg_main routine. - */ -class SsgMainTest : public SsgFunctionTest { - protected: - /* Retrun true if string belongs to a multi instance service */ - bool is_multi_instance(const std::string str) { - return (str.find("@") != std::string::npos) ? true : false; - } - - /* Returns true if it is a timer service */ - bool is_timer_service(const std::string str) { - return (str.find(".timer") != std::string::npos) ? true : false; - } - - /* Find a string in a file */ - bool find_string_in_file(std::string str, - std::string file_name, - int num_asics) { - bool found = false; - std::string line; - - std::ifstream file(TEST_UNIT_FILE_PREFIX + file_name); - while (getline(file, line) && !found) { - if (str == line) { - found = true; - } - } - return found; - } - - /* This function validates if a given dependency list for an unit file - * exists in the unit file as per expected_result. The items in the list - * should exist if expected_result is true. - */ - void validate_output_dependency_list(std::vector strs, - std::string target, - bool expected_result, - int num_asics) { - for (std::string str : strs) { - bool finished = false; - for (int i = 0 ; i < num_asics && !finished; ++i) { - auto str_t = str; - if (is_multi_instance(str)) { - /* insert instance id in string */ - str_t = (boost::format{str} % i).str(); - } else { - /* Run once for single instance */ - finished = true; - } - EXPECT_EQ(find_string_in_file(str_t, target, num_asics), - expected_result) - << "Error validating " + str_t + " in " + target; - } - } - } - - /* This function validates if unit file paths in the provided - * list strs exists or not as per expected_result. The unit files - * should exist if expected_result is true. - */ - void validate_output_unit_files(std::vector strs, - std::string target, - bool expected_result, - int num_asics) { - for (std::string str : strs) { - bool finished = false; - for (int i = 0 ; i < num_asics && !finished; ++i) { - auto str_t = str; - if (is_multi_instance(str)) { - /* insert instance id in string */ - str_t = (boost::format{str} % i).str(); - } else { - /* Run once for single instance */ - finished = true; - } - fs::path path{TEST_OUTPUT_DIR + target + "/" + str_t}; - EXPECT_EQ(fs::exists(path), expected_result) - << "Failed validation: " << path; - } - } - } - - /* - * This function validates the generated dependencies in a Unit File. - */ - void validate_depedency_in_unit_file(int num_asics) { - std::string test_service = "test.service"; - - /* Validate Unit file dependency creation for multi instance - * services. These entries should be present for multi asic - * system but not present for single asic system. - */ - validate_output_dependency_list(multi_asic_dependency_list, - test_service, IS_MULTI_ASIC(num_asics), num_asics); - - /* Validate Unit file dependency creation for single instance - * services. These entries should not be present for multi asic - * system but present for single asic system. - */ - validate_output_dependency_list(single_asic_dependency_list, - test_service, IS_SINGLE_ASIC(num_asics), num_asics); - - /* Validate Unit file dependency creation for single instance - * common services. These entries should not be present for multi - * and single asic system. - */ - validate_output_dependency_list(common_dependency_list, - test_service, true, num_asics); - } - - /* - * This function validates the list of generated Service Unit Files. - */ - void validate_service_file_generated_list(int num_asics) { - std::string test_target = "multi-user.target.wants"; - validate_output_unit_files(multi_asic_service_list, - test_target, IS_MULTI_ASIC(num_asics), num_asics); - validate_output_unit_files(single_asic_service_list, - test_target, IS_SINGLE_ASIC(num_asics), num_asics); - validate_output_unit_files(common_service_list, - test_target, true, num_asics); - } - - /* ssg_main test routine. - * input: num_asics number of asics - */ - void ssg_main_test(int num_asics) { - FILE* fp; - std::vector argv_; - std::vector arguments = { - "ssg_main", - TEST_OUTPUT_DIR.c_str() - }; - std::string num_asic_str = "NUM_ASIC=" + std::to_string(num_asics); - - std::string unit_file_path = fs::current_path().string() + "/" +TEST_UNIT_FILE_PREFIX; - g_unit_file_prefix = unit_file_path.c_str(); - g_config_file = TEST_CONFIG_FILE.c_str(); - g_machine_config_file = TEST_MACHINE_CONF.c_str(); - g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str(); - - /* Set NUM_ASIC value in asic.conf */ - fp = fopen(TEST_ASIC_CONF.c_str(), "w"); - ASSERT_NE(fp, nullptr); - fputs(num_asic_str.c_str(), fp); - fclose(fp); - - /* Create argv list for ssg_main. */ - for (const auto& arg : arguments) { - argv_.push_back((char*)arg.data()); - } - argv_.push_back(nullptr); - - /* Call ssg_main */ - EXPECT_EQ(ssg_main(argv_.size(), argv_.data()), 0); - - /* Validate systemd service template creation. */ - validate_service_file_generated_list(num_asics); - - /* Validate Test Unit file for dependency creation. */ - validate_depedency_in_unit_file(num_asics); - } - - /* Save global variables before running tests */ - virtual void SetUp() { - SsgFunctionTest::SetUp(); - } - - /* Restore global vars */ - virtual void TearDown() { - SsgFunctionTest::TearDown(); - } - - - private: - static const std::vector single_asic_service_list; - static const std::vector multi_asic_service_list; - static const std::vector common_service_list; - static const std::vector single_asic_dependency_list; - static const std::vector multi_asic_dependency_list; - static const std::vector common_dependency_list; -}; - -/* - * The following list defines the Service unit files symlinks generated by - * Systemd sonic generator for single and multi asic systems. The test case - * use these lists to check for presence/absence of unit files based on - * num_asics value. - */ - -/* Systemd service Unit file list for single asic only system */ -const std::vector -SsgMainTest::single_asic_service_list = { - "multi_inst_b.service", -}; - -/* Systemd service Unit file list for multi asic only system. - * %1% is formatter for boost::format API and replaced by asic num. - */ -const std::vector -SsgMainTest::multi_asic_service_list = { - "multi_inst_a@%1%.service", - "multi_inst_b@%1%.service", -}; - -/* Common Systemd service Unit file list for single and multi asic system. */ -const std::vector -SsgMainTest::common_service_list = { - "multi_inst_a.service", - "single_inst.service", - "test.service", - -}; - -/* - * The following list defines the systemd dependencies in a unit file to be - * varified for single and multi asic systems. Based on num_asics and type of - * service listed as dependency in Unit file, systemd sonic generator modifies - * the original unit file, if required, for multi asic system. - * For example: if test.service file defines a dependency "After=multi_inst_a.service", - * as multi_inst_a.service is a multi instance service, - * for a system with 2 asics, systemd sonic generator shall modify - * test.service to include following dependency strings: - * "After=multi_inst_a@0.service" - * After=multi_inst_a@1.service" - */ - -/* Systemd service Unit file dependency entries for Single asic system. */ -const std::vector -SsgMainTest::single_asic_dependency_list = { - "After=multi_inst_a.service multi_inst_b.service", -}; - -/* Systemd service Unit file dependency entries for multi asic system. */ -const std::vector -SsgMainTest::multi_asic_dependency_list = { - "After=multi_inst_a@%1%.service", - "After=multi_inst_b@%1%.service", -}; - -/* Common Systemd service Unit file dependency entries for single and multi asic - * systems. - */ -const std::vector -SsgMainTest::common_dependency_list = { - "Before=single_inst.service", -}; - -/* Test get functions for global vasr*/ -TEST_F(SystemdSonicGeneratorFixture, get_global_vars) { - EXPECT_EQ(g_unit_file_prefix, nullptr); - EXPECT_STREQ(get_unit_file_prefix(), UNIT_FILE_PREFIX); - g_unit_file_prefix = TEST_UNIT_FILE_PREFIX.c_str(); - EXPECT_STREQ(get_unit_file_prefix(), TEST_UNIT_FILE_PREFIX.c_str()); - - EXPECT_EQ(g_config_file, nullptr); - EXPECT_STREQ(get_config_file(), CONFIG_FILE); - g_config_file = TEST_CONFIG_FILE.c_str(); - EXPECT_STREQ(get_config_file(), TEST_CONFIG_FILE.c_str()); - - EXPECT_EQ(g_machine_config_file, nullptr); - EXPECT_STREQ(get_machine_config_file(), MACHINE_CONF_FILE); - g_machine_config_file = TEST_MACHINE_CONF.c_str(); - EXPECT_STREQ(get_machine_config_file(), TEST_MACHINE_CONF.c_str()); - - EXPECT_EQ(g_asic_conf_format, nullptr); - EXPECT_STREQ(get_asic_conf_format(), ASIC_CONF_FORMAT); - g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str(); - EXPECT_STREQ(get_asic_conf_format(), TEST_ASIC_CONF_FORMAT.c_str()); -} - -TEST_F(SystemdSonicGeneratorFixture, global_vars) { - EXPECT_EQ(g_unit_file_prefix, nullptr); - EXPECT_STREQ(get_unit_file_prefix(), UNIT_FILE_PREFIX); - - EXPECT_EQ(g_config_file, nullptr); - EXPECT_STREQ(get_config_file(), CONFIG_FILE); - - EXPECT_EQ(g_machine_config_file, nullptr); - EXPECT_STREQ(get_machine_config_file(), MACHINE_CONF_FILE); -} - -/* TEST machine/unit/config if file is missing */ -TEST_F(SsgFunctionTest, missing_file) { - EXPECT_TRUE(fs::exists(TEST_MACHINE_CONF.c_str())); - EXPECT_TRUE(fs::exists(TEST_UNIT_FILE_PREFIX.c_str())); - EXPECT_TRUE(fs::exists(TEST_OUTPUT_DIR.c_str())); - EXPECT_TRUE(fs::exists(TEST_PLATFORM_DIR.c_str())); -} - -/* TEST insert_instance_number() */ -TEST_F(SsgFunctionTest, insert_instance_number) { - char input[] = "test@.service"; - for (int i = 0; i <= 100; ++i) { - std::string out = "test@" + std::to_string(i) + ".service"; - char* ret = insert_instance_number(input, i); - ASSERT_NE(ret, nullptr); - EXPECT_STREQ(ret, out.c_str()); - } -} - -/* TEST get_num_of_asic() */ -TEST_F(SsgFunctionTest, get_num_of_asic) { - FILE* fp; - - g_machine_config_file = TEST_MACHINE_CONF.c_str(); - g_asic_conf_format = TEST_ASIC_CONF_FORMAT.c_str(); - - fp = fopen(TEST_ASIC_CONF.c_str(), "w"); - ASSERT_NE(fp, nullptr); - fputs("NUM_ASIC=1", fp); - fclose(fp); - EXPECT_EQ(get_num_of_asic(), 1); - - fp = fopen(TEST_ASIC_CONF.c_str(), "w"); - ASSERT_NE(fp, nullptr); - fputs("NUM_ASIC=10", fp); - fclose(fp); - EXPECT_EQ(get_num_of_asic(), 10); - - fp = fopen(TEST_ASIC_CONF.c_str(), "w"); - ASSERT_NE(fp, nullptr); - fputs("NUM_ASIC=40", fp); - fclose(fp); - EXPECT_EQ(get_num_of_asic(), 40); -} - -/* TEST get_unit_files()*/ -TEST_F(SsgFunctionTest, get_unit_files) { - g_unit_file_prefix = TEST_UNIT_FILE_PREFIX.c_str(); - g_config_file = TEST_CONFIG_FILE.c_str(); - char* unit_files[NUM_UNIT_FILES]; - int num_unit_files = get_unit_files(unit_files); - EXPECT_EQ(num_unit_files, NUM_UNIT_FILES); - for (std::string service : generated_services) { - bool found = false; - for (auto& unit_file : unit_files) { - if(unit_file == service) { - found = true; - break; - } - } - EXPECT_TRUE(found) << "unit file not found: " << service; - } -} - -/* TEST ssg_main() argv error */ -TEST_F(SsgMainTest, ssg_main_argv) { - FILE* fp; - std::vector argv_; - std::vector arguments = { - "ssg_main", - }; - - /* Create argv list for ssg_main. */ - for (const auto& arg : arguments) { - argv_.push_back((char*)arg.data()); - } - - /* Call ssg_main */ - EXPECT_EQ(ssg_main(argv_.size(), argv_.data()), 1); -} - -/* TEST ssg_main() single asic */ -TEST_F(SsgMainTest, ssg_main_single_npu) { - ssg_main_test(1); -} - -/* TEST ssg_main() multi(10) asic */ -TEST_F(SsgMainTest, ssg_main_10_npu) { - ssg_main_test(10); -} - -/* TEST ssg_main() multi(40) asic */ -TEST_F(SsgMainTest, ssg_main_40_npu) { - ssg_main_test(40); -} -} - -int main(int argc, char** argv) { - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.c b/src/systemd-sonic-generator/systemd-sonic-generator.c index 96193b9fe3..1052e2db62 100644 --- a/src/systemd-sonic-generator/systemd-sonic-generator.c +++ b/src/systemd-sonic-generator/systemd-sonic-generator.c @@ -9,36 +9,14 @@ #include #include -#define MAX_NUM_TARGETS 48 -#define MAX_NUM_INSTALL_LINES 48 +#define MAX_NUM_TARGETS 15 +#define MAX_NUM_INSTALL_LINES 15 #define MAX_NUM_UNITS 128 #define MAX_BUF_SIZE 512 -const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/"; -const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; -const char* MACHINE_CONF_FILE = "/host/machine.conf"; -const char* ASIC_CONF_FORMAT = "/usr/share/sonic/device/%s/asic.conf"; - -const char* g_unit_file_prefix = NULL; -const char* get_unit_file_prefix() { - return (g_unit_file_prefix) ? g_unit_file_prefix : UNIT_FILE_PREFIX; -} - -const char* g_config_file = NULL; -const char* get_config_file() { - return (g_config_file) ? g_config_file : CONFIG_FILE; -} - -const char* g_machine_config_file = NULL; -const char* get_machine_config_file() { - return (g_machine_config_file) ? g_machine_config_file : MACHINE_CONF_FILE; -} - -const char* g_asic_conf_format = NULL; -const char* get_asic_conf_format() { - return (g_asic_conf_format) ? g_asic_conf_format : ASIC_CONF_FORMAT; -} - +static const char* UNIT_FILE_PREFIX = "/usr/lib/systemd/system/"; +static const char* CONFIG_FILE = "/etc/sonic/generated_services.conf"; +static const char* MACHINE_CONF_FILE = "/host/machine.conf"; static int num_asics; static char** multi_instance_services; static int num_multi_inst; @@ -150,7 +128,7 @@ static int get_install_targets_from_line(char* target_string, char* install_type strcat(final_target, install_type); free(target); - + targets[num_targets + existing_targets] = strdup(final_target); num_targets++; } @@ -174,12 +152,12 @@ static void replace_multi_inst_dep(char *src) { ssize_t nread; bool section_done = false; char tmp_file_path[PATH_MAX]; - + /* Assumes that the service files has 3 sections, * in the order: Unit, Service and Install. - * Assumes that the timer file has 3 sections, + * Assumes that the timer file has 3 sectiosn, * in the order: Unit, Timer and Install. - * Read service dependency from Unit and Install + * Read service dependency from Unit and Install * sections, replace if dependent on multi instance * service. */ @@ -188,7 +166,7 @@ static void replace_multi_inst_dep(char *src) { fp_tmp = fopen(tmp_file_path, "w"); while ((nread = getline(&line, &len, fp_src)) != -1 ) { - if ((strstr(line, "[Service]") != NULL) || + if ((strstr(line, "[Service]") != NULL) || (strstr(line, "[Timer]") != NULL)) { section_done = true; fputs(line,fp_tmp); @@ -210,7 +188,7 @@ static void replace_multi_inst_dep(char *src) { } else { service_name = strdup(word); service_name = strtok_r(service_name, ".", &save_ptr2); - type = strtok_r(NULL, "\n", &save_ptr2); + type = strtok_r(NULL, " ", &save_ptr2); if (is_multi_instance_service(word)) { for(i = 0; i < num_asics; i++) { snprintf(buf, MAX_BUF_SIZE, "%s=%s@%d.%s\n", @@ -237,7 +215,7 @@ static void replace_multi_inst_dep(char *src) { rename(tmp_file_path, src); } -int get_install_targets(char* unit_file, char* targets[]) { +static int get_install_targets(char* unit_file, char* targets[]) { /*** Returns install targets for a unit file @@ -256,7 +234,7 @@ int get_install_targets(char* unit_file, char* targets[]) { char *instance_name; char *dot_ptr; - strcpy(file_path, get_unit_file_prefix()); + strcpy(file_path, UNIT_FILE_PREFIX); strcat(file_path, unit_file); instance_name = strdup(unit_file); @@ -302,7 +280,7 @@ int get_install_targets(char* unit_file, char* targets[]) { } -int get_unit_files(char* unit_files[]) { +static int get_unit_files(char* unit_files[]) { /*** Reads a list of unit files to be installed from /etc/sonic/generated_services.conf ***/ @@ -311,19 +289,18 @@ int get_unit_files(char* unit_files[]) { size_t len = 0; ssize_t read; char *pos; - const char* config_file = get_config_file(); - fp = fopen(config_file, "r"); + fp = fopen(CONFIG_FILE, "r"); if (fp == NULL) { - fprintf(stderr, "Failed to open %s\n", config_file); + fprintf(stderr, "Failed to open %s\n", CONFIG_FILE); exit(EXIT_FAILURE); } int num_unit_files = 0; num_multi_inst = 0; - multi_instance_services = calloc(MAX_NUM_UNITS, sizeof(char *)); + multi_instance_services = malloc(MAX_NUM_UNITS * sizeof(char *)); while ((read = getline(&line, &len, fp)) != -1) { if (num_unit_files >= MAX_NUM_UNITS) { @@ -335,7 +312,7 @@ int get_unit_files(char* unit_files[]) { /* Get the multi-instance services */ pos = strchr(line, '@'); if (pos != NULL) { - multi_instance_services[num_multi_inst] = calloc(strlen(line), sizeof(char)); + multi_instance_services[num_multi_inst] = malloc(strlen(line)*sizeof(char)); strncpy(multi_instance_services[num_multi_inst], line, pos-line); num_multi_inst++; } @@ -357,33 +334,41 @@ int get_unit_files(char* unit_files[]) { } -char* insert_instance_number(char* unit_file, int instance) { +static char* insert_instance_number(char* unit_file, int instance) { /*** Adds an instance number to a systemd template name E.g. given unit_file='example@.service', instance=3, - returns a pointer to 'example@3.service' + returns a pointer to 'example@1.service' ***/ + char* prefix; + char* suffix; + char* instance_string; char* instance_name; - int ret; - int prefix_len; - const char *suffix = strchr(unit_file, '@'); - if (!suffix) { - fprintf(stderr, "Invalid unit file %s for instance %d\n", unit_file, instance); - return NULL; - } + char* temp_unit_file; - /*** - suffix is "@.service", set suffix=".service" - prefix_len is length of "example@" - ***/ - prefix_len = ++suffix - unit_file; - ret = asprintf(&instance_name, "%.*s%d%s", prefix_len, unit_file, instance, suffix); - if (ret == -1) { + instance_string = malloc(2 * sizeof(char)); + snprintf(instance_string, 2, "%d", instance); + + instance_name = malloc(strlen(unit_file) + 2); + + if (instance_name == NULL) { fprintf(stderr, "Error creating instance %d of %s\n", instance, unit_file); return NULL; } + temp_unit_file = strdup(unit_file); + prefix = strtok(temp_unit_file, "@"); + suffix = strtok(NULL, "@"); + + strcpy(instance_name, prefix); + strcat(instance_name, "@"); + strcat(instance_name, instance_string); + strcat(instance_name, suffix); + + free(instance_string); + free(temp_unit_file); + return instance_name; } @@ -396,7 +381,7 @@ static int create_symlink(char* unit, char* target, char* install_dir, int insta char* unit_instance; int r; - strcpy(src_path, get_unit_file_prefix()); + strcpy(src_path, UNIT_FILE_PREFIX); strcat(src_path, unit); if (instance < 0) { @@ -477,7 +462,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { assert(unit_file); assert(target); - + if ((num_asics > 1) && strstr(unit_file, "@") != NULL) { @@ -491,16 +476,16 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { } r = create_symlink(unit_file, target_instance, install_dir, i); - if (r < 0) + if (r < 0) fprintf(stderr, "Error installing %s for target %s\n", unit_file, target_instance); - + free(target_instance); - } + } } else { r = create_symlink(unit_file, target, install_dir, -1); - if (r < 0) + if (r < 0) fprintf(stderr, "Error installing %s for target %s\n", unit_file, target); } @@ -508,7 +493,7 @@ static int install_unit_file(char* unit_file, char* target, char* install_dir) { } -int get_num_of_asic() { +static int get_num_of_asic() { /*** Determines if the current platform is single or multi-ASIC ***/ @@ -522,12 +507,11 @@ int get_num_of_asic() { char asic_file[512]; char* str_num_asic; int num_asic = 1; - const char* machine_config_file = get_machine_config_file(); - fp = fopen(machine_config_file, "r"); + fp = fopen(MACHINE_CONF_FILE, "r"); if (fp == NULL) { - fprintf(stderr, "Failed to open %s\n", machine_config_file); + fprintf(stderr, "Failed to open %s\n", MACHINE_CONF_FILE); exit(EXIT_FAILURE); } @@ -540,9 +524,10 @@ int get_num_of_asic() { break; } } + fclose(fp); if(platform != NULL) { - snprintf(asic_file, 512, get_asic_conf_format(), platform); + snprintf(asic_file, 512, "/usr/share/sonic/device/%s/asic.conf", platform); fp = fopen(asic_file, "r"); if (fp != NULL) { while ((nread = getline(&line, &len, fp)) != -1) { @@ -564,7 +549,8 @@ int get_num_of_asic() { } -int ssg_main(int argc, char **argv) { + +int main(int argc, char **argv) { char* unit_files[MAX_NUM_UNITS]; char install_dir[PATH_MAX]; char* targets[MAX_NUM_TARGETS]; @@ -581,8 +567,10 @@ int ssg_main(int argc, char **argv) { } num_asics = get_num_of_asic(); + strcpy(install_dir, argv[1]); strcat(install_dir, "/"); + num_unit_files = get_unit_files(unit_files); // For each unit file, get the installation targets and install the unit @@ -622,10 +610,3 @@ int ssg_main(int argc, char **argv) { return 0; } - - -#ifndef _SSG_UNITTEST -int main(int argc, char **argv) { - return ssg_main(argc, argv); -} -#endif diff --git a/src/systemd-sonic-generator/systemd-sonic-generator.h b/src/systemd-sonic-generator/systemd-sonic-generator.h deleted file mode 100644 index 25c179caa0..0000000000 --- a/src/systemd-sonic-generator/systemd-sonic-generator.h +++ /dev/null @@ -1,35 +0,0 @@ -/*------------------------------------------------------------------ - * systemd-sonic-generator.h - Header file - * - * Initial: Apr 2021 - * - * Copyright (c) 2021 by Cisco Systems, Inc. - *------------------------------------------------------------------ - */ -#ifdef __cplusplus -extern "C" { -#endif - -/* expose global vars for testing purpose */ -extern const char* UNIT_FILE_PREFIX; -extern const char* CONFIG_FILE; -extern const char* MACHINE_CONF_FILE; -extern const char* ASIC_CONF_FORMAT; -extern const char* g_unit_file_prefix; -extern const char* g_config_file; -extern const char* g_machine_config_file; -extern const char* g_asic_conf_format; - -/* C-functions under test */ -extern const char* get_unit_file_prefix(); -extern const char* get_config_file(); -extern const char* get_machine_config_file(); -extern const char* get_asic_conf_format(); -extern char* insert_instance_number(char* unit_file, int instance); -extern int ssg_main(int argc, char** argv); -extern int get_num_of_asic(); -extern int get_install_targets(char* unit_file, char* targets[]); -extern int get_unit_files(char* unit_files[]); -#ifdef __cplusplus -} -#endif diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service deleted file mode 100644 index 500cb0ae16..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a.service +++ /dev/null @@ -1,9 +0,0 @@ -[Unit] -Description=Multi Instance A Test service -StartLimitIntervalSec=1200 -StartLimitBurst=3 -[Service] -User=root -ExecStop=/usr/bin/test.sh stop -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service deleted file mode 100644 index 816d698b4d..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/multi_inst_a@.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Multi INstance A test Service - -After=multi_inst_a.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 -[Service] -User=root -ExecStop=/usr/bin/test.sh stop %i -Restart=always -RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service deleted file mode 100644 index 04960be66c..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b.service +++ /dev/null @@ -1,13 +0,0 @@ -[Unit] -Description=Multi instance b Test service - -Requires=multi_inst_a.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 -[Service] -User=root -ExecStop=/usr/bin/test.sh stop -Restart=always -RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service b/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service deleted file mode 100644 index dee76391da..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/multi_inst_b@.service +++ /dev/null @@ -1,12 +0,0 @@ -[Unit] -Description=Multi instance b Test service -Requires=multi_inst_a@%i.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 -[Service] -User=root -ExecStart=/usr/local/bin/test.sh wait %i -Restart=always -RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/single_inst.service b/src/systemd-sonic-generator/tests/testfiles/single_inst.service deleted file mode 100644 index 7f0fd72524..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/single_inst.service +++ /dev/null @@ -1,11 +0,0 @@ -[Unit] -Description=Platform monitor container -Requires=multi_inst_a.service -StartLimitIntervalSec=1200 -StartLimitBurst=3 -[Service] -ExecStart=/usr/bin/test.sh wait -Restart=always -RestartSec=30 -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/test.service b/src/systemd-sonic-generator/tests/testfiles/test.service deleted file mode 100644 index e8b37f641f..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/test.service +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Multi ASIC Test service -After=multi_inst_a.service multi_inst_b.service -Before=single_inst.service -[Service] -Type=oneshot -RemainAfterExit=yes -ExecStart=/usr/bin/test.sh start -[Install] -WantedBy=multi-user.target diff --git a/src/systemd-sonic-generator/tests/testfiles/test.timer b/src/systemd-sonic-generator/tests/testfiles/test.timer deleted file mode 100644 index 254bec362a..0000000000 --- a/src/systemd-sonic-generator/tests/testfiles/test.timer +++ /dev/null @@ -1,10 +0,0 @@ -[Unit] -Description=Test Timer service -After=multi_inst_b.service -[Timer] -OnUnitActiveSec=0 sec -OnBootSec=3min 30 sec -Unit=snmp.service -[Install] -WantedBy=timers.target -WantedBy=multi_inst_b.service