root/source3/smbd/perfcount.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. smb_perfcount_find_module
  2. smb_register_perfcounter
  3. smb_load_perfcount_module
  4. smb_init_perfcount_data
  5. smb_perfcount_init

   1 /*
   2    Unix SMB/Netbios implementation.
   3    Perfcounter initialization and support functions
   4    Copyright (C) Todd Stecher 2009
   5 
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10 
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15 
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 
  19 */
  20 
  21 #include "includes.h"
  22 
  23 struct smb_perfcount_handlers *g_smb_perfcount_handlers = NULL;
  24 
  25 struct smb_perfcount_module {
  26         char *name;
  27         struct smb_perfcount_handlers *handlers;
  28         struct smb_perfcount_module *prev, *next;
  29 };
  30 
  31 struct smb_perfcount_module *modules = NULL;
  32 
  33 
  34 /*
  35  * a module is registered before it is actually loaded - keep a list
  36  *
  37  * @todo - currently perfcount modules are globally configured, so
  38  * building the list is not strictly required.
  39  * However, its a proven concept in VFS, and is here to allow a
  40  * move to eventual per-service perfcount configuration.
  41  *
  42  * Note many pre-connection statistics are interesting
  43  * (e.g. before binding to an individual share).
  44  *
  45  */
  46 static struct smb_perfcount_module *smb_perfcount_find_module(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  47 {
  48         struct smb_perfcount_module *entry = modules;
  49 
  50         while (entry) {
  51                 if (strcmp(entry->name, name)==0)
  52                         return entry;
  53 
  54                 entry = entry->next;
  55         }
  56 
  57         return NULL;
  58 }
  59 NTSTATUS smb_register_perfcounter(int interface_version, const char *name,
     /* [<][>][^][v][top][bottom][index][help] */
  60                                   const struct smb_perfcount_handlers *handlers)
  61 {
  62         struct smb_perfcount_module *entry = modules;
  63 
  64         if ((interface_version != SMB_PERFCOUNTER_INTERFACE_VERSION)) {
  65                 DEBUG(0, ("Failed to register perfcount module.\n"
  66                           "The module was compiled against "
  67                           "SMB_PERFCOUNTER_INTERFACE_VERSION %d,\n"
  68                           "current SMB_PERFCOUNTER_INTERFACE_VERSION is %d.\n"
  69                           "Please recompile against the current Samba Version!\n",
  70                           interface_version, SMB_PERFCOUNTER_INTERFACE_VERSION));
  71                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
  72         }
  73 
  74         if (!name || !name[0] || !handlers) {
  75                 DEBUG(0,("smb_register_perfcounter() called with NULL pointer "
  76                         "or empty name!\n"));
  77                 return NT_STATUS_INVALID_PARAMETER;
  78         }
  79 
  80         if (smb_perfcount_find_module(name)) {
  81                 DEBUG(3,("Perfcount Module %s already loaded!\n", name));
  82                 return NT_STATUS_OK;
  83         }
  84 
  85         entry = SMB_XMALLOC_P(struct smb_perfcount_module);
  86         entry->name = smb_xstrdup(name);
  87         entry->handlers = (struct smb_perfcount_handlers*) handlers;
  88 
  89         DLIST_ADD(modules, entry);
  90         DEBUG(3, ("Successfully added perfcounter module '%s'\n", name));
  91         return NT_STATUS_OK;
  92 }
  93 
  94 /****************************************************************************
  95   initialise smb perf counters
  96  ****************************************************************************/
  97 static bool smb_load_perfcount_module(const char *name)
     /* [<][>][^][v][top][bottom][index][help] */
  98 {
  99         char *module_path = NULL;
 100         char *module_name = NULL;
 101         char *module_param = NULL, *p;
 102 
 103         const struct smb_perfcount_module *entry;
 104 
 105         DEBUG(3, ("Initialising perfcounter module [%s]\n", name));
 106 
 107         if (g_smb_perfcount_handlers) {
 108                 DEBUG(3,("Only 1 perfcount handler may be registered in "
 109                         "smb.conf\n"));
 110                 return true;
 111         }
 112 
 113         module_path = smb_xstrdup(name);
 114 
 115         p = strchr_m(module_path, ':');
 116 
 117         if (p) {
 118                 *p = 0;
 119                 module_param = p+1;
 120                 trim_char(module_param, ' ', ' ');
 121         }
 122 
 123         trim_char(module_path, ' ', ' ');
 124 
 125         module_name = smb_xstrdup(module_path);
 126 
 127         if (module_name[0] == '/') {
 128 
 129                 /*
 130                  * Extract the module name from the path. Just use the base
 131                  * name of the last path component.
 132                  */
 133 
 134                 SAFE_FREE(module_name);
 135                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
 136 
 137                 p = strchr_m(module_name, '.');
 138 
 139                 if (p != NULL) {
 140                         *p = '\0';
 141                 }
 142         }
 143 
 144         /* load the perfcounter module */
 145         if((entry = smb_perfcount_find_module(module_name)) ||
 146            (NT_STATUS_IS_OK(smb_probe_module("perfcount", module_path)) &&
 147                 (entry = smb_perfcount_find_module(module_name)))) {
 148 
 149                 DEBUG(3,("Successfully loaded perfcounter module [%s] \n", name));
 150         } else {
 151                 DEBUG(0,("Can't find a perfcounter module [%s]\n",name));
 152                 goto fail;
 153         }
 154 
 155         g_smb_perfcount_handlers = entry->handlers;
 156 
 157         SAFE_FREE(module_path);
 158         SAFE_FREE(module_name);
 159         return True;
 160 
 161  fail:
 162         SAFE_FREE(module_path);
 163         SAFE_FREE(module_name);
 164         return False;
 165 }
 166 
 167 void smb_init_perfcount_data(struct smb_perfcount_data *pcd)
     /* [<][>][^][v][top][bottom][index][help] */
 168 {
 169 
 170         ZERO_STRUCTP(pcd);
 171         pcd->handlers = g_smb_perfcount_handlers;
 172 }
 173 
 174 bool smb_perfcount_init(void)
     /* [<][>][^][v][top][bottom][index][help] */
 175 {
 176         char *perfcount_object;
 177 
 178         perfcount_object = lp_perfcount_module();
 179 
 180         /* don't init */
 181         if (!perfcount_object || !perfcount_object[0])
 182                 return True;
 183 
 184         if (!smb_load_perfcount_module(perfcount_object)) {
 185                 DEBUG(0, ("smbd_load_percount_module failed for %s\n",
 186                         perfcount_object));
 187                 return False;
 188         }
 189 
 190 
 191         return True;
 192 }

/* [<][>][^][v][top][bottom][index][help] */