From 3f7dc3fd80e7fe548f89b96ab4228135dca688db Mon Sep 17 00:00:00 2001 From: Vo Trung Chi Date: Thu, 1 Aug 2019 07:38:42 +0700 Subject: using POSIX shared memory APIs (#90) (#151) Replace all Linux specific shared memory APIs with POSIX alternatives. Signed-off-by: Vo Trung Chi --- include/dlt/dlt_common.h | 7 + include/dlt/dlt_shm.h | 39 ++--- src/daemon/dlt-daemon.c | 33 +++- src/daemon/dlt-daemon.h | 5 +- src/lib/dlt_user.c | 22 +-- src/shared/dlt_common.c | 20 +++ src/shared/dlt_shm.c | 339 +++++++++++++++++++++++++++----------- tests/CMakeLists.txt | 9 + tests/gtest_dlt_daemon_gateway.sh | 14 +- tests/gtest_dlt_shm.cpp | 67 ++++++++ 10 files changed, 411 insertions(+), 144 deletions(-) create mode 100644 tests/gtest_dlt_shm.cpp diff --git a/include/dlt/dlt_common.h b/include/dlt/dlt_common.h index 94177e3..4f030a5 100644 --- a/include/dlt/dlt_common.h +++ b/include/dlt/dlt_common.h @@ -421,6 +421,13 @@ extern char dltSerialHeaderChar[DLT_ID_SIZE]; */ extern char dltFifoBaseDir[DLT_PATH_MAX]; +#ifdef DLT_SHM_ENABLE +/** + * The common name of the dlt-daemon and application share memory + */ +extern char dltShmName[NAME_MAX + 1]; +#endif + /** * The type of a DLT ID (context id, application id, etc.) */ diff --git a/include/dlt/dlt_shm.h b/include/dlt/dlt_shm.h index 92365b8..0c6ee42 100644 --- a/include/dlt/dlt_shm.h +++ b/include/dlt/dlt_shm.h @@ -55,28 +55,20 @@ #ifndef DLT_SHM_H #define DLT_SHM_H +#include #include "dlt_common.h" -/* shared memory key */ -/* must be the same for server and cleint */ -#define DLT_SHM_KEY 11771 - -/* default size of shared memory */ -/* size is extended during creation to fit segment size */ -/* client retreives real size from shm buffer */ +/** + * Default size of shared memory. + * size is extended during creation to fit segment size. + * client retrieves real size from file descriptor of shared memory. + */ #define DLT_SHM_SIZE 100000 -/* Id of the used semaphore */ -/* used for synchronisation of write and read access of multiple clients and server */ -/* must be the same for server and client */ -#define DLT_SHM_SEM 22771 - -#define DLT_SHM_HEAD "SHM" - typedef struct { - int shmid; /* Id of shared memory */ - int semid; /* Id of semaphore */ + int shmfd; /* file descriptor of shared memory */ + sem_t *sem; /* pointer to semaphore */ DltBuffer buffer; } DltShm; @@ -87,27 +79,27 @@ typedef struct int size; } DltShmBlockHead; -#define DLT_SHM_SEM_GET(id) dlt_shm_pv(id, -1) -#define DLT_SHM_SEM_FREE(id) dlt_shm_pv(id, 1) +#define DLT_SHM_SEM_GET(id) sem_wait(id) +#define DLT_SHM_SEM_FREE(id) sem_post(id) /** * Initialise the shared memory on the client side. * This function must be called before using further shm functions. * @param buf pointer to shm structure - * @param key the identifier of the shm, must be the same for server and client + * @param name the name of the shm, must be the same for server and client * @return negative value if there was an error */ -extern DltReturnValue dlt_shm_init_client(DltShm *buf, int key); +extern DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name); /** * Initialise the shared memory on the server side. * This function must be called before using further shm functions. * @param buf pointer to shm structure - * @param key the identifier of the shm, must be the same for server and client + * @param name the name of the shm, must be the same for server and client * @param size the requested size of the shm * @return negative value if there was an error */ -extern DltReturnValue dlt_shm_init_server(DltShm *buf, int key, int size); +extern DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size); /** * Push data from client onto the shm. @@ -216,8 +208,9 @@ extern int dlt_shm_recover(DltShm *buf); /** * Deinitialise the shared memory on the server side. * @param buf pointer to shm structure + * @param name name of the shared memory * @return negative value if there was an error */ -extern int dlt_shm_free_server(DltShm *buf); +extern DltReturnValue dlt_shm_free_server(DltShm *buf, const char *name); #endif /* DLT_SHM_H */ diff --git a/src/daemon/dlt-daemon.c b/src/daemon/dlt-daemon.c index 3c80434..2f18ca8 100644 --- a/src/daemon/dlt-daemon.c +++ b/src/daemon/dlt-daemon.c @@ -106,6 +106,12 @@ void usage() printf(" (Applications wanting to connect to a daemon using a\n"); printf(" custom directory need to be started with the environment \n"); printf(" variable DLT_PIPE_DIR set appropriately)\n"); +#ifdef DLT_SHM_ENABLE + printf(" -s filename The file name to create the share memory (Default: /dlt-shm)\n"); + printf(" (Applications wanting to connect to a daemon using a\n"); + printf(" custom shm name need to be started with the environment \n"); + printf(" variable DLT_SHM_NAME set appropriately)\n"); +#endif printf(" -p port port to monitor for incoming requests (Default: 3490)\n"); printf(" (Applications wanting to connect to a daemon using a custom\n"); printf(" port need to be started with the environment variable\n"); @@ -132,9 +138,17 @@ int option_handling(DltDaemonLocal *daemon_local, int argc, char *argv[]) strncpy(dltFifoBaseDir, DLT_USER_IPC_PATH, DLT_PATH_MAX); dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; +#ifdef DLT_SHM_ENABLE + strncpy(dltShmName, "/dlt-shm", NAME_MAX); +#endif + opterr = 0; +#ifdef DLT_SHM_ENABLE + while ((c = getopt (argc, argv, "hdc:t:s:p:")) != -1) +#else while ((c = getopt (argc, argv, "hdc:t:p:")) != -1) +#endif switch (c) { case 'd': { @@ -152,6 +166,13 @@ int option_handling(DltDaemonLocal *daemon_local, int argc, char *argv[]) dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; break; } +#ifdef DLT_SHM_ENABLE + case 's': + { + strncpy(dltShmName, optarg, NAME_MAX); + break; + } +#endif case 'p': { daemon_local->flags.port = atoi(optarg); @@ -192,9 +213,13 @@ int option_handling(DltDaemonLocal *daemon_local, int argc, char *argv[]) #ifndef DLT_USE_UNIX_SOCKET_IPC snprintf(daemon_local->flags.userPipesDir, DLT_PATH_MAX, "%s/dltpipes", dltFifoBaseDir); -#endif snprintf(daemon_local->flags.daemonFifoName, DLT_PATH_MAX, "%s/dlt", dltFifoBaseDir); +#endif + +#ifdef DLT_SHM_ENABLE + strncpy(daemon_local->flags.dltShmName, dltShmName, NAME_MAX); +#endif return 0; @@ -930,7 +955,9 @@ int dlt_daemon_local_init_p2(DltDaemon *daemon, DltDaemonLocal *daemon_local, in #ifdef DLT_SHM_ENABLE /* init shared memory */ - if (dlt_shm_init_server(&(daemon_local->dlt_shm), DLT_SHM_KEY, daemon_local->flags.sharedMemorySize) == -1) { + if (dlt_shm_init_server(&(daemon_local->dlt_shm), daemon_local->flags.dltShmName, + daemon_local->flags.sharedMemorySize) == DLT_RETURN_ERROR) + { dlt_log(LOG_ERR, "Could not initialize shared memory\n"); return -1; } @@ -1312,7 +1339,7 @@ void dlt_daemon_local_cleanup(DltDaemon *daemon, DltDaemonLocal *daemon_local, i #ifdef DLT_SHM_ENABLE /* free shared memory */ - dlt_shm_free_server(&(daemon_local->dlt_shm)); + dlt_shm_free_server(&(daemon_local->dlt_shm), daemon_local->flags.dltShmName); #endif if (daemon_local->flags.offlineLogstorageMaxDevices > 0) { diff --git a/src/daemon/dlt-daemon.h b/src/daemon/dlt-daemon.h index 39ccb91..4702b69 100644 --- a/src/daemon/dlt-daemon.h +++ b/src/daemon/dlt-daemon.h @@ -121,9 +121,12 @@ typedef struct char appSockPath[DLT_DAEMON_FLAG_MAX]; /**< Path to User socket */ #else char userPipesDir[DLT_PATH_MAX]; /**< (String: Directory) directory where dltpipes reside (Default: /tmp/dltpipes) */ -#endif char daemonFifoName[DLT_PATH_MAX]; /**< (String: Filename) name of local fifo (Default: /tmp/dlt) */ char daemonFifoGroup[DLT_PATH_MAX]; /**< (String: Group name) Owner group of local fifo (Default: Primary Group) */ +#endif +#ifdef DLT_SHM_ENABLE + char dltShmName[NAME_MAX + 1]; /**< Shared memory name */ +#endif unsigned int port; /**< port number */ char ctrlSockPath[DLT_DAEMON_FLAG_MAX]; /**< Path to Control socket */ int gatewayMode; /**< (Boolean) Gateway Mode */ diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index d040d38..4ae1fde 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -365,16 +365,12 @@ DltReturnValue dlt_init(void) memset(&(dlt_user.dlt_shm), 0, sizeof(DltShm)); /* init shared memory */ - if (dlt_shm_init_client(&(dlt_user.dlt_shm), DLT_SHM_KEY) < 0) { - dlt_vlog(LOG_WARNING, - "Logging disabled, Shared memory %d cannot be created!\n", - DLT_SHM_KEY); - /*return 0; */ - } + if (dlt_shm_init_client(&(dlt_user.dlt_shm), dltShmName) < DLT_RETURN_OK) + dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled," + " Shared memory %s cannot be created!\n", dltShmName); #endif #ifdef DLT_USE_UNIX_SOCKET_IPC - if (dlt_initialize_socket_connection() != DLT_RETURN_OK) /* We could connect to the pipe, but not to the socket, which is normally */ /* open before by the DLT daemon => bad failure => return error code */ @@ -382,7 +378,6 @@ DltReturnValue dlt_init(void) return DLT_RETURN_ERROR; #else /* FIFO connection */ - if (dlt_initialize_fifo_connection() != DLT_RETURN_OK) return DLT_RETURN_ERROR; @@ -391,7 +386,6 @@ DltReturnValue dlt_init(void) dlt_user_initialised = false; return DLT_RETURN_ERROR; } - #endif /* These will be lazy initialized only when needed */ @@ -4439,13 +4433,9 @@ void dlt_user_log_reattach_to_daemon(void) #ifdef DLT_SHM_ENABLE /* init shared memory */ - if (dlt_shm_init_client(&dlt_user.dlt_shm, DLT_SHM_KEY) < 0) - dlt_vnlog(LOG_WARNING, - DLT_USER_BUFFER_LENGTH, - "Loging disabled, Shared memory %d cannot be created!\n", - DLT_SHM_KEY); - /*return DLT_RETURN_OK; */ - + if (dlt_shm_init_client(&dlt_user.dlt_shm, dltShmName) < DLT_RETURN_OK) + dlt_vnlog(LOG_WARNING, DLT_USER_BUFFER_LENGTH, "Logging disabled," + " Shared memory %s cannot be created!\n", dltShmName); #endif dlt_log(LOG_NOTICE, "Logging (re-)enabled!\n"); diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 58896f6..8cb9413 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -67,6 +67,10 @@ const char dltSerialHeader[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 }; char dltSerialHeaderChar[DLT_ID_SIZE] = { 'D', 'L', 'S', 1 }; char dltFifoBaseDir[DLT_PATH_MAX] = "/tmp"; +#ifdef DLT_SHM_ENABLE +char dltShmName[NAME_MAX + 1] = "/dlt-shm"; +#endif + /* internal logging parameters */ static int logging_mode = DLT_LOG_TO_CONSOLE; static int logging_level = LOG_INFO; @@ -1703,6 +1707,14 @@ void dlt_log_set_fifo_basedir(const char *env_pipe_dir) dltFifoBaseDir[DLT_PATH_MAX - 1] = 0; } +#ifdef DLT_SHM_ENABLE +void dlt_log_set_shm_name(const char * env_shm_name) +{ + strncpy(dltShmName, env_shm_name, NAME_MAX); + dltShmName[NAME_MAX] = 0; +} +#endif + void dlt_log_init(int mode) { if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) { @@ -3704,6 +3716,14 @@ void dlt_check_envvar() if (env_pipe_dir != NULL) dlt_log_set_fifo_basedir(env_pipe_dir); + +#ifdef DLT_SHM_ENABLE + char* env_shm_name = getenv("DLT_SHM_NAME"); + if (env_shm_name != NULL) + { + dlt_log_set_shm_name(env_shm_name); + } +#endif } int dlt_set_loginfo_parse_service_id(char *resp_text, diff --git a/src/shared/dlt_shm.c b/src/shared/dlt_shm.c index 8fb3a72..e1c96b7 100644 --- a/src/shared/dlt_shm.c +++ b/src/shared/dlt_shm.c @@ -53,16 +53,16 @@ *******************************************************************************/ #include -#include -#include -#include +#include #include +#include #include #include +#include #if !defined(_MSC_VER) -# include -# include +#include +#include #endif #include @@ -82,114 +82,206 @@ void dlt_shm_print_hex(char *ptr, int size) printf("\n"); } -void dlt_shm_pv(int id, int operation) +DltReturnValue dlt_shm_init_server(DltShm *buf, const char *name, int size) { - static struct sembuf semaphor; - - semaphor.sem_op = operation; - semaphor.sem_flg = SEM_UNDO; - - if (semop(id, &semaphor, 1) == -1) - dlt_log(LOG_WARNING, "SHM: semop() failed"); -} - -int dlt_shm_init_server(DltShm *buf, int key, int size) -{ - struct shmid_ds shm_buf; unsigned char *ptr; - /* Init parameters */ - buf->shmid = 0; - buf->semid = 0; + /* Check if buffer and name available */ + if (buf == NULL || name == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return DLT_RETURN_WRONG_PARAMETER; + } - /* Create the segment. */ - if ((buf->shmid = shmget(key, size, IPC_CREAT | 0666)) < 0) { - dlt_log(LOG_WARNING, "SHM: shmget() failed"); + /* Init parameters */ + buf->shmfd = 0; + buf->sem = NULL; + + /** + * Create the shared memory segment. + * @name Name of the new shared memory object. + * (shm_open will create a file under /dev/shm/) + * @oflag O_CREAT | O_EXCL | O_RDWR + * O_CREAT | O_EXCL: The shm_open() fails if the shared memory exists. + * O_RDWR: Open the object for read-write access. + * @mode 0666 + * The shared memory object's permission. + */ + buf->shmfd = shm_open(name, O_CREAT | O_EXCL | O_RDWR, 0666); + if (buf->shmfd == -1) + { + dlt_vlog(LOG_ERR, "%s: shm_open() failed: %s\n", + __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } - /* get the size of shm */ - if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) { - dlt_log(LOG_WARNING, "SHM: shmctl() failed"); + /* Set the size of shm */ + if (ftruncate(buf->shmfd, size) == -1) + { + dlt_vlog(LOG_ERR, "%s: ftruncate() failed: %s\n", + __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } /* Now we attach the segment to our data space. */ - if ((ptr = shmat(buf->shmid, NULL, 0)) == (unsigned char *)-1) { - dlt_log(LOG_WARNING, "SHM: shmat() failed"); + ptr = (unsigned char *)mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + buf->shmfd, 0); + if (ptr == MAP_FAILED) + { + dlt_vlog(LOG_ERR, "%s: mmap() failed: %s\n", + __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } - /* Init semaphore */ - if ((buf->semid = semget(DLT_SHM_SEM, 1, S_IRWXU | S_IRWXG | S_IRWXO | IPC_CREAT | IPC_EXCL)) == -1) { - if ((buf->semid = semget(DLT_SHM_SEM, 1, S_IRWXU | S_IRWXG | S_IRWXO | IPC_EXCL)) == -1) { - dlt_log(LOG_WARNING, "SHM: semget() failed"); - return DLT_RETURN_ERROR; /* ERROR */ - } + /** + * Create the semaphore with input name + * @name name + * Name of the new semaphore + * (sem_open will create a file under /dev/shm/sem.) + * @oflag O_CREAT | O_EXCEL + * The sem_open() fails if the semaphore name exists. + * @mode 0777 + * The permissions to be placed on the new semaphore. + * @value 1 + * Initial value for the new semaphore. + */ + buf->sem = sem_open(name, O_CREAT | O_EXCL, 0666, 1); + if (buf->sem == SEM_FAILED) + { + dlt_vlog(LOG_ERR, "%s: sem_open() failed: %s\n", + __func__, strerror(errno)); + return DLT_RETURN_ERROR; /* ERROR */ } - if (semctl(buf->semid, 0, SETVAL, (int)1) == -1) { - dlt_log(LOG_WARNING, "SHM: semctl() failed"); + /* Init buffer */ + dlt_buffer_init_static_server(&(buf->buffer), ptr, size); + + /* The 'buf->shmfd' is no longer needed */ + if (close(buf->shmfd) == -1) + { + dlt_vlog(LOG_ERR, "%s: Failed to close shared memory" + " file descriptor: %s\n", __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } - /* init buffer */ - dlt_buffer_init_static_server(&(buf->buffer), ptr, shm_buf.shm_segsz); - return DLT_RETURN_OK; /* OK */ } -DltReturnValue dlt_shm_init_client(DltShm *buf, int key) +DltReturnValue dlt_shm_init_client(DltShm *buf, const char *name) { - struct shmid_ds shm_buf; + struct stat shm_buf; unsigned char *ptr; - /* init parameters */ - buf->shmid = 0; - buf->semid = 0; + /* Check if buffer and name available */ + if (buf == NULL || name == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return DLT_RETURN_WRONG_PARAMETER; + } - /* Create the segment. */ - if ((buf->shmid = shmget(key, 0, 0666)) < 0) { - dlt_log(LOG_WARNING, "SHM: shmget() failed"); + /* Init parameters */ + buf->shmfd = 0; + buf->sem = NULL; + + /** + * Open the existing shared memory segment created by the server. + * @name Name of the existing shared memory object. + * (shm_open will open the file under /dev/shm/) + * @oflag O_RDWR + * Open the object for read-write access. + * @mode 0 + * We are not creating a new object, this argument should be specified as 0. + */ + buf->shmfd = shm_open(name, O_RDWR, 0); + if (buf->shmfd == -1) + { + dlt_vlog(LOG_ERR, "%s: shm_open() failed: %s\n", + __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } - /* get the size of shm */ - if (shmctl(buf->shmid, IPC_STAT, &shm_buf)) { - dlt_log(LOG_WARNING, "SHM: shmctl() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + /* Get the size of shm */ + if (fstat(buf->shmfd, &shm_buf) == -1) + { + dlt_vlog(LOG_ERR, "%s: fstat() failed: %s\n", + __func__, strerror(errno)); + return DLT_RETURN_ERROR; /* ERROR */ } /* Now we attach the segment to our data space. */ - if ((ptr = shmat(buf->shmid, NULL, 0)) == (unsigned char *)-1) { - dlt_log(LOG_WARNING, "shmat() failed"); + ptr = (unsigned char *)mmap(NULL, shm_buf.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, buf->shmfd, 0); + if (ptr == MAP_FAILED) + { + dlt_vlog(LOG_ERR, "%s: mmap() failed: %s\n", + __func__, strerror(errno)); return DLT_RETURN_ERROR; /* ERROR */ } - /* Init semaphore */ - if ((buf->semid = semget(DLT_SHM_SEM, 0, 0)) == -1) { - dlt_log(LOG_WARNING, "SHM: semget() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + /** + * Open the existing semaphore with name created by the server + * The call requires only two arguments. + * @name name + * Name of the existing semaphore + * (sem_open will open a file under /dev/shm/sem.) + * @oflag 0 + * We are accessing an existing semaphore, oflag should be specified as 0. + */ + buf->sem = sem_open(name, 0); + if (buf->sem == SEM_FAILED) + { + dlt_vlog(LOG_ERR, "%s: sem_open() failed: %s\n", + __func__, strerror(errno)); + return DLT_RETURN_ERROR; /* ERROR */ } - /* init buffer */ - dlt_buffer_init_static_client(&(buf->buffer), ptr, shm_buf.shm_segsz); + /* Init buffer */ + dlt_buffer_init_static_client(&(buf->buffer), ptr, shm_buf.st_size); + + /* The 'buf->shmfd' is no longer needed */ + if (close(buf->shmfd) == -1) + { + dlt_vlog(LOG_ERR, "%s: Failed to close shared memory" + " file descriptor: %s\n", __func__, strerror(errno)); + return DLT_RETURN_ERROR; /* ERROR */ + } return DLT_RETURN_OK; /* OK */ } void dlt_shm_info(DltShm *buf) { + /* Check if buffer available */ + if (buf == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return; + } + dlt_buffer_info(&(buf->buffer)); } void dlt_shm_status(DltShm *buf) { + /* Check if buffer available */ + if (buf == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return; + } + dlt_buffer_status(&(buf->buffer)); } int dlt_shm_get_total_size(DltShm *buf) { + /* Check if buffer available */ + if (buf == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return -1; + } + return dlt_buffer_get_total_size(&(buf->buffer)); } @@ -197,19 +289,28 @@ int dlt_shm_get_used_size(DltShm *buf) { int ret; - /* check if buffer available */ - if (!buf->buffer.mem) + /* Check if buffer available */ + if ((buf == NULL) || (buf->buffer.mem == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; + } - DLT_SHM_SEM_GET(buf->semid); - ret = dlt_buffer_get_used_size(&(buf->buffer)); - DLT_SHM_SEM_FREE(buf->semid); + DLT_SHM_SEM_GET(buf->sem); + ret = dlt_buffer_get_used_size(&(buf->buffer)); + DLT_SHM_SEM_FREE(buf->sem); return ret; } int dlt_shm_get_message_count(DltShm *buf) { + /* Check if buffer available */ + if (buf == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return -1; + } return dlt_buffer_get_message_count(&(buf->buffer)); } @@ -223,13 +324,17 @@ int dlt_shm_push(DltShm *buf, { int ret; - /* check if buffer available */ - if (!buf->buffer.mem) + /* Check if buffer available */ + if ((buf == NULL) || (buf->buffer.mem == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; + } - DLT_SHM_SEM_GET(buf->semid); - ret = dlt_buffer_push3(&(buf->buffer), data1, size1, data2, size2, data3, size3); - DLT_SHM_SEM_FREE(buf->semid); + DLT_SHM_SEM_GET(buf->sem); + ret = dlt_buffer_push3(&(buf->buffer), + data1, size1, data2, size2, data3, size3); + DLT_SHM_SEM_FREE(buf->sem); return ret; } @@ -238,13 +343,16 @@ int dlt_shm_pull(DltShm *buf, unsigned char *data, int max_size) { int ret; - /* check if buffer available */ - if (!buf->buffer.mem) + /* Check if buffer available */ + if ((buf == NULL) || (buf->buffer.mem == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; + } - DLT_SHM_SEM_GET(buf->semid); + DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_pull(&(buf->buffer), data, max_size); - DLT_SHM_SEM_FREE(buf->semid); + DLT_SHM_SEM_FREE(buf->sem); return ret; } @@ -253,13 +361,16 @@ int dlt_shm_copy(DltShm *buf, unsigned char *data, int max_size) { int ret; - /* check if buffer available */ - if (!buf->buffer.mem) + /* Check if buffer available */ + if ((buf == NULL) || (buf->buffer.mem == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; + } - DLT_SHM_SEM_GET(buf->semid); + DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_copy(&(buf->buffer), data, max_size); - DLT_SHM_SEM_FREE(buf->semid); + DLT_SHM_SEM_FREE(buf->sem); return ret; } @@ -268,54 +379,82 @@ int dlt_shm_remove(DltShm *buf) { int ret; - /* check if buffer available */ - if (!buf->buffer.mem) + /* Check if buffer available */ + if ((buf == NULL) || (buf->buffer.mem == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); return -1; + } - DLT_SHM_SEM_GET(buf->semid); + DLT_SHM_SEM_GET(buf->sem); ret = dlt_buffer_remove(&(buf->buffer)); - DLT_SHM_SEM_FREE(buf->semid); + DLT_SHM_SEM_FREE(buf->sem); return ret; } -DltReturnValue dlt_shm_free_server(DltShm *buf) +DltReturnValue dlt_shm_free_server(DltShm *buf, const char *name) { + if ((buf == NULL) || (buf->buffer.shm == NULL) || name == NULL) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return DLT_RETURN_WRONG_PARAMETER; + } - if (shmdt(buf->buffer.shm)) { - dlt_log(LOG_WARNING, "SHM: shmdt() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + if (munmap(buf->buffer.shm, buf->buffer.min_size) == -1) + { + dlt_vlog(LOG_ERR, "%s: munmap() failed: %s\n", + __func__, strerror(errno)); } - if (shmctl(buf->shmid, IPC_RMID, NULL) == -1) { - dlt_log(LOG_WARNING, "SHM: shmdt() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + if (shm_unlink(name) == -1) + { + dlt_vlog(LOG_ERR, "%s: shm_unlink() failed: %s\n", + __func__, strerror(errno)); } - if (semctl(buf->semid, 0, IPC_RMID, (int)0) == -1) { - dlt_log(LOG_WARNING, "SHM: shmdt() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + if (sem_close(buf->sem) == -1) + { + dlt_vlog(LOG_ERR, "%s: sem_close() failed: %s\n", + __func__, strerror(errno)); + } + + if (sem_unlink(name) == -1) + { + dlt_vlog(LOG_ERR, "%s: sem_unlink() failed: %s\n", + __func__, strerror(errno)); } /* Reset parameters */ - buf->shmid = 0; - buf->semid = 0; + buf->shmfd = 0; + buf->sem = NULL; return dlt_buffer_free_static(&(buf->buffer)); - } DltReturnValue dlt_shm_free_client(DltShm *buf) { + if ((buf == NULL) || (buf->buffer.shm == NULL)) + { + dlt_vlog(LOG_ERR, "%s: Wrong parameter: Null pointer\n", __func__); + return DLT_RETURN_WRONG_PARAMETER; + } - if (shmdt(buf->buffer.shm)) { - dlt_log(LOG_WARNING, "SHM: shmdt() failed"); - return DLT_RETURN_ERROR; /* ERROR */ + if (munmap(buf->buffer.shm, buf->buffer.min_size) == -1) + { + dlt_vlog(LOG_ERR, "%s: munmap() failed: %s\n", + __func__, strerror(errno)); + } + + if (sem_close(buf->sem) == -1) + { + dlt_vlog(LOG_ERR, "%s: sem_close() failed: %s\n", + __func__, strerror(errno)); } /* Reset parameters */ - buf->shmid = 0; - buf->semid = 0; + buf->shmfd = 0; + buf->sem = NULL; return dlt_buffer_free_static(&(buf->buffer)); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 609a7a0..db9160c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,6 +28,11 @@ add_executable(dlt-test-preregister-context dlt-test-preregister-context.c) add_executable(gtest_dlt_daemon_gateway gtest_dlt_daemon_gateway.cpp ${systemd_SRCS}) add_executable(gtest_dlt_daemon_event_handler gtest_dlt_daemon_event_handler.cpp ${systemd_SRCS}) add_executable(gtest_dlt_daemon_offline_log gtest_dlt_daemon_offline_log.cpp ${systemd_SRCS}) + +if(WITH_DLT_SHM_ENABLE) + add_executable(gtest_dlt_shm gtest_dlt_shm.cpp) +endif(WITH_DLT_SHM_ENABLE) + target_link_libraries(gtest_dlt_common ${DLT_LIBRARIES}) target_link_libraries(gtest_dlt_user ${DLT_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_common ${DLT_LIBRARIES}) @@ -38,6 +43,10 @@ target_link_libraries(gtest_dlt_daemon_gateway ${DLT_DAEMON_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_event_handler ${DLT_DAEMON_LIBRARIES}) target_link_libraries(gtest_dlt_daemon_offline_log ${DLT_DAEMON_LIBRARIES}) +if(WITH_DLT_SHM_ENABLE) + target_link_libraries(gtest_dlt_shm ${DLT_DAEMON_LIBRARIES}) +endif(WITH_DLT_SHM_ENABLE) + if(WITH_DLT_CXX11_EXT) add_executable(dlt-test-cpp-extension dlt-test-cpp-extension.cpp) target_link_libraries(dlt-test-cpp-extension ${DLT_LIBRARIES}) diff --git a/tests/gtest_dlt_daemon_gateway.sh b/tests/gtest_dlt_daemon_gateway.sh index 6ce625b..d74f519 100755 --- a/tests/gtest_dlt_daemon_gateway.sh +++ b/tests/gtest_dlt_daemon_gateway.sh @@ -105,6 +105,10 @@ cleanup() rm -f $tmpPath/dlt.conf rm -f $tmpPath/dlt_gateway.conf + rm -f /dev/shm/dlt-shm + rm -f /dev/shm/sem.dlt-shm + rm -f /dev/shm/dlt-shm-passive + rm -f /dev/shm/sem.dlt-shm-passive return 0 } # @@ -171,9 +175,17 @@ setupTest() # startDaemons() { + DLT_PASSIVE_SHM_NAME="" tmpPath=/tmp dlt-daemon -d - dlt-daemon -d -p 3495 -c $tmpPath/dlt.conf + sleep 1 + + # Check if the dlt shm file exist (DLT_SHM_ENABLE=ON) + if [ -f /dev/shm/dlt-shm ]; then + DLT_PASSIVE_SHM_NAME="-s dlt-shm-passive" + fi + + dlt-daemon -d -p 3495 -c $tmpPath/dlt.conf $DLT_PASSIVE_SHM_NAME return 0 } diff --git a/tests/gtest_dlt_shm.cpp b/tests/gtest_dlt_shm.cpp new file mode 100644 index 0000000..7260080 --- /dev/null +++ b/tests/gtest_dlt_shm.cpp @@ -0,0 +1,67 @@ +#include +extern "C" +{ + #include "dlt_shm.h" +} + +DltShm *server_buf = (DltShm *)calloc(1, sizeof(DltShm)); +DltShm *client_buf = (DltShm *)calloc(1, sizeof(DltShm)); + +char *dltShmNameTest = (char *)"dlt-shm-test"; +int size = 1000; + +/* Method: dlt_shm::t_dlt_shm_init_server */ +TEST(t_dlt_shm_init_server, normal) +{ + EXPECT_EQ(DLT_RETURN_OK, dlt_shm_init_server(server_buf, dltShmNameTest, size)); +} + +/* Method: dlt_shm::t_dlt_shm_init_server */ +TEST(t_dlt_shm_init_server, nullpointer) +{ + EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_init_server(NULL, NULL, size)); +} + +/* Method: dlt_shm::t_dlt_shm_init_client */ +TEST(t_dlt_shm_init_client, normal) +{ + EXPECT_EQ(DLT_RETURN_OK, dlt_shm_init_client(client_buf, dltShmNameTest)); +} + +/* Method: dlt_shm::t_dlt_shm_init_client */ +TEST(t_dlt_shm_init_client, nullpointer) +{ + EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_init_client(NULL, NULL)); +} + +/* Method: dlt_shm::t_dlt_shm_free_client */ +TEST(t_dlt_shm_free_client, normal) +{ + EXPECT_EQ(DLT_RETURN_OK, dlt_shm_free_client(client_buf)); +} + +/* Method: dlt_shm::t_dlt_shm_free_client */ +TEST(t_dlt_shm_free_client, nullpointer) +{ + EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_free_client(NULL)); +} + +/* Method: dlt_shm::t_dlt_shm_free_server */ +TEST(t_dlt_shm_free_server, normal) +{ + EXPECT_EQ(DLT_RETURN_OK, dlt_shm_free_server(server_buf, dltShmNameTest)); +} + +/* Method: dlt_shm::t_dlt_shm_free_server */ +TEST(t_dlt_shm_free_server, nullpointer) +{ + EXPECT_EQ(DLT_RETURN_WRONG_PARAMETER, dlt_shm_free_server(NULL, NULL)); +} + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + ::testing::FLAGS_gtest_break_on_failure = false; + + return RUN_ALL_TESTS(); +} -- cgit v1.2.1