📄 reg_perfcount.c
字号:
retval = CounterType; /* First mask out reserved lower 8 bits */ retval = retval & 0xFFFFFF00; retval = retval << 22; retval = retval >> 22; return retval;}/******************************************************************************************************************************************/static uint32 _reg_perfcount_compute_scale(SMB_BIG_INT data){ int scale = 0; if(data == 0) return scale; while(data > 100) { data /= 10; scale--; } while(data < 10) { data *= 10; scale++; } return (uint32)scale;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_get_counter_info(PERF_DATA_BLOCK *block, prs_struct *ps, int CounterIndex, PERF_OBJECT_TYPE *obj, TDB_CONTEXT *names){ TDB_DATA key, data; char buf[PERFCOUNT_MAX_LEN]; size_t dsize, padding; long int data32, dbuf[2]; SMB_BIG_INT data64; uint32 counter_size; obj->counters[obj->NumCounters].DefaultScale = 0; dbuf[0] = dbuf[1] = 0; padding = 0; _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, "type"); data = tdb_fetch(names, key); if(data.dptr == NULL) { DEBUG(3, ("_reg_perfcount_get_counter_info: No type data for counter [%d].\n", CounterIndex)); return False; } memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); obj->counters[obj->NumCounters].CounterType = atoi(buf); DEBUG(10, ("_reg_perfcount_get_counter_info: Got type [%d] for counter [%d].\n", obj->counters[obj->NumCounters].CounterType, CounterIndex)); free(data.dptr); /* Fetch the actual data */ _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, CounterIndex, ""); _reg_perfcount_get_counter_data(key, &data); if(data.dptr == NULL) { DEBUG(3, ("_reg_perfcount_get_counter_info: No counter data for counter [%d].\n", CounterIndex)); return False; } counter_size = _reg_perfcount_get_size_field(obj->counters[obj->NumCounters].CounterType); if(counter_size == PERF_SIZE_DWORD) { dsize = sizeof(data32); memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); data32 = strtol(buf, NULL, 0); if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER) obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale((SMB_BIG_INT)data32); else obj->counters[obj->NumCounters].DefaultScale = 0; dbuf[0] = data32; padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize; } else if(counter_size == PERF_SIZE_LARGE) { dsize = sizeof(data64); memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); data64 = atof(buf); if((obj->counters[obj->NumCounters].CounterType & 0x00000F00) == PERF_TYPE_NUMBER) obj->counters[obj->NumCounters].DefaultScale = _reg_perfcount_compute_scale(data64); else obj->counters[obj->NumCounters].DefaultScale = 0; memcpy((void *)dbuf, (const void *)&data64, dsize); padding = (dsize - (obj->counter_data.ByteLength%dsize)) % dsize; } else /* PERF_SIZE_VARIABLE_LEN */ { dsize = data.dsize; memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); } free(data.dptr); obj->counter_data.ByteLength += dsize + padding; obj->counter_data.data = TALLOC_REALLOC_ARRAY(ps->mem_ctx, obj->counter_data.data, uint8, obj->counter_data.ByteLength - sizeof(uint32)); if(obj->counter_data.data == NULL) return False; if(dbuf[0] != 0 || dbuf[1] != 0) { memcpy((void *)(obj->counter_data.data + (obj->counter_data.ByteLength - (sizeof(uint32) + dsize))), (const void *)dbuf, dsize); } else { /* Handling PERF_SIZE_VARIABLE_LEN */ memcpy((void *)(obj->counter_data.data + (obj->counter_data.ByteLength - (sizeof(uint32) + dsize))), (const void *)buf, dsize); } obj->counters[obj->NumCounters].CounterOffset = obj->counter_data.ByteLength - dsize; if(obj->counters[obj->NumCounters].CounterOffset % dsize != 0) { DEBUG(3,("Improperly aligned counter [%d]\n", obj->NumCounters)); } obj->counters[obj->NumCounters].CounterSize = dsize; return True;}/******************************************************************************************************************************************/PERF_OBJECT_TYPE *_reg_perfcount_find_obj(PERF_DATA_BLOCK *block, int objind){ int i; PERF_OBJECT_TYPE *obj = NULL; for(i = 0; i < block->NumObjectTypes; i++) { if(block->objects[i].ObjectNameTitleIndex == objind) { obj = &(block->objects[i]); } } return obj;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_add_counter(PERF_DATA_BLOCK *block, prs_struct *ps, int num, TDB_DATA data, TDB_CONTEXT *names){ char *begin, *end, *start, *stop; int parent; PERF_OBJECT_TYPE *obj; BOOL success = False; char buf[PERFCOUNT_MAX_LEN]; obj = NULL; memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); begin = index(buf, '['); end = index(buf, ']'); if(begin == NULL || end == NULL) return False; start = begin+1; while(start < end) { stop = index(start, ','); if(stop == NULL) stop = end; *stop = '\0'; parent = atoi(start); obj = _reg_perfcount_find_obj(block, parent); if(obj == NULL) { /* At this point we require that the parent object exist. This can probably be handled better at some later time */ DEBUG(3, ("_reg_perfcount_add_counter: Could not find parent object [%d] for counter [%d].\n", parent, num)); return False; } obj->counters = (PERF_COUNTER_DEFINITION *)TALLOC_REALLOC_ARRAY(ps->mem_ctx, obj->counters, PERF_COUNTER_DEFINITION, obj->NumCounters+1); if(obj->counters == NULL) return False; memset((void *)&(obj->counters[obj->NumCounters]), 0, sizeof(PERF_COUNTER_DEFINITION)); obj->counters[obj->NumCounters].CounterNameTitleIndex=num; obj->counters[obj->NumCounters].CounterHelpTitleIndex=num+1; obj->counters[obj->NumCounters].DetailLevel = PERF_DETAIL_NOVICE; obj->counters[obj->NumCounters].ByteLength = sizeof(PERF_COUNTER_DEFINITION); success = _reg_perfcount_get_counter_info(block, ps, num, obj, names); obj->NumCounters += 1; start = stop + 1; } /* Handle case of Objects/Counters without any counter data, which would suggest that the required instances are not there yet, so change NumInstances from PERF_NO_INSTANCES to 0 */ return True;}/******************************************************************************************************************************************/BOOL _reg_perfcount_get_instance_info(PERF_INSTANCE_DEFINITION *inst, prs_struct *ps, int instId, PERF_OBJECT_TYPE *obj, TDB_CONTEXT *names){ TDB_DATA key, data; char buf[PERFCOUNT_MAX_LEN], temp[PERFCOUNT_MAX_LEN]; wpstring name; int pad; /* First grab the instance data from the data file */ memset(temp, 0, PERFCOUNT_MAX_LEN); snprintf(temp, PERFCOUNT_MAX_LEN, "i%d", instId); _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp); _reg_perfcount_get_counter_data(key, &data); if(data.dptr == NULL) { DEBUG(3, ("_reg_perfcount_get_instance_info: No instance data for instance [%s].\n", buf)); return False; } inst->counter_data.ByteLength = data.dsize + sizeof(inst->counter_data.ByteLength); inst->counter_data.data = TALLOC_REALLOC_ARRAY(ps->mem_ctx, inst->counter_data.data, uint8, data.dsize); if(inst->counter_data.data == NULL) return False; memset(inst->counter_data.data, 0, data.dsize); memcpy(inst->counter_data.data, data.dptr, data.dsize); free(data.dptr); /* Fetch instance name */ memset(temp, 0, PERFCOUNT_MAX_LEN); snprintf(temp, PERFCOUNT_MAX_LEN, "i%dname", instId); _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, obj->ObjectNameTitleIndex, temp); data = tdb_fetch(names, key); if(data.dptr == NULL) { /* Not actually an error, but possibly unintended? -- just logging FYI */ DEBUG(3, ("_reg_perfcount_get_instance_info: No instance name for instance [%s].\n", buf)); inst->NameLength = 0; } else { memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); rpcstr_push((void *)name, buf, sizeof(name), STR_TERMINATE); inst->NameLength = (strlen_w(name) * 2) + 2; inst->data = TALLOC_REALLOC_ARRAY(ps->mem_ctx, inst->data, uint8, inst->NameLength); memcpy(inst->data, name, inst->NameLength); free(data.dptr); } inst->ParentObjectTitleIndex = 0; inst->ParentObjectTitlePointer = 0; inst->UniqueID = PERF_NO_UNIQUE_ID; inst->NameOffset = 6 * sizeof(uint32); inst->ByteLength = inst->NameOffset + inst->NameLength; /* Need to be aligned on a 64-bit boundary here for counter_data */ if((pad = (inst->ByteLength % 8))) { pad = 8 - pad; inst->data = TALLOC_REALLOC_ARRAY(ps->mem_ctx, inst->data, uint8, inst->NameLength + pad); memset(inst->data + inst->NameLength, 0, pad); inst->ByteLength += pad; } return True;}/******************************************************************************************************************************************/BOOL _reg_perfcount_add_instance(PERF_OBJECT_TYPE *obj, prs_struct *ps, int instInd, TDB_CONTEXT *names){ BOOL success; PERF_INSTANCE_DEFINITION *inst; success = False; if(obj->instances == NULL) { obj->instances = TALLOC_REALLOC_ARRAY(ps->mem_ctx, obj->instances, PERF_INSTANCE_DEFINITION, obj->NumInstances); } if(obj->instances == NULL) return False; memset(&(obj->instances[instInd]), 0, sizeof(PERF_INSTANCE_DEFINITION)); inst = &(obj->instances[instInd]); success = _reg_perfcount_get_instance_info(inst, ps, instInd, obj, names); return True;}/******************************************************************************************************************************************/static int _reg_perfcount_assemble_global(PERF_DATA_BLOCK *block, prs_struct *ps, int base_index, TDB_CONTEXT *names){ BOOL success; int i, j, retval = 0; char keybuf[PERFCOUNT_MAX_LEN]; TDB_DATA key, data; for(i = 1; i <= base_index; i++) { j = i*2; _reg_perfcount_make_key(&key, keybuf, PERFCOUNT_MAX_LEN, j, "rel"); data = tdb_fetch(names, key); if(data.dptr != NULL) { if(_reg_perfcount_isparent(data)) success = _reg_perfcount_add_object(block, ps, j, data, names); else if(_reg_perfcount_ischild(data)) success = _reg_perfcount_add_counter(block, ps, j, data, names); else { DEBUG(3, ("Bogus relationship [%s] for counter [%d].\n", data.dptr, j)); success = False; } if(success == False) { DEBUG(3, ("_reg_perfcount_assemble_global: Failed to add new relationship for counter [%d].\n", j)); retval = -1; } free(data.dptr); } else DEBUG(3, ("NULL relationship for counter [%d] using key [%s].\n", j, keybuf)); } return retval;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_get_64(SMB_BIG_UINT *retval, TDB_CONTEXT *tdb, int key_part1, const char *key_part2){ TDB_DATA key, data; char buf[PERFCOUNT_MAX_LEN]; _reg_perfcount_make_key(&key, buf, PERFCOUNT_MAX_LEN, key_part1, key_part2); data = tdb_fetch(tdb, key); if(data.dptr == NULL) { DEBUG(3,("_reg_perfcount_get_64: No data found for key [%s].\n", key.dptr)); return False; } memset(buf, 0, PERFCOUNT_MAX_LEN); memcpy(buf, data.dptr, data.dsize); free(data.dptr); *retval = atof(buf); return True;}/******************************************************************************************************************************************/static BOOL _reg_perfcount_init_data_block_perf(PERF_DATA_BLOCK *block, TDB_CONTEXT *names){ SMB_BIG_UINT PerfFreq, PerfTime, PerfTime100nSec; TDB_CONTEXT *counters; BOOL status = False; const char *fname = counters_directory( DATA_DB ); counters = tdb_open_log(fname, 0, TDB_DEFAULT, O_RDONLY, 0444); if(counters == NULL) { DEBUG(1, ("reg_perfcount_init_data_block_perf: unable to open [%s].\n", fname)); return False; } status = _reg_perfcount_get_64(&PerfFreq, names, 0, "PerfFreq"); if(status == False) { tdb_close(counters); return status; } memcpy((void *)&(block->PerfFreq), (const void *)&PerfFreq, sizeof(PerfFreq)); status = _reg_perfcount_get_64(&PerfTime, counters, 0, "PerfTime"); if(status == False) { tdb_close(counters); return status; } memcpy((void *)&(block->PerfTime), (const void *)&PerfTime, sizeof(PerfTime)); status = _reg_perfcount_get_64(&PerfTime100nSec, counters, 0, "PerfTime100nSec"); if(status == False) { tdb_close(counters); return status; } memcpy((void *)&(block->PerfTime100nSec), (const void *)&PerfTime100nSec, sizeof(PerfTime100nSec)); tdb_close(counters);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -