1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

profiling: Factor out functions to read smbprofile.tdb

We don't need all of Samba just to dump contents of this tdb, make
exporting profile information cheaper.

No direct use yet, but it's a good cleanup IMHO

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
Volker Lendecke 2023-05-31 09:48:58 +02:00 committed by Jeremy Allison
parent 18070a2d65
commit 1cd2f38b54
4 changed files with 217 additions and 141 deletions

View File

@ -22,6 +22,7 @@
*/
#include "replace.h"
#include <tdb.h>
#include "lib/util/time.h"
struct tevent_context;
@ -517,6 +518,10 @@ void smbprofile_dump(void);
void smbprofile_cleanup(pid_t pid, pid_t dst);
void smbprofile_stats_accumulate(struct profile_stats *acc,
const struct profile_stats *add);
int smbprofile_magic(const struct profile_stats *stats, uint64_t *_magic);
void smbprofile_collect_tdb(struct tdb_context *tdb,
uint64_t magic,
struct profile_stats *stats);
void smbprofile_collect(struct profile_stats *stats);
static inline uint64_t profile_timestamp(void)

View File

@ -32,10 +32,6 @@
#include <sys/resource.h>
#endif
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include "lib/crypto/gnutls_helpers.h"
struct profile_stats *profile_p;
struct smbprofile_global_state smbprofile_state;
@ -124,8 +120,6 @@ static void reqprofile_message(struct messaging_context *msg_ctx,
******************************************************************/
bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
{
uint8_t digest[gnutls_hash_get_len(GNUTLS_DIG_SHA1)];
gnutls_hash_hd_t hash_hnd = NULL;
char *db_name;
bool ok = false;
int rc;
@ -154,78 +148,15 @@ bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
reqprofile_message);
}
GNUTLS_FIPS140_SET_LAX_MODE();
rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA1);
if (rc < 0) {
goto out;
}
rc = gnutls_hash(hash_hnd,
&smbprofile_state.stats.global,
sizeof(smbprofile_state.stats.global));
#define __UPDATE(str) do { \
rc |= gnutls_hash(hash_hnd, str, strlen(str)); \
} while(0)
#define SMBPROFILE_STATS_START
#define SMBPROFILE_STATS_SECTION_START(name, display) do { \
__UPDATE(#name "+" #display); \
} while(0);
#define SMBPROFILE_STATS_COUNT(name) do { \
__UPDATE(#name "+count"); \
} while(0);
#define SMBPROFILE_STATS_TIME(name) do { \
__UPDATE(#name "+time"); \
} while(0);
#define SMBPROFILE_STATS_BASIC(name) do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
} while(0);
#define SMBPROFILE_STATS_BYTES(name) do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
__UPDATE(#name "+idle"); \
__UPDATE(#name "+bytes"); \
} while(0);
#define SMBPROFILE_STATS_IOBYTES(name) do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
__UPDATE(#name "+idle"); \
__UPDATE(#name "+inbytes"); \
__UPDATE(#name "+outbytes"); \
} while(0);
#define SMBPROFILE_STATS_SECTION_END
#define SMBPROFILE_STATS_END
SMBPROFILE_STATS_ALL_SECTIONS
#undef __UPDATE
#undef SMBPROFILE_STATS_START
#undef SMBPROFILE_STATS_SECTION_START
#undef SMBPROFILE_STATS_COUNT
#undef SMBPROFILE_STATS_TIME
#undef SMBPROFILE_STATS_BASIC
#undef SMBPROFILE_STATS_BYTES
#undef SMBPROFILE_STATS_IOBYTES
#undef SMBPROFILE_STATS_SECTION_END
#undef SMBPROFILE_STATS_END
if (rc != 0) {
gnutls_hash_deinit(hash_hnd, NULL);
goto out;
}
gnutls_hash_deinit(hash_hnd, digest);
GNUTLS_FIPS140_SET_STRICT_MODE();
profile_p = &smbprofile_state.stats.global;
profile_p->magic = BVAL(digest, 0);
if (profile_p->magic == 0) {
profile_p->magic = BVAL(digest, 8);
rc = smbprofile_magic(profile_p, &profile_p->magic);
if (rc != 0) {
goto out;
}
ok = true;
out:
GNUTLS_FIPS140_SET_STRICT_MODE();
return ok;
}
@ -389,77 +320,12 @@ void smbprofile_cleanup(pid_t pid, pid_t dst)
tdb_chainunlock(smbprofile_state.internal.db->tdb, key);
}
void smbprofile_stats_accumulate(struct profile_stats *acc,
const struct profile_stats *add)
{
#define SMBPROFILE_STATS_START
#define SMBPROFILE_STATS_SECTION_START(name, display)
#define SMBPROFILE_STATS_COUNT(name) do { \
acc->values.name##_stats.count += add->values.name##_stats.count; \
} while(0);
#define SMBPROFILE_STATS_TIME(name) do { \
acc->values.name##_stats.time += add->values.name##_stats.time; \
} while(0);
#define SMBPROFILE_STATS_BASIC(name) do { \
acc->values.name##_stats.count += add->values.name##_stats.count; \
acc->values.name##_stats.time += add->values.name##_stats.time; \
} while(0);
#define SMBPROFILE_STATS_BYTES(name) do { \
acc->values.name##_stats.count += add->values.name##_stats.count; \
acc->values.name##_stats.time += add->values.name##_stats.time; \
acc->values.name##_stats.idle += add->values.name##_stats.idle; \
acc->values.name##_stats.bytes += add->values.name##_stats.bytes; \
} while(0);
#define SMBPROFILE_STATS_IOBYTES(name) do { \
acc->values.name##_stats.count += add->values.name##_stats.count; \
acc->values.name##_stats.time += add->values.name##_stats.time; \
acc->values.name##_stats.idle += add->values.name##_stats.idle; \
acc->values.name##_stats.inbytes += add->values.name##_stats.inbytes; \
acc->values.name##_stats.outbytes += add->values.name##_stats.outbytes; \
} while(0);
#define SMBPROFILE_STATS_SECTION_END
#define SMBPROFILE_STATS_END
SMBPROFILE_STATS_ALL_SECTIONS
#undef SMBPROFILE_STATS_START
#undef SMBPROFILE_STATS_SECTION_START
#undef SMBPROFILE_STATS_COUNT
#undef SMBPROFILE_STATS_TIME
#undef SMBPROFILE_STATS_BASIC
#undef SMBPROFILE_STATS_BYTES
#undef SMBPROFILE_STATS_IOBYTES
#undef SMBPROFILE_STATS_SECTION_END
#undef SMBPROFILE_STATS_END
}
static int smbprofile_collect_fn(struct tdb_context *tdb,
TDB_DATA key, TDB_DATA value,
void *private_data)
{
struct profile_stats *acc = (struct profile_stats *)private_data;
const struct profile_stats *v;
if (value.dsize != sizeof(struct profile_stats)) {
return 0;
}
v = (const struct profile_stats *)value.dptr;
if (v->magic != profile_p->magic) {
return 0;
}
smbprofile_stats_accumulate(acc, v);
return 0;
}
void smbprofile_collect(struct profile_stats *stats)
{
*stats = (struct profile_stats) {};
if (smbprofile_state.internal.db == NULL) {
return;
}
tdb_traverse_read(smbprofile_state.internal.db->tdb,
smbprofile_collect_fn, stats);
smbprofile_collect_tdb(smbprofile_state.internal.db->tdb,
profile_p->magic,
stats);
}

View File

@ -0,0 +1,202 @@
/*
* Unix SMB/CIFS implementation.
* store smbd profiling information in shared memory
* Copyright (C) Andrew Tridgell 1999
* Copyright (C) James Peach 2006
*
* 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 "replace.h"
#include <tdb.h>
#include <gnutls/gnutls.h>
#include <gnutls/crypto.h>
#include "lib/crypto/gnutls_helpers.h"
#include "lib/util/byteorder.h"
#include "source3/include/smbprofile.h"
void smbprofile_stats_accumulate(struct profile_stats *acc,
const struct profile_stats *add)
{
#define SMBPROFILE_STATS_START
#define SMBPROFILE_STATS_SECTION_START(name, display)
#define SMBPROFILE_STATS_COUNT(name) \
do { \
acc->values.name##_stats.count += \
add->values.name##_stats.count; \
} while (0);
#define SMBPROFILE_STATS_TIME(name) \
do { \
acc->values.name##_stats.time += \
add->values.name##_stats.time; \
} while (0);
#define SMBPROFILE_STATS_BASIC(name) \
do { \
acc->values.name##_stats.count += \
add->values.name##_stats.count; \
acc->values.name##_stats.time += \
add->values.name##_stats.time; \
} while (0);
#define SMBPROFILE_STATS_BYTES(name) \
do { \
acc->values.name##_stats.count += \
add->values.name##_stats.count; \
acc->values.name##_stats.time += \
add->values.name##_stats.time; \
acc->values.name##_stats.idle += \
add->values.name##_stats.idle; \
acc->values.name##_stats.bytes += \
add->values.name##_stats.bytes; \
} while (0);
#define SMBPROFILE_STATS_IOBYTES(name) \
do { \
acc->values.name##_stats.count += \
add->values.name##_stats.count; \
acc->values.name##_stats.time += \
add->values.name##_stats.time; \
acc->values.name##_stats.idle += \
add->values.name##_stats.idle; \
acc->values.name##_stats.inbytes += \
add->values.name##_stats.inbytes; \
acc->values.name##_stats.outbytes += \
add->values.name##_stats.outbytes; \
} while (0);
#define SMBPROFILE_STATS_SECTION_END
#define SMBPROFILE_STATS_END
SMBPROFILE_STATS_ALL_SECTIONS
#undef SMBPROFILE_STATS_START
#undef SMBPROFILE_STATS_SECTION_START
#undef SMBPROFILE_STATS_COUNT
#undef SMBPROFILE_STATS_TIME
#undef SMBPROFILE_STATS_BASIC
#undef SMBPROFILE_STATS_BYTES
#undef SMBPROFILE_STATS_IOBYTES
#undef SMBPROFILE_STATS_SECTION_END
#undef SMBPROFILE_STATS_END
}
int smbprofile_magic(const struct profile_stats *stats, uint64_t *_magic)
{
uint8_t digest[gnutls_hash_get_len(GNUTLS_DIG_SHA1)];
gnutls_hash_hd_t hash_hnd = NULL;
int rc;
GNUTLS_FIPS140_SET_LAX_MODE();
rc = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_SHA1);
if (rc < 0) {
goto out;
}
rc = gnutls_hash(hash_hnd, stats, sizeof(*stats));
#define __UPDATE(str) \
do { \
rc |= gnutls_hash(hash_hnd, str, strlen(str)); \
} while (0)
#define SMBPROFILE_STATS_START
#define SMBPROFILE_STATS_SECTION_START(name, display) \
do { \
__UPDATE(#name "+" #display); \
} while (0);
#define SMBPROFILE_STATS_COUNT(name) \
do { \
__UPDATE(#name "+count"); \
} while (0);
#define SMBPROFILE_STATS_TIME(name) \
do { \
__UPDATE(#name "+time"); \
} while (0);
#define SMBPROFILE_STATS_BASIC(name) \
do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
} while (0);
#define SMBPROFILE_STATS_BYTES(name) \
do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
__UPDATE(#name "+idle"); \
__UPDATE(#name "+bytes"); \
} while (0);
#define SMBPROFILE_STATS_IOBYTES(name) \
do { \
__UPDATE(#name "+count"); \
__UPDATE(#name "+time"); \
__UPDATE(#name "+idle"); \
__UPDATE(#name "+inbytes"); \
__UPDATE(#name "+outbytes"); \
} while (0);
#define SMBPROFILE_STATS_SECTION_END
#define SMBPROFILE_STATS_END
SMBPROFILE_STATS_ALL_SECTIONS
#undef __UPDATE
#undef SMBPROFILE_STATS_START
#undef SMBPROFILE_STATS_SECTION_START
#undef SMBPROFILE_STATS_COUNT
#undef SMBPROFILE_STATS_TIME
#undef SMBPROFILE_STATS_BASIC
#undef SMBPROFILE_STATS_BYTES
#undef SMBPROFILE_STATS_IOBYTES
#undef SMBPROFILE_STATS_SECTION_END
#undef SMBPROFILE_STATS_END
if (rc != 0) {
gnutls_hash_deinit(hash_hnd, NULL);
goto out;
}
gnutls_hash_deinit(hash_hnd, digest);
out:
GNUTLS_FIPS140_SET_STRICT_MODE();
if (rc == 0) {
uint64_t magic = PULL_LE_U64(digest, 0);
if (magic == 0) {
magic = PULL_LE_U64(digest, 0);
}
*_magic = magic;
}
return rc;
}
static int smbprofile_collect_fn(struct tdb_context *tdb,
TDB_DATA key,
TDB_DATA value,
void *private_data)
{
struct profile_stats *acc = (struct profile_stats *)private_data;
const struct profile_stats *v;
if (value.dsize != sizeof(struct profile_stats)) {
return 0;
}
v = (const struct profile_stats *)value.dptr;
if (v->magic != acc->magic) {
return 0;
}
smbprofile_stats_accumulate(acc, v);
return 0;
}
void smbprofile_collect_tdb(struct tdb_context *tdb,
uint64_t magic,
struct profile_stats *stats)
{
*stats = (struct profile_stats){.magic = magic};
tdb_traverse_read(tdb, smbprofile_collect_fn, stats);
}

View File

@ -773,11 +773,14 @@ bld.SAMBA3_SUBSYSTEM('LEASES_UTIL',
deps='NDR_OPEN_FILES')
if bld.CONFIG_GET("WITH_PROFILE"):
bld.SAMBA_SUBSYSTEM('PROFILE_READ',
source='profile/profile_read.c',
deps='gnutls talloc tdb')
bld.SAMBA3_SUBSYSTEM('PROFILE',
source='profile/profile.c',
deps='''
samba-util
gnutls
PROFILE_READ
''')
else:
bld.SAMBA3_SUBSYSTEM('PROFILE',