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