Skip to content

Commit 4d5d36f

Browse files
Move logs for systemd-sonic-generator into /dev/kmsg (#34)
* move logs for systemd-sonic-generator into /dev/kmsg * Apply suggestion from @saiarcot895 Use stpncpy to build kmsg log strings Co-authored-by: Saikrishna Arcot <[email protected]> --------- Co-authored-by: Saikrishna Arcot <[email protected]> Co-authored-by: Saikrishna Arcot <[email protected]>
1 parent 16985cc commit 4d5d36f

1 file changed

Lines changed: 71 additions & 37 deletions

File tree

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

Lines changed: 71 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,40 @@
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
*/
955989
static 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

Comments
 (0)