1515#include < fstream>
1616#include < unordered_map>
1717#include < regex>
18+ #include < fcntl.h>
19+ #include < stdarg.h>
20+
21+ // Utility function for logging to /dev/kmsg
22+ void log_to_kmsg (const char * format, ...) {
23+ static int kmsg_fd = -1 ;
24+
25+ // Open /dev/kmsg if not already opened
26+ if (kmsg_fd == -1 ) {
27+ kmsg_fd = open (" /dev/kmsg" , O_WRONLY);
28+ if (kmsg_fd == -1 ) {
29+ // Fallback to stderr if /dev/kmsg is not available
30+ va_list args;
31+ va_start (args, format);
32+ vfprintf (stderr, format, args);
33+ va_end (args);
34+ return ;
35+ }
36+ }
37+
38+ va_list args;
39+ va_start (args, format);
40+
41+ // Format the message
42+ char kmsg_buffer[1024 ];
43+ char *buffer_p;
44+ buffer_p = stpncpy (kmsg_buffer, " <6>systemd-sonic-generator: " , sizeof (kmsg_buffer))
45+ vsnprintf (buffer_p, sizeof (kmsg_buffer) - (buffer_p - kmsg_buffer), format, args);
46+ va_end (args);
47+ kmsg_buffer[1023 ] = ' \0 ' ;
48+
49+ // Write to /dev/kmsg
50+ write (kmsg_fd, kmsg_buffer, strlen (kmsg_buffer));
51+ }
1852
1953#define MAX_NUM_TARGETS 48
2054#define MAX_NUM_INSTALL_LINES 48
@@ -187,7 +221,7 @@ static int get_target_lines(const char* unit_file, char* target_lines[]) {
187221 fp = fopen (unit_file, " r" );
188222
189223 if (fp == NULL ) {
190- fprintf (stderr, " Failed to open file %s\n " , unit_file);
224+ log_to_kmsg ( " Failed to open file %s\n " , unit_file);
191225 return -1 ;
192226 }
193227
@@ -201,8 +235,8 @@ static int get_target_lines(const char* unit_file, char* target_lines[]) {
201235 }
202236 else if (found_install) {
203237 if (num_target_lines >= MAX_NUM_INSTALL_LINES) {
204- fprintf (stderr, " Number of lines in [Install] section of %s exceeds MAX_NUM_INSTALL_LINES\n " , unit_file);
205- fputs (" Extra [Install] lines will be ignored\n " , stderr );
238+ log_to_kmsg ( " Number of lines in [Install] section of %s exceeds MAX_NUM_INSTALL_LINES\n " , unit_file);
239+ log_to_kmsg (" Extra [Install] lines will be ignored\n " );
206240 break ;
207241 }
208242 target_lines[num_target_lines] = strdup (line);
@@ -278,16 +312,16 @@ static int get_install_targets_from_line(std::string target_string, std::string
278312 int num_targets = 0 ;
279313
280314 if (target_string.empty () || install_type.empty ()) {
281- fprintf (stderr, " Invalid target string or install type\n " );
315+ log_to_kmsg ( " Invalid target string or install type\n " );
282316 exit (EXIT_FAILURE);
283317 }
284318
285319 std::stringstream ss (target_string);
286320
287321 while (ss >> target) {
288322 if (num_targets + existing_targets >= MAX_NUM_TARGETS) {
289- fprintf (stderr, " Number of targets exceeds MAX_NUM_TARGETS\n " );
290- fputs (" Additional targets will be ignored\n " , stderr );
323+ log_to_kmsg ( " Number of targets exceeds MAX_NUM_TARGETS\n " );
324+ log_to_kmsg (" Additional targets will be ignored\n " );
291325 break ;
292326 }
293327 // handle install targets using the '%i' systemd specifier
@@ -468,7 +502,7 @@ int get_install_targets(std::string unit_file, char* targets[]) {
468502
469503 num_target_lines = get_target_lines (file_path.c_str (), target_lines);
470504 if (num_target_lines < 0 ) {
471- fprintf (stderr, " Error parsing targets for %s\n " , unit_file.c_str ());
505+ log_to_kmsg ( " Error parsing targets for %s\n " , unit_file.c_str ());
472506 return -1 ;
473507 }
474508
@@ -515,7 +549,7 @@ int get_unit_files(const char* config_file, char* unit_files[], int unit_files_s
515549 fp = fopen (config_file, " r" );
516550
517551 if (fp == NULL ) {
518- fprintf (stderr, " Failed to open %s\n " , config_file);
552+ log_to_kmsg ( " Failed to open %s\n " , config_file);
519553 exit (EXIT_FAILURE);
520554 }
521555
@@ -528,7 +562,7 @@ int get_unit_files(const char* config_file, char* unit_files[], int unit_files_s
528562
529563 while ((read = getline (&line, &len, fp)) != -1 ) {
530564 if (num_unit_files >= unit_files_size) {
531- fprintf (stderr, " Maximum number of units exceeded, ignoring extras\n " );
565+ log_to_kmsg ( " Maximum number of units exceeded, ignoring extras\n " );
532566 break ;
533567 }
534568 strip_trailing_newline (line);
@@ -591,7 +625,7 @@ std::string insert_instance_number(const std::string& unit_file, int instance, c
591625 ***/
592626 size_t at_pos = unit_file.find (" @" );
593627 if (at_pos == std::string::npos) {
594- fprintf (stderr, " Invalid unit file %s for instance %d\n " , unit_file.c_str (), instance);
628+ log_to_kmsg ( " Invalid unit file %s for instance %d\n " , unit_file.c_str (), instance);
595629 return " " ;
596630 }
597631
@@ -623,36 +657,36 @@ static int create_symlink(const std::string& unit, const std::string& target, co
623657 // If doesn't exist, create
624658 r = mkdir (final_install_dir.c_str (), 0755 );
625659 if (r == -1 ) {
626- fprintf (stderr, " Unable to create target directory %s\n " , final_install_dir.c_str ());
660+ log_to_kmsg ( " Unable to create target directory %s\n " , final_install_dir.c_str ());
627661 return -1 ;
628662 }
629663 }
630664 else if (S_ISREG (st.st_mode )) {
631665 // If is regular file, remove and create
632666 r = remove (final_install_dir.c_str ());
633667 if (r == -1 ) {
634- fprintf (stderr, " Unable to remove file with same name as target directory %s\n " , final_install_dir.c_str ());
668+ log_to_kmsg ( " Unable to remove file with same name as target directory %s\n " , final_install_dir.c_str ());
635669 return -1 ;
636670 }
637671
638672 r = mkdir (final_install_dir.c_str (), 0755 );
639673 if (r == -1 ) {
640- fprintf (stderr, " Unable to create target directory %s\n " , final_install_dir.c_str ());
674+ log_to_kmsg ( " Unable to create target directory %s\n " , final_install_dir.c_str ());
641675 return -1 ;
642676 }
643677 }
644678 else if (S_ISDIR (st.st_mode )) {
645679 // If directory, verify correct permissions
646680 r = chmod (final_install_dir.c_str (), 0755 );
647681 if (r == -1 ) {
648- fprintf (stderr, " Unable to change permissions of existing target directory %s\n " , final_install_dir.c_str ());
682+ log_to_kmsg ( " Unable to change permissions of existing target directory %s\n " , final_install_dir.c_str ());
649683 return -1 ;
650684 }
651685 }
652686
653687 if (is_devnull (dest_path.c_str ())) {
654688 if (remove (dest_path.c_str ()) != 0 ) {
655- fprintf (stderr, " Unable to remove existing symlink %s\n " , dest_path.c_str ());
689+ log_to_kmsg ( " Unable to remove existing symlink %s\n " , dest_path.c_str ());
656690 return -1 ;
657691 }
658692 }
@@ -662,7 +696,7 @@ static int create_symlink(const std::string& unit, const std::string& target, co
662696 if (r < 0 ) {
663697 if (errno == EEXIST)
664698 return 0 ;
665- fprintf (stderr, " Error creating symlink %s from source %s\n " , dest_path.c_str (), src_path.c_str ());
699+ log_to_kmsg ( " Error creating symlink %s from source %s\n " , dest_path.c_str (), src_path.c_str ());
666700 return -1 ;
667701 }
668702
@@ -686,7 +720,7 @@ static int install_unit_file(std::string unit_file, std::string target, std::str
686720 int r;
687721
688722 if (unit_file.empty () || target.empty () || install_dir.empty ()){
689- fprintf (stderr, " Invalid unit file, target or install directory\n " );
723+ log_to_kmsg ( " Invalid unit file, target or install directory\n " );
690724 exit (EXIT_FAILURE);
691725 }
692726
@@ -703,7 +737,7 @@ static int install_unit_file(std::string unit_file, std::string target, std::str
703737
704738 r = create_symlink (unit_file, target_instance, install_dir, i, " " );
705739 if (r < 0 )
706- fprintf (stderr, " Error installing %s for target %s\n " , unit_file.c_str (), target_instance.c_str ());
740+ log_to_kmsg ( " Error installing %s for target %s\n " , unit_file.c_str (), target_instance.c_str ());
707741 }
708742 } else if (num_dpus > 0 && unit_file.find (" @" ) != std::string::npos) {
709743 // If multi-instance service for DPU
@@ -713,12 +747,12 @@ static int install_unit_file(std::string unit_file, std::string target, std::str
713747 for (int i = 0 ; i < num_dpus; i++) {
714748 r = create_symlink (unit_file, target, install_dir, i, DPU_PREFIX);
715749 if (r < 0 )
716- fprintf (stderr, " Error installing %s for target %s\n " , unit_file.c_str (), target.c_str ());
750+ log_to_kmsg ( " Error installing %s for target %s\n " , unit_file.c_str (), target.c_str ());
717751 }
718752 } else {
719753 r = create_symlink (unit_file, target, install_dir, -1 , " " );
720754 if (r < 0 )
721- fprintf (stderr, " Error installing %s for target %s\n " , unit_file.c_str (), target.c_str ());
755+ log_to_kmsg ( " Error installing %s for target %s\n " , unit_file.c_str (), target.c_str ());
722756 }
723757
724758 return 0 ;
@@ -751,7 +785,7 @@ const char* get_platform() {
751785 const char * machine_config_file = get_machine_config_file ();
752786 fp = fopen (machine_config_file, " r" );
753787 if (fp == NULL ) {
754- fprintf (stderr, " Failed to open %s\n " , machine_config_file);
788+ log_to_kmsg ( " Failed to open %s\n " , machine_config_file);
755789 exit (EXIT_FAILURE);
756790 }
757791
@@ -846,29 +880,29 @@ const struct json_object* get_platform_info() {
846880
847881 FILE *fp = fopen (platform_file_path, " r" );
848882 if (fp == NULL ) {
849- fprintf (stdout, " Failed to open %s\n " , platform_file_path);
883+ log_to_kmsg ( " Failed to open %s\n " , platform_file_path);
850884 set_invalid_pointer ((void **)&platform_info);
851885 return NULL ;
852886 }
853887 if (fseek (fp, 0 , SEEK_END) != 0 ) {
854- fprintf (stdout, " Failed to seek to end of %s\n " , platform_file_path);
888+ log_to_kmsg ( " Failed to seek to end of %s\n " , platform_file_path);
855889 fclose (fp);
856890 exit (EXIT_FAILURE);
857891 }
858892 size_t fsize = ftell (fp);
859893 if (fseek (fp, 0 , SEEK_SET) != 0 ) {
860- fprintf (stdout, " Failed to seek to beginning of %s\n " , platform_file_path);
894+ log_to_kmsg ( " Failed to seek to beginning of %s\n " , platform_file_path);
861895 fclose (fp);
862896 exit (EXIT_FAILURE);
863897 }
864898 char *platform_json = (char *) malloc (fsize + 1 );
865899 if (platform_json == NULL ) {
866- fprintf (stdout, " Failed to allocate memory for %s\n " , platform_file_path);
900+ log_to_kmsg ( " Failed to allocate memory for %s\n " , platform_file_path);
867901 fclose (fp);
868902 exit (EXIT_FAILURE);
869903 }
870904 if (fread (platform_json, fsize, 1 , fp) != 1 ) {
871- fprintf (stdout, " Failed to read %s\n " , platform_file_path);
905+ log_to_kmsg ( " Failed to read %s\n " , platform_file_path);
872906 free (platform_json);
873907 fclose (fp);
874908 exit (EXIT_FAILURE);
@@ -878,7 +912,7 @@ const struct json_object* get_platform_info() {
878912
879913 platform_info = json_tokener_parse (platform_json);
880914 if (platform_info == NULL ) {
881- fprintf (stderr, " Failed to parse %s\n " , platform_file_path);
915+ log_to_kmsg ( " Failed to parse %s\n " , platform_file_path);
882916 free (platform_json);
883917 return NULL ;
884918 }
@@ -954,21 +988,21 @@ static int get_num_of_dpu() {
954988 */
955989static int install_network_unit (std::string unit_name, const std::filesystem::path& install_dir) {
956990 if (unit_name.empty ()) {
957- fprintf (stderr, " Invalid network unit\n " );
991+ log_to_kmsg ( " Invalid network unit\n " );
958992 exit (EXIT_FAILURE);
959993 }
960994
961995 std::string unit_type = unit_name.substr (unit_name.find (" ." ) + 1 );
962996 if (unit_type.empty ()) {
963- fprintf (stderr, " Invalid network unit %s\n " , unit_name.c_str ());
997+ log_to_kmsg ( " Invalid network unit %s\n " , unit_name.c_str ());
964998 return -1 ;
965999 }
9661000
9671001 std::string install_path;
9681002 std::string original_path;
9691003 std::string subdir = " /network/" ;
9701004 if (unit_type != " netdev" && unit_type != " network" ) {
971- fprintf (stderr, " Invalid network unit %s\n " , unit_type.c_str ());
1005+ log_to_kmsg ( " Invalid network unit %s\n " , unit_type.c_str ());
9721006 return -1 ;
9731007 }
9741008
@@ -980,26 +1014,26 @@ static int install_network_unit(std::string unit_name, const std::filesystem::pa
9801014 if (stat (install_path.c_str (), &st) == 0 ) {
9811015 // If the file already exists, remove it
9821016 if (S_ISDIR (st.st_mode )) {
983- fprintf (stderr, " Error: %s is a directory\n " , install_path.c_str ());
1017+ log_to_kmsg ( " Error: %s is a directory\n " , install_path.c_str ());
9841018 return -1 ;
9851019 }
9861020 if (remove (install_path.c_str ()) != 0 ) {
987- fprintf (stderr, " Error removing existing file %s\n " , install_path.c_str ());
1021+ log_to_kmsg ( " Error removing existing file %s\n " , install_path.c_str ());
9881022 return -1 ;
9891023 }
9901024 }
9911025
9921026 if (is_devnull (install_path.c_str ())) {
9931027 if (remove (install_path.c_str ()) != 0 ) {
994- fprintf (stderr, " Unable to remove existing symlink %s\n " , install_path.c_str ());
1028+ log_to_kmsg ( " Unable to remove existing symlink %s\n " , install_path.c_str ());
9951029 return -1 ;
9961030 }
9971031 }
9981032
9991033 if (symlink (original_path.c_str (), install_path.c_str ()) != 0 ) {
10001034 if (errno == EEXIST)
10011035 return 0 ;
1002- fprintf (stderr, " Error creating symlink %s -> %s (%s)\n " , install_path.c_str (), original_path.c_str (), strerror (errno));
1036+ log_to_kmsg ( " Error creating symlink %s -> %s (%s)\n " , install_path.c_str (), original_path.c_str (), strerror (errno));
10031037 return -1 ;
10041038 }
10051039
@@ -1082,7 +1116,7 @@ int ssg_main(int argc, char **argv) {
10821116#endif
10831117
10841118 if (argc <= 1 ) {
1085- fputs (" Installation directory required as argument\n " , stderr );
1119+ log_to_kmsg (" Installation directory required as argument\n " );
10861120 return 1 ;
10871121 }
10881122
@@ -1121,14 +1155,14 @@ int ssg_main(int argc, char **argv) {
11211155
11221156 num_targets = get_install_targets (unit_instance, targets);
11231157 if (num_targets < 0 ) {
1124- fprintf (stderr, " Error parsing %s\n " , unit_instance.c_str ());
1158+ log_to_kmsg ( " Error parsing %s\n " , unit_instance.c_str ());
11251159 free (unit_files[i]);
11261160 continue ;
11271161 }
11281162
11291163 for (int j = 0 ; j < num_targets; j++) {
11301164 if (install_unit_file (unit_instance, targets[j], install_dir) != 0 )
1131- fprintf (stderr, " Error installing %s to target directory %s\n " , unit_instance.c_str (), targets[j]);
1165+ log_to_kmsg ( " Error installing %s to target directory %s\n " , unit_instance.c_str (), targets[j]);
11321166
11331167 free (targets[j]);
11341168 }
0 commit comments