X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Feal_common_trace_utils.c;h=64f58fb66a1576b5c8d69e9b7d984fc7d0c49604;hb=84fb33fec179ea96f814aed9f658d5a2df20745d;hp=503d0ab3d968927bc492747a78bf25af205a1735;hpb=29d985cad8dbf3920cbcbd470e6509f67ce9cd6c;p=dpdk.git diff --git a/lib/librte_eal/common/eal_common_trace_utils.c b/lib/librte_eal/common/eal_common_trace_utils.c index 503d0ab3d9..64f58fb66a 100644 --- a/lib/librte_eal/common/eal_common_trace_utils.c +++ b/lib/librte_eal/common/eal_common_trace_utils.c @@ -118,6 +118,152 @@ fail: return -rte_errno; } +static int +trace_dir_update(const char *str) +{ + struct trace *trace = trace_obj_get(); + int rc, remaining; + + remaining = sizeof(trace->dir) - trace->dir_offset; + rc = rte_strscpy(&trace->dir[0] + trace->dir_offset, str, remaining); + if (rc < 0) + goto fail; + + trace->dir_offset += rc; +fail: + return rc; +} + +int +eal_trace_args_save(const char *val) +{ + struct trace *trace = trace_obj_get(); + struct trace_arg *arg = malloc(sizeof(*arg)); + + if (arg == NULL) { + trace_err("failed to allocate memory for %s", val); + return -ENOMEM; + } + + arg->val = strdup(val); + if (arg->val == NULL) { + trace_err("failed to allocate memory for %s", val); + free(arg); + return -ENOMEM; + } + + STAILQ_INSERT_TAIL(&trace->args, arg, next); + return 0; +} + +void +eal_trace_args_free(void) +{ + struct trace *trace = trace_obj_get(); + struct trace_arg *arg; + + while (!STAILQ_EMPTY(&trace->args)) { + arg = STAILQ_FIRST(&trace->args); + STAILQ_REMOVE_HEAD(&trace->args, next); + free(arg->val); + free(arg); + } +} + +int +trace_args_apply(const char *arg) +{ + if (rte_trace_regexp(arg, true) < 0) { + trace_err("cannot enable trace for %s", arg); + return -1; + } + + return 0; +} + +int +eal_trace_bufsz_args_save(char const *val) +{ + struct trace *trace = trace_obj_get(); + uint64_t bufsz; + + bufsz = rte_str_to_size(val); + if (bufsz == 0) { + trace_err("buffer size cannot be zero"); + return -EINVAL; + } + + trace->buff_len = bufsz; + return 0; +} + +void +trace_bufsz_args_apply(void) +{ + struct trace *trace = trace_obj_get(); + + if (trace->buff_len == 0) + trace->buff_len = 1024 * 1024; /* 1MB */ +} + +int +eal_trace_mode_args_save(const char *val) +{ + struct trace *trace = trace_obj_get(); + size_t len = strlen(val); + unsigned long tmp; + char *pattern; + + if (len == 0) { + trace_err("value is not provided with option"); + return -EINVAL; + } + + pattern = (char *)calloc(1, len + 2); + if (pattern == NULL) { + trace_err("fail to allocate memory"); + return -ENOMEM; + } + + sprintf(pattern, "%s*", val); + + if (fnmatch(pattern, "overwrite", 0) == 0) + tmp = RTE_TRACE_MODE_OVERWRITE; + else if (fnmatch(pattern, "discard", 0) == 0) + tmp = RTE_TRACE_MODE_DISCARD; + else { + free(pattern); + return -EINVAL; + } + + trace->mode = tmp; + free(pattern); + return 0; +} + +int +eal_trace_dir_args_save(char const *val) +{ + struct trace *trace = trace_obj_get(); + char *dir_path; + int rc; + + if (strlen(val) >= sizeof(trace->dir) - 1) { + trace_err("input string is too big"); + return -ENAMETOOLONG; + } + + if (asprintf(&dir_path, "%s/", val) == -1) { + trace_err("failed to copy directory: %s", strerror(errno)); + return -ENOMEM; + } + + rc = trace_dir_update(dir_path); + + free(dir_path); + return rc; +} + int trace_epoch_time_save(void) { @@ -188,6 +334,10 @@ trace_mkdir(void) return rc; } + rc = trace_dir_update(dir_path); + free(dir_path); + if (rc < 0) + return rc; } /* Create the path if it t exist, no "mkdir -p" available here */ @@ -199,6 +349,9 @@ trace_mkdir(void) } rc = trace_session_name_generate(session); + if (rc < 0) + return rc; + rc = trace_dir_update(session); if (rc < 0) return rc; @@ -213,3 +366,83 @@ trace_mkdir(void) return 0; } +static int +trace_meta_save(struct trace *trace) +{ + char file_name[PATH_MAX]; + FILE *f; + int rc; + + rc = snprintf(file_name, PATH_MAX, "%s/metadata", trace->dir); + if (rc < 0) + return rc; + + f = fopen(file_name, "w"); + if (f == NULL) + return -errno; + + rc = rte_trace_metadata_dump(f); + + if (fclose(f)) + rc = -errno; + + return rc; +} + + +static inline int +trace_file_sz(struct __rte_trace_header *hdr) +{ + return sizeof(struct __rte_trace_stream_header) + hdr->offset; +} + +static int +trace_mem_save(struct trace *trace, struct __rte_trace_header *hdr, + uint32_t cnt) +{ + char file_name[PATH_MAX]; + FILE *f; + int rc; + + rc = snprintf(file_name, PATH_MAX, "%s/channel0_%d", trace->dir, cnt); + if (rc < 0) + return rc; + + f = fopen(file_name, "w"); + if (f == NULL) + return -errno; + + rc = fwrite(&hdr->stream_header, trace_file_sz(hdr), 1, f); + rc = (rc == 1) ? 0 : -EACCES; + + if (fclose(f)) + rc = -errno; + + return rc; +} + +int +rte_trace_save(void) +{ + struct trace *trace = trace_obj_get(); + struct __rte_trace_header *header; + uint32_t count; + int rc = 0; + + if (trace->nb_trace_mem_list == 0) + return rc; + + rc = trace_meta_save(trace); + if (rc) + return rc; + + rte_spinlock_lock(&trace->lock); + for (count = 0; count < trace->nb_trace_mem_list; count++) { + header = trace->lcore_meta[count].mem; + rc = trace_mem_save(trace, header, count); + if (rc) + break; + } + rte_spinlock_unlock(&trace->lock); + return rc; +}