From 25b5bb3056bbd7d0aaeeff106e9cfc9cc309bc78 Mon Sep 17 00:00:00 2001 From: Christof Schmitt Date: Thu, 16 Feb 2017 16:22:38 -0700 Subject: [PATCH] net: Add net tdb command to print information from tdb records The main purpose is to debug "hot" records from ctdb. ctdb tracks contended records and identifies them by key in the dbstatistics: DB Statistics: locking.tdb [...] Num Hot Keys: 1 Count:3 Key:6a4128e3ced4681b02a00000000000000000000000000000 This command allows querying additional information for the associated key to identify the affected file. For now this only adds a subcommand for the locking.tdb, but could be extended to others: net tdb locking 6a4128e3ced4681b02a00000000000000000000000000000 Share path: /test/share Name: testfile Number of share modes: 2 Signed-off-by: Christof Schmitt Reviewed-by: Volker Lendecke --- source3/utils/net.c | 8 +++ source3/utils/net_proto.h | 3 + source3/utils/net_tdb.c | 120 ++++++++++++++++++++++++++++++++++++ source3/utils/wscript_build | 1 + 4 files changed, 132 insertions(+) create mode 100644 source3/utils/net_tdb.c diff --git a/source3/utils/net.c b/source3/utils/net.c index beb8760bda8..34884f0fead 100644 --- a/source3/utils/net.c +++ b/source3/utils/net.c @@ -751,6 +751,14 @@ static struct functable net_func[] = { "'net notify' commands.") }, + { "tdb", + net_tdb, + NET_TRANSPORT_LOCAL, + N_("Show information from tdb records"), + N_(" Use 'net help tdb' to get more information about " + "'net tdb' commands.") + }, + #ifdef WITH_FAKE_KASERVER { "afs", net_afs, diff --git a/source3/utils/net_proto.h b/source3/utils/net_proto.h index 093aa4be93e..f0ae538cbc4 100644 --- a/source3/utils/net_proto.h +++ b/source3/utils/net_proto.h @@ -462,4 +462,7 @@ int net_rpc_trust(struct net_context *c, int argc, const char **argv); int net_rpc_conf(struct net_context *c, int argc, const char **argv); int net_notify(struct net_context *c, int argc, const char **argv); + +int net_tdb(struct net_context *c, int argc, const char **argv); + #endif /* _NET_PROTO_H_ */ diff --git a/source3/utils/net_tdb.c b/source3/utils/net_tdb.c new file mode 100644 index 00000000000..a03cc0e2c09 --- /dev/null +++ b/source3/utils/net_tdb.c @@ -0,0 +1,120 @@ +/* + * Samba Unix/Linux client library + * net tdb commands to query tdb record information + * Copyright (C) 2016, 2017 Christof Schmitt + * + * 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 "includes.h" +#include "utils/net.h" +#include "locking/proto.h" +#include "librpc/gen_ndr/open_files.h" +#include "librpc/gen_ndr/ndr_open_files.h" + +static int net_tdb_locking_dump(TALLOC_CTX *mem_ctx, + struct share_mode_data *data) +{ + struct ndr_print *ndr_print; + + ndr_print = talloc_zero(mem_ctx, struct ndr_print); + if (ndr_print == NULL) { + d_printf("Could not allocate memory.\n"); + return -1; + } + + ndr_print->print = ndr_print_printf_helper; + ndr_print->depth = 1; + ndr_print_share_mode_data(ndr_print, "SHARE_MODE_DATA", data); + TALLOC_FREE(ndr_print); + + return 0; +} + +static int net_tdb_locking_fetch(TALLOC_CTX *mem_ctx, const char *hexkey, + struct share_mode_lock **lock) +{ + DATA_BLOB blob; + struct file_id id; + bool ok; + + blob = strhex_to_data_blob(mem_ctx, hexkey); + if (blob.length != sizeof(struct file_id)) { + d_printf("Invalid length of key\n"); + return -1; + } + + id = *(struct file_id *)blob.data; + + ok = locking_init_readonly(); + if (!ok) { + d_printf("locking_init_readonly failed\n"); + return -1; + } + + *lock = fetch_share_mode_unlocked(mem_ctx, id); + + if (*lock == NULL) { + d_printf("Record with key %s not found.\n", hexkey); + return -1; + } + + return 0; +} + +static int net_tdb_locking(struct net_context *c, int argc, const char **argv) +{ + TALLOC_CTX *mem_ctx = talloc_stackframe(); + struct share_mode_lock *lock; + int ret; + + if (argc < 1) { + d_printf("Usage: net tdb locking [ dump ]\n"); + ret = -1; + goto out; + } + + ret = net_tdb_locking_fetch(mem_ctx, argv[0], &lock); + if (ret != 0) { + goto out; + } + + if (argc == 2 && strequal(argv[1], "dump")) { + ret = net_tdb_locking_dump(mem_ctx, lock->data); + } else { + d_printf("Share path: %s\n", lock->data->servicepath); + d_printf("Name: %s\n", lock->data->base_name); + d_printf("Number of share modes: %" PRIu32 "\n", + lock->data->num_share_modes); + } + +out: + TALLOC_FREE(mem_ctx); + return ret; +} + +int net_tdb(struct net_context *c, int argc, const char **argv) +{ + struct functable func[] = { + { "locking", + net_tdb_locking, + NET_TRANSPORT_LOCAL, + N_("Show information for a record in locking.tdb"), + N_("net tdb locking ") + }, + {NULL, NULL, 0, NULL, NULL} + }; + + return net_run_function(c, argc, argv, "net tdb", func); +} diff --git a/source3/utils/wscript_build b/source3/utils/wscript_build index 4295f859249..3c1f9a4773d 100644 --- a/source3/utils/wscript_build +++ b/source3/utils/wscript_build @@ -205,6 +205,7 @@ bld.SAMBA3_BINARY('net', net_rpc_conf.c net_afs.c net_notify.c + net_tdb.c ../registry/reg_parse.c ../registry/reg_format.c ../registry/reg_import.c -- 2.34.1