replace common qcom sources with samsung ones
This commit is contained in:
2
qcom/opensource/dataservices/datatop/Android.mk
Normal file
2
qcom/opensource/dataservices/datatop/Android.mk
Normal file
@@ -0,0 +1,2 @@
|
||||
include $(call all-subdir-makefiles)
|
||||
|
||||
3
qcom/opensource/dataservices/datatop/Makefile.am
Normal file
3
qcom/opensource/dataservices/datatop/Makefile.am
Normal file
@@ -0,0 +1,3 @@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
SUBDIRS = src
|
||||
51
qcom/opensource/dataservices/datatop/autogen.sh
Normal file
51
qcom/opensource/dataservices/datatop/autogen.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
ACLOCAL=`which aclocal`
|
||||
AUTOCONF=`which autoconf`
|
||||
AUTOMAKE=`which automake`
|
||||
|
||||
if [ ! -x "$ACLOCAL" ]; then
|
||||
echo "Missing 'aclocal'; not in path. Make sure it is installed!"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ ! -x "$AUTOCONF" ]; then
|
||||
echo "Missing 'autoconf'; not in path. Make sure it is installed!"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
if [ ! -x "$AUTOMAKE" ]; then
|
||||
echo "Missing 'automake'; not in path. Make sure it is installed!"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
$ACLOCAL
|
||||
$AUTOCONF
|
||||
$AUTOMAKE -a
|
||||
56
qcom/opensource/dataservices/datatop/configure.ac
Normal file
56
qcom/opensource/dataservices/datatop/configure.ac
Normal file
@@ -0,0 +1,56 @@
|
||||
# -*- Autoconf -*-
|
||||
|
||||
# Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of The Linux Foundation nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.68])
|
||||
AC_INIT([Data Top], [1.0.4], [harouth@codeaurora.org])
|
||||
AC_CONFIG_SRCDIR([src/datatop.c])
|
||||
#AC_CONFIG_HEADERS([src/config.h])
|
||||
AC_CONFIG_FILES([Makefile
|
||||
src/Makefile])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
|
||||
# Checks for libraries.
|
||||
|
||||
# Checks for header files.
|
||||
AC_CHECK_HEADERS([stdlib.h string.h])
|
||||
|
||||
# Checks for typedefs, structures, and compiler characteristics.
|
||||
|
||||
# Checks for library functions.
|
||||
AC_FUNC_MALLOC
|
||||
|
||||
|
||||
#### Generate Makefile Data
|
||||
AM_INIT_AUTOMAKE([datatop], [1.0.4])
|
||||
|
||||
AC_OUTPUT
|
||||
36
qcom/opensource/dataservices/datatop/src/Android.mk
Normal file
36
qcom/opensource/dataservices/datatop/src/Android.mk
Normal file
@@ -0,0 +1,36 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_SRC_FILES := datatop.c
|
||||
LOCAL_SRC_FILES += datatop_cpu_stats_poll.c
|
||||
LOCAL_SRC_FILES += datatop_dev_poll.c
|
||||
LOCAL_SRC_FILES += datatop_dual_line_poll.c
|
||||
LOCAL_SRC_FILES += datatop_fileops.c
|
||||
LOCAL_SRC_FILES += datatop_gen_poll.c
|
||||
LOCAL_SRC_FILES += datatop_helpers.c
|
||||
LOCAL_SRC_FILES += datatop_linked_list.c
|
||||
LOCAL_SRC_FILES += datatop_meminfo_file_poll.c
|
||||
LOCAL_SRC_FILES += datatop_opt.c
|
||||
LOCAL_SRC_FILES += datatop_single_line_poll.c
|
||||
LOCAL_SRC_FILES += datatop_stat_poll.c
|
||||
LOCAL_SRC_FILES += datatop_str.c
|
||||
LOCAL_SRC_FILES += datatop_sys_snap.c
|
||||
LOCAL_SRC_FILES += datatop_value_only_poll.c
|
||||
LOCAL_SRC_FILES += datatop_ip_table_poll.c
|
||||
|
||||
LOCAL_CFLAGS := -Wall -Wextra -Werror -pedantic -std=c99
|
||||
LOCAL_CFLAGS += -DVERSION="\"1.0.4"\"
|
||||
LOCAL_CFLAGS += -DHAVE_STRL_FUNCTIONS
|
||||
LOCAL_CFLAGS += -D _BSD_SOURCE
|
||||
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_MODULE := datatop
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_VENDOR)/lib
|
||||
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_VENDOR)/lib64
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
||||
23
qcom/opensource/dataservices/datatop/src/Makefile.am
Normal file
23
qcom/opensource/dataservices/datatop/src/Makefile.am
Normal file
@@ -0,0 +1,23 @@
|
||||
## Makefile.am for main application
|
||||
|
||||
CFLAGS := -std=c99 # Target c99 for portability
|
||||
CFLAGS += -Wall -Wextra -Werror -pedantic # Strict code quality enforcement
|
||||
CFLAGS += -g -D _BSD_SOURCE # Enable debugging and BSD time functions
|
||||
|
||||
bin_PROGRAMS = datatop
|
||||
datatop_SOURCES := datatop.c
|
||||
datatop_SOURCES += datatop_fileops.c
|
||||
datatop_SOURCES += datatop_dual_line_poll.c
|
||||
datatop_SOURCES += datatop_single_line_poll.c
|
||||
datatop_SOURCES += datatop_meminfo_file_poll.c
|
||||
datatop_SOURCES += datatop_dev_poll.c
|
||||
datatop_SOURCES += datatop_stat_poll.c
|
||||
datatop_SOURCES += datatop_value_only_poll.c
|
||||
datatop_SOURCES += datatop_str.c
|
||||
datatop_SOURCES += datatop_cpu_stats_poll.c
|
||||
datatop_SOURCES += datatop_helpers.c
|
||||
datatop_SOURCES += datatop_linked_list.c
|
||||
datatop_SOURCES += datatop_opt.c
|
||||
datatop_SOURCES += datatop_gen_poll.c
|
||||
datatop_SOURCES += datatop_sys_snap.c
|
||||
datatop_SOURCES += datatop_ip_table_poll.c
|
||||
306
qcom/opensource/dataservices/datatop/src/datatop.c
Executable file
306
qcom/opensource/dataservices/datatop/src/datatop.c
Executable file
@@ -0,0 +1,306 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop.c
|
||||
* @brief Executes commands for application.
|
||||
*
|
||||
* Contains the main() function where program executes. Calls appropriate
|
||||
* methods based on user's CLI commands. Executes parsing function to
|
||||
* determine necessary output and handles errors which may arise during the
|
||||
* parse. Initiliazes files for data collection. Will call functions designed
|
||||
* to poll and print the data in understandable format.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_linked_list.h"
|
||||
#include "datatop_opt.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_polling.h"
|
||||
#include "datatop_gen_poll.h"
|
||||
|
||||
|
||||
#define DTOP_SEC_TO_USEC(x) ((x)*1000000)
|
||||
#define DTOP_USEC_TO_SEC(x) ((x)/1000000)
|
||||
struct dtop_linked_list *first_dpg_list;
|
||||
struct cli_opts usr_cl_opts;
|
||||
|
||||
/**
|
||||
* @brief Prints the datapoint names and values to the terminal.
|
||||
*
|
||||
* @param dpg_list A pointer to the first node of a linked list which
|
||||
* contains all data_point_gatherer structs to print.
|
||||
*/
|
||||
void dtop_print_terminal(struct dtop_linked_list *dpg_list)
|
||||
{
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
dtop_print_dpg(dpset);
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polls the data periodically and prints to file specified by the user.
|
||||
*
|
||||
* Polls the data as often as specified by the user in their CLI arguments
|
||||
* and outputs the data to a file also specified in CLI arguments. Then prints
|
||||
* a snapshot of delta(dp_value) to the terminal.
|
||||
*
|
||||
* @param dpg_list A pointer to the first node of a linked list which contains
|
||||
* all data_point_gatherer structs to poll and print.
|
||||
* @param fw A pointer to the file which will be printed to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
int dtop_poll_periodically(struct dtop_linked_list *dpg_list, FILE *fw)
|
||||
{
|
||||
struct timeval tv, timeout;
|
||||
fd_set rfds;
|
||||
time_t curtime, endtime;
|
||||
int inp, quit = 0;
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
struct timeval ftime, itime, polltime;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
curtime = DTOP_SEC_TO_USEC(tv.tv_sec)+tv.tv_usec;
|
||||
endtime = DTOP_SEC_TO_USEC(tv.tv_sec)+ DTOP_SEC_TO_USEC(usr_cl_opts.poll_time);
|
||||
|
||||
/* print all of our datapoint names as column headers in csv format */
|
||||
if (fprintf(fw, "\"Time\",") < 0)
|
||||
return FILE_ERROR;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
if (dtop_print_dpg_names_csv(dpset, fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
if (fprintf(fw, "\n") < 0)
|
||||
return FILE_ERROR;
|
||||
|
||||
dtop_print_interactive_opts();
|
||||
gettimeofday(&itime, NULL);
|
||||
/* periodically poll the datapoints and print in csv format */
|
||||
while (curtime < endtime
|
||||
|| usr_cl_opts.poll_time == POLL_NOT_SPECIFIED) {
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(0, &rfds);
|
||||
timeout.tv_sec = DTOP_USEC_TO_SEC(usr_cl_opts.poll_per);
|
||||
timeout.tv_usec = (usr_cl_opts.poll_per%1000000);
|
||||
//ftime is right before timeout calculations for most acurate calculations
|
||||
gettimeofday(&ftime, NULL);
|
||||
timersub(&ftime, &itime, &polltime);
|
||||
timersub(&timeout,&polltime, &timeout);
|
||||
inp = select(1, &rfds, NULL, NULL, &timeout);
|
||||
gettimeofday(&itime, NULL);
|
||||
if (inp) {
|
||||
char s[4];
|
||||
scanf("%s", s);
|
||||
if (strcmp(s, "quit") == 0
|
||||
|| strcmp(s, "q") == 0) {
|
||||
quit = QUIT;
|
||||
break;
|
||||
}
|
||||
if (strcmp(s, "i") == 0) {
|
||||
dtop_print_snapshot_diff(first_dpg_list);
|
||||
dtop_reset_dp_initial_values(first_dpg_list);
|
||||
}
|
||||
if (strcmp(s, "l") == 0)
|
||||
dtop_print_snapshot_diff(first_dpg_list);
|
||||
}
|
||||
gettimeofday(&tv, NULL);
|
||||
curtime = DTOP_SEC_TO_USEC(tv.tv_sec)+tv.tv_usec;
|
||||
dtop_poll(dpg_list);
|
||||
if (dtop_print_time_at_poll(fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
if (dtop_write_pollingdata_csv(dpg_list, fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
|
||||
}
|
||||
|
||||
if (quit != QUIT)
|
||||
dtop_print_snapshot_diff(dpg_list);
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
static void dtop_set_niceness(int niceness)
|
||||
{
|
||||
int pid, rc;
|
||||
pid = getpid();
|
||||
printf("Requesting nice %d\n", niceness);
|
||||
rc = setpriority(PRIO_PROCESS, pid, niceness);
|
||||
if (rc != 0)
|
||||
fprintf(stderr, "Error setting priority [%d]\n", errno);
|
||||
|
||||
rc = getpriority(PRIO_PROCESS, pid);
|
||||
printf("Running with nice %d.\n", rc);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int parse_status;
|
||||
pthread_t tid;
|
||||
printf("DataTop - Version %s\n", VERSION);
|
||||
printf("(c)2014-2015 Linux Foundation\n");
|
||||
|
||||
dtop_load_default_options(&usr_cl_opts);
|
||||
|
||||
parse_status = dtop_parse_cli_opts(&usr_cl_opts, argc, argv);
|
||||
switch (parse_status) {
|
||||
case PARSE_SUCCESS:
|
||||
dtop_set_niceness(usr_cl_opts.priority);
|
||||
break;
|
||||
|
||||
case PARSE_FORCE_EXIT:
|
||||
exit(EXIT_SUCCESS);
|
||||
break;
|
||||
|
||||
case PARSE_FAILURE:
|
||||
default:
|
||||
printf("Failed to parse command line arguments.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (usr_cl_opts.iptables_rules_routes == OPT_CHOSE) {
|
||||
if (usr_cl_opts.out_dir[0] == '\0') {
|
||||
printf("Please provide an out directory.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
dtop_dual_line_init("/proc/net/netstat");
|
||||
dtop_dual_line_init("/proc/net/snmp");
|
||||
dtop_single_line_init("/proc/net/snmp6");
|
||||
dtop_gen_init("/proc/sys/net/");
|
||||
dtop_gen_init("/sys/module/rmnet/parameters/");
|
||||
dtop_gen_init("/sys/module/rmnet_perf/parameters/");
|
||||
dtop_gen_init("/sys/module/rmnet_shs/parameters/");
|
||||
dtop_gen_init("/sys/module/rmnet_data/parameters/");
|
||||
dtop_gen_init("/sys/class/net/rmnet_mhi0/statistics/");
|
||||
dtop_gen_init("/sys/class/net/usb_rmnet0/statistics/");
|
||||
dtop_gen_init("/sys/class/net/rmnet_ipa0/statistics/");
|
||||
dtop_meminfo_init();
|
||||
dtop_dev_init();
|
||||
dtop_stat_init();
|
||||
dtop_cpu_stats_init();
|
||||
dtop_gen_init("/sys/kernel/debug/clk/bimc_clk/");
|
||||
dtop_gen_init("/sys/kernel/debug/clk/snoc_clk/");
|
||||
dtop_gen_init("/sys/kernel/debug/clk/pnoc_clk/");
|
||||
|
||||
if (usr_cl_opts.iptables_rules_routes == OPT_CHOSE) {
|
||||
printf("Datatop IP Tables, rules, routes\n");
|
||||
dtop_ip_table_init(usr_cl_opts.out_dir);
|
||||
if(0 != pthread_create(&tid, NULL, &dtop_ip_table_start_poll, NULL)) {
|
||||
printf("Unable to create capture_ip_tables_rules_routes thread\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (usr_cl_opts.print_cl == OPT_CHOSE) {
|
||||
dtop_poll(first_dpg_list);
|
||||
dtop_print_terminal(first_dpg_list);
|
||||
}
|
||||
|
||||
if (usr_cl_opts.print_csv == OPT_CHOSE) {
|
||||
FILE *to_file = NULL;
|
||||
if ((dtop_open_writing_file(usr_cl_opts.file_name,
|
||||
&to_file)) == VALID) {
|
||||
printf("\nData being polled for %ld seconds.\n",
|
||||
usr_cl_opts.poll_time);
|
||||
if (dtop_poll_periodically(first_dpg_list, to_file)
|
||||
== FILE_ERROR) {
|
||||
fprintf(stderr, "err=%d: %s\n", errno,
|
||||
strerror(errno));
|
||||
dtop_close_file(to_file);
|
||||
deconstruct_dpgs(first_dpg_list);
|
||||
dtop_rem_linked_list(first_dpg_list);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
dtop_close_file(to_file);
|
||||
} else {
|
||||
printf("File Can Not Be Opened\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (usr_cl_opts.snapshot_file) {
|
||||
if (dtop_print_system_snapshot(usr_cl_opts.snapshot_file)
|
||||
== FILE_ERROR) {
|
||||
fprintf(stderr, "err=%d: %s\n", errno,
|
||||
strerror(errno));
|
||||
deconstruct_dpgs(first_dpg_list);
|
||||
dtop_rem_linked_list(first_dpg_list);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (usr_cl_opts.print_cl == OPT_NOT_CHOSE &&
|
||||
usr_cl_opts.print_csv == OPT_NOT_CHOSE) {
|
||||
if ((!usr_cl_opts.snapshot_file)
|
||||
|| usr_cl_opts.poll_time_selected == POLL_TIME_SELECTED) {
|
||||
printf("\nData will now be polled for %ld seconds.\n",
|
||||
usr_cl_opts.poll_time);
|
||||
dtop_poll(first_dpg_list);
|
||||
sleep(usr_cl_opts.poll_time);
|
||||
dtop_poll(first_dpg_list);
|
||||
dtop_print_snapshot_diff(first_dpg_list);
|
||||
}
|
||||
}
|
||||
|
||||
deconstruct_dpgs(first_dpg_list);
|
||||
dtop_rem_linked_list(first_dpg_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds each dpg as a node to a linked list.
|
||||
*
|
||||
* Called when a dpg is initialized.
|
||||
*
|
||||
* @param dpg A pointer to a data_point_gatherer struct which is to be added to the linked list.
|
||||
*/
|
||||
void dtop_register(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
if (dpg)
|
||||
first_dpg_list = dtop_add_linked_list(dpg, first_dpg_list);
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_cpu_stats_poll.c
|
||||
* @brief Calls dtop_value_only_init for necessary cpu datapoints.
|
||||
*
|
||||
* File contains methods for determing number of cpu's online and calling
|
||||
* correct initialization function to gather scaling_cur_freq data point
|
||||
* for each cpu along with each cpu's online status.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
#include "datatop_polling.h"
|
||||
|
||||
#define DTOP_GEN_SIZE 8192
|
||||
#define DTOP_GEN_LINE (DTOP_GEN_SIZE>>2)
|
||||
#define NO_CPUS_ONLINE -1
|
||||
|
||||
/**
|
||||
* @brief Searches /sys/devices/system/cpu/ directory to get find number of CPUs.
|
||||
*
|
||||
* @return Number of CPUs found in directory.
|
||||
*/
|
||||
static int dtop_cpu_search(void)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *entry;
|
||||
struct stat s;
|
||||
int cpu_amt;
|
||||
char cwd[1024];
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd))) {
|
||||
fprintf(stderr, "Failed to get current working dir\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dp = opendir("/sys/devices/system/cpu/");
|
||||
if (dp == NULL) {
|
||||
fprintf(stderr, "err=%d: %s\n", errno, strerror(errno));
|
||||
fprintf(stderr, "Cannot open directory: %s\n",
|
||||
"/sys/devices/system/cpu/");
|
||||
return NO_CPUS_ONLINE;
|
||||
}
|
||||
|
||||
chdir("/sys/devices/system/cpu/");
|
||||
cpu_amt = 0;
|
||||
while ((entry = readdir(dp))) {
|
||||
if (stat(entry->d_name, &s)) {
|
||||
printf("stat err=%d: %s\n", errno, strerror(errno));
|
||||
return NO_CPUS_ONLINE;
|
||||
}
|
||||
|
||||
if (entry->d_name[0] == 'c' &&
|
||||
entry->d_name[1] == 'p' &&
|
||||
entry->d_name[2] == 'u' &&
|
||||
(isdigit(entry->d_name[3]))) {
|
||||
|
||||
cpu_amt++;
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
chdir(cwd);
|
||||
return cpu_amt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg designed for CPU online and CPU scaling_cur_freq stats.
|
||||
*
|
||||
* @param name Name of file dpg represents.
|
||||
*/
|
||||
static void construct_cpu_stat_dpg(char *name)
|
||||
{
|
||||
char *file = malloc(strlen(name) + 1);
|
||||
struct dtop_data_point *dp =
|
||||
malloc(sizeof(struct dtop_data_point));
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
|
||||
strlcpy(file, name, strlen(name) + 1);
|
||||
|
||||
dp[0].type = DTOP_ULONG;
|
||||
dp[0].name = malloc(5);
|
||||
strlcpy(dp[0].name, "", 5);
|
||||
dp[0].prefix = NULL;
|
||||
dp[0].data.d_ulong = 0;
|
||||
dp[0].initial_data.d_ulong = 0;
|
||||
dp[0].skip = DO_NOT_SKIP;
|
||||
dp[0].initial_data_populated = NOT_POPULATED;
|
||||
|
||||
dpg->prefix = file;
|
||||
dpg->file = file;
|
||||
dpg->poll = dtop_value_only_poll;
|
||||
dpg->data_points = dp;
|
||||
dpg->data_points_len = 1;
|
||||
dpg->deconstruct = dtop_value_only_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dpg constructor for necessary CPU stat files.
|
||||
*
|
||||
* Creates file names based on number of CPUs found and calls the
|
||||
* dpg constructor for them.
|
||||
*
|
||||
* @param file Directory where the CPUs are found.
|
||||
* @param add String which is concatenated onto file and represents
|
||||
* the path after a CPU directory is entered.
|
||||
* @param cpu_amt Amount of CPUs found on device.
|
||||
*/
|
||||
static void cpu_poll_helper(char *file, char *add, int cpu_amt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < cpu_amt; i++) {
|
||||
char *cpu_num = malloc(5);
|
||||
char *newfile;
|
||||
int nf_len;
|
||||
snprintf(cpu_num, 5, "%d", i);
|
||||
nf_len = strlen(file) + strlen(add) + strlen(cpu_num) + 2;
|
||||
newfile = malloc(nf_len);
|
||||
strlcpy(newfile, file, nf_len);
|
||||
strlcat(newfile, cpu_num, nf_len);
|
||||
strlcat(newfile, add, nf_len);
|
||||
free(cpu_num);
|
||||
construct_cpu_stat_dpg(newfile);
|
||||
free(newfile);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls necessary functions for CPU stat dpgs.
|
||||
*/
|
||||
void dtop_cpu_stats_init(void)
|
||||
{
|
||||
int cpu_amt;
|
||||
char *file = "/sys/devices/system/cpu/cpu";
|
||||
char *add = "/cpufreq/scaling_cur_freq";
|
||||
|
||||
cpu_amt = dtop_cpu_search();
|
||||
cpu_poll_helper(file, add, cpu_amt);
|
||||
add = "/online";
|
||||
cpu_poll_helper(file, add, cpu_amt);
|
||||
}
|
||||
320
qcom/opensource/dataservices/datatop/src/datatop_dev_poll.c
Normal file
320
qcom/opensource/dataservices/datatop/src/datatop_dev_poll.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_dev_poll.c
|
||||
* @brief Adds ability for data collection from /proc/net/dev
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* "/proc/net/dev"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_DEV_SIZE 8192
|
||||
#define DTOP_DEV_LINE (DTOP_DEV_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @struct dtop_dev_vars
|
||||
* @brief Struct used to hold necessary variables for /proc/net/dev dpg
|
||||
*
|
||||
* @var dtop_dev_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_dev_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_dev_vars {
|
||||
char **line;
|
||||
int line_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parses lines with data in "/proc/net/dev"
|
||||
*
|
||||
* @param line1 Line to parse to find datapoint names and values.
|
||||
* @param len1 Length of line1.
|
||||
* @param index Index in the dictionary the key (name) is added to.
|
||||
* @param dict Dictionary the keys and values are added to.
|
||||
*/
|
||||
static void dt_dev_parse(char *line1, int len1,
|
||||
int index, struct dt_procdict *dict)
|
||||
{
|
||||
int i, start = 0;
|
||||
int j, k, n;
|
||||
i = 0;
|
||||
while (line1[i] == ' ' || line1[i] == ' ')
|
||||
i++;
|
||||
dict->key[index] = &line1[i];
|
||||
for (i = 0; i < len1; i++) {
|
||||
if (line1[i] == ':') {
|
||||
line1[i+1] = 0;
|
||||
start = i+2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = 0;
|
||||
for (j = start; j < len1; j++) {
|
||||
if (line1[j] != ' ' && line1[j] != ' ') {
|
||||
dict->val[k] = &line1[j];
|
||||
n = j;
|
||||
while (line1[n] != 0 && line1[n] != ' ' && line1[n] != ' ')
|
||||
n++;
|
||||
if (n < len1)
|
||||
line1[n] = 0;
|
||||
j = n;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from "/proc/net/dev"
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_dev_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) *
|
||||
((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int read;
|
||||
struct dt_procdict *dict = malloc(sizeof(struct dt_procdict)
|
||||
*((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count-2);
|
||||
int j, n, sum;
|
||||
int index = 0;
|
||||
int dp = 0;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_DEV_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < ((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
line_len[n] = dt_read_line(((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line[n],
|
||||
DTOP_DEV_LINE, data,
|
||||
DTOP_DEV_SIZE, sum);
|
||||
if (n <= (((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count - 1)) {
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
for (n = 2; n < ((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
dt_dev_parse(((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line[n], line_len[n],
|
||||
index, &dict[index]);
|
||||
index++;
|
||||
}
|
||||
|
||||
|
||||
/* Assigns the dp value to the dp struct */
|
||||
for (n = 2; n < ((struct dtop_dev_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
dtop_store_dp(&(dpg->data_points[dp]),
|
||||
dict[n-2].val[j]);
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
free(line_len);
|
||||
free(dict);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated "/proc/net/dev" dpg.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_dev_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i, j, dp;
|
||||
dp = 0;
|
||||
for (j = 0; j < ((((struct dtop_dev_vars *)
|
||||
(dpset->priv))->line_count)-2); j++) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
free(dpset->data_points[dp].prefix);
|
||||
dp++;
|
||||
}
|
||||
}
|
||||
free(dpset->data_points);
|
||||
for (i = 0; i < ((struct dtop_dev_vars *)
|
||||
(dpset->priv))->line_count; i++)
|
||||
free(((struct dtop_dev_vars *)(dpset->priv))->line[i]);
|
||||
free(((struct dtop_dev_vars *)(dpset->priv))->line);
|
||||
free(((struct dtop_dev_vars *)(dpset->priv)));
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for "/proc/net/dev" file
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_dev_vars struct that holds relevant dpg variables.
|
||||
*/
|
||||
static void construct_dev_file_dpg(struct dtop_dev_vars *storage,
|
||||
int dp_count, struct dtop_data_point *data_points)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
|
||||
dpg->prefix = "/proc/net/dev";
|
||||
dpg->file = "/proc/net/dev";
|
||||
dpg->poll = dtop_dev_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->priv = (struct dtop_dev_vars *)storage;
|
||||
dpg->data_points_len = dp_count;
|
||||
dpg->deconstruct = dtop_dev_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans "/proc/net/dev in order to autodetect dps.
|
||||
*
|
||||
* Searches through "/proc/net/dev" file for all available data
|
||||
* points to create as dp structs.
|
||||
*
|
||||
* @param name This is the file name "/proc/net/dev" passed in by dtop_dev_init
|
||||
* @param storage dtop_dev_vars struct where relevant variables are stored.
|
||||
*/
|
||||
int dtop_dev_search(char *name, struct dtop_dev_vars *storage)
|
||||
{
|
||||
int i, n, sum;
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) * storage->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
struct dt_procdict dev_dict;
|
||||
struct dtop_data_point *data_points = malloc
|
||||
(sizeof(struct dtop_data_point) * 16 * (storage->line_count-2));
|
||||
int dp_count = (16 * (storage->line_count - 2));
|
||||
int index = 0;
|
||||
int dp = 0;
|
||||
|
||||
storage->line = malloc(storage->line_count * sizeof(*storage->line));
|
||||
|
||||
for (i = 0; i < storage->line_count; i++)
|
||||
storage->line[i] = malloc(sizeof(char) * DTOP_DEV_LINE);
|
||||
|
||||
dev_dict.val[0] = "bytes";
|
||||
dev_dict.val[1] = "packets";
|
||||
dev_dict.val[2] = "errs";
|
||||
dev_dict.val[3] = "drop";
|
||||
dev_dict.val[4] = "fifo";
|
||||
dev_dict.val[5] = "frame";
|
||||
dev_dict.val[6] = "compressed";
|
||||
dev_dict.val[7] = "multicast";
|
||||
dev_dict.val[8] = "bytes";
|
||||
dev_dict.val[9] = "packets";
|
||||
dev_dict.val[10] = "errs";
|
||||
dev_dict.val[11] = "drop";
|
||||
dev_dict.val[12] = "fifo";
|
||||
dev_dict.val[13] = "colls";
|
||||
dev_dict.val[14] = "carrier";
|
||||
dev_dict.val[15] = "compressed";
|
||||
|
||||
read = dt_read_file(name, &data, DTOP_DEV_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < storage->line_count; n++) {
|
||||
line_len[n] = dt_read_line(storage->line[n],
|
||||
DTOP_DEV_LINE, data,
|
||||
DTOP_DEV_SIZE, sum);
|
||||
if (n < (storage->line_count - 1))
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
construct_dev_file_dpg(storage, dp_count, data_points);
|
||||
|
||||
for (n = 2; n < storage->line_count; n++) {
|
||||
dt_dev_parse(storage->line[n], line_len[n], index, &dict);
|
||||
index++;
|
||||
}
|
||||
|
||||
for (n = 2; n < storage->line_count; n++) {
|
||||
for (i = 0; i < 16; i++) {
|
||||
char *pref = malloc(30 * sizeof(char));
|
||||
data_points[dp].skip = 0;
|
||||
data_points[dp].initial_data_populated = NOT_POPULATED;
|
||||
if (i < 8)
|
||||
strlcpy(pref, "Receive:", 30 * sizeof(char));
|
||||
else if (i >= 8)
|
||||
strlcpy(pref, "Transmit:", 30 * sizeof(char));
|
||||
strlcat(pref, dev_dict.val[i], 30 * sizeof(char));
|
||||
data_points[dp].prefix = pref;
|
||||
data_points[dp].name = dict.key[n-2];
|
||||
data_points[dp].type = DTOP_ULONG;
|
||||
dp++;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
|
||||
free(line_len);
|
||||
dt_free(&data);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for "/proc/net/dev" file.
|
||||
*/
|
||||
void dtop_dev_init(void)
|
||||
{
|
||||
struct dtop_dev_vars *storage = malloc
|
||||
(sizeof(struct dtop_dev_vars));
|
||||
storage->line_count = dtop_get_file_line_amount("/proc/net/dev");
|
||||
dtop_dev_search("/proc/net/dev", storage);
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_dual_line_poll.c
|
||||
* @brief Adds ability for data collection from dual line files.
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* dual line files, meaning the first line contains the dp names
|
||||
* while the second line contains the corresponding values.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_DUAL_SIZE 8192
|
||||
#define DTOP_DUAL_LINE (DTOP_DUAL_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @struct dtop_dual_line_vars
|
||||
* @brief Struct used to hold necessary variables for dual_line_file dpgs.
|
||||
*
|
||||
* @var dtop_dual_line_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_dual_line_vars::line2
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_dual_line_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_dual_line_vars {
|
||||
char **line;
|
||||
char **line2;
|
||||
int line_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from a dual_line file.
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_dual_line_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) *
|
||||
((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int *line_len2 = malloc(sizeof(int) *
|
||||
((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int read;
|
||||
|
||||
struct dt_procdict *dict = malloc(sizeof(struct dt_procdict)
|
||||
* (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count/2));
|
||||
struct dt_procdict *prefix_dict = malloc(sizeof(struct dt_procdict)
|
||||
* (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count/2));
|
||||
int i, j, k, n, sum, sum2;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_DUAL_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
sum2 = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < ((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
line_len[n] = dt_read_line(((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line[n],
|
||||
DTOP_DUAL_LINE, data,
|
||||
DTOP_DUAL_SIZE, sum);
|
||||
line_len2[n] = dt_read_line(((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line2[n],
|
||||
DTOP_DUAL_LINE, data,
|
||||
DTOP_DUAL_SIZE, sum2);
|
||||
if (n <= (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count-2)) {
|
||||
sum += (line_len[n] + 1);
|
||||
sum2 += (line_len2[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores dp names and values in dictionary */
|
||||
for (i = 0; i < (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count/2); i++)
|
||||
dt_parse_proc_dictionary(((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line[2*i],
|
||||
line_len[2*i],
|
||||
((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line[(2*i)+1],
|
||||
line_len[(2*i)+1],
|
||||
&dict[i]);
|
||||
|
||||
/* Stores dp prefices in dictionary */
|
||||
for (i = 0; i < (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count/2); i++)
|
||||
dt_parse_for_prefix(((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line2[2*i], line_len2[2*i],
|
||||
&prefix_dict[i]);
|
||||
|
||||
/* Assigns a dp value to each dp struct */
|
||||
for (k = 0; k < (((struct dtop_dual_line_vars *)
|
||||
(dpg->priv))->line_count/2); k++) {
|
||||
for (j = 0; j < dpg->data_points_len; j++) {
|
||||
i = dt_find_dict_idx(dpg->data_points[j].name,
|
||||
&dict[k]);
|
||||
if (i >= 0 && i < dict[k].max &&
|
||||
(strcmp(dpg->data_points[j].prefix,
|
||||
prefix_dict[k].val[i]) == 0))
|
||||
|
||||
dtop_store_dp(&(dpg->data_points[j]),
|
||||
dict[k].val[i]);
|
||||
}
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
free(line_len);
|
||||
free(line_len2);
|
||||
free(dict);
|
||||
free(prefix_dict);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated dual_line_file dpgs.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_dual_line_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
free(dpset->data_points);
|
||||
for (i = 0; i < ((struct dtop_dual_line_vars *)
|
||||
(dpset->priv))->line_count; i++) {
|
||||
free(((struct dtop_dual_line_vars *)(dpset->priv))->line[i]);
|
||||
free(((struct dtop_dual_line_vars *)(dpset->priv))->line2[i]);
|
||||
}
|
||||
free(((struct dtop_dual_line_vars *)(dpset->priv))->line);
|
||||
free(((struct dtop_dual_line_vars *)(dpset->priv))->line2);
|
||||
free(((struct dtop_dual_line_vars *)(dpset->priv)));
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for a dual_line file.
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param name Name of file dpg represents.
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_dual_line_vars struct that hold relevant dpg variables.
|
||||
* @param dp_count Number of datapoints in dtop_data_point struct array.
|
||||
*/
|
||||
static void construct_dual_line_file_dpg(char *name, struct dtop_data_point
|
||||
*data_points, struct dtop_dual_line_vars *storage, int dp_count)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
dpg->prefix = name;
|
||||
dpg->file = name;
|
||||
dpg->poll = dtop_dual_line_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->priv = (struct dtop_dual_line_vars *)storage;
|
||||
dpg->data_points_len = dp_count;
|
||||
dpg->deconstruct = dtop_dual_line_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans a dual_line file for all datapoints and creats dps.
|
||||
*
|
||||
* Searches through a dual_line file (Key on one line with value on next line)
|
||||
* for all available data points to create as dp structs.
|
||||
*
|
||||
* @param name Name of file.
|
||||
* @param storage dtop_dual_line_vars struct where relevant variables are stored.
|
||||
*/
|
||||
int dtop_dual_line_search(char *name, struct dtop_dual_line_vars *storage)
|
||||
{
|
||||
int i, j, k, n, sum, sum2;
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) * storage->line_count);
|
||||
int *line_len2 = malloc(sizeof(int) * storage->line_count);
|
||||
int read;
|
||||
struct dt_procdict *dict, *prefix_dict;
|
||||
struct dtop_data_point *data_points;
|
||||
int dp_count = 0;
|
||||
|
||||
storage->line = malloc(storage->line_count * sizeof(*storage->line));
|
||||
storage->line2 = malloc(storage->line_count * sizeof(*storage->line2));
|
||||
for (i = 0; i < storage->line_count; i++) {
|
||||
storage->line[i] = malloc(sizeof(char) * DTOP_DUAL_LINE);
|
||||
storage->line2[i] = malloc(sizeof(char) * DTOP_DUAL_LINE);
|
||||
}
|
||||
dict = malloc(sizeof(struct dt_procdict) * (storage->line_count/2));
|
||||
prefix_dict = malloc(sizeof(struct dt_procdict)
|
||||
* (storage->line_count/2));
|
||||
|
||||
read = dt_read_file(name, &data, DTOP_DUAL_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
sum2 = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < storage->line_count; n++) {
|
||||
line_len[n] = dt_read_line(storage->line[n],
|
||||
DTOP_DUAL_LINE, data,
|
||||
DTOP_DUAL_SIZE, sum);
|
||||
line_len2[n] = dt_read_line(storage->line2[n],
|
||||
DTOP_DUAL_LINE, data,
|
||||
DTOP_DUAL_SIZE, sum2);
|
||||
if (n <= (storage->line_count-2)) {
|
||||
sum += (line_len[n] + 1);
|
||||
sum2 += (line_len2[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores dp names and prefixes in dictionaries */
|
||||
for (i = 0; i < (storage->line_count/2); i++)
|
||||
dt_parse_proc_dictionary(storage->line[2*i], line_len[2*i],
|
||||
storage->line[(2*i)+1], line_len[(2*i)+1], &dict[i]);
|
||||
|
||||
for (i = 0; i < (storage->line_count/2); i++)
|
||||
dt_parse_for_prefix(storage->line2[2*i], line_len2[2*i],
|
||||
&prefix_dict[i]);
|
||||
|
||||
/* Finds how many data points were gathered from the file */
|
||||
for (j = 0; j < (storage->line_count/2); j++) {
|
||||
for (i = 0; i < dict[j].max; i++)
|
||||
dp_count++;
|
||||
}
|
||||
|
||||
data_points = malloc(dp_count * sizeof(struct dtop_data_point));
|
||||
|
||||
k = 0;
|
||||
/* Creates a dtop_data_point struct for each dp found in the file */
|
||||
for (j = 0; j < (storage->line_count/2); j++)
|
||||
for (i = 0; i < dict[j].max; i++) {
|
||||
if (dict[j].val[i][0] == '-')
|
||||
data_points[k].type = DTOP_LONG;
|
||||
else
|
||||
data_points[k].type = DTOP_ULONG;
|
||||
data_points[k].name = dict[j].key[i];
|
||||
data_points[k].prefix = prefix_dict[j].val[i];
|
||||
data_points[k].skip = DO_NOT_SKIP;
|
||||
data_points[k].initial_data_populated = NOT_POPULATED;
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Calls dpg constructor, dpg will point to the dp struct */
|
||||
construct_dual_line_file_dpg(name, data_points, storage, dp_count);
|
||||
|
||||
free(line_len);
|
||||
free(line_len2);
|
||||
free(dict);
|
||||
free(prefix_dict);
|
||||
dt_free(&data);
|
||||
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for a file with dual line pairs.
|
||||
*/
|
||||
void dtop_dual_line_init(char *name)
|
||||
{
|
||||
struct dtop_dual_line_vars *storage = malloc
|
||||
(sizeof(struct dtop_dual_line_vars));
|
||||
storage->line_count = dtop_get_file_line_amount(name);
|
||||
|
||||
if (storage->line_count%2 != 0) {
|
||||
printf("Dual line file, %s, contains error.\n", name);
|
||||
printf("Data will not be collected from %s\n", name);
|
||||
return;
|
||||
}
|
||||
dtop_dual_line_search(name, storage);
|
||||
}
|
||||
202
qcom/opensource/dataservices/datatop/src/datatop_fileops.c
Normal file
202
qcom/opensource/dataservices/datatop/src/datatop_fileops.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_fileops.c
|
||||
* @brief Declares functions for reading and writing to files.
|
||||
*
|
||||
* Declares functions called when reading from files which data is collected.
|
||||
* Also contains methods to handle files which will be written to.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_linked_list.h"
|
||||
#include "datatop_opt.h"
|
||||
#include "datatop_fileops.h"
|
||||
|
||||
/**
|
||||
* @brief Reads the lines from files which we are collecting data from.
|
||||
*
|
||||
* @param file File which is read from
|
||||
* @param buffer Pointer to buffer where data will be read. The buffer is allocated
|
||||
* in dt_read_file() and passed back to the caller. Caller should
|
||||
* free this when done.
|
||||
* @param len Maximum amount of data which should be read from the file.
|
||||
* @return Number of bytes of data placed in *buffer.
|
||||
*/
|
||||
int dt_read_file(const char *file, char **buffer, int len)
|
||||
{
|
||||
int read;
|
||||
FILE *fp;
|
||||
|
||||
*buffer = (char *)malloc(len);
|
||||
if (!(*buffer)) {
|
||||
fprintf(stderr, "%s(): malloc(%d) failed\n", __func__, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fp = fopen(file, "r");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "%s(): Failed to open %s: ", __func__, file);
|
||||
fprintf(stderr, "Error: %s\n", strerror(errno));
|
||||
free(*buffer);
|
||||
*buffer = 0;
|
||||
return 0;
|
||||
}
|
||||
read = fread(*buffer, sizeof(char), len, fp);
|
||||
fclose(fp);
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deallocates memory no longer being used.
|
||||
*
|
||||
* @param buffer Buffer to be deallocated.
|
||||
*/
|
||||
void dt_free(char **buffer)
|
||||
{
|
||||
free(*buffer);
|
||||
*buffer = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks for access to a file for writing.
|
||||
*
|
||||
* @param fw File to check access of.
|
||||
* @return INVALID - File already exists or write access denied.
|
||||
* @return VALID - File does not exist and can be written to.
|
||||
*/
|
||||
int dtop_check_writefile_access(char *fw)
|
||||
{
|
||||
if (!access(fw, F_OK)) {
|
||||
printf("File specified already exists\n");
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
if (!access(fw, W_OK)) {
|
||||
printf("Permission to write to specified file denied\n");
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks for the presence of a dir.
|
||||
*
|
||||
* @param fw Dir to check the presence
|
||||
* @return INVALID - Out dir doesn't exist.
|
||||
* @return VALID - Out dir exist and can be written to.
|
||||
*/
|
||||
int dtop_check_out_dir_presence(char *fw)
|
||||
{
|
||||
if (access(fw, F_OK)) {
|
||||
printf("Out dir not present\n");
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a directory
|
||||
*
|
||||
* @param New directory full path.
|
||||
* @return INVALID - Out dir doesn't exist or write access denied.
|
||||
* @return VALID - Out dir exist and can be written to.
|
||||
*/
|
||||
int dtop_create_dir(char *full_path)
|
||||
{
|
||||
if (!mkdir(full_path, 0755)) {
|
||||
printf("Unable to create dir: %s, errno: %d\n", full_path, errno);
|
||||
return INVALID;
|
||||
}
|
||||
|
||||
return VALID;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Opens file and handles possible errors.
|
||||
*
|
||||
* @param fw File path to be opened.
|
||||
* @param to_file Pointer to the *file that is opened.
|
||||
* @return VALID - File opened successfully.
|
||||
* @return INVALID - File could not be opened.
|
||||
*/
|
||||
int dtop_open_writing_file(char *fw, FILE **to_file)
|
||||
{
|
||||
*to_file = fopen(fw, "w");
|
||||
if (*to_file) {
|
||||
return VALID;
|
||||
} else {
|
||||
fprintf(stderr, "Value of errno: %d\n", errno);
|
||||
fprintf(stderr, "Error opening file: %s\n", strerror(errno));
|
||||
fprintf(stderr, "Please try writing to a non-existent file\n");
|
||||
printf("See datatop -h for help\n");
|
||||
return INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Closes a file if not a standard stream.
|
||||
*
|
||||
* @param fw File to be closed.
|
||||
*/
|
||||
void dtop_close_file(FILE *fw)
|
||||
{
|
||||
if (fw != stdout && fw != stderr && fw != stdin)
|
||||
fclose(fw);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Helper function to find number of lines in dual_line file.
|
||||
*
|
||||
* @return Number of lines in a dual_line file.
|
||||
*/
|
||||
int dtop_get_file_line_amount(char *name)
|
||||
{
|
||||
signed char rc = 0;
|
||||
int line_count = 0;
|
||||
FILE *file = fopen(name, "r");
|
||||
while (rc != EOF) {
|
||||
if (rc == '\n')
|
||||
line_count++;
|
||||
rc = fgetc(file);
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
return line_count;
|
||||
}
|
||||
50
qcom/opensource/dataservices/datatop/src/datatop_fileops.h
Normal file
50
qcom/opensource/dataservices/datatop/src/datatop_fileops.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_fileops.h
|
||||
* @brief Declares functions held within datatop_fileops.h
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_FILEOPS_H
|
||||
#define DATATOP_FILEOPS_H
|
||||
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_linked_list.h"
|
||||
#include "datatop_opt.h"
|
||||
|
||||
int dt_read_file(const char *file, char **buffer, int len);
|
||||
void dt_free(char **buffer);
|
||||
int dtop_check_writefile_access(char *fw);
|
||||
int dtop_check_out_dir_presence(char *fw);
|
||||
int dtop_create_dir(char *full_path);
|
||||
int dtop_open_writing_file(char *fw, FILE **to_file);
|
||||
void dtop_close_file(FILE *fw);
|
||||
int dtop_get_file_line_amount(char *file);
|
||||
#endif /* DATATOP_FILEOPS_H */
|
||||
280
qcom/opensource/dataservices/datatop/src/datatop_gen_poll.c
Normal file
280
qcom/opensource/dataservices/datatop/src/datatop_gen_poll.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_gen_poll.c
|
||||
* @brief Contains functions which add ability to scan directories for data points.
|
||||
*
|
||||
* Contains functions that search through a directory and create dpg's for any
|
||||
* important data values found which can then be polled for data collection.
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
#include "datatop_gen_poll.h"
|
||||
|
||||
#define DTOP_GEN_SIZE 8192
|
||||
#define DTOP_GEN_LINE (DTOP_GEN_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @brief Searches a file to find the number of data values it contains.
|
||||
*
|
||||
* @param dpg The struct which contains the file to search.
|
||||
* @return Number of datapoints found in the file.
|
||||
*/
|
||||
static int get_number_of_values(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int read;
|
||||
char line[DTOP_GEN_LINE];
|
||||
int line_len;
|
||||
int i, num;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_GEN_SIZE);
|
||||
line_len = dt_read_line(line, DTOP_GEN_LINE, data, DTOP_GEN_SIZE, 0);
|
||||
|
||||
if (read == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (line_len < 1) {
|
||||
dt_free(&data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
num = 1;
|
||||
for (i = 0; i < line_len; i++) {
|
||||
if ((line[i] == ' ' || line[i] == ','
|
||||
|| line[i] == ' ') &&line[i+1] != 0)
|
||||
num++;
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
return num;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from a dpg that was constructed during dtop_search.
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_gen_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int read;
|
||||
char line[DTOP_GEN_LINE];
|
||||
int line_len;
|
||||
struct dt_procdict dict;
|
||||
int i;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_GEN_SIZE);
|
||||
line_len = dt_read_line(line, DTOP_GEN_LINE, data, DTOP_GEN_SIZE, 0);
|
||||
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
dt_single_line_parse(line, line_len, &dict);
|
||||
|
||||
for (i = 0; i < dpg->data_points_len; i++) {
|
||||
if (dict.val[i][0] == '-')
|
||||
dpg->data_points[i].type = DTOP_LONG;
|
||||
dtop_store_dp(&(dpg->data_points[i]), dict.val[i]);
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated dpg's.
|
||||
*
|
||||
* Frees the memory of dpg variables and the dpg for all dynamically allocated
|
||||
* dpgs.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_gen_dpg_deconstructor(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dpset->data_points_len; i++)
|
||||
free(dpset->data_points[i].name);
|
||||
free(dpset->data_points);
|
||||
free(dpset->file);
|
||||
free(dpset->prefix);
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg and all necessary dp's corresponding to it.
|
||||
*
|
||||
* Dynamically allocates memory for dpg and dp structs which are then
|
||||
* created and added to a linked_list of dpgs through the dtop_register
|
||||
* function.
|
||||
*
|
||||
* @param dir Directory which file is located in, assigned to the dpg prefix.
|
||||
* @param name Name of file that dpg represents, assigned to a dp name.
|
||||
*/
|
||||
static void dpg_construction(char *dir, char *name)
|
||||
{
|
||||
int num, i;
|
||||
int both_len = strlen(dir) + strlen(name) + 1;
|
||||
char *both = malloc(both_len);
|
||||
char *maindir;
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
strlcpy(both, dir, both_len);
|
||||
strlcat(both, name, both_len);
|
||||
maindir = malloc(strlen(dir) + 1);
|
||||
strlcpy(maindir, dir, strlen(dir) + 1);
|
||||
|
||||
dpg->prefix = maindir;
|
||||
dpg->file = both;
|
||||
dpg->poll = dtop_gen_poll;
|
||||
dpg->deconstruct = dtop_gen_dpg_deconstructor;
|
||||
num = get_number_of_values(dpg);
|
||||
|
||||
if (num != 0) {
|
||||
struct dtop_data_point *dp = malloc
|
||||
(num * sizeof(struct dtop_data_point));
|
||||
for (i = 0; i < num; i++) {
|
||||
if (num == 1) {
|
||||
dp[i].name = malloc(strlen(name) + 1);
|
||||
strlcpy(dp[i].name, name, strlen(name) + 1);
|
||||
} else {
|
||||
char *add = malloc(7 * sizeof(char));
|
||||
char *newname;
|
||||
int nn_len, dpn_len;
|
||||
snprintf(add, 7 * sizeof(char), "[%d]:", i);
|
||||
nn_len = strlen(name) + strlen(add) + 1;
|
||||
newname = malloc(nn_len);
|
||||
strlcpy(newname, name, nn_len);
|
||||
strlcat(newname, add, nn_len);
|
||||
dpn_len = strlen(newname) + 1;
|
||||
dp[i].name = malloc(dpn_len);
|
||||
strlcpy(dp[i].name, newname, dpn_len);
|
||||
free(add);
|
||||
free(newname);
|
||||
}
|
||||
dp[i].prefix = NULL;
|
||||
dp[i].type = DTOP_ULONG;
|
||||
dp[i].skip = DO_NOT_SKIP;
|
||||
dp[i].initial_data_populated = NOT_POPULATED;
|
||||
}
|
||||
|
||||
dpg->data_points = dp;
|
||||
dpg->data_points_len = num;
|
||||
|
||||
dtop_register(dpg);
|
||||
} else {
|
||||
free(dpg->prefix);
|
||||
free(dpg->file);
|
||||
free(dpg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans a directory for all important datapoints to be collected.
|
||||
*
|
||||
* Recursively scans a directory and locates all files which data will be
|
||||
* collected from.
|
||||
*
|
||||
* @param dir Directory to search.
|
||||
*/
|
||||
static int dtop_search(char *dir)
|
||||
{
|
||||
DIR *dp;
|
||||
struct dirent *entry;
|
||||
struct stat s;
|
||||
char cwd[1024];
|
||||
|
||||
if (!getcwd(cwd, sizeof(cwd))) {
|
||||
fprintf(stderr, "Failed to get current working dir\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dp = opendir(dir);
|
||||
if (dp == NULL) {
|
||||
fprintf(stderr, "err=%d: %s\n", errno, strerror(errno));
|
||||
fprintf(stderr, "Cannot open directory: %s\n", dir);
|
||||
return DIR_FAILURE;
|
||||
}
|
||||
|
||||
chdir(dir);
|
||||
|
||||
while ((entry = readdir(dp))) {
|
||||
if (stat(entry->d_name, &s)) {
|
||||
printf("stat err=%d: %s\n", errno, strerror(errno));
|
||||
return DIR_FAILURE;
|
||||
}
|
||||
|
||||
if (strcmp(".", entry->d_name) != 0 &&
|
||||
strcmp("..", entry->d_name) != 0 &&
|
||||
S_ISREG(s.st_mode)) {
|
||||
|
||||
dpg_construction(dir, entry->d_name);
|
||||
|
||||
} else if (strcmp(".", entry->d_name) != 0 &&
|
||||
strcmp("..", entry->d_name) != 0 &&
|
||||
S_ISDIR(s.st_mode)) {
|
||||
int nd_len = strlen(dir) + strlen(entry->d_name) + 2;
|
||||
char *newdir = malloc(nd_len);
|
||||
strlcpy(newdir, dir, nd_len);
|
||||
strlcat(newdir, entry->d_name, nd_len);
|
||||
strlcat(newdir, "/", nd_len);
|
||||
dtop_search(newdir);
|
||||
free(newdir);
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dp);
|
||||
chdir(cwd);
|
||||
return DIR_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for any specified directory.
|
||||
*
|
||||
* @param dir Directory to search.
|
||||
*/
|
||||
void dtop_gen_init(char *dir)
|
||||
{
|
||||
dtop_search(dir);
|
||||
}
|
||||
43
qcom/opensource/dataservices/datatop/src/datatop_gen_poll.h
Normal file
43
qcom/opensource/dataservices/datatop/src/datatop_gen_poll.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_gen_poll.h
|
||||
* @brief Declares functions held within datatop_gen_poll.c
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_GEN_POLL_H
|
||||
#define DATATOP_GEN_POLL_H
|
||||
|
||||
#define DIR_SUCCESS 0
|
||||
#define DIR_FAILURE 1
|
||||
|
||||
void dtop_gen_init(char *dir);
|
||||
#endif /* DATATOP_GEN_POLL_H */
|
||||
|
||||
478
qcom/opensource/dataservices/datatop/src/datatop_helpers.c
Normal file
478
qcom/opensource/dataservices/datatop/src/datatop_helpers.c
Normal file
@@ -0,0 +1,478 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_helpers.c
|
||||
* @brief Contains functions which output data.
|
||||
*
|
||||
* Contains functions which are used for printing data to output streams.
|
||||
* Handles all formatting for data output. Also contains functions which
|
||||
* are responsible for data gathering and collection.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_linked_list.h"
|
||||
#include "datatop_fileops.h"
|
||||
|
||||
/**
|
||||
* @brief Prints the name and prefix of a datapoint.
|
||||
*
|
||||
* @param dp Dp whose name and prefix is printed.
|
||||
* @param prefix Directory where dp is contained.
|
||||
* @param fw File to print the information to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
static int dtop_format_dp_names(struct dtop_data_point *dp, const char
|
||||
*prefix, FILE *fw)
|
||||
{
|
||||
if (dp->prefix) {
|
||||
if (fprintf(fw, "\"%s:%s:%s\",", prefix, dp->prefix,
|
||||
dp->name) < 0)
|
||||
return FILE_ERROR;
|
||||
} else {
|
||||
if (fprintf(fw, "\"%s::%s\",", prefix, dp->name) < 0)
|
||||
return FILE_ERROR;
|
||||
}
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the value of a datapoint.
|
||||
*
|
||||
* Checks the type of the value and will print it accordingly.
|
||||
*
|
||||
* @param dp Pointer to the data_point struct which holds the value that will
|
||||
* be printed.
|
||||
* @param fw File to print the information to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
static int dtop_format_dp_values(struct dtop_data_point *dp, FILE *fw)
|
||||
{
|
||||
switch (dp->type) {
|
||||
case DTOP_ULONG:
|
||||
if (fprintf(fw, "%"PRIu64, dp->data.d_ulong) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_LONG:
|
||||
if (fprintf(fw, "%"PRId64, dp->data.d_long) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_UINT:
|
||||
if (fprintf(fw, "%d", dp->data.d_uint) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_INT:
|
||||
if (fprintf(fw, "%u", dp->data.d_uint) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_UCHAR:
|
||||
if (fprintf(fw, "%c,", dp->data.d_uchar) < 0)
|
||||
return FILE_ERROR;
|
||||
if (fprintf(fw, "(0x%02X)", dp->data.d_uchar) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_CHAR:
|
||||
if (fprintf(fw, "%c,", dp->data.d_char) < 0)
|
||||
return FILE_ERROR;
|
||||
if (fprintf(fw, "(%d)", dp->data.d_char) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
case DTOP_STR:
|
||||
if (fprintf(fw, "\"%s\"", dp->data.d_str) < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
default:
|
||||
if (fprintf(fw, "UNKNOWN_TYPE") < 0)
|
||||
return FILE_ERROR;
|
||||
break;
|
||||
}
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the name and prefix of a dp, formatted appropriately.
|
||||
*
|
||||
* @param dpset data_point_gatherer used to access dp directory.
|
||||
* @param dp data_point used to get datapoint prefix if available.
|
||||
*/
|
||||
static void dtop_format_text_for_snapshot
|
||||
(struct dtop_data_point_gatherer *dpset, struct dtop_data_point dp)
|
||||
{
|
||||
printf("%s:", dpset->prefix);
|
||||
if (dp.prefix)
|
||||
printf("%s:", dp.prefix);
|
||||
|
||||
printf("%s::", dp.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints a datapoint value to a specified csv file.
|
||||
*
|
||||
* @param dp Datapoint that holds the value to be printed.
|
||||
* @param fw File to print to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
static int dtop_print_dp_csv(struct dtop_data_point *dp, FILE *fw)
|
||||
{
|
||||
if (dtop_format_dp_values(dp, fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
if (fprintf(fw, ",") < 0)
|
||||
return FILE_ERROR;
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints a datapoint value to the terminal.
|
||||
*
|
||||
* @param dp Holds the value to be printed print.
|
||||
* @param prefix Used to print prefix of the data_point.
|
||||
*/
|
||||
static void dtop_print_dp(struct dtop_data_point *dp, const char *prefix)
|
||||
{
|
||||
dtop_format_dp_names(dp, prefix, stdout);
|
||||
printf(" ");
|
||||
dtop_format_dp_values(dp, stdout);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finds delta(value) of a datapoint.
|
||||
*
|
||||
* Function accounts for different types that values may be.
|
||||
*
|
||||
* @param dpset Pointer to a data_point used as another parameter for printing.
|
||||
* @param dp Datapoint which contains the value to find the difference of.
|
||||
*/
|
||||
static void dtop_handle_dp_type_for_snapshot(
|
||||
struct dtop_data_point_gatherer *dpset, struct dtop_data_point dp)
|
||||
{
|
||||
int64_t int64;
|
||||
|
||||
switch (dp.type) {
|
||||
case DTOP_ULONG:
|
||||
default:
|
||||
/* This is less than ideal. Replace with 128-bit ops later */
|
||||
int64 = (int64_t)dp.data.d_ulong
|
||||
- (int64_t)dp.initial_data.d_ulong;
|
||||
if (int64 != 0) {
|
||||
dtop_format_text_for_snapshot(dpset, dp);
|
||||
printf("%"PRId64"\n", int64);
|
||||
}
|
||||
break;
|
||||
|
||||
case DTOP_LONG:
|
||||
/* This is less than ideal. Replace with 128-bit ops later */
|
||||
int64 = (int64_t)dp.data.d_long
|
||||
- (int64_t)dp.initial_data.d_long;
|
||||
if (int64 != 0) {
|
||||
dtop_format_text_for_snapshot(dpset, dp);
|
||||
printf("%"PRId64"\n", int64);
|
||||
}
|
||||
break;
|
||||
|
||||
case DTOP_UINT:
|
||||
int64 = (int64_t)dp.data.d_uint
|
||||
- (int64_t)dp.initial_data.d_uint;
|
||||
if (int64 != 0) {
|
||||
dtop_format_text_for_snapshot(dpset, dp);
|
||||
printf("%"PRId64"\n", int64);
|
||||
}
|
||||
break;
|
||||
|
||||
case DTOP_INT:
|
||||
int64 = (int64_t)dp.data.d_int
|
||||
- (int64_t)dp.initial_data.d_int;
|
||||
if (int64 != 0) {
|
||||
dtop_format_text_for_snapshot(dpset, dp);
|
||||
printf("%"PRId64"\n", int64);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls the dtop_print_dp_csv function for each data_point a dpg has access to.
|
||||
*
|
||||
* @param dpg A data_point_gatherer struct that is iterated through for each datapoint.
|
||||
* @param fw File to print datapoint values to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
static int dtop_print_dpg_csv(struct dtop_data_point_gatherer *dpg, FILE *fw)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dpg->data_points_len; i++)
|
||||
if (dtop_print_dp_csv(&(dpg->data_points[i]), fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls the dtop_format_dp_names function for each data_point a dpg has access to.
|
||||
*
|
||||
* @param dpg A data_point_gatherer struct that is iterated through for each datapoint.
|
||||
* @param fw File to printg datapoint names and prefixes to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
int dtop_print_dpg_names_csv(struct dtop_data_point_gatherer *dpg, FILE *fw)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < dpg->data_points_len; i++)
|
||||
if (dtop_format_dp_names(&(dpg->data_points[i]),
|
||||
dpg->prefix, fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints all dp values to a specified file.
|
||||
*
|
||||
* This function is responsible for the printing of all data_point values
|
||||
* to a specified file. It will iterate through the linked list which contains
|
||||
* all of the dpgs and will print each dp value, being sure to flush the buffer.
|
||||
*
|
||||
* @param dpg_list Pointer to first node of linked list which contains all dpgs.
|
||||
* @param fw File that data prints to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
int dtop_write_pollingdata_csv(struct dtop_linked_list *dpg_list, FILE *fw)
|
||||
{
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
if (dtop_print_dpg_csv(dpset, fw) == FILE_ERROR)
|
||||
return FILE_ERROR;
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
fflush(fw);
|
||||
}
|
||||
|
||||
if (fprintf(fw, "\n") < 0)
|
||||
return FILE_ERROR;
|
||||
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls the dtop_print_dp function for each data_point a dpg has access to.
|
||||
*
|
||||
* @param dpg A data_point_gatherer struct that is iterated through for each datapoint.
|
||||
*/
|
||||
void dtop_print_dpg(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dpg->data_points_len; i++)
|
||||
dtop_print_dp(&(dpg->data_points[i]), dpg->prefix);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the values for the datapoints and populates the initial value.
|
||||
*
|
||||
* @param dp A datapoint whose value will be stored.
|
||||
* @param str Str used for sscanf function call to find value of dp.
|
||||
*/
|
||||
void dtop_store_dp(struct dtop_data_point *dp, const char *str)
|
||||
{
|
||||
switch (dp->type) {
|
||||
case DTOP_ULONG:
|
||||
sscanf(str, "%"PRIu64, &(dp->data.d_ulong));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_ulong = dp->data.d_ulong;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_LONG:
|
||||
sscanf(str, "%"PRId64, &(dp->data.d_long));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_long = dp->data.d_long;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_UINT:
|
||||
sscanf(str, "%u", &(dp->data.d_uint));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_uint = dp->data.d_uint;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_INT:
|
||||
sscanf(str, "%d", &(dp->data.d_int));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_int = dp->data.d_int;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_UCHAR:
|
||||
sscanf(str, "%c", &(dp->data.d_uchar));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_uchar = dp->data.d_uchar;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_CHAR:
|
||||
sscanf(str, "%c", &(dp->data.d_char));
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
dp->initial_data.d_char = dp->data.d_char;
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
case DTOP_STR:
|
||||
sscanf(str, "%s", dp->data.d_str);
|
||||
if (dp->initial_data_populated == NOT_POPULATED) {
|
||||
memcpy(dp->initial_data.d_str, dp->data.d_str,
|
||||
DTOP_DP_MAX_STR_LEN);
|
||||
dp->initial_data_populated = POPULATED;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Responsible for calculating and printing current time to file.
|
||||
*
|
||||
* Prints the time since 1970, in Seconds and Milliseconds.
|
||||
*
|
||||
* @param fw File that time is printed to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
int dtop_print_time_at_poll(FILE *fw)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
if (fprintf(fw, "%10ld", tv.tv_sec) < 0)
|
||||
return FILE_ERROR;
|
||||
|
||||
if (fprintf(fw, ".%06ld,", tv.tv_usec) < 0)
|
||||
return FILE_ERROR;
|
||||
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Polls all dp values and updates each value.
|
||||
*
|
||||
* @param dpg_list Pointer to first node of linked list which contains all dpgs.
|
||||
*/
|
||||
void dtop_poll(struct dtop_linked_list *dpg_list)
|
||||
{
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
dpset->poll(dpset);
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the delta(value) of all data_points to terminal.
|
||||
*
|
||||
* @param dpg_list Pointer to first node of linked list which contains all dpgs.
|
||||
*/
|
||||
void dtop_print_snapshot_diff(struct dtop_linked_list *dpg_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
printf("\n");
|
||||
printf("Change In Datapoint Values\n");
|
||||
printf("---------------------------\n");
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
for (i = 0; i < dpset->data_points_len; i++)
|
||||
dtop_handle_dp_type_for_snapshot(dpset,
|
||||
dpset->data_points[i]);
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Resets the initial values of all data_points.
|
||||
*
|
||||
* @param dpg_list Pointer to first node of linked list which contains all dpgs.
|
||||
*/
|
||||
void dtop_reset_dp_initial_values(struct dtop_linked_list *dpg_list)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
for (i = 0; i < dpset->data_points_len; i++)
|
||||
dpset->data_points[i].initial_data_populated
|
||||
= NOT_POPULATED;
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls deconstructor method for all dpgs dynamically created.
|
||||
*
|
||||
* Checks to see if each dpg created has a deconstructor method. If not null,
|
||||
* function calls the appropiate deconstructor method to deallocate memory.
|
||||
*
|
||||
* @param dpg_list Pointer to first node of linked list which contains all dpgs.
|
||||
*/
|
||||
void deconstruct_dpgs(struct dtop_linked_list *dpg_list)
|
||||
{
|
||||
struct dtop_linked_list *curr_ptr = dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
while (curr_ptr) {
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
if (dpset->deconstruct)
|
||||
dpset->deconstruct(dpset);
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
}
|
||||
166
qcom/opensource/dataservices/datatop/src/datatop_interface.h
Normal file
166
qcom/opensource/dataservices/datatop/src/datatop_interface.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_interface.h
|
||||
* @brief Declares functions held within datatop.c and datatop_helpers.c
|
||||
*
|
||||
* Declares functions which are held within datatop.c and datatop_helpers.c.
|
||||
* Also defines data structures used for storing data gathered during polling
|
||||
* such as datapoint names, values, and prefixes along with other valuable
|
||||
* information.
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_INTERFACE_H
|
||||
#define DATATOP_INTERFACE_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "datatop_linked_list.h"
|
||||
|
||||
#define DTOP_ULONG 0
|
||||
#define DTOP_LONG 1
|
||||
#define DTOP_UINT 2
|
||||
#define DTOP_INT 3
|
||||
#define DTOP_UCHAR 4
|
||||
#define DTOP_CHAR 5
|
||||
#define DTOP_STR 6
|
||||
|
||||
#define FILE_ERROR -1
|
||||
#define FILE_SUCCESS 0
|
||||
#define SKIP 1
|
||||
#define DO_NOT_SKIP 0
|
||||
#define POPULATED 1
|
||||
#define NOT_POPULATED 0
|
||||
|
||||
#define DTOP_POLL_OK 0
|
||||
#define DTOP_POLL_IO_ERR 1
|
||||
#define NOT_CHECKED 0
|
||||
|
||||
#define QUIT 1
|
||||
|
||||
#define DTOP_DP_MAX_STR_LEN 32
|
||||
|
||||
#define DTOP_DP_HFILL .initial_data_populated = NOT_POPULATED, \
|
||||
.skip = 0
|
||||
|
||||
/**
|
||||
* @struct dtop_data_union
|
||||
* @brief Provides the type for dp value.
|
||||
*/
|
||||
union dtop_data_union {
|
||||
uint64_t d_ulong;
|
||||
int64_t d_long;
|
||||
uint32_t d_uint;
|
||||
int32_t d_int;
|
||||
uint8_t d_uchar;
|
||||
int8_t d_char;
|
||||
char d_str[DTOP_DP_MAX_STR_LEN];
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dtop_data_point
|
||||
* @brief Individual datapoint in a file.
|
||||
*
|
||||
* @var dtop_data_point::name
|
||||
* Stores the datapoints name.
|
||||
* @var dtop_data_point::prefix
|
||||
* Stores the individual prefix for the dp.
|
||||
* @var dtop_data_point::type
|
||||
* Type dp value is, see definitions.
|
||||
* @var dtop_data_point::initial_data
|
||||
* Holds the initial value of the dp the first time it was polled.
|
||||
* @var dtop_data_point::initial_data_populated
|
||||
* Variable that is changed when initial_data is populated.
|
||||
* @var dtop_data_point::data
|
||||
* Value of the dp at the most recent poll.
|
||||
*/
|
||||
struct dtop_data_point {
|
||||
char *name;
|
||||
char *prefix;
|
||||
|
||||
/* Results of polling */
|
||||
char type;
|
||||
union dtop_data_union initial_data;
|
||||
char initial_data_populated;
|
||||
union dtop_data_union data;
|
||||
|
||||
/* Skip on subsequent polls */
|
||||
char skip;
|
||||
};
|
||||
|
||||
/**
|
||||
* @struct dtop_data_point_gatherer
|
||||
* @brief Struct used to hold data about a set of collected data.
|
||||
*
|
||||
* @var dtop_data_point_gatherer::prefix
|
||||
* Name of directory which data is collected from.
|
||||
* @var dtop_data_point_gatherer::file
|
||||
* File path that data is collected from.
|
||||
* @var dtop_data_point_gatherer::poll
|
||||
* Poll function takes a dtop_data_point_gatherer as parameter.
|
||||
* int equals, DTOP_POLL_IO_ERR - Poll of dpg unsuccessful, or
|
||||
* DTOP_POLL_OK - Poll of dpg successful.
|
||||
* @var dtop_data_point_gatherer::data_points
|
||||
* Pointer to a dtop_data_point struct (dp).
|
||||
* @var dtop_data_point_gatherer::data_points_len
|
||||
* Number of elements in the array of dp's the dpg accesses.
|
||||
*/
|
||||
struct dtop_data_point_gatherer {
|
||||
char *prefix;
|
||||
char *file;
|
||||
int (*poll)(struct dtop_data_point_gatherer *dpg);
|
||||
void (*deconstruct)(struct dtop_data_point_gatherer *dpg);
|
||||
|
||||
struct dtop_data_point *data_points;
|
||||
int data_points_len;
|
||||
|
||||
/* Private data */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
void dtop_register(struct dtop_data_point_gatherer *dpg);
|
||||
void dtop_store_dp(struct dtop_data_point *dp, const char *str);
|
||||
void dtop_print_dpg(struct dtop_data_point_gatherer *dpg);
|
||||
void get_snapshot_diff(struct dtop_linked_list *dpg_list);
|
||||
void dtop_print_snapshot_diff(struct dtop_linked_list *dpg_list);
|
||||
void dtop_poll(struct dtop_linked_list *dpg_list);
|
||||
int dtop_print_time_at_poll(FILE *fw);
|
||||
int dtop_print_dpg_names_csv(struct dtop_data_point_gatherer *dpg, FILE *fw);
|
||||
int dtop_write_pollingdata_csv(struct dtop_linked_list *dpg_list, FILE *fw);
|
||||
void dtop_reset_dp_initial_values(struct dtop_linked_list *dpg_list);
|
||||
void deconstruct_dpgs(struct dtop_linked_list *dpg_list);
|
||||
int dtop_print_system_snapshot(char *file);
|
||||
|
||||
|
||||
#ifndef HAVE_STRL_FUNCTIONS
|
||||
#define strlcpy(X,Y,Z) strcpy(X,Y)
|
||||
#define strlcat(X,Y,Z) strcat(X,Y)
|
||||
#endif /* HAVE_STRL_FUNCTIONS */
|
||||
|
||||
#endif /* DATATOP_INTERFACE_H */
|
||||
344
qcom/opensource/dataservices/datatop/src/datatop_ip_table_poll.c
Normal file
344
qcom/opensource/dataservices/datatop/src/datatop_ip_table_poll.c
Normal file
@@ -0,0 +1,344 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_ip_table_poll.c
|
||||
* @brief Adds ability for TP Tables, Rules and Routes data collection
|
||||
Unlike other polls, this is intended for running as a separate
|
||||
thread as it can cause delays of > 3sec per poll
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include <pthread.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
#include "datatop_polling.h"
|
||||
|
||||
#define DTOP_IPTRR_POLL_PERIOD 5.00
|
||||
|
||||
/**
|
||||
* @struct dtop_ip_table_vars
|
||||
* @brief Struct used to hold necessary variables for /proc/stat dpg
|
||||
*
|
||||
* @var dtop_ip_table_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_ip_table_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_ip_table_vars {
|
||||
char *out_dir;
|
||||
}dtop_ip_table_storage;
|
||||
|
||||
struct dtop_linked_list *ip_dpg_list = NULL;
|
||||
|
||||
pthread_mutex_t dtop_ip_table_lock;
|
||||
|
||||
/**
|
||||
* @brief Perform IP table command and store it in a file
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_ip_table_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
FILE *fd;
|
||||
FILE *fo = (FILE *)dpg->file;
|
||||
char buf[1001];
|
||||
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
|
||||
if(fo == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not fopen: %s\n", dpg->file);
|
||||
return DTOP_POLL_IO_ERR;
|
||||
}
|
||||
|
||||
time ( &rawtime );
|
||||
timeinfo = gmtime ( &rawtime );
|
||||
|
||||
fprintf ( fo, "============\nStart: %s==========\n", asctime (timeinfo) );
|
||||
fflush(fo);
|
||||
|
||||
/* redirect stderr to output file */
|
||||
dup2(fileno(fo), 2);
|
||||
|
||||
fd = popen((char *)dpg->priv, "r");
|
||||
if(fd == NULL)
|
||||
{
|
||||
fprintf(stderr, "Could not popen: %s\n", (char *)dpg->priv);
|
||||
return DTOP_POLL_IO_ERR;
|
||||
}
|
||||
|
||||
while(fgets(buf, 1000, fd) != NULL)
|
||||
{
|
||||
fputs(buf, fo);
|
||||
}
|
||||
|
||||
fprintf ( fo, "============\nEnd: %s==========\n\n", asctime (timeinfo) );
|
||||
fflush(fo);
|
||||
pclose(fd);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated IP table dpg.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_ip_table_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
free(dpset->prefix);
|
||||
if(dpset->file)
|
||||
{
|
||||
fclose((FILE *)dpset->file);
|
||||
}
|
||||
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Registers a new IP table dpg to the list.
|
||||
*
|
||||
* @param dpg Dpg to construct and allocate memory for.
|
||||
*/
|
||||
void dtop_ip_table_register(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
if (dpg)
|
||||
ip_dpg_list = dtop_add_linked_list(dpg, ip_dpg_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open the files for writing the output for each dpg.
|
||||
*
|
||||
* @param None
|
||||
*/
|
||||
int dtop_ip_table_init_files()
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
struct dtop_linked_list *curr_ptr = ip_dpg_list;
|
||||
FILE *fd;
|
||||
|
||||
while(curr_ptr)
|
||||
{
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
fd = fopen(dpset->prefix, "a+");
|
||||
if(!fd)
|
||||
{
|
||||
fprintf(stderr, "Could not fopen: %s\n", dpset->prefix);
|
||||
return DTOP_POLL_IO_ERR;
|
||||
}
|
||||
dpset->file = (char *)fd;
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Perform cleanup of IP table dgp list at exit.
|
||||
*
|
||||
* @param None
|
||||
*/
|
||||
void dtop_ip_table_poll_cleanup()
|
||||
{
|
||||
pthread_mutex_lock(&dtop_ip_table_lock);
|
||||
deconstruct_dpgs(ip_dpg_list);
|
||||
dtop_rem_linked_list(ip_dpg_list);
|
||||
pthread_mutex_unlock(&dtop_ip_table_lock);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The thread to poll for IP table data.
|
||||
*
|
||||
* @param arg ptr
|
||||
*/
|
||||
void *dtop_ip_table_start_poll(void *arg)
|
||||
{
|
||||
time_t start_t, curr_t;
|
||||
double diff_t = 9999999.00; /* some high # > DTOP_IPTRR_POLL_PERIOD */
|
||||
int ret = DTOP_POLL_OK;
|
||||
|
||||
(void) arg;
|
||||
|
||||
if (pthread_mutex_init(&dtop_ip_table_lock, NULL) != 0)
|
||||
{
|
||||
printf("\n mutex init failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
atexit(dtop_ip_table_poll_cleanup);
|
||||
|
||||
if(DTOP_POLL_OK != ( ret = dtop_ip_table_init_files()))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
struct dtop_linked_list *curr_ptr = ip_dpg_list;
|
||||
struct dtop_data_point_gatherer *dpset;
|
||||
|
||||
pthread_mutex_lock(&dtop_ip_table_lock);
|
||||
|
||||
if (diff_t >= DTOP_IPTRR_POLL_PERIOD)
|
||||
{
|
||||
printf("Poll for IP Tables, Rules & Routes\n");
|
||||
time(&start_t);
|
||||
while (curr_ptr)
|
||||
{
|
||||
dpset = (struct dtop_data_point_gatherer *) curr_ptr->data;
|
||||
dpset->poll(dpset);
|
||||
curr_ptr = curr_ptr->next_ptr;
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&dtop_ip_table_lock);
|
||||
|
||||
/* sleep for 500 milliseconds */
|
||||
usleep(500 * 1000);
|
||||
time(&curr_t);
|
||||
diff_t = difftime(curr_t, start_t);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for ip table command
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_ip_table_vars struct that holds relevant dpg variables.
|
||||
*/
|
||||
/*static void construct_ip_table_dpg(struct dtop_data_point
|
||||
*data_points, struct dtop_ip_table_vars *command, int dp_count)
|
||||
*/
|
||||
static void construct_ip_table_dpg(char *command)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
char *file_name = (char *)malloc(strlen(command)+ 1 + 1 + strlen(dtop_ip_table_storage.out_dir) + 4);
|
||||
int i, fname_start_ind;
|
||||
|
||||
strcpy(file_name, dtop_ip_table_storage.out_dir);
|
||||
strcat(file_name, "/");
|
||||
|
||||
fname_start_ind = strlen(file_name);
|
||||
strcat(file_name, command);
|
||||
strcat(file_name, ".txt");
|
||||
|
||||
for(i=fname_start_ind; file_name[i]; i++)
|
||||
{
|
||||
if(file_name[i] == ' ')
|
||||
file_name[i] = '_';
|
||||
if(file_name[i] == '/')
|
||||
file_name[i] = '-';
|
||||
}
|
||||
|
||||
dpg->prefix = file_name;
|
||||
dpg->poll = dtop_ip_table_poll;
|
||||
dpg->priv = (char *)command;
|
||||
dpg->file = NULL;
|
||||
dpg->deconstruct = dtop_ip_table_dpg_deconstructor;
|
||||
|
||||
dtop_ip_table_register(dpg);
|
||||
}
|
||||
|
||||
/*
|
||||
* @brief Scans "/proc/stat" in order to autodetect dps.
|
||||
*
|
||||
* Searches through "/proc/stat" file for all available data
|
||||
* points to create as dp structs.
|
||||
*
|
||||
* @param storage dtop_ip_table_vars struct where relevant variables are stored.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for "/proc/stat" file.
|
||||
*/
|
||||
void dtop_ip_table_init(char *out_dir)
|
||||
{
|
||||
dtop_ip_table_storage.out_dir = out_dir;
|
||||
construct_ip_table_dpg("ip xfrm state show");
|
||||
construct_ip_table_dpg("ip xfrm policy show");
|
||||
construct_ip_table_dpg("ip addr");
|
||||
construct_ip_table_dpg("iptables -t raw -L -n -v");
|
||||
construct_ip_table_dpg("iptables -t mangle -L -n -v");
|
||||
construct_ip_table_dpg("iptables -L -n -v");
|
||||
construct_ip_table_dpg("iptables -t nat -L -n -v");
|
||||
construct_ip_table_dpg("ip6tables -t raw -L -n -v");
|
||||
construct_ip_table_dpg("ip6tables -t mangle -L -n -v");
|
||||
construct_ip_table_dpg("ip6tables -L -n -v");
|
||||
construct_ip_table_dpg("ip6tables -t nat -L -n -v");
|
||||
construct_ip_table_dpg("ip rule show");
|
||||
construct_ip_table_dpg("ip -6 rule show");
|
||||
construct_ip_table_dpg("ip route show table all");
|
||||
construct_ip_table_dpg("ip -6 route show table all");
|
||||
construct_ip_table_dpg("ip route show table rmnet_data0");
|
||||
construct_ip_table_dpg("ip route show table rmnet_data1");
|
||||
construct_ip_table_dpg("ip route show table rmnet_data2");
|
||||
construct_ip_table_dpg("ip route show table rmnet_data6");
|
||||
construct_ip_table_dpg("ip route show table rmnet_data7");
|
||||
construct_ip_table_dpg("ip route show table r_rmnet_data0");
|
||||
construct_ip_table_dpg("ip route show table r_rmnet_data1");
|
||||
construct_ip_table_dpg("ip route show table r_rmnet_data2");
|
||||
construct_ip_table_dpg("ip route show table r_rmnet_data6");
|
||||
construct_ip_table_dpg("ip route show table r_rmnet_data7");
|
||||
construct_ip_table_dpg("ip -6 route show table rmnet_data0");
|
||||
construct_ip_table_dpg("ip -6 route show table rmnet_data1");
|
||||
construct_ip_table_dpg("ip -6 route show table rmnet_data2");
|
||||
construct_ip_table_dpg("ip -6 route show table rmnet_data6");
|
||||
construct_ip_table_dpg("ip -6 route show table rmnet_data7");
|
||||
construct_ip_table_dpg("ip -6 route show table r_rmnet_data0");
|
||||
construct_ip_table_dpg("ip -6 route show table r_rmnet_data1");
|
||||
construct_ip_table_dpg("ip -6 route show table r_rmnet_data2");
|
||||
construct_ip_table_dpg("ip -6 route show table r_rmnet_data6");
|
||||
construct_ip_table_dpg("ip -6 route show table r_rmnet_data7");
|
||||
construct_ip_table_dpg("ip route show table wlan0");
|
||||
construct_ip_table_dpg("ip -6 route show table wlan0");
|
||||
construct_ip_table_dpg("ip route show table dummy0");
|
||||
construct_ip_table_dpg("ip -6 route show table dummy0");
|
||||
construct_ip_table_dpg("cat /proc/net/xfrm_stat");
|
||||
construct_ip_table_dpg("cat /proc/sys/net/ipv4/ip_forward");
|
||||
construct_ip_table_dpg("cat /proc/sys/net/ipv6/conf/all/forwarding");
|
||||
|
||||
printf("Poll for IP Tables, Rules & Routes every 5 seconds\n");
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_linked_list.c
|
||||
* @brief Necessary linked_list functions created.
|
||||
*
|
||||
* Holds function which adds to or creates a linked list
|
||||
* used for storing dtop_data_point_gatherer's (dpg's).
|
||||
* Datapoints are stored in linked list for ability to
|
||||
* iteratively poll and print efficiently. Handles creation
|
||||
* and deletion of memory for linked list nodes.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "datatop_linked_list.h"
|
||||
|
||||
/**
|
||||
* @brief Adds a node to the beginning of a linked list.
|
||||
*
|
||||
* @param data A void pointer which can hold any data in the node.
|
||||
* @param list The list that is added to.
|
||||
* @return Updated linked list struct.
|
||||
*/
|
||||
struct dtop_linked_list *dtop_add_linked_list(void *data,
|
||||
struct dtop_linked_list *list)
|
||||
{
|
||||
struct dtop_linked_list *list_node;
|
||||
list_node = malloc(sizeof(struct dtop_linked_list));
|
||||
|
||||
if (!list_node) {
|
||||
fprintf(stderr, "failed to allocate memory.\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
list_node->data = data;
|
||||
list_node->next_ptr = list;
|
||||
list = list_node;
|
||||
return list;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deletes a linked list.
|
||||
*
|
||||
* @param head_ptr Pointer to the first node in the linked list that is to be deleted.
|
||||
*/
|
||||
void dtop_rem_linked_list(struct dtop_linked_list *head_ptr)
|
||||
{
|
||||
struct dtop_linked_list *tmp_ptr = NULL;
|
||||
while (head_ptr) {
|
||||
tmp_ptr = head_ptr;
|
||||
head_ptr = head_ptr->next_ptr;
|
||||
free(tmp_ptr);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_linked_list.h
|
||||
* @brief Defines linked list struct and declares linked list methods.
|
||||
*
|
||||
* Defines linked list struct which can be used for any data
|
||||
* storage. Declares methods held within datatop_linked_list.c.
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_LINKED_LIST_H
|
||||
#define DATATOP_LINKED_LIST_H
|
||||
|
||||
/**
|
||||
* @struct dtop_linked_list
|
||||
* @brief Struct used to represent linked list node that stores a pointer with any type.
|
||||
*
|
||||
* @var dtop_linked_list::next_ptr
|
||||
* Pointer to next node in the list.
|
||||
* @var dtop_linked_list::data
|
||||
* Pointer to data the node stores.
|
||||
*/
|
||||
struct dtop_linked_list {
|
||||
struct dtop_linked_list *next_ptr;
|
||||
void *data;
|
||||
};
|
||||
|
||||
struct dtop_linked_list *dtop_add_linked_list(void *data,
|
||||
struct dtop_linked_list *list);
|
||||
void dtop_rem_linked_list(struct dtop_linked_list *head_ptr);
|
||||
#endif /* DATATOP_LINKED_LIST_H */
|
||||
|
||||
@@ -0,0 +1,282 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_meminfo_file_poll.c
|
||||
* @brief Adds ability for data collection from /proc/meminfo
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* "/proc/meminfo"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_MEM_SIZE 8192
|
||||
#define DTOP_MEM_LINE (DTOP_MEM_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @struct dtop_meminfo_vars
|
||||
* @brief Struct used to hold necessary variables for /proc/meminfo dpg
|
||||
*
|
||||
* @var dtop_meminfo_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_meminfo_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_meminfo_vars {
|
||||
char **line;
|
||||
int line_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parses lines with data in "/proc/meminfo"
|
||||
*
|
||||
* @param line1 Line to parse to find datapoint names and values.
|
||||
* @param len1 Length of line1.
|
||||
* @param l Index in the dictionary the key/value pair is added to.
|
||||
* @param dict Dictionary the keys and values are added to.
|
||||
*/
|
||||
int dt_meminfo_parse(char *line1, int len1,
|
||||
int l, struct dt_procdict *dict)
|
||||
{
|
||||
int i, k, n;
|
||||
if (len1 < 1)
|
||||
return 0;
|
||||
|
||||
if (line1 == 0 || dict == 0)
|
||||
return 0;
|
||||
|
||||
k = l;
|
||||
dict->key[k] = &line1[0];
|
||||
for (i = 0; i < len1 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line1[i] == ' ' || line1[i] == ' ') {
|
||||
line1[i] = 0;
|
||||
n = i+1;
|
||||
while (line1[n] == ' ' || line1[n] == ' ')
|
||||
n++;
|
||||
dict->val[k] = &line1[n];
|
||||
while (line1[n] != ' ')
|
||||
n++;
|
||||
line1[n] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
dict->max = k;
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from a "/proc/meminfo"
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_meminfo_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) *
|
||||
((struct dtop_meminfo_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
int i, j, n, sum;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_MEM_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < ((struct dtop_meminfo_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
line_len[n] = dt_read_line(((struct dtop_meminfo_vars *)
|
||||
(dpg->priv))->line[n],
|
||||
DTOP_MEM_LINE, data,
|
||||
DTOP_MEM_SIZE, sum);
|
||||
if (n <= (((struct dtop_meminfo_vars *)
|
||||
(dpg->priv))->line_count - 1)) {
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores dp names and values in dictionary */
|
||||
for (i = 0; i < dpg->data_points_len; i++)
|
||||
dt_meminfo_parse(((struct dtop_meminfo_vars *)
|
||||
(dpg->priv))->line[i], line_len[i], i, &dict);
|
||||
|
||||
/* Assigns the dp value to the dp struct */
|
||||
for (j = 0; j < dpg->data_points_len; j++) {
|
||||
i = dt_find_dict_idx(dpg->data_points[j].name, &dict);
|
||||
if (i >= 0 && i < dict.max) {
|
||||
sscanf(dict.val[i], "%" PRIu64,
|
||||
&(dpg->data_points[i].data.d_ulong));
|
||||
dpg->data_points[i].data.d_ulong *= 1024;
|
||||
if (dpg->data_points[i].
|
||||
initial_data_populated == NOT_POPULATED) {
|
||||
dpg->data_points[i].initial_data.d_ulong
|
||||
= dpg->data_points[i].data.d_ulong;
|
||||
dpg->data_points[i].initial_data_populated
|
||||
= POPULATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
free(line_len);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated "/proc/meminfo" dpg.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_meminfo_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
free(dpset->data_points);
|
||||
for (i = 0; i < ((struct dtop_meminfo_vars *)
|
||||
(dpset->priv))->line_count; i++)
|
||||
free(((struct dtop_meminfo_vars *)(dpset->priv))->line[i]);
|
||||
free(((struct dtop_meminfo_vars *)(dpset->priv))->line);
|
||||
free(((struct dtop_meminfo_vars *)(dpset->priv)));
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for "/proc/meminfo" file
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_meminfo_vars struct that holds relevant dpg variables.
|
||||
*/
|
||||
static void construct_meminfo_file_dpg(struct dtop_data_point
|
||||
*data_points, struct dtop_meminfo_vars *storage)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
dpg->prefix = "/proc/meminfo";
|
||||
dpg->file = "/proc/meminfo";
|
||||
dpg->poll = dtop_meminfo_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->priv = (struct dtop_meminfo_vars *)storage;
|
||||
dpg->data_points_len = storage->line_count;
|
||||
dpg->deconstruct = dtop_meminfo_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans "/proc/meminfo in order to autodetect dps.
|
||||
*
|
||||
* Searches through "/proc/meminfo" file for all available data
|
||||
* points to create as dp structs.
|
||||
*
|
||||
* @param storage dtop_meminfo_vars struct where relevant variables are stored.
|
||||
*/
|
||||
int dtop_meminfo_search(struct dtop_meminfo_vars *storage)
|
||||
{
|
||||
int i, k, n, sum;
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) * storage->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
struct dtop_data_point *data_points;
|
||||
|
||||
storage->line = malloc(storage->line_count * sizeof(*storage->line));
|
||||
|
||||
for (i = 0; i < storage->line_count; i++)
|
||||
storage->line[i] = malloc(sizeof(char) * DTOP_MEM_LINE);
|
||||
|
||||
read = dt_read_file("/proc/meminfo", &data, DTOP_MEM_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < storage->line_count; n++) {
|
||||
line_len[n] = dt_read_line(storage->line[n],
|
||||
DTOP_MEM_LINE, data,
|
||||
DTOP_MEM_SIZE, sum);
|
||||
if (n < (storage->line_count - 1))
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
/* Stores dp names in dictionary */
|
||||
for (i = 0; i < (storage->line_count); i++)
|
||||
dt_parse_proc_same_line_key_and_val(storage->line[i],
|
||||
line_len[i], i, &dict);
|
||||
|
||||
data_points = malloc
|
||||
(storage->line_count * sizeof(struct dtop_data_point));
|
||||
|
||||
k = 0;
|
||||
/* Creates a dtop_data_point struct for each dp found in the file */
|
||||
for (i = 0; i < dict.max; i++) {
|
||||
data_points[i].name = dict.key[i];
|
||||
data_points[i].prefix = NULL;
|
||||
data_points[i].type = DTOP_ULONG;
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Calls dpg constructor, dpg will point to the dp struct */
|
||||
construct_meminfo_file_dpg(data_points, storage);
|
||||
|
||||
free(line_len);
|
||||
dt_free(&data);
|
||||
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for "/proc/meminfo" file.
|
||||
*/
|
||||
void dtop_meminfo_init(void)
|
||||
{
|
||||
struct dtop_meminfo_vars *storage = malloc
|
||||
(sizeof(struct dtop_meminfo_vars));
|
||||
storage->line_count = dtop_get_file_line_amount("/proc/meminfo");
|
||||
dtop_meminfo_search(storage);
|
||||
}
|
||||
215
qcom/opensource/dataservices/datatop/src/datatop_opt.c
Executable file
215
qcom/opensource/dataservices/datatop/src/datatop_opt.c
Executable file
@@ -0,0 +1,215 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_opt.c
|
||||
* @brief Adds getopt functionality for CLI commands.
|
||||
*
|
||||
* Contains method for getopt functionality used for parsing
|
||||
* the CLI arguments into executable commands. Handles
|
||||
* errors which arise when parsing.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <getopt.h>
|
||||
#include <time.h>
|
||||
#include "datatop_opt.h"
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_linked_list.h"
|
||||
#include "datatop_fileops.h"
|
||||
|
||||
/**
|
||||
* @brief Populate the comand line options with sane defaults
|
||||
*
|
||||
* @param clopts Struct used to hold data regarding CLI arguments.
|
||||
*/
|
||||
void dtop_load_default_options(struct cli_opts *clopts)
|
||||
{
|
||||
memset(clopts, 0, sizeof(struct cli_opts));
|
||||
|
||||
clopts->priority = DEFAULT_NICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses all CLI commands for main() to execute.
|
||||
*
|
||||
* @param clopts Struct used to hold data regarding CLI arguments.
|
||||
* @param argc Parameter used to read CLI commands from.
|
||||
* @param argv Parameter used to read CLI arguments from.
|
||||
* @return PARSE_SUCCESS - CLI arguments read successfully,
|
||||
* @return PARSE_FAILURE - CLI arguments and/or input not valid.
|
||||
* @return PARSE_FORCE_EXIT - Exit immediately, print help options.
|
||||
*/
|
||||
int dtop_parse_cli_opts(struct cli_opts *clopts, int argc, char **argv)
|
||||
{
|
||||
int option;
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
char timestamp[100];
|
||||
|
||||
time ( &rawtime );
|
||||
timeinfo = gmtime ( &rawtime );
|
||||
strftime (timestamp, 100,"%F_%H-%M-%S",timeinfo);
|
||||
|
||||
if (!clopts || !*argv) {
|
||||
printf("Internal Error: Null Pointer\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
while ((option = getopt(argc, argv, "phri:t:w:o:s:n:")) != -1) {
|
||||
switch (option) {
|
||||
case 'p':
|
||||
clopts->print_cl = OPT_CHOSE;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
dtop_print_help_opts();
|
||||
return PARSE_FORCE_EXIT;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
clopts->priority = strtol(optarg, 0, 10);
|
||||
if (clopts->priority > 19 || clopts->priority < -20) {
|
||||
printf("Argument for -n is not valid. ");
|
||||
printf("Must be between -20 and 19.\n");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
clopts->poll_per = strtol(optarg, 0, 10);
|
||||
if (clopts->poll_per < 200000) {
|
||||
printf("Argument for -i is not valid. ");
|
||||
printf("Must be atleast 200000\n");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
clopts->poll_time = strtol(optarg, 0, 10);
|
||||
clopts->poll_time_selected = POLL_TIME_SELECTED;
|
||||
if (clopts->poll_time <= 0) {
|
||||
printf("Argument for -t is not valid. ");
|
||||
printf("Must be positive integer.\n");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
if (dtop_check_writefile_access(optarg) == VALID) {
|
||||
clopts->file_name = optarg;
|
||||
clopts->print_csv = OPT_CHOSE;
|
||||
} else {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
if (dtop_check_out_dir_presence(optarg) != VALID) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(strlen(optarg) + strlen(timestamp) > OUT_DIR_LEN_MAX) {
|
||||
printf("Out dir too long!");
|
||||
goto error;
|
||||
}
|
||||
strcpy(clopts->out_dir, optarg);
|
||||
strcat(clopts->out_dir, "/");
|
||||
strcat(clopts->out_dir, timestamp);
|
||||
if(dtop_create_dir(clopts->out_dir) != INVALID) {
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (dtop_check_writefile_access(optarg) == VALID)
|
||||
clopts->snapshot_file = optarg;
|
||||
else
|
||||
goto error;
|
||||
break;
|
||||
|
||||
case 'r':
|
||||
clopts->iptables_rules_routes = OPT_CHOSE;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (clopts->poll_time == 0) {
|
||||
if (clopts->print_csv == 1)
|
||||
clopts->poll_time = POLL_NOT_SPECIFIED;
|
||||
else
|
||||
clopts->poll_time = POLL_TIME_DEFAULT;
|
||||
}
|
||||
if (clopts->poll_per == 0)
|
||||
clopts->poll_per = DEFAULT_POLL_INTERVAL;
|
||||
|
||||
return PARSE_SUCCESS;
|
||||
|
||||
error:
|
||||
printf("See datatop -h for help\n");
|
||||
return PARSE_FAILURE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints the options the user has for the program to terminal.
|
||||
*/
|
||||
void dtop_print_help_opts(void)
|
||||
{
|
||||
printf("The following datatop commands are:\n");
|
||||
printf("\t-p\t\t\tPrint output to terminal\n");
|
||||
printf("\t-i , u-seconds\t\tSpecify polling period \n");
|
||||
printf("\t-t , seconds\t\tSpecify polling duration\n");
|
||||
printf("\t-w , file name (.csv)\tWrite output to a file\n");
|
||||
printf("\t-s , file name\t\tPrint system snapshot to a file\n");
|
||||
printf("\t-n , nice value\t\tSet niceness (default 19)\n");
|
||||
printf("\t-r , \t\t\tCapture IPTables, Rules and Routes\n");
|
||||
printf("\t-o , out directory for -w options\t\tOut dir where the set of files are saved\n");
|
||||
printf("\t-h\t\t\tGet help\n");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Prints the interactive options the user can enter during runtime.
|
||||
*/
|
||||
void dtop_print_interactive_opts(void)
|
||||
{
|
||||
printf("The following interactive commands are:\n");
|
||||
printf("\tq | quit\tTerminate program at any time\n");
|
||||
printf("\ti\t\tPrint dp differences, reset initial dp values\n");
|
||||
printf("\tl\t\tPrint dp differences since last reset\n");
|
||||
printf("\n");
|
||||
}
|
||||
91
qcom/opensource/dataservices/datatop/src/datatop_opt.h
Executable file
91
qcom/opensource/dataservices/datatop/src/datatop_opt.h
Executable file
@@ -0,0 +1,91 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_opt.h
|
||||
* @brief Declares methods and defines struct used within datatop_opt.c
|
||||
*
|
||||
* Struct defined is used when parsing the CLI arguments.
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_OPT_H
|
||||
#define DATATOP_OPT_H
|
||||
|
||||
#define OPT_CHOSE 1
|
||||
#define OPT_NOT_CHOSE 0
|
||||
#define DEFAULT_POLL_INTERVAL 1000000
|
||||
#define POLL_NOT_SPECIFIED -1
|
||||
#define POLL_TIME_DEFAULT 30
|
||||
#define POLL_TIME_SELECTED 1
|
||||
#define PARSE_SUCCESS 0
|
||||
#define PARSE_FAILURE -1
|
||||
#define PARSE_FORCE_EXIT -2
|
||||
#define VALID 0
|
||||
#define INVALID -1
|
||||
#define DEFAULT_NICE 19 /* Lowest priority */
|
||||
#define OUT_DIR_LEN_MAX 150
|
||||
|
||||
/**
|
||||
* @struct cli_opts
|
||||
* @brief Struct used to store arguments from CLI input.
|
||||
*
|
||||
* @var cli_opts::print_cl
|
||||
* Represents -p argument.
|
||||
* @var cli_opts::poll_per
|
||||
* Polling frequency argument.
|
||||
* @var cli_opts::poll_time
|
||||
* Polling duration argument.
|
||||
* @var cli_opts::cli_help
|
||||
* Represents -h argument.
|
||||
* @var cli_opts::file_name
|
||||
* File name argument.
|
||||
* @var cli_opts::print_csv
|
||||
* Represents -w argument.
|
||||
*/
|
||||
struct cli_opts {
|
||||
int print_cl; /* -p option */
|
||||
long int poll_per; /* -i option */
|
||||
long int poll_time; /* -t option */
|
||||
int cli_help; /* -h option */
|
||||
char *file_name; /* -w option */
|
||||
char *snapshot_file; /* -s option */
|
||||
int iptables_rules_routes; /* -r option */
|
||||
char out_dir[OUT_DIR_LEN_MAX]; /* -o option */
|
||||
int print_csv;
|
||||
int poll_time_selected;
|
||||
int priority; /* -n option (niceness) */
|
||||
};
|
||||
|
||||
int dtop_parse_cli_opts(struct cli_opts *clopts, int argc, char **argv);
|
||||
void dtop_print_help_opts(void);
|
||||
void dtop_print_interactive_opts(void);
|
||||
void dtop_load_default_options(struct cli_opts *clopts);
|
||||
|
||||
#endif /* DATATOP_OPT_H */
|
||||
|
||||
51
qcom/opensource/dataservices/datatop/src/datatop_polling.h
Normal file
51
qcom/opensource/dataservices/datatop/src/datatop_polling.h
Normal file
@@ -0,0 +1,51 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015-2016, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_dual_line_poll.h
|
||||
* @brief Declares methods held in datatop_dual_line_poll.c
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_DUAL_LINE_POLL_H
|
||||
#define DATATOP_DUAL_LINE_POLL_H
|
||||
|
||||
void dtop_dual_line_init(char *name);
|
||||
void dtop_single_line_init(char *name);
|
||||
void dtop_value_only_init(char *name);
|
||||
void dtop_meminfo_init(void);
|
||||
void dtop_dev_init(void);
|
||||
void dtop_stat_init(void);
|
||||
void dtop_ip_table_init(char *out_dir);
|
||||
void *dtop_ip_table_start_poll(void * arg);
|
||||
void dtop_cpu_stats_init(void);
|
||||
int dtop_value_only_poll(struct dtop_data_point_gatherer *dpg);
|
||||
void dtop_value_only_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset);
|
||||
|
||||
#endif /* DATATOP_DUAL_LINE_POLL_H */
|
||||
@@ -0,0 +1,243 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_single_line_poll.c
|
||||
* @brief Adds ability for data collection from single line files
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* single line files, meaning a file with multiple lines, but each
|
||||
* line contains the name of the dp, followed by the value.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_SINGLE_SIZE 8192
|
||||
#define DTOP_SINGLE_LINE (DTOP_SINGLE_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @struct dtop_single_line_vars
|
||||
* @brief Struct used to hold necessary variables for dual_line_file dpgs.
|
||||
*
|
||||
* @var dtop_single_line_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_single_line_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_single_line_vars {
|
||||
char **line;
|
||||
int line_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from a single_line files.
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_single_line_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) *
|
||||
((struct dtop_single_line_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
int i, j, n, sum;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_SINGLE_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < ((struct dtop_single_line_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
line_len[n] = dt_read_line(((struct dtop_single_line_vars *)
|
||||
(dpg->priv))->line[n],
|
||||
DTOP_SINGLE_LINE, data,
|
||||
DTOP_SINGLE_SIZE, sum);
|
||||
if (n <= (((struct dtop_single_line_vars *)
|
||||
(dpg->priv))->line_count - 1)) {
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores dp names and values in dictionary */
|
||||
for (i = 0; i < dpg->data_points_len; i++)
|
||||
dt_parse_proc_same_line_key_and_val((
|
||||
(struct dtop_single_line_vars *)
|
||||
(dpg->priv))->line[i], line_len[i], i, &dict);
|
||||
|
||||
/* Assigns the dp value to the dp struct */
|
||||
for (j = 0; j < dpg->data_points_len; j++) {
|
||||
i = dt_find_dict_idx(dpg->data_points[j].name, &dict);
|
||||
if (i >= 0 && i < dict.max)
|
||||
dtop_store_dp(&(dpg->data_points[j]),
|
||||
dict.val[i]);
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
free(line_len);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated single_line_file dpgs.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_single_line_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
free(dpset->data_points);
|
||||
for (i = 0; i < ((struct dtop_single_line_vars *)
|
||||
(dpset->priv))->line_count; i++)
|
||||
free(((struct dtop_single_line_vars *)(dpset->priv))->line[i]);
|
||||
free(((struct dtop_single_line_vars *)(dpset->priv))->line);
|
||||
free(((struct dtop_single_line_vars *)(dpset->priv)));
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for a single_line file.
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param name Name of file dpg represents.
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_single_line_vars struct that holds relevant dpg variables.
|
||||
*/
|
||||
static void construct_single_line_file_dpg(char *name, struct dtop_data_point
|
||||
*data_points, struct dtop_single_line_vars *storage)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
dpg->prefix = name;
|
||||
dpg->file = name;
|
||||
dpg->poll = dtop_single_line_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->priv = (struct dtop_single_line_vars *)storage;
|
||||
dpg->data_points_len = storage->line_count;
|
||||
dpg->deconstruct = dtop_single_line_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans a single_line file for all datapoints and creats dps.
|
||||
*
|
||||
* Searches through a single_line file (Key followed by value on the
|
||||
* same line) for all available data points to create as dp structs.
|
||||
*
|
||||
* @param name Name of file.
|
||||
* @param storage dtop_single_line_vars struct where relevant variables are stored.
|
||||
*/
|
||||
int dtop_single_line_search(char *name, struct dtop_single_line_vars *storage)
|
||||
{
|
||||
int i, k, n, sum;
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) * storage->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
struct dtop_data_point *data_points;
|
||||
|
||||
storage->line = malloc(storage->line_count * sizeof(*storage->line));
|
||||
|
||||
for (i = 0; i < storage->line_count; i++)
|
||||
storage->line[i] = malloc(sizeof(char) * DTOP_SINGLE_LINE);
|
||||
|
||||
read = dt_read_file(name, &data, DTOP_SINGLE_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < storage->line_count; n++) {
|
||||
line_len[n] = dt_read_line(storage->line[n],
|
||||
DTOP_SINGLE_LINE, data,
|
||||
DTOP_SINGLE_SIZE, sum);
|
||||
if (n < (storage->line_count - 1))
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
/* Stores dp names and values in dictionary */
|
||||
for (i = 0; i < (storage->line_count); i++)
|
||||
dt_parse_proc_same_line_key_and_val(storage->line[i],
|
||||
line_len[i], i, &dict);
|
||||
|
||||
data_points = malloc
|
||||
(storage->line_count * sizeof(struct dtop_data_point));
|
||||
|
||||
k = 0;
|
||||
/* Creates a dtop_data_point struct for each dp found in the file */
|
||||
for (i = 0; i < dict.max; i++) {
|
||||
if (dict.val[i][0] == '-')
|
||||
data_points[k].type = DTOP_LONG;
|
||||
else
|
||||
data_points[k].type = DTOP_ULONG;
|
||||
data_points[i].name = dict.key[i];
|
||||
data_points[i].prefix = NULL;
|
||||
k++;
|
||||
}
|
||||
|
||||
/* Calls dpg constructor, dpg will point to the dp struct */
|
||||
construct_single_line_file_dpg(name, data_points, storage);
|
||||
|
||||
free(line_len);
|
||||
dt_free(&data);
|
||||
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for a files with single line format.
|
||||
*
|
||||
* Single line format refers to a file, where each line contains
|
||||
* the name of a dp, followed by the value of a dp.
|
||||
*/
|
||||
void dtop_single_line_init(char *name)
|
||||
{
|
||||
struct dtop_single_line_vars *storage = malloc
|
||||
(sizeof(struct dtop_single_line_vars));
|
||||
storage->line_count = dtop_get_file_line_amount(name);
|
||||
dtop_single_line_search(name, storage);
|
||||
}
|
||||
319
qcom/opensource/dataservices/datatop/src/datatop_stat_poll.c
Normal file
319
qcom/opensource/dataservices/datatop/src/datatop_stat_poll.c
Normal file
@@ -0,0 +1,319 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_stat_poll.c
|
||||
* @brief Adds ability for data collection from /proc/stat
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* "/proc/stat"
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_STAT_SIZE 16384
|
||||
#define DTOP_STAT_LINE (DTOP_STAT_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @struct dtop_stat_vars
|
||||
* @brief Struct used to hold necessary variables for /proc/stat dpg
|
||||
*
|
||||
* @var dtop_stat_vars::line
|
||||
* Array of strings where necessary dp names and values are held.
|
||||
* @var dtop_stat_vars::line_count
|
||||
* Number of lines the file is that the dpg represents.
|
||||
*/
|
||||
struct dtop_stat_vars {
|
||||
char **line;
|
||||
int line_count;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Parses lines with data in "/proc/stat"
|
||||
*
|
||||
* @param line1 Line to parse to find datapoint names and values.
|
||||
* @param len1 Length of line1.
|
||||
* @param n_index Index in the dictionary the key (name) is added to.
|
||||
* @param v_index Index in the dictionary the value is added to.
|
||||
* @param dict Dictionary the keys and values are added to.
|
||||
*/
|
||||
static int dt_stat_parse(char *line1, int len1,
|
||||
int n_index, int v_index, struct dt_procdict *dict)
|
||||
{
|
||||
int i, k, j, start = 0;
|
||||
if (len1 < 1)
|
||||
return 0;
|
||||
|
||||
if (line1 == 0 || dict == 0)
|
||||
return 0;
|
||||
|
||||
dict->key[n_index] = &line1[0];
|
||||
for (i = 0; i < len1; i++) {
|
||||
if (line1[i] == ' ') {
|
||||
line1[i] = 0;
|
||||
start = (i+1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
k = v_index;
|
||||
for (i = start; i < len1 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line1[i] != ' ') {
|
||||
dict->val[k] = &line1[i];
|
||||
for (j = i; j < len1; j++) {
|
||||
if (line1[j] == ' ') {
|
||||
line1[j] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
i = j;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
dict->max = k;
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from "/proc/stat"
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_stat_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) *
|
||||
((struct dtop_stat_vars *)
|
||||
(dpg->priv))->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
int i, n, sum;
|
||||
int dp_count = 0;
|
||||
|
||||
read = dt_read_file(dpg->file, &data, DTOP_STAT_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < ((struct dtop_stat_vars *)
|
||||
(dpg->priv))->line_count; n++) {
|
||||
line_len[n] = dt_read_line(((struct dtop_stat_vars *)
|
||||
(dpg->priv))->line[n],
|
||||
DTOP_STAT_LINE, data,
|
||||
DTOP_STAT_SIZE, sum);
|
||||
if (n <= (((struct dtop_stat_vars *)
|
||||
(dpg->priv))->line_count - 1)) {
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Stores dp names and values in dictionary */
|
||||
for (i = 0; i < ((struct dtop_stat_vars *)(dpg->priv))->line_count; i++)
|
||||
dp_count = dt_stat_parse(((struct dtop_stat_vars *)
|
||||
(dpg->priv))->line[i], line_len[i], i, dp_count, &dict);
|
||||
|
||||
/* Assigns the dp value to the dp struct */
|
||||
for (n = 0; n < dp_count; n++) {
|
||||
dtop_store_dp(&(dpg->data_points[n]),
|
||||
dict.val[n]);
|
||||
}
|
||||
|
||||
dt_free(&data);
|
||||
free(line_len);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated "/proc/stat" dpg.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
static void dtop_stat_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dpset->data_points_len; i++)
|
||||
free(dpset->data_points[i].name);
|
||||
free(dpset->data_points);
|
||||
for (i = 0; i < ((struct dtop_stat_vars *)
|
||||
(dpset->priv))->line_count; i++)
|
||||
free(((struct dtop_stat_vars *)(dpset->priv))->line[i]);
|
||||
free(((struct dtop_stat_vars *)(dpset->priv))->line);
|
||||
free(((struct dtop_stat_vars *)(dpset->priv)));
|
||||
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for "/proc/stat" file
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param storage dtop_stat_vars struct that holds relevant dpg variables.
|
||||
* @param dp_count Number of data_points in data_points array
|
||||
*/
|
||||
static void construct_stat_file_dpg(struct dtop_data_point
|
||||
*data_points, struct dtop_stat_vars *storage, int dp_count)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
dpg->prefix = "/proc/stat";
|
||||
dpg->file = "/proc/stat";
|
||||
dpg->poll = dtop_stat_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->priv = (struct dtop_stat_vars *)storage;
|
||||
dpg->data_points_len = dp_count;
|
||||
dpg->deconstruct = dtop_stat_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans "/proc/stat" in order to autodetect dps.
|
||||
*
|
||||
* Searches through "/proc/stat" file for all available data
|
||||
* points to create as dp structs.
|
||||
*
|
||||
* @param storage dtop_stat_vars struct where relevant variables are stored.
|
||||
*/
|
||||
int dtop_stat_search(struct dtop_stat_vars *storage)
|
||||
{
|
||||
int i, n, sum;
|
||||
char *data;
|
||||
int *line_len = malloc(sizeof(int) * storage->line_count);
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
int dp_count = 0;
|
||||
int end;
|
||||
int *dp_per_line;
|
||||
struct dtop_data_point *data_points;
|
||||
int count = 0;
|
||||
|
||||
storage->line = malloc(storage->line_count * sizeof(*storage->line));
|
||||
|
||||
for (i = 0; i < storage->line_count; i++)
|
||||
storage->line[i] = malloc(sizeof(char) * DTOP_STAT_LINE);
|
||||
|
||||
read = dt_read_file("/proc/stat", &data, DTOP_STAT_SIZE);
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
sum = 0;
|
||||
/* Assigns each line read from the file, a length */
|
||||
for (n = 0; n < storage->line_count; n++) {
|
||||
line_len[n] = dt_read_line(storage->line[n],
|
||||
DTOP_STAT_LINE, data,
|
||||
DTOP_STAT_SIZE, sum);
|
||||
if (n < (storage->line_count - 1))
|
||||
sum += (line_len[n] + 1);
|
||||
}
|
||||
|
||||
dp_per_line = malloc(sizeof(int) * (storage->line_count));
|
||||
/* Stores dp names in dictionary */
|
||||
|
||||
for (i = 0; i < (storage->line_count); i++) {
|
||||
end = dp_count;
|
||||
dp_count = dt_stat_parse(storage->line[i],
|
||||
line_len[i], i, dp_count, &dict);
|
||||
dp_per_line[i] = (dp_count - end);
|
||||
}
|
||||
|
||||
data_points = malloc(dp_count * sizeof(struct dtop_data_point));
|
||||
|
||||
for (i = 0; i < (storage->line_count); i++) {
|
||||
for (n = 0; n < dp_per_line[i]; n++) {
|
||||
if (dp_per_line[i] == 1) {
|
||||
int dk_len = strlen(dict.key[i]) + 1;
|
||||
int dp_len;
|
||||
char *newname = malloc(dk_len);
|
||||
strlcpy(newname, dict.key[i], dk_len);
|
||||
dp_len = strlen(newname) + 1;
|
||||
data_points[count].name = malloc(dp_len);
|
||||
strlcpy(data_points[count].name, newname,
|
||||
dp_len);
|
||||
free(newname);
|
||||
} else {
|
||||
char *add = malloc(15 * sizeof(char));
|
||||
char *newname;
|
||||
int nn_len, dpn_len;
|
||||
snprintf(add, 15 * sizeof(char), "[%d]:", n);
|
||||
nn_len = strlen(dict.key[i]) + strlen(add) + 1;
|
||||
newname = malloc(nn_len);
|
||||
strlcpy(newname, dict.key[i], nn_len);
|
||||
strlcat(newname, add, nn_len);
|
||||
dpn_len = strlen(newname) + 1;
|
||||
data_points[count].name = malloc(dpn_len);
|
||||
strlcpy(data_points[count].name, newname,
|
||||
dpn_len);
|
||||
free(newname);
|
||||
free(add);
|
||||
}
|
||||
data_points[count].prefix = NULL;
|
||||
data_points[count].type = DTOP_ULONG;
|
||||
data_points[count].initial_data_populated
|
||||
= NOT_POPULATED;
|
||||
data_points[count].skip = DO_NOT_SKIP;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calls dpg constructor, dpg will point to the dp struct */
|
||||
construct_stat_file_dpg(data_points, storage, dp_count);
|
||||
free(dp_per_line);
|
||||
free(line_len);
|
||||
dt_free(&data);
|
||||
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for "/proc/stat" file.
|
||||
*/
|
||||
void dtop_stat_init(void)
|
||||
{
|
||||
struct dtop_stat_vars *storage = malloc
|
||||
(sizeof(struct dtop_stat_vars));
|
||||
storage->line_count = dtop_get_file_line_amount("/proc/stat");
|
||||
dtop_stat_search(storage);
|
||||
}
|
||||
260
qcom/opensource/dataservices/datatop/src/datatop_str.c
Normal file
260
qcom/opensource/dataservices/datatop/src/datatop_str.c
Normal file
@@ -0,0 +1,260 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_str.c
|
||||
* @brief Algorithms used for storing and polling data created.
|
||||
*
|
||||
* Methods created which store collected data from files in
|
||||
* dictionaries for many different file formats.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "datatop_str.h"
|
||||
|
||||
/** @brief Reads an individual line from a file.
|
||||
*
|
||||
* Will read from buf2 until either a '\n' is reached, or the end of buf1
|
||||
* or buf2 is reached. The result is guaranteed to be null terminated.
|
||||
*
|
||||
* @param buf1 Destination buffer to store the read line.
|
||||
* @param len1 Size of destination buffer.
|
||||
* @param buf2 Source buffer to read lines from. Const, will not be
|
||||
* modified by this function.
|
||||
* @param len2 Size of the source buffer.
|
||||
* @param start Offset (in bytes) to start reading from source buffer.
|
||||
* @return Length of line (of chars).
|
||||
*/
|
||||
int dt_read_line(char *buf1, int len1, const char *buf2, int len2, int start)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (len1 < 1 || len2 < 1 || start < 0 || start > len2)
|
||||
return 0;
|
||||
|
||||
if (buf1 == 0 || buf2 == 0)
|
||||
return 0;
|
||||
|
||||
i = 0;
|
||||
j = start;
|
||||
|
||||
while ((i < (len1-1)) && (j < len2)) {
|
||||
buf1[i] = buf2[j];
|
||||
if (buf1[i] == '\n')
|
||||
break;
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
buf1[i] = 0;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses files that have Names and Values on separate lines.
|
||||
*
|
||||
* Use this method to parse files that have names on one line, followed by
|
||||
* the corresponding values on the next line. Such as "/proc/net/netstat"
|
||||
*
|
||||
* @param line1 First line that is parsed to store the datapoint names as keys.
|
||||
* @param len1 Length of line1.
|
||||
* @param line2 Second line that is parsed to store the datapoint values as dictionary values.
|
||||
* @param len2 Length of line2.
|
||||
* @param dict Dictionary that keys and values are added to.
|
||||
* @return Number of key/val pairs in the dictionary.
|
||||
*/
|
||||
int dt_parse_proc_dictionary(char *line1, int len1, char *line2,
|
||||
int len2, struct dt_procdict *dict)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
if (len1 < 1 || len2 < 1)
|
||||
return 0;
|
||||
|
||||
if (line1 == 0 || line2 == 0 || dict == 0)
|
||||
return 0;
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < len1 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line1[i] == ' ') {
|
||||
dict->key[k] = &line1[i+1];
|
||||
line1[i] = 0;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
j = k;
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < len2 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line2[i] == ' ') {
|
||||
dict->val[k] = &line2[i+1];
|
||||
line2[i] = 0;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
if (j != k) {
|
||||
if (k < j)
|
||||
j = k;
|
||||
fprintf(stderr, "Warning, list index length mismatch\n");
|
||||
}
|
||||
dict->max = j;
|
||||
return j;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses line for prefixes for files that have individual data_point prefixes.
|
||||
*
|
||||
* Use this method for lines that have a prefix before data begins. Such as
|
||||
* "/proc/net/snmp"
|
||||
*
|
||||
* @param line1 Line to parse to find datapoint prefix.
|
||||
* @param len1 Length of line1.
|
||||
* @param dict Dictionary prefix is being added to.
|
||||
*/
|
||||
void dt_parse_for_prefix(char *line1, int len1, struct dt_procdict *dict)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
if (len1 < 1)
|
||||
return;
|
||||
|
||||
if (line1 == 0 || dict == 0)
|
||||
return;
|
||||
|
||||
k = 0;
|
||||
for (i = 0; i < len1 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line1[i] == ' ') {
|
||||
dict->key[k] = &line1[i+1];
|
||||
line1[i] = 0;
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
for (j = 0; j < k; j++)
|
||||
dict->val[j] = &line1[0];
|
||||
|
||||
for (j = 0; j < len1; j++) {
|
||||
if (line1[j] == ':')
|
||||
line1[j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Finds the dictionary index of a data_point name.
|
||||
*
|
||||
* @param str Name of data_point that is to be located in dict.
|
||||
* @param dict Dictionary to look through for dp name.
|
||||
* @return Dictionary index of name if found.
|
||||
* @return -1 if name not found in dictionary keys.
|
||||
*/
|
||||
int dt_find_dict_idx(const char *str, struct dt_procdict *dict)
|
||||
{
|
||||
int i;
|
||||
if (str == 0 || dict == 0)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < dict->max; i++) {
|
||||
if (dict->key[i] && !strcmp(str, dict->key[i]))
|
||||
return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses files that have Names and Values on same line.
|
||||
*
|
||||
* Use this method to parse lines that have a dp name followed
|
||||
* by a dp value. Such as "/proc/net/snmp6"
|
||||
*
|
||||
* @param line1 Line to parse to find datapoint names and values.
|
||||
* @param len1 Length of line1.
|
||||
* @param l Index in the dictionary the key/val pair is added to.
|
||||
* @param dict Dictionary the keys and values are added to.
|
||||
* @return Number of key/val pairs in the dictionary.
|
||||
*/
|
||||
int dt_parse_proc_same_line_key_and_val(char *line1, int len1,
|
||||
int l, struct dt_procdict *dict)
|
||||
{
|
||||
int i, k, n;
|
||||
if (len1 < 1)
|
||||
return 0;
|
||||
|
||||
if (line1 == 0 || dict == 0)
|
||||
return 0;
|
||||
|
||||
k = l;
|
||||
for (i = 0; i < len1 && k < DTOP_DICT_SIZE; i++) {
|
||||
if (line1[i] == ' ') {
|
||||
dict->key[k] = &line1[0];
|
||||
line1[i] = 0;
|
||||
for (n = i+1; n < len1; n++) {
|
||||
if (line1[n] != ' ') {
|
||||
dict->val[k] = &line1[n+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
k++;
|
||||
dict->max = k;
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parses files that have a single line.
|
||||
*
|
||||
* Parses a single line file for csv, tab-separated, space-separated, and single
|
||||
* value formats and adds values to a dictionary. Such as
|
||||
* "/proc/sys/net/ipv4/ping_group_range"
|
||||
*
|
||||
* Use this method to parse lines that contain only values.
|
||||
*
|
||||
* @param line1 Line to parse.
|
||||
* @param len1 Length of line1.
|
||||
* @param dict Dictionary datapoints are added to.
|
||||
* @return Number of values dictionary holds.
|
||||
*/
|
||||
int dt_single_line_parse(char *line1, int len1, struct dt_procdict *dict)
|
||||
{
|
||||
int i, k;
|
||||
k = 0;
|
||||
dict->val[k] = &line1[0];
|
||||
k++;
|
||||
|
||||
for (i = 0; i < len1; i++) {
|
||||
if (line1[i] == ' ' || line1[i] == ',' || line1[i] == ' ') {
|
||||
line1[i] = 0;
|
||||
dict->val[k] = &line1[i+1];
|
||||
k++;
|
||||
}
|
||||
}
|
||||
dict->max = k;
|
||||
return k;
|
||||
}
|
||||
70
qcom/opensource/dataservices/datatop/src/datatop_str.h
Normal file
70
qcom/opensource/dataservices/datatop/src/datatop_str.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_str.h
|
||||
* @brief Declares methods held in datatop_str.c and defines dictionary struct.
|
||||
*/
|
||||
|
||||
#ifndef DATATOP_STR_H
|
||||
#define DATATOP_STR_H
|
||||
|
||||
#define DTOP_DICT_SIZE 2048
|
||||
|
||||
/**
|
||||
* @struct dt_procdict
|
||||
* @brief Struct used to create dictionary for parsing purposes.
|
||||
*
|
||||
* @var dt_procdict::max
|
||||
* Number of key/val pairs in dictionary.
|
||||
* @var dt_procdict::key
|
||||
* Holds the key that is used to access the value.
|
||||
* @var dt_procdict::val
|
||||
* Value that the key accesses.
|
||||
*/
|
||||
struct dt_procdict {
|
||||
int max;
|
||||
char *key[DTOP_DICT_SIZE];
|
||||
char *val[DTOP_DICT_SIZE];
|
||||
};
|
||||
|
||||
int dt_read_line(char *buf1, int len1, const char *buf2, int len2, int start);
|
||||
|
||||
int dt_parse_proc_dictionary(char *line1, int len1, char *line2, int len2,
|
||||
struct dt_procdict *dict);
|
||||
|
||||
int dt_find_dict_idx(const char *str, struct dt_procdict *dict);
|
||||
|
||||
int dt_parse_proc_same_line_key_and_val(char *line1, int len1, int l,
|
||||
struct dt_procdict *dict);
|
||||
|
||||
void dt_parse_for_prefix(char *line1, int len1, struct dt_procdict *dict);
|
||||
|
||||
int dt_single_line_parse(char *line1, int len1, struct dt_procdict *dict);
|
||||
#endif /* DATATOP_STR_H */
|
||||
199
qcom/opensource/dataservices/datatop/src/datatop_sys_snap.c
Normal file
199
qcom/opensource/dataservices/datatop/src/datatop_sys_snap.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
#include "datatop_opt.h"
|
||||
|
||||
#define DTOP_SNAP_SIZE 8192
|
||||
#define DTOP_SNAP_LINE (DTOP_SNAP_SIZE>>2)
|
||||
|
||||
static int dtop_system_snapshot_helper_print(char *file, const char *str)
|
||||
{
|
||||
FILE *snap_file = fopen(file, "a");
|
||||
|
||||
if (snap_file) {
|
||||
if (fprintf(snap_file, "%s", str) < 0) {
|
||||
fclose(snap_file);
|
||||
return FILE_ERROR;
|
||||
}
|
||||
} else {
|
||||
return FILE_ERROR;
|
||||
}
|
||||
fflush(snap_file);
|
||||
fclose(snap_file);
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A helper function to dtop_print_system_snapshot.
|
||||
*
|
||||
* @param fw File that desired system data is printed to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
static int dtop_run_and_log(char *file, const char *c1, const char **args)
|
||||
{
|
||||
int i;
|
||||
pid_t child_pid;
|
||||
|
||||
i = 0;
|
||||
dtop_system_snapshot_helper_print(file, "\n"
|
||||
"--------------------------------------------------------------\n"
|
||||
"Command: ");
|
||||
while(args[i] != 0) {
|
||||
dtop_system_snapshot_helper_print(file, args[i++]);
|
||||
dtop_system_snapshot_helper_print(file, " ");
|
||||
}
|
||||
dtop_system_snapshot_helper_print(file, "\n");
|
||||
|
||||
|
||||
child_pid = fork();
|
||||
if (child_pid == 0) {
|
||||
int fd = open(file, O_WRONLY | O_APPEND | O_CREAT,
|
||||
S_IRUSR | S_IWUSR);
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
dup2(fd, STDERR_FILENO);
|
||||
close(fd);
|
||||
execvp(c1, (char * const *)args);
|
||||
printf("Failed to execute %s\n", c1);
|
||||
printf("errno=%d error=%s\n", errno, strerror(errno));
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
exit(0);
|
||||
} else if (child_pid < 0) {
|
||||
return FILE_ERROR;
|
||||
} else {
|
||||
int return_status;
|
||||
waitpid(child_pid, &return_status, 0);
|
||||
|
||||
if (return_status != 0)
|
||||
return FILE_ERROR;
|
||||
}
|
||||
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* IPv4 */
|
||||
const char *ip_addr_cmd[] = {"ip", "addr", 0};
|
||||
const char *ip_route_cmd[] = {"ip", "route", 0};
|
||||
const char *ip_route_all_tables_cmd[] = {"ip", "route", "show", "table", "all", 0};
|
||||
const char *ip_rule_cmd[] = {"ip", "rule", "show", 0};
|
||||
const char *ip_tables_cmd[] = {"iptables", "-L", "-n", "-v", 0};
|
||||
const char *ip_tables_nat_cmd[] = {"iptables", "-t", "nat", "-L", "-n", "-v", 0};
|
||||
const char *ip_tables_mangle_cmd[] = {"iptables", "-t", "mangle", "-L", "-n", "-v", 0};
|
||||
const char *ip_tables_raw_cmd[] = {"iptables", "-t", "raw", "-L", "-n", "-v", 0};
|
||||
|
||||
/* IPv6 */
|
||||
const char *ip6_addr_cmd[] = {"ip", "-6", "addr", 0};
|
||||
const char *ip6_route_cmd[] = {"ip", "-6", "route", 0};
|
||||
const char *ip6_route_all_tables_cmd[] = {"ip", "-6", "route", "show", "table", "all", 0};
|
||||
const char *ip6_rule_cmd[] = {"ip", "-6", "rule", "show", 0};
|
||||
const char *ip6_tables_cmd[] = {"ip6tables", "-L", "-n", "-v", 0};
|
||||
const char *ip6_tables_nat_cmd[] = {"ip6tables", "-t", "nat", "-L", "-n", "-v", 0};
|
||||
const char *ip6_tables_mangle_cmd[] = {"ip6tables", "-t", "mangle", "-L", "-n", "-v", 0};
|
||||
const char *ip6_tables_raw_cmd[] = {"ip6tables", "-t", "raw", "-L", "-n", "-v", 0};
|
||||
|
||||
/* Misc */
|
||||
const char *rps_config[] = {"cat", "/sys/class/net/rmnet_mhi0/queues/rx-0/rps_cpus", 0};
|
||||
const char *if_config[] = {"/data/busybox/busybox", "ifconfig", 0};
|
||||
const char *netcfg[] = {"netcfg", 0};
|
||||
const char *softnet_stat[] = {"cat", "/proc/net/softnet_stat", 0};
|
||||
|
||||
/* XFRM logging */
|
||||
const char *xfrm_state[] = {"ip", "xfrm", "state", "show", 0};
|
||||
const char *xfrm_policy[] = {"ip", "xfrm", "policy", "show", 0};
|
||||
const char *xfrm_netstat[] = {"cat", "/proc/net/xfrm_stat", 0};
|
||||
|
||||
#define DO_DTOP_RUN_AND_LOG(X) \
|
||||
dtop_run_and_log(file, X[0], X);
|
||||
/**
|
||||
* @brief Prints a System snapshot to a file specified by the user.
|
||||
*
|
||||
* @param fw File that system snapshot is printed to.
|
||||
* @return FILE_ERROR - Writing to file was unsuccessful.
|
||||
* @return FILE_SUCCESS - Writing to file was successful.
|
||||
*/
|
||||
int dtop_print_system_snapshot(char *file)
|
||||
{
|
||||
dtop_system_snapshot_helper_print(file,
|
||||
"==============================================================\n"
|
||||
" System Data Snapshot - Captured with Data Top \n"
|
||||
" Version ");
|
||||
dtop_system_snapshot_helper_print(file, VERSION);
|
||||
dtop_system_snapshot_helper_print(file, "\n"
|
||||
"==============================================================\n"
|
||||
"\n");
|
||||
|
||||
/* IPv4 */
|
||||
DO_DTOP_RUN_AND_LOG(ip_addr_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_route_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_route_all_tables_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_rule_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_tables_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_tables_nat_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_tables_mangle_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip_tables_raw_cmd);
|
||||
|
||||
/* IPv6 */
|
||||
DO_DTOP_RUN_AND_LOG(ip6_addr_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_route_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_route_all_tables_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_rule_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_tables_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_tables_nat_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_tables_mangle_cmd);
|
||||
DO_DTOP_RUN_AND_LOG(ip6_tables_raw_cmd);
|
||||
|
||||
/* Misc */
|
||||
DO_DTOP_RUN_AND_LOG(rps_config);
|
||||
DO_DTOP_RUN_AND_LOG(if_config);
|
||||
DO_DTOP_RUN_AND_LOG(netcfg);
|
||||
DO_DTOP_RUN_AND_LOG(softnet_stat);
|
||||
|
||||
/* XFRM logging */
|
||||
DO_DTOP_RUN_AND_LOG(xfrm_state);
|
||||
DO_DTOP_RUN_AND_LOG(xfrm_policy);
|
||||
DO_DTOP_RUN_AND_LOG(xfrm_netstat);
|
||||
|
||||
return FILE_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
/************************************************************************
|
||||
Copyright (c) 2015, The Linux Foundation. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of The Linux Foundation nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
************************************************************************/
|
||||
|
||||
/**
|
||||
* @file datatop_value_only_poll.c
|
||||
* @brief Adds ability for data collection from files with only values
|
||||
*
|
||||
* File contains methods for searching and polling data from
|
||||
* value_only files, meaning a file with a single line, containing
|
||||
* only values.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "datatop_interface.h"
|
||||
#include "datatop_fileops.h"
|
||||
#include "datatop_str.h"
|
||||
|
||||
#define DTOP_SINGLE_SIZE 8192
|
||||
#define DTOP_SINGLE_LINE (DTOP_SINGLE_SIZE>>2)
|
||||
|
||||
/**
|
||||
* @brief Stores the data collected from a value_only files.
|
||||
*
|
||||
* @param dpg Struct that polled data is added to.
|
||||
* @return DTOP_POLL_IO_ERR - Poll of dpg unsuccessful.
|
||||
* @return DTOP_POLL_OK - Poll of dpg successful.
|
||||
*/
|
||||
int dtop_value_only_poll(struct dtop_data_point_gatherer *dpg)
|
||||
{
|
||||
char *data;
|
||||
int line_len;
|
||||
char line[DTOP_SINGLE_LINE];
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
int j;
|
||||
FILE *check = fopen(dpg->file, "r");
|
||||
if (check) {
|
||||
fclose(check);
|
||||
read = dt_read_file(dpg->file, &data, DTOP_SINGLE_SIZE);
|
||||
} else {
|
||||
return DTOP_POLL_IO_ERR;
|
||||
}
|
||||
|
||||
if (read == 0 || data == 0)
|
||||
return DTOP_POLL_IO_ERR;
|
||||
|
||||
line_len = dt_read_line(line, DTOP_SINGLE_LINE, data,
|
||||
DTOP_SINGLE_SIZE, 0);
|
||||
|
||||
/* Stores dp values in dictionary */
|
||||
dt_single_line_parse(line, line_len, &dict);
|
||||
|
||||
/* Assigns the dp value to the dp struct */
|
||||
for (j = 0; j < dpg->data_points_len; j++)
|
||||
dtop_store_dp(&(dpg->data_points[j]), dict.val[j]);
|
||||
|
||||
dt_free(&data);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Frees dynamically allocated single line dpg.
|
||||
*
|
||||
* Frees the memory of the dpg along with it's data_points
|
||||
* and other malloc'd memory no longer needed.
|
||||
*
|
||||
* @param dpg Dpg to deconstruct and deallocate memory for.
|
||||
*/
|
||||
void dtop_value_only_dpg_deconstructor
|
||||
(struct dtop_data_point_gatherer *dpset)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < dpset->data_points_len; i++)
|
||||
free(dpset->data_points[i].name);
|
||||
free(dpset->data_points);
|
||||
free(dpset->file);
|
||||
free(dpset);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a dpg for a single line file.
|
||||
*
|
||||
* Dynamically allocates memory for dpg which is then added to a linked list
|
||||
* via the dtop_register(dpg) function call.
|
||||
*
|
||||
* @param name Name of file dpg represents.
|
||||
* @param data_points dtop_data_point struct that dpg points to.
|
||||
* @param dp_count Number of data_points in data_points array
|
||||
*/
|
||||
static void construct_value_only_dpg(char *name, struct dtop_data_point
|
||||
*data_points, int dp_count)
|
||||
{
|
||||
struct dtop_data_point_gatherer *dpg = malloc
|
||||
(sizeof(struct dtop_data_point_gatherer));
|
||||
dpg->prefix = name;
|
||||
dpg->file = name;
|
||||
dpg->poll = dtop_value_only_poll;
|
||||
dpg->data_points = data_points;
|
||||
dpg->data_points_len = dp_count;
|
||||
dpg->deconstruct = dtop_value_only_dpg_deconstructor;
|
||||
|
||||
dtop_register(dpg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Scans a single line file in order to autodetect dps.
|
||||
*
|
||||
* Searches through a file that contains a single line and only
|
||||
* values in order to detect and create dp's/
|
||||
*
|
||||
* @param name Name of file to scan.
|
||||
*/
|
||||
int dtop_value_only_search(char *name)
|
||||
{
|
||||
int i;
|
||||
char *data;
|
||||
char line[DTOP_SINGLE_LINE];
|
||||
int line_len;
|
||||
int read;
|
||||
struct dt_procdict dict;
|
||||
struct dtop_data_point *data_points;
|
||||
|
||||
|
||||
read = dt_read_file(name, &data, DTOP_SINGLE_SIZE);
|
||||
if (read == 0 || data == 0) {
|
||||
free(name);
|
||||
return DTOP_POLL_IO_ERR;
|
||||
}
|
||||
|
||||
line_len = dt_read_line(line,
|
||||
DTOP_SINGLE_LINE, data,
|
||||
DTOP_SINGLE_SIZE, 0);
|
||||
|
||||
/* Stores dp values in dictionary */
|
||||
dt_single_line_parse(line, line_len, &dict);
|
||||
|
||||
data_points = malloc(dict.max * sizeof(struct dtop_data_point));
|
||||
|
||||
/* Creates a dtop_data_point struct for each dp found in the file */
|
||||
for (i = 0; i < dict.max; i++) {
|
||||
char *newname = malloc(sizeof(10));
|
||||
if (dict.val[i][0] == '-')
|
||||
data_points[i].type = DTOP_LONG;
|
||||
else
|
||||
data_points[i].type = DTOP_ULONG;
|
||||
data_points[i].name = malloc(sizeof(10));
|
||||
if (dict.max > 1)
|
||||
snprintf(newname, sizeof(10), "[%d]:", i);
|
||||
else
|
||||
strlcpy(newname, "", sizeof(10));
|
||||
strlcpy(data_points[i].name, newname, sizeof(10));
|
||||
free(newname);
|
||||
data_points[i].prefix = NULL;
|
||||
data_points[i].skip = DO_NOT_SKIP;
|
||||
data_points[i].initial_data_populated = NOT_POPULATED;
|
||||
}
|
||||
|
||||
/* Calls dpg constructor, dpg will point to the dp struct */
|
||||
construct_value_only_dpg(name, data_points, dict.max);
|
||||
|
||||
dt_free(&data);
|
||||
return DTOP_POLL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calls dtop_search for files with a single line and only values.
|
||||
*/
|
||||
void dtop_value_only_init(char *name)
|
||||
{
|
||||
char *file = malloc(strlen(name) + 1);
|
||||
strlcpy(file, name, strlen(name) + 1);
|
||||
dtop_value_only_search(file);
|
||||
}
|
||||
Reference in New Issue
Block a user