From: Volker Lendecke Date: Wed, 31 May 2023 07:48:58 +0000 (+0200) Subject: profiling: Factor out functions to read smbprofile.tdb X-Git-Tag: talloc-2.4.1~344 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1cd2f38b54b7a79ae21a328075fae07cfdc5e9aa;p=thirdparty%2Fsamba.git 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 Reviewed-by: Jeremy Allison --- diff --git a/source3/include/smbprofile.h b/source3/include/smbprofile.h index 3c9de159212..91af220051d 100644 --- a/source3/include/smbprofile.h +++ b/source3/include/smbprofile.h @@ -22,6 +22,7 @@ */ #include "replace.h" +#include #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) diff --git a/source3/profile/profile.c b/source3/profile/profile.c index efb603d85cb..6decb855282 100644 --- a/source3/profile/profile.c +++ b/source3/profile/profile.c @@ -32,10 +32,6 @@ #include #endif -#include -#include -#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(); + profile_p = &smbprofile_state.stats.global; - 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 + rc = smbprofile_magic(profile_p, &profile_p->magic); 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); - } - 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); } diff --git a/source3/profile/profile_read.c b/source3/profile/profile_read.c new file mode 100644 index 00000000000..45a1980773f --- /dev/null +++ b/source3/profile/profile_read.c @@ -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 . + */ + +#include "replace.h" +#include +#include +#include +#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); +} diff --git a/source3/wscript_build b/source3/wscript_build index a178a43b71a..5410da1b50f 100644 --- a/source3/wscript_build +++ b/source3/wscript_build @@ -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',