OLD | NEW |
1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // Implementation of bootstat_log(), part of the Chromium OS 'bootstat' | 5 // Implementation of bootstat_log(), part of the Chromium OS 'bootstat' |
6 // facility. | 6 // facility. |
7 | 7 |
8 #include "bootstat.h" | 8 #include "bootstat.h" |
9 #include "bootstat_test.h" | 9 #include "bootstat_test.h" |
10 | 10 |
11 #include <assert.h> | 11 #include <assert.h> |
| 12 #include <errno.h> |
12 #include <stddef.h> | 13 #include <stddef.h> |
13 #include <stdio.h> | 14 #include <stdio.h> |
| 15 #include <string.h> |
14 | 16 |
15 #include <sys/fcntl.h> | 17 #include <sys/fcntl.h> |
16 #include <sys/param.h> | 18 #include <sys/param.h> |
17 #include <sys/stat.h> | 19 #include <sys/stat.h> |
18 #include <sys/types.h> | 20 #include <sys/types.h> |
19 #include <unistd.h> | 21 #include <unistd.h> |
20 | 22 |
21 // | 23 // |
22 // Default path to directory where output statistics will be stored. | 24 // Variables relating to the directory where output statistics will |
| 25 // be stored. |
23 // | 26 // |
| 27 static char output_directory_buffer[PATH_MAX+1]; |
24 static const char kDefaultOutputDirectoryName[] = "/tmp"; | 28 static const char kDefaultOutputDirectoryName[] = "/tmp"; |
| 29 static const char *output_directory_name = kDefaultOutputDirectoryName; |
| 30 |
| 31 // The longest path we allow to be stored in output_directory_buffer. |
| 32 // The buffer is filled by the snprintf() in append_logdata() (the |
| 33 // format string is "%s/%s-%.*s"). |
| 34 // |
| 35 // The "+ 2" in the formula accounts for '\0' characters counted in |
| 36 // BOOTSTAT_MAX_EVENT_LEN and the 'sizeof' expression. |
| 37 // |
| 38 const int kMaxOutputDirectoryPath = (sizeof(output_directory_buffer) - |
| 39 BOOTSTAT_MAX_EVENT_LEN - sizeof("/uptime-") + 1); |
25 | 40 |
26 // | 41 // |
27 // Paths to the statistics files we snapshot as part of the data to | 42 // Paths to the statistics files we snapshot as part of the data to |
28 // be logged. | 43 // be logged. |
29 // | 44 // |
30 static const char kDefaultUptimeStatisticsFileName[] = "/proc/uptime"; | 45 static const char kDefaultUptimeStatisticsFileName[] = "/proc/uptime"; |
31 | 46 |
32 #if defined (__amd64__) || defined (__x86_64__) || defined (__i386__) | 47 #if defined (__amd64__) || defined (__x86_64__) || defined (__i386__) |
33 static const char kDefaultDiskStatisticsFileName[] = "/sys/block/sda/stat"; | 48 static const char kDefaultDiskStatisticsFileName[] = "/sys/block/sda/stat"; |
34 #elif defined (__arm__) | 49 #elif defined (__arm__) |
35 static const char kDefaultDiskStatisticsFileName[] = "/sys/block/mmcblk0/stat"; | 50 static const char kDefaultDiskStatisticsFileName[] = "/sys/block/mmcblk0/stat"; |
36 #else | 51 #else |
37 #error "unknown processor type?" | 52 #error "unknown processor type?" |
38 #endif | 53 #endif |
39 | 54 |
40 static const char *output_directory_name = kDefaultOutputDirectoryName; | |
41 static const char *uptime_statistics_file_name = | 55 static const char *uptime_statistics_file_name = |
42 kDefaultUptimeStatisticsFileName; | 56 kDefaultUptimeStatisticsFileName; |
43 static const char *disk_statistics_file_name = kDefaultDiskStatisticsFileName; | 57 static const char *disk_statistics_file_name = |
| 58 kDefaultDiskStatisticsFileName; |
44 | 59 |
45 static void append_logdata(const char* input_path, | 60 static void append_logdata(const char* input_path, |
46 const char* output_name_prefix, | 61 const char* output_name_prefix, |
47 const char* event_name) | 62 const char* event_name) |
48 { | 63 { |
49 const mode_t kFileCreationMode = | 64 const mode_t kFileCreationMode = |
50 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; | 65 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; |
51 char output_path[PATH_MAX]; | 66 char output_path[PATH_MAX]; |
52 char buffer[256]; | 67 char buffer[256]; |
53 ssize_t num_read; | 68 ssize_t num_read; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 } | 106 } |
92 | 107 |
93 | 108 |
94 void bootstat_log(const char* event_name) | 109 void bootstat_log(const char* event_name) |
95 { | 110 { |
96 append_logdata(uptime_statistics_file_name, "uptime", event_name); | 111 append_logdata(uptime_statistics_file_name, "uptime", event_name); |
97 append_logdata(disk_statistics_file_name, "disk", event_name); | 112 append_logdata(disk_statistics_file_name, "disk", event_name); |
98 } | 113 } |
99 | 114 |
100 | 115 |
101 void bootstat_set_output_directory(const char* dirname) | 116 int bootstat_set_output_directory(const char* dirname) |
102 { | 117 { |
103 if (dirname != NULL) | 118 int rv; |
104 output_directory_name = dirname; | 119 char namebuffer[kMaxOutputDirectoryPath + 3]; |
105 else | 120 |
| 121 if (dirname == NULL) { |
106 output_directory_name = kDefaultOutputDirectoryName; | 122 output_directory_name = kDefaultOutputDirectoryName; |
| 123 return 0; |
| 124 } |
| 125 |
| 126 if (strlen(dirname) > kMaxOutputDirectoryPath) { |
| 127 errno = ENAMETOOLONG; |
| 128 return -1; |
| 129 } |
| 130 |
| 131 // We test for "%s/." rather than "%s" as a cheap way to force |
| 132 // euidaccess() to confirm that the path is a directory, in |
| 133 // addition to being writable and executable. |
| 134 // |
| 135 // sprintf() is safe, because we checked strlen() above. |
| 136 sprintf(namebuffer, "%s/.", dirname); |
| 137 rv = euidaccess(namebuffer, W_OK | X_OK); |
| 138 if (rv < 0) { |
| 139 return -1; |
| 140 } |
| 141 |
| 142 strcpy(output_directory_buffer, dirname); |
| 143 output_directory_name = output_directory_buffer; |
| 144 return 0; |
107 } | 145 } |
108 | 146 |
109 | 147 |
110 void bootstat_set_uptime_file_name(const char* filename) | 148 void bootstat_set_uptime_file_name(const char* filename) |
111 { | 149 { |
112 if (filename != NULL) | 150 if (filename != NULL) |
113 uptime_statistics_file_name = filename; | 151 uptime_statistics_file_name = filename; |
114 else | 152 else |
115 uptime_statistics_file_name = kDefaultUptimeStatisticsFileName; | 153 uptime_statistics_file_name = kDefaultUptimeStatisticsFileName; |
116 } | 154 } |
117 | 155 |
118 | 156 |
119 void bootstat_set_disk_file_name(const char* filename) | 157 void bootstat_set_disk_file_name(const char* filename) |
120 { | 158 { |
121 if (filename != NULL) | 159 if (filename != NULL) |
122 disk_statistics_file_name = filename; | 160 disk_statistics_file_name = filename; |
123 else | 161 else |
124 disk_statistics_file_name = kDefaultDiskStatisticsFileName; | 162 disk_statistics_file_name = kDefaultDiskStatisticsFileName; |
125 } | 163 } |
OLD | NEW |