chiark / gitweb /
readahead: merge three binaries into one
[elogind.git] / src / readahead / readahead-analyze.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2012 Auke Kok <auke-jan.h.kok@intel.com>
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <stdbool.h>
26 #include <unistd.h>
27 #include <inttypes.h>
28 #include <linux/limits.h>
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <string.h>
32
33 #include "readahead-common.h"
34
35 int main_analyze(const char *pack_path)
36 {
37         char line[1024];
38         char path[PATH_MAX];
39         FILE *pack;
40         int a;
41         int missing = 0;
42         off_t size;
43         long tsize = 0;
44         uint64_t inode;
45         uint32_t b;
46         uint32_t c;
47         struct stat st;
48         int pagesize = getpagesize();
49
50         if (!pack_path)
51                 pack_path = "/.readahead";
52
53         pack = fopen(pack_path, "r");
54         if (!pack) {
55                 fprintf(stderr, "Pack file missing\n");
56                 return EXIT_FAILURE;
57         }
58
59         if (!(fgets(line, sizeof(line), pack))) {
60                 fprintf(stderr, "Pack file corrupt\n");
61                 return EXIT_FAILURE;
62         }
63
64         if (!strstr(line, READAHEAD_PACK_FILE_VERSION)) {
65                 fprintf(stderr, "Pack file version incompatible with this parser\n");
66                 return EXIT_FAILURE;
67         }
68
69         if ((a = getc(pack)) == EOF) {
70                 fprintf(stderr, "Pack file corrupt\n");
71                 return EXIT_FAILURE;
72         }
73
74         fprintf(stdout, "   pct  sections     size: path\n");
75         fprintf(stdout, "   ===  ========     ====: ====\n");
76
77         while(true) {
78                 int pages = 0;
79                 int sections = 0;
80
81                 if (!fgets(path, sizeof(path), pack))
82                         break; /* done */
83
84                 path[strlen(path)-1] = 0;
85
86                 if (fread(&inode, sizeof(inode), 1, pack) != 1) {
87                         fprintf(stderr, "Pack file corrupt\n");
88                         return EXIT_FAILURE;
89                 }
90
91                 while (true) {
92                         if (fread(&b, sizeof(b), 1, pack) != 1  ||
93                             fread(&c, sizeof(c), 1, pack) != 1) {
94                                 fprintf(stderr, "Pack file corrupt\n");
95                                 return EXIT_FAILURE;
96                         }
97                         if ((b == 0) && (c == 0))
98                                 break;
99
100                         /* Uncomment this to get all the chunks separately
101                         fprintf(stdout, " %d: %d %d\n", sections, b, c);
102                          */
103
104                         pages += (c - b);
105                         sections++;
106                 }
107
108                 if (stat(path, &st) == 0) {
109                         if (sections == 0)
110                                 size = st.st_size;
111                         else
112                                 size = pages * pagesize;
113
114                         tsize += size;
115
116                         fprintf(stdout, "  %4d%% (%2d) %12ld: %s\n",
117                                 sections ? (int)(size / st.st_size * 100.0) : 100,
118                                 sections ? sections : 1,
119                                 (unsigned long)size,
120                                 path);
121                 } else {
122                         fprintf(stdout, "  %4dp (%2d) %12s: %s (MISSING)\n",
123                                 sections ? pages : -1,
124                                 sections ? sections : 1,
125                                 "???",
126                                 path);
127                         missing++;
128                 }
129
130         }
131
132         fprintf(stdout, "\nHOST:    %s", line);
133         fprintf(stdout, "TYPE:    %c\n", a);
134         fprintf(stdout, "MISSING: %d\n", missing);
135         fprintf(stdout, "TOTAL:   %ld\n", tsize);
136
137         return EXIT_SUCCESS;
138 }