btt: fixed open in setup_ifile
[blktrace.git] / btt / misc.c
CommitLineData
63eba147
JA
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 */
99bb5ebc 21#include <errno.h>
63eba147
JA
22#include <stdio.h>
23#include <string.h>
99bb5ebc 24#include <unistd.h>
b2ecdd0f
ADB
25#include <sys/types.h>
26#include <sys/stat.h>
99bb5ebc
AB
27#include <sys/time.h>
28#include <sys/resource.h>
e6855475 29#include <fcntl.h>
63eba147
JA
30
31#define INLINE_DECLARE
32#include "globals.h"
33
63eba147
JA
34int in_devices(struct blk_io_trace *t)
35{
36 int i;
37 unsigned int mjr, mnr;
38 char *p = devices;
39
40 if (p == NULL) return 1; /* Allow anything */
41
42 for (;;) {
43 i = sscanf(p, "%u,%u;", &mjr, &mnr);
63eba147
JA
44 if ((mjr == MAJOR(t->device) && (mnr == MINOR(t->device))))
45 return 1;
46
47 p = strchr(p, ';');
48 if (!p)
49 break;
50 p++;
51 }
52
53 return 0;
54}
55
b2ecdd0f
ADB
56void add_file(struct file_info **fipp, FILE *fp, char *oname)
57{
69040794 58 struct file_info *fip = malloc(sizeof(*fip));
b2ecdd0f 59
69040794
AB
60 fip->ofp = fp;
61 fip->oname = oname;
b2ecdd0f
ADB
62 fip->next = *fipp;
63 *fipp = fip;
64}
65
66void clean_files(struct file_info **fipp)
67{
68 struct stat buf;
69 struct file_info *fip;
70
71 while ((fip = *fipp) != NULL) {
72 *fipp = fip->next;
73
74 fclose(fip->ofp);
75 if (!stat(fip->oname, &buf) && (buf.st_size == 0))
76 unlink(fip->oname);
69040794
AB
77
78 free(fip->oname);
b2ecdd0f
ADB
79 free(fip);
80 }
81}
6eb42155 82
69040794
AB
83struct buf_info {
84 struct buf_info *next;
85 void *buf;
86} *all_bufs;
87void add_buf(void *buf)
88{
89 struct buf_info *bip = malloc(sizeof(*bip));
90
91 bip->buf = buf;
92 bip->next = all_bufs;
93 all_bufs = bip;
94}
95
96void clean_bufs(void)
97{
98 struct buf_info *bip;
99
100 while ((bip = all_bufs) != NULL) {
101 all_bufs = bip->next;
102 free(bip->buf);
103 free(bip);
104 }
105}
8b10aae0 106
84a26fcd
AB
107char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens)
108{
109 if (dip->map == NULL) {
110 if (add_parens)
111 snprintf(pad, len, "(%3d,%3d)",
112 MAJOR(dip->device), MINOR(dip->device));
113 else
114 snprintf(pad, len, "%d,%d",
115 MAJOR(dip->device), MINOR(dip->device));
116 }
117 else
118 snprintf(pad, len, "%s", dip->map->device);
119
120 return pad;
121}
122
99bb5ebc
AB
123/*
124 * Due to the N(devs) parts of a lot of the output features provided
125 * by btt, it will fail opens on large(ish) systems. Here we try to
126 * keep bumping our open file limits, and if those fail, we return NULL.
127 *
128 * Root users will probably be OK with this, others...
129 */
e6855475
AB
130static int increase_limit(int resource, rlim_t increase)
131{
132 struct rlimit rlim;
133 int save_errno = errno;
134
135 if (!getrlimit(resource, &rlim)) {
136 rlim.rlim_cur += increase;
137 if (rlim.rlim_cur >= rlim.rlim_max)
138 rlim.rlim_max = rlim.rlim_cur + increase;
139
140 if (!setrlimit(resource, &rlim))
141 return 1;
142 }
143
144 errno = save_errno;
145 return 0;
146}
147
148static int handle_open_failure(void)
149{
150 if (errno == ENFILE || errno == EMFILE)
151 return increase_limit(RLIMIT_NOFILE, 16);
152 return 0;
153}
154
99bb5ebc
AB
155FILE *my_fopen(const char *path, const char *mode)
156{
157 FILE *fp;
158
e6855475 159 do {
99bb5ebc 160 fp = fopen(path, mode);
e6855475 161 } while (fp == NULL && handle_open_failure());
99bb5ebc
AB
162
163 return fp;
164}
165
e6855475
AB
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
6eb42155 177void dbg_ping(void) {}