1/* 2 * blktrace output analysis: generate a timeline & gather statistics 3 * 4 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com> 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 2 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, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 */ 21#include <errno.h> 22#include <stdio.h> 23#include <string.h> 24#include <unistd.h> 25#include <sys/types.h> 26#include <sys/stat.h> 27#include <sys/time.h> 28#include <sys/resource.h> 29#include <fcntl.h> 30 31#define INLINE_DECLARE 32#include "globals.h" 33 34struct file_info { 35 struct list_head head; 36 FILE *ofp; 37 char *oname; 38}; 39 40struct buf_info { 41 struct list_head head; 42 void *buf; 43}; 44 45LIST_HEAD(files_to_clean); 46LIST_HEAD(all_bufs); 47 48static void clean_files(void) 49{ 50 struct list_head *p, *q; 51 52 list_for_each_safe(p, q, &files_to_clean) { 53 struct stat buf; 54 struct file_info *fip = list_entry(p, struct file_info, head); 55 56 fclose(fip->ofp); 57 if (!stat(fip->oname, &buf) && (buf.st_size == 0)) 58 unlink(fip->oname); 59 60 list_del(&fip->head); 61 free(fip->oname); 62 free(fip); 63 } 64} 65 66static void clean_bufs(void) 67{ 68 struct list_head *p, *q; 69 70 list_for_each_safe(p, q, &all_bufs) { 71 struct buf_info *bip = list_entry(p, struct buf_info, head); 72 73 list_del(&bip->head); 74 free(bip->buf); 75 free(bip); 76 } 77} 78 79#ifndef _ANDROID_ 80/* 81 * Due to the N(devs) parts of a lot of the output features provided 82 * by btt, it will fail opens on large(ish) systems. Here we try to 83 * keep bumping our open file limits, and if those fail, we return NULL. 84 * 85 * Root users will probably be OK with this, others... 86 */ 87static int increase_limit(int resource, rlim_t increase) 88{ 89 struct rlimit rlim; 90 int save_errno = errno; 91 92 if (!getrlimit(resource, &rlim)) { 93 rlim.rlim_cur += increase; 94 if (rlim.rlim_cur >= rlim.rlim_max) 95 rlim.rlim_max = rlim.rlim_cur + increase; 96 97 if (!setrlimit(resource, &rlim)) 98 return 1; 99 } 100 101 errno = save_errno; 102 return 0; 103} 104#endif 105 106static int handle_open_failure(void) 107{ 108 if (errno == ENFILE || errno == EMFILE) 109#ifndef _ANDROID_ 110 return increase_limit(RLIMIT_NOFILE, 16); 111#else 112 return -ENOSYS; 113#endif 114 115 return 0; 116} 117 118void add_file(FILE *fp, char *oname) 119{ 120 struct file_info *fip = malloc(sizeof(*fip)); 121 122 fip->ofp = fp; 123 fip->oname = oname; 124 list_add_tail(&fip->head, &files_to_clean); 125} 126 127void add_buf(void *buf) 128{ 129 struct buf_info *bip = malloc(sizeof(*bip)); 130 131 bip->buf = buf; 132 list_add_tail(&bip->head, &all_bufs); 133} 134 135void clean_allocs(void) 136{ 137 clean_files(); 138 clean_bufs(); 139} 140 141char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens) 142{ 143 if (dip->devmap) 144 snprintf(pad, len, "%s", dip->devmap); 145 else if (add_parens) 146 snprintf(pad, len, "(%3d,%3d)", 147 MAJOR(dip->device), MINOR(dip->device)); 148 else 149 snprintf(pad, len, "%d,%d", 150 MAJOR(dip->device), MINOR(dip->device)); 151 152 return pad; 153} 154 155FILE *my_fopen(const char *path, const char *mode) 156{ 157 FILE *fp; 158 159 do { 160 fp = fopen(path, mode); 161 } while (fp == NULL && handle_open_failure()); 162 163 return fp; 164} 165 166int my_open(const char *path, int flags) 167{ 168 int fd; 169 170 do { 171 fd = open(path, flags); 172 } while (fd < 0 && handle_open_failure()); 173 174 return fd; 175} 176 177void dbg_ping(void) {} 178