@@ -40,8 +40,7 @@ given _instance_. If _instance_ is NULL, the top trace instance is used.
RETURN VALUE
------------
The _tracefs_options_get_supported()_ and _tracefs_options_get_enabled()_ functions return pointer
-to allocated bitmask with trace options, or NULL in case of an error. The returned bitmask must be
-freed with free();
+to allocated bitmask with trace options, or NULL in case of an error.
The _tracefs_option_is_supported()_ and _tracefs_option_is_enabled()_ functions return true if the
option in supported / enabled, or false otherwise.
@@ -52,14 +51,13 @@ EXAMPLE
--
#include <tracefs.h>
...
-struct tracefs_options_mask *options;
+const struct tracefs_options_mask *options;
...
options = tracefs_options_get_supported(NULL);
if (!options) {
/* Failed to get supported options */
} else {
...
- free(options);
}
...
options = tracefs_options_get_enabled(NULL);
@@ -67,7 +65,6 @@ if (!options) {
/* Failed to get options, enabled in the top instance */
} else {
...
- free(options);
}
...
@@ -25,6 +25,8 @@ struct tracefs_instance {
int flags;
int ftrace_filter_fd;
int ftrace_notrace_fd;
+ struct tracefs_options_mask supported_opts;
+ struct tracefs_options_mask enabled_opts;
};
extern pthread_mutex_t toplevel_lock;
@@ -48,4 +50,10 @@ char *trace_find_tracing_dir(void);
#define DEFFILEMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH) /* 0666*/
#endif
+struct tracefs_options_mask *
+supported_opts_mask(struct tracefs_instance *instance);
+
+struct tracefs_options_mask *
+enabled_opts_mask(struct tracefs_instance *instance);
+
#endif /* _TRACE_FS_LOCAL_H */
@@ -132,7 +132,7 @@ enum tracefs_option_id {
#define TRACEFS_OPTION_MAX (TRACEFS_OPTION_VERBOSE + 1)
struct tracefs_options_mask;
-bool tracefs_option_is_set(struct tracefs_options_mask *options,
+bool tracefs_option_is_set(const struct tracefs_options_mask *options,
enum tracefs_option_id id);
struct tracefs_options_mask *tracefs_options_get_supported(struct tracefs_instance *instance);
bool tracefs_option_is_supported(struct tracefs_instance *instance, enum tracefs_option_id id);
@@ -21,6 +21,21 @@
#define FLAG_INSTANCE_NEWLY_CREATED (1 << 0)
+struct tracefs_options_mask toplevel_supported_opts;
+struct tracefs_options_mask toplevel_enabled_opts;
+
+__hidden inline struct tracefs_options_mask *
+supported_opts_mask(struct tracefs_instance *instance)
+{
+ return instance? &instance->supported_opts : &toplevel_supported_opts;
+}
+
+__hidden inline struct tracefs_options_mask *
+enabled_opts_mask(struct tracefs_instance *instance)
+{
+ return instance? &instance->enabled_opts : &toplevel_enabled_opts;
+}
+
/**
* instance_alloc - allocate a new ftrace instance
* @trace_dir - Full path to the tracing directory, where the instance is
@@ -211,56 +211,52 @@ enum tracefs_option_id tracefs_option_id(const char *name)
static struct tracefs_options_mask *trace_get_options(struct tracefs_instance *instance,
bool enabled)
{
+ pthread_mutex_t *lock = instance ? &instance->lock : &toplevel_lock;
struct tracefs_options_mask *bitmask;
enum tracefs_option_id id;
+ unsigned long long set;
char file[PATH_MAX];
- struct dirent *dent;
- char *dname = NULL;
- DIR *dir = NULL;
+ struct stat st;
long long val;
+ char *path;
+ int ret;
- bitmask = calloc(1, sizeof(struct tracefs_options_mask));
- if (!bitmask)
- return NULL;
- dname = tracefs_instance_get_file(instance, "options");
- if (!dname)
- goto error;
- dir = opendir(dname);
- if (!dir)
- goto error;
-
- while ((dent = readdir(dir))) {
- if (*dent->d_name == '.')
- continue;
- if (enabled) {
- snprintf(file, PATH_MAX, "options/%s", dent->d_name);
- if (tracefs_instance_file_read_number(instance, file, &val) != 0 ||
- val != 1)
- continue;
+ bitmask = enabled? enabled_opts_mask(instance) :
+ supported_opts_mask(instance);
+
+ for (id = 1; id < TRACEFS_OPTION_MAX; id++) {
+ snprintf(file, PATH_MAX, "options/%s", options_map[id]);
+ path = tracefs_instance_get_file(instance, file);
+ if (!path)
+ return NULL;
+
+ set = 1;
+ ret = stat(path, &st);
+ if (ret < 0 || !S_ISREG(st.st_mode)) {
+ set = 0;
+ } else if (enabled) {
+ ret = tracefs_instance_file_read_number(instance, file, &val);
+ if (ret != 0 || val != 1)
+ set = 0;
}
- id = tracefs_option_id(dent->d_name);
- if (id > TRACEFS_OPTION_INVALID)
- bitmask->mask |= (1ULL << (id - 1));
+
+ pthread_mutex_lock(lock);
+ bitmask->mask = (bitmask->mask & ~(1ULL << (id - 1))) | (set << (id - 1));
+ pthread_mutex_unlock(lock);
+
+ tracefs_put_tracing_file(path);
}
- closedir(dir);
- tracefs_put_tracing_file(dname);
- return bitmask;
-error:
- if (dir)
- closedir(dir);
- tracefs_put_tracing_file(dname);
- free(bitmask);
- return NULL;
+ return bitmask;
}
/**
* tracefs_options_get_supported - Get all supported trace options in given instance
* @instance: ftrace instance, can be NULL for the top instance
*
- * Returns allocated bitmask structure with all trace options, supported in given
- * instance, or NULL in case of an error. The returned structure must be freed with free()
+ * Returns bitmask structure with all trace options, supported in given instance,
+ * or NULL in case of an error.
*/
struct tracefs_options_mask *tracefs_options_get_supported(struct tracefs_instance *instance)
{
@@ -271,8 +267,8 @@ struct tracefs_options_mask *tracefs_options_get_supported(struct tracefs_instan
* tracefs_options_get_enabled - Get all currently enabled trace options in given instance
* @instance: ftrace instance, can be NULL for the top instance
*
- * Returns allocated bitmask structure with all trace options, enabled in given
- * instance, or NULL in case of an error. The returned structure must be freed with free()
+ * Returns bitmask structure with all trace options, enabled in given instance,
+ * or NULL in case of an error.
*/
struct tracefs_options_mask *tracefs_options_get_enabled(struct tracefs_instance *instance)
{
@@ -282,7 +278,7 @@ struct tracefs_options_mask *tracefs_options_get_enabled(struct tracefs_instance
static int trace_config_option(struct tracefs_instance *instance,
enum tracefs_option_id id, bool set)
{
- char *set_str = set ? "1" : "0";
+ const char *set_str = set ? "1" : "0";
char file[PATH_MAX];
const char *name;
@@ -370,7 +366,7 @@ bool tracefs_option_is_enabled(struct tracefs_instance *instance, enum tracefs_o
* Returns true if an option with given id is set in the bitmask,
* false if it is not set.
*/
-bool tracefs_option_is_set(struct tracefs_options_mask *options,
+bool tracefs_option_is_set(const struct tracefs_options_mask *options,
enum tracefs_option_id id)
{
if (id > TRACEFS_OPTION_INVALID)
If the instance owns two mask objects, we no longer need to dynamically allocate memory in tracefs_options_get_supported() and tracefs_options_get_enabled(). This will simplify the code on the caller side, since the user is no longer responsible for freeing those masks. Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com> --- Documentation/libtracefs-option-get.txt | 7 +-- include/tracefs-local.h | 8 +++ include/tracefs.h | 2 +- src/tracefs-instance.c | 15 +++++ src/tracefs-tools.c | 74 ++++++++++++------------- 5 files changed, 61 insertions(+), 45 deletions(-)