mirror of
https://github.com/samba-team/samba.git
synced 2025-03-25 14:50:24 +03:00
r11579: syncing up perf counter code cfrom trunk
(This used to be commit 59c00924b67aa3d37a933731a56d03963ec7f1b5)
This commit is contained in:
parent
38b54d063d
commit
77460a9075
38
examples/perfcounter/Makefile
Normal file
38
examples/perfcounter/Makefile
Normal file
@ -0,0 +1,38 @@
|
||||
#
|
||||
# Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
|
||||
SAMBA_SRC_DIR=../../source
|
||||
TDB_SRC_DIR=$(SAMBA_SRC_DIR)/tdb
|
||||
|
||||
CFLAGS = -g -I$(SAMBA_SRC_DIR)/include -I$(TDB_SRC_DIR)
|
||||
CC = gcc
|
||||
|
||||
PROGS = perfcount
|
||||
TDB_OBJ = $(TDB_SRC_DIR)/tdb.o $(TDB_SRC_DIR)/spinlock.o $(TDB_SRC_DIR)/tdbback.o
|
||||
PERF_WRITER_OBJ = perf_writer.o perf_writer_mem.o perf_writer_util.o perf_writer_cpu.o perf_writer_process.o perf_writer_disk.o
|
||||
|
||||
default: $(PROGS)
|
||||
|
||||
$(TDB_OBJ):
|
||||
cd $(TDB_SRC_DIR) && make
|
||||
|
||||
perfcount: $(PERF_WRITER_OBJ) $(TDB_OBJ)
|
||||
$(CC) $(CFLAGS) -o perfcount $(PERF_WRITER_OBJ) $(TDB_OBJ)
|
||||
|
||||
clean:
|
||||
rm -f $(PROGS) *.o *~ *% core
|
196
examples/perfcounter/perf.h
Normal file
196
examples/perfcounter/perf.h
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __PERF_H__
|
||||
#define __PERF_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <limits.h>
|
||||
#include "tdb.h"
|
||||
#include <rpc_perfcount_defs.h>
|
||||
#include <sys/statfs.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/sysinfo.h>
|
||||
|
||||
#define NUM_COUNTERS 10
|
||||
|
||||
#define NAME_LEN 256
|
||||
#define HELP_LEN 1024
|
||||
|
||||
#define PERF_OBJECT 0
|
||||
#define PERF_INSTANCE 1
|
||||
#define PERF_COUNTER 2
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE !FALSE
|
||||
|
||||
#define PROC_BUF 256
|
||||
#define LARGE_BUF 16384
|
||||
|
||||
typedef struct perf_counter
|
||||
{
|
||||
int index;
|
||||
char name[NAME_LEN];
|
||||
char help[HELP_LEN];
|
||||
char relationships[NAME_LEN];
|
||||
unsigned int counter_type;
|
||||
int record_type;
|
||||
} PerfCounter;
|
||||
|
||||
typedef struct mem_data
|
||||
{
|
||||
unsigned int availPhysKb;
|
||||
unsigned int availSwapKb;
|
||||
unsigned int totalPhysKb;
|
||||
unsigned int totalSwapKb;
|
||||
} MemData;
|
||||
|
||||
typedef struct mem_info
|
||||
{
|
||||
PerfCounter memObjDesc;
|
||||
PerfCounter availPhysKb;
|
||||
PerfCounter availSwapKb;
|
||||
PerfCounter totalPhysKb;
|
||||
PerfCounter totalSwapKb;
|
||||
MemData *data;
|
||||
} MemInfo;
|
||||
|
||||
typedef struct cpu_data
|
||||
{
|
||||
unsigned long long user;
|
||||
unsigned long long nice;
|
||||
unsigned long long system;
|
||||
unsigned long long idle;
|
||||
} CPUData;
|
||||
|
||||
typedef struct cpu_info
|
||||
{
|
||||
unsigned int numCPUs;
|
||||
PerfCounter cpuObjDesc;
|
||||
PerfCounter userCPU;
|
||||
PerfCounter niceCPU;
|
||||
PerfCounter systemCPU;
|
||||
PerfCounter idleCPU;
|
||||
CPUData *data;
|
||||
} CPUInfo;
|
||||
|
||||
typedef struct disk_meta_data
|
||||
{
|
||||
char name[NAME_LEN];
|
||||
char mountpoint[NAME_LEN];
|
||||
} DiskMetaData;
|
||||
|
||||
typedef struct disk_data
|
||||
{
|
||||
unsigned long long freeMegs;
|
||||
unsigned int writesPerSec;
|
||||
unsigned int readsPerSec;
|
||||
} DiskData;
|
||||
|
||||
typedef struct disk_info
|
||||
{
|
||||
unsigned int numDisks;
|
||||
DiskMetaData *mdata;
|
||||
PerfCounter diskObjDesc;
|
||||
PerfCounter freeMegs;
|
||||
PerfCounter writesPerSec;
|
||||
PerfCounter readsPerSec;
|
||||
DiskData *data;
|
||||
} DiskInfo;
|
||||
|
||||
typedef struct process_data
|
||||
{
|
||||
unsigned int runningProcessCount;
|
||||
} ProcessData;
|
||||
|
||||
typedef struct process_info
|
||||
{
|
||||
PerfCounter processObjDesc;
|
||||
PerfCounter runningProcessCount;
|
||||
ProcessData *data;
|
||||
} ProcessInfo;
|
||||
|
||||
typedef struct perf_data_block
|
||||
{
|
||||
unsigned int counter_id;
|
||||
unsigned int num_counters;
|
||||
unsigned int NumObjectTypes;
|
||||
unsigned long long PerfTime;
|
||||
unsigned long long PerfFreq;
|
||||
unsigned long long PerfTime100nSec;
|
||||
MemInfo memInfo;
|
||||
CPUInfo cpuInfo;
|
||||
ProcessInfo processInfo;
|
||||
DiskInfo diskInfo;
|
||||
} PERF_DATA_BLOCK;
|
||||
|
||||
typedef struct runtime_settings
|
||||
{
|
||||
/* Runtime flags */
|
||||
int dflag;
|
||||
/* DB path names */
|
||||
char dbDir[PATH_MAX];
|
||||
char nameFile[PATH_MAX];
|
||||
char counterFile[PATH_MAX];
|
||||
/* TDB context */
|
||||
TDB_CONTEXT *cnames;
|
||||
TDB_CONTEXT *cdata;
|
||||
} RuntimeSettings;
|
||||
|
||||
/* perf_writer_ng_util.c function prototypes */
|
||||
void fatal(char *msg);
|
||||
void add_key(TDB_CONTEXT *db, char *keystring, char *datastring, int flags);
|
||||
void add_key_raw(TDB_CONTEXT *db, char *keystring, void *datastring, size_t datasize, int flags);
|
||||
void make_key(char *buf, int buflen, int key_part1, char *key_part2);
|
||||
void parse_flags(RuntimeSettings *rt, int argc, char **argv);
|
||||
void setup_file_paths(RuntimeSettings *rt);
|
||||
void daemonize(RuntimeSettings *rt);
|
||||
|
||||
/* perf_writer_ng_mem.c function prototypes */
|
||||
void get_meminfo(PERF_DATA_BLOCK *data);
|
||||
void init_memdata_desc(PERF_DATA_BLOCK *data);
|
||||
void init_memdata(PERF_DATA_BLOCK *data);
|
||||
void output_mem_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt);
|
||||
void output_meminfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags);
|
||||
void init_perf_counter(PerfCounter *counter, PerfCounter *parent, unsigned int index, char *name, char *help, int counter_type, int record_type);
|
||||
|
||||
/* perf_writer_ng_cpu.c function prototypes */
|
||||
unsigned long long get_cpufreq();
|
||||
void init_cpudata_desc(PERF_DATA_BLOCK *data);
|
||||
void get_cpuinfo(PERF_DATA_BLOCK *data);
|
||||
void init_cpu_data(PERF_DATA_BLOCK *data);
|
||||
void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt);
|
||||
void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags);
|
||||
|
||||
#endif /* __PERF_H__ */
|
214
examples/perfcounter/perf_writer.c
Normal file
214
examples/perfcounter/perf_writer.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
sig_atomic_t keep_running = TRUE;
|
||||
|
||||
/* allocates memory and gets numCPUs, total memory, and PerfFreq, number of disks... */
|
||||
void get_constants(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
data->cpuInfo.numCPUs = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
data->PerfFreq = sysconf(_SC_CLK_TCK);
|
||||
init_mem_data(data);
|
||||
init_cpu_data(data);
|
||||
init_process_data(data);
|
||||
init_disk_data(data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_num_instances(PerfCounter obj, int numInst, RuntimeSettings rt)
|
||||
{
|
||||
char key[NAME_LEN];
|
||||
char sdata[NAME_LEN];
|
||||
|
||||
make_key(key, NAME_LEN, obj.index, "inst");
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
sprintf(sdata, "%d", numInst);
|
||||
add_key(rt.cnames, key, sdata, TDB_INSERT);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_perf_desc(PerfCounter counter, RuntimeSettings rt)
|
||||
{
|
||||
char key[NAME_LEN];
|
||||
char sdata[NAME_LEN];
|
||||
|
||||
/* First insert the counter name */
|
||||
make_key(key, NAME_LEN, counter.index, NULL);
|
||||
add_key(rt.cnames, key, counter.name, TDB_INSERT);
|
||||
/* Add the help string */
|
||||
make_key(key, NAME_LEN, counter.index + 1, NULL);
|
||||
add_key(rt.cnames, key, counter.help, TDB_INSERT);
|
||||
/* Add the relationships */
|
||||
make_key(key, NAME_LEN, counter.index, "rel");
|
||||
add_key(rt.cnames, key, counter.relationships, TDB_INSERT);
|
||||
/* Add type data if not PERF_OBJECT or PERF_INSTANCE */
|
||||
if(counter.record_type == PERF_COUNTER)
|
||||
{
|
||||
make_key(key, NAME_LEN, counter.index, "type");
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
sprintf(sdata, "%d", counter.counter_type);
|
||||
add_key(rt.cnames, key, sdata, TDB_INSERT);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void initialize(PERF_DATA_BLOCK *data, RuntimeSettings *rt, int argc, char **argv)
|
||||
{
|
||||
memset(data, 0, sizeof(*data));
|
||||
memset(rt, 0, sizeof(*data));
|
||||
|
||||
parse_flags(rt, argc, argv);
|
||||
setup_file_paths(rt);
|
||||
|
||||
get_constants(data);
|
||||
|
||||
if(rt->dflag == TRUE)
|
||||
daemonize(rt);
|
||||
|
||||
output_mem_desc(data, *rt);
|
||||
output_cpu_desc(data, *rt);
|
||||
output_process_desc(data, *rt);
|
||||
output_disk_desc(data, *rt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void refresh_perf_data_block(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
data->PerfTime100nSec = 0;
|
||||
get_meminfo(data);
|
||||
get_cpuinfo(data);
|
||||
get_processinfo(data);
|
||||
get_diskinfo(data);
|
||||
return;
|
||||
}
|
||||
|
||||
void output_perf_counter(PerfCounter counter, unsigned long long data,
|
||||
RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
char key[NAME_LEN];
|
||||
char sdata[NAME_LEN];
|
||||
unsigned int size_mask;
|
||||
|
||||
make_key(key, NAME_LEN, counter.index, NULL);
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
|
||||
size_mask = counter.counter_type & PERF_SIZE_VARIABLE_LEN;
|
||||
|
||||
if(size_mask == PERF_SIZE_DWORD)
|
||||
sprintf(sdata, "%d", (unsigned int)data);
|
||||
else if(size_mask == PERF_SIZE_LARGE)
|
||||
sprintf(sdata, "%Lu", data);
|
||||
|
||||
add_key(rt.cdata, key, sdata, tdb_flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_perf_instance(int parentObjInd,
|
||||
int instanceInd,
|
||||
void *instData,
|
||||
size_t dsize,
|
||||
char *name,
|
||||
RuntimeSettings rt,
|
||||
int tdb_flags)
|
||||
{
|
||||
char key[NAME_LEN];
|
||||
char sdata[NAME_LEN];
|
||||
|
||||
memset(key, 0, NAME_LEN);
|
||||
sprintf(key, "%di%d", parentObjInd, instanceInd);
|
||||
add_key_raw(rt.cdata, key, instData, dsize, tdb_flags);
|
||||
|
||||
/* encode name */
|
||||
memset(key, 0, NAME_LEN);
|
||||
sprintf(key, "%di%dname", parentObjInd, instanceInd);
|
||||
add_key(rt.cnames, key, name, tdb_flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_global_data(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
int i;
|
||||
char key[NAME_LEN];
|
||||
char sdata[NAME_LEN];
|
||||
|
||||
/* Initialize BaseIndex */
|
||||
make_key(key, NAME_LEN, 1, NULL);
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
sprintf(sdata, "%d", data->num_counters);
|
||||
add_key(rt.cnames, key, sdata, tdb_flags);
|
||||
/* Initialize PerfTime, PerfFreq and PerfTime100nSec */
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
make_key(key, NAME_LEN, 0, "PerfTime");
|
||||
sprintf(sdata, "%Lu", data->PerfTime);
|
||||
add_key(rt.cdata, key, sdata, tdb_flags);
|
||||
make_key(key, NAME_LEN, 0, "PerfTime100nSec");
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
sprintf(sdata, "%Lu", data->PerfTime100nSec);
|
||||
add_key(rt.cdata, key, sdata, tdb_flags);
|
||||
memset(sdata, 0, NAME_LEN);
|
||||
make_key(key, NAME_LEN, 0, "PerfFreq");
|
||||
sprintf(sdata, "%Lu", data->PerfFreq);
|
||||
add_key(rt.cnames, key, sdata, tdb_flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_perf_data_block(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
output_global_data(data, rt, tdb_flags);
|
||||
output_meminfo(data, rt, tdb_flags);
|
||||
output_cpuinfo(data, rt, tdb_flags);
|
||||
output_processinfo(data, rt, tdb_flags);
|
||||
output_diskinfo(data, rt, tdb_flags);
|
||||
return;
|
||||
}
|
||||
|
||||
void update_counters(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
refresh_perf_data_block(data, rt);
|
||||
output_perf_data_block(data, rt, TDB_REPLACE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
PERF_DATA_BLOCK data;
|
||||
RuntimeSettings rt;
|
||||
|
||||
initialize(&data, &rt, argc, argv);
|
||||
|
||||
while(keep_running)
|
||||
{
|
||||
update_counters(&data, rt);
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
190
examples/perfcounter/perf_writer_cpu.c
Normal file
190
examples/perfcounter/perf_writer_cpu.c
Normal file
@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
void init_cpudata_desc(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
init_perf_counter(&(data->cpuInfo.cpuObjDesc),
|
||||
&(data->cpuInfo.cpuObjDesc),
|
||||
get_counter_id(data),
|
||||
"Processor",
|
||||
"The Processor object consists of counters that describe the behavior of the CPU.",
|
||||
0,
|
||||
PERF_OBJECT);
|
||||
init_perf_counter(&(data->cpuInfo.userCPU),
|
||||
&(data->cpuInfo.cpuObjDesc),
|
||||
get_counter_id(data),
|
||||
"\% User CPU Utilization",
|
||||
"\% User CPU Utilization is the percentage of the CPU used by processes executing user code.",
|
||||
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->cpuInfo.systemCPU),
|
||||
&(data->cpuInfo.cpuObjDesc),
|
||||
get_counter_id(data),
|
||||
"\% System CPU Utilization",
|
||||
"\% System CPU Utilization is the percentage of the CPU used by processes doing system calls.",
|
||||
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_PERCENT,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->cpuInfo.niceCPU),
|
||||
&(data->cpuInfo.cpuObjDesc),
|
||||
get_counter_id(data),
|
||||
"\% Nice CPU Utilization",
|
||||
"\% Nice CPU Utilization is the percentage of the CPU used by processes running in nice mode.",
|
||||
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->cpuInfo.idleCPU),
|
||||
&(data->cpuInfo.cpuObjDesc),
|
||||
get_counter_id(data),
|
||||
"\% Idle CPU",
|
||||
"\% Idle CPU is the percentage of the CPU not doing any work.",
|
||||
PERF_SIZE_LARGE | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_TIMER_100NS | PERF_DELTA_COUNTER | PERF_DISPLAY_NOSHOW,
|
||||
PERF_COUNTER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void get_cpuinfo(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
int num, i;
|
||||
unsigned int cpuid;
|
||||
char buf[PROC_BUF];
|
||||
static FILE *fp = NULL;
|
||||
|
||||
if(!fp)
|
||||
{
|
||||
if(!(fp = fopen("/proc/stat", "r")))
|
||||
{
|
||||
perror("get_cpuinfo: fopen");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
rewind(fp);
|
||||
fflush(fp);
|
||||
|
||||
/* Read in the first line and discard it -- that has the CPU summary */
|
||||
if(!fgets(buf, sizeof(buf), fp))
|
||||
{
|
||||
perror("get_cpuinfo: fgets");
|
||||
exit(1);
|
||||
}
|
||||
for(i = 0; i < data->cpuInfo.numCPUs; i++)
|
||||
{
|
||||
if(!fgets(buf, sizeof(buf), fp))
|
||||
{
|
||||
perror("get_cpuinfo: fgets");
|
||||
exit(1);
|
||||
}
|
||||
num = sscanf(buf, "cpu%u %Lu %Lu %Lu %Lu",
|
||||
&cpuid,
|
||||
&data->cpuInfo.data[i].user,
|
||||
&data->cpuInfo.data[i].nice,
|
||||
&data->cpuInfo.data[i].system,
|
||||
&data->cpuInfo.data[i].idle);
|
||||
if(i != cpuid)
|
||||
{
|
||||
perror("get_cpuinfo: /proc/stat inconsistent?");
|
||||
exit(1);
|
||||
}
|
||||
/*
|
||||
Alternate way of doing things:
|
||||
struct tms buffer;
|
||||
data->PerfTime100nSec = times(&buffer);
|
||||
*/
|
||||
data->PerfTime100nSec += data->cpuInfo.data[i].user +
|
||||
data->cpuInfo.data[i].nice +
|
||||
data->cpuInfo.data[i].system +
|
||||
data->cpuInfo.data[i].idle;
|
||||
}
|
||||
data->PerfTime100nSec /= data->cpuInfo.numCPUs;
|
||||
return;
|
||||
}
|
||||
|
||||
void init_cpu_data(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
data->cpuInfo.data = calloc(data->cpuInfo.numCPUs, sizeof(*data->cpuInfo.data));
|
||||
if(!data->cpuInfo.data)
|
||||
{
|
||||
perror("init_cpu_data: out of memory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_cpudata_desc(data);
|
||||
|
||||
get_cpuinfo(data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_cpu_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
output_perf_desc(data->cpuInfo.cpuObjDesc, rt);
|
||||
output_perf_desc(data->cpuInfo.userCPU, rt);
|
||||
output_perf_desc(data->cpuInfo.niceCPU, rt);
|
||||
output_perf_desc(data->cpuInfo.systemCPU, rt);
|
||||
output_perf_desc(data->cpuInfo.idleCPU, rt);
|
||||
if(data->cpuInfo.numCPUs > 1)
|
||||
output_num_instances(data->cpuInfo.cpuObjDesc, data->cpuInfo.numCPUs + 1, rt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_cpuinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
int i;
|
||||
char buf[NAME_LEN];
|
||||
|
||||
output_perf_counter(data->cpuInfo.userCPU,
|
||||
data->cpuInfo.data[0].user,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->cpuInfo.systemCPU,
|
||||
data->cpuInfo.data[0].system,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->cpuInfo.niceCPU,
|
||||
data->cpuInfo.data[0].nice,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->cpuInfo.idleCPU,
|
||||
data->cpuInfo.data[0].idle,
|
||||
rt, tdb_flags);
|
||||
if(data->cpuInfo.numCPUs > 1)
|
||||
{
|
||||
for(i = 0; i < data->cpuInfo.numCPUs; i++)
|
||||
{
|
||||
memset(buf, 0, NAME_LEN);
|
||||
sprintf(buf, "cpu%d", i);
|
||||
output_perf_instance(data->cpuInfo.cpuObjDesc.index,
|
||||
i,
|
||||
(void *)&(data->cpuInfo.data[i]),
|
||||
sizeof(data->cpuInfo.data[i]),
|
||||
buf, rt, tdb_flags);
|
||||
}
|
||||
|
||||
memset(buf, 0, NAME_LEN);
|
||||
sprintf(buf, "_Total");
|
||||
output_perf_instance(data->cpuInfo.cpuObjDesc.index,
|
||||
i,
|
||||
(void *)&(data->cpuInfo.data[i]),
|
||||
sizeof(data->cpuInfo.data[i]),
|
||||
buf, rt, tdb_flags);
|
||||
}
|
||||
return;
|
||||
}
|
225
examples/perfcounter/perf_writer_disk.c
Normal file
225
examples/perfcounter/perf_writer_disk.c
Normal file
@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
void init_diskdata_desc(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
init_perf_counter(&(data->diskInfo.diskObjDesc),
|
||||
&(data->diskInfo.diskObjDesc),
|
||||
get_counter_id(data),
|
||||
"Logical Disk",
|
||||
"The Logical Disk object consists of counters that show information about disks.",
|
||||
0,
|
||||
PERF_OBJECT);
|
||||
init_perf_counter(&(data->diskInfo.freeMegs),
|
||||
&(data->diskInfo.diskObjDesc),
|
||||
get_counter_id(data),
|
||||
"Megabytes Free",
|
||||
"The amount of available disk space, in megabytes.",
|
||||
PERF_SIZE_LARGE | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->diskInfo.writesPerSec),
|
||||
&(data->diskInfo.diskObjDesc),
|
||||
get_counter_id(data),
|
||||
"Writes/sec",
|
||||
"The number of writes per second to that disk.",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->diskInfo.readsPerSec),
|
||||
&(data->diskInfo.diskObjDesc),
|
||||
get_counter_id(data),
|
||||
"Reads/sec",
|
||||
"The number of reads of that disk per second.",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_COUNTER | PERF_COUNTER_RATE | PERF_DELTA_COUNTER | PERF_DISPLAY_PER_SEC,
|
||||
PERF_COUNTER);
|
||||
|
||||
return;
|
||||
}
|
||||
void init_num_disks(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
FILE *mtab;
|
||||
char buf[PROC_BUF];
|
||||
char *start, *stop;
|
||||
int i = 0, num;
|
||||
|
||||
if(!(mtab = fopen("/etc/mtab", "r")))
|
||||
{
|
||||
perror("init_disk_names: fopen");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rewind(mtab);
|
||||
fflush(mtab);
|
||||
|
||||
while(fgets(buf, sizeof(buf), mtab))
|
||||
{
|
||||
if(start = strstr(buf, "/dev/"))
|
||||
{
|
||||
if(start = strstr(start, "da"))
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->diskInfo.numDisks = i;
|
||||
fclose(mtab);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_disk_names(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
FILE *mtab;
|
||||
char buf[PROC_BUF];
|
||||
char *start, *stop;
|
||||
int i = 0, num;
|
||||
|
||||
if(!(mtab = fopen("/etc/mtab", "r")))
|
||||
{
|
||||
perror("init_disk_names: fopen");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
rewind(mtab);
|
||||
fflush(mtab);
|
||||
|
||||
while(fgets(buf, sizeof(buf), mtab))
|
||||
{
|
||||
if(start = strstr(buf, "/dev/"))
|
||||
{
|
||||
if(start = strstr(start, "da"))
|
||||
{
|
||||
start -=1;
|
||||
stop = strstr(start, " ");
|
||||
memcpy(data->diskInfo.mdata[i].name, start, stop - start);
|
||||
start = stop +1;
|
||||
stop = strstr(start, " ");
|
||||
memcpy(data->diskInfo.mdata[i].mountpoint, start, stop - start);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose(mtab);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void get_diskinfo(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
int i;
|
||||
DiskData *p;
|
||||
struct statfs statfsbuf;
|
||||
int status, num;
|
||||
char buf[LARGE_BUF], *start;
|
||||
FILE *diskstats;
|
||||
long reads, writes, discard;
|
||||
|
||||
diskstats = fopen("/proc/diskstats", "r");
|
||||
rewind(diskstats);
|
||||
fflush(diskstats);
|
||||
status = fread(buf, sizeof(char), LARGE_BUF, diskstats);
|
||||
fclose(diskstats);
|
||||
|
||||
for(i = 0; i < data->diskInfo.numDisks; i++)
|
||||
{
|
||||
p = &(data->diskInfo.data[i]);
|
||||
status = statfs(data->diskInfo.mdata[i].mountpoint, &statfsbuf);
|
||||
p->freeMegs = (statfsbuf.f_bfree*statfsbuf.f_bsize)/1048576;
|
||||
start = strstr(buf, data->diskInfo.mdata[i].name);
|
||||
start += strlen(data->diskInfo.mdata[i].name) + 1;
|
||||
num = sscanf(start, "%u %u %u %u",
|
||||
&reads,
|
||||
&discard,
|
||||
&writes,
|
||||
&discard);
|
||||
p->writesPerSec = writes;
|
||||
p->readsPerSec = reads;
|
||||
fprintf(stderr, "%s:\t%u\t%u\n",
|
||||
data->diskInfo.mdata[i].mountpoint,
|
||||
reads, writes);
|
||||
}
|
||||
return;
|
||||
}
|
||||
void init_disk_data(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
init_diskdata_desc(data);
|
||||
|
||||
init_num_disks(data);
|
||||
|
||||
data->diskInfo.mdata = calloc(data->diskInfo.numDisks, sizeof(DiskMetaData));
|
||||
if(!data->diskInfo.mdata)
|
||||
{
|
||||
fatal("init_disk_data: out of memory");
|
||||
}
|
||||
|
||||
init_disk_names(data);
|
||||
|
||||
data->diskInfo.data = calloc(data->diskInfo.numDisks, sizeof(DiskData));
|
||||
if(!data->diskInfo.data)
|
||||
{
|
||||
fatal("init_disk_data: out of memory");
|
||||
}
|
||||
|
||||
get_diskinfo(data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_disk_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
output_perf_desc(data->diskInfo.diskObjDesc, rt);
|
||||
output_perf_desc(data->diskInfo.freeMegs, rt);
|
||||
output_perf_desc(data->diskInfo.writesPerSec, rt);
|
||||
output_perf_desc(data->diskInfo.readsPerSec, rt);
|
||||
output_num_instances(data->diskInfo.diskObjDesc, data->diskInfo.numDisks, rt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_diskinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
int i;
|
||||
|
||||
output_perf_counter(data->diskInfo.freeMegs,
|
||||
data->diskInfo.data[0].freeMegs,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->diskInfo.writesPerSec,
|
||||
(unsigned long long)data->diskInfo.data[0].writesPerSec,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->diskInfo.readsPerSec,
|
||||
(unsigned long long)data->diskInfo.data[0].readsPerSec,
|
||||
rt, tdb_flags);
|
||||
|
||||
for(i = 0; i < data->diskInfo.numDisks; i++)
|
||||
{
|
||||
output_perf_instance(data->diskInfo.diskObjDesc.index,
|
||||
i,
|
||||
(void *)&(data->diskInfo.data[i]),
|
||||
sizeof(DiskData),
|
||||
data->diskInfo.mdata[i].mountpoint,
|
||||
rt, tdb_flags);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
125
examples/perfcounter/perf_writer_mem.c
Normal file
125
examples/perfcounter/perf_writer_mem.c
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
void get_meminfo(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
int status;
|
||||
struct sysinfo info;
|
||||
status = sysinfo(&info);
|
||||
|
||||
data->memInfo.data->availPhysKb = (info.freeram * info.mem_unit)/1024;
|
||||
data->memInfo.data->availSwapKb = (info.freeswap * info.mem_unit)/1024;
|
||||
data->memInfo.data->totalPhysKb = (info.totalram * info.mem_unit)/1024;
|
||||
data->memInfo.data->totalSwapKb = (info.totalswap * info.mem_unit)/1024;
|
||||
|
||||
/* Also get uptime since we have the structure */
|
||||
data->PerfTime = (unsigned long)info.uptime;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_memdata_desc(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
init_perf_counter(&(data->memInfo.memObjDesc),
|
||||
&(data->memInfo.memObjDesc),
|
||||
get_counter_id(data),
|
||||
"Memory",
|
||||
"The Memory performance object consists of counters that describe the behavior of physical and virtual memory on the computer.",
|
||||
0,
|
||||
PERF_OBJECT);
|
||||
init_perf_counter(&(data->memInfo.availPhysKb),
|
||||
&(data->memInfo.memObjDesc),
|
||||
get_counter_id(data),
|
||||
"Available Physical Kilobytes",
|
||||
"Available Physical Kilobytes is the number of free kilobytes in physical memory",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->memInfo.availSwapKb),
|
||||
&(data->memInfo.memObjDesc),
|
||||
get_counter_id(data),
|
||||
"Available Swap Kilobytes",
|
||||
"Available Swap Kilobytes is the number of free kilobytes in swap space",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->memInfo.totalPhysKb),
|
||||
&(data->memInfo.memObjDesc),
|
||||
get_counter_id(data),
|
||||
"Total Physical Kilobytes",
|
||||
"Total Physical Kilobytes is a base counter",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW,
|
||||
PERF_COUNTER);
|
||||
init_perf_counter(&(data->memInfo.totalSwapKb),
|
||||
&(data->memInfo.memObjDesc),
|
||||
get_counter_id(data),
|
||||
"Total Swap Kilobytes",
|
||||
"Total Swap Kilobytes is a base counter",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_COUNTER_BASE | PERF_DISPLAY_NOSHOW,
|
||||
PERF_COUNTER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_mem_data(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
data->memInfo.data = calloc(1, sizeof(*data->memInfo.data));
|
||||
if(!data->memInfo.data)
|
||||
{
|
||||
perror("init_memdata: out of memory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_memdata_desc(data);
|
||||
|
||||
get_meminfo(data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_mem_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
output_perf_desc(data->memInfo.memObjDesc, rt);
|
||||
output_perf_desc(data->memInfo.availPhysKb, rt);
|
||||
output_perf_desc(data->memInfo.availSwapKb, rt);
|
||||
output_perf_desc(data->memInfo.totalPhysKb, rt);
|
||||
output_perf_desc(data->memInfo.totalSwapKb, rt);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_meminfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
output_perf_counter(data->memInfo.availPhysKb,
|
||||
(unsigned long long)data->memInfo.data->availPhysKb,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->memInfo.availSwapKb,
|
||||
(unsigned long long)data->memInfo.data->availSwapKb,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->memInfo.totalPhysKb,
|
||||
(unsigned long long)data->memInfo.data->totalPhysKb,
|
||||
rt, tdb_flags);
|
||||
output_perf_counter(data->memInfo.totalSwapKb,
|
||||
(unsigned long long)data->memInfo.data->totalSwapKb,
|
||||
rt, tdb_flags);
|
||||
|
||||
return;
|
||||
}
|
86
examples/perfcounter/perf_writer_process.c
Normal file
86
examples/perfcounter/perf_writer_process.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
void get_processinfo(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
int status;
|
||||
struct sysinfo info;
|
||||
status = sysinfo(&info);
|
||||
|
||||
data->processInfo.data->runningProcessCount = (unsigned int)info.procs;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_processdata_desc(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
init_perf_counter(&(data->processInfo.processObjDesc),
|
||||
&(data->processInfo.processObjDesc),
|
||||
get_counter_id(data),
|
||||
"Processes",
|
||||
"%The Processes performance object displays aggregate information about processes on the machine.",
|
||||
0,
|
||||
PERF_OBJECT);
|
||||
init_perf_counter(&(data->processInfo.runningProcessCount),
|
||||
&(data->processInfo.processObjDesc),
|
||||
get_counter_id(data),
|
||||
"Process Count",
|
||||
"Process Count is the number of processes currently on the machine.",
|
||||
PERF_SIZE_DWORD | PERF_TYPE_NUMBER | PERF_NUMBER_DECIMAL | PERF_DISPLAY_NO_SUFFIX,
|
||||
PERF_COUNTER);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void init_process_data(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
data->processInfo.data = calloc(1, sizeof(*data->processInfo.data));
|
||||
if(!(data->processInfo.data))
|
||||
{
|
||||
perror("init_process_data: out of memory");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
init_processdata_desc(data);
|
||||
|
||||
get_processinfo(data);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_processinfo(PERF_DATA_BLOCK *data, RuntimeSettings rt, int tdb_flags)
|
||||
{
|
||||
output_perf_counter(data->processInfo.runningProcessCount,
|
||||
(unsigned long long)data->processInfo.data->runningProcessCount,
|
||||
rt, tdb_flags);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void output_process_desc(PERF_DATA_BLOCK *data, RuntimeSettings rt)
|
||||
{
|
||||
output_perf_desc(data->processInfo.processObjDesc, rt);
|
||||
output_perf_desc(data->processInfo.runningProcessCount, rt);
|
||||
|
||||
return;
|
||||
}
|
244
examples/perfcounter/perf_writer_util.c
Normal file
244
examples/perfcounter/perf_writer_util.c
Normal file
@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Performance Counter Daemon
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "perf.h"
|
||||
|
||||
extern sig_atomic_t keep_running;
|
||||
|
||||
void fatal(char *msg)
|
||||
{
|
||||
perror(msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void add_key_raw(TDB_CONTEXT *db, char *keystring, void *databuf, size_t datasize, int flags)
|
||||
{
|
||||
TDB_DATA key, data;
|
||||
|
||||
key.dptr = keystring;
|
||||
key.dsize = strlen(keystring);
|
||||
data.dptr = databuf;
|
||||
data.dsize = datasize;
|
||||
fprintf(stderr, "doing insert of [%x] with key [%s] into [%s]\n",
|
||||
data.dptr,
|
||||
keystring,
|
||||
db->name);
|
||||
|
||||
tdb_store(db, key, data, flags);
|
||||
}
|
||||
|
||||
void add_key(TDB_CONTEXT *db, char *keystring, char *datastring, int flags)
|
||||
{
|
||||
TDB_DATA key, data;
|
||||
|
||||
key.dptr = keystring;
|
||||
key.dsize = strlen(keystring);
|
||||
data.dptr = datastring;
|
||||
data.dsize = strlen(datastring);
|
||||
/* fprintf(stderr, "doing insert of [%s] with key [%s] into [%s]\n",
|
||||
data.dptr,
|
||||
keystring,
|
||||
db->name);*/
|
||||
|
||||
tdb_store(db, key, data, flags);
|
||||
}
|
||||
|
||||
void make_key(char *buf, int buflen, int key_part1, char *key_part2)
|
||||
{
|
||||
memset(buf, 0, buflen);
|
||||
if(key_part2 != NULL)
|
||||
sprintf(buf, "%d%s", key_part1, key_part2);
|
||||
else
|
||||
sprintf(buf, "%d", key_part1);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void usage(char *progname)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s [-d] [-f <file_path>].\n", progname);
|
||||
fprintf(stderr, "\t-d: run as a daemon.\n");
|
||||
fprintf(stderr, "\t-f <file_path>: path where the TDB files reside.\n");
|
||||
fprintf(stderr, "\t\tDEFAULT is /tmp/counters\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void parse_flags(RuntimeSettings *rt, int argc, char **argv)
|
||||
{
|
||||
int flag;
|
||||
|
||||
while((flag = getopt(argc, argv, "df:")) != -1)
|
||||
{
|
||||
switch(flag)
|
||||
{
|
||||
case 'd':
|
||||
{
|
||||
rt->dflag = TRUE;
|
||||
break;
|
||||
}
|
||||
case 'f':
|
||||
{
|
||||
memcpy(rt->dbDir, optarg, strlen(optarg));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void setup_file_paths(RuntimeSettings *rt)
|
||||
{
|
||||
int status;
|
||||
|
||||
if(strlen(rt->dbDir) == 0)
|
||||
{
|
||||
/* No file path was passed in, use default */
|
||||
sprintf(rt->dbDir, "/tmp/counters");
|
||||
}
|
||||
|
||||
sprintf(rt->nameFile, "%s/names.tdb", rt->dbDir);
|
||||
sprintf(rt->counterFile, "%s/data.tdb", rt->dbDir);
|
||||
|
||||
mkdir(rt->dbDir, O_RDWR);
|
||||
rt->cnames = tdb_open(rt->nameFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
|
||||
rt->cdata = tdb_open(rt->counterFile, 0, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644);
|
||||
|
||||
if(rt->cnames == NULL || rt->cdata == NULL)
|
||||
{
|
||||
perror("setup_file_paths");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void sigterm_handler()
|
||||
{
|
||||
keep_running = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
void daemonize(RuntimeSettings *rt)
|
||||
{
|
||||
pid_t pid;
|
||||
int i;
|
||||
int fd;
|
||||
|
||||
/* Check if we're already a daemon */
|
||||
if(getppid() == 1)
|
||||
return;
|
||||
pid = fork();
|
||||
if(pid < 0)
|
||||
/* can't fork */
|
||||
exit(1);
|
||||
else if(pid > 0)
|
||||
{
|
||||
/* we're the parent */
|
||||
tdb_close(rt->cnames);
|
||||
tdb_close(rt->cdata);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* get a new session */
|
||||
if(setsid() == -1)
|
||||
exit(2);
|
||||
|
||||
/* Change CWD */
|
||||
chdir("/");
|
||||
|
||||
/* close file descriptors */
|
||||
close(STDIN_FILENO);
|
||||
close(STDOUT_FILENO);
|
||||
close(STDERR_FILENO);
|
||||
|
||||
/* And reopen them as safe defaults */
|
||||
fd = open("/dev/null", O_RDONLY);
|
||||
if(fd != 0)
|
||||
{
|
||||
dup2(fd, 0);
|
||||
close(fd);
|
||||
}
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
if(fd != 1)
|
||||
{
|
||||
dup2(fd, 1);
|
||||
close(fd);
|
||||
}
|
||||
fd = open("/dev/null", O_WRONLY);
|
||||
if(fd != 2)
|
||||
{
|
||||
dup2(fd, 2);
|
||||
close(fd);
|
||||
}
|
||||
|
||||
/* handle signals */
|
||||
signal(SIGINT, SIG_IGN);
|
||||
signal(SIGHUP, SIG_IGN);
|
||||
signal(SIGTERM, sigterm_handler);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int get_counter_id(PERF_DATA_BLOCK *data)
|
||||
{
|
||||
data->counter_id += 2;
|
||||
data->num_counters++;
|
||||
|
||||
return data->counter_id;
|
||||
}
|
||||
|
||||
void init_perf_counter(PerfCounter *counter,
|
||||
PerfCounter *parent,
|
||||
unsigned int index,
|
||||
char *name,
|
||||
char *help,
|
||||
int counter_type,
|
||||
int record_type)
|
||||
{
|
||||
counter->index = index;
|
||||
memcpy(counter->name, name, strlen(name));
|
||||
memcpy(counter->help, help, strlen(help));
|
||||
counter->counter_type = counter_type;
|
||||
counter->record_type = record_type;
|
||||
|
||||
switch(record_type)
|
||||
{
|
||||
case PERF_OBJECT:
|
||||
sprintf(counter->relationships, "p");
|
||||
break;
|
||||
case PERF_COUNTER:
|
||||
sprintf(counter->relationships, "c[%d]", parent->index);
|
||||
break;
|
||||
case PERF_INSTANCE:
|
||||
sprintf(counter->relationships, "i[%d]", parent->index);
|
||||
break;
|
||||
default:
|
||||
perror("init_perf_counter: unknown record type");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
66
examples/perfcounter/perfcountd.init
Executable file
66
examples/perfcounter/perfcountd.init
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (C) Gerald Carter 2005
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
#
|
||||
####################################################################
|
||||
|
||||
## This file should have uid root, gid sys and chmod 744
|
||||
|
||||
PATH=/bin:/usr/bin:/sbin:/usr/sbin
|
||||
|
||||
killproc()
|
||||
{
|
||||
pid=`ps aux | grep $1 | egrep -v '(grep|perfcountd)' | awk '{print $2}'`
|
||||
if [ "$pid" != "" ]; then
|
||||
kill $pid
|
||||
fi
|
||||
}
|
||||
|
||||
# Start/stop processes
|
||||
|
||||
case "$1"
|
||||
in
|
||||
start)
|
||||
/opt/samba/bin/perfcount -d -f /var/lib/samba/perfmon 2> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed!"
|
||||
exit 1
|
||||
fi
|
||||
echo "done!"
|
||||
;;
|
||||
stop)
|
||||
killproc perfcount
|
||||
;;
|
||||
|
||||
status)
|
||||
pid=`ps aux | grep perfcount | egrep -v '(grep|perfcountd)' | awk '{print $2}'`
|
||||
if [ "$pid" == "" ]; then
|
||||
echo "Dead!"
|
||||
exit 2;
|
||||
fi
|
||||
echo "OK!"
|
||||
;;
|
||||
restart)
|
||||
$0 stop && $0 start
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage: $0 { start|stop|restart|status }"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -121,7 +121,6 @@ typedef struct
|
||||
char *szConfigFile;
|
||||
char *szSMBPasswdFile;
|
||||
char *szPrivateDir;
|
||||
char *szCountersDir;
|
||||
char **szPassdbBackend;
|
||||
char **szPreloadModules;
|
||||
char *szPasswordServer;
|
||||
@ -848,7 +847,6 @@ static struct parm_struct parm_table[] = {
|
||||
{"password server", P_STRING, P_GLOBAL, &Globals.szPasswordServer, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
|
||||
{"smb passwd file", P_STRING, P_GLOBAL, &Globals.szSMBPasswdFile, NULL, NULL, FLAG_ADVANCED},
|
||||
{"private dir", P_STRING, P_GLOBAL, &Globals.szPrivateDir, NULL, NULL, FLAG_ADVANCED},
|
||||
{"counters dir", P_STRING, P_GLOBAL, &Globals.szCountersDir, NULL, NULL, FLAG_ADVANCED},
|
||||
{"passdb backend", P_LIST, P_GLOBAL, &Globals.szPassdbBackend, NULL, NULL, FLAG_ADVANCED | FLAG_WIZARD},
|
||||
{"algorithmic rid base", P_INTEGER, P_GLOBAL, &Globals.AlgorithmicRidBase, NULL, NULL, FLAG_ADVANCED},
|
||||
{"root directory", P_STRING, P_GLOBAL, &Globals.szRootdir, NULL, NULL, FLAG_ADVANCED},
|
||||
@ -1711,7 +1709,6 @@ FN_GLOBAL_STRING(lp_logfile, &Globals.szLogFile)
|
||||
FN_GLOBAL_STRING(lp_configfile, &Globals.szConfigFile)
|
||||
FN_GLOBAL_STRING(lp_smb_passwd_file, &Globals.szSMBPasswdFile)
|
||||
FN_GLOBAL_STRING(lp_private_dir, &Globals.szPrivateDir)
|
||||
FN_GLOBAL_STRING(lp_counters_dir, &Globals.szCountersDir)
|
||||
FN_GLOBAL_STRING(lp_serverstring, &Globals.szServerString)
|
||||
FN_GLOBAL_INTEGER(lp_printcap_cache_time, &Globals.PrintcapCacheTime)
|
||||
FN_GLOBAL_STRING(lp_enumports_cmd, &Globals.szEnumPortsCommand)
|
||||
|
@ -131,6 +131,7 @@ BOOL init_registry( void )
|
||||
|
||||
svcctl_init_keys();
|
||||
eventlog_init_keys();
|
||||
perfcount_init_keys();
|
||||
|
||||
/* close and let each smbd open up as necessary */
|
||||
|
||||
|
@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Virtual Windows Registry Layer
|
||||
*
|
||||
* Copyright (C) Marcin Krzysztof Porwit 2005,
|
||||
* Copyright (C) Gerald (Jerry) Carter 2005.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#undef DBGC_CLASS
|
||||
@ -5,21 +27,54 @@
|
||||
|
||||
#define PERFCOUNT_MAX_LEN 256
|
||||
|
||||
#define PERFCOUNTDIR "perfmon"
|
||||
#define NAMES_DB "names.tdb"
|
||||
#define DATA_DB "data.tdb"
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static char* counters_directory( const char *dbname )
|
||||
{
|
||||
static pstring fname;
|
||||
fstring path;
|
||||
|
||||
if ( !dbname )
|
||||
return NULL;
|
||||
|
||||
fstr_sprintf( path, "%s/%s", PERFCOUNTDIR, dbname );
|
||||
|
||||
pstrcpy( fname, lock_path( path ) );
|
||||
|
||||
return fname;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
void perfcount_init_keys( void )
|
||||
{
|
||||
char *p = lock_path(PERFCOUNTDIR);
|
||||
|
||||
/* no registry keys; just create the perfmon directory */
|
||||
|
||||
if ( !directory_exist( p, NULL ) )
|
||||
mkdir( p, 0755 );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_base_index(void)
|
||||
{
|
||||
pstring fname;
|
||||
const char *fname = counters_directory( NAMES_DB );
|
||||
TDB_CONTEXT *names;
|
||||
TDB_DATA kbuf, dbuf;
|
||||
char key[] = "1";
|
||||
uint32 retval = 0;
|
||||
char buf[PERFCOUNT_MAX_LEN];
|
||||
const char *counter_dir = lp_counters_dir();
|
||||
|
||||
|
||||
if ( !*counter_dir )
|
||||
return 0;
|
||||
|
||||
pstr_sprintf( fname, "%s/names.tdb", counter_dir );
|
||||
|
||||
names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
@ -62,6 +117,9 @@ uint32 reg_perfcount_get_base_index(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_last_counter(uint32 base_index)
|
||||
{
|
||||
uint32 retval;
|
||||
@ -74,6 +132,9 @@ uint32 reg_perfcount_get_last_counter(uint32 base_index)
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_last_help(uint32 last_counter)
|
||||
{
|
||||
uint32 retval;
|
||||
@ -86,6 +147,10 @@ uint32 reg_perfcount_get_last_help(uint32 last_counter)
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static uint32 _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
|
||||
int keyval,
|
||||
char **retbuf,
|
||||
@ -145,20 +210,20 @@ static uint32 _reg_perfcount_multi_sz_from_tdb(TDB_CONTEXT *tdb,
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_counter_help(uint32 base_index, char **retbuf)
|
||||
{
|
||||
char *buf1 = NULL, *buf2 = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
TDB_CONTEXT *names;
|
||||
pstring fname;
|
||||
const char *fname = counters_directory( NAMES_DB );
|
||||
int i;
|
||||
|
||||
if(base_index == 0)
|
||||
return 0;
|
||||
|
||||
pstrcpy(fname, lp_counters_dir());
|
||||
pstrcat(fname, "/names.tdb");
|
||||
|
||||
names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
if(names == NULL)
|
||||
@ -193,20 +258,20 @@ uint32 reg_perfcount_get_counter_help(uint32 base_index, char **retbuf)
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_counter_names(uint32 base_index, char **retbuf)
|
||||
{
|
||||
char *buf1 = NULL, *buf2 = NULL;
|
||||
uint32 buffer_size = 0;
|
||||
TDB_CONTEXT *names;
|
||||
pstring fname;
|
||||
const char *fname = counters_directory( NAMES_DB );
|
||||
int i;
|
||||
|
||||
if(base_index == 0)
|
||||
return 0;
|
||||
|
||||
pstrcpy(fname, lp_counters_dir());
|
||||
pstrcat(fname, "/names.tdb");
|
||||
|
||||
names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
if(names == NULL)
|
||||
@ -243,6 +308,9 @@ uint32 reg_perfcount_get_counter_names(uint32 base_index, char **retbuf)
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static void _reg_perfcount_make_key(TDB_DATA *key,
|
||||
char *buf,
|
||||
int buflen,
|
||||
@ -261,6 +329,9 @@ static void _reg_perfcount_make_key(TDB_DATA *key,
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_isparent(TDB_DATA data)
|
||||
{
|
||||
if(data.dsize > 0)
|
||||
@ -273,6 +344,9 @@ static BOOL _reg_perfcount_isparent(TDB_DATA data)
|
||||
return False;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_ischild(TDB_DATA data)
|
||||
{
|
||||
if(data.dsize > 0)
|
||||
@ -285,6 +359,9 @@ static BOOL _reg_perfcount_ischild(TDB_DATA data)
|
||||
return False;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static uint32 _reg_perfcount_get_numinst(int objInd, TDB_CONTEXT *names)
|
||||
{
|
||||
TDB_DATA key, data;
|
||||
@ -301,6 +378,9 @@ static uint32 _reg_perfcount_get_numinst(int objInd, TDB_CONTEXT *names)
|
||||
return (uint32)atoi(buf);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_add_object(PERF_DATA_BLOCK *block,
|
||||
prs_struct *ps,
|
||||
int num,
|
||||
@ -341,15 +421,14 @@ static BOOL _reg_perfcount_add_object(PERF_DATA_BLOCK *block,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
BOOL _reg_perfcount_get_counter_data(TDB_DATA key, TDB_DATA *data)
|
||||
{
|
||||
TDB_CONTEXT *counters;
|
||||
|
||||
pstring fname;
|
||||
const char *fname = counters_directory( DATA_DB );
|
||||
|
||||
pstrcpy(fname, lp_counters_dir());
|
||||
pstrcat(fname, "/data.tdb");
|
||||
|
||||
counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
if(counters == NULL)
|
||||
@ -365,6 +444,9 @@ BOOL _reg_perfcount_get_counter_data(TDB_DATA key, TDB_DATA *data)
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static uint32 _reg_perfcount_get_size_field(uint32 CounterType)
|
||||
{
|
||||
uint32 retval;
|
||||
@ -379,7 +461,10 @@ static uint32 _reg_perfcount_get_size_field(uint32 CounterType)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static uint32 _reg_perfcount_compute_scale(long long int data)
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static uint32 _reg_perfcount_compute_scale(SMB_BIG_INT data)
|
||||
{
|
||||
int scale = 0;
|
||||
if(data == 0)
|
||||
@ -398,6 +483,9 @@ static uint32 _reg_perfcount_compute_scale(long long int data)
|
||||
return (uint32)scale;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
|
||||
prs_struct *ps,
|
||||
int CounterIndex,
|
||||
@ -408,7 +496,7 @@ static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
|
||||
char buf[PERFCOUNT_MAX_LEN];
|
||||
size_t dsize, padding;
|
||||
long int data32, dbuf[2];
|
||||
long long int data64;
|
||||
SMB_BIG_INT data64;
|
||||
uint32 counter_size;
|
||||
|
||||
obj->counters[obj->NumCounters].DefaultScale = 0;
|
||||
@ -447,7 +535,7 @@ static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
|
||||
memcpy(buf, data.dptr, data.dsize);
|
||||
data32 = strtol(buf, NULL, 0);
|
||||
if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
|
||||
obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((long long int)data32);
|
||||
obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((SMB_BIG_INT)data32);
|
||||
else
|
||||
obj->counters[obj->NumCounters].DefaultScale = 0;
|
||||
dbuf[0] = data32;
|
||||
@ -458,7 +546,7 @@ static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
|
||||
dsize = sizeof(data64);
|
||||
memset(buf, 0, PERFCOUNT_MAX_LEN);
|
||||
memcpy(buf, data.dptr, data.dsize);
|
||||
data64 = strtoll(buf, NULL, 0);
|
||||
data64 = atof(buf);
|
||||
if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER)
|
||||
obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale(data64);
|
||||
else
|
||||
@ -504,6 +592,9 @@ static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
PERF_OBJECT_TYPE *_reg_perfcount_find_obj(PERF_DATA_BLOCK *block, int objind)
|
||||
{
|
||||
int i;
|
||||
@ -521,6 +612,9 @@ PERF_OBJECT_TYPE *_reg_perfcount_find_obj(PERF_DATA_BLOCK *block, int objind)
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_add_counter(PERF_DATA_BLOCK *block,
|
||||
prs_struct *ps,
|
||||
int num,
|
||||
@ -582,6 +676,9 @@ static BOOL _reg_perfcount_add_counter(PERF_DATA_BLOCK *block,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
BOOL _reg_perfcount_get_instance_info(PERF_INSTANCE_DEFINITION *inst,
|
||||
prs_struct *ps,
|
||||
int instId,
|
||||
@ -662,6 +759,9 @@ BOOL _reg_perfcount_get_instance_info(PERF_INSTANCE_DEFINITION *inst,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
BOOL _reg_perfcount_add_instance(PERF_OBJECT_TYPE *obj,
|
||||
prs_struct *ps,
|
||||
int instInd,
|
||||
@ -689,6 +789,9 @@ BOOL _reg_perfcount_add_instance(PERF_OBJECT_TYPE *obj,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static int _reg_perfcount_assemble_global(PERF_DATA_BLOCK *block,
|
||||
prs_struct *ps,
|
||||
int base_index,
|
||||
@ -728,7 +831,10 @@ static int _reg_perfcount_assemble_global(PERF_DATA_BLOCK *block,
|
||||
return retval;
|
||||
}
|
||||
|
||||
static BOOL _reg_perfcount_get_64(unsigned long long *retval,
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_get_64(SMB_BIG_UINT *retval,
|
||||
TDB_CONTEXT *tdb,
|
||||
int key_part1,
|
||||
const char *key_part2)
|
||||
@ -749,23 +855,21 @@ static BOOL _reg_perfcount_get_64(unsigned long long *retval,
|
||||
memcpy(buf, data.dptr, data.dsize);
|
||||
free(data.dptr);
|
||||
|
||||
*retval = strtoll(buf, NULL, 0);
|
||||
*retval = atof(buf);
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_init_data_block_perf(PERF_DATA_BLOCK *block,
|
||||
TDB_CONTEXT *names)
|
||||
{
|
||||
unsigned long long PerfFreq, PerfTime, PerfTime100nSec;
|
||||
SMB_BIG_UINT PerfFreq, PerfTime, PerfTime100nSec;
|
||||
TDB_CONTEXT *counters;
|
||||
BOOL status;
|
||||
pstring fname;
|
||||
|
||||
status = False;
|
||||
|
||||
pstrcpy(fname, lp_counters_dir());
|
||||
pstrcat(fname, "/data.tdb");
|
||||
BOOL status = False;
|
||||
const char *fname = counters_directory( DATA_DB );
|
||||
|
||||
counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
@ -803,6 +907,9 @@ static BOOL _reg_perfcount_init_data_block_perf(PERF_DATA_BLOCK *block,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static void _reg_perfcount_init_data_block(PERF_DATA_BLOCK *block, prs_struct *ps, TDB_CONTEXT *names)
|
||||
{
|
||||
wpstring temp;
|
||||
@ -839,6 +946,9 @@ static void _reg_perfcount_init_data_block(PERF_DATA_BLOCK *block, prs_struct *p
|
||||
return;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static uint32 _reg_perfcount_perf_data_block_fixup(PERF_DATA_BLOCK *block, prs_struct *ps)
|
||||
{
|
||||
int obj, cnt, inst, pad, i;
|
||||
@ -923,20 +1033,20 @@ static uint32 _reg_perfcount_perf_data_block_fixup(PERF_DATA_BLOCK *block, prs_s
|
||||
|
||||
return block->TotalByteLength;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
uint32 reg_perfcount_get_perf_data_block(uint32 base_index,
|
||||
prs_struct *ps,
|
||||
PERF_DATA_BLOCK *block,
|
||||
char *object_ids)
|
||||
{
|
||||
uint32 buffer_size = 0, last_counter;
|
||||
pstring fname;
|
||||
const char *fname = counters_directory( NAMES_DB );
|
||||
TDB_CONTEXT *names;
|
||||
int retval;
|
||||
|
||||
pstrcpy(fname, lp_counters_dir());
|
||||
pstrcat(fname, "/names.tdb");
|
||||
|
||||
|
||||
names = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444);
|
||||
|
||||
if(names == NULL)
|
||||
@ -966,6 +1076,9 @@ uint32 reg_perfcount_get_perf_data_block(uint32 base_index,
|
||||
return buffer_size + block->HeaderLength;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_perf_data_block(prs_struct *ps, PERF_DATA_BLOCK block, int depth)
|
||||
{
|
||||
int i;
|
||||
@ -1017,6 +1130,9 @@ static BOOL _reg_perfcount_marshall_perf_data_block(prs_struct *ps, PERF_DATA_BL
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_perf_counters(prs_struct *ps,
|
||||
PERF_OBJECT_TYPE object,
|
||||
int depth)
|
||||
@ -1058,6 +1174,9 @@ static BOOL _reg_perfcount_marshall_perf_counters(prs_struct *ps,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_perf_counter_data(prs_struct *ps,
|
||||
PERF_COUNTER_BLOCK counter_data,
|
||||
int depth)
|
||||
@ -1078,6 +1197,9 @@ static BOOL _reg_perfcount_marshall_perf_counter_data(prs_struct *ps,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_perf_instances(prs_struct *ps,
|
||||
PERF_OBJECT_TYPE object,
|
||||
int depth)
|
||||
@ -1116,6 +1238,9 @@ static BOOL _reg_perfcount_marshall_perf_instances(prs_struct *ps,
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_perf_objects(prs_struct *ps, PERF_DATA_BLOCK block, int depth)
|
||||
{
|
||||
int obj;
|
||||
@ -1183,6 +1308,9 @@ static BOOL _reg_perfcount_marshall_perf_objects(prs_struct *ps, PERF_DATA_BLOCK
|
||||
return True;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
static BOOL _reg_perfcount_marshall_hkpd(prs_struct *ps, PERF_DATA_BLOCK block)
|
||||
{
|
||||
int depth = 0;
|
||||
@ -1193,6 +1321,10 @@ static BOOL _reg_perfcount_marshall_hkpd(prs_struct *ps, PERF_DATA_BLOCK block)
|
||||
}
|
||||
return False;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
*********************************************************************/
|
||||
|
||||
WERROR reg_perfcount_get_hkpd(prs_struct *ps, uint32 max_buf_size, uint32 *outbuf_len, char *object_ids)
|
||||
{
|
||||
/*
|
||||
|
@ -71,6 +71,7 @@ struct service_display_info common_unix_svcs[] = {
|
||||
{ "apache", NULL, "HTTP Server", NULL },
|
||||
{ "autofs", NULL, "Automounter", NULL },
|
||||
{ "squid", NULL, "Web Cache Proxy ", NULL },
|
||||
{ "perfcountd", NULL, "Performance Monitoring Daemon", NULL },
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
|
@ -117,11 +117,14 @@ static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
|
||||
return werror_to_ntstatus(result);
|
||||
}
|
||||
|
||||
result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
|
||||
if ( !W_ERROR_IS_OK(result) ) {
|
||||
d_printf("Unable to open [%s]\n", argv[0]);
|
||||
return werror_to_ntstatus(result);
|
||||
if ( strlen( subpath ) != 0 ) {
|
||||
result = rpccli_reg_open_entry(pipe_hnd, mem_ctx, &pol_hive, subpath, MAXIMUM_ALLOWED_ACCESS, &pol_key );
|
||||
if ( !W_ERROR_IS_OK(result) ) {
|
||||
d_printf("Unable to open [%s]\n", argv[0]);
|
||||
return werror_to_ntstatus(result);
|
||||
}
|
||||
}
|
||||
memcpy( &pol_key, &pol_hive, sizeof(POLICY_HND) );
|
||||
|
||||
/* get the subkeys */
|
||||
|
||||
@ -183,7 +186,8 @@ static NTSTATUS rpc_registry_enumerate_internal(const DOM_SID *domain_sid,
|
||||
out:
|
||||
/* cleanup */
|
||||
|
||||
rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
|
||||
if ( strlen( subpath ) != 0 )
|
||||
rpccli_reg_close(pipe_hnd, mem_ctx, &pol_key );
|
||||
rpccli_reg_close(pipe_hnd, mem_ctx, &pol_hive );
|
||||
|
||||
return werror_to_ntstatus(result);
|
||||
|
Loading…
x
Reference in New Issue
Block a user