LCOV - code coverage report
Current view: top level - source3/smbd - perfcount.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 10 74 13.5 %
Date: 2024-06-13 04:01:37 Functions: 2 5 40.0 %

          Line data    Source code
       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             : #include "smbd/smbd.h"
      23             : 
      24             : static struct smb_perfcount_handlers *g_smb_perfcount_handlers = NULL;
      25             : 
      26             : struct smb_perfcount_module {
      27             :         char *name;
      28             :         struct smb_perfcount_handlers *handlers;
      29             :         struct smb_perfcount_module *prev, *next;
      30             : };
      31             : 
      32             : struct smb_perfcount_module *modules = NULL;
      33             : 
      34             : 
      35             : /*
      36             :  * a module is registered before it is actually loaded - keep a list
      37             :  *
      38             :  * @todo - currently perfcount modules are globally configured, so
      39             :  * building the list is not strictly required.
      40             :  * However, its a proven concept in VFS, and is here to allow a
      41             :  * move to eventual per-service perfcount configuration.
      42             :  *
      43             :  * Note many pre-connection statistics are interesting
      44             :  * (e.g. before binding to an individual share).
      45             :  *
      46             :  */
      47           0 : static struct smb_perfcount_module *smb_perfcount_find_module(const char *name)
      48             : {
      49           0 :         struct smb_perfcount_module *entry = modules;
      50             : 
      51           0 :         while (entry) {
      52           0 :                 if (strcmp(entry->name, name)==0)
      53           0 :                         return entry;
      54             : 
      55           0 :                 entry = entry->next;
      56             :         }
      57             : 
      58           0 :         return NULL;
      59             : }
      60           0 : NTSTATUS smb_register_perfcounter(int interface_version, const char *name,
      61             :                                   const struct smb_perfcount_handlers *handlers)
      62             : {
      63           0 :         struct smb_perfcount_module *entry = modules;
      64             : 
      65           0 :         if (interface_version != SMB_PERFCOUNTER_INTERFACE_VERSION) {
      66           0 :                 DEBUG(0, ("Failed to register perfcount module.\n"
      67             :                           "The module was compiled against "
      68             :                           "SMB_PERFCOUNTER_INTERFACE_VERSION %d,\n"
      69             :                           "current SMB_PERFCOUNTER_INTERFACE_VERSION is %d.\n"
      70             :                           "Please recompile against the current Samba Version!\n",
      71             :                           interface_version, SMB_PERFCOUNTER_INTERFACE_VERSION));
      72           0 :                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
      73             :         }
      74             : 
      75           0 :         if (!name || !name[0] || !handlers) {
      76           0 :                 DEBUG(0,("smb_register_perfcounter() called with NULL pointer "
      77             :                         "or empty name!\n"));
      78           0 :                 return NT_STATUS_INVALID_PARAMETER;
      79             :         }
      80             : 
      81           0 :         if (smb_perfcount_find_module(name)) {
      82           0 :                 DEBUG(3,("Perfcount Module %s already loaded!\n", name));
      83           0 :                 return NT_STATUS_OK;
      84             :         }
      85             : 
      86           0 :         entry = SMB_XMALLOC_P(struct smb_perfcount_module);
      87           0 :         entry->name = smb_xstrdup(name);
      88           0 :         entry->handlers = discard_const_p(struct smb_perfcount_handlers, handlers);
      89             : 
      90           0 :         DLIST_ADD(modules, entry);
      91           0 :         DEBUG(3, ("Successfully added perfcounter module '%s'\n", name));
      92           0 :         return NT_STATUS_OK;
      93             : }
      94             : 
      95             : /****************************************************************************
      96             :   initialise smb perf counters
      97             :  ****************************************************************************/
      98           0 : static bool smb_load_perfcount_module(const char *name)
      99             : {
     100           0 :         char *module_path = NULL;
     101           0 :         char *module_name = NULL;
     102           0 :         char *module_param = NULL, *p;
     103             : 
     104             :         const struct smb_perfcount_module *entry;
     105             : 
     106           0 :         DEBUG(3, ("Initialising perfcounter module [%s]\n", name));
     107             : 
     108           0 :         if (g_smb_perfcount_handlers) {
     109           0 :                 DEBUG(3,("Only 1 perfcount handler may be registered in "
     110             :                         "smb.conf\n"));
     111           0 :                 return true;
     112             :         }
     113             : 
     114           0 :         module_path = smb_xstrdup(name);
     115             : 
     116           0 :         p = strchr_m(module_path, ':');
     117             : 
     118           0 :         if (p) {
     119           0 :                 *p = 0;
     120           0 :                 module_param = p+1;
     121           0 :                 trim_char(module_param, ' ', ' ');
     122             :         }
     123             : 
     124           0 :         trim_char(module_path, ' ', ' ');
     125             : 
     126           0 :         module_name = smb_xstrdup(module_path);
     127             : 
     128           0 :         if (module_name[0] == '/') {
     129             : 
     130             :                 /*
     131             :                  * Extract the module name from the path. Just use the base
     132             :                  * name of the last path component.
     133             :                  */
     134             : 
     135           0 :                 SAFE_FREE(module_name);
     136           0 :                 module_name = smb_xstrdup(strrchr_m(module_path, '/')+1);
     137             : 
     138           0 :                 p = strchr_m(module_name, '.');
     139             : 
     140           0 :                 if (p != NULL) {
     141           0 :                         *p = '\0';
     142             :                 }
     143             :         }
     144             : 
     145             :         /* load the perfcounter module */
     146           0 :         if((entry = smb_perfcount_find_module(module_name)) ||
     147           0 :            (NT_STATUS_IS_OK(smb_probe_module_absolute_path(module_path)) &&
     148           0 :                 (entry = smb_perfcount_find_module(module_name)))) {
     149             : 
     150           0 :                 DEBUG(3,("Successfully loaded perfcounter module [%s] \n", name));
     151             :         } else {
     152           0 :                 DEBUG(0,("Can't find a perfcounter module [%s]\n",name));
     153           0 :                 goto fail;
     154             :         }
     155             : 
     156           0 :         g_smb_perfcount_handlers = entry->handlers;
     157             : 
     158           0 :         SAFE_FREE(module_path);
     159           0 :         SAFE_FREE(module_name);
     160           0 :         return True;
     161             : 
     162           0 :  fail:
     163           0 :         SAFE_FREE(module_path);
     164           0 :         SAFE_FREE(module_name);
     165           0 :         return False;
     166             : }
     167             : 
     168        3677 : void smb_init_perfcount_data(struct smb_perfcount_data *pcd)
     169             : {
     170             : 
     171        3677 :         ZERO_STRUCTP(pcd);
     172        3677 :         pcd->handlers = g_smb_perfcount_handlers;
     173        3677 : }
     174             : 
     175        5270 : bool smb_perfcount_init(void)
     176             : {
     177        3626 :         const struct loadparm_substitution *lp_sub =
     178        1644 :                 loadparm_s3_global_substitution();
     179             :         char *perfcount_object;
     180             : 
     181        5270 :         perfcount_object = lp_perfcount_module(talloc_tos(), lp_sub);
     182             : 
     183             :         /* don't init */
     184        5270 :         if (!perfcount_object || !perfcount_object[0])
     185        5270 :                 return True;
     186             : 
     187           0 :         if (!smb_load_perfcount_module(perfcount_object)) {
     188           0 :                 DEBUG(0, ("smbd_load_percount_module failed for %s\n",
     189             :                         perfcount_object));
     190           0 :                 return False;
     191             :         }
     192             : 
     193             : 
     194           0 :         return True;
     195             : }

Generated by: LCOV version 1.13