1*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 2*15db2897SKrishnendu Sadhukhan - Sun Microsystems * CDDL HEADER START 3*15db2897SKrishnendu Sadhukhan - Sun Microsystems * 4*15db2897SKrishnendu Sadhukhan - Sun Microsystems * The contents of this file are subject to the terms of the 5*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Common Development and Distribution License (the "License"). 6*15db2897SKrishnendu Sadhukhan - Sun Microsystems * You may not use this file except in compliance with the License. 7*15db2897SKrishnendu Sadhukhan - Sun Microsystems * 8*15db2897SKrishnendu Sadhukhan - Sun Microsystems * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*15db2897SKrishnendu Sadhukhan - Sun Microsystems * or http://www.opensolaris.org/os/licensing. 10*15db2897SKrishnendu Sadhukhan - Sun Microsystems * See the License for the specific language governing permissions 11*15db2897SKrishnendu Sadhukhan - Sun Microsystems * and limitations under the License. 12*15db2897SKrishnendu Sadhukhan - Sun Microsystems * 13*15db2897SKrishnendu Sadhukhan - Sun Microsystems * When distributing Covered Code, include this CDDL HEADER in each 14*15db2897SKrishnendu Sadhukhan - Sun Microsystems * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*15db2897SKrishnendu Sadhukhan - Sun Microsystems * If applicable, add the following below this CDDL HEADER, with the 16*15db2897SKrishnendu Sadhukhan - Sun Microsystems * fields enclosed by brackets "[]" replaced with your own identifying 17*15db2897SKrishnendu Sadhukhan - Sun Microsystems * information: Portions Copyright [yyyy] [name of copyright owner] 18*15db2897SKrishnendu Sadhukhan - Sun Microsystems * 19*15db2897SKrishnendu Sadhukhan - Sun Microsystems * CDDL HEADER END 20*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 21*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 22*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Copyright (c) 2008-2009, Intel Corporation. 23*15db2897SKrishnendu Sadhukhan - Sun Microsystems * All Rights Reserved. 24*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 25*15db2897SKrishnendu Sadhukhan - Sun Microsystems 26*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdio.h> 27*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <stdlib.h> 28*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <memory.h> 29*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <string.h> 30*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <procfs.h> 31*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <sys/types.h> 32*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <sys/stat.h> 33*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <fcntl.h> 34*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <limits.h> 35*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include <unistd.h> 36*15db2897SKrishnendu Sadhukhan - Sun Microsystems 37*15db2897SKrishnendu Sadhukhan - Sun Microsystems #include "latencytop.h" 38*15db2897SKrishnendu Sadhukhan - Sun Microsystems 39*15db2897SKrishnendu Sadhukhan - Sun Microsystems static GHashTable *proc_table = NULL; /* pid -> char * */ 40*15db2897SKrishnendu Sadhukhan - Sun Microsystems static GHashTable *klog_table = NULL; /* char * -> uint64_t total */ 41*15db2897SKrishnendu Sadhukhan - Sun Microsystems static char klog_filename[PATH_MAX] = DEFAULT_KLOG_FILE; 42*15db2897SKrishnendu Sadhukhan - Sun Microsystems static int klog_level = LT_KLOG_LEVEL_NONE; 43*15db2897SKrishnendu Sadhukhan - Sun Microsystems 44*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void 45*15db2897SKrishnendu Sadhukhan - Sun Microsystems print_proc(void *key, const char *args, FILE *fp) 46*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 47*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "%-8ld \"%s\"\n", (long)key, args); 48*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 49*15db2897SKrishnendu Sadhukhan - Sun Microsystems 50*15db2897SKrishnendu Sadhukhan - Sun Microsystems static void 51*15db2897SKrishnendu Sadhukhan - Sun Microsystems print_stat(const char *key, lt_stat_data_t *log, FILE *fp) 52*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 53*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "%lld, %lld, %lld, %s\n", 54*15db2897SKrishnendu Sadhukhan - Sun Microsystems (long long)log->lt_s_total, 55*15db2897SKrishnendu Sadhukhan - Sun Microsystems (long long)log->lt_s_count, 56*15db2897SKrishnendu Sadhukhan - Sun Microsystems (long long)log->lt_s_max, 57*15db2897SKrishnendu Sadhukhan - Sun Microsystems key); 58*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 59*15db2897SKrishnendu Sadhukhan - Sun Microsystems 60*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 61*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Initialization for kernel logging. 62*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 63*15db2897SKrishnendu Sadhukhan - Sun Microsystems void 64*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_init(void) 65*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 66*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (klog_table != NULL || proc_table != NULL) { 67*15db2897SKrishnendu Sadhukhan - Sun Microsystems return; 68*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 69*15db2897SKrishnendu Sadhukhan - Sun Microsystems 70*15db2897SKrishnendu Sadhukhan - Sun Microsystems klog_table = g_hash_table_new_full(g_str_hash, g_str_equal, 71*15db2897SKrishnendu Sadhukhan - Sun Microsystems (GDestroyNotify)free, (GDestroyNotify)free); 72*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_check_null(klog_table); 73*15db2897SKrishnendu Sadhukhan - Sun Microsystems 74*15db2897SKrishnendu Sadhukhan - Sun Microsystems proc_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, 75*15db2897SKrishnendu Sadhukhan - Sun Microsystems NULL, (GDestroyNotify)free); 76*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_check_null(proc_table); 77*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 78*15db2897SKrishnendu Sadhukhan - Sun Microsystems 79*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 80*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Set log file path. 81*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 82*15db2897SKrishnendu Sadhukhan - Sun Microsystems int 83*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_set_log_file(const char *filename) 84*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 85*15db2897SKrishnendu Sadhukhan - Sun Microsystems FILE *fp; 86*15db2897SKrishnendu Sadhukhan - Sun Microsystems int file_exist; 87*15db2897SKrishnendu Sadhukhan - Sun Microsystems 88*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_assert(strlen(filename) < sizeof (klog_filename)); 89*15db2897SKrishnendu Sadhukhan - Sun Microsystems 90*15db2897SKrishnendu Sadhukhan - Sun Microsystems file_exist = lt_file_exist(filename); 91*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* Test if we can write to the file */ 92*15db2897SKrishnendu Sadhukhan - Sun Microsystems fp = fopen(filename, "a"); 93*15db2897SKrishnendu Sadhukhan - Sun Microsystems 94*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (fp == NULL) { 95*15db2897SKrishnendu Sadhukhan - Sun Microsystems return (-2); 96*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 97*15db2897SKrishnendu Sadhukhan - Sun Microsystems 98*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fclose(fp); 99*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* Don't leave empty file around */ 100*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (!file_exist) { 101*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) unlink(filename); 102*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 103*15db2897SKrishnendu Sadhukhan - Sun Microsystems 104*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) strncpy(klog_filename, filename, 105*15db2897SKrishnendu Sadhukhan - Sun Microsystems sizeof (klog_filename)); 106*15db2897SKrishnendu Sadhukhan - Sun Microsystems 107*15db2897SKrishnendu Sadhukhan - Sun Microsystems return (0); 108*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 109*15db2897SKrishnendu Sadhukhan - Sun Microsystems 110*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 111*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Set log level. 112*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 113*15db2897SKrishnendu Sadhukhan - Sun Microsystems int 114*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_set_log_level(int level) 115*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 116*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (level < 0 || level > (int)LT_KLOG_LEVEL_ALL) { 117*15db2897SKrishnendu Sadhukhan - Sun Microsystems return (-1); 118*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 119*15db2897SKrishnendu Sadhukhan - Sun Microsystems 120*15db2897SKrishnendu Sadhukhan - Sun Microsystems klog_level = level; 121*15db2897SKrishnendu Sadhukhan - Sun Microsystems 122*15db2897SKrishnendu Sadhukhan - Sun Microsystems return (0); 123*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 124*15db2897SKrishnendu Sadhukhan - Sun Microsystems 125*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 126*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Write content to log file. 127*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 128*15db2897SKrishnendu Sadhukhan - Sun Microsystems void 129*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_write(void) 130*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 131*15db2897SKrishnendu Sadhukhan - Sun Microsystems FILE *fp; 132*15db2897SKrishnendu Sadhukhan - Sun Microsystems char buffer[32]; 133*15db2897SKrishnendu Sadhukhan - Sun Microsystems 134*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (klog_level == LT_KLOG_LEVEL_NONE) { 135*15db2897SKrishnendu Sadhukhan - Sun Microsystems return; 136*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 137*15db2897SKrishnendu Sadhukhan - Sun Microsystems 138*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_assert(klog_table != NULL && proc_table != NULL); 139*15db2897SKrishnendu Sadhukhan - Sun Microsystems fp = fopen(klog_filename, "a"); 140*15db2897SKrishnendu Sadhukhan - Sun Microsystems 141*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (fp == NULL) { 142*15db2897SKrishnendu Sadhukhan - Sun Microsystems return; 143*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 144*15db2897SKrishnendu Sadhukhan - Sun Microsystems 145*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_time_str(buffer, sizeof (buffer)); 146*15db2897SKrishnendu Sadhukhan - Sun Microsystems 147*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "# Log generated at %s by %s\n", buffer, TITLE); 148*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "# List of processes\n"); 149*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "PID, CMD\n"); 150*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_foreach(proc_table, (GHFunc)print_proc, fp); 151*15db2897SKrishnendu Sadhukhan - Sun Microsystems 152*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "# Statistics\n"); 153*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fprintf(fp, "TOTAL, COUNT, MAX, PID, KSTACK\n"); 154*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_foreach(klog_table, (GHFunc)print_stat, fp); 155*15db2897SKrishnendu Sadhukhan - Sun Microsystems 156*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) fclose(fp); 157*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 158*15db2897SKrishnendu Sadhukhan - Sun Microsystems 159*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 160*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Clean up. It flushes all log content in memory to log file. 161*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 162*15db2897SKrishnendu Sadhukhan - Sun Microsystems void 163*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_deinit(void) 164*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 165*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (klog_table != NULL) { 166*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_destroy(klog_table); 167*15db2897SKrishnendu Sadhukhan - Sun Microsystems klog_table = NULL; 168*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 169*15db2897SKrishnendu Sadhukhan - Sun Microsystems 170*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (proc_table != NULL) { 171*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_destroy(proc_table); 172*15db2897SKrishnendu Sadhukhan - Sun Microsystems proc_table = NULL; 173*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 174*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 175*15db2897SKrishnendu Sadhukhan - Sun Microsystems 176*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* 177*15db2897SKrishnendu Sadhukhan - Sun Microsystems * Write a kernel stack and its statistics to log file. Only "total" will 178*15db2897SKrishnendu Sadhukhan - Sun Microsystems * be logged, others are internally discarded. 179*15db2897SKrishnendu Sadhukhan - Sun Microsystems */ 180*15db2897SKrishnendu Sadhukhan - Sun Microsystems /* ARGSUSED */ 181*15db2897SKrishnendu Sadhukhan - Sun Microsystems void 182*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_klog_log(int level, pid_t pid, char *stack, 183*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_type_t type, uint64_t value) 184*15db2897SKrishnendu Sadhukhan - Sun Microsystems { 185*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_stat_data_t *entry = NULL; 186*15db2897SKrishnendu Sadhukhan - Sun Microsystems char *psargs; 187*15db2897SKrishnendu Sadhukhan - Sun Microsystems char *str; 188*15db2897SKrishnendu Sadhukhan - Sun Microsystems int str_len; 189*15db2897SKrishnendu Sadhukhan - Sun Microsystems 190*15db2897SKrishnendu Sadhukhan - Sun Microsystems if ((level & klog_level) == 0) { 191*15db2897SKrishnendu Sadhukhan - Sun Microsystems return; 192*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 193*15db2897SKrishnendu Sadhukhan - Sun Microsystems 194*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_assert(klog_table != NULL && proc_table != NULL); 195*15db2897SKrishnendu Sadhukhan - Sun Microsystems psargs = (char *)g_hash_table_lookup(proc_table, 196*15db2897SKrishnendu Sadhukhan - Sun Microsystems LT_INT_TO_POINTER(pid)); 197*15db2897SKrishnendu Sadhukhan - Sun Microsystems 198*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (psargs == NULL) { 199*15db2897SKrishnendu Sadhukhan - Sun Microsystems psargs = lt_get_proc_field(pid, LT_FIELD_PSARGS); 200*15db2897SKrishnendu Sadhukhan - Sun Microsystems 201*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (psargs == NULL) { 202*15db2897SKrishnendu Sadhukhan - Sun Microsystems psargs = lt_get_proc_field(pid, LT_FIELD_FNAME); 203*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 204*15db2897SKrishnendu Sadhukhan - Sun Microsystems 205*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (psargs == NULL) { 206*15db2897SKrishnendu Sadhukhan - Sun Microsystems return; 207*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 208*15db2897SKrishnendu Sadhukhan - Sun Microsystems 209*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_insert(proc_table, 210*15db2897SKrishnendu Sadhukhan - Sun Microsystems LT_INT_TO_POINTER(pid), psargs); 211*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 212*15db2897SKrishnendu Sadhukhan - Sun Microsystems 213*15db2897SKrishnendu Sadhukhan - Sun Microsystems str_len = strlen(stack) + 20; 214*15db2897SKrishnendu Sadhukhan - Sun Microsystems str = lt_malloc(str_len); 215*15db2897SKrishnendu Sadhukhan - Sun Microsystems (void) snprintf(str, str_len, "%ld, \"%s\"", pid, stack); 216*15db2897SKrishnendu Sadhukhan - Sun Microsystems entry = (lt_stat_data_t *)g_hash_table_lookup(klog_table, str); 217*15db2897SKrishnendu Sadhukhan - Sun Microsystems 218*15db2897SKrishnendu Sadhukhan - Sun Microsystems if (entry == NULL) { 219*15db2897SKrishnendu Sadhukhan - Sun Microsystems entry = (lt_stat_data_t *)lt_zalloc(sizeof (lt_stat_data_t)); 220*15db2897SKrishnendu Sadhukhan - Sun Microsystems g_hash_table_insert(klog_table, str, entry); 221*15db2897SKrishnendu Sadhukhan - Sun Microsystems } else { 222*15db2897SKrishnendu Sadhukhan - Sun Microsystems free(str); 223*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 224*15db2897SKrishnendu Sadhukhan - Sun Microsystems 225*15db2897SKrishnendu Sadhukhan - Sun Microsystems lt_update_stat_value(entry, type, value); 226*15db2897SKrishnendu Sadhukhan - Sun Microsystems } 227