Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/profile/profile.c

    r740 r988  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33   store smbd profiling information in shared memory
     
    99   the Free Software Foundation; either version 3 of the License, or
    1010   (at your option) any later version.
    11    
     11
    1212   This program is distributed in the hope that it will be useful,
    1313   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1414   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1515   GNU General Public License for more details.
    16    
     16
    1717   You should have received a copy of the GNU General Public License
    1818   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2323#include "system/shmem.h"
    2424#include "system/filesys.h"
     25#include "system/time.h"
    2526#include "messages.h"
    2627#include "smbprofile.h"
    27 
    28 #ifdef WITH_PROFILE
    29 #define IPC_PERMS ((S_IRUSR | S_IWUSR) | S_IRGRP | S_IROTH)
    30 #endif /* WITH_PROFILE */
    31 
    32 #ifdef WITH_PROFILE
    33 static int shm_id;
    34 static bool read_only;
     28#include "lib/tdb_wrap/tdb_wrap.h"
     29#include <tevent.h>
     30#include "../lib/crypto/crypto.h"
     31
     32#ifdef HAVE_SYS_RESOURCE_H
     33#include <sys/resource.h>
    3534#endif
    3635
    37 struct profile_header *profile_h;
    3836struct profile_stats *profile_p;
    39 
    40 bool do_profile_flag = False;
    41 bool do_profile_times = False;
     37struct smbprofile_global_state smbprofile_state;
    4238
    4339/****************************************************************************
     
    4642void set_profile_level(int level, struct server_id src)
    4743{
    48 #ifdef WITH_PROFILE
     44        SMB_ASSERT(smbprofile_state.internal.db != NULL);
     45
    4946        switch (level) {
    5047        case 0:         /* turn off profiling */
    51                 do_profile_flag = False;
    52                 do_profile_times = False;
     48                smbprofile_state.config.do_count = false;
     49                smbprofile_state.config.do_times = false;
    5350                DEBUG(1,("INFO: Profiling turned OFF from pid %d\n",
    5451                         (int)procid_to_pid(&src)));
    5552                break;
    5653        case 1:         /* turn on counter profiling only */
    57                 do_profile_flag = True;
    58                 do_profile_times = False;
     54                smbprofile_state.config.do_count = true;
     55                smbprofile_state.config.do_times = false;
    5956                DEBUG(1,("INFO: Profiling counts turned ON from pid %d\n",
    6057                         (int)procid_to_pid(&src)));
    6158                break;
    6259        case 2:         /* turn on complete profiling */
    63                 do_profile_flag = True;
    64                 do_profile_times = True;
     60                smbprofile_state.config.do_count = true;
     61                smbprofile_state.config.do_times = true;
    6562                DEBUG(1,("INFO: Full profiling turned ON from pid %d\n",
    6663                         (int)procid_to_pid(&src)));
    6764                break;
    6865        case 3:         /* reset profile values */
    69                 memset((char *)profile_p, 0, sizeof(*profile_p));
     66                ZERO_STRUCT(profile_p->values);
     67                tdb_wipe_all(smbprofile_state.internal.db->tdb);
    7068                DEBUG(1,("INFO: Profiling values cleared from pid %d\n",
    7169                         (int)procid_to_pid(&src)));
    7270                break;
    7371        }
    74 #else /* WITH_PROFILE */
    75         DEBUG(1,("INFO: Profiling support unavailable in this build.\n"));
    76 #endif /* WITH_PROFILE */
    77 }
    78 
    79 #ifdef WITH_PROFILE
     72}
    8073
    8174/****************************************************************************
     
    10396****************************************************************************/
    10497static void reqprofile_message(struct messaging_context *msg_ctx,
    105                                void *private_data, 
    106                                uint32_t msg_type, 
     98                               void *private_data,
     99                               uint32_t msg_type,
    107100                               struct server_id src,
    108101                               DATA_BLOB *data)
     
    110103        int level;
    111104
    112 #ifdef WITH_PROFILE
    113         level = 1 + (do_profile_flag?2:0) + (do_profile_times?4:0);
    114 #else
    115         level = 0;
    116 #endif
     105        level = 1;
     106        if (smbprofile_state.config.do_count) {
     107                level += 2;
     108        }
     109        if (smbprofile_state.config.do_times) {
     110                level += 4;
     111        }
     112
    117113        DEBUG(1,("INFO: Received REQ_PROFILELEVEL message from PID %u\n",
    118114                 (unsigned int)procid_to_pid(&src)));
    119115        messaging_send_buf(msg_ctx, src, MSG_PROFILELEVEL,
    120                            (uint8 *)&level, sizeof(level));
     116                           (uint8_t *)&level, sizeof(level));
    121117}
    122118
     
    126122bool profile_setup(struct messaging_context *msg_ctx, bool rdonly)
    127123{
    128         struct shmid_ds shm_ds;
    129 
    130         read_only = rdonly;
    131 
    132  again:
    133         /* try to use an existing key */
    134         shm_id = shmget(PROF_SHMEM_KEY, 0, 0);
    135        
    136         /* if that failed then create one. There is a race condition here
    137            if we are running from inetd. Bad luck. */
    138         if (shm_id == -1) {
    139                 if (read_only) return False;
    140                 shm_id = shmget(PROF_SHMEM_KEY, sizeof(*profile_h),
    141                                 IPC_CREAT | IPC_EXCL | IPC_PERMS);
    142         }
    143        
    144         if (shm_id == -1) {
    145                 DEBUG(0,("Can't create or use IPC area. Error was %s\n",
    146                          strerror(errno)));
    147                 return False;
    148         }   
    149        
    150        
    151         profile_h = (struct profile_header *)shmat(shm_id, 0,
    152                                                    read_only?SHM_RDONLY:0);
    153         if ((long)profile_h == -1) {
    154                 DEBUG(0,("Can't attach to IPC area. Error was %s\n",
    155                          strerror(errno)));
    156                 return False;
    157         }
    158 
    159         /* find out who created this memory area */
    160         if (shmctl(shm_id, IPC_STAT, &shm_ds) != 0) {
    161                 DEBUG(0,("ERROR shmctl : can't IPC_STAT. Error was %s\n",
    162                          strerror(errno)));
    163                 return False;
    164         }
    165 
    166         if (shm_ds.shm_perm.cuid != sec_initial_uid() ||
    167             shm_ds.shm_perm.cgid != sec_initial_gid()) {
    168                 DEBUG(0,("ERROR: we did not create the shmem "
    169                          "(owned by another user, uid %u, gid %u)\n",
    170                          shm_ds.shm_perm.cuid,
    171                          shm_ds.shm_perm.cgid));
    172                 return False;
    173         }
    174 
    175         if (shm_ds.shm_segsz != sizeof(*profile_h)) {
    176                 DEBUG(0,("WARNING: profile size is %d (expected %d). Deleting\n",
    177                          (int)shm_ds.shm_segsz, (int)sizeof(*profile_h)));
    178                 if (shmctl(shm_id, IPC_RMID, &shm_ds) == 0) {
    179                         goto again;
    180                 } else {
    181                         return False;
    182                 }
    183         }
    184 
    185         if (!read_only && (shm_ds.shm_nattch == 1)) {
    186                 memset((char *)profile_h, 0, sizeof(*profile_h));
    187                 profile_h->prof_shm_magic = PROF_SHM_MAGIC;
    188                 profile_h->prof_shm_version = PROF_SHM_VERSION;
    189                 DEBUG(3,("Initialised profile area\n"));
    190         }
    191 
    192         profile_p = &profile_h->stats;
     124        unsigned char tmp[16] = {};
     125        MD5_CTX md5;
     126        char *db_name;
     127
     128        if (smbprofile_state.internal.db != NULL) {
     129                return true;
     130        }
     131
     132        db_name = cache_path("smbprofile.tdb");
     133        if (db_name == NULL) {
     134                return false;
     135        }
     136
     137        smbprofile_state.internal.db = tdb_wrap_open(
     138                NULL, db_name, 0,
     139                rdonly ? 0 : TDB_CLEAR_IF_FIRST|TDB_MUTEX_LOCKING,
     140                O_CREAT | (rdonly ? O_RDONLY : O_RDWR), 0644);
     141        if (smbprofile_state.internal.db == NULL) {
     142                return false;
     143        }
     144
    193145        if (msg_ctx != NULL) {
    194146                messaging_register(msg_ctx, NULL, MSG_PROFILE,
     
    197149                                   reqprofile_message);
    198150        }
     151
     152        MD5Init(&md5);
     153
     154        MD5Update(&md5,
     155                  (const uint8_t *)&smbprofile_state.stats.global,
     156                  sizeof(smbprofile_state.stats.global));
     157
     158#define __UPDATE(str) do { \
     159        MD5Update(&md5, (const uint8_t *)str, strlen(str)); \
     160} while(0)
     161#define SMBPROFILE_STATS_START
     162#define SMBPROFILE_STATS_SECTION_START(name, display) do { \
     163        __UPDATE(#name "+" #display); \
     164} while(0);
     165#define SMBPROFILE_STATS_COUNT(name) do { \
     166        __UPDATE(#name "+count"); \
     167} while(0);
     168#define SMBPROFILE_STATS_TIME(name) do { \
     169        __UPDATE(#name "+time"); \
     170} while(0);
     171#define SMBPROFILE_STATS_BASIC(name) do { \
     172        __UPDATE(#name "+count"); \
     173        __UPDATE(#name "+time"); \
     174} while(0);
     175#define SMBPROFILE_STATS_BYTES(name) do { \
     176        __UPDATE(#name "+count"); \
     177        __UPDATE(#name "+time"); \
     178        __UPDATE(#name "+idle"); \
     179        __UPDATE(#name "+bytes"); \
     180} while(0);
     181#define SMBPROFILE_STATS_IOBYTES(name) do { \
     182        __UPDATE(#name "+count"); \
     183        __UPDATE(#name "+time"); \
     184        __UPDATE(#name "+idle"); \
     185        __UPDATE(#name "+inbytes"); \
     186        __UPDATE(#name "+outbytes"); \
     187} while(0);
     188#define SMBPROFILE_STATS_SECTION_END
     189#define SMBPROFILE_STATS_END
     190        SMBPROFILE_STATS_ALL_SECTIONS
     191#undef __UPDATE
     192#undef SMBPROFILE_STATS_START
     193#undef SMBPROFILE_STATS_SECTION_START
     194#undef SMBPROFILE_STATS_COUNT
     195#undef SMBPROFILE_STATS_TIME
     196#undef SMBPROFILE_STATS_BASIC
     197#undef SMBPROFILE_STATS_BYTES
     198#undef SMBPROFILE_STATS_IOBYTES
     199#undef SMBPROFILE_STATS_SECTION_END
     200#undef SMBPROFILE_STATS_END
     201
     202        MD5Final(tmp, &md5);
     203
     204        profile_p = &smbprofile_state.stats.global;
     205
     206        profile_p->magic = BVAL(tmp, 0);
     207        if (profile_p->magic == 0) {
     208                profile_p->magic = BVAL(tmp, 8);
     209        }
     210
    199211        return True;
    200212}
    201213
    202  const char * profile_value_name(enum profile_stats_values val)
    203 {
    204         static const char * valnames[PR_VALUE_MAX + 1] =
    205         {
    206             "smbd_idle",                /* PR_VALUE_SMBD_IDLE */
    207             "syscall_opendir",          /* PR_VALUE_SYSCALL_OPENDIR */
    208             "syscall_readdir",          /* PR_VALUE_SYSCALL_READDIR */
    209             "syscall_seekdir",          /* PR_VALUE_SYSCALL_SEEKDIR */
    210             "syscall_telldir",          /* PR_VALUE_SYSCALL_TELLDIR */
    211             "syscall_rewinddir",        /* PR_VALUE_SYSCALL_REWINDDIR */
    212             "syscall_mkdir",            /* PR_VALUE_SYSCALL_MKDIR */
    213             "syscall_rmdir",            /* PR_VALUE_SYSCALL_RMDIR */
    214             "syscall_closedir",         /* PR_VALUE_SYSCALL_CLOSEDIR */
    215             "syscall_open",             /* PR_VALUE_SYSCALL_OPEN */
    216             "syscall_createfile",       /* PR_VALUE_SYSCALL_CREATEFILE */
    217             "syscall_close",            /* PR_VALUE_SYSCALL_CLOSE */
    218             "syscall_read",             /* PR_VALUE_SYSCALL_READ */
    219             "syscall_pread",            /* PR_VALUE_SYSCALL_PREAD */
    220             "syscall_write",            /* PR_VALUE_SYSCALL_WRITE */
    221             "syscall_pwrite",           /* PR_VALUE_SYSCALL_PWRITE */
    222             "syscall_lseek",            /* PR_VALUE_SYSCALL_LSEEK */
    223             "syscall_sendfile",         /* PR_VALUE_SYSCALL_SENDFILE */
    224             "syscall_recvfile",         /* PR_VALUE_SYSCALL_RECVFILE */
    225             "syscall_rename",           /* PR_VALUE_SYSCALL_RENAME */
    226             "syscall_rename_at",        /* PR_VALUE_SYSCALL_RENAME_AT */
    227             "syscall_fsync",            /* PR_VALUE_SYSCALL_FSYNC */
    228             "syscall_stat",             /* PR_VALUE_SYSCALL_STAT */
    229             "syscall_fstat",            /* PR_VALUE_SYSCALL_FSTAT */
    230             "syscall_lstat",            /* PR_VALUE_SYSCALL_LSTAT */
    231             "syscall_unlink",           /* PR_VALUE_SYSCALL_UNLINK */
    232             "syscall_chmod",            /* PR_VALUE_SYSCALL_CHMOD */
    233             "syscall_fchmod",           /* PR_VALUE_SYSCALL_FCHMOD */
    234             "syscall_chown",            /* PR_VALUE_SYSCALL_CHOWN */
    235             "syscall_fchown",           /* PR_VALUE_SYSCALL_FCHOWN */
    236             "syscall_chdir",            /* PR_VALUE_SYSCALL_CHDIR */
    237             "syscall_getwd",            /* PR_VALUE_SYSCALL_GETWD */
    238             "syscall_ntimes",           /* PR_VALUE_SYSCALL_NTIMES */
    239             "syscall_ftruncate",        /* PR_VALUE_SYSCALL_FTRUNCATE */
    240             "syscall_fallocate",        /* PR_VALUE_SYSCALL_FALLOCATE */
    241             "syscall_fcntl_lock",       /* PR_VALUE_SYSCALL_FCNTL_LOCK */
    242             "syscall_kernel_flock",     /* PR_VALUE_SYSCALL_KERNEL_FLOCK */
    243             "syscall_linux_setlease",   /* PR_VALUE_SYSCALL_LINUX_SETLEASE */
    244             "syscall_fcntl_getlock",    /* PR_VALUE_SYSCALL_FCNTL_GETLOCK */
    245             "syscall_readlink",         /* PR_VALUE_SYSCALL_READLINK */
    246             "syscall_symlink",          /* PR_VALUE_SYSCALL_SYMLINK */
    247             "syscall_link",             /* PR_VALUE_SYSCALL_LINK */
    248             "syscall_mknod",            /* PR_VALUE_SYSCALL_MKNOD */
    249             "syscall_realpath",         /* PR_VALUE_SYSCALL_REALPATH */
    250             "syscall_get_quota",        /* PR_VALUE_SYSCALL_GET_QUOTA */
    251             "syscall_set_quota",        /* PR_VALUE_SYSCALL_SET_QUOTA */
    252             "syscall_get_sd",           /* PR_VALUE_SYSCALL_GET_SD */
    253             "syscall_set_sd",           /* PR_VALUE_SYSCALL_SET_SD */
    254             "syscall_brl_lock",         /* PR_VALUE_SYSCALL_BRL_LOCK */
    255             "syscall_brl_unlock",       /* PR_VALUE_SYSCALL_BRL_UNLOCK */
    256             "syscall_brl_cancel",       /* PR_VALUE_SYSCALL_BRL_CANCEL */
    257             "SMBmkdir",         /* PR_VALUE_SMBMKDIR */
    258             "SMBrmdir",         /* PR_VALUE_SMBRMDIR */
    259             "SMBopen",          /* PR_VALUE_SMBOPEN */
    260             "SMBcreate",        /* PR_VALUE_SMBCREATE */
    261             "SMBclose",         /* PR_VALUE_SMBCLOSE */
    262             "SMBflush",         /* PR_VALUE_SMBFLUSH */
    263             "SMBunlink",        /* PR_VALUE_SMBUNLINK */
    264             "SMBmv",            /* PR_VALUE_SMBMV */
    265             "SMBgetatr",        /* PR_VALUE_SMBGETATR */
    266             "SMBsetatr",        /* PR_VALUE_SMBSETATR */
    267             "SMBread",          /* PR_VALUE_SMBREAD */
    268             "SMBwrite",         /* PR_VALUE_SMBWRITE */
    269             "SMBlock",          /* PR_VALUE_SMBLOCK */
    270             "SMBunlock",        /* PR_VALUE_SMBUNLOCK */
    271             "SMBctemp",         /* PR_VALUE_SMBCTEMP */
    272             "SMBmknew",         /* PR_VALUE_SMBMKNEW */
    273             "SMBcheckpath",     /* PR_VALUE_SMBCHECKPATH */
    274             "SMBexit",          /* PR_VALUE_SMBEXIT */
    275             "SMBlseek",         /* PR_VALUE_SMBLSEEK */
    276             "SMBlockread",              /* PR_VALUE_SMBLOCKREAD */
    277             "SMBwriteunlock",           /* PR_VALUE_SMBWRITEUNLOCK */
    278             "SMBreadbraw",              /* PR_VALUE_SMBREADBRAW */
    279             "SMBreadBmpx",              /* PR_VALUE_SMBREADBMPX */
    280             "SMBreadBs",                /* PR_VALUE_SMBREADBS */
    281             "SMBwritebraw",             /* PR_VALUE_SMBWRITEBRAW */
    282             "SMBwriteBmpx",             /* PR_VALUE_SMBWRITEBMPX */
    283             "SMBwriteBs",               /* PR_VALUE_SMBWRITEBS */
    284             "SMBwritec",                /* PR_VALUE_SMBWRITEC */
    285             "SMBsetattrE",              /* PR_VALUE_SMBSETATTRE */
    286             "SMBgetattrE",              /* PR_VALUE_SMBGETATTRE */
    287             "SMBlockingX",              /* PR_VALUE_SMBLOCKINGX */
    288             "SMBtrans",         /* PR_VALUE_SMBTRANS */
    289             "SMBtranss",        /* PR_VALUE_SMBTRANSS */
    290             "SMBioctl",         /* PR_VALUE_SMBIOCTL */
    291             "SMBioctls",        /* PR_VALUE_SMBIOCTLS */
    292             "SMBcopy",          /* PR_VALUE_SMBCOPY */
    293             "SMBmove",          /* PR_VALUE_SMBMOVE */
    294             "SMBecho",          /* PR_VALUE_SMBECHO */
    295             "SMBwriteclose",    /* PR_VALUE_SMBWRITECLOSE */
    296             "SMBopenX",         /* PR_VALUE_SMBOPENX */
    297             "SMBreadX",         /* PR_VALUE_SMBREADX */
    298             "SMBwriteX",        /* PR_VALUE_SMBWRITEX */
    299             "SMBtrans2",        /* PR_VALUE_SMBTRANS2 */
    300             "SMBtranss2",       /* PR_VALUE_SMBTRANSS2 */
    301             "SMBfindclose",     /* PR_VALUE_SMBFINDCLOSE */
    302             "SMBfindnclose",    /* PR_VALUE_SMBFINDNCLOSE */
    303             "SMBtcon",          /* PR_VALUE_SMBTCON */
    304             "SMBtdis",          /* PR_VALUE_SMBTDIS */
    305             "SMBnegprot",       /* PR_VALUE_SMBNEGPROT */
    306             "SMBsesssetupX",    /* PR_VALUE_SMBSESSSETUPX */
    307             "SMBulogoffX",      /* PR_VALUE_SMBULOGOFFX */
    308             "SMBtconX",         /* PR_VALUE_SMBTCONX */
    309             "SMBdskattr",               /* PR_VALUE_SMBDSKATTR */
    310             "SMBsearch",                /* PR_VALUE_SMBSEARCH */
    311             "SMBffirst",                /* PR_VALUE_SMBFFIRST */
    312             "SMBfunique",               /* PR_VALUE_SMBFUNIQUE */
    313             "SMBfclose",                /* PR_VALUE_SMBFCLOSE */
    314             "SMBnttrans",               /* PR_VALUE_SMBNTTRANS */
    315             "SMBnttranss",              /* PR_VALUE_SMBNTTRANSS */
    316             "SMBntcreateX",             /* PR_VALUE_SMBNTCREATEX */
    317             "SMBntcancel",              /* PR_VALUE_SMBNTCANCEL */
    318             "SMBntrename",              /* PR_VALUE_SMBNTRENAME */
    319             "SMBsplopen",               /* PR_VALUE_SMBSPLOPEN */
    320             "SMBsplwr",                 /* PR_VALUE_SMBSPLWR */
    321             "SMBsplclose",              /* PR_VALUE_SMBSPLCLOSE */
    322             "SMBsplretq",               /* PR_VALUE_SMBSPLRETQ */
    323             "SMBsends",                 /* PR_VALUE_SMBSENDS */
    324             "SMBsendb",                 /* PR_VALUE_SMBSENDB */
    325             "SMBfwdname",               /* PR_VALUE_SMBFWDNAME */
    326             "SMBcancelf",               /* PR_VALUE_SMBCANCELF */
    327             "SMBgetmac",                /* PR_VALUE_SMBGETMAC */
    328             "SMBsendstrt",              /* PR_VALUE_SMBSENDSTRT */
    329             "SMBsendend",               /* PR_VALUE_SMBSENDEND */
    330             "SMBsendtxt",               /* PR_VALUE_SMBSENDTXT */
    331             "SMBinvalid",               /* PR_VALUE_SMBINVALID */
    332             "pathworks_setdir",         /* PR_VALUE_PATHWORKS_SETDIR */
    333             "Trans2_open",              /* PR_VALUE_TRANS2_OPEN */
    334             "Trans2_findfirst",         /* PR_VALUE_TRANS2_FINDFIRST */
    335             "Trans2_findnext",          /* PR_VALUE_TRANS2_FINDNEXT */
    336             "Trans2_qfsinfo",           /* PR_VALUE_TRANS2_QFSINFO */
    337             "Trans2_setfsinfo",         /* PR_VALUE_TRANS2_SETFSINFO */
    338             "Trans2_qpathinfo",         /* PR_VALUE_TRANS2_QPATHINFO */
    339             "Trans2_setpathinfo",       /* PR_VALUE_TRANS2_SETPATHINFO */
    340             "Trans2_qfileinfo",         /* PR_VALUE_TRANS2_QFILEINFO */
    341             "Trans2_setfileinfo",       /* PR_VALUE_TRANS2_SETFILEINFO */
    342             "Trans2_fsctl",             /* PR_VALUE_TRANS2_FSCTL */
    343             "Trans2_ioctl",             /* PR_VALUE_TRANS2_IOCTL */
    344             "Trans2_findnotifyfirst",   /* PR_VALUE_TRANS2_FINDNOTIFYFIRST */
    345             "Trans2_findnotifynext",    /* PR_VALUE_TRANS2_FINDNOTIFYNEXT */
    346             "Trans2_mkdir",             /* PR_VALUE_TRANS2_MKDIR */
    347             "Trans2_session_setup",     /* PR_VALUE_TRANS2_SESSION_SETUP */
    348             "Trans2_get_dfs_referral",  /* PR_VALUE_TRANS2_GET_DFS_REFERRAL */
    349             "Trans2_report_dfs_inconsistancy",  /* PR_VALUE_TRANS2_REPORT_DFS_INCONSISTANCY */
    350             "NT_transact_create",       /* PR_VALUE_NT_TRANSACT_CREATE */
    351             "NT_transact_ioctl",        /* PR_VALUE_NT_TRANSACT_IOCTL */
    352             "NT_transact_set_security_desc",    /* PR_VALUE_NT_TRANSACT_SET_SECURITY_DESC */
    353             "NT_transact_notify_change",/* PR_VALUE_NT_TRANSACT_NOTIFY_CHANGE */
    354             "NT_transact_rename",       /* PR_VALUE_NT_TRANSACT_RENAME */
    355             "NT_transact_query_security_desc",  /* PR_VALUE_NT_TRANSACT_QUERY_SECURITY_DESC */
    356             "NT_transact_get_user_quota",/* PR_VALUE_NT_TRANSACT_GET_USER_QUOTA */
    357             "NT_transact_set_user_quota",/* PR_VALUE_NT_TRANSACT_SET_USER_QUOTA */
    358             "get_nt_acl",               /* PR_VALUE_GET_NT_ACL */
    359             "fget_nt_acl",              /* PR_VALUE_FGET_NT_ACL */
    360             "fset_nt_acl",              /* PR_VALUE_FSET_NT_ACL */
    361             "chmod_acl",                /* PR_VALUE_CHMOD_ACL */
    362             "fchmod_acl",               /* PR_VALUE_FCHMOD_ACL */
    363             "name_release",             /* PR_VALUE_NAME_RELEASE */
    364             "name_refresh",             /* PR_VALUE_NAME_REFRESH */
    365             "name_registration",        /* PR_VALUE_NAME_REGISTRATION */
    366             "node_status",              /* PR_VALUE_NODE_STATUS */
    367             "name_query",               /* PR_VALUE_NAME_QUERY */
    368             "host_announce",            /* PR_VALUE_HOST_ANNOUNCE */
    369             "workgroup_announce",       /* PR_VALUE_WORKGROUP_ANNOUNCE */
    370             "local_master_announce",    /* PR_VALUE_LOCAL_MASTER_ANNOUNCE */
    371             "master_browser_announce",  /* PR_VALUE_MASTER_BROWSER_ANNOUNCE */
    372             "lm_host_announce",         /* PR_VALUE_LM_HOST_ANNOUNCE */
    373             "get_backup_list",          /* PR_VALUE_GET_BACKUP_LIST */
    374             "reset_browser",            /* PR_VALUE_RESET_BROWSER */
    375             "announce_request",         /* PR_VALUE_ANNOUNCE_REQUEST */
    376             "lm_announce_request",      /* PR_VALUE_LM_ANNOUNCE_REQUEST */
    377             "domain_logon",             /* PR_VALUE_DOMAIN_LOGON */
    378             "sync_browse_lists",        /* PR_VALUE_SYNC_BROWSE_LISTS */
    379             "run_elections",            /* PR_VALUE_RUN_ELECTIONS */
    380             "election",                 /* PR_VALUE_ELECTION */
    381             "smb2_negprot",             /* PR_VALUE_SMB2_NEGPROT */
    382             "smb2_sesssetup",           /* PR_VALUE_SMB2_SESSETUP */
    383             "smb2_logoff",              /* PR_VALUE_SMB2_LOGOFF */
    384             "smb2_tcon",                /* PR_VALUE_SMB2_TCON */
    385             "smb2_tdis",                /* PR_VALUE_SMB2_TDIS */
    386             "smb2_create",              /* PR_VALUE_SMB2_CREATE */
    387             "smb2_close",               /* PR_VALUE_SMB2_CLOSE */
    388             "smb2_flush",               /* PR_VALUE_SMB2_FLUSH */
    389             "smb2_read",                /* PR_VALUE_SMB2_READ */
    390             "smb2_write",               /* PR_VALUE_SMB2_WRITE */
    391             "smb2_lock",                /* PR_VALUE_SMB2_LOCK */
    392             "smb2_ioctl",               /* PR_VALUE_SMB2_IOCTL */
    393             "smb2_cancel",              /* PR_VALUE_SMB2_CANCEL */
    394             "smb2_keepalive",           /* PR_VALUE_SMB2_KEEPALIVE */
    395             "smb2_find",                /* PR_VALUE_SMB2_FIND */
    396             "smb2_notify",              /* PR_VALUE_SMB2_NOTIFY */
    397             "smb2_getinfo",             /* PR_VALUE_SMB2_GETINFO */
    398             "smb2_setinfo"              /* PR_VALUE_SMB2_SETINFO */
    399             "smb2_break",               /* PR_VALUE_SMB2_BREAK */
    400             "" /* PR_VALUE_MAX */
    401         };
    402 
    403         SMB_ASSERT(val >= 0);
    404         SMB_ASSERT(val < PR_VALUE_MAX);
    405         return valnames[val];
    406 }
    407 
    408 #endif /* WITH_PROFILE */
     214void smbprofile_dump_setup(struct tevent_context *ev)
     215{
     216        TALLOC_FREE(smbprofile_state.internal.te);
     217        smbprofile_state.internal.ev = ev;
     218}
     219
     220static void smbprofile_dump_timer(struct tevent_context *ev,
     221                                  struct tevent_timer *te,
     222                                  struct timeval current_time,
     223                                  void *private_data)
     224{
     225        smbprofile_dump();
     226}
     227
     228void smbprofile_dump_schedule_timer(void)
     229{
     230        struct timeval tv;
     231
     232        GetTimeOfDay(&tv);
     233        tv.tv_sec += 1;
     234
     235        smbprofile_state.internal.te = tevent_add_timer(
     236                                smbprofile_state.internal.ev,
     237                                smbprofile_state.internal.ev,
     238                                tv,
     239                                smbprofile_dump_timer,
     240                                NULL);
     241}
     242
     243static int profile_stats_parser(TDB_DATA key, TDB_DATA value,
     244                                void *private_data)
     245{
     246        struct profile_stats *s = private_data;
     247
     248        if (value.dsize != sizeof(struct profile_stats)) {
     249                *s = (struct profile_stats) {};
     250                return 0;
     251        }
     252
     253        memcpy(s, value.dptr, value.dsize);
     254        if (s->magic != profile_p->magic) {
     255                *s = (struct profile_stats) {};
     256                return 0;
     257        }
     258
     259        return 0;
     260}
     261
     262void smbprofile_dump(void)
     263{
     264        pid_t pid = getpid();
     265        TDB_DATA key = { .dptr = (uint8_t *)&pid, .dsize = sizeof(pid) };
     266        struct profile_stats s = {};
     267        int ret;
     268#ifdef HAVE_GETRUSAGE
     269        struct rusage rself;
     270#endif /* HAVE_GETRUSAGE */
     271
     272        TALLOC_FREE(smbprofile_state.internal.te);
     273
     274        if (smbprofile_state.internal.db == NULL) {
     275                return;
     276        }
     277
     278#ifdef HAVE_GETRUSAGE
     279        ret = getrusage(RUSAGE_SELF, &rself);
     280        if (ret != 0) {
     281                ZERO_STRUCT(rself);
     282        }
     283
     284        profile_p->values.cpu_user_stats.time =
     285                (rself.ru_utime.tv_sec * 1000000) +
     286                rself.ru_utime.tv_usec;
     287        profile_p->values.cpu_system_stats.time =
     288                (rself.ru_stime.tv_sec * 1000000) +
     289                rself.ru_stime.tv_usec;
     290#endif /* HAVE_GETRUSAGE */
     291
     292        ret = tdb_chainlock(smbprofile_state.internal.db->tdb, key);
     293        if (ret != 0) {
     294                return;
     295        }
     296
     297        tdb_parse_record(smbprofile_state.internal.db->tdb,
     298                         key, profile_stats_parser, &s);
     299
     300        smbprofile_stats_accumulate(profile_p, &s);
     301
     302        tdb_store(smbprofile_state.internal.db->tdb, key,
     303                  (TDB_DATA) {
     304                        .dptr = (uint8_t *)profile_p,
     305                        .dsize = sizeof(*profile_p)
     306                  },
     307                  0);
     308
     309        tdb_chainunlock(smbprofile_state.internal.db->tdb, key);
     310        ZERO_STRUCT(profile_p->values);
     311
     312        return;
     313}
     314
     315void smbprofile_cleanup(pid_t pid, pid_t dst)
     316{
     317        TDB_DATA key = { .dptr = (uint8_t *)&pid, .dsize = sizeof(pid) };
     318        struct profile_stats s = {};
     319        struct profile_stats acc = {};
     320        int ret;
     321
     322        if (smbprofile_state.internal.db == NULL) {
     323                return;
     324        }
     325
     326        ret = tdb_chainlock(smbprofile_state.internal.db->tdb, key);
     327        if (ret != 0) {
     328                return;
     329        }
     330        ret = tdb_parse_record(smbprofile_state.internal.db->tdb,
     331                               key, profile_stats_parser, &s);
     332        if (ret == -1) {
     333                tdb_chainunlock(smbprofile_state.internal.db->tdb, key);
     334                return;
     335        }
     336        tdb_delete(smbprofile_state.internal.db->tdb, key);
     337        tdb_chainunlock(smbprofile_state.internal.db->tdb, key);
     338
     339        pid = dst;
     340        ret = tdb_chainlock(smbprofile_state.internal.db->tdb, key);
     341        if (ret != 0) {
     342                return;
     343        }
     344        tdb_parse_record(smbprofile_state.internal.db->tdb,
     345                         key, profile_stats_parser, &acc);
     346
     347        /*
     348         * We may have to fix the disconnect count
     349         * in case the process died
     350         */
     351        s.values.disconnect_stats.count = s.values.connect_stats.count;
     352
     353        smbprofile_stats_accumulate(&acc, &s);
     354
     355        acc.magic = profile_p->magic;
     356        tdb_store(smbprofile_state.internal.db->tdb, key,
     357                  (TDB_DATA) {
     358                        .dptr = (uint8_t *)&acc,
     359                        .dsize = sizeof(acc)
     360                  },
     361                  0);
     362
     363        tdb_chainunlock(smbprofile_state.internal.db->tdb, key);
     364}
     365
     366void smbprofile_stats_accumulate(struct profile_stats *acc,
     367                                 const struct profile_stats *add)
     368{
     369#define SMBPROFILE_STATS_START
     370#define SMBPROFILE_STATS_SECTION_START(name, display)
     371#define SMBPROFILE_STATS_COUNT(name) do { \
     372        acc->values.name##_stats.count += add->values.name##_stats.count; \
     373} while(0);
     374#define SMBPROFILE_STATS_TIME(name) do { \
     375        acc->values.name##_stats.time += add->values.name##_stats.time; \
     376} while(0);
     377#define SMBPROFILE_STATS_BASIC(name) do { \
     378        acc->values.name##_stats.count += add->values.name##_stats.count; \
     379        acc->values.name##_stats.time += add->values.name##_stats.time; \
     380} while(0);
     381#define SMBPROFILE_STATS_BYTES(name) do { \
     382        acc->values.name##_stats.count += add->values.name##_stats.count; \
     383        acc->values.name##_stats.time += add->values.name##_stats.time; \
     384        acc->values.name##_stats.idle += add->values.name##_stats.idle; \
     385        acc->values.name##_stats.bytes += add->values.name##_stats.bytes; \
     386} while(0);
     387#define SMBPROFILE_STATS_IOBYTES(name) do { \
     388        acc->values.name##_stats.count += add->values.name##_stats.count; \
     389        acc->values.name##_stats.time += add->values.name##_stats.time; \
     390        acc->values.name##_stats.idle += add->values.name##_stats.idle; \
     391        acc->values.name##_stats.inbytes += add->values.name##_stats.inbytes; \
     392        acc->values.name##_stats.outbytes += add->values.name##_stats.outbytes; \
     393} while(0);
     394#define SMBPROFILE_STATS_SECTION_END
     395#define SMBPROFILE_STATS_END
     396        SMBPROFILE_STATS_ALL_SECTIONS
     397#undef SMBPROFILE_STATS_START
     398#undef SMBPROFILE_STATS_SECTION_START
     399#undef SMBPROFILE_STATS_COUNT
     400#undef SMBPROFILE_STATS_TIME
     401#undef SMBPROFILE_STATS_BASIC
     402#undef SMBPROFILE_STATS_BYTES
     403#undef SMBPROFILE_STATS_IOBYTES
     404#undef SMBPROFILE_STATS_SECTION_END
     405#undef SMBPROFILE_STATS_END
     406}
     407
     408static int smbprofile_collect_fn(struct tdb_context *tdb,
     409                                 TDB_DATA key, TDB_DATA value,
     410                                 void *private_data)
     411{
     412        struct profile_stats *acc = (struct profile_stats *)private_data;
     413        const struct profile_stats *v;
     414
     415        if (value.dsize != sizeof(struct profile_stats)) {
     416                return 0;
     417        }
     418
     419        v = (const struct profile_stats *)value.dptr;
     420
     421        if (v->magic != profile_p->magic) {
     422                return 0;
     423        }
     424
     425        smbprofile_stats_accumulate(acc, v);
     426        return 0;
     427}
     428
     429void smbprofile_collect(struct profile_stats *stats)
     430{
     431        *stats = (struct profile_stats) {};
     432
     433        if (smbprofile_state.internal.db == NULL) {
     434                return;
     435        }
     436
     437        tdb_traverse_read(smbprofile_state.internal.db->tdb,
     438                          smbprofile_collect_fn, stats);
     439}
Note: See TracChangeset for help on using the changeset viewer.