-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathmrdump_status.c
197 lines (175 loc) · 5.18 KB
/
mrdump_status.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#include <errno.h>
#include <fcntl.h>
#include <linux/fs.h>
#include <memory.h>
#include <stdint.h>
#include <log/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mrdump_user.h>
#define MRDUMP_VERSION_FILE "/sys/module/mrdump/version"
static const char *expdb_devs[] = {
"/dev/block/platform/mtk-msdc.0/11230000.msdc0/by-name/expdb",
"/dev/block/platform/mtk-msdc.0/11230000.MSDC0/by-name/expdb",
NULL
};
#define MRDUMP_OFFSET 3145728
#define MRDUMP_SIG "MRDUMP04"
struct __attribute__((__packed__)) mrdump_cblock_result {
char sig[9];
char status[128];
char log_buf[2048];
};
struct partinfo {
int fd;
uint64_t size;
uint32_t blksize;
};
static int expdb_open(struct partinfo *partinfo)
{
int fd, i;
uint64_t part_size;
uint32_t part_blksize;
memset(partinfo, 0, sizeof(struct partinfo));
for (i = 0; expdb_devs[i] != NULL; i++) {
if ((fd = open(expdb_devs[i], O_RDWR)) < 0) {
ALOGI("%s: open %s failed(%d)", __func__, expdb_devs[i], errno);
continue;
};
if (ioctl(fd, BLKGETSIZE64, &part_size) < 0) {
ALOGE("%s, get expdb partition size fail(%d)", __func__, errno);
close(fd);
return -1;
}
if (ioctl(fd, BLKSSZGET, &part_blksize) < 0) {
ALOGE("%s, get sector size fail(%d)", __func__, errno);
close(fd);
return -1;
}
partinfo->fd = fd;
partinfo->size = part_size;
partinfo->blksize = part_blksize;
return 0;
}
ALOGE("%s: No expdb partition found", __func__);
return -1;
}
int mrdump_is_supported(void)
{
FILE *fp = fopen(MRDUMP_VERSION_FILE, "r");
if (fp != NULL) {
char ver_str[16];
if (fgets(ver_str, sizeof(ver_str), fp) != NULL) {
ALOGI("MT-RADMUMP support version %s", ver_str);
fclose(fp);
return 1;
}
fclose(fp);
return 0;
}
else {
return 0;
}
}
bool mrdump_status_clear(void)
{
struct partinfo partinfo;
if (expdb_open(&partinfo) >= 0) {
if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
ALOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
struct mrdump_cblock_result cblock_result;
if (read(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
ALOGE("%s: Can't read part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
memset(cblock_result.status, 0, sizeof(cblock_result.status));
strcpy(cblock_result.status, "CLEAR");
if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
ALOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
if (write(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
ALOGE("%s: Can't write part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
close(partinfo.fd);
return true;
}
return false;
}
bool mrdump_status_get(struct mrdump_status_result *result)
{
memset(result, 0, sizeof(struct mrdump_status_result));
result->struct_size = sizeof(struct mrdump_status_result);
struct partinfo partinfo;
if (expdb_open(&partinfo) >= 0) {
if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
ALOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
struct mrdump_cblock_result cblock_result;
if (read(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
ALOGE("%s: Can't read part fd %d\n", __func__, partinfo.fd);
close(partinfo.fd);
return false;
}
close(partinfo.fd);
if (strcmp(cblock_result.sig, MRDUMP_SIG) != 0) {
ALOGE("%s: Signature mismatched\n", __func__);
return false;
}
/* Copy/parsing status line */
strlcpy(result->status_line, cblock_result.status, sizeof(result->status_line));
char *saveptr;
cblock_result.status[sizeof(cblock_result.status) - 1] = 0;
char *strval = strtok_r(cblock_result.status, "\n", &saveptr);
if (strval != NULL) {
if (strcmp(strval, "OK") == 0) {
result->status = MRDUMP_STATUS_OK;
result->output = MRDUMP_OUTPUT_NULL;
do {
strval = strtok_r(NULL, "\n", &saveptr);
if (strval != NULL) {
if (strncmp(strval, "OUTPUT:", 7) == 0) {
if (strcmp(strval + 7, "EXT4_DATA") == 0) {
result->output = MRDUMP_OUTPUT_EXT4_DATA;
}
else if (strcmp(strval + 7, "VFAT_INT_STORAGE") == 0) {
result->output = MRDUMP_OUTPUT_VFAT_INT_STORAGE;
}
else {
return false;
}
}
else if (strncmp(strval, "MODE:", 5) == 0) {
strlcpy(result->mode, strval + 5, sizeof(result->mode));
}
}
} while (strval != NULL);
}
else if (strcmp(strval, "NONE") == 0) {
result->status = MRDUMP_STATUS_NONE;
}
else if (strcmp(strval, "CLEAR") == 0) {
result->status = MRDUMP_STATUS_NONE;
}
else {
result->status = MRDUMP_STATUS_FAILED;
}
}
else {
ALOGE("%s: status parsing error \"%s\"\n", __func__, cblock_result.status);
return false;
}
strlcpy(result->log_buf, cblock_result.log_buf, sizeof(result->log_buf));
return true;
}
return false;
}