|
|
@@ -0,0 +1,946 @@
|
|
|
1
|
+/* 硬盘温度 */
|
|
|
2
|
+// #include <unistd.h>
|
|
|
3
|
+// #include <stdio.h>
|
|
|
4
|
+// #include <string.h>
|
|
|
5
|
+#include <getopt.h>
|
|
|
6
|
+// #include <unistd.h>
|
|
|
7
|
+// #include <stdlib.h>
|
|
|
8
|
+#include <sys/ioctl.h>
|
|
|
9
|
+#include <linux/hdreg.h>
|
|
|
10
|
+#include <scsi/scsi.h>
|
|
|
11
|
+#include <scsi/sg.h>
|
|
|
12
|
+#include <scsi/scsi_ioctl.h>
|
|
|
13
|
+#include <fcntl.h>
|
|
|
14
|
+
|
|
|
15
|
+#define DEF(X) 1
|
|
|
16
|
+static int debug;
|
|
|
17
|
+
|
|
|
18
|
+#define CPU_TEMP_FILE1 "/sys/class/hwmon/hwmon1/temp3_input"
|
|
|
19
|
+#define CPU_TEMP_FILE2 "/sys/class/therma/temp"
|
|
|
20
|
+
|
|
|
21
|
+int get_cpu_temp(int file_type)
|
|
|
22
|
+{
|
|
|
23
|
+ int cpu_temp;
|
|
|
24
|
+
|
|
|
25
|
+ /* cpu温度获取 */
|
|
|
26
|
+ FILE *fp = fopen(file_type ? CPU_TEMP_FILE1 : CPU_TEMP_FILE2, "r");
|
|
|
27
|
+
|
|
|
28
|
+ if (NULL == fp)
|
|
|
29
|
+ {
|
|
|
30
|
+ printf("open file failed,%s\n", strerror(errno));
|
|
|
31
|
+ }
|
|
|
32
|
+ else
|
|
|
33
|
+ {
|
|
|
34
|
+ // rewind(fp);
|
|
|
35
|
+ fscanf(fp, "%d", &cpu_temp);
|
|
|
36
|
+ fclose(fp);
|
|
|
37
|
+ }
|
|
|
38
|
+
|
|
|
39
|
+ return cpu_temp / 1000;
|
|
|
40
|
+}
|
|
|
41
|
+
|
|
|
42
|
+#if DEF(ATA)
|
|
|
43
|
+typedef unsigned short u16;
|
|
|
44
|
+#define swapb(x) \
|
|
|
45
|
+ ({ \
|
|
|
46
|
+ u16 __x = (x); \
|
|
|
47
|
+ (x) = ((u16)( \
|
|
|
48
|
+ (((u16)(__x) & (u16)0x00ffU) << 8) | \
|
|
|
49
|
+ (((u16)(__x) & (u16)0xff00U) >> 8) )); \
|
|
|
50
|
+ })
|
|
|
51
|
+#define GBUF_SIZE 65535
|
|
|
52
|
+#define DEFAULT_ATTRIBUTE_ID 194
|
|
|
53
|
+#define DEFAULT_ATTRIBUTE_ID2 190
|
|
|
54
|
+#define SBUFF_SIZE 512
|
|
|
55
|
+static char sbuff[SBUFF_SIZE];
|
|
|
56
|
+
|
|
|
57
|
+static int ata_probe(int device)
|
|
|
58
|
+{
|
|
|
59
|
+ if (device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))
|
|
|
60
|
+ {
|
|
|
61
|
+ return 0;
|
|
|
62
|
+ }
|
|
|
63
|
+ else
|
|
|
64
|
+ {
|
|
|
65
|
+ return 1;
|
|
|
66
|
+ }
|
|
|
67
|
+}
|
|
|
68
|
+
|
|
|
69
|
+int ata_enable_smart(int device)
|
|
|
70
|
+{
|
|
|
71
|
+ unsigned char cmd[4] = {WIN_SMART, 0, SMART_ENABLE, 0};
|
|
|
72
|
+ return ioctl(device, HDIO_DRIVE_CMD, cmd);
|
|
|
73
|
+}
|
|
|
74
|
+
|
|
|
75
|
+
|
|
|
76
|
+int ata_get_smart_values(int device, unsigned char *buff)
|
|
|
77
|
+{
|
|
|
78
|
+ unsigned char cmd[516] = {WIN_SMART, 0, SMART_READ_VALUES, 1};
|
|
|
79
|
+ int ret;
|
|
|
80
|
+ ret = ioctl(device, HDIO_DRIVE_CMD, cmd);
|
|
|
81
|
+
|
|
|
82
|
+ if (ret)
|
|
|
83
|
+ {
|
|
|
84
|
+ return ret;
|
|
|
85
|
+ }
|
|
|
86
|
+
|
|
|
87
|
+ memcpy(buff, cmd + 4, 512);
|
|
|
88
|
+ return 0;
|
|
|
89
|
+}
|
|
|
90
|
+
|
|
|
91
|
+static char *ata_model(int device)
|
|
|
92
|
+{
|
|
|
93
|
+ if (device == -1 || ioctl(device, HDIO_GET_IDENTITY, sbuff))
|
|
|
94
|
+ {
|
|
|
95
|
+ return strdup("unknown");
|
|
|
96
|
+ }
|
|
|
97
|
+ else
|
|
|
98
|
+ {
|
|
|
99
|
+ return strdup((char *)((u16 *)sbuff + 27));
|
|
|
100
|
+ }
|
|
|
101
|
+}
|
|
|
102
|
+
|
|
|
103
|
+unsigned char *ata_search_temperature(const unsigned char *smart_data, int attribute_id)
|
|
|
104
|
+{
|
|
|
105
|
+ int i, n;
|
|
|
106
|
+ n = 3;
|
|
|
107
|
+ i = 0;
|
|
|
108
|
+
|
|
|
109
|
+ if (debug)
|
|
|
110
|
+ {
|
|
|
111
|
+ printf("============ ata ============\n");
|
|
|
112
|
+ }
|
|
|
113
|
+
|
|
|
114
|
+ while ((debug || *(smart_data + n) != attribute_id) && i < 30)
|
|
|
115
|
+ {
|
|
|
116
|
+ if (debug && *(smart_data + n))
|
|
|
117
|
+ printf("field(%d)\t = %d\t(0x%02x)\n",
|
|
|
118
|
+ (int)*(smart_data + n),
|
|
|
119
|
+ (int)*(smart_data + n + 3),
|
|
|
120
|
+ *(smart_data + n + 3));
|
|
|
121
|
+
|
|
|
122
|
+ n += 12;
|
|
|
123
|
+ i++;
|
|
|
124
|
+ }
|
|
|
125
|
+
|
|
|
126
|
+ if (i >= 30)
|
|
|
127
|
+ {
|
|
|
128
|
+ return NULL;
|
|
|
129
|
+ }
|
|
|
130
|
+ else
|
|
|
131
|
+ {
|
|
|
132
|
+ return (unsigned char *)(smart_data + n);
|
|
|
133
|
+ }
|
|
|
134
|
+}
|
|
|
135
|
+
|
|
|
136
|
+
|
|
|
137
|
+int ata_get_temperature(int fd)
|
|
|
138
|
+{
|
|
|
139
|
+ unsigned char values[512]/*, thresholds[512]*/;
|
|
|
140
|
+ unsigned char *field;
|
|
|
141
|
+ int i;
|
|
|
142
|
+ unsigned short *p;
|
|
|
143
|
+
|
|
|
144
|
+ if (ata_enable_smart(fd) != 0)
|
|
|
145
|
+ {
|
|
|
146
|
+ printf("ATA S.M.A.R.T. not available!\n");
|
|
|
147
|
+ return -1;
|
|
|
148
|
+ }
|
|
|
149
|
+
|
|
|
150
|
+ if (ata_get_smart_values(fd, values))
|
|
|
151
|
+ {
|
|
|
152
|
+ printf("ATA Enable S.M.A.R.T. err!\n");
|
|
|
153
|
+ return -1;
|
|
|
154
|
+ }
|
|
|
155
|
+
|
|
|
156
|
+ p = (u16 *)values;
|
|
|
157
|
+
|
|
|
158
|
+ for (i = 0; i < 256; i++)
|
|
|
159
|
+ {
|
|
|
160
|
+ swapb(*(p + i));
|
|
|
161
|
+ }
|
|
|
162
|
+
|
|
|
163
|
+ /* get SMART threshold values */
|
|
|
164
|
+ /*
|
|
|
165
|
+ if(get_smart_threshold_values(fd, thresholds)) {
|
|
|
166
|
+ perror("ioctl");
|
|
|
167
|
+ exit(3);
|
|
|
168
|
+ }
|
|
|
169
|
+
|
|
|
170
|
+ p = (u16*)thresholds;
|
|
|
171
|
+ for(i = 0; i < 256; i++) {
|
|
|
172
|
+ swapb(*(p+i));
|
|
|
173
|
+ }
|
|
|
174
|
+ */
|
|
|
175
|
+ /* temperature */
|
|
|
176
|
+ field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);
|
|
|
177
|
+
|
|
|
178
|
+ if (!field)
|
|
|
179
|
+ {
|
|
|
180
|
+ field = ata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);
|
|
|
181
|
+ }
|
|
|
182
|
+
|
|
|
183
|
+ if (field)
|
|
|
184
|
+ {
|
|
|
185
|
+ return *(field + 3);
|
|
|
186
|
+ }
|
|
|
187
|
+ else
|
|
|
188
|
+ {
|
|
|
189
|
+ return -1;
|
|
|
190
|
+ }
|
|
|
191
|
+}
|
|
|
192
|
+#endif
|
|
|
193
|
+
|
|
|
194
|
+
|
|
|
195
|
+#if DEF(SCSI)
|
|
|
196
|
+#define TEMPERATURE_PAGE 0x0d
|
|
|
197
|
+#define CDB_12_HDR_SIZE 14
|
|
|
198
|
+#define CDB_12_MAX_DATA_SIZE 0xffffffff
|
|
|
199
|
+#define CDB_6_HDR_SIZE 14
|
|
|
200
|
+#define CDB_6_MAX_DATA_SIZE 0xff
|
|
|
201
|
+
|
|
|
202
|
+#define DEXCPT_DISABLE 0xf7
|
|
|
203
|
+#define DEXCPT_ENABLE 0x08
|
|
|
204
|
+#define EWASC_ENABLE 0x10
|
|
|
205
|
+#define EWASC_DISABLE 0xef
|
|
|
206
|
+#define GBUF_SIZE 65535
|
|
|
207
|
+#define MODE_DATA_HDR_SIZE 12
|
|
|
208
|
+#define SMART_SUPPORT 0x00
|
|
|
209
|
+
|
|
|
210
|
+struct cdb10hdr
|
|
|
211
|
+{
|
|
|
212
|
+ unsigned int inbufsize;
|
|
|
213
|
+ unsigned int outbufsize;
|
|
|
214
|
+ unsigned int cdb[10];
|
|
|
215
|
+};
|
|
|
216
|
+
|
|
|
217
|
+struct cdb6hdr
|
|
|
218
|
+{
|
|
|
219
|
+ unsigned int inbufsize;
|
|
|
220
|
+ unsigned int outbufsize;
|
|
|
221
|
+ unsigned char cdb[6];
|
|
|
222
|
+};
|
|
|
223
|
+
|
|
|
224
|
+static void scsi_fixstring(unsigned char *s, int bytecount)
|
|
|
225
|
+{
|
|
|
226
|
+ unsigned char *p;
|
|
|
227
|
+ unsigned char *end;
|
|
|
228
|
+ p = s;
|
|
|
229
|
+ end = s + bytecount;
|
|
|
230
|
+
|
|
|
231
|
+ /* strip leading blanks */
|
|
|
232
|
+ while (s != end && *s == ' ')
|
|
|
233
|
+ {
|
|
|
234
|
+ ++s;
|
|
|
235
|
+ }
|
|
|
236
|
+
|
|
|
237
|
+ /* compress internal blanks and strip trailing blanks */
|
|
|
238
|
+ while (s != end && *s)
|
|
|
239
|
+ {
|
|
|
240
|
+ if (*s++ != ' ' || (s != end && *s && *s != ' '))
|
|
|
241
|
+ {
|
|
|
242
|
+ *p++ = *(s - 1);
|
|
|
243
|
+ }
|
|
|
244
|
+ }
|
|
|
245
|
+
|
|
|
246
|
+ /* wipe out trailing garbage */
|
|
|
247
|
+ while (p != end)
|
|
|
248
|
+ {
|
|
|
249
|
+ *p++ = '\0';
|
|
|
250
|
+ }
|
|
|
251
|
+}
|
|
|
252
|
+
|
|
|
253
|
+int scsi_SG_IO(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len, unsigned char *sense,
|
|
|
254
|
+ unsigned char sense_len, int dxfer_direction)
|
|
|
255
|
+{
|
|
|
256
|
+ struct sg_io_hdr io_hdr;
|
|
|
257
|
+ memset(&io_hdr, 0, sizeof(struct sg_io_hdr));
|
|
|
258
|
+ io_hdr.interface_id = 'S';
|
|
|
259
|
+ io_hdr.cmdp = cdb;
|
|
|
260
|
+ io_hdr.cmd_len = cdb_len;
|
|
|
261
|
+ io_hdr.dxfer_len = buffer_len;
|
|
|
262
|
+ io_hdr.dxferp = buffer;
|
|
|
263
|
+ io_hdr.mx_sb_len = sense_len;
|
|
|
264
|
+ io_hdr.sbp = sense;
|
|
|
265
|
+ io_hdr.dxfer_direction = dxfer_direction;
|
|
|
266
|
+ io_hdr.timeout = 3000; /* 3 seconds should be ample */
|
|
|
267
|
+ return ioctl(device, SG_IO, &io_hdr);
|
|
|
268
|
+}
|
|
|
269
|
+
|
|
|
270
|
+int scsi_SEND_COMMAND(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len,
|
|
|
271
|
+ int dxfer_direction)
|
|
|
272
|
+{
|
|
|
273
|
+ unsigned char buf[2048];
|
|
|
274
|
+ unsigned int inbufsize, outbufsize, ret;
|
|
|
275
|
+
|
|
|
276
|
+ switch (dxfer_direction)
|
|
|
277
|
+ {
|
|
|
278
|
+ case SG_DXFER_FROM_DEV:
|
|
|
279
|
+ inbufsize = 0;
|
|
|
280
|
+ outbufsize = buffer_len;
|
|
|
281
|
+ break;
|
|
|
282
|
+
|
|
|
283
|
+ case SG_DXFER_TO_DEV:
|
|
|
284
|
+ inbufsize = buffer_len;
|
|
|
285
|
+ outbufsize = 0;
|
|
|
286
|
+ break;
|
|
|
287
|
+
|
|
|
288
|
+ default:
|
|
|
289
|
+ inbufsize = 0;
|
|
|
290
|
+ outbufsize = 0;
|
|
|
291
|
+ break;
|
|
|
292
|
+ }
|
|
|
293
|
+
|
|
|
294
|
+ memcpy(buf, &inbufsize, sizeof(inbufsize));
|
|
|
295
|
+ memcpy(buf + sizeof(inbufsize), &outbufsize, sizeof(outbufsize));
|
|
|
296
|
+ memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize), cdb, cdb_len);
|
|
|
297
|
+ memcpy(buf + sizeof(inbufsize) + sizeof(outbufsize) + cdb_len, buffer, buffer_len);
|
|
|
298
|
+ ret = ioctl(device, SCSI_IOCTL_SEND_COMMAND, buf);
|
|
|
299
|
+ memcpy(buffer, buf + sizeof(inbufsize) + sizeof(outbufsize), buffer_len);
|
|
|
300
|
+ return ret;
|
|
|
301
|
+}
|
|
|
302
|
+
|
|
|
303
|
+int scsi_command(int device, unsigned char *cdb, int cdb_len, unsigned char *buffer, int buffer_len,
|
|
|
304
|
+ int dxfer_direction)
|
|
|
305
|
+{
|
|
|
306
|
+ static int SG_IO_supported = -1;
|
|
|
307
|
+ int ret;
|
|
|
308
|
+
|
|
|
309
|
+ if (SG_IO_supported == 1)
|
|
|
310
|
+ {
|
|
|
311
|
+ return scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);
|
|
|
312
|
+ }
|
|
|
313
|
+ else if (SG_IO_supported == 0)
|
|
|
314
|
+ {
|
|
|
315
|
+ return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);
|
|
|
316
|
+ }
|
|
|
317
|
+ else
|
|
|
318
|
+ {
|
|
|
319
|
+ ret = scsi_SG_IO(device, cdb, cdb_len, buffer, buffer_len, NULL, 0, dxfer_direction);
|
|
|
320
|
+
|
|
|
321
|
+ if (ret == 0)
|
|
|
322
|
+ {
|
|
|
323
|
+ SG_IO_supported = 1;
|
|
|
324
|
+ return ret;
|
|
|
325
|
+ }
|
|
|
326
|
+ else
|
|
|
327
|
+ {
|
|
|
328
|
+ SG_IO_supported = 0;
|
|
|
329
|
+ return scsi_SEND_COMMAND(device, cdb, cdb_len, buffer, buffer_len, dxfer_direction);
|
|
|
330
|
+ }
|
|
|
331
|
+ }
|
|
|
332
|
+}
|
|
|
333
|
+
|
|
|
334
|
+int scsi_inquiry(int device, unsigned char *buffer)
|
|
|
335
|
+{
|
|
|
336
|
+ unsigned char cdb[6];
|
|
|
337
|
+ memset(cdb, 0, sizeof(cdb));
|
|
|
338
|
+ cdb[0] = INQUIRY;
|
|
|
339
|
+ cdb[4] = 36; /* should be 36 for unsafe devices (like USB mass storage stuff)
|
|
|
340
|
+ * otherwise they can lock up! SPC sections 7.4 and 8.6 */
|
|
|
341
|
+
|
|
|
342
|
+ if (scsi_command(device, cdb, sizeof(cdb), buffer, cdb[4], SG_DXFER_FROM_DEV) != 0)
|
|
|
343
|
+ {
|
|
|
344
|
+ return 1;
|
|
|
345
|
+ }
|
|
|
346
|
+ else
|
|
|
347
|
+ {
|
|
|
348
|
+ scsi_fixstring(buffer + 8, 24);
|
|
|
349
|
+ return 0;
|
|
|
350
|
+ }
|
|
|
351
|
+}
|
|
|
352
|
+
|
|
|
353
|
+unsigned char modesense(int device, unsigned char pagenum, unsigned char *pBuf)
|
|
|
354
|
+{
|
|
|
355
|
+ unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE];
|
|
|
356
|
+ struct cdb6hdr *ioctlhdr;
|
|
|
357
|
+ unsigned char status;
|
|
|
358
|
+ memset(&tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE);
|
|
|
359
|
+ ioctlhdr = (struct cdb6hdr *)&tBuf;
|
|
|
360
|
+ ioctlhdr->inbufsize = 0;
|
|
|
361
|
+ ioctlhdr->outbufsize = 0xff;
|
|
|
362
|
+ ioctlhdr->cdb[0] = MODE_SENSE;
|
|
|
363
|
+ ioctlhdr->cdb[1] = 0x00;
|
|
|
364
|
+ ioctlhdr->cdb[2] = pagenum;
|
|
|
365
|
+ ioctlhdr->cdb[3] = 0x00;
|
|
|
366
|
+ ioctlhdr->cdb[4] = CDB_6_MAX_DATA_SIZE;
|
|
|
367
|
+ ioctlhdr->cdb[5] = 0x00;
|
|
|
368
|
+ status = ioctl(device, 1, &tBuf);
|
|
|
369
|
+ memcpy(pBuf, &tBuf[8], 256);
|
|
|
370
|
+ return status;
|
|
|
371
|
+}
|
|
|
372
|
+
|
|
|
373
|
+unsigned char modeselect(int device, unsigned char pagenum, unsigned char *pBuf)
|
|
|
374
|
+{
|
|
|
375
|
+ struct cdb6hdr *ioctlhdr;
|
|
|
376
|
+ unsigned char tBuf[CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE];
|
|
|
377
|
+ unsigned char status;
|
|
|
378
|
+ memset(&tBuf, 0, CDB_6_MAX_DATA_SIZE + CDB_6_HDR_SIZE);
|
|
|
379
|
+ ioctlhdr = (struct cdb6hdr *)&tBuf;
|
|
|
380
|
+ ioctlhdr->inbufsize = pBuf[0] + 1;
|
|
|
381
|
+ ioctlhdr->outbufsize = 0;
|
|
|
382
|
+ ioctlhdr->cdb[0] = MODE_SELECT;
|
|
|
383
|
+ ioctlhdr->cdb[1] = 0x11;
|
|
|
384
|
+ ioctlhdr->cdb[2] = 0x00;
|
|
|
385
|
+ ioctlhdr->cdb[3] = 0x00;
|
|
|
386
|
+ ioctlhdr->cdb[4] = pBuf[0] + 1;
|
|
|
387
|
+ ioctlhdr->cdb[5] = 0x00;
|
|
|
388
|
+ tBuf[CDB_6_HDR_SIZE + 3] = 0x08;
|
|
|
389
|
+ tBuf[CDB_6_HDR_SIZE + 10] = 0x02;
|
|
|
390
|
+ memcpy(&tBuf[CDB_6_HDR_SIZE + MODE_DATA_HDR_SIZE],
|
|
|
391
|
+ pBuf + MODE_DATA_HDR_SIZE,
|
|
|
392
|
+ pBuf[0] - MODE_DATA_HDR_SIZE + 1);
|
|
|
393
|
+ tBuf[26] &= 0x3f;
|
|
|
394
|
+ status = ioctl(device, 1, &tBuf);
|
|
|
395
|
+ return status;
|
|
|
396
|
+}
|
|
|
397
|
+
|
|
|
398
|
+unsigned char scsi_smart_mode_page1c_handler(int device, unsigned char setting, unsigned char *retval)
|
|
|
399
|
+{
|
|
|
400
|
+ char tBuf[CDB_6_MAX_DATA_SIZE];
|
|
|
401
|
+
|
|
|
402
|
+ if (modesense(device, 0x1c, (unsigned char *)&tBuf) != 0)
|
|
|
403
|
+ {
|
|
|
404
|
+ return 1;
|
|
|
405
|
+ }
|
|
|
406
|
+
|
|
|
407
|
+ switch (setting)
|
|
|
408
|
+ {
|
|
|
409
|
+ case DEXCPT_DISABLE:
|
|
|
410
|
+ tBuf[14] &= 0xf7;
|
|
|
411
|
+ tBuf[15] = 0x04;
|
|
|
412
|
+ break;
|
|
|
413
|
+
|
|
|
414
|
+ case DEXCPT_ENABLE:
|
|
|
415
|
+ tBuf[14] |= 0x08;
|
|
|
416
|
+ break;
|
|
|
417
|
+
|
|
|
418
|
+ case EWASC_ENABLE:
|
|
|
419
|
+ tBuf[14] |= 0x10;
|
|
|
420
|
+ break;
|
|
|
421
|
+
|
|
|
422
|
+ case EWASC_DISABLE:
|
|
|
423
|
+ tBuf[14] &= 0xef;
|
|
|
424
|
+ break;
|
|
|
425
|
+
|
|
|
426
|
+ case SMART_SUPPORT:
|
|
|
427
|
+ *retval = tBuf[14] & 0x08;
|
|
|
428
|
+ return 0;
|
|
|
429
|
+ break;
|
|
|
430
|
+
|
|
|
431
|
+ default:
|
|
|
432
|
+ return 1;
|
|
|
433
|
+ }
|
|
|
434
|
+
|
|
|
435
|
+ if (modeselect(device, 0x1c, (unsigned char *)&tBuf) != 0)
|
|
|
436
|
+ {
|
|
|
437
|
+ return 1;
|
|
|
438
|
+ }
|
|
|
439
|
+
|
|
|
440
|
+ return 0;
|
|
|
441
|
+}
|
|
|
442
|
+
|
|
|
443
|
+unsigned char log_sense(int device, unsigned char pagenum, unsigned char *pBuf)
|
|
|
444
|
+{
|
|
|
445
|
+ struct cdb10hdr *ioctlhdr;
|
|
|
446
|
+ unsigned char tBuf[1024 + CDB_12_HDR_SIZE];
|
|
|
447
|
+ unsigned char status;
|
|
|
448
|
+ memset(&tBuf, 0, 255);
|
|
|
449
|
+ ioctlhdr = (struct cdb10hdr *)tBuf;
|
|
|
450
|
+ ioctlhdr->inbufsize = 0;
|
|
|
451
|
+ ioctlhdr->outbufsize = 1024;
|
|
|
452
|
+ ioctlhdr->cdb[0] = LOG_SENSE;
|
|
|
453
|
+ ioctlhdr->cdb[1] = 0x00;
|
|
|
454
|
+ ioctlhdr->cdb[2] = 0x40 | pagenum;
|
|
|
455
|
+ ioctlhdr->cdb[3] = 0x00;
|
|
|
456
|
+ ioctlhdr->cdb[4] = 0x00;
|
|
|
457
|
+ ioctlhdr->cdb[5] = 0x00;
|
|
|
458
|
+ ioctlhdr->cdb[6] = 0x00;
|
|
|
459
|
+ ioctlhdr->cdb[7] = 0x04;
|
|
|
460
|
+ ioctlhdr->cdb[8] = 0x00;
|
|
|
461
|
+ ioctlhdr->cdb[9] = 0x00;
|
|
|
462
|
+ status = ioctl(device, 1, &tBuf);
|
|
|
463
|
+ memcpy(pBuf, &tBuf[8], 1024);
|
|
|
464
|
+ return status;
|
|
|
465
|
+}
|
|
|
466
|
+
|
|
|
467
|
+static int scsi_probe(int device)
|
|
|
468
|
+{
|
|
|
469
|
+ int bus_num;
|
|
|
470
|
+
|
|
|
471
|
+ if (ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))
|
|
|
472
|
+ {
|
|
|
473
|
+ return 0;
|
|
|
474
|
+ }
|
|
|
475
|
+ else
|
|
|
476
|
+ {
|
|
|
477
|
+ return 1;
|
|
|
478
|
+ }
|
|
|
479
|
+}
|
|
|
480
|
+
|
|
|
481
|
+static char *scsi_model(int device)
|
|
|
482
|
+{
|
|
|
483
|
+ unsigned char buf[36];
|
|
|
484
|
+
|
|
|
485
|
+ if (scsi_inquiry(device, buf) != 0)
|
|
|
486
|
+ {
|
|
|
487
|
+ return strdup("unknown");
|
|
|
488
|
+ }
|
|
|
489
|
+ else
|
|
|
490
|
+ {
|
|
|
491
|
+ return strdup(buf + 8);
|
|
|
492
|
+ }
|
|
|
493
|
+}
|
|
|
494
|
+
|
|
|
495
|
+int scsi_get_temperature(int fd)
|
|
|
496
|
+{
|
|
|
497
|
+ unsigned char buf[1024];
|
|
|
498
|
+ unsigned char smartsupport;
|
|
|
499
|
+ char gBuf[GBUF_SIZE];
|
|
|
500
|
+
|
|
|
501
|
+ if (0 != scsi_smart_mode_page1c_handler(fd, SMART_SUPPORT, &smartsupport))
|
|
|
502
|
+ {
|
|
|
503
|
+ printf("SCSI S.M.A.R.T. not available!\n");
|
|
|
504
|
+ return -1;
|
|
|
505
|
+ }
|
|
|
506
|
+
|
|
|
507
|
+ if (0 != scsi_smart_mode_page1c_handler(fd, DEXCPT_DISABLE, NULL))
|
|
|
508
|
+ {
|
|
|
509
|
+ printf("SCSI Enable S.M.A.R.T. err!\n");
|
|
|
510
|
+ return -1;
|
|
|
511
|
+ }
|
|
|
512
|
+
|
|
|
513
|
+ if (log_sense(fd, TEMPERATURE_PAGE, buf) != 0)
|
|
|
514
|
+ {
|
|
|
515
|
+ printf("SCSI read err!\n");
|
|
|
516
|
+ return -1;
|
|
|
517
|
+ }
|
|
|
518
|
+
|
|
|
519
|
+ return buf[9];
|
|
|
520
|
+}
|
|
|
521
|
+
|
|
|
522
|
+#endif
|
|
|
523
|
+
|
|
|
524
|
+
|
|
|
525
|
+#if DEF(SATA)
|
|
|
526
|
+#ifndef ATA_16
|
|
|
527
|
+/* Values for T10/04-262r7 */
|
|
|
528
|
+#define ATA_16 0x85 /* 16-byte pass-thru */
|
|
|
529
|
+#endif
|
|
|
530
|
+
|
|
|
531
|
+int sata_pass_thru(int device, unsigned char *cmd, unsigned char *buffer)
|
|
|
532
|
+{
|
|
|
533
|
+ unsigned char cdb[16];
|
|
|
534
|
+ unsigned char sense[32];
|
|
|
535
|
+ int dxfer_direction;
|
|
|
536
|
+ int ret;
|
|
|
537
|
+ memset(cdb, 0, sizeof(cdb));
|
|
|
538
|
+ cdb[0] = ATA_16;
|
|
|
539
|
+
|
|
|
540
|
+ if (cmd[3])
|
|
|
541
|
+ {
|
|
|
542
|
+ cdb[1] = (4 << 1); /* PIO Data-in */
|
|
|
543
|
+ cdb[2] = 0x2e; /* no off.line, cc, read from dev, lock count in sector count field */
|
|
|
544
|
+ dxfer_direction = SG_DXFER_FROM_DEV;
|
|
|
545
|
+ }
|
|
|
546
|
+ else
|
|
|
547
|
+ {
|
|
|
548
|
+ cdb[1] = (3 << 1); /* Non-data */
|
|
|
549
|
+ cdb[2] = 0x20; /* cc */
|
|
|
550
|
+ dxfer_direction = SG_DXFER_NONE;
|
|
|
551
|
+ }
|
|
|
552
|
+
|
|
|
553
|
+ cdb[4] = cmd[2];
|
|
|
554
|
+
|
|
|
555
|
+ if (cmd[0] == WIN_SMART)
|
|
|
556
|
+ {
|
|
|
557
|
+ cdb[6] = cmd[3];
|
|
|
558
|
+ cdb[8] = cmd[1];
|
|
|
559
|
+ cdb[10] = 0x4f;
|
|
|
560
|
+ cdb[12] = 0xc2;
|
|
|
561
|
+ }
|
|
|
562
|
+ else
|
|
|
563
|
+ {
|
|
|
564
|
+ cdb[6] = cmd[1];
|
|
|
565
|
+ }
|
|
|
566
|
+
|
|
|
567
|
+ cdb[14] = cmd[0];
|
|
|
568
|
+ ret = scsi_SG_IO(device, cdb, sizeof(cdb), buffer, cmd[3] * 512, sense, sizeof(sense), dxfer_direction);
|
|
|
569
|
+
|
|
|
570
|
+ /* Verify SATA magics */
|
|
|
571
|
+ if (sense[0] != 0x72)
|
|
|
572
|
+ {
|
|
|
573
|
+ return 1;
|
|
|
574
|
+ }
|
|
|
575
|
+ else
|
|
|
576
|
+ {
|
|
|
577
|
+ return ret;
|
|
|
578
|
+ }
|
|
|
579
|
+}
|
|
|
580
|
+
|
|
|
581
|
+void sata_fixstring(unsigned char *s, int bytecount)
|
|
|
582
|
+{
|
|
|
583
|
+ unsigned char *p;
|
|
|
584
|
+ unsigned char *end;
|
|
|
585
|
+ p = s;
|
|
|
586
|
+ end = &s[bytecount & ~1]; /* bytecount must be even */
|
|
|
587
|
+
|
|
|
588
|
+ /* convert from big-endian to host byte order */
|
|
|
589
|
+ for (p = end; p != s;)
|
|
|
590
|
+ {
|
|
|
591
|
+ unsigned short *pp = (unsigned short *)(p -= 2);
|
|
|
592
|
+ *pp = ntohs(*pp);
|
|
|
593
|
+ }
|
|
|
594
|
+
|
|
|
595
|
+ /* strip leading blanks */
|
|
|
596
|
+ while (s != end && *s == ' ')
|
|
|
597
|
+ {
|
|
|
598
|
+ ++s;
|
|
|
599
|
+ }
|
|
|
600
|
+
|
|
|
601
|
+ /* compress internal blanks and strip trailing blanks */
|
|
|
602
|
+ while (s != end && *s)
|
|
|
603
|
+ {
|
|
|
604
|
+ if (*s++ != ' ' || (s != end && *s && *s != ' '))
|
|
|
605
|
+ {
|
|
|
606
|
+ *p++ = *(s - 1);
|
|
|
607
|
+ }
|
|
|
608
|
+ }
|
|
|
609
|
+
|
|
|
610
|
+ /* wipe out trailing garbage */
|
|
|
611
|
+ while (p != end)
|
|
|
612
|
+ {
|
|
|
613
|
+ *p++ = '\0';
|
|
|
614
|
+ }
|
|
|
615
|
+}
|
|
|
616
|
+
|
|
|
617
|
+static int sata_probe(int device)
|
|
|
618
|
+{
|
|
|
619
|
+ int bus_num;
|
|
|
620
|
+ unsigned char cmd[4] = {WIN_IDENTIFY, 0, 0, 1};
|
|
|
621
|
+ unsigned char identify[512];
|
|
|
622
|
+ char buf[36]; /* should be 36 for unsafe devices (like USB mass storage stuff)
|
|
|
623
|
+ otherwise they can lock up! SPC sections 7.4 and 8.6 */
|
|
|
624
|
+
|
|
|
625
|
+ /* SATA disks are difficult to detect as they answer to both ATA and SCSI
|
|
|
626
|
+ commands */
|
|
|
627
|
+
|
|
|
628
|
+ /* First check that the device is accessible through SCSI */
|
|
|
629
|
+ if (ioctl(device, SCSI_IOCTL_GET_BUS_NUMBER, &bus_num))
|
|
|
630
|
+ {
|
|
|
631
|
+ return 0;
|
|
|
632
|
+ }
|
|
|
633
|
+
|
|
|
634
|
+ /* Get SCSI name and verify it starts with "ATA " */
|
|
|
635
|
+ if (scsi_inquiry(device, buf))
|
|
|
636
|
+ {
|
|
|
637
|
+ return 0;
|
|
|
638
|
+ }
|
|
|
639
|
+ else if (strncmp(buf + 8, "ATA ", 4))
|
|
|
640
|
+ {
|
|
|
641
|
+ return 0;
|
|
|
642
|
+ }
|
|
|
643
|
+
|
|
|
644
|
+ /* Verify that it supports ATA pass thru */
|
|
|
645
|
+ if (sata_pass_thru(device, cmd, identify) != 0)
|
|
|
646
|
+ {
|
|
|
647
|
+ return 0;
|
|
|
648
|
+ }
|
|
|
649
|
+ else
|
|
|
650
|
+ {
|
|
|
651
|
+ return 1;
|
|
|
652
|
+ }
|
|
|
653
|
+}
|
|
|
654
|
+
|
|
|
655
|
+int sata_enable_smart(int device)
|
|
|
656
|
+{
|
|
|
657
|
+ unsigned char cmd[4] = {WIN_SMART, 0, SMART_ENABLE, 0};
|
|
|
658
|
+ return sata_pass_thru(device, cmd, NULL);
|
|
|
659
|
+}
|
|
|
660
|
+
|
|
|
661
|
+int sata_get_smart_values(int device, unsigned char *buff)
|
|
|
662
|
+{
|
|
|
663
|
+ unsigned char cmd[4] = {WIN_SMART, 0, SMART_READ_VALUES, 1};
|
|
|
664
|
+ return sata_pass_thru(device, cmd, buff);
|
|
|
665
|
+}
|
|
|
666
|
+
|
|
|
667
|
+static char *sata_model(int device)
|
|
|
668
|
+{
|
|
|
669
|
+ unsigned char cmd[4] = {WIN_IDENTIFY, 0, 0, 1};
|
|
|
670
|
+ unsigned char identify[512];
|
|
|
671
|
+
|
|
|
672
|
+ if (device == -1 || sata_pass_thru(device, cmd, identify))
|
|
|
673
|
+ {
|
|
|
674
|
+ return strdup("unknown");
|
|
|
675
|
+ }
|
|
|
676
|
+ else
|
|
|
677
|
+ {
|
|
|
678
|
+ sata_fixstring(identify + 54, 40);
|
|
|
679
|
+ return strdup(identify + 54);
|
|
|
680
|
+ }
|
|
|
681
|
+}
|
|
|
682
|
+
|
|
|
683
|
+static unsigned char *sata_search_temperature(const unsigned char *smart_data, int attribute_id)
|
|
|
684
|
+{
|
|
|
685
|
+ int i, n;
|
|
|
686
|
+ n = 3;
|
|
|
687
|
+ i = 0;
|
|
|
688
|
+
|
|
|
689
|
+ if (debug)
|
|
|
690
|
+ {
|
|
|
691
|
+ printf("============ sata ============\n");
|
|
|
692
|
+ }
|
|
|
693
|
+
|
|
|
694
|
+ while ((debug || *(smart_data + n) != attribute_id) && i < 30)
|
|
|
695
|
+ {
|
|
|
696
|
+ if (debug && *(smart_data + n))
|
|
|
697
|
+ {
|
|
|
698
|
+ printf("field(%d)\t = %d\t(0x%02x)\n", *(smart_data + n), *(smart_data + n + 3), *(smart_data + n + 3));
|
|
|
699
|
+ }
|
|
|
700
|
+
|
|
|
701
|
+ n += 12;
|
|
|
702
|
+ i++;
|
|
|
703
|
+ }
|
|
|
704
|
+
|
|
|
705
|
+ if (i >= 30)
|
|
|
706
|
+ {
|
|
|
707
|
+ return NULL;
|
|
|
708
|
+ }
|
|
|
709
|
+ else
|
|
|
710
|
+ {
|
|
|
711
|
+ return (unsigned char *)(smart_data + n);
|
|
|
712
|
+ }
|
|
|
713
|
+}
|
|
|
714
|
+
|
|
|
715
|
+
|
|
|
716
|
+int sata_get_temperature(int fd)
|
|
|
717
|
+{
|
|
|
718
|
+ unsigned char values[512];
|
|
|
719
|
+ unsigned char *field;
|
|
|
720
|
+ int i;
|
|
|
721
|
+ u16 *p;
|
|
|
722
|
+
|
|
|
723
|
+ /* get SMART values */
|
|
|
724
|
+ if (sata_enable_smart(fd) != 0)
|
|
|
725
|
+ {
|
|
|
726
|
+ printf("SATA S.M.A.R.T. not available!\n");
|
|
|
727
|
+ return -1;
|
|
|
728
|
+ }
|
|
|
729
|
+
|
|
|
730
|
+ if (sata_get_smart_values(fd, values))
|
|
|
731
|
+ {
|
|
|
732
|
+ printf("SATA Enable S.M.A.R.T. err!\n");
|
|
|
733
|
+ return -1;
|
|
|
734
|
+ }
|
|
|
735
|
+
|
|
|
736
|
+ p = (u16 *)values;
|
|
|
737
|
+
|
|
|
738
|
+ for (i = 0; i < 256; i++)
|
|
|
739
|
+ {
|
|
|
740
|
+ swapb(*(p + i));
|
|
|
741
|
+ }
|
|
|
742
|
+
|
|
|
743
|
+ /* temperature */
|
|
|
744
|
+ field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID);
|
|
|
745
|
+
|
|
|
746
|
+ if (!field)
|
|
|
747
|
+ {
|
|
|
748
|
+ field = sata_search_temperature(values, DEFAULT_ATTRIBUTE_ID2);
|
|
|
749
|
+ }
|
|
|
750
|
+
|
|
|
751
|
+ if (field)
|
|
|
752
|
+ {
|
|
|
753
|
+ return *(field + 3);
|
|
|
754
|
+ }
|
|
|
755
|
+ else
|
|
|
756
|
+ {
|
|
|
757
|
+ return -1;
|
|
|
758
|
+ }
|
|
|
759
|
+}
|
|
|
760
|
+#endif
|
|
|
761
|
+
|
|
|
762
|
+
|
|
|
763
|
+/* 获取硬盘温度 */
|
|
|
764
|
+int get_sata_hddtemp(char *device, int *value)
|
|
|
765
|
+{
|
|
|
766
|
+ int fd = 0;
|
|
|
767
|
+ fd = open(device, O_RDONLY | O_NONBLOCK);
|
|
|
768
|
+
|
|
|
769
|
+ if (fd < 0)
|
|
|
770
|
+ {
|
|
|
771
|
+ printf("open hdd device err!\n");
|
|
|
772
|
+ return (-1);
|
|
|
773
|
+ }
|
|
|
774
|
+
|
|
|
775
|
+ if (sata_probe(fd))
|
|
|
776
|
+ {
|
|
|
777
|
+ *value = sata_get_temperature(fd);
|
|
|
778
|
+ }
|
|
|
779
|
+ else if (ata_probe(fd))
|
|
|
780
|
+ {
|
|
|
781
|
+ *value = ata_get_temperature(fd);
|
|
|
782
|
+ }
|
|
|
783
|
+ else if (scsi_probe(fd))
|
|
|
784
|
+ {
|
|
|
785
|
+ *value = scsi_get_temperature(fd);
|
|
|
786
|
+ }
|
|
|
787
|
+
|
|
|
788
|
+ if (*value < 0)
|
|
|
789
|
+ {
|
|
|
790
|
+ return -1;
|
|
|
791
|
+ }
|
|
|
792
|
+
|
|
|
793
|
+ close(fd);
|
|
|
794
|
+ return 0;
|
|
|
795
|
+}
|
|
|
796
|
+
|
|
|
797
|
+
|
|
|
798
|
+/* 获取cpu使用率 */
|
|
|
799
|
+typedef struct cpu_occupy_ //定义一个cpu occupy的结构体
|
|
|
800
|
+{
|
|
|
801
|
+ char name[20]; //定义一个char类型的数组名name有20个元素
|
|
|
802
|
+ unsigned int user; //定义一个无符号的int类型的user
|
|
|
803
|
+ unsigned int nice; //定义一个无符号的int类型的nice
|
|
|
804
|
+ unsigned int system; //定义一个无符号的int类型的system
|
|
|
805
|
+ unsigned int idle; //定义一个无符号的int类型的idle
|
|
|
806
|
+ unsigned int iowait;
|
|
|
807
|
+ unsigned int irq;
|
|
|
808
|
+ unsigned int softirq;
|
|
|
809
|
+}cpu_occupy_t;
|
|
|
810
|
+
|
|
|
811
|
+double cal_cpuoccupy(cpu_occupy_t *o, cpu_occupy_t *n)
|
|
|
812
|
+{
|
|
|
813
|
+ double od, nd;
|
|
|
814
|
+ double id, sd;
|
|
|
815
|
+ double cpu_use;
|
|
|
816
|
+
|
|
|
817
|
+ od = (double)(o->user + o->nice + o->system + o->idle + o->softirq + o->iowait + o->irq); //第一次(用户+优先级+系统+空闲)的时间再赋给od
|
|
|
818
|
+ nd = (double)(n->user + n->nice + n->system + n->idle + n->softirq + n->iowait + n->irq); //第二次(用户+优先级+系统+空闲)的时间再赋给od
|
|
|
819
|
+
|
|
|
820
|
+ id = (double)(n->idle); //用户第一次和第二次的时间之差再赋给id
|
|
|
821
|
+ sd = (double)(o->idle); //系统第一次和第二次的时间之差再赋给sd
|
|
|
822
|
+ if ((nd - od) != 0)
|
|
|
823
|
+ cpu_use = 100.0 - ((id - sd)) / (nd - od) * 100.00; //((用户+系统)乖100)除(第一次和第二次的时间差)再赋给g_cpu_used
|
|
|
824
|
+ else
|
|
|
825
|
+ cpu_use = 0;
|
|
|
826
|
+ return cpu_use;
|
|
|
827
|
+}
|
|
|
828
|
+
|
|
|
829
|
+void get_cpuoccupy(cpu_occupy_t *cpust)
|
|
|
830
|
+{
|
|
|
831
|
+ FILE *fd;
|
|
|
832
|
+ int n;
|
|
|
833
|
+ char buff[256];
|
|
|
834
|
+ cpu_occupy_t *cpu_occupy;
|
|
|
835
|
+ cpu_occupy = cpust;
|
|
|
836
|
+
|
|
|
837
|
+ fd = fopen("/proc/stat", "r");
|
|
|
838
|
+ if (fd == NULL)
|
|
|
839
|
+ {
|
|
|
840
|
+ perror("fopen:");
|
|
|
841
|
+ exit(0);
|
|
|
842
|
+ }
|
|
|
843
|
+ fgets(buff, sizeof(buff), fd);
|
|
|
844
|
+
|
|
|
845
|
+ sscanf(buff, "%s %u %u %u %u %u %u %u", cpu_occupy->name, &cpu_occupy->user, &cpu_occupy->nice, &cpu_occupy->system,
|
|
|
846
|
+ &cpu_occupy->idle, &cpu_occupy->iowait, &cpu_occupy->irq, &cpu_occupy->softirq);
|
|
|
847
|
+
|
|
|
848
|
+ fclose(fd);
|
|
|
849
|
+}
|
|
|
850
|
+
|
|
|
851
|
+double get_sysCpuUsage(void)
|
|
|
852
|
+{
|
|
|
853
|
+ cpu_occupy_t cpu_stat1;
|
|
|
854
|
+ cpu_occupy_t cpu_stat2;
|
|
|
855
|
+ double cpu;
|
|
|
856
|
+ get_cpuoccupy((cpu_occupy_t *)&cpu_stat1);
|
|
|
857
|
+ sleep(1);
|
|
|
858
|
+ //第二次获取cpu使用情况
|
|
|
859
|
+ get_cpuoccupy((cpu_occupy_t *)&cpu_stat2);
|
|
|
860
|
+ //计算cpu使用率
|
|
|
861
|
+ cpu = cal_cpuoccupy((cpu_occupy_t *)&cpu_stat1, (cpu_occupy_t *)&cpu_stat2);
|
|
|
862
|
+ return cpu;
|
|
|
863
|
+}
|
|
|
864
|
+
|
|
|
865
|
+/* 获取内存使用率 */
|
|
|
866
|
+struct MEM_INFO
|
|
|
867
|
+{
|
|
|
868
|
+ unsigned int total;
|
|
|
869
|
+ unsigned int free;
|
|
|
870
|
+ unsigned int buffers;
|
|
|
871
|
+ unsigned int cached;
|
|
|
872
|
+ unsigned int swap_cached;
|
|
|
873
|
+ unsigned int swap_total;
|
|
|
874
|
+ unsigned int swap_free;
|
|
|
875
|
+ unsigned int available;
|
|
|
876
|
+};
|
|
|
877
|
+typedef struct MEM_INFO Mem_info;
|
|
|
878
|
+
|
|
|
879
|
+void get_mem_occupy(Mem_info *o)
|
|
|
880
|
+{
|
|
|
881
|
+ FILE *fpMemInfo = fopen("/proc/meminfo", "r");
|
|
|
882
|
+ if (NULL == fpMemInfo)
|
|
|
883
|
+ {
|
|
|
884
|
+ return;
|
|
|
885
|
+ }
|
|
|
886
|
+ int i = 0;
|
|
|
887
|
+ int value;
|
|
|
888
|
+ char name[1024];
|
|
|
889
|
+ char line[1024];
|
|
|
890
|
+ int nFiledNumber = 2;
|
|
|
891
|
+ int nMemberNumber = 5;
|
|
|
892
|
+ while (fgets(line, sizeof(line) - 1, fpMemInfo))
|
|
|
893
|
+ {
|
|
|
894
|
+ if (sscanf(line, "%s%u", name, &value) != nFiledNumber)
|
|
|
895
|
+ {
|
|
|
896
|
+ continue;
|
|
|
897
|
+ }
|
|
|
898
|
+ if (0 == strcmp(name, "MemTotal:"))
|
|
|
899
|
+ {
|
|
|
900
|
+ ++i;
|
|
|
901
|
+ o->total = value;
|
|
|
902
|
+ }
|
|
|
903
|
+ else if (0 == strcmp(name, "MemFree:"))
|
|
|
904
|
+ {
|
|
|
905
|
+ ++i;
|
|
|
906
|
+ o->free = value;
|
|
|
907
|
+ }
|
|
|
908
|
+ else if (0 == strcmp(name, "MemAvailable:"))
|
|
|
909
|
+ {
|
|
|
910
|
+ ++i;
|
|
|
911
|
+ o->available = value;
|
|
|
912
|
+ }
|
|
|
913
|
+ else if (0 == strcmp(name, "Buffers:"))
|
|
|
914
|
+ {
|
|
|
915
|
+ ++i;
|
|
|
916
|
+ o->buffers = value;
|
|
|
917
|
+ }
|
|
|
918
|
+ else if (0 == strcmp(name, "Cached:"))
|
|
|
919
|
+ {
|
|
|
920
|
+ ++i;
|
|
|
921
|
+ o->cached = value;
|
|
|
922
|
+ }
|
|
|
923
|
+ if (i == nMemberNumber)
|
|
|
924
|
+ {
|
|
|
925
|
+ break;
|
|
|
926
|
+ }
|
|
|
927
|
+ }
|
|
|
928
|
+ // system("free");
|
|
|
929
|
+ // system("cat /proc/meminfo");
|
|
|
930
|
+ // printf("MemTotal : %d\n",o->total);
|
|
|
931
|
+ // printf("MemFree : %d\n",o->free);
|
|
|
932
|
+ // printf("MemAvailable : %d\n",o->available);
|
|
|
933
|
+ // printf("MemBuffers : %d\n",o->buffers);
|
|
|
934
|
+ // printf("MemCached : %d\n",o->cached);
|
|
|
935
|
+ // printf("MemSwapCached : %d\n",o->swap_cached);
|
|
|
936
|
+ // printf("MemSwapTotal : %d\n",o->swap_total);
|
|
|
937
|
+ // printf("MemSwapFree : %d\n",o->swap_free);
|
|
|
938
|
+ fclose(fpMemInfo);
|
|
|
939
|
+}
|
|
|
940
|
+
|
|
|
941
|
+float cal_mem_occupy(void)
|
|
|
942
|
+{
|
|
|
943
|
+ Mem_info omem;
|
|
|
944
|
+ get_mem_occupy(&omem);
|
|
|
945
|
+ return (100.0 * (omem.total - omem.available) / omem.total);
|
|
|
946
|
+}
|