1
0
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:
Gerald Carter 2005-11-08 16:33:45 +00:00 committed by Gerald (Jerry) Carter
parent 38b54d063d
commit 77460a9075
14 changed files with 1568 additions and 49 deletions

View 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
View 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__ */

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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;
}

View 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

View File

@ -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)

View File

@ -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 */

View File

@ -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)
{
/*

View File

@ -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 }
};

View File

@ -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);