Skip to content
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

dlt-qnx-system improvement #495

Merged
merged 1 commit into from
Jun 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions doc/dlt-qnx-system.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,20 @@ The description field is in the registration with libdlt.
}
}
```


### Runtime enable/disable slog2 adapter

The slog2 parser callback can be disabled and reenabled at runtime by using an injection.

| App ID | Context ID | Service ID | Data | Description |
|--------|------------|------------|------|------------------------|
| QSYM | QSYC | 0x1000 | 00 | Disable slog2 adapter |
| QSYM | QSYC | 0x1000 | 01 | Reenable slog2 adapter |

### Example:

```bash
dlt-control -e QNX -a QSYM -c QSYC -s 4096 -m "00" -u
dlt-control -e QNX -a QSYM -c QSYC -s 4096 -m "01" -u
```
37 changes: 28 additions & 9 deletions src/dlt-qnx-system/dlt-qnx-slogger2-adapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ extern DltContext dltQnxSystem;
static DltContext dltQnxSlogger2Context;

extern DltQnxSystemThreads g_threads;

extern volatile bool g_inj_disable_slog2_cb;

static std::unordered_map<std::string, DltContext*> g_slog2file;

static void dlt_context_map_read(const char *json_filename)
Expand Down Expand Up @@ -137,8 +140,11 @@ static int sloggerinfo_callback(slog2_packet_info_t *info, void *payload, void *
if (param == NULL)
return -1;

if (info->data_type == SLOG2_TYPE_ONLINE)
info->severity = SLOG2_INFO;
if (g_inj_disable_slog2_cb == true) {
DLT_LOG(dltQnxSystem, DLT_LOG_INFO,
DLT_STRING("Disabling slog2 callback by injection request."));
return -1;
}

DltLogLevelType loglevel;
switch (info->severity)
Expand Down Expand Up @@ -206,6 +212,7 @@ static int sloggerinfo_callback(slog2_packet_info_t *info, void *payload, void *

static void *slogger2_thread(void *v_conf)
{
int ret = -1;
DltQnxSystemConfiguration *conf = (DltQnxSystemConfiguration *)v_conf;

if (v_conf == NULL)
Expand All @@ -215,18 +222,15 @@ static void *slogger2_thread(void *v_conf)

DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
DLT_STRING("dlt-qnx-slogger2-adapter, in thread."));
DLT_REGISTER_CONTEXT(dltQnxSlogger2Context, conf->qnxslogger2.contextId,
"SLOGGER2 Adapter");

dlt_context_map_read(CONFIGURATION_FILES_DIR "/dlt-slog2ctxt.json");

/**
* Thread will block inside this function to get new log because
* flag = SLOG2_PARSE_FLAGS_DYNAMIC
*/
int ret = slog2_parse_all(
ret = slog2_parse_all(
SLOG2_PARSE_FLAGS_DYNAMIC, /* live streaming of all buffers merged */
NULL, NULL, &packet_info, sloggerinfo_callback, (void*) conf);

if (ret == -1) {
DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_ERROR,
"slog2_parse_all() returned error=", ret);
Expand All @@ -237,8 +241,18 @@ static void *slogger2_thread(void *v_conf)

DLT_UNREGISTER_CONTEXT(dltQnxSlogger2Context);

/* Send a signal to main thread to wake up sigwait */
pthread_kill(g_threads.mainThread, SIGTERM);
/* process should be shutdown if the callback was not manually disabled */
if (g_inj_disable_slog2_cb == false) {
for (auto& x: g_slog2file) {
if(x.second != NULL) {
delete(x.second);
x.second = NULL;
}
}
/* Send a signal to main thread to wake up sigwait */
pthread_kill(g_threads.mainThread, SIGTERM);
}

return reinterpret_cast<void*>(ret);
}

Expand All @@ -247,6 +261,11 @@ void start_qnx_slogger2(DltQnxSystemConfiguration *conf)
static pthread_attr_t t_attr;
static pthread_t pt;

DLT_REGISTER_CONTEXT(dltQnxSlogger2Context, conf->qnxslogger2.contextId,
"SLOGGER2 Adapter");

dlt_context_map_read(CONFIGURATION_FILES_DIR "/dlt-slog2ctxt.json");

DLT_LOG_CXX(dltQnxSlogger2Context, DLT_LOG_DEBUG,
"dlt-qnx-slogger2-adapter, start syslog");
pthread_create(&pt, &t_attr, slogger2_thread, conf);
Expand Down
151 changes: 99 additions & 52 deletions src/dlt-qnx-system/dlt-qnx-system.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <sys/types.h>
#include <fcntl.h>
#include <err.h>
#include <stdbool.h>

#include "dlt.h"
#include "dlt-qnx-system.h"
Expand All @@ -36,18 +37,30 @@ DLT_DECLARE_CONTEXT(dltQnxSystem)
/* Global variables */
volatile DltQnxSystemThreads g_threads;

#define INJECTION_SLOG2_ADAPTER 4096

#define DATA_DISABLED "00"
#define DATA_ENABLED "01"

volatile bool g_inj_disable_slog2_cb = false;

/* Function prototype */
static void daemonize();
static void start_threads(DltQnxSystemConfiguration *config);
static void start_threads();
static void join_threads();
static int read_configuration_file(DltQnxSystemConfiguration *config,
const char *file_name);
static int read_configuration_file(const char *file_name);
static int read_command_line(DltQnxSystemCliOptions *options, int argc, char *argv[]);

static int dlt_injection_cb(uint32_t service_id, void *data, uint32_t length);

static DltQnxSystemConfiguration *g_dlt_qnx_conf = NULL;
static void init_configuration();
static void clean_up();


int main(int argc, char* argv[])
{
DltQnxSystemCliOptions options;
DltQnxSystemConfiguration config;
int sigNo = 0;
int ret = 0;
sigset_t mask;
Expand All @@ -59,7 +72,7 @@ int main(int argc, char* argv[])
return -1;
}

if (read_configuration_file(&config, options.configurationFileName) < 0)
if (read_configuration_file(options.configurationFileName) < 0)
{
fprintf(stderr, "Failed to read configuration file!\n");
return -1;
Expand All @@ -82,17 +95,19 @@ int main(int argc, char* argv[])
return -1;
}

DLT_REGISTER_APP(config.applicationId, "DLT QNX System");
DLT_REGISTER_CONTEXT(dltQnxSystem, config.applicationContextId,
DLT_REGISTER_APP(g_dlt_qnx_conf->applicationId, "DLT QNX System");
DLT_REGISTER_CONTEXT(dltQnxSystem, g_dlt_qnx_conf->applicationContextId,
"Context of main dlt qnx system manager");
dlt_register_injection_callback(&dltQnxSystem,
INJECTION_SLOG2_ADAPTER, dlt_injection_cb);

DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
DLT_STRING("Setting signals wait for abnormal exit"));

g_threads.mainThread = pthread_self();

DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG, DLT_STRING("Launching threads."));
start_threads(&config);
start_threads();

ret = sigwait(&mask, &sigNo);

Expand All @@ -114,6 +129,7 @@ int main(int argc, char* argv[])
DLT_STRING(strsignal(sigNo)));

DLT_UNREGISTER_APP_FLUSH_BUFFERED_LOGS();
clean_up();
return 0;

}
Expand Down Expand Up @@ -193,23 +209,22 @@ static int read_command_line(DltQnxSystemCliOptions *options, int argc, char *ar
/**
* Initialize configuration to default values.
*/
static void init_configuration(DltQnxSystemConfiguration *config)
static void init_configuration()
{
g_dlt_qnx_conf = calloc(1, sizeof(DltQnxSystemConfiguration));
/* Common */
config->applicationId = "QSYM";
config->applicationContextId = "QSYC";

g_dlt_qnx_conf->applicationId = strdup("QSYM");
g_dlt_qnx_conf->applicationContextId = strdup("QSYC");
/* Slogger2 */
config->qnxslogger2.enable = 0;
config->qnxslogger2.contextId = "QSLA";
config->qnxslogger2.useOriginalTimestamp = 1;
g_dlt_qnx_conf->qnxslogger2.enable = 0;
g_dlt_qnx_conf->qnxslogger2.contextId = strdup("QSLA");
g_dlt_qnx_conf->qnxslogger2.useOriginalTimestamp = 1;
}

/**
* Read options from the configuration file
*/
static int read_configuration_file(DltQnxSystemConfiguration *config,
const char *file_name)
static int read_configuration_file(const char *file_name)
{
FILE *file;
char *line;
Expand All @@ -218,12 +233,16 @@ static int read_configuration_file(DltQnxSystemConfiguration *config,
char *pch;
int ret = 0;

init_configuration(config);
init_configuration();
if (g_dlt_qnx_conf == NULL) {
fprintf(stderr,
"dlt-qnx-system, could not allocate memory.\n");
return -1;
}

file = fopen(file_name, "r");

if (file == NULL)
{
if (file == NULL) {
fprintf(stderr,
"dlt-qnx-system, could not open configuration file.\n");
return -1;
Expand Down Expand Up @@ -270,42 +289,34 @@ static int read_configuration_file(DltQnxSystemConfiguration *config,
/* Common */
if (strcmp(token, "ApplicationId") == 0)
{
config->applicationId = (char *)malloc(strlen(value) + 1);
MALLOC_ASSERT(config->applicationId);
/**
* strcpy unritical here, because size matches exactly the
* size to be copied
*/
strcpy(config->applicationId, value);
if (g_dlt_qnx_conf->applicationId)
free(g_dlt_qnx_conf->applicationId);
g_dlt_qnx_conf->applicationId = strndup(value, DLT_ID_SIZE);
MALLOC_ASSERT(g_dlt_qnx_conf->applicationId);
}
else if (strcmp(token, "ApplicationContextID") == 0)
{
config->applicationContextId = (char *)malloc(strlen(value) + 1);
MALLOC_ASSERT(config->applicationContextId);
/**
* strcpy unritical here, because size matches exactly
* the size to be copied
*/
strcpy(config->applicationContextId, value);
if (g_dlt_qnx_conf->applicationContextId)
free(g_dlt_qnx_conf->applicationContextId);
g_dlt_qnx_conf->applicationContextId = strndup(value, DLT_ID_SIZE);
MALLOC_ASSERT(g_dlt_qnx_conf->applicationContextId);
strncpy(g_dlt_qnx_conf->applicationContextId, value, DLT_ID_SIZE);
}
/* Slogger2 */
else if (strcmp(token, "QnxSlogger2Enable") == 0)
{
config->qnxslogger2.enable = atoi(value);
g_dlt_qnx_conf->qnxslogger2.enable = atoi(value);
}
else if (strcmp(token, "QnxSlogger2ContextId") == 0)
{
config->qnxslogger2.contextId = (char *)malloc(strlen(value) + 1);
MALLOC_ASSERT(config->qnxslogger2.contextId);
/**
* strcpy unritical here, because size matches exactly
* the size to be copied
*/
strcpy(config->qnxslogger2.contextId, value);
if (g_dlt_qnx_conf->qnxslogger2.contextId)
free(g_dlt_qnx_conf->qnxslogger2.contextId);
g_dlt_qnx_conf->qnxslogger2.contextId = strndup(value, DLT_ID_SIZE);
MALLOC_ASSERT(g_dlt_qnx_conf->qnxslogger2.contextId);
}
else if (strcmp(token, "QnxSlogger2UseOriginalTimestamp") == 0)
{
config->qnxslogger2.useOriginalTimestamp = atoi(value);
g_dlt_qnx_conf->qnxslogger2.useOriginalTimestamp = atoi(value);
}
else
{
Expand Down Expand Up @@ -372,16 +383,10 @@ static void daemonize()
signal(SIGTTIN, SIG_IGN);
}

static void start_threads(DltQnxSystemConfiguration *config)
static void start_threads()
{
int i = 0;

/* Check parameter */
if (!config)
{
return;
}

DLT_LOG(dltQnxSystem, DLT_LOG_DEBUG,
DLT_STRING("dlt-qnx-system, start threads"));

Expand All @@ -393,9 +398,9 @@ static void start_threads(DltQnxSystemConfiguration *config)
g_threads.threads[i] = 0;
}

if (config->qnxslogger2.enable)
if (g_dlt_qnx_conf->qnxslogger2.enable)
{
start_qnx_slogger2(config);
start_qnx_slogger2(g_dlt_qnx_conf);
}
}

Expand Down Expand Up @@ -430,3 +435,45 @@ static void join_threads()

DLT_UNREGISTER_CONTEXT(dltQnxSystem);
}

static int dlt_injection_cb(uint32_t service_id, void *data, uint32_t length)
{
(void) length;
DLT_LOG(dltQnxSystem, DLT_LOG_INFO,
DLT_STRING("Injection received:"),
DLT_INT32(service_id));

if (service_id != INJECTION_SLOG2_ADAPTER)
return -1;

if (0 == strncmp((char*) data, DATA_DISABLED, sizeof(DATA_DISABLED)-1))
g_inj_disable_slog2_cb = true;
else if (0 == strncmp((char*) data, DATA_ENABLED, sizeof(DATA_ENABLED)-1)) {
if (g_inj_disable_slog2_cb == true) {
g_inj_disable_slog2_cb = false;
start_threads();
}
}

return 0;
}

static void clean_up()
{
if (g_dlt_qnx_conf->applicationId) {
free(g_dlt_qnx_conf->applicationId);
g_dlt_qnx_conf->applicationId = NULL;
}
if (g_dlt_qnx_conf->applicationContextId) {
free(g_dlt_qnx_conf->applicationContextId);
g_dlt_qnx_conf->applicationContextId = NULL;
}
if (g_dlt_qnx_conf->qnxslogger2.contextId) {
free(g_dlt_qnx_conf->qnxslogger2.contextId);
g_dlt_qnx_conf->qnxslogger2.contextId = NULL;
}
if (g_dlt_qnx_conf) {
free(g_dlt_qnx_conf);
g_dlt_qnx_conf = NULL;
}
}