"Fossies" - the Fresh Open Source Software Archive 
Member "atop-2.8.1/atopconvert.c" (7 Jan 2023, 40068 Bytes) of package /linux/misc/atop-2.8.1.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "atopconvert.c" see the
Fossies "Dox" file reference documentation and the latest
Fossies "Diffs" side-by-side code changes report:
2.8.0_vs_2.8.1.
1 /*
2 ** ATOP - System & Process Monitor
3 **
4 ** The program 'atop' offers the possibility to view the activity of
5 ** the system on system-level as well as process-level.
6 **
7 ** This program converts a raw logfile created by a particular version
8 ** of atop to (by default) the current version of atop.
9 ** ==========================================================================
10 ** Author: Gerlof Langeveld
11 ** E-mail: gerlof.langeveld@atoptool.nl
12 ** Initial: July/August 2018
13 ** --------------------------------------------------------------------------
14 ** Copyright (C) 2018-2022 Gerlof Langeveld
15 **
16 ** This program is free software; you can redistribute it and/or modify it
17 ** under the terms of the GNU General Public License as published by the
18 ** Free Software Foundation; either version 2, or (at your option) any
19 ** later version.
20 **
21 ** This program is distributed in the hope that it will be useful, but
22 ** WITHOUT ANY WARRANTY; without even the implied warranty of
23 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
24 ** See the GNU General Public License for more details.
25 **
26 ** You should have received a copy of the GNU General Public License
27 ** along with this program; if not, write to the Free Software
28 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
29 ** --------------------------------------------------------------------------
30 */
31 #include <sys/types.h>
32 #include <sys/param.h>
33 #include <sys/mman.h>
34 #include <sys/stat.h>
35 #include <time.h>
36 #include <stdio.h>
37 #include <errno.h>
38 #include <fcntl.h>
39 #include <stdlib.h>
40 #include <signal.h>
41 #include <ctype.h>
42 #include <sys/utsname.h>
43 #include <string.h>
44 #include <regex.h>
45 #include <zlib.h>
46 #include <sys/time.h>
47 #include <sys/resource.h>
48 #include <unistd.h>
49 #include <stdarg.h>
50
51 #include "atop.h"
52 #include "photosyst.h"
53 #include "photoproc.h"
54 #include "rawlog.h"
55
56 #include "prev/netstats_wrong.h"
57
58 #include "prev/photosyst_20.h"
59 #include "prev/photoproc_20.h"
60
61 #include "prev/photosyst_21.h"
62 #include "prev/photoproc_21.h"
63
64 #include "prev/photosyst_22.h"
65 #include "prev/photoproc_22.h"
66
67 #include "prev/photosyst_23.h"
68 #include "prev/photoproc_23.h"
69
70 #include "prev/photosyst_24.h"
71 #include "prev/photoproc_24.h"
72
73 #include "prev/photosyst_25.h"
74 #include "prev/photoproc_25.h"
75
76 #include "prev/photosyst_26.h"
77 #include "prev/photoproc_26.h"
78
79 #include "prev/photosyst_27.h"
80 #include "prev/photoproc_27.h"
81
82 #include "prev/photosyst_28.h"
83 #include "prev/photoproc_28.h"
84
85
86 ///////////////////////////////////////////////////////////////
87 // Conversion functions
88 // --------------------
89 // The structures with system level and process level info
90 // consists of sub-structures, generally for cpu, memory,
91 // disk and network values. These sub-structures might have
92 // changed from a specific version of atop to the next version.
93 // For modified sub-structures, conversion functions have to be
94 // written. These conversion functions will be called in a chained
95 // way for one version increment at the time. Suppose that a
96 // raw log is offered that has been created by atop 2.0 to be
97 // converted to atop 2.3, every sub-structure will be converted
98 // from 2.0 to 2.1, from 2.1 to 2.2 and finally from 2.2 to 2.3.
99 // When a sub-structure has NOT been changed from one version to
100 // another, it will just be copied by the generic conversion
101 // function 'justcopy' to the proper location in the structure
102 // of the next version.
103 // All conversion steps are controlled by the convs[] table.
104 ///////////////////////////////////////////////////////////////
105
106 // Generic function that just copies an old structure byte-wise to
107 // a new structure (new structure implicitly padded with binary zeroes)
108 //
109 void
110 justcopy(void *old, void *new, count_t oldsize, count_t newsize)
111 {
112 if (oldsize)
113 memcpy(new, old, newsize > oldsize ? oldsize : newsize);
114 }
115
116 // /////////////////////////////////////////////////////////////////
117 // Specific functions that convert an old sstat sub-structure to
118 // a new sub-structure (system level)
119 // /////////////////////////////////////////////////////////////////
120 void
121 scpu_to_21(void *old, void *new, count_t oldsize, count_t newsize)
122 {
123 // cfuture[1] --> cfuture[4] in struct percpu
124 //
125 struct cpustat_20 *c20 = old;
126 struct cpustat_21 *c21 = new;
127 int i;
128
129 memcpy(c21, c20, (char *)&c20->all - (char *)c20); // base values
130 memcpy(&c21->all, &c20->all, sizeof(struct percpu_20));
131
132 for (i=0; i < MAXCPU_20; i++)
133 memcpy( &(c21->cpu[i]), &(c20->cpu[i]), sizeof(struct percpu_20));
134 }
135
136 void
137 sdsk_to_21(void *old, void *new, count_t oldsize, count_t newsize)
138 {
139 // MAXDSK and MAXLVM have been enlarged
140 //
141 struct dskstat_20 *d20 = old;
142 struct dskstat_21 *d21 = new;
143
144 d21->ndsk = d20->ndsk;
145 d21->nmdd = d20->nmdd;
146 d21->nlvm = d20->nlvm;
147
148 memcpy(d21->dsk, d20->dsk, sizeof d20->dsk);
149 memcpy(d21->mdd, d20->mdd, sizeof d20->mdd);
150 memcpy(d21->lvm, d20->lvm, sizeof d20->lvm);
151 }
152
153 void
154 sint_to_22(void *old, void *new, count_t oldsize, count_t newsize)
155 {
156 // members 'type' and 'speedp' added to struct perintf
157 //
158 struct intfstat_21 *i21 = old;
159 struct intfstat_22 *i22 = new;
160 int i;
161
162 i22->nrintf = i21->nrintf;
163
164 for (i=0; i < MAXINTF_21; i++)
165 {
166 memcpy(&(i22->intf[i]), &(i21->intf[i]),
167 sizeof(struct perintf_21));
168
169 // correct last members by refilling
170 //
171 i22->intf[i].type = '?';
172 i22->intf[i].speed = i21->intf[i].speed;
173 i22->intf[i].speedp = i21->intf[i].speed;
174 i22->intf[i].duplex = i21->intf[i].duplex;
175
176 memset(i22->intf[i].cfuture, 0, sizeof i22->intf[i].cfuture);
177 }
178 }
179
180 void
181 scpu_to_27(void *old, void *new, count_t oldsize, count_t newsize)
182 {
183 // cfuture[2] --> cfuture[4] in struct percpu
184 //
185 struct cpustat_26 *c26 = old;
186 struct cpustat_27 *c27 = new;
187 int i;
188
189 memcpy(c27, c26, (char *)&c26->all - (char *)c26); // base values
190 memcpy(&c27->all, &c26->all, sizeof(struct percpu_26));
191
192 for (i=0; i < MAXCPU_26; i++)
193 memcpy( &(c27->cpu[i]), &(c26->cpu[i]), sizeof(struct percpu_26));
194 }
195
196 void
197 smem_to_27(void *old, void *new, count_t oldsize, count_t newsize)
198 {
199 struct memstat_26 *m26 = old;
200 struct memstat_27 *m27 = new;
201
202 memcpy(m27, m26, sizeof *m26);
203
204 m27->oomkills = -1; // explicitly define 'unused'
205 }
206
207 void
208 sdsk_to_27(void *old, void *new, count_t oldsize, count_t newsize)
209 {
210 struct dskstat_26 *d26 = old;
211 struct dskstat_27 *d27 = new;
212 int i;
213
214 memcpy(d27, d26, oldsize);
215
216 for (i=0; i < d27->ndsk; i++)
217 d27->dsk[i].ndisc = -1; // explicitly define 'unused'
218
219 for (i=0; i < d27->nmdd; i++)
220 d27->mdd[i].ndisc = -1; // explicitly define 'unused'
221
222 for (i=0; i < d27->nlvm; i++)
223 d27->lvm[i].ndisc = -1; // explicitly define 'unused'
224 }
225
226 void
227 smem_to_28(void *old, void *new, count_t oldsize, count_t newsize)
228 {
229 struct memstat_27 *m27 = old;
230 struct memstat_28 *m28 = new;
231
232 memcpy(m28, m27, sizeof *m27);
233
234 m28->tcpsock = 0; // new counter
235 m28->udpsock = 0; // new counter
236
237 m28->commitlim = m27->commitlim;
238 m28->committed = m27->committed;
239 m28->shmem = m27->shmem;
240 m28->shmrss = m27->shmrss;
241 m28->shmswp = m27->shmswp;
242 m28->slabreclaim = m27->slabreclaim;
243 m28->tothugepage = m27->tothugepage;
244 m28->freehugepage = m27->freehugepage;
245 m28->hugepagesz = m27->hugepagesz;
246 m28->vmwballoon = m27->vmwballoon;
247 m28->zfsarcsize = m27->zfsarcsize;
248 m28->swapcached = m27->swapcached;
249 m28->ksmsharing = m27->ksmsharing;
250 m28->ksmshared = m27->ksmshared;
251 m28->zswstored = m27->zswstored;
252 m28->zswtotpool = m27->zswtotpool;
253 m28->oomkills = m27->oomkills;
254 m28->compactstall = m27->compactstall;
255 m28->pgmigrate = m27->pgmigrate;
256 m28->numamigrate = m27->numamigrate;
257
258 m28->pgouts = 0; // new counter
259 m28->pgins = 0; // new counter
260 m28->pagetables = 0; // new counter
261
262 memset(m28->cfuture, 0, sizeof m28->cfuture);
263 }
264
265 void
266 sdsk_to_28(void *old, void *new, count_t oldsize, count_t newsize)
267 {
268 struct dskstat_27 *d27 = old;
269 struct dskstat_28 *d28 = new;
270 int i;
271
272 d28->ndsk = d27->ndsk;
273 d28->nmdd = d27->nmdd;
274 d28->nlvm = d27->nlvm;
275
276 for (i=0; i < d28->ndsk; i++)
277 memcpy(&(d28->dsk[i]), &(d27->dsk[i]), sizeof d27->dsk[i]);
278
279 for (i=0; i < d28->nmdd; i++)
280 memcpy(&(d28->mdd[i]), &(d27->mdd[i]), sizeof d27->mdd[i]);
281
282 for (i=0; i < d28->nlvm; i++)
283 memcpy(&(d28->lvm[i]), &(d27->lvm[i]), sizeof d27->lvm[i]);
284 }
285
286 void
287 smnu_to_28(void *old, void *new, count_t oldsize, count_t newsize)
288 {
289 struct memnuma_27 *n27 = old;
290 struct memnuma_28 *n28 = new;
291 int i;
292
293 n28->nrnuma = n27->nrnuma;
294
295 for (i=0; i < n28->nrnuma; i++)
296 {
297 n28->numa[i].numanr = i;
298 n28->numa[i].frag = n27->numa[i].frag;
299 n28->numa[i].totmem = n27->numa[i].totmem;
300 n28->numa[i].freemem = n27->numa[i].freemem;
301 n28->numa[i].filepage = n27->numa[i].filepage;
302 n28->numa[i].dirtymem = n27->numa[i].dirtymem;
303 n28->numa[i].filepage = n27->numa[i].filepage;
304 n28->numa[i].slabmem = n27->numa[i].slabmem;
305 n28->numa[i].slabreclaim = n27->numa[i].slabreclaim;
306 n28->numa[i].active = n27->numa[i].active;
307 n28->numa[i].inactive = n27->numa[i].inactive;
308 n28->numa[i].shmem = n27->numa[i].shmem;
309 n28->numa[i].tothp = n27->numa[i].tothp;
310 }
311 }
312
313 void
314 scnu_to_28(void *old, void *new, count_t oldsize, count_t newsize)
315 {
316 struct cpunuma_27 *n27 = old;
317 struct cpunuma_28 *n28 = new;
318 int i;
319
320 n28->nrnuma = n27->nrnuma;
321
322 for (i=0; i < n28->nrnuma; i++)
323 {
324 n28->numa[i].numanr = i;
325 n28->numa[i].nrcpu = n27->numa[i].nrcpu;
326 n28->numa[i].stime = n27->numa[i].stime;
327 n28->numa[i].utime = n27->numa[i].utime;
328 n28->numa[i].ntime = n27->numa[i].ntime;
329 n28->numa[i].itime = n27->numa[i].itime;
330 n28->numa[i].wtime = n27->numa[i].wtime;
331 n28->numa[i].Itime = n27->numa[i].Itime;
332 n28->numa[i].Stime = n27->numa[i].Stime;
333 n28->numa[i].steal = n27->numa[i].steal;
334 n28->numa[i].guest = n27->numa[i].guest;
335 }
336 }
337
338
339 // /////////////////////////////////////////////////////////////////
340 // Specific functions that convert an old tstat sub-structure to
341 // a new sub-structure (process level)
342 // /////////////////////////////////////////////////////////////////
343 void
344 tgen_to_21(void *old, void *new, count_t oldsize, count_t newsize)
345 {
346 // member 'envid' inserted in struct gen
347 //
348 struct gen_20 *g20 = old;
349 struct gen_21 *g21 = new;
350
351 memcpy(g21, g20, (char *)g20->ifuture - (char *)g20); // base values
352 g21->envid = 0;
353 }
354
355 void
356 tmem_to_21(void *old, void *new, count_t oldsize, count_t newsize)
357 {
358 // members 'pmem' and 'cfuture[4]' inserted in struct mem
359 //
360 struct mem_20 *m20 = old;
361 struct mem_21 *m21 = new;
362
363 m21->minflt = m20->minflt;
364 m21->majflt = m20->majflt;
365 m21->vexec = m20->vexec;
366 m21->vmem = m20->vmem;
367 m21->rmem = m20->rmem;
368 m21->pmem = 0;
369 m21->vgrow = m20->vgrow;
370 m21->rgrow = m20->rgrow;
371 m21->vdata = m20->vdata;
372 m21->vstack = m20->vstack;
373 m21->vlibs = m20->vlibs;
374 m21->vswap = m20->vswap;
375 }
376
377 void
378 tgen_to_22(void *old, void *new, count_t oldsize, count_t newsize)
379 {
380 // member 'envid' removed, members 'ctid' and 'vpid' inserted in struct gen
381 //
382 struct gen_21 *g21 = old;
383 struct gen_22 *g22 = new;
384
385 memcpy(g22, g21, (char *)&g21->envid - (char *)g21); // copy base values
386 g22->ctid = g21->envid;
387 g22->vpid = 0;
388 }
389
390 void
391 tcpu_to_26(void *old, void *new, count_t oldsize, count_t newsize)
392 {
393 // unused values appear not to be zeroed in version 2.5
394 //
395 struct cpu_25 *c25 = old;
396 struct cpu_26 *c26 = new;
397
398 memcpy(c26, c25, sizeof *c26); // copy entire struct
399
400 memset(&(c26->wchan), 0, sizeof c26->wchan);
401 c26->rundelay = 0;
402 }
403
404 void
405 tmem_to_26(void *old, void *new, count_t oldsize, count_t newsize)
406 {
407 // unused values appear not to be zeroed in version 2.5
408 //
409 struct mem_25 *m25 = old;
410 struct mem_26 *m26 = new;
411
412 memcpy(m26, m25, sizeof *m26); // copy entire struct
413
414 m26->vlock = 0;
415 }
416
417 void
418 tcpu_to_28(void *old, void *new, count_t oldsize, count_t newsize)
419 {
420 // cgroup counters inserted
421 //
422 struct cpu_27 *c27 = old;
423 struct cpu_28 *c28 = new;
424
425 c28->utime = c27->utime;
426 c28->stime = c27->stime;
427 c28->nice = c27->nice;
428 c28->prio = c27->prio;
429 c28->rtprio = c27->rtprio;
430 c28->policy = c27->policy;
431 c28->curcpu = c27->curcpu;
432 c28->sleepavg = c27->sleepavg;
433 c28->rundelay = c27->rundelay;
434
435 memcpy(c28->wchan, c27->wchan, sizeof c28->wchan);
436
437 c28->blkdelay = 0;
438 c28->cgcpuweight= 0;
439 c28->cgcpumax = 0;
440 c28->cgcpumaxr = 0;
441
442 memset(c28->ifuture, 0, sizeof c28->ifuture);
443 memset(c28->cfuture, 0, sizeof c28->cfuture);
444 }
445
446 void
447 tmem_to_28(void *old, void *new, count_t oldsize, count_t newsize)
448 {
449 struct mem_27 *m27 = old;
450 struct mem_28 *m28 = new;
451
452 memcpy(m28, m27, sizeof *m27); // copy old struct
453
454 m28->cgmemmax = 0;
455 m28->cgmemmaxr = 0;
456 m28->cgswpmax = 0;
457 m28->cgswpmaxr = 0;
458
459 memset(m28->cfuture, 0, sizeof m28->cfuture);
460 }
461
462 ///////////////////////////////////////////////////////////////
463 // conversion definition for various structs in sstat and tstat
464 //
465 #define SETVERSION(major, minor) ((major << 8) | minor)
466 #define STROFFSET(str, begin) ((long)((char *)str - (char *)begin))
467
468 struct sconvstruct {
469 count_t structsize;
470 void *structptr;
471 void (*structconv)(void *, void *, count_t, count_t);
472 };
473
474 struct tconvstruct {
475 count_t structsize;
476 long structoffset;
477 void (*structconv)(void *, void *, count_t, count_t);
478 };
479
480 struct sstat_20 sstat_20;
481 struct sstat_21 sstat_21;
482 struct sstat_22 sstat_22;
483 struct sstat_23 sstat_23;
484 struct sstat_24 sstat_24;
485 struct sstat_25 sstat_25;
486 struct sstat_26 sstat_26;
487 struct sstat_27 sstat_27;
488 struct sstat_28 sstat_28;
489 struct sstat sstat;
490
491 struct tstat_20 tstat_20;
492 struct tstat_21 tstat_21;
493 struct tstat_22 tstat_22;
494 struct tstat_23 tstat_23;
495 struct tstat_24 tstat_24;
496 struct tstat_25 tstat_25;
497 struct tstat_26 tstat_26;
498 struct tstat_27 tstat_27;
499 struct tstat_28 tstat_28;
500 struct tstat tstat;
501
502 struct convertall {
503 int version; // version of raw log
504
505 unsigned int sstatlen; // length of struct sstat
506 void *sstat; // pointer to sstat struct
507
508 unsigned int tstatlen; // length of struct tstat
509 void *tstat; // pointer to tstat structs
510
511 // conversion definition for subparts within sstat
512 struct sconvstruct scpu;
513 struct sconvstruct smem;
514 struct sconvstruct snet;
515 struct sconvstruct sintf;
516 struct sconvstruct sdsk;
517 struct sconvstruct snfs;
518 struct sconvstruct scfs;
519 struct sconvstruct swww;
520 struct sconvstruct spsi;
521 struct sconvstruct sgpu;
522 struct sconvstruct sifb;
523 struct sconvstruct smnum;
524 struct sconvstruct scnum;
525 struct sconvstruct sllc;
526
527 // conversion definition for subparts within tstat
528 struct tconvstruct tgen;
529 struct tconvstruct tcpu;
530 struct tconvstruct tdsk;
531 struct tconvstruct tmem;
532 struct tconvstruct tnet;
533 struct tconvstruct tgpu;
534 } convs[] =
535 {
536 {SETVERSION(2,0),
537 sizeof(struct sstat_20), &sstat_20,
538 sizeof(struct tstat_20), NULL,
539
540 {sizeof(struct cpustat_20), &sstat_20.cpu, NULL},
541 {sizeof(struct memstat_20), &sstat_20.mem, NULL},
542 {sizeof(struct netstat_20), &sstat_20.net, NULL},
543 {sizeof(struct intfstat_20), &sstat_20.intf, NULL},
544 {sizeof(struct dskstat_20), &sstat_20.dsk, NULL},
545 {0, NULL, NULL},
546 {0, NULL, NULL},
547 {sizeof(struct wwwstat_20), &sstat_20.www, NULL},
548 {0, NULL, NULL},
549 {0, NULL, NULL},
550 {0, NULL, NULL},
551 {0, NULL, NULL},
552 {0, NULL, NULL},
553 {0, NULL, NULL},
554
555 {sizeof(struct gen_20),
556 STROFFSET(&tstat_20.gen, &tstat_20), NULL},
557 {sizeof(struct cpu_20),
558 STROFFSET(&tstat_20.cpu, &tstat_20), NULL},
559 {sizeof(struct dsk_20),
560 STROFFSET(&tstat_20.dsk, &tstat_20), NULL},
561 {sizeof(struct mem_20),
562 STROFFSET(&tstat_20.mem, &tstat_20), NULL},
563 {sizeof(struct net_20),
564 STROFFSET(&tstat_20.net, &tstat_20), NULL},
565 {0, 0, NULL},
566 },
567
568 {SETVERSION(2,1), // 2.0 --> 2.1
569 sizeof(struct sstat_21), &sstat_21,
570 sizeof(struct tstat_21), NULL,
571
572 {sizeof(struct cpustat_21), &sstat_21.cpu, scpu_to_21},
573 {sizeof(struct memstat_21), &sstat_21.mem, justcopy},
574 {sizeof(struct netstat_21), &sstat_21.net, justcopy},
575 {sizeof(struct intfstat_21), &sstat_21.intf, justcopy},
576 {sizeof(struct dskstat_21), &sstat_21.dsk, sdsk_to_21},
577 {0, NULL, NULL},
578 {0, NULL, NULL},
579 {sizeof(struct wwwstat_21), &sstat_21.www, justcopy},
580 {0, NULL, NULL},
581 {0, NULL, NULL},
582 {0, NULL, NULL},
583 {0, NULL, NULL},
584 {0, NULL, NULL},
585 {0, NULL, NULL},
586
587 {sizeof(struct gen_21),
588 STROFFSET(&tstat_21.gen, &tstat_21), tgen_to_21},
589 {sizeof(struct cpu_21),
590 STROFFSET(&tstat_21.cpu, &tstat_21), justcopy},
591 {sizeof(struct dsk_21),
592 STROFFSET(&tstat_21.dsk, &tstat_21), justcopy},
593 {sizeof(struct mem_21),
594 STROFFSET(&tstat_21.mem, &tstat_21), tmem_to_21},
595 {sizeof(struct net_21),
596 STROFFSET(&tstat_21.net, &tstat_21), justcopy},
597 {0, 0, NULL},
598 },
599
600 {SETVERSION(2,2), // 2.1 --> 2.2
601 sizeof(struct sstat_22), &sstat_22,
602 sizeof(struct tstat_22), NULL,
603
604 {sizeof(struct cpustat_22), &sstat_22.cpu, justcopy},
605 {sizeof(struct memstat_22), &sstat_22.mem, justcopy},
606 {sizeof(struct netstat_22), &sstat_22.net, justcopy},
607 {sizeof(struct intfstat_22), &sstat_22.intf, sint_to_22},
608 {sizeof(struct dskstat_22), &sstat_22.dsk, justcopy},
609 {sizeof(struct nfsstat_22), &sstat_22.nfs, NULL},
610 {sizeof(struct contstat_22), &sstat_22.cfs, NULL},
611 {sizeof(struct wwwstat_22), &sstat_22.www, justcopy},
612 {0, NULL, NULL},
613 {0, NULL, NULL},
614 {0, NULL, NULL},
615 {0, NULL, NULL},
616 {0, NULL, NULL},
617 {0, NULL, NULL},
618
619 {sizeof(struct gen_22),
620 STROFFSET(&tstat_22.gen, &tstat_22), tgen_to_22},
621 {sizeof(struct cpu_22),
622 STROFFSET(&tstat_22.cpu, &tstat_22), justcopy},
623 {sizeof(struct dsk_22),
624 STROFFSET(&tstat_22.dsk, &tstat_22), justcopy},
625 {sizeof(struct mem_22),
626 STROFFSET(&tstat_22.mem, &tstat_22), justcopy},
627 {sizeof(struct net_22),
628 STROFFSET(&tstat_22.net, &tstat_22), justcopy},
629 {0, 0, NULL},
630 },
631
632 {SETVERSION(2,3), // 2.2 --> 2.3
633 sizeof(struct sstat_23), &sstat_23,
634 sizeof(struct tstat_23), NULL,
635
636 {sizeof(struct cpustat_23), &sstat_23.cpu, justcopy},
637 {sizeof(struct memstat_23), &sstat_23.mem, justcopy},
638 {sizeof(struct netstat_23), &sstat_23.net, justcopy},
639 {sizeof(struct intfstat_23), &sstat_23.intf, justcopy},
640 {sizeof(struct dskstat_23), &sstat_23.dsk, justcopy},
641 {sizeof(struct nfsstat_23), &sstat_23.nfs, justcopy},
642 {sizeof(struct contstat_23), &sstat_23.cfs, justcopy},
643 {sizeof(struct wwwstat_23), &sstat_23.www, justcopy},
644 {0, NULL, NULL},
645 {0, NULL, NULL},
646 {0, NULL, NULL},
647 {0, NULL, NULL},
648 {0, NULL, NULL},
649 {0, NULL, NULL},
650
651 {sizeof(struct gen_23),
652 STROFFSET(&tstat_23.gen, &tstat_23), justcopy},
653 {sizeof(struct cpu_23),
654 STROFFSET(&tstat_23.cpu, &tstat_23), justcopy},
655 {sizeof(struct dsk_23),
656 STROFFSET(&tstat_23.dsk, &tstat_23), justcopy},
657 {sizeof(struct mem_23),
658 STROFFSET(&tstat_23.mem, &tstat_23), justcopy},
659 {sizeof(struct net_23),
660 STROFFSET(&tstat_23.net, &tstat_23), justcopy},
661 {0, 0, NULL},
662 },
663
664 {SETVERSION(2,4), // 2.3 --> 2.4
665 sizeof(struct sstat_24), &sstat_24,
666 sizeof(struct tstat_24), NULL,
667
668 {sizeof(struct cpustat_24), &sstat_24.cpu, justcopy},
669 {sizeof(struct memstat_24), &sstat_24.mem, justcopy},
670 {sizeof(struct netstat_24), &sstat_24.net, justcopy},
671 {sizeof(struct intfstat_24), &sstat_24.intf, justcopy},
672 {sizeof(struct dskstat_24), &sstat_24.dsk, justcopy},
673 {sizeof(struct nfsstat_24), &sstat_24.nfs, justcopy},
674 {sizeof(struct contstat_24), &sstat_24.cfs, justcopy},
675 {sizeof(struct wwwstat_24), &sstat_24.www, justcopy},
676 {0, &sstat_24.psi, NULL},
677 {0, &sstat_24.gpu, NULL},
678 {0, &sstat_24.ifb, NULL},
679 {0, NULL, NULL},
680 {0, NULL, NULL},
681 {0, NULL, NULL},
682
683 {sizeof(struct gen_24),
684 STROFFSET(&tstat_24.gen, &tstat_24), justcopy},
685 {sizeof(struct cpu_24),
686 STROFFSET(&tstat_24.cpu, &tstat_24), justcopy},
687 {sizeof(struct dsk_24),
688 STROFFSET(&tstat_24.dsk, &tstat_24), justcopy},
689 {sizeof(struct mem_24),
690 STROFFSET(&tstat_24.mem, &tstat_24), justcopy},
691 {sizeof(struct net_24),
692 STROFFSET(&tstat_24.net, &tstat_24), justcopy},
693 {sizeof(struct gpu_24),
694 STROFFSET(&tstat_24.gpu, &tstat_24), justcopy},
695 },
696
697 {SETVERSION(2,5), // 2.4 --> 2.5
698 sizeof(struct sstat_25), &sstat_25,
699 sizeof(struct tstat_25), NULL,
700
701 {sizeof(struct cpustat_25), &sstat_25.cpu, justcopy},
702 {sizeof(struct memstat_25), &sstat_25.mem, justcopy},
703 {sizeof(struct netstat_25), &sstat_25.net, justcopy},
704 {sizeof(struct intfstat_25), &sstat_25.intf, justcopy},
705 {sizeof(struct dskstat_25), &sstat_25.dsk, justcopy},
706 {sizeof(struct nfsstat_25), &sstat_25.nfs, justcopy},
707 {sizeof(struct contstat_25), &sstat_25.cfs, justcopy},
708 {sizeof(struct wwwstat_25), &sstat_25.www, justcopy},
709 {sizeof(struct pressure_25), &sstat_25.psi, justcopy},
710 {sizeof(struct gpustat_25), &sstat_25.gpu, justcopy},
711 {sizeof(struct ifbstat_25), &sstat_25.ifb, justcopy},
712 {0, NULL, NULL},
713 {0, NULL, NULL},
714 {0, NULL, NULL},
715
716 {sizeof(struct gen_25),
717 STROFFSET(&tstat_25.gen, &tstat_25), justcopy},
718 {sizeof(struct cpu_25),
719 STROFFSET(&tstat_25.cpu, &tstat_25), justcopy},
720 {sizeof(struct dsk_25),
721 STROFFSET(&tstat_25.dsk, &tstat_25), justcopy},
722 {sizeof(struct mem_25),
723 STROFFSET(&tstat_25.mem, &tstat_25), justcopy},
724 {sizeof(struct net_25),
725 STROFFSET(&tstat_25.net, &tstat_25), justcopy},
726 {sizeof(struct gpu_25),
727 STROFFSET(&tstat_25.gpu, &tstat_25), justcopy},
728 },
729
730 {SETVERSION(2,6), // 2.5 --> 2.6
731 sizeof(struct sstat_26), &sstat_26,
732 sizeof(struct tstat_26), NULL,
733
734 {sizeof(struct cpustat_26), &sstat_26.cpu, justcopy},
735 {sizeof(struct memstat_26), &sstat_26.mem, justcopy},
736 {sizeof(struct netstat_26), &sstat_26.net, justcopy},
737 {sizeof(struct intfstat_26), &sstat_26.intf, justcopy},
738 {sizeof(struct dskstat_26), &sstat_26.dsk, justcopy},
739 {sizeof(struct nfsstat_26), &sstat_26.nfs, justcopy},
740 {sizeof(struct contstat_26), &sstat_26.cfs, justcopy},
741 {sizeof(struct wwwstat_26), &sstat_26.www, justcopy},
742 {sizeof(struct pressure_26), &sstat_26.psi, justcopy},
743 {sizeof(struct gpustat_26), &sstat_26.gpu, justcopy},
744 {sizeof(struct ifbstat_26), &sstat_26.ifb, justcopy},
745 {0, NULL, NULL},
746 {0, NULL, NULL},
747 {0, NULL, NULL},
748
749 {sizeof(struct gen_26),
750 STROFFSET(&tstat_26.gen, &tstat_26), justcopy},
751 {sizeof(struct cpu_26),
752 STROFFSET(&tstat_26.cpu, &tstat_26), tcpu_to_26},
753 {sizeof(struct dsk_26),
754 STROFFSET(&tstat_26.dsk, &tstat_26), justcopy},
755 {sizeof(struct mem_26),
756 STROFFSET(&tstat_26.mem, &tstat_26), tmem_to_26},
757 {sizeof(struct net_26),
758 STROFFSET(&tstat_26.net, &tstat_26), justcopy},
759 {sizeof(struct gpu_26),
760 STROFFSET(&tstat_26.gpu, &tstat_26), justcopy},
761 },
762
763 {SETVERSION(2,7), // 2.6 --> 2.7
764 sizeof(struct sstat_27), &sstat_27,
765 sizeof(struct tstat_27), NULL,
766
767 {sizeof(struct cpustat_27), &sstat_27.cpu, scpu_to_27},
768 {sizeof(struct memstat_27), &sstat_27.mem, smem_to_27},
769 {sizeof(struct netstat_27), &sstat_27.net, justcopy},
770 {sizeof(struct intfstat_27), &sstat_27.intf, justcopy},
771 {sizeof(struct dskstat_27), &sstat_27.dsk, sdsk_to_27},
772 {sizeof(struct nfsstat_27), &sstat_27.nfs, justcopy},
773 {sizeof(struct contstat_27), &sstat_27.cfs, justcopy},
774 {sizeof(struct wwwstat_27), &sstat_27.www, justcopy},
775 {sizeof(struct pressure_27), &sstat_27.psi, justcopy},
776 {sizeof(struct gpustat_27), &sstat_27.gpu, justcopy},
777 {sizeof(struct ifbstat_27), &sstat_27.ifb, justcopy},
778 {0, &sstat_27.memnuma, NULL},
779 {0, &sstat_27.cpunuma, NULL},
780 {0, NULL, NULL},
781
782 {sizeof(struct gen_27),
783 STROFFSET(&tstat_27.gen, &tstat_27), justcopy},
784 {sizeof(struct cpu_27),
785 STROFFSET(&tstat_27.cpu, &tstat_27), justcopy},
786 {sizeof(struct dsk_27),
787 STROFFSET(&tstat_27.dsk, &tstat_27), justcopy},
788 {sizeof(struct mem_27),
789 STROFFSET(&tstat_27.mem, &tstat_27), justcopy},
790 {sizeof(struct net_27),
791 STROFFSET(&tstat_27.net, &tstat_27), justcopy},
792 {sizeof(struct gpu_27),
793 STROFFSET(&tstat_27.gpu, &tstat_27), justcopy},
794 },
795
796 {SETVERSION(2,8), // 2.7 --> 2.8
797 sizeof(struct sstat_28), &sstat_28,
798 sizeof(struct tstat_28), NULL,
799
800 {sizeof(struct cpustat_28), &sstat_28.cpu, justcopy},
801 {sizeof(struct memstat_28), &sstat_28.mem, smem_to_28},
802 {sizeof(struct netstat_28), &sstat_28.net, justcopy},
803 {sizeof(struct intfstat_28), &sstat_28.intf, justcopy},
804 {sizeof(struct dskstat_28), &sstat_28.dsk, sdsk_to_28},
805 {sizeof(struct nfsstat_28), &sstat_28.nfs, justcopy},
806 {sizeof(struct contstat_28), &sstat_28.cfs, justcopy},
807 {sizeof(struct wwwstat_28), &sstat_28.www, justcopy},
808 {sizeof(struct pressure_28), &sstat_28.psi, justcopy},
809 {sizeof(struct gpustat_28), &sstat_28.gpu, justcopy},
810 {sizeof(struct ifbstat_28), &sstat_28.ifb, justcopy},
811 {sizeof(struct memnuma_28), &sstat_28.memnuma, smnu_to_28},
812 {sizeof(struct cpunuma_28), &sstat_28.cpunuma, scnu_to_28},
813 {0, &sstat_28.llc, NULL},
814
815 {sizeof(struct gen_28),
816 STROFFSET(&tstat_28.gen, &tstat_28), justcopy},
817 {sizeof(struct cpu_28),
818 STROFFSET(&tstat_28.cpu, &tstat_28), tcpu_to_28},
819 {sizeof(struct dsk_28),
820 STROFFSET(&tstat_28.dsk, &tstat_28), justcopy},
821 {sizeof(struct mem_28),
822 STROFFSET(&tstat_28.mem, &tstat_28), tmem_to_28},
823 {sizeof(struct net_28),
824 STROFFSET(&tstat_28.net, &tstat_28), justcopy},
825 {sizeof(struct gpu_28),
826 STROFFSET(&tstat_28.gpu, &tstat_28), justcopy},
827 },
828 };
829
830 int numconvs = sizeof convs / sizeof(struct convertall);
831
832 ///////////////////////////////////////////////////////////////
833 // End of conversion functions
834 ///////////////////////////////////////////////////////////////
835
836 // function prototypes
837 //
838 static int openin(char *);
839 static void readin(int, void *, int);
840
841 static int openout(char *);
842 static void writeout(int, void *, int);
843 static void writesamp(int, struct rawrecord *, void *, int, void *,
844 int, int);
845
846 static void copy_file(int, int);
847 static void convert_samples(int, int, struct rawheader *, int, int);
848 static void do_sconvert(struct sconvstruct *, struct sconvstruct *);
849 static void do_tconvert(void *, void *,
850 struct tconvstruct *, struct tconvstruct *);
851
852 static int getrawsstat(int, struct sstat *, int);
853 static int getrawtstat(int, struct tstat *, int, int);
854 static void testcompval(int, char *);
855
856 int
857 main(int argc, char *argv[])
858 {
859 int ifd, ofd;
860 struct rawheader irh, orh;
861 int i, versionix, targetix = -1;
862 int c, major, minor, targetvers;
863 char *infile, *outfile;
864
865 // verify the command line arguments:
866 // optional flags and mandatory input and output filename
867 //
868 if (argc < 2)
869 prusage(argv[0]);
870
871 while ((c = getopt(argc, argv, "?t:")) != EOF)
872 {
873 switch (c)
874 {
875 case '?': // usage wanted ?
876 prusage(argv[0]);
877 break;
878
879 case 't': // target version
880 if ( sscanf(optarg, "%d.%d", &major, &minor) != 2)
881 {
882 fprintf(stderr,
883 "target version format: major.minor\n");
884 prusage(argv[0]);
885 }
886
887 targetvers = SETVERSION(major, minor);
888
889 // search for target version in conversion table
890 //
891 for (i=0, targetix=-1; i < numconvs; i++)
892 {
893 if (targetvers == convs[i].version)
894 {
895 targetix = i;
896 break;
897 }
898 }
899
900 if (targetix == -1) // incorrect target version?
901 {
902 fprintf(stderr,
903 "target version incorrect!");
904 prusage(argv[0]);
905 }
906 break;
907
908 default:
909 prusage(argv[0]);
910 break;
911 }
912 }
913
914 if (optind >= argc)
915 prusage(argv[0]);
916
917 infile = argv[optind++];
918
919 // determine target version (default: latest version)
920 //
921 if (targetix == -1) // no specific target version requested?
922 targetix = numconvs - 1;
923
924 // open the input file and verify magic number
925 //
926 if ( (ifd = openin(infile)) == -1)
927 {
928 prusage(argv[0]);
929 exit(2);
930 }
931
932 readin(ifd, &irh, sizeof irh);
933
934 if (irh.magic != MYMAGIC)
935 {
936 fprintf(stderr,
937 "File %s does not contain atop/atopsar data "
938 "(wrong magic number)\n", infile);
939 exit(3);
940 }
941
942 printf("Version of %s: %d.%d\n", infile,
943 (irh.aversion >> 8) & 0x7f, irh.aversion & 0xff);
944
945 if (irh.rawheadlen != sizeof(struct rawheader) ||
946 irh.rawreclen != sizeof(struct rawrecord) )
947 {
948 fprintf(stderr,
949 "File %s created with atop compiled "
950 "for other CPU architecture\n", infile);
951 exit(3);
952 }
953
954 // search for version of input file in conversion table
955 //
956 for (i=0, versionix=-1; i < numconvs; i++)
957 {
958 if (convs[i].version == (irh.aversion & 0x7fff))
959 {
960 versionix = i;
961 break;
962 }
963 }
964
965 if (versionix == -1)
966 {
967 fprintf(stderr,
968 "This version is not supported for conversion!\n");
969 exit(11);
970 }
971
972 if (versionix > targetix)
973 {
974 fprintf(stderr, "Downgrading of version is not supported!\n");
975 exit(11);
976 }
977
978 if (irh.sstatlen != convs[versionix].sstatlen ||
979 irh.tstatlen != convs[versionix].tstatlen )
980 {
981 fprintf(stderr,
982 "File %s contains unexpected internal structures\n",
983 infile);
984 fprintf(stderr, "sstat: %d/%d, tstat: %d/%d\n",
985 irh.sstatlen, convs[versionix].sstatlen,
986 irh.tstatlen, convs[versionix].tstatlen);
987
988 exit(11);
989 }
990
991 // handle the output file
992 //
993 if (optind >= argc)
994 exit(0);
995
996 outfile = argv[optind++];
997
998 if (strcmp(infile, outfile) == 0)
999 {
1000 fprintf(stderr,
1001 "input file and output file should not be identical!\n");
1002 exit(12);
1003 }
1004
1005 // open the output file
1006 //
1007 if ( (ofd = openout(outfile)) == -1)
1008 {
1009 prusage(argv[0]);
1010 exit(4);
1011 }
1012
1013 // write raw header to output file
1014 //
1015 orh = irh;
1016
1017 orh.aversion = convs[targetix].version | 0x8000;
1018 orh.sstatlen = convs[targetix].sstatlen;
1019 orh.tstatlen = convs[targetix].tstatlen;
1020
1021 writeout(ofd, &orh, sizeof orh);
1022
1023 printf("Version of %s: %d.%d\n", outfile,
1024 (orh.aversion >> 8) & 0x7f, orh.aversion & 0xff);
1025
1026 // copy and convert every sample, unless the version of the
1027 // input file is identical to the target version (then just copy)
1028 //
1029 if (versionix < targetix)
1030 convert_samples(ifd, ofd, &irh, versionix, targetix);
1031 else
1032 copy_file(ifd, ofd);
1033
1034 close(ifd);
1035 close(ofd);
1036
1037 return 0;
1038 }
1039
1040 //
1041 // Function that reads the input file sample-by-sample,
1042 // converts it to an output sample and writes that to the output file
1043 //
1044 static void
1045 convert_samples(int ifd, int ofd, struct rawheader *irh, int ivix, int ovix)
1046 {
1047 struct rawrecord irr, orr;
1048 int i, t;
1049 count_t count = 0;
1050
1051 while ( read(ifd, &irr, irh->rawreclen) == irh->rawreclen)
1052 {
1053 count++;
1054
1055 // read compressed system-level statistics and decompress
1056 //
1057 if ( !getrawsstat(ifd, convs[ivix].sstat, irr.scomplen) )
1058 exit(7);
1059
1060 // read compressed process-level statistics and decompress
1061 //
1062 convs[ivix].tstat = malloc(convs[ivix].tstatlen * irr.ndeviat);
1063
1064 ptrverify(convs[ivix].tstat,
1065 "Malloc failed for %d stored tasks\n", irr.ndeviat);
1066
1067 if ( !getrawtstat(ifd, convs[ivix].tstat,
1068 irr.pcomplen, irr.ndeviat) )
1069 exit(7);
1070
1071 // STEP-BY-STEP CONVERSION FROM OLD VERSION TO NEW VERSION
1072 //
1073 for (i=ivix; i < ovix; i++)
1074 {
1075 // convert system-level statistics to newer version
1076 //
1077 memset(convs[i+1].sstat, 0, convs[i+1].sstatlen);
1078
1079 do_sconvert(&(convs[i].scpu), &(convs[i+1].scpu));
1080 do_sconvert(&(convs[i].smem), &(convs[i+1].smem));
1081 do_sconvert(&(convs[i].snet), &(convs[i+1].snet));
1082 do_sconvert(&(convs[i].sintf), &(convs[i+1].sintf));
1083 do_sconvert(&(convs[i].sdsk), &(convs[i+1].sdsk));
1084 do_sconvert(&(convs[i].snfs), &(convs[i+1].snfs));
1085 do_sconvert(&(convs[i].scfs), &(convs[i+1].scfs));
1086 do_sconvert(&(convs[i].spsi), &(convs[i+1].spsi));
1087 do_sconvert(&(convs[i].sgpu), &(convs[i+1].sgpu));
1088 do_sconvert(&(convs[i].sifb), &(convs[i+1].sifb));
1089 do_sconvert(&(convs[i].smnum), &(convs[i+1].smnum));
1090 do_sconvert(&(convs[i].scnum), &(convs[i+1].scnum));
1091 do_sconvert(&(convs[i].swww), &(convs[i+1].swww));
1092
1093 // convert process-level statistics to newer version
1094 //
1095 convs[i+1].tstat = malloc(convs[i+1].tstatlen *
1096 irr.ndeviat);
1097 ptrverify(convs[ivix].tstat,
1098 "Malloc failed for %d stored tasks\n", irr.ndeviat);
1099
1100 memset(convs[i+1].tstat, 0, convs[i+1].tstatlen *
1101 irr.ndeviat);
1102
1103 for (t=0; t < irr.ndeviat; t++) // for every task
1104 {
1105 do_tconvert(
1106 convs[i].tstat +(t*convs[i].tstatlen),
1107 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1108 &(convs[i].tgen), &(convs[i+1].tgen));
1109
1110 do_tconvert(
1111 convs[i].tstat +(t*convs[i].tstatlen),
1112 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1113 &(convs[i].tcpu), &(convs[i+1].tcpu));
1114
1115 do_tconvert(
1116 convs[i].tstat +(t*convs[i].tstatlen),
1117 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1118 &(convs[i].tdsk), &(convs[i+1].tdsk));
1119
1120 do_tconvert(
1121 convs[i].tstat +(t*convs[i].tstatlen),
1122 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1123 &(convs[i].tmem), &(convs[i+1].tmem));
1124
1125 do_tconvert(
1126 convs[i].tstat +(t*convs[i].tstatlen),
1127 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1128 &(convs[i].tnet), &(convs[i+1].tnet));
1129
1130 do_tconvert(
1131 convs[i].tstat +(t*convs[i].tstatlen),
1132 convs[i+1].tstat+(t*convs[i+1].tstatlen),
1133 &(convs[i].tgpu), &(convs[i+1].tgpu));
1134 }
1135
1136 free(convs[i].tstat);
1137 }
1138
1139 // write new sample to output file
1140 //
1141 orr = irr;
1142
1143 writesamp(ofd, &orr, convs[ovix].sstat, convs[ovix].sstatlen,
1144 convs[ovix].tstat, convs[ovix].tstatlen,
1145 irr.ndeviat);
1146
1147 // cleanup
1148 //
1149 free(convs[ovix].tstat);
1150 }
1151
1152 printf("Samples converted: %llu\n", count);
1153 }
1154
1155 //
1156 // Function that calls the appropriate function to convert a struct
1157 // from the sstat structure
1158 //
1159 static void
1160 do_sconvert(struct sconvstruct *cur, struct sconvstruct *next)
1161 {
1162 if (next->structconv)
1163 {
1164 (*(next->structconv))(cur->structptr, next->structptr,
1165 cur->structsize, next->structsize);
1166 }
1167 }
1168
1169 //
1170 // Function that calls the appropriate function to convert a struct
1171 // from one of the tstat structures
1172 //
1173 static void
1174 do_tconvert(void *curtstat, void *nexttstat,
1175 struct tconvstruct *cur, struct tconvstruct *next)
1176 {
1177 if (next->structconv)
1178 {
1179 (*(next->structconv))(curtstat + cur->structoffset,
1180 nexttstat + next->structoffset,
1181 cur->structsize, next->structsize);
1182 }
1183 }
1184
1185
1186 //
1187 // Function to copy input file transparently to output file
1188 //
1189 static void
1190 copy_file(int ifd, int ofd)
1191 {
1192 unsigned char buf[64*1024];
1193 int nr, nw;
1194
1195 (void) lseek(ifd, 0, SEEK_SET);
1196 (void) lseek(ofd, 0, SEEK_SET);
1197
1198 while ( (nr = read(ifd, buf, sizeof buf)) > 0)
1199 {
1200 if ( (nw = write(ofd, buf, nr)) < nr)
1201 {
1202 if (nw == -1)
1203 {
1204 perror("write output file");
1205 exit(42);
1206 }
1207 else
1208 {
1209 fprintf(stderr,
1210 "Output file saturated\n");
1211 exit(42);
1212 }
1213 }
1214 }
1215
1216 if (nr == -1)
1217 {
1218 perror("read input file");
1219 exit(42);
1220 }
1221 else
1222 {
1223 printf("Raw file copied (version already up-to-date)\n");
1224 }
1225 }
1226
1227 //
1228 // Function that opens an existing raw file and
1229 // verifies the magic number
1230 //
1231 static int
1232 openin(char *infile)
1233 {
1234 int rawfd;
1235
1236 /*
1237 ** open raw file for reading
1238 */
1239 if ( (rawfd = open(infile, O_RDONLY)) == -1)
1240 {
1241 fprintf(stderr, "%s - ", infile);
1242 perror("open for reading");
1243 return -1;
1244 }
1245
1246 return rawfd;
1247 }
1248
1249 //
1250 // Function that reads a chunk of bytes from
1251 // the input raw file
1252 //
1253 static void
1254 readin(int rawfd, void *buf, int size)
1255 {
1256 /*
1257 ** read the requested chunk and verify
1258 */
1259 if ( read(rawfd, buf, size) < size)
1260 {
1261 fprintf(stderr, "can not read raw file\n");
1262 close(rawfd);
1263 exit(9);
1264 }
1265 }
1266
1267
1268 //
1269 // Function that creates a raw log for output
1270 //
1271 static int
1272 openout(char *outfile)
1273 {
1274 int rawfd;
1275
1276 /*
1277 ** create new output file
1278 */
1279 if ( (rawfd = creat(outfile, 0666)) == -1)
1280 {
1281 fprintf(stderr, "%s - ", outfile);
1282 perror("create raw output file");
1283 return -1;
1284 }
1285
1286 return rawfd;
1287 }
1288
1289 //
1290 // Function that reads a chunk of bytes from
1291 // the input raw file
1292 //
1293 static void
1294 writeout(int rawfd, void *buf, int size)
1295 {
1296 /*
1297 ** write the provided chunk and verify
1298 */
1299 if ( write(rawfd, buf, size) < size)
1300 {
1301 fprintf(stderr, "can not write raw file\n");
1302 close(rawfd);
1303 exit(10);
1304 }
1305 }
1306
1307 //
1308 // Function that shows the usage message
1309 //
1310 void
1311 prusage(char *name)
1312 {
1313 fprintf(stderr,
1314 "Usage: %s [-t version] rawinput [rawoutput]\n", name);
1315 fprintf(stderr,
1316 "\t-t version target version (default: %d.%d) for output\n",
1317 (convs[numconvs-1].version >> 8) & 0x7f,
1318 convs[numconvs-1].version & 0x7f);
1319
1320 exit(1);
1321 }
1322
1323
1324 //
1325 // Function to read the system-level statistics from the current offset
1326 //
1327 static int
1328 getrawsstat(int rawfd, struct sstat *sp, int complen)
1329 {
1330 Byte *compbuf;
1331 unsigned long uncomplen = sizeof(struct sstat);
1332 int rv;
1333
1334 compbuf = malloc(complen);
1335
1336 ptrverify(compbuf, "Malloc failed for reading compressed sysstats\n");
1337
1338 if ( read(rawfd, compbuf, complen) < complen)
1339 {
1340 free(compbuf);
1341 fprintf(stderr,
1342 "Failed to read %d bytes for system\n", complen);
1343 return 0;
1344 }
1345
1346 rv = uncompress((Byte *)sp, &uncomplen, compbuf, complen);
1347
1348 testcompval(rv, "uncompress");
1349
1350 free(compbuf);
1351
1352 return 1;
1353 }
1354
1355 //
1356 // Function to read the process-level statistics from the current offset
1357 //
1358 static int
1359 getrawtstat(int rawfd, struct tstat *pp, int complen, int ndeviat)
1360 {
1361 Byte *compbuf;
1362 unsigned long uncomplen = sizeof(struct tstat) * ndeviat;
1363 int rv;
1364
1365 compbuf = malloc(complen);
1366
1367 ptrverify(compbuf, "Malloc failed for reading compressed procstats\n");
1368
1369 if ( read(rawfd, compbuf, complen) < complen)
1370 {
1371 free(compbuf);
1372 fprintf(stderr,
1373 "Failed to read %d bytes for tasks\n", complen);
1374 return 0;
1375 }
1376
1377 rv = uncompress((Byte *)pp, &uncomplen, compbuf, complen);
1378
1379 testcompval(rv, "uncompress");
1380
1381 free(compbuf);
1382
1383 return 1;
1384 }
1385
1386 //
1387 // Function that writes a new sample to the output file
1388 //
1389 static void
1390 writesamp(int ofd, struct rawrecord *rr,
1391 void *sstat, int sstatlen, void *tstat, int tstatlen, int ntask)
1392 {
1393 int rv;
1394 Byte scompbuf[sstatlen], *pcompbuf;
1395 unsigned long scomplen = sizeof scompbuf;
1396 unsigned long pcomplen = tstatlen * ntask;
1397
1398 /*
1399 ** compress system- and process-level statistics
1400 */
1401 rv = compress(scompbuf, &scomplen,
1402 (Byte *)sstat, (unsigned long)sstatlen);
1403
1404 testcompval(rv, "compress");
1405
1406 pcompbuf = malloc(pcomplen);
1407
1408 ptrverify(pcompbuf, "Malloc failed for compression buffer\n");
1409
1410 rv = compress(pcompbuf, &pcomplen, (Byte *)tstat,
1411 (unsigned long)pcomplen);
1412
1413 testcompval(rv, "compress");
1414
1415 rr->scomplen = scomplen;
1416 rr->pcomplen = pcomplen;
1417
1418 if ( write(ofd, rr, sizeof *rr) == -1)
1419 {
1420 perror("write raw record");
1421 exit(7);
1422 }
1423
1424 /*
1425 ** write compressed system status structure to file
1426 */
1427 if ( write(ofd, scompbuf, scomplen) == -1)
1428 {
1429 perror("write raw status record");
1430 exit(7);
1431 }
1432
1433 /*
1434 ** write compressed list of process status structures to file
1435 */
1436 if ( write(ofd, pcompbuf, pcomplen) == -1)
1437 {
1438 perror("write raw process record");
1439 exit(7);
1440 }
1441
1442 free(pcompbuf);
1443 }
1444
1445
1446 //
1447 // check success of (de)compression
1448 //
1449 static void
1450 testcompval(int rv, char *func)
1451 {
1452 switch (rv)
1453 {
1454 case Z_OK:
1455 case Z_STREAM_END:
1456 case Z_NEED_DICT:
1457 break;
1458
1459 case Z_MEM_ERROR:
1460 fprintf(stderr, "%s: failed due to lack of memory\n", func);
1461 exit(7);
1462
1463 case Z_BUF_ERROR:
1464 fprintf(stderr, "%s: failed due to lack of room in buffer\n",
1465 func);
1466 exit(7);
1467
1468 case Z_DATA_ERROR:
1469 fprintf(stderr,
1470 "%s: failed due to corrupted/incomplete data\n", func);
1471 exit(7);
1472
1473 default:
1474 fprintf(stderr,
1475 "%s: unexpected error %d\n", func, rv);
1476 exit(7);
1477 }
1478 }
1479
1480 //
1481 // generic pointer verification after malloc
1482 //
1483 void
1484 ptrverify(const void *ptr, const char *errormsg, ...)
1485 {
1486 if (!ptr)
1487 {
1488 va_list args;
1489 va_start(args, errormsg);
1490 vfprintf(stderr, errormsg, args);
1491 va_end (args);
1492
1493 exit(13);
1494 }
1495 }