diff options
Diffstat (limited to 'btt/misc.c')
-rw-r--r-- | btt/misc.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/btt/misc.c b/btt/misc.c new file mode 100644 index 0000000..0cd2e98 --- /dev/null +++ b/btt/misc.c @@ -0,0 +1,177 @@ +/* + * blktrace output analysis: generate a timeline & gather statistics + * + * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include <errno.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <fcntl.h> + +#define INLINE_DECLARE +#include "globals.h" + +struct file_info { + struct list_head head; + FILE *ofp; + char *oname; +}; + +struct buf_info { + struct list_head head; + void *buf; +}; + +LIST_HEAD(files_to_clean); +LIST_HEAD(all_bufs); + +static void clean_files(void) +{ + struct list_head *p, *q; + + list_for_each_safe(p, q, &files_to_clean) { + struct stat buf; + struct file_info *fip = list_entry(p, struct file_info, head); + + fclose(fip->ofp); + if (!stat(fip->oname, &buf) && (buf.st_size == 0)) + unlink(fip->oname); + + list_del(&fip->head); + free(fip->oname); + free(fip); + } +} + +static void clean_bufs(void) +{ + struct list_head *p, *q; + + list_for_each_safe(p, q, &all_bufs) { + struct buf_info *bip = list_entry(p, struct buf_info, head); + + list_del(&bip->head); + free(bip->buf); + free(bip); + } +} + +#ifndef _ANDROID_ +/* + * Due to the N(devs) parts of a lot of the output features provided + * by btt, it will fail opens on large(ish) systems. Here we try to + * keep bumping our open file limits, and if those fail, we return NULL. + * + * Root users will probably be OK with this, others... + */ +static int increase_limit(int resource, rlim_t increase) +{ + struct rlimit rlim; + int save_errno = errno; + + if (!getrlimit(resource, &rlim)) { + rlim.rlim_cur += increase; + if (rlim.rlim_cur >= rlim.rlim_max) + rlim.rlim_max = rlim.rlim_cur + increase; + + if (!setrlimit(resource, &rlim)) + return 1; + } + + errno = save_errno; + return 0; +} +#endif + +static int handle_open_failure(void) +{ + if (errno == ENFILE || errno == EMFILE) +#ifndef _ANDROID_ + return increase_limit(RLIMIT_NOFILE, 16); +#else + return -ENOSYS; +#endif + + return 0; +} + +void add_file(FILE *fp, char *oname) +{ + struct file_info *fip = malloc(sizeof(*fip)); + + fip->ofp = fp; + fip->oname = oname; + list_add_tail(&fip->head, &files_to_clean); +} + +void add_buf(void *buf) +{ + struct buf_info *bip = malloc(sizeof(*bip)); + + bip->buf = buf; + list_add_tail(&bip->head, &all_bufs); +} + +void clean_allocs(void) +{ + clean_files(); + clean_bufs(); +} + +char *make_dev_hdr(char *pad, size_t len, struct d_info *dip, int add_parens) +{ + if (dip->devmap) + snprintf(pad, len, "%s", dip->devmap); + else if (add_parens) + snprintf(pad, len, "(%3d,%3d)", + MAJOR(dip->device), MINOR(dip->device)); + else + snprintf(pad, len, "%d,%d", + MAJOR(dip->device), MINOR(dip->device)); + + return pad; +} + +FILE *my_fopen(const char *path, const char *mode) +{ + FILE *fp; + + do { + fp = fopen(path, mode); + } while (fp == NULL && handle_open_failure()); + + return fp; +} + +int my_open(const char *path, int flags) +{ + int fd; + + do { + fd = open(path, flags); + } while (fd < 0 && handle_open_failure()); + + return fd; +} + +void dbg_ping(void) {} |