chiark / gitweb /
6ee355146a3708384893c4a9b7797ef53fcfabd6
[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
36 int main(int argc, char *argv[])
37 {
38         char line[1024];
39         char path[PATH_MAX];
40         FILE *pack;
41         int a;
42         int missing = 0;
43         off_t size;
44         long tsize = 0;
45         uint64_t inode;
46         uint32_t b;
47         uint32_t c;
48         struct stat st;
49         int pagesize = getpagesize();
50
51         if (argc != 2)
52                 snprintf(path, PATH_MAX, "/.readahead");
53         else
54                 snprintf(path, PATH_MAX, "%s", argv[1]);
55
56         pack = fopen(path, "r");
57         if (!pack) {
58                 fprintf(stderr, "Pack file missing\n");
59                 exit(EXIT_FAILURE);
60         }
61
62         if (!(fgets(line, sizeof(line), pack))) {
63                 fprintf(stderr, "Pack file corrupt\n");
64                 exit(EXIT_FAILURE);
65         }
66
67         if (!strstr(line, READAHEAD_PACK_FILE_VERSION)) {
68                 fprintf(stderr, "Pack file version incompatible with this parser\n");
69                 exit(EXIT_FAILURE);
70         }
71
72         if ((a = getc(pack)) == EOF) {
73                 fprintf(stderr, "Pack file corrupt\n");
74                 exit(EXIT_FAILURE);
75         }
76
77         fprintf(stdout, "   pct  sections     size: path\n");
78         fprintf(stdout, "   ===  ========     ====: ====\n");
79
80         while(true) {
81                 int pages = 0;
82                 int sections = 0;
83
84                 if (!fgets(path, sizeof(path), pack))
85                         break; /* done */
86
87                 path[strlen(path)-1] = 0;
88
89                 if (fread(&inode, sizeof(inode), 1, pack) != 1) {
90                         fprintf(stderr, "Pack file corrupt\n");
91                         exit(EXIT_FAILURE);
92                 }
93
94                 while (true) {
95                         if (fread(&b, sizeof(b), 1, pack) != 1  ||
96                             fread(&c, sizeof(c), 1, pack) != 1) {
97                                 fprintf(stderr, "Pack file corrupt\n");
98                                 exit(EXIT_FAILURE);
99                         }
100                         if ((b == 0) && (c == 0))
101                                 break;
102
103                         /* Uncomment this to get all the chunks separately
104                         fprintf(stdout, " %d: %d %d\n", sections, b, c);
105                          */
106
107                         pages += (c - b);
108                         sections++;
109                 }
110
111                 if (stat(path, &st) == 0) {
112                         if (sections == 0)
113                                 size = st.st_size;
114                         else
115                                 size = pages * pagesize;
116
117                         tsize += size;
118
119                         fprintf(stdout, "  %4d%% (%2d) %12ld: %s\n",
120                                 sections ? (int)(size / st.st_size * 100.0) : 100,
121                                 sections ? sections : 1,
122                                 (unsigned long)size,
123                                 path);
124                 } else {
125                         fprintf(stdout, "  %4dp (%2d) %12s: %s (MISSING)\n",
126                                 sections ? pages : -1,
127                                 sections ? sections : 1,
128                                 "???",
129                                 path);
130                         missing++;
131                 }
132
133         }
134
135         fprintf(stdout, "\nHOST:    %s", line);
136         fprintf(stdout, "TYPE:    %c\n", a);
137         fprintf(stdout, "MISSING: %d\n", missing);
138         fprintf(stdout, "TOTAL:   %ld\n", tsize);
139
140         exit(EXIT_SUCCESS);
141 }