mirror of
https://github.com/samba-team/samba.git
synced 2025-02-03 13:47:25 +03:00
s3: Test module for perfcount system
Add 'perfcount module = pc_test' to exercise this module. Results are logged into smb.log every 50 operations (configurable via smb.conf).
This commit is contained in:
parent
ad07bb8dbd
commit
dbe2588e46
@ -668,6 +668,7 @@ VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \
|
||||
modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.c \
|
||||
modules/onefs_cbrl.o
|
||||
PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
|
||||
PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
|
||||
|
||||
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
|
||||
|
||||
@ -2562,6 +2563,10 @@ bin/pc_onefs.@SHLIBEXT@: $(BINARY_PREREQS) $(PERFCOUNT_ONEFS_OBJ)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD_MODULE) $(PERFCOUNT_ONEFS_OBJ)
|
||||
|
||||
bin/pc_test.@SHLIBEXT@: $(BINARY_PREREQS) $(PERFCOUNT_TEST_OBJ)
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD_MODULE) $(PERFCOUNT_TEST_OBJ)
|
||||
|
||||
bin/registry.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/registry.o
|
||||
@echo "Building plugin $@"
|
||||
@$(SHLD_MODULE) libgpo/gpext/registry.o
|
||||
|
@ -421,7 +421,7 @@ default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_
|
||||
|
||||
if test "x$developer" = xyes; then
|
||||
default_static_modules="$default_static_modules rpc_rpcecho"
|
||||
default_shared_modules="$default_shared_modules charset_weird"
|
||||
default_shared_modules="$default_shared_modules charset_weird perfcount_test"
|
||||
fi
|
||||
|
||||
#
|
||||
@ -6137,6 +6137,7 @@ SMB_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS)
|
||||
SMB_SUBSYSTEM(VFS,smbd/vfs.o)
|
||||
|
||||
SMB_MODULE(perfcount_onefs, \$(PERFCOUNT_ONEFS), "bin/pc_onefs.$SHLIBEXT", PERFCOUNT)
|
||||
SMB_MODULE(perfcount_test, \$(PERFCOUNT_TEST), "bin/pc_test.$SHLIBEXT", PERFCOUNT)
|
||||
SMB_SUBSYSTEM(PERFCOUNT,smbd/perfcount.o)
|
||||
|
||||
SMB_MODULE(gpext_registry, libgpo/gpext/registry.o, "bin/registry.$SHLIBEXT", GPEXT)
|
||||
|
363
source3/modules/perfcount_test.c
Normal file
363
source3/modules/perfcount_test.c
Normal file
@ -0,0 +1,363 @@
|
||||
/*
|
||||
* Unix SMB/CIFS implementation.
|
||||
* Test module for perfcounters
|
||||
*
|
||||
* Copyright (C) Todd Stecher 2008
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#define PARM_PC_TEST_TYPE "pc_test"
|
||||
#define PARM_DUMPON_COUNT "count"
|
||||
#define PARM_DUMPON_COUNT_DEFAULT 50
|
||||
|
||||
struct perfcount_test_identity {
|
||||
uid_t uid;
|
||||
char *user;
|
||||
char *domain;
|
||||
};
|
||||
|
||||
struct perfcount_test_counter {
|
||||
int op;
|
||||
int sub_op;
|
||||
int ioctl;
|
||||
uint64_t bytes_in;
|
||||
uint64_t bytes_out;
|
||||
int count;
|
||||
|
||||
struct perfcount_test_counter *next;
|
||||
struct perfcount_test_counter *prev;
|
||||
};
|
||||
|
||||
struct perfcount_test_context {
|
||||
|
||||
/* wip: identity */
|
||||
struct perfcount_test_identity *id;
|
||||
struct perfcount_test_counter *ops;
|
||||
};
|
||||
|
||||
#define MAX_OP 256
|
||||
struct perfcount_test_counter *g_list[MAX_OP];
|
||||
|
||||
int count;
|
||||
|
||||
/* determine frequency of dumping results */
|
||||
int count_mod = 1;
|
||||
|
||||
static void perfcount_test_add_counters(struct perfcount_test_context *ctxt)
|
||||
{
|
||||
struct perfcount_test_counter *head;
|
||||
struct perfcount_test_counter *ptc;
|
||||
struct perfcount_test_counter *tmp;
|
||||
bool found;
|
||||
|
||||
for (ptc = ctxt->ops; ptc != NULL; ) {
|
||||
|
||||
found = false;
|
||||
|
||||
if (ptc->op > MAX_OP)
|
||||
continue;
|
||||
|
||||
for (head = g_list[ptc->op]; head != NULL; head = head->next) {
|
||||
if ((ptc->sub_op == head->sub_op) &&
|
||||
(ptc->ioctl == head->ioctl)) {
|
||||
head->bytes_in += ptc->bytes_in;
|
||||
head->bytes_out += ptc->bytes_out;
|
||||
head->count++;
|
||||
tmp = ptc->next;
|
||||
DLIST_REMOVE(ctxt->ops, ptc);
|
||||
SAFE_FREE(ptc);
|
||||
ptc = tmp;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* not in global tracking list - add it */
|
||||
if (!found) {
|
||||
tmp = ptc->next;
|
||||
DLIST_REMOVE(ctxt->ops, ptc);
|
||||
ptc->count = 1;
|
||||
DLIST_ADD(g_list[ptc->op], ptc);
|
||||
ptc = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static void perfcount_test_dump_id(struct perfcount_test_identity *id, int lvl)
|
||||
{
|
||||
if (!id)
|
||||
return;
|
||||
|
||||
DEBUG(lvl,("uid - %d\n", id->uid));
|
||||
DEBUG(lvl,("user - %s\n", id->user));
|
||||
DEBUG(lvl,("domain - %s\n", id->domain));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static const char *trans_subop_table[] = {
|
||||
"unknown", "trans:create", "trans:ioctl", "trans:set sd",
|
||||
"trans:change notify", "trans: rename", "trans:get sd",
|
||||
"trans:get quota", "trans:set quota"
|
||||
};
|
||||
|
||||
static const char *trans2_subop_table[] = {
|
||||
"trans2:open", "trans2:find first", "trans2:find next",
|
||||
"trans2:q fsinfo", "trans2:set fsinfo", "trans2:q path info",
|
||||
"trans2:set pathinfo", "trans2:fs ctl", "trans2: io ctl",
|
||||
"trans2:find notify first", "trans2:find notify next",
|
||||
"trans2:mkdir", "trans2:sess setup", "trans2:get dfs referral",
|
||||
"trans2:report dfs inconsistent"
|
||||
};
|
||||
|
||||
static const char *smb_subop_name(int op, int subop)
|
||||
{
|
||||
/* trans */
|
||||
if (op == 0x25) {
|
||||
if (subop > sizeof(trans_subop_table) /
|
||||
sizeof(trans_subop_table[0])) {
|
||||
return "unknown";
|
||||
}
|
||||
return trans_subop_table[subop];
|
||||
} else if (op == 0x32) {
|
||||
if (subop > sizeof(trans2_subop_table) /
|
||||
sizeof(trans2_subop_table[0])) {
|
||||
return "unknown";
|
||||
}
|
||||
return trans2_subop_table[subop];
|
||||
}
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static void perfcount_test_dump_counter(struct perfcount_test_counter *ptc,
|
||||
int lvl)
|
||||
{
|
||||
DEBUG(lvl, ("OP: %s\n", smb_fn_name(ptc->op)));
|
||||
if (ptc->sub_op > 0) {
|
||||
DEBUG(lvl, ("SUBOP: %s\n",
|
||||
smb_subop_name(ptc->op, ptc->sub_op)));
|
||||
}
|
||||
|
||||
if (ptc->ioctl > 0) {
|
||||
DEBUG(lvl, ("IOCTL: %d\n", ptc->ioctl));
|
||||
}
|
||||
|
||||
DEBUG(lvl, ("Count: %d\n\n", ptc->count));
|
||||
}
|
||||
|
||||
static void perfcount_test_dump_counters(void)
|
||||
{
|
||||
int i;
|
||||
struct perfcount_test_counter *head;
|
||||
|
||||
count_mod = lp_parm_int(0, PARM_PC_TEST_TYPE, PARM_DUMPON_COUNT,
|
||||
PARM_DUMPON_COUNT_DEFAULT);
|
||||
|
||||
if ((count++ % count_mod) != 0)
|
||||
return;
|
||||
|
||||
DEBUG(0,("##### Dumping Performance Counters #####\n"));
|
||||
|
||||
for (i=0; i < 256; i++) {
|
||||
for (head = g_list[i]; head != NULL; head = head->next) {
|
||||
perfcount_test_dump_counter(head, 0);
|
||||
head->prev = NULL;
|
||||
SAFE_FREE(head->prev);
|
||||
}
|
||||
SAFE_FREE(head);
|
||||
}
|
||||
}
|
||||
|
||||
/* operations */
|
||||
static void perfcount_test_start(struct smb_perfcount_data *pcd)
|
||||
{
|
||||
struct perfcount_test_context *ctxt;
|
||||
struct perfcount_test_counter *ctr;
|
||||
/*
|
||||
* there shouldn't already be a context here - if so,
|
||||
* there's an unbalanced call to start / end.
|
||||
*/
|
||||
if (pcd->context) {
|
||||
DEBUG(0,("perfcount_test_start - starting "
|
||||
"initialized context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
ctxt = SMB_MALLOC_P(struct perfcount_test_context);
|
||||
if (!ctxt)
|
||||
return;
|
||||
|
||||
ZERO_STRUCTP(ctxt);
|
||||
|
||||
/* create 'default' context */
|
||||
ctr = SMB_MALLOC_P(struct perfcount_test_counter);
|
||||
if (!ctr) {
|
||||
SAFE_FREE(ctxt);
|
||||
return;
|
||||
}
|
||||
|
||||
ZERO_STRUCTP(ctr);
|
||||
ctr->op = ctr->sub_op = ctr->ioctl = -1;
|
||||
DLIST_ADD(ctxt->ops, ctr);
|
||||
|
||||
pcd->context = (void*)ctxt;
|
||||
}
|
||||
|
||||
static void perfcount_test_add(struct smb_perfcount_data *pcd)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
struct perfcount_test_counter *ctr;
|
||||
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_add - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
ctr = SMB_MALLOC_P(struct perfcount_test_counter);
|
||||
if (!ctr) {
|
||||
return;
|
||||
}
|
||||
|
||||
DLIST_ADD(ctxt->ops, ctr);
|
||||
|
||||
}
|
||||
|
||||
static void perfcount_test_set_op(struct smb_perfcount_data *pcd, int op)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_op - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
ctxt->ops->op = op;
|
||||
}
|
||||
|
||||
static void perfcount_test_set_subop(struct smb_perfcount_data *pcd, int sub_op)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_sub_op - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
ctxt->ops->sub_op = sub_op;
|
||||
}
|
||||
|
||||
static void perfcount_test_set_ioctl(struct smb_perfcount_data *pcd, int io_ctl)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_ioctl - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
ctxt->ops->ioctl = io_ctl;
|
||||
}
|
||||
|
||||
static void perfcount_test_set_msglen_in(struct smb_perfcount_data *pcd,
|
||||
uint64_t bytes_in)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_msglen_in - "
|
||||
"uninitialized perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
ctxt->ops->bytes_in = bytes_in;
|
||||
}
|
||||
|
||||
static void perfcount_test_set_msglen_out(struct smb_perfcount_data *pcd,
|
||||
uint64_t bytes_out)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_msglen_out - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
ctxt->ops->bytes_out = bytes_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* For perf reasons, its best to use some global state
|
||||
* when an operation is deferred, we need to alloc a copy.
|
||||
*/
|
||||
static void perfcount_test_defer_op(struct smb_perfcount_data *pcd,
|
||||
struct smb_perfcount_data *def_pcd)
|
||||
{
|
||||
/* we don't do anything special to deferred ops */
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_set_msglen_out - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void perfcount_test_set_client(struct smb_perfcount_data *pcd,
|
||||
uid_t uid, const char *user,
|
||||
const char *domain)
|
||||
{
|
||||
// WIP
|
||||
return;
|
||||
}
|
||||
|
||||
static void perfcount_test_end(struct smb_perfcount_data *pcd)
|
||||
{
|
||||
struct perfcount_test_context *ctxt = pcd->context;
|
||||
if (pcd->context == NULL) {
|
||||
DEBUG(0,("perfcount_test_end - uninitialized "
|
||||
"perfcount context - %p\n", pcd));
|
||||
return;
|
||||
}
|
||||
|
||||
/* @bug - we don't store outbytes right for chained cmds */
|
||||
perfcount_test_add_counters(ctxt);
|
||||
perfcount_test_dump_counters();
|
||||
SAFE_FREE(ctxt);
|
||||
}
|
||||
|
||||
|
||||
static struct smb_perfcount_handlers perfcount_test_handlers = {
|
||||
perfcount_test_start,
|
||||
perfcount_test_add,
|
||||
perfcount_test_set_op,
|
||||
perfcount_test_set_subop,
|
||||
perfcount_test_set_ioctl,
|
||||
perfcount_test_set_msglen_in,
|
||||
perfcount_test_set_msglen_out,
|
||||
perfcount_test_set_client,
|
||||
perfcount_test_defer_op,
|
||||
perfcount_test_end
|
||||
};
|
||||
|
||||
NTSTATUS perfcount_test_init(void)
|
||||
{
|
||||
return smb_register_perfcounter(SMB_PERFCOUNTER_INTERFACE_VERSION,
|
||||
"pc_test", &perfcount_test_handlers);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user