835 lines
19 KiB
C
835 lines
19 KiB
C
/*
|
|
* Copyright (c) Huawei Technologies Co., Ltd. 2012-2018. All rights reserved.
|
|
*
|
|
* Description: drivers to generate imonitor event struct and convert it
|
|
* to regular string which can be analysed by imonitor engine
|
|
* Author: yaomanhai <yaomanhai@huawei.com>
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/module.h>
|
|
#include <linux/types.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/string.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/version.h>
|
|
|
|
#include "huawei_platform/log/hw_log.h"
|
|
#include "huawei_platform/log/log_exception.h"
|
|
|
|
#include "huawei_platform/log/imonitor.h"
|
|
#include "huawei_platform/log/imonitor_events.h"
|
|
|
|
#define BIT_TYPE (1)
|
|
#define TINYINT_TYPE (2)
|
|
#define SMALLINT_TYPE (3)
|
|
#define INT_TYPE (4)
|
|
#define FLOAT_TYPE (5)
|
|
#define DATETIME_TYPE (6)
|
|
#define CLASS_TYPE (7)
|
|
#define BASE_TYPE_MAX CLASS_TYPE
|
|
#define VARCHAR_TYPE (100)
|
|
|
|
#define BIT_TYPE_LEN (1)
|
|
#define TINYINT_TYPE_LEN (1)
|
|
#define SMALLINT_TYPE_LEN (2)
|
|
#define INT_TYPE_LEN (4)
|
|
#define FLOAT_TYPE_LEN (4)
|
|
#define DATETIME_TYPE_LEN (20)
|
|
|
|
#define MASK_OFFSET_GET_OFFSET(m) ((m) & (unsigned int)0x7FFFFFFF)
|
|
#define MASK_OFFSET_SET_MASK(m) ((m) | ((unsigned int)1 << 31))
|
|
#define MASK_OFFSET_GET_MASK(m) ((m) >> 31)
|
|
|
|
#define MAX_PATH_NUMBER (10)
|
|
#define MAX_PATH_LEN (256)
|
|
#define MAX_STR_LEN (10*1024)
|
|
|
|
/*64K is max length of /dev/hwlog_exception*/
|
|
#define EVENT_INFO_BUF_LEN (64*1024)
|
|
#define EVENT_INFO_PACK_BUF_LEN (2*1024)
|
|
|
|
#define HWLOG_TAG imonitor
|
|
HWLOG_REGIST();
|
|
|
|
#define BUF_POINTER_FORWARD \
|
|
do { \
|
|
if (tmplen < len) { \
|
|
tmp += tmplen; \
|
|
len -= tmplen; \
|
|
} else { \
|
|
hwlog_err("string over length"); \
|
|
tmp += len; \
|
|
len = 0; \
|
|
} \
|
|
} while (0)
|
|
|
|
struct imonitor_param;
|
|
struct imonitor_param {
|
|
int key;
|
|
char *key_v2;
|
|
char *value;
|
|
struct imonitor_param *next;
|
|
};
|
|
|
|
/*event obj struct*/
|
|
struct imonitor_eventobj {
|
|
unsigned int eventid;
|
|
const unsigned short *desc;
|
|
unsigned int params_count;
|
|
char api_version;
|
|
|
|
/*record params linked list*/
|
|
struct imonitor_param *head;
|
|
/*time*/
|
|
long long time;
|
|
/*dynamic file path should be packed and uploaded*/
|
|
char *dynamic_path[MAX_PATH_NUMBER];
|
|
/*
|
|
* dynamic file path should be packed and uploaded, deleted
|
|
* after packing and uploading
|
|
*/
|
|
char *dynamic_path_delete[MAX_PATH_NUMBER];
|
|
};
|
|
|
|
#define CHECK_V1_API(obj) \
|
|
do { \
|
|
if (obj->api_version == 0) { \
|
|
obj->api_version = 1; \
|
|
} else if (obj->api_version == 2) { \
|
|
hwlog_err("cannot use v1 api (%s) after v2 api used", __FUNCTION__); \
|
|
return -1; \
|
|
} \
|
|
}while(0)
|
|
|
|
#define CHECK_V2_API(obj) \
|
|
do { \
|
|
if (obj->api_version == 0) { \
|
|
obj->api_version = 2; \
|
|
} else if (obj->api_version == 1) { \
|
|
hwlog_err("cannot use v2 api (%s) after v1 api used", __FUNCTION__); \
|
|
return -1; \
|
|
} \
|
|
}while(0)
|
|
|
|
#ifndef IMONITOR_NEW_API
|
|
int imonitor_set_param_integer(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid, long value);
|
|
|
|
int imonitor_set_param_string(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid, const char* value);
|
|
#endif
|
|
|
|
#ifndef IMONITOR_NEW_API_V2
|
|
int imonitor_set_param_integer_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param, long value);
|
|
|
|
int imonitor_set_param_string_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param, const char* value);
|
|
|
|
int imonitor_unset_param_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param);
|
|
#endif
|
|
|
|
static int imonitor_convert_string(struct imonitor_eventobj *eventobj, char **pbuf);
|
|
static struct imonitor_param* create_imonitor_param(void);
|
|
static void destroy_imonitor_param(struct imonitor_param* p);
|
|
static struct imonitor_param* get_imonitor_param(struct imonitor_param *head, int key, const char* key_s);
|
|
static void del_imonitor_param(struct imonitor_eventobj *obj, int key, const char* key_s);
|
|
static void add_imonitor_param(struct imonitor_eventobj *obj, struct imonitor_param *param);
|
|
|
|
static struct imonitor_param* create_imonitor_param(void)
|
|
{
|
|
struct imonitor_param* param = (struct imonitor_param *)vmalloc(sizeof(struct imonitor_param));
|
|
if (param == NULL) {
|
|
return NULL;
|
|
}
|
|
param->key = -1;
|
|
param->key_v2 = NULL;
|
|
param->value = NULL;
|
|
param->next = NULL;
|
|
return param;
|
|
}
|
|
|
|
static void destroy_imonitor_param(struct imonitor_param* p)
|
|
{
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
if (p->value != NULL) {
|
|
vfree(p->value);
|
|
}
|
|
if (p->key_v2 != NULL) {
|
|
kfree(p->key_v2);
|
|
}
|
|
vfree(p);
|
|
}
|
|
|
|
static struct imonitor_param* get_imonitor_param(struct imonitor_param *head, int key, const char* key_s)
|
|
{
|
|
struct imonitor_param *p = head;
|
|
while (p != NULL) {
|
|
if (key_s != NULL) {
|
|
if (strcmp(p->key_v2, key_s) == 0) {
|
|
return p;
|
|
}
|
|
} else if (p->key == key) {
|
|
return p;
|
|
}
|
|
p = p->next;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void del_imonitor_param(struct imonitor_eventobj *obj, int key, const char* key_s)
|
|
{
|
|
struct imonitor_param *prev = NULL;
|
|
struct imonitor_param *p = obj->head;
|
|
while (p != NULL) {
|
|
int is_found = 0;
|
|
if (key_s != NULL) {
|
|
if (strcmp(p->key_v2, key_s) == 0) {
|
|
is_found = 1;
|
|
}
|
|
} else if (p->key == key) {
|
|
is_found = 1;
|
|
}
|
|
if (is_found) {
|
|
if (prev == NULL) {
|
|
obj->head = p->next;
|
|
} else {
|
|
prev->next = p->next;
|
|
}
|
|
destroy_imonitor_param(p);
|
|
break;
|
|
}
|
|
prev = p;
|
|
p = p->next;
|
|
}
|
|
}
|
|
|
|
static void add_imonitor_param(struct imonitor_eventobj *obj, struct imonitor_param *param)
|
|
{
|
|
if (obj->head == NULL) {
|
|
obj->head = param;
|
|
} else {
|
|
struct imonitor_param *p = obj->head;
|
|
while (p->next != NULL) {
|
|
p = p->next;
|
|
}
|
|
p->next = param;
|
|
}
|
|
}
|
|
|
|
struct imonitor_eventobj *imonitor_create_eventobj(unsigned int eventid)
|
|
{
|
|
/*Look for module*/
|
|
unsigned int i;
|
|
|
|
const struct imonitor_module_index *module_index = NULL;
|
|
|
|
const struct imonitor_event_index *event_index = NULL;
|
|
|
|
struct imonitor_eventobj *eventobj = NULL;
|
|
|
|
for (i = 0; i < imonitor_modules_count; i++) {
|
|
if (eventid >= imonitor_modules_table[i].min_eventid
|
|
&& eventid <= imonitor_modules_table[i].max_eventid) {
|
|
module_index = &(imonitor_modules_table[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (NULL == module_index) {
|
|
//hwlog_err("Invalid eventid: %d", eventid);
|
|
} else {
|
|
/*Look for eventid description*/
|
|
for (i = 0; i < module_index->events_count; i++) {
|
|
if (eventid == module_index->events[i].eventid) {
|
|
event_index = &(module_index->events[i]);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (NULL == event_index) {
|
|
//hwlog_err("Invalid eventid: %d", eventid);
|
|
}
|
|
|
|
/*combined event obj struct*/
|
|
eventobj = vmalloc(sizeof(struct imonitor_eventobj));
|
|
if (NULL == eventobj)
|
|
return NULL;
|
|
eventobj->eventid = eventid;
|
|
eventobj->api_version = 0;
|
|
hwlog_info("imonitor_create_eventobj: %d", eventid);
|
|
|
|
/*Initial path NULL*/
|
|
for (i = 0; i < MAX_PATH_NUMBER; i++) {
|
|
eventobj->dynamic_path[i] = NULL;
|
|
eventobj->dynamic_path_delete[i] = NULL;
|
|
}
|
|
|
|
/*Time*/
|
|
eventobj->time = 0;
|
|
|
|
/*below are parameters related*/
|
|
if (NULL == event_index || 0 == event_index->params_count) {/*no parameters for this event*/
|
|
eventobj->params_count = 0;
|
|
eventobj->desc = NULL;
|
|
eventobj->head = NULL;
|
|
return (void *)eventobj;
|
|
}
|
|
|
|
eventobj->params_count = event_index->params_count;
|
|
eventobj->desc = event_index->desc;
|
|
eventobj->head = NULL;
|
|
|
|
return (void *)eventobj;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_create_eventobj);
|
|
|
|
int imonitor_set_param(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid, long value)
|
|
{
|
|
unsigned short type;
|
|
char *param;
|
|
|
|
if (NULL == eventobj) {
|
|
hwlog_err("Bad param for imonitor_set_param");
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (paramid >= eventobj->params_count) {
|
|
hwlog_err("Bad param for imonitor_set_param, paramid: %d",
|
|
paramid);
|
|
return -EINVAL;
|
|
}
|
|
|
|
type = eventobj->desc[paramid];
|
|
switch (type) {
|
|
case BIT_TYPE:
|
|
if (((char)value) > 1) {
|
|
hwlog_err("Invalid value for bit type, value: %d",
|
|
(int)value);
|
|
return -EINVAL;
|
|
}
|
|
/*go through down*/
|
|
case TINYINT_TYPE:
|
|
case SMALLINT_TYPE:
|
|
case INT_TYPE:
|
|
imonitor_set_param_integer(eventobj, paramid, value);
|
|
break;
|
|
case FLOAT_TYPE:
|
|
/* kernel not support float */
|
|
break;
|
|
case DATETIME_TYPE:
|
|
if (0 == value)
|
|
hwlog_err("Invalid value for datetime type");
|
|
else {
|
|
int len = DATETIME_TYPE_LEN;
|
|
param = (char*)vmalloc(len);
|
|
if (param == NULL) {
|
|
break;
|
|
}
|
|
strncpy((char *)param, (char *)value, len);
|
|
param[len - 1] = '\0';
|
|
imonitor_set_param_string(eventobj, paramid, param);
|
|
vfree(param);
|
|
}
|
|
break;
|
|
case CLASS_TYPE:
|
|
/* kernel not support class */
|
|
break;
|
|
default:
|
|
if (type > BASE_TYPE_MAX && type <= VARCHAR_TYPE) {
|
|
hwlog_err("type error: %d", type);
|
|
return -EINVAL;
|
|
}
|
|
if (0 == value)
|
|
hwlog_err("Invalid value for varchar type");
|
|
else {
|
|
int len = type - VARCHAR_TYPE;
|
|
if (len <= 0) {
|
|
break;
|
|
}
|
|
param = (char*)vmalloc(len);
|
|
if (param == NULL) {
|
|
break;
|
|
}
|
|
strncpy((char *)param, (char *)value, len);
|
|
param[len - 1] = '\0';
|
|
imonitor_set_param_string(eventobj,paramid, param);
|
|
vfree(param);
|
|
}
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_param);
|
|
|
|
int imonitor_set_param_integer(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid, long value)
|
|
{
|
|
struct imonitor_param *param;
|
|
if (NULL == eventobj) {
|
|
hwlog_err("Bad param for imonitor_set_param_integer");
|
|
return -EINVAL;
|
|
}
|
|
CHECK_V1_API(eventobj);
|
|
param = get_imonitor_param(eventobj->head, (int)paramid, NULL);
|
|
if (param == NULL) {
|
|
param = create_imonitor_param();
|
|
if (param == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
param->key = paramid;
|
|
add_imonitor_param(eventobj, param);
|
|
}
|
|
if (param->value != NULL) {
|
|
vfree(param->value);
|
|
}
|
|
param->value = (char*)vmalloc(21);
|
|
if (param->value == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
snprintf(param->value, 21, "%d", (int)value);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_param_integer);
|
|
|
|
int imonitor_set_param_string(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid, const char* value)
|
|
{
|
|
struct imonitor_param *param;
|
|
int len;
|
|
if (NULL == eventobj || NULL == value) {
|
|
hwlog_err("Bad param for imonitor_set_param_string");
|
|
return -EINVAL;
|
|
}
|
|
CHECK_V1_API(eventobj);
|
|
param = get_imonitor_param(eventobj->head, (int)paramid, NULL);
|
|
if (param == NULL) {
|
|
param = create_imonitor_param();
|
|
if (param == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
param->key = paramid;
|
|
add_imonitor_param(eventobj, param);
|
|
}
|
|
if (param->value != NULL) {
|
|
vfree(param->value);
|
|
}
|
|
len = strlen(value);
|
|
if (len > MAX_STR_LEN) {
|
|
// prevent length larger than MAX_STR_LEN
|
|
len = MAX_STR_LEN;
|
|
}
|
|
param->value = vmalloc(len + 1);
|
|
if (param->value == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
strncpy(param->value, value, len);
|
|
param->value[len] = '\0';
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_param_string);
|
|
|
|
int imonitor_unset_param(struct imonitor_eventobj *eventobj,
|
|
unsigned short paramid)
|
|
{
|
|
if (NULL == eventobj) {
|
|
hwlog_err("Bad param for imonitor_unset_param");
|
|
return -EINVAL;
|
|
}
|
|
|
|
CHECK_V1_API(eventobj);
|
|
del_imonitor_param(eventobj, (int)paramid, NULL);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_unset_param);
|
|
|
|
int imonitor_set_param_integer_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param, long value)
|
|
{
|
|
struct imonitor_param *i_param;
|
|
if (NULL == eventobj || NULL == param) {
|
|
hwlog_err("Bad param for imonitor_set_param_integer_v2");
|
|
return -EINVAL;
|
|
}
|
|
CHECK_V2_API(eventobj);
|
|
i_param = get_imonitor_param(eventobj->head, -1, param);
|
|
if (i_param == NULL) {
|
|
i_param = create_imonitor_param();
|
|
if (i_param == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
i_param->key_v2 = kstrdup(param, GFP_ATOMIC);
|
|
add_imonitor_param(eventobj, i_param);
|
|
}
|
|
if (i_param->value != NULL) {
|
|
vfree(i_param->value);
|
|
}
|
|
i_param->value = (char*)vmalloc(21);
|
|
if (i_param->value == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
snprintf(i_param->value, 21, "%d", (int)value);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_param_integer_v2);
|
|
|
|
int imonitor_set_param_string_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param, const char* value)
|
|
{
|
|
struct imonitor_param *i_param;
|
|
int len;
|
|
if (NULL == eventobj || NULL == param || NULL == value) {
|
|
hwlog_err("Bad param for imonitor_set_param_string_v2");
|
|
return -EINVAL;
|
|
}
|
|
CHECK_V2_API(eventobj);
|
|
i_param = get_imonitor_param(eventobj->head, -1, param);
|
|
if (i_param == NULL) {
|
|
i_param = create_imonitor_param();
|
|
if (i_param == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
i_param->key_v2 = kstrdup(param, GFP_ATOMIC);
|
|
add_imonitor_param(eventobj, i_param);
|
|
}
|
|
if (i_param->value != NULL) {
|
|
vfree(i_param->value);
|
|
}
|
|
len = strlen(value);
|
|
if (len > MAX_STR_LEN) {
|
|
// prevent length larger than MAX_STR_LEN
|
|
len = MAX_STR_LEN;
|
|
}
|
|
i_param->value = vmalloc(len + 1);
|
|
if (i_param->value == NULL) {
|
|
return -ENOMEM;
|
|
}
|
|
strncpy(i_param->value, value, len);
|
|
i_param->value[len] = '\0';
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_param_string_v2);
|
|
|
|
int imonitor_unset_param_v2(struct imonitor_eventobj *eventobj,
|
|
const char* param)
|
|
{
|
|
if (NULL == eventobj || NULL == param) {
|
|
hwlog_err("Bad param for imonitor_unset_param_v2");
|
|
return -EINVAL;
|
|
}
|
|
|
|
CHECK_V2_API(eventobj);
|
|
del_imonitor_param(eventobj, -1, param);
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_unset_param_v2);
|
|
|
|
int imonitor_set_time(struct imonitor_eventobj *eventobj, long long seconds)
|
|
{
|
|
if (NULL == eventobj || 0 == seconds) {
|
|
hwlog_err("Bad param for imonitor_set_time");
|
|
return -EINVAL;
|
|
}
|
|
eventobj->time = seconds;
|
|
return 0;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_set_time);
|
|
|
|
static int add_path(char **pool, const char *path)
|
|
{
|
|
int i;
|
|
|
|
if (NULL == path || 0 == path[0]) {
|
|
hwlog_err("Bad param add_path");
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (strlen(path) > MAX_PATH_LEN) {
|
|
hwlog_err("file path over max: %d", MAX_PATH_LEN);
|
|
return -EINVAL;
|
|
}
|
|
|
|
for (i = 0; i < MAX_PATH_NUMBER; i++) {
|
|
if (NULL != pool[i])
|
|
continue;
|
|
pool[i] = kstrdup(path, GFP_ATOMIC);
|
|
break;
|
|
}
|
|
|
|
if (MAX_PATH_NUMBER == i) {
|
|
hwlog_err("Too many pathes");
|
|
return -EINVAL;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int imonitor_add_dynamic_path(struct imonitor_eventobj *eventobj,
|
|
const char *path)
|
|
{
|
|
if (NULL == eventobj) {
|
|
hwlog_err("Bad param imonitor_add_dynamic_path");
|
|
return -EINVAL;
|
|
}
|
|
return add_path(eventobj->dynamic_path, path);
|
|
}
|
|
EXPORT_SYMBOL(imonitor_add_dynamic_path);
|
|
|
|
int imonitor_add_and_del_dynamic_path(struct imonitor_eventobj *eventobj,
|
|
const char *path)
|
|
{
|
|
if (NULL == eventobj) {
|
|
hwlog_err("Bad param imonitor_add_and_del_dynamic_path");
|
|
return -EINVAL;
|
|
}
|
|
return add_path(eventobj->dynamic_path_delete, path);
|
|
}
|
|
EXPORT_SYMBOL(imonitor_add_and_del_dynamic_path);
|
|
|
|
/* make string ":" to "::", ";" to ";;", and remove newline character
|
|
for example: "abc:def;ghi" transfer to "abc::def;;ghi" */
|
|
static char *make_regular(char *value)
|
|
{
|
|
int count = 0;
|
|
int len = 0;
|
|
char *temp, *regular, *regular_temp;
|
|
|
|
temp = value;
|
|
while (*temp != '\0') {
|
|
if (*temp == ':')
|
|
count++;
|
|
else if (*temp == ';')
|
|
count++;
|
|
else if (*temp == '\n' || *temp == '\r')
|
|
*temp = ' ';
|
|
temp++;
|
|
len++;
|
|
}
|
|
if (count == 0) {
|
|
/* no need to transfer, just return old value */
|
|
return value;
|
|
}
|
|
regular = vmalloc(len + count*2 + 1);
|
|
if (regular == NULL) {
|
|
return NULL;
|
|
}
|
|
regular_temp = regular;
|
|
temp = value;
|
|
while (*temp != 0) {
|
|
if (*temp == ':' || *temp == ';')
|
|
*regular_temp++ = *temp;
|
|
*regular_temp++ = *temp;
|
|
temp++;
|
|
}
|
|
*regular_temp = '\0';
|
|
return regular;
|
|
}
|
|
|
|
static int imonitor_convert_string(struct imonitor_eventobj *eventobj, char **pbuf)
|
|
{
|
|
int len;
|
|
char *tmp;
|
|
int tmplen;
|
|
unsigned int i = 0;
|
|
unsigned int keycount = 0;
|
|
struct imonitor_param *p;
|
|
char *buf = vmalloc(EVENT_INFO_BUF_LEN);
|
|
if(NULL == buf)
|
|
{
|
|
goto ERRORDONE;
|
|
}
|
|
|
|
len = EVENT_INFO_BUF_LEN;
|
|
tmp = buf;
|
|
/*fill eventid*/
|
|
tmplen = snprintf(tmp, len, "eventid %d", eventobj->eventid);
|
|
BUF_POINTER_FORWARD;
|
|
|
|
/*fill the path*/
|
|
for (i = 0; i < MAX_PATH_NUMBER; i++) {
|
|
if (NULL == eventobj->dynamic_path[i])
|
|
break;
|
|
tmplen = snprintf(tmp, len, " -i %s",
|
|
eventobj->dynamic_path[i]);
|
|
BUF_POINTER_FORWARD;
|
|
}
|
|
for (i = 0; i < MAX_PATH_NUMBER; i++) {
|
|
if (NULL == eventobj->dynamic_path_delete[i])
|
|
break;
|
|
tmplen = snprintf(tmp, len, " -d %s",
|
|
eventobj->dynamic_path_delete[i]);
|
|
BUF_POINTER_FORWARD;
|
|
}
|
|
|
|
/*fill time*/
|
|
if (eventobj->time) {
|
|
tmplen = snprintf(tmp, len, " -t %lld", eventobj->time);
|
|
BUF_POINTER_FORWARD;
|
|
}
|
|
|
|
/*fill the param info*/
|
|
keycount = 0;
|
|
p = eventobj->head;
|
|
while (p != NULL) {
|
|
char *value, *regular_value;
|
|
int need_free = 1;
|
|
|
|
if (p->value == NULL) {
|
|
p = p->next;
|
|
continue;
|
|
}
|
|
if (0 == keycount) {
|
|
tmplen = snprintf(tmp, len, " --extra ");
|
|
BUF_POINTER_FORWARD;
|
|
}
|
|
keycount++;
|
|
/*fill key*/
|
|
if (p->key_v2 != NULL) {
|
|
tmplen = snprintf(tmp, len, "%s:", p->key_v2);
|
|
} else {
|
|
tmplen = snprintf(tmp, len, "%d:", p->key);
|
|
}
|
|
BUF_POINTER_FORWARD;
|
|
/*fill value*/
|
|
tmplen = 0;
|
|
|
|
value = p->value;
|
|
regular_value = make_regular(value);
|
|
if (regular_value == NULL) {
|
|
regular_value = "NULL";
|
|
need_free = 0;
|
|
}
|
|
tmplen = snprintf(tmp, len, "%s;",
|
|
regular_value);
|
|
if (value != regular_value && need_free)
|
|
vfree(regular_value);
|
|
BUF_POINTER_FORWARD;
|
|
p = p->next;
|
|
}
|
|
|
|
*pbuf = buf;
|
|
return (EVENT_INFO_BUF_LEN - len);
|
|
|
|
ERRORDONE:
|
|
if (NULL != buf)
|
|
vfree(buf);
|
|
*pbuf = NULL;
|
|
return 0;
|
|
}
|
|
|
|
static int imonitor_write_log_exception(char *str, const int strlen)
|
|
{
|
|
char tempchr;
|
|
int nLeftBufLen = strlen+1;
|
|
char *strptr = str;
|
|
int sentcnt = 0;
|
|
|
|
while (nLeftBufLen > 0) {
|
|
if (nLeftBufLen <= EVENT_INFO_PACK_BUF_LEN) {
|
|
logbuf_to_exception(0, 0, IDAP_LOGTYPE_CMD, 0, strptr, nLeftBufLen);
|
|
sentcnt++;
|
|
break;
|
|
} else {
|
|
tempchr = strptr[EVENT_INFO_PACK_BUF_LEN-1];
|
|
strptr[EVENT_INFO_PACK_BUF_LEN-1] = '\0';
|
|
logbuf_to_exception(0, 0, IDAP_LOGTYPE_CMD, 1, strptr, EVENT_INFO_PACK_BUF_LEN);
|
|
nLeftBufLen -= (EVENT_INFO_PACK_BUF_LEN-1);
|
|
strptr += (EVENT_INFO_PACK_BUF_LEN-1);
|
|
strptr[0] = tempchr;
|
|
sentcnt++;
|
|
}
|
|
}
|
|
|
|
return sentcnt;
|
|
}
|
|
|
|
static void imonitor_file_lock(struct file *filp, int cmd)
|
|
{
|
|
struct file_lock *fl;
|
|
|
|
fl = locks_alloc_lock();
|
|
if (NULL == fl) {
|
|
hwlog_err("imonitor_file_lock alloc error");
|
|
return;
|
|
}
|
|
fl->fl_file = filp;
|
|
fl->fl_owner = filp;
|
|
fl->fl_pid = 0;
|
|
fl->fl_flags = FL_FLOCK;
|
|
fl->fl_type = cmd;
|
|
fl->fl_end = OFFSET_MAX;
|
|
#if (LINUX_VERSION_CODE > KERNEL_VERSION(4, 4, 0))
|
|
locks_lock_file_wait(filp, fl);
|
|
#else
|
|
flock_lock_file_wait(filp, fl);
|
|
#endif
|
|
locks_free_lock(fl);
|
|
}
|
|
|
|
int imonitor_send_event(struct imonitor_eventobj *obj)
|
|
{
|
|
char *str = NULL;
|
|
int buflen = 0;
|
|
int nSentPacket = 0;
|
|
struct file *fp;
|
|
|
|
if (NULL == obj) {
|
|
hwlog_err("Bad param imonitor_send_event");
|
|
return -EINVAL;
|
|
}
|
|
|
|
buflen = imonitor_convert_string(obj, &str);
|
|
if (NULL == str)
|
|
return -EINVAL;
|
|
|
|
fp = filp_open("/dev/hwlog_exception", O_WRONLY, 0);
|
|
if (IS_ERR(fp)) {
|
|
hwlog_info("imonitor_send_event open fail");
|
|
nSentPacket = imonitor_write_log_exception(str, buflen);
|
|
} else {
|
|
imonitor_file_lock(fp, F_WRLCK);
|
|
nSentPacket = imonitor_write_log_exception(str, buflen);
|
|
imonitor_file_lock(fp, F_UNLCK);
|
|
filp_close(fp, 0);
|
|
}
|
|
hwlog_info("imonitor send event: %s", str);
|
|
vfree(str);
|
|
return nSentPacket;
|
|
}
|
|
EXPORT_SYMBOL(imonitor_send_event);
|
|
|
|
void imonitor_destroy_eventobj(struct imonitor_eventobj *eventobj)
|
|
{
|
|
int i;
|
|
struct imonitor_param *p;
|
|
if (NULL == eventobj)
|
|
return;
|
|
|
|
p = eventobj->head;
|
|
while (p != NULL) {
|
|
struct imonitor_param *del = p;
|
|
p = p->next;
|
|
destroy_imonitor_param(del);
|
|
}
|
|
eventobj->head = NULL;
|
|
|
|
for (i = 0; i < MAX_PATH_NUMBER; i++) {
|
|
if (eventobj->dynamic_path[i] != NULL) {
|
|
kfree(eventobj->dynamic_path[i]);
|
|
eventobj->dynamic_path[i] = NULL;
|
|
}
|
|
if (eventobj->dynamic_path_delete[i] != NULL) {
|
|
kfree(eventobj->dynamic_path_delete[i]);
|
|
eventobj->dynamic_path_delete[i] = NULL;
|
|
}
|
|
}
|
|
|
|
vfree(eventobj);
|
|
}
|
|
EXPORT_SYMBOL(imonitor_destroy_eventobj);
|