]> granicus.if.org Git - sysstat/blob - sa_conv.c
sar/sadf: Use size_t type for size variable in read() syscall
[sysstat] / sa_conv.c
1 /*
2  * sa_conv.c: Convert an old format sa file to the up-to-date format.
3  * (C) 1999-2017 by Sebastien GODARD (sysstat <at> orange.fr)
4  *
5  ***************************************************************************
6  * This program is free software; you can redistribute it and/or modify it *
7  * under the terms of the GNU General Public License as published  by  the *
8  * Free Software Foundation; either version 2 of the License, or (at  your *
9  * option) any later version.                                              *
10  *                                                                         *
11  * This program is distributed in the hope that it  will  be  useful,  but *
12  * WITHOUT ANY WARRANTY; without the implied warranty  of  MERCHANTABILITY *
13  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
14  * for more details.                                                       *
15  *                                                                         *
16  * You should have received a copy of the GNU General Public License along *
17  * with this program; if not, write to the Free Software Foundation, Inc., *
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA              *
19  ***************************************************************************
20  */
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <errno.h>
27
28 #include "version.h"
29 #include "sadf.h"
30 #include "sa_conv.h"
31
32 #ifdef USE_NLS
33 # include <locale.h>
34 # include <libintl.h>
35 # define _(string) gettext(string)
36 #else
37 # define _(string) (string)
38 #endif
39
40 extern int endian_mismatch;
41 extern unsigned int act_types_nr[];
42 extern unsigned int rec_types_nr[];
43 extern unsigned int hdr_types_nr[];
44
45 unsigned int oact_types_nr[] = {OLD_FILE_ACTIVITY_ULL_NR, OLD_FILE_ACTIVITY_UL_NR, OLD_FILE_ACTIVITY_U_NR};
46
47 /*
48  ***************************************************************************
49  * Read and upgrade file's magic data section.
50  *
51  * IN:
52  * @dfile       System activity data file name.
53  * @stdfd       File descriptor for STDOUT.
54  *
55  * OUT:
56  * @fd          File descriptor for sa datafile to convert.
57  * @file_magic  File's magic structure.
58  * @hdr_size    Size of header structure read from file.
59  * @previous_format
60  *              Format magic number of file to convert, converted to
61  *              current endianness.
62  * @endian_mismatch
63  *              TRUE if data read from file don't match current machine's
64  *              endianness.
65  *
66  * RETURNS:
67  * -1 on error, 0 otherwise.
68  ***************************************************************************
69  */
70 int upgrade_magic_section(char dfile[], int *fd, int stdfd, struct file_magic *file_magic,
71                           unsigned int *hdr_size, int *previous_format, int *endian_mismatch)
72 {
73         struct file_magic fm;
74         unsigned int fm_types_nr[] = {FILE_MAGIC_ULL_NR, FILE_MAGIC_UL_NR, FILE_MAGIC_U_NR};
75
76         /* Open and read sa magic structure */
77         sa_open_read_magic(fd, dfile, file_magic, TRUE, endian_mismatch, FALSE);
78
79         switch (file_magic->format_magic) {
80
81                 case FORMAT_MAGIC:
82                 case FORMAT_MAGIC_SWAPPED:
83                         *previous_format = FORMAT_MAGIC;
84                         return 0;
85                         break;
86
87                 case FORMAT_MAGIC_2171:
88                 case FORMAT_MAGIC_2171_SWAPPED:
89                         *previous_format = FORMAT_MAGIC_2171;
90                         break;
91
92                 case FORMAT_MAGIC_2173:
93                 case FORMAT_MAGIC_2173_SWAPPED:
94                         *previous_format = FORMAT_MAGIC_2173;
95                         break;
96
97                 default:
98                         fprintf(stderr, _("Cannot convert the format of this file\n"));
99                         return -1;
100                         break;
101         }
102
103         fprintf(stderr, "file_magic: ");
104         if (*previous_format == FORMAT_MAGIC_2171) {
105                 /*
106                  * We have read too many bytes: file_magic structure
107                  * was smaller with previous sysstat versions.
108                  * Go back 4 (unsigned int header_size) + 64 (char pad[64]) bytes.
109                  */
110                 if (lseek(*fd, -68, SEEK_CUR) < 0) {
111                         fprintf(stderr, "\nlseek: %s\n", strerror(errno));
112                         return -1;
113                 }
114         }
115
116         /* Set format magic number to that of current version */
117         file_magic->format_magic = (*endian_mismatch ? FORMAT_MAGIC_SWAPPED
118                                                      : FORMAT_MAGIC);
119
120         /* Save original header structure's size */
121         *hdr_size = file_magic->header_size;
122
123         /* Fill new structure members */
124         file_magic->header_size = FILE_HEADER_SIZE;
125         file_magic->hdr_types_nr[0] = FILE_HEADER_ULL_NR;
126         file_magic->hdr_types_nr[1] = FILE_HEADER_UL_NR;
127         file_magic->hdr_types_nr[2] = FILE_HEADER_U_NR;
128         memset(file_magic->pad, 0, sizeof(unsigned char) * FILE_MAGIC_PADDING);
129
130         /* Indicate that file has been upgraded */
131         enum_version_nr(&fm);
132         file_magic->upgraded = (fm.sysstat_patchlevel << 8) +
133                                fm.sysstat_sublevel + 1;
134
135         memcpy(&fm, file_magic, FILE_MAGIC_SIZE);
136         /* Restore endianness before writing */
137         if (*endian_mismatch) {
138                 /* Start swapping at field "header_size" position */
139                 swap_struct(fm_types_nr, &(fm.header_size), 0);
140         }
141
142         /* Write file's magic structure */
143         if (write(stdfd, &fm, FILE_MAGIC_SIZE) != FILE_MAGIC_SIZE) {
144                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
145                 return -1;
146         }
147         fprintf(stderr, "OK\n");
148
149         return 0;
150 }
151
152 /*
153  ***************************************************************************
154  * Upgrade file_header structure (from 0x2171 format to current format).
155  *
156  * IN:
157  * @buffer      File's header structure (as read from file).
158  * @previous_format
159  *              Format magic number of file to convert.
160  * @endian_mismatch
161  *              TRUE if data read from file don't match current
162  *              machine's endianness.
163  *
164  * OUT:
165  * @file_hdr    File's header structure (up-to-date format).
166  * @arch_64     TRUE if file's data come from a 64-bit machine.
167  * @vol_act_nr  Number of volatile activity structures following a restart
168  *              record for 0x2173 file format.
169  ***************************************************************************
170  */
171 void upgrade_file_header(void *buffer, struct file_header *file_hdr, int previous_format,
172                          int endian_mismatch, int *arch_64, unsigned int *vol_act_nr)
173 {
174         struct file_header_2171 *f_hdr_2171 = (struct file_header_2171 *) buffer;
175         struct file_header_2173 *f_hdr_2173 = (struct file_header_2173 *) buffer;
176         unsigned int hdr_2171_types_nr[] = {FILE_HEADER_2171_ULL_NR, FILE_HEADER_2171_UL_NR, FILE_HEADER_2171_U_NR};
177         unsigned int hdr_2173_types_nr[] = {FILE_HEADER_2173_ULL_NR, FILE_HEADER_2173_UL_NR, FILE_HEADER_2173_U_NR};
178         int i;
179
180         memset(file_hdr, 0, FILE_HEADER_SIZE);
181         file_hdr->sa_hz = HZ;
182
183         if (previous_format == FORMAT_MAGIC_2171) {
184                 *arch_64 = (f_hdr_2171->sa_sizeof_long == SIZEOF_LONG_64BIT);
185
186                 /* Normalize endianness for f_hdr_2171 structure */
187                 if (endian_mismatch) {
188                         swap_struct(hdr_2171_types_nr, f_hdr_2171, *arch_64);
189                 }
190
191                 file_hdr->sa_ust_time = (unsigned long long) f_hdr_2171->sa_ust_time;
192                 /* sa_cpu_nr field will be updated later */
193                 file_hdr->sa_act_nr = f_hdr_2171->sa_act_nr;
194                 file_hdr->sa_year = (int) f_hdr_2171->sa_year;
195                 file_hdr->sa_day = f_hdr_2171->sa_day;
196                 file_hdr->sa_month = f_hdr_2171->sa_month;
197                 file_hdr->sa_sizeof_long = f_hdr_2171->sa_sizeof_long;
198                 strncpy(file_hdr->sa_sysname, f_hdr_2171->sa_sysname, UTSNAME_LEN);
199                 file_hdr->sa_sysname[UTSNAME_LEN - 1] = '\0';
200                 strncpy(file_hdr->sa_nodename, f_hdr_2171->sa_nodename, UTSNAME_LEN);
201                 file_hdr->sa_nodename[UTSNAME_LEN - 1] = '\0';
202                 strncpy(file_hdr->sa_release, f_hdr_2171->sa_release, UTSNAME_LEN);
203                 file_hdr->sa_release[UTSNAME_LEN - 1] = '\0';
204                 strncpy(file_hdr->sa_machine, f_hdr_2171->sa_machine, UTSNAME_LEN);
205                 file_hdr->sa_machine[UTSNAME_LEN - 1] = '\0';
206         }
207
208         else if (previous_format == FORMAT_MAGIC_2173) {
209                 *arch_64 = (f_hdr_2173->sa_sizeof_long == SIZEOF_LONG_64BIT);
210
211                 /* Normalize endianness for f_hdr_2171 structure */
212                 if (endian_mismatch) {
213                         swap_struct(hdr_2173_types_nr, f_hdr_2173, *arch_64);
214                 }
215
216                 file_hdr->sa_ust_time = (unsigned long long) f_hdr_2173->sa_ust_time;
217                 /* sa_cpu_nr field will be updated later */
218                 file_hdr->sa_act_nr = f_hdr_2173->sa_act_nr;
219                 file_hdr->sa_year = (int) f_hdr_2173->sa_year;
220                 file_hdr->sa_day = f_hdr_2173->sa_day;
221                 file_hdr->sa_month = f_hdr_2173->sa_month;
222                 file_hdr->sa_sizeof_long = f_hdr_2173->sa_sizeof_long;
223                 strncpy(file_hdr->sa_sysname, f_hdr_2173->sa_sysname, UTSNAME_LEN);
224                 file_hdr->sa_sysname[UTSNAME_LEN - 1] = '\0';
225                 strncpy(file_hdr->sa_nodename, f_hdr_2173->sa_nodename, UTSNAME_LEN);
226                 file_hdr->sa_nodename[UTSNAME_LEN - 1] = '\0';
227                 strncpy(file_hdr->sa_release, f_hdr_2173->sa_release, UTSNAME_LEN);
228                 file_hdr->sa_release[UTSNAME_LEN - 1] = '\0';
229                 strncpy(file_hdr->sa_machine, f_hdr_2173->sa_machine, UTSNAME_LEN);
230                 file_hdr->sa_machine[UTSNAME_LEN - 1] = '\0';
231
232                 *vol_act_nr = f_hdr_2173->sa_vol_act_nr;
233         }
234
235         for (i = 0; i < 3; i++) {
236                 file_hdr->act_types_nr[i] = act_types_nr[i];
237                 file_hdr->rec_types_nr[i] = rec_types_nr[i];
238         }
239         file_hdr->act_size = FILE_ACTIVITY_SIZE;
240         file_hdr->rec_size = RECORD_HEADER_SIZE;
241 }
242
243 /*
244  ***************************************************************************
245  * Read and upgrade file's header section.
246  *
247  * IN:
248  * @dfile       System activity data file name.
249  * @fd          File descriptor for sa datafile to convert.
250  * @stdfd       File descriptor for STDOUT.
251  * @act         Array of activities.
252  * @file_magic  File's magic structure.
253  * @hdr_size    Size of header structure read from file.
254  * @previous_format
255  *              Format magic number of file to convert.
256  * @endian_mismatch
257  *              TRUE if data read from file don't match current machine's
258  *              endianness.
259  *
260  * OUT:
261  * @file_hdr    File's header structure (up-to-date format).
262  * @arch_64     TRUE if file's data come from a 64-bit machine.
263  * @vol_act_nr  Number of volatile activity structures following a restart
264  *              record for 0x2173 file format.
265  * @ofile_actlst
266  *              Activity list in file.
267  *
268  * RETURNS:
269  * -1 on error, 0 otherwise.
270 ***************************************************************************
271  */
272 int upgrade_header_section(char dfile[], int fd, int stdfd, struct activity *act[],
273                            struct file_magic *file_magic, struct file_header *file_hdr,
274                            unsigned int hdr_size, int previous_format, int *arch_64,
275                            int endian_mismatch, unsigned int *vol_act_nr,
276                            struct old_file_activity **ofile_actlst)
277 {
278         struct old_file_activity *ofal;
279         struct file_header fh;
280         int i, n, p;
281         unsigned int a_cpu = FALSE;
282         void *buffer = NULL;
283
284         fprintf(stderr, "file_header: ");
285
286         /* Read file header structure */
287         n = (previous_format == FORMAT_MAGIC_2171 ? FILE_HEADER_SIZE_2171
288                                                   : hdr_size);
289         SREALLOC(buffer, char, n);
290         sa_fread(fd, buffer, (size_t) n, HARD_SIZE);
291
292         /* Upgrade file_header structure */
293         upgrade_file_header(buffer, file_hdr, previous_format,
294                             endian_mismatch, arch_64, vol_act_nr);
295
296         free(buffer);
297
298         /* Sanity check */
299         if (file_hdr->sa_act_nr > MAX_NR_ACT)
300                 goto invalid_header;
301
302         /* Read file activity list */
303         SREALLOC(*ofile_actlst, struct old_file_activity, OLD_FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr);
304         ofal = *ofile_actlst;
305
306         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++) {
307
308                 sa_fread(fd, ofal, OLD_FILE_ACTIVITY_SIZE, HARD_SIZE);
309
310                 /* Normalize endianness for file_activity structures */
311                 if (endian_mismatch) {
312                         swap_struct(oact_types_nr, ofal, *arch_64);
313                 }
314
315                 if ((ofal->nr < 1) || (ofal->nr2 < 1))
316                         /*
317                          * Every activity, known or unknown,
318                          * should have at least one item and sub-item.
319                          */
320                         goto invalid_header;
321
322                 if ((p = get_activity_position(act, ofal->id, RESUME_IF_NOT_FOUND)) >= 0) {
323                         /* This is a known activity, maybe with an unknown format */
324
325                         if ((ofal->id == A_CPU) && !a_cpu) {
326                                 /*
327                                  * We have found the CPU activity: Set sa_cpu_nr field
328                                  * in file_header structure that should contains the
329                                  * number of CPU when the file was created.
330                                  */
331                                 file_hdr->sa_cpu_nr = ofal->nr;
332                                 a_cpu = TRUE;
333                         }
334
335                         /* Size of an activity cannot be zero */
336                         if (!ofal->size)
337                                 goto invalid_header;
338
339                         /* Size of activity in file is larger than up-to-date activity size */
340                         if (ofal->size > act[p]->msize) {
341                                 act[p]->msize = ofal->size;
342                         }
343
344                         /*
345                          * When upgrading a file:
346                          * ofal->size   : Size of an item for current activity, as
347                          *                read from the file.
348                          * act[p]->msize: Size of the buffer in memory where an item
349                          *                for current activity, as read from the file,
350                          *                will be saved. We have:
351                          *                act[p]->msize >= {ofal->size ; act[p]->fsize}
352                          * act[p]->fsize: Size of an item for current activity with
353                          *                up-to-date format.
354                          */
355                         act[p]->nr_ini = ofal->nr;
356                         act[p]->nr2    = ofal->nr2;
357                         /*
358                          * Don't set act[p]->fsize! Should retain the size of an item
359                          * for up-to-date format!
360                          */
361                 }
362         }
363
364         if (!a_cpu) {
365                 /*
366                  * CPU activity should always be in file for versions older than 11.7.1
367                  * and have a known format (expected magical number).
368                  */
369                 fprintf(stderr, _("\nCPU activity not found in file. Aborting...\n"));
370                 return -1;
371         }
372
373         memcpy(&fh, file_hdr, FILE_HEADER_SIZE);
374         /* Restore endianness before writing */
375         if (endian_mismatch) {
376                 /* Start swapping at field "header_size" position */
377                 swap_struct(hdr_types_nr, &fh, *arch_64);
378         }
379
380         /* Write file_header structure */
381         if ((n = write(stdfd, &fh, FILE_HEADER_SIZE)) != FILE_HEADER_SIZE) {
382                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
383                 return -1;
384         }
385
386         fprintf(stderr, "OK\n");
387
388         return 0;
389
390 invalid_header:
391
392         fprintf(stderr, _("\nInvalid data found. Aborting...\n"));
393
394         return -1;
395
396 }
397
398 /*
399  ***************************************************************************
400  * Convert a long integer value to a long long integer value.
401  * The long integer value may be 32 or 64-bit wide and come from a 32 or
402  * 64-bit architecture.
403  *
404  * Note: Consider the value 0x01020304 read on a 32-bit machine.
405  * Big-endian, saved as:   01 02 03 04
406  * Lille-endian, saved as: 04 03 02 01
407  * The value should be saved as an 64-bit value and endianness should be
408  * preserved:
409  * Big-endian:    00 00 00 00 01 02 03 04
410  * Little-endian: 04 03 02 01 00 00 00 00
411  *
412  * IN:
413  * @buffer      Address of value to convert.
414  * @endian_mismatch
415  *              TRUE if data read from file don't match current machine's
416  *              endianness.
417  * @arch_64     TRUE if file's data come from a 64-bit machine.
418  ***************************************************************************
419  */
420 unsigned long long moveto_long_long(void *buffer, int endian_mismatch, int arch_64)
421 {
422         unsigned int *u_int;
423         unsigned long long *ull_int, ull_i;
424
425         if (arch_64) {
426                 ull_int = (unsigned long long *) buffer;
427                 return *ull_int;
428         }
429
430         u_int = (unsigned int *) buffer;
431         if (endian_mismatch) {
432                 ull_i = (unsigned long long) *u_int;
433                 return (ull_i >> 32) | (ull_i << 32);
434         }
435         else {
436                 return (unsigned long long) *u_int;
437         }
438 }
439
440 /*
441  ***************************************************************************
442  * Upgrade stats_cpu structure (from ACTIVITY_MAGIC_BASE format to
443  * ACTIVITY_MAGIC_BASE + 1 format).
444  *
445  * IN:
446  * @act         Array of activities.
447  * @p           Position of activity in array.
448  * @st_size     Size of the structure read from file.
449  ***************************************************************************
450  */
451 void upgrade_stats_cpu(struct activity *act[], int p, int st_size)
452 {
453         int i;
454         struct stats_cpu *scc;
455         struct stats_cpu_8a *scp;
456
457         for (i = 0; i < act[p]->nr_ini; i++) {
458                 /*
459                  * For previous structure's format: Use msize (which has possibly been set to
460                  * the size of the structure read from disk if it's greater than that of
461                  * current format: See upgrade_header_section()).
462                  * For current structure format: Use fsize. This is the normal size of
463                  * structure's up-to-date format that will be written to file.
464                  */
465                 scp = (struct stats_cpu_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
466                 scc = (struct stats_cpu *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
467
468                 scc->cpu_user = scp->cpu_user;
469                 scc->cpu_nice = scp->cpu_nice;
470                 scc->cpu_sys = scp->cpu_sys;
471                 scc->cpu_idle = scp->cpu_idle;
472                 scc->cpu_iowait = scp->cpu_iowait;
473                 scc->cpu_steal = scp->cpu_steal;
474                 scc->cpu_hardirq = scp->cpu_hardirq;
475                 scc->cpu_softirq = scp->cpu_softirq;
476                 scc->cpu_guest = scp->cpu_guest;
477
478                 if (st_size >= STATS_CPU_8A_SIZE) {
479                         /* guest_nice field has been added without a structure format change */
480                         scc->cpu_guest_nice = scp->cpu_guest_nice;
481                 }
482         }
483 }
484
485 /*
486  ***************************************************************************
487  * Upgrade stats_pcsw structure (from ACTIVITY_MAGIC_BASE format to
488  * ACTIVITY_MAGIC_BASE + 1 format).
489  *
490  * IN:
491  * @act         Array of activities.
492  * @p           Position of activity in array.
493  ***************************************************************************
494  */
495 void upgrade_stats_pcsw(struct activity *act[], int p)
496 {
497         struct stats_pcsw *spc = (struct stats_pcsw *) act[p]->buf[1];
498         struct stats_pcsw_8a *spp = (struct stats_pcsw_8a *) act[p]->buf[0];
499
500         spc->context_switch = spp->context_switch;
501         /*
502          * Copy a long into a long. Take into account that file may have been
503          * created on a 64-bit machine and we may be converting on a 32-bit machine.
504          */
505         memcpy(&spc->processes, &spp->processes, 8);
506 }
507
508 /*
509  ***************************************************************************
510  * Upgrade stats_irq structure (from ACTIVITY_MAGIC_BASE format to
511  * ACTIVITY_MAGIC_BASE + 1 format).
512  *
513  * IN:
514  * @act         Array of activities.
515  * @p           Position of activity in array.
516  ***************************************************************************
517  */
518 void upgrade_stats_irq(struct activity *act[], int p)
519 {
520         int i;
521         struct stats_irq *sic;
522         struct stats_irq_8a *sip;
523
524         for (i = 0; i < act[p]->nr_ini; i++) {
525                 sip = (struct stats_irq_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
526                 sic = (struct stats_irq *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
527
528                 sic->irq_nr = sip->irq_nr;
529         }
530 }
531
532 /*
533  ***************************************************************************
534  * Upgrade stats_io structure (from ACTIVITY_MAGIC_BASE format to
535  * ACTIVITY_MAGIC_BASE + 1 format).
536  *
537  * IN:
538  * @act         Array of activities.
539  * @p           Position of activity in array.
540  * @endian_mismatch
541  *              TRUE if data read from file don't match current machine's
542  *              endianness.
543  ***************************************************************************
544  */
545 void upgrade_stats_io(struct activity *act[], int p, int endian_mismatch)
546 {
547         struct stats_io *sic = (struct stats_io *) act[p]->buf[1];
548         struct stats_io_8a *sip = (struct stats_io_8a *) act[p]->buf[0];
549
550         sic->dk_drive = moveto_long_long(&sip->dk_drive, endian_mismatch, FALSE);
551         sic->dk_drive_rio = moveto_long_long(&sip->dk_drive_rio, endian_mismatch, FALSE);
552         sic->dk_drive_wio = moveto_long_long(&sip->dk_drive_wio, endian_mismatch, FALSE);
553         sic->dk_drive_rblk = moveto_long_long(&sip->dk_drive_rblk, endian_mismatch, FALSE);
554         sic->dk_drive_wblk = moveto_long_long(&sip->dk_drive_wblk, endian_mismatch, FALSE);
555 }
556
557 /*
558  ***************************************************************************
559  * Upgrade stats_memory structure (from ACTIVITY_MAGIC_BASE format to
560  * ACTIVITY_MAGIC_BASE + 1 format).
561  *
562  * IN:
563  * @act         Array of activities.
564  * @p           Position of activity in array.
565  * @st_size     Size of the structure read from file.
566  * @endian_mismatch
567  *              TRUE if data read from file don't match current machine's
568  *              endianness.
569  * @arch_64     TRUE if file's data come from a 64-bit machine.
570  ***************************************************************************
571  */
572 void upgrade_stats_memory(struct activity *act[], int p, int st_size,
573                           int endian_mismatch, int arch_64)
574 {
575         struct stats_memory *smc = (struct stats_memory *) act[p]->buf[1];
576         struct stats_memory_8a *smp = (struct stats_memory_8a *) act[p]->buf[0];
577
578         smc->frmkb = moveto_long_long(&smp->frmkb, endian_mismatch, arch_64);
579         smc->bufkb = moveto_long_long(&smp->bufkb, endian_mismatch, arch_64);
580         smc->camkb = moveto_long_long(&smp->camkb, endian_mismatch, arch_64);
581         smc->tlmkb = moveto_long_long(&smp->tlmkb, endian_mismatch, arch_64);
582         smc->frskb = moveto_long_long(&smp->frskb, endian_mismatch, arch_64);
583         smc->tlskb = moveto_long_long(&smp->tlskb, endian_mismatch, arch_64);
584         smc->caskb = moveto_long_long(&smp->caskb, endian_mismatch, arch_64);
585         smc->comkb = moveto_long_long(&smp->comkb, endian_mismatch, arch_64);
586         smc->activekb = moveto_long_long(&smp->activekb, endian_mismatch, arch_64);
587         smc->inactkb = moveto_long_long(&smp->inactkb, endian_mismatch, arch_64);
588
589         /* Some fields have been added without a structure format change */
590         if (st_size >= STATS_MEMORY_8A_1_SIZE) {
591                                 smc->dirtykb = moveto_long_long(&smp->dirtykb, endian_mismatch, arch_64);
592         }
593         if (st_size >= STATS_MEMORY_8A_2_SIZE) {
594                 smc->anonpgkb = moveto_long_long(&smp->anonpgkb, endian_mismatch, arch_64);
595                 smc->slabkb = moveto_long_long(&smp->slabkb, endian_mismatch, arch_64);
596                 smc->kstackkb = moveto_long_long(&smp->kstackkb, endian_mismatch, arch_64);
597                 smc->pgtblkb = moveto_long_long(&smp->pgtblkb, endian_mismatch, arch_64);
598                 smc->vmusedkb = moveto_long_long(&smp->vmusedkb, endian_mismatch, arch_64);
599         }
600         if (st_size >= STATS_MEMORY_8A_SIZE) {
601                 smc->availablekb = moveto_long_long(&(smp->availablekb), endian_mismatch, arch_64);;
602         }
603 }
604
605 /*
606  ***************************************************************************
607  * Upgrade stats_ktables structure (from ACTIVITY_MAGIC_BASE format to
608  * ACTIVITY_MAGIC_BASE + 1 format).
609  *
610  * IN:
611  * @act         Array of activities.
612  * @p           Position of activity in array.
613  * @endian_mismatch
614  *              TRUE if data read from file don't match current machine's
615  *              endianness.
616  ***************************************************************************
617  */
618 void upgrade_stats_ktables(struct activity *act[], int p, int endian_mismatch)
619 {
620         struct stats_ktables *skc = (struct stats_ktables *) act[p]->buf[1];
621         struct stats_ktables_8a *skp = (struct stats_ktables_8a *) act[p]->buf[0];
622
623         skc->file_used = moveto_long_long(&skp->file_used, endian_mismatch, FALSE);
624         skc->inode_used = moveto_long_long(&skp->inode_used, endian_mismatch, FALSE);
625         skc->dentry_stat = moveto_long_long(&skp->dentry_stat, endian_mismatch, FALSE);
626         skc->pty_nr = moveto_long_long(&skp->pty_nr, endian_mismatch, FALSE);
627 }
628
629 /*
630  ***************************************************************************
631  * Upgrade stats_queue structure (from ACTIVITY_MAGIC_BASE or
632  * ACTIVITY_MAGIC_BASE + 1 format to ACTIVITY_MAGIC_BASE + 2 format).
633  *
634  * IN:
635  * @act         Array of activities.
636  * @p           Position of activity in array.
637  * @magic       Structure format magic value.
638  * @endian_mismatch
639  *              TRUE if data read from file don't match current machine's
640  *              endianness.
641  * @arch_64     TRUE if file's data come from a 64-bit machine.
642  ***************************************************************************
643  */
644 void upgrade_stats_queue(struct activity *act[], int p, unsigned int magic,
645                          int endian_mismatch, int arch_64)
646 {
647         struct stats_queue *sqc = (struct stats_queue *) act[p]->buf[1];
648
649         if (magic == ACTIVITY_MAGIC_BASE) {
650                 struct stats_queue_8a *sqp = (struct stats_queue_8a *) act[p]->buf[0];
651
652                 sqc->nr_running = moveto_long_long(&sqp->nr_running, endian_mismatch, arch_64);
653                 sqc->procs_blocked = 0ULL;      /* New field */
654                 sqc->nr_threads = moveto_long_long(&sqp->nr_threads, endian_mismatch, FALSE);
655                 sqc->load_avg_1 = sqp->load_avg_1;
656                 sqc->load_avg_5 = sqp->load_avg_5;
657                 sqc->load_avg_15 = sqp->load_avg_15;
658         }
659         else {
660                 struct stats_queue_8b *sqp = (struct stats_queue_8b *) act[p]->buf[0];
661
662                 sqc->nr_running = moveto_long_long(&sqp->nr_running, endian_mismatch, arch_64);
663                 sqc->procs_blocked = moveto_long_long(&sqp->procs_blocked, endian_mismatch, arch_64);
664                 sqc->nr_threads = moveto_long_long(&sqp->nr_threads, endian_mismatch, FALSE);
665                 sqc->load_avg_1 = sqp->load_avg_1;
666                 sqc->load_avg_5 = sqp->load_avg_5;
667                 sqc->load_avg_15 = sqp->load_avg_15;
668         }
669 }
670
671 /*
672  ***************************************************************************
673  * Upgrade stats_serial structure (from ACTIVITY_MAGIC_BASE format to
674  * ACTIVITY_MAGIC_BASE + 1 format).
675  *
676  * IN:
677  * @act         Array of activities.
678  * @p           Position of activity in array.
679  * @st_size     Size of the structure read from file.
680  * @endian_mismatch
681  *              TRUE if data read from file don't match current machine's
682  *              endianness.
683  *
684  * RETURNS:
685  * Number of serial line structures that actually need to be written to
686  * disk.
687  ***************************************************************************
688  */
689 int upgrade_stats_serial(struct activity *act[], int p, int st_size, int endian_mismatch)
690 {
691         int i;
692         unsigned int line;
693         struct stats_serial *ssc;
694
695         /* Copy TTY stats to target structure */
696         memcpy(act[p]->buf[1], act[p]->buf[0], act[p]->nr_ini * st_size);
697
698         for (i = 0; i < act[p]->nr_ini; i++) {
699                 ssc = (struct stats_serial *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
700
701                 /* Line number now starts at 0 instead of 1 */
702                 line = (endian_mismatch ? __builtin_bswap32(ssc->line) : ssc->line);
703                 if (!line)
704                         break;
705                 line--;
706                 ssc->line = (endian_mismatch ? __builtin_bswap32(line) : line);
707         }
708
709         return i;
710 }
711
712 /*
713  ***************************************************************************
714  * Upgrade stats_disk structure (from ACTIVITY_MAGIC_BASE format to
715  * ACTIVITY_MAGIC_BASE + 1 format).
716  *
717  * IN:
718  * @act         Array of activities.
719  * @p           Position of activity in array.
720  * @magic       Structure format magic value.
721  * @endian_mismatch
722  *              TRUE if data read from file don't match current machine's
723  *              endianness.
724  * @arch_64     TRUE if file's data come from a 64-bit machine.
725  ***************************************************************************
726  */
727 void upgrade_stats_disk(struct activity *act[], int p, unsigned int magic,
728                         int endian_mismatch, int arch_64)
729 {
730         int i;
731         struct stats_disk *sdc;
732
733         if (magic == ACTIVITY_MAGIC_BASE) {
734                 struct stats_disk_8a *sdp;
735
736                 for (i = 0; i < act[p]->nr_ini; i++) {
737                         sdp = (struct stats_disk_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
738                         sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
739
740                         sdc->nr_ios = moveto_long_long(&sdp->nr_ios, endian_mismatch, arch_64);
741                         sdc->rd_sect = (unsigned long) sdp->rd_sect;
742                         sdc->wr_sect = (unsigned long) sdp->wr_sect;
743                         sdc->rd_ticks = (unsigned int) sdp->rd_ticks;
744                         sdc->wr_ticks = (unsigned int) sdp->wr_ticks;
745                         sdc->tot_ticks = (unsigned int) sdp->tot_ticks;
746                         sdc->rq_ticks = (unsigned int) sdp->rq_ticks;
747                         sdc->major = sdp->major;
748                         sdc->minor = sdp->minor;
749                 }
750         }
751         else {
752                 struct stats_disk_8b *sdp;
753
754                 for (i = 0; i < act[p]->nr_ini; i++) {
755                         sdp = (struct stats_disk_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
756                         sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
757
758                         sdc->nr_ios = sdp->nr_ios;
759                         memcpy(&sdc->rd_sect, &sdp->rd_sect, 8);
760                         memcpy(&sdc->wr_sect, &sdp->wr_sect, 8);
761                         sdc->rd_ticks = sdp->rd_ticks;
762                         sdc->wr_ticks = sdp->wr_ticks;
763                         sdc->tot_ticks = sdp->tot_ticks;
764                         sdc->rq_ticks = sdp->rq_ticks;
765                         sdc->major = sdp->major;
766                         sdc->minor = sdp->minor;
767                 }
768         }
769 }
770
771 /*
772  ***************************************************************************
773  * Upgrade stats_net_dev structure (from ACTIVITY_MAGIC_BASE or
774  * ACTIVITY_MAGIC_BASE + 1 format to ACTIVITY_MAGIC_BASE + 3 format).
775  *
776  * IN:
777  * @act         Array of activities.
778  * @p           Position of activity in array.
779  * @magic       Structure format magic value.
780  * @endian_mismatch
781  *              TRUE if data read from file don't match current machine's
782  *              endianness.
783  * @arch_64     TRUE if file's data come from a 64-bit machine.
784  ***************************************************************************
785  */
786 void upgrade_stats_net_dev(struct activity *act[], int p, unsigned int magic,
787                            int endian_mismatch, int arch_64)
788 {
789         int i;
790         struct stats_net_dev *sndc;
791
792         if (magic == ACTIVITY_MAGIC_BASE) {
793                 struct stats_net_dev_8a *sndp;
794
795                 for (i = 0; i < act[p]->nr_ini; i++) {
796                         sndp = (struct stats_net_dev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
797                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
798
799                         sndc->rx_packets = moveto_long_long(&sndp->rx_packets, endian_mismatch, arch_64);
800                         sndc->tx_packets = moveto_long_long(&sndp->tx_packets, endian_mismatch, arch_64);
801                         sndc->rx_bytes = moveto_long_long(&sndp->rx_bytes, endian_mismatch, arch_64);
802                         sndc->tx_bytes = moveto_long_long(&sndp->tx_bytes, endian_mismatch, arch_64);
803                         sndc->rx_compressed = moveto_long_long(&sndp->rx_compressed, endian_mismatch, arch_64);
804                         sndc->tx_compressed = moveto_long_long(&sndp->tx_compressed, endian_mismatch, arch_64);
805                         sndc->multicast = moveto_long_long(&sndp->multicast, endian_mismatch, arch_64);
806                         sndc->speed = 0; /* New field */
807                         strncpy(sndc->interface, sndp->interface, MAX_IFACE_LEN);
808                         sndc->interface[MAX_IFACE_LEN - 1] = '\0';
809                         sndc->duplex = '\0'; /* New field */
810                 }
811         }
812         else if (magic == ACTIVITY_MAGIC_BASE + 1) {
813                 struct stats_net_dev_8b *sndp;
814
815                 for (i = 0; i < act[p]->nr_ini; i++) {
816                         sndp = (struct stats_net_dev_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
817                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
818
819                         sndc->rx_packets = sndp->rx_packets;
820                         sndc->tx_packets = sndp->tx_packets;
821                         sndc->rx_bytes = sndp->rx_bytes;
822                         sndc->tx_bytes = sndp->tx_bytes;
823                         sndc->rx_compressed = sndp->rx_compressed;
824                         sndc->tx_compressed = sndp->tx_compressed;
825                         sndc->multicast = sndp->multicast;
826                         sndc->speed = 0; /* New field */
827                         strncpy(sndc->interface, sndp->interface, MAX_IFACE_LEN);
828                         sndc->interface[MAX_IFACE_LEN - 1] = '\0';
829                         sndc->duplex = '\0'; /* New field */
830                 }
831         }
832         else {
833                 struct stats_net_dev_8c *sndp;
834
835                 for (i = 0; i < act[p]->nr_ini; i++) {
836                         sndp = (struct stats_net_dev_8c *) ((char *) act[p]->buf[0] + i * act[p]->msize);
837                         sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
838
839                         sndc->rx_packets = sndp->rx_packets;
840                         sndc->tx_packets = sndp->tx_packets;
841                         sndc->rx_bytes = sndp->rx_bytes;
842                         sndc->tx_bytes = sndp->tx_bytes;
843                         sndc->rx_compressed = sndp->rx_compressed;
844                         sndc->tx_compressed = sndp->tx_compressed;
845                         sndc->multicast = sndp->multicast;
846                         sndc->speed = sndp->speed;
847                         strncpy(sndc->interface, sndp->interface, MAX_IFACE_LEN);
848                         sndc->interface[MAX_IFACE_LEN - 1] = '\0';
849                         sndc->duplex = sndp->duplex;
850                 }
851         }
852 }
853
854 /*
855  ***************************************************************************
856  * Upgrade stats_net_edev structure (from ACTIVITY_MAGIC_BASE format to
857  * ACTIVITY_MAGIC_BASE + 1 format).
858  *
859  * IN:
860  * @act         Array of activities.
861  * @p           Position of activity in array.
862  * @magic       Structure format magic value.
863  * @endian_mismatch
864  *              TRUE if data read from file don't match current machine's
865  *              endianness.
866  * @arch_64     TRUE if file's data come from a 64-bit machine.
867  ***************************************************************************
868  */
869 void upgrade_stats_net_edev(struct activity *act[], int p, unsigned int magic,
870                             int endian_mismatch, int arch_64)
871 {
872         int i;
873         struct stats_net_edev *snedc;
874
875         if (magic == ACTIVITY_MAGIC_BASE) {
876                 struct stats_net_edev_8a *snedp;
877
878                 for (i = 0; i < act[p]->nr_ini; i++) {
879                         snedp = (struct stats_net_edev_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
880                         snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
881
882                         snedc->collisions = moveto_long_long(&snedp->collisions, endian_mismatch, arch_64);
883                         snedc->rx_errors = moveto_long_long(&snedp->rx_errors, endian_mismatch, arch_64);
884                         snedc->tx_errors = moveto_long_long(&snedp->tx_errors, endian_mismatch, arch_64);
885                         snedc->rx_dropped = moveto_long_long(&snedp->rx_dropped, endian_mismatch, arch_64);
886                         snedc->tx_dropped = moveto_long_long(&snedp->tx_dropped, endian_mismatch, arch_64);
887                         snedc->rx_fifo_errors = moveto_long_long(&snedp->rx_fifo_errors, endian_mismatch, arch_64);
888                         snedc->tx_fifo_errors = moveto_long_long(&snedp->tx_fifo_errors, endian_mismatch, arch_64);
889                         snedc->rx_frame_errors = moveto_long_long(&snedp->rx_frame_errors, endian_mismatch, arch_64);
890                         snedc->tx_carrier_errors = moveto_long_long(&snedp->tx_carrier_errors, endian_mismatch, arch_64);
891                         strncpy(snedc->interface, snedp->interface, MAX_IFACE_LEN);
892                         snedc->interface[MAX_IFACE_LEN - 1] = '\0';
893                 }
894         }
895         else {
896                 struct stats_net_edev_8b *snedp;
897
898                 for (i = 0; i < act[p]->nr_ini; i++) {
899                         snedp = (struct stats_net_edev_8b *) ((char *) act[p]->buf[0] + i * act[p]->msize);
900                         snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
901
902                         snedc->collisions = snedp->collisions;
903                         snedc->rx_errors = snedp->rx_errors;
904                         snedc->tx_errors = snedp->tx_errors;
905                         snedc->rx_dropped = snedp->rx_dropped;
906                         snedc->tx_dropped = snedp->tx_dropped;
907                         snedc->rx_fifo_errors = snedp->rx_fifo_errors;
908                         snedc->tx_fifo_errors = snedp->tx_fifo_errors;
909                         snedc->rx_frame_errors = snedp->rx_frame_errors;
910                         snedc->tx_carrier_errors = snedp->tx_carrier_errors;
911                         strncpy(snedc->interface, snedp->interface, MAX_IFACE_LEN);
912                         snedc->interface[MAX_IFACE_LEN - 1] = '\0';
913                 }
914         }
915 }
916
917 /*
918  ***************************************************************************
919  * Upgrade stats_net_ip structure (from ACTIVITY_MAGIC_BASE format to
920  * ACTIVITY_MAGIC_BASE + 1 format).
921  *
922  * IN:
923  * @act         Array of activities.
924  * @p           Position of activity in array.
925  * @magic       Structure format magic value.
926  * @endian_mismatch
927  *              TRUE if data read from file don't match current machine's
928  *              endianness.
929  * @arch_64     TRUE if file's data come from a 64-bit machine.
930  ***************************************************************************
931  */
932 void upgrade_stats_net_ip(struct activity *act[], int p, unsigned int magic,
933                           int endian_mismatch, int arch_64)
934 {
935         struct stats_net_ip *snic = (struct stats_net_ip *) act[p]->buf[1];
936
937         if (magic == ACTIVITY_MAGIC_BASE) {
938                 struct stats_net_ip_8a *snip = (struct stats_net_ip_8a *) act[p]->buf[0];
939
940                 snic->InReceives = moveto_long_long(&snip->InReceives, endian_mismatch, arch_64);
941                 snic->ForwDatagrams = moveto_long_long(&snip->ForwDatagrams, endian_mismatch, arch_64);
942                 snic->InDelivers = moveto_long_long(&snip->InDelivers, endian_mismatch, arch_64);
943                 snic->OutRequests = moveto_long_long(&snip->OutRequests, endian_mismatch, arch_64);
944                 snic->ReasmReqds = moveto_long_long(&snip->ReasmReqds, endian_mismatch, arch_64);
945                 snic->ReasmOKs = moveto_long_long(&snip->ReasmOKs, endian_mismatch, arch_64);
946                 snic->FragOKs = moveto_long_long(&snip->FragOKs, endian_mismatch, arch_64);
947                 snic->FragCreates = moveto_long_long(&snip->FragCreates, endian_mismatch, arch_64);
948         }
949         else {
950                 struct stats_net_ip_8b *snip = (struct stats_net_ip_8b *) act[p]->buf[0];
951
952                 snic->InReceives = snip->InReceives;
953                 snic->ForwDatagrams = snip->ForwDatagrams;
954                 snic->InDelivers = snip->InDelivers;
955                 snic->OutRequests = snip->OutRequests;
956                 snic->ReasmReqds = snip->ReasmReqds;
957                 snic->ReasmOKs = snip->ReasmOKs;
958                 snic->FragOKs = snip->FragOKs;
959                 snic->FragCreates = snip->FragCreates;
960         }
961 }
962
963 /*
964  ***************************************************************************
965  * Upgrade stats_net_eip structure (from ACTIVITY_MAGIC_BASE format to
966  * ACTIVITY_MAGIC_BASE + 1 format).
967  *
968  * IN:
969  * @act         Array of activities.
970  * @p           Position of activity in array.
971  * @magic       Structure format magic value.
972  * @endian_mismatch
973  *              TRUE if data read from file don't match current machine's
974  *              endianness.
975  * @arch_64     TRUE if file's data come from a 64-bit machine.
976  ***************************************************************************
977  */
978 void upgrade_stats_net_eip(struct activity *act[], int p, unsigned int magic,
979                            int endian_mismatch, int arch_64)
980 {
981         struct stats_net_eip *sneic = (struct stats_net_eip *) act[p]->buf[1];
982
983         if (magic == ACTIVITY_MAGIC_BASE) {
984                 struct stats_net_eip_8a *sneip = (struct stats_net_eip_8a *) act[p]->buf[0];
985
986                 sneic->InHdrErrors = moveto_long_long(&sneip->InHdrErrors, endian_mismatch, arch_64);
987                 sneic->InAddrErrors = moveto_long_long(&sneip->InAddrErrors, endian_mismatch, arch_64);
988                 sneic->InUnknownProtos = moveto_long_long(&sneip->InUnknownProtos, endian_mismatch, arch_64);
989                 sneic->InDiscards = moveto_long_long(&sneip->InDiscards, endian_mismatch, arch_64);
990                 sneic->OutDiscards = moveto_long_long(&sneip->OutDiscards, endian_mismatch, arch_64);
991                 sneic->OutNoRoutes = moveto_long_long(&sneip->OutNoRoutes, endian_mismatch, arch_64);
992                 sneic->ReasmFails = moveto_long_long(&sneip->ReasmFails, endian_mismatch, arch_64);
993                 sneic->FragFails = moveto_long_long(&sneip->FragFails, endian_mismatch, arch_64);
994         }
995         else {
996                 struct stats_net_eip_8b *sneip = (struct stats_net_eip_8b *) act[p]->buf[0];
997
998                 sneic->InHdrErrors = sneip->InHdrErrors;
999                 sneic->InAddrErrors = sneip->InAddrErrors;
1000                 sneic->InUnknownProtos = sneip->InUnknownProtos;
1001                 sneic->InDiscards = sneip->InDiscards;
1002                 sneic->OutDiscards = sneip->OutDiscards;
1003                 sneic->OutNoRoutes = sneip->OutNoRoutes;
1004                 sneic->ReasmFails = sneip->ReasmFails;
1005                 sneic->FragFails = sneip->FragFails;
1006         }
1007 }
1008
1009 /*
1010  ***************************************************************************
1011  * Upgrade stats_net_ip6 structure (from ACTIVITY_MAGIC_BASE format to
1012  * ACTIVITY_MAGIC_BASE + 1 format).
1013  *
1014  * IN:
1015  * @act         Array of activities.
1016  * @p           Position of activity in array.
1017  * @magic       Structure format magic value.
1018  * @endian_mismatch
1019  *              TRUE if data read from file don't match current machine's
1020  *              endianness.
1021  * @arch_64     TRUE if file's data come from a 64-bit machine.
1022  ***************************************************************************
1023  */
1024 void upgrade_stats_net_ip6(struct activity *act[], int p, unsigned int magic,
1025                            int endian_mismatch, int arch_64)
1026 {
1027         struct stats_net_ip6 *snic6 = (struct stats_net_ip6 *) act[p]->buf[1];
1028
1029         if (magic == ACTIVITY_MAGIC_BASE) {
1030                 struct stats_net_ip6_8a *snip6 = (struct stats_net_ip6_8a *) act[p]->buf[0];
1031
1032                 snic6->InReceives6 = moveto_long_long(&snip6->InReceives6, endian_mismatch, arch_64);
1033                 snic6->OutForwDatagrams6 = moveto_long_long(&snip6->OutForwDatagrams6, endian_mismatch, arch_64);
1034                 snic6->InDelivers6 = moveto_long_long(&snip6->InDelivers6, endian_mismatch, arch_64);
1035                 snic6->OutRequests6 = moveto_long_long(&snip6->OutRequests6, endian_mismatch, arch_64);
1036                 snic6->ReasmReqds6 = moveto_long_long(&snip6->ReasmReqds6, endian_mismatch, arch_64);
1037                 snic6->ReasmOKs6 = moveto_long_long(&snip6->ReasmOKs6, endian_mismatch, arch_64);
1038                 snic6->InMcastPkts6 = moveto_long_long(&snip6->InMcastPkts6, endian_mismatch, arch_64);
1039                 snic6->OutMcastPkts6 = moveto_long_long(&snip6->OutMcastPkts6, endian_mismatch, arch_64);
1040                 snic6->FragOKs6 = moveto_long_long(&snip6->FragOKs6, endian_mismatch, arch_64);
1041                 snic6->FragCreates6 = moveto_long_long(&snip6->FragCreates6, endian_mismatch, arch_64);
1042         }
1043         else {
1044                 struct stats_net_ip6_8b *snip6 = (struct stats_net_ip6_8b *) act[p]->buf[0];
1045
1046                 snic6->InReceives6 = snip6->InReceives6;
1047                 snic6->OutForwDatagrams6 = snip6->OutForwDatagrams6;
1048                 snic6->InDelivers6 = snip6->InDelivers6;
1049                 snic6->OutRequests6 = snip6->OutRequests6;
1050                 snic6->ReasmReqds6 = snip6->ReasmReqds6;
1051                 snic6->ReasmOKs6 = snip6->ReasmOKs6;
1052                 snic6->InMcastPkts6 = snip6->InMcastPkts6;
1053                 snic6->OutMcastPkts6 = snip6->OutMcastPkts6;
1054                 snic6->FragOKs6 = snip6->FragOKs6;
1055                 snic6->FragCreates6 = snip6->FragCreates6;
1056         }
1057 }
1058
1059 /*
1060  ***************************************************************************
1061  * Upgrade stats_net_eip6 structure (from ACTIVITY_MAGIC_BASE format to
1062  * ACTIVITY_MAGIC_BASE + 1 format).
1063  *
1064  * IN:
1065  * @act         Array of activities.
1066  * @p           Position of activity in array.
1067  * @magic       Structure format magic value.
1068  * @endian_mismatch
1069  *              TRUE if data read from file don't match current machine's
1070  *              endianness.
1071  * @arch_64     TRUE if file's data come from a 64-bit machine.
1072  ***************************************************************************
1073  */
1074 void upgrade_stats_net_eip6(struct activity *act[], int p, unsigned int magic,
1075                             int endian_mismatch, int arch_64)
1076 {
1077         struct stats_net_eip6 *sneic6 = (struct stats_net_eip6 *) act[p]->buf[1];
1078
1079         if (magic == ACTIVITY_MAGIC_BASE) {
1080                 struct stats_net_eip6_8a *sneip6 = (struct stats_net_eip6_8a *) act[p]->buf[0];
1081
1082                 sneic6->InHdrErrors6 = moveto_long_long(&sneip6->InHdrErrors6, endian_mismatch, arch_64);
1083                 sneic6->InAddrErrors6 = moveto_long_long(&sneip6->InAddrErrors6, endian_mismatch, arch_64);
1084                 sneic6->InUnknownProtos6 = moveto_long_long(&sneip6->InUnknownProtos6, endian_mismatch, arch_64);
1085                 sneic6->InTooBigErrors6 = moveto_long_long(&sneip6->InTooBigErrors6, endian_mismatch, arch_64);
1086                 sneic6->InDiscards6 = moveto_long_long(&sneip6->InDiscards6, endian_mismatch, arch_64);
1087                 sneic6->OutDiscards6 = moveto_long_long(&sneip6->OutDiscards6, endian_mismatch, arch_64);
1088                 sneic6->InNoRoutes6 = moveto_long_long(&sneip6->InNoRoutes6, endian_mismatch, arch_64);
1089                 sneic6->OutNoRoutes6 = moveto_long_long(&sneip6->OutNoRoutes6, endian_mismatch, arch_64);
1090                 sneic6->ReasmFails6 = moveto_long_long(&sneip6->ReasmFails6, endian_mismatch, arch_64);
1091                 sneic6->FragFails6 = moveto_long_long(&sneip6->FragFails6, endian_mismatch, arch_64);
1092                 sneic6->InTruncatedPkts6 = moveto_long_long(&sneip6->InTruncatedPkts6, endian_mismatch, arch_64);
1093         }
1094         else {
1095                 struct stats_net_eip6_8b *sneip6 = (struct stats_net_eip6_8b *) act[p]->buf[0];
1096
1097                 sneic6->InHdrErrors6 = sneip6->InHdrErrors6;
1098                 sneic6->InAddrErrors6 = sneip6->InAddrErrors6;
1099                 sneic6->InUnknownProtos6 = sneip6->InUnknownProtos6;
1100                 sneic6->InTooBigErrors6 = sneip6->InTooBigErrors6;
1101                 sneic6->InDiscards6 = sneip6->InDiscards6;
1102                 sneic6->OutDiscards6 = sneip6->OutDiscards6;
1103                 sneic6->InNoRoutes6 = sneip6->InNoRoutes6;
1104                 sneic6->OutNoRoutes6 = sneip6->OutNoRoutes6;
1105                 sneic6->ReasmFails6 = sneip6->ReasmFails6;
1106                 sneic6->FragFails6 = sneip6->FragFails6;
1107                 sneic6->InTruncatedPkts6 = sneip6->InTruncatedPkts6;
1108         }
1109 }
1110
1111 /*
1112  ***************************************************************************
1113  * Upgrade stats_huge structure (from ACTIVITY_MAGIC_BASE format to
1114  * ACTIVITY_MAGIC_BASE + 1 format).
1115  *
1116  * IN:
1117  * @act         Array of activities.
1118  * @p           Position of activity in array.
1119  * @endian_mismatch
1120  *              TRUE if data read from file don't match current machine's
1121  *              endianness.
1122  * @arch_64     TRUE if file's data come from a 64-bit machine.
1123  ***************************************************************************
1124  */
1125 void upgrade_stats_huge(struct activity *act[], int p,
1126                         int endian_mismatch, int arch_64)
1127 {
1128         struct stats_huge *shc = (struct stats_huge *) act[p]->buf[1];
1129         struct stats_huge_8a *shp = (struct stats_huge_8a *) act[p]->buf[0];
1130
1131         shc->frhkb = moveto_long_long(&shp->frhkb, endian_mismatch, arch_64);
1132         shc->tlhkb = moveto_long_long(&shp->tlhkb, endian_mismatch, arch_64);
1133 }
1134
1135 /*
1136  ***************************************************************************
1137  * Upgrade stats_pwr_wghfreq structure (from ACTIVITY_MAGIC_BASE format to
1138  * ACTIVITY_MAGIC_BASE + 1 format).
1139  *
1140  * IN:
1141  * @act         Array of activities.
1142  * @p           Position of activity in array.
1143  ***************************************************************************
1144  */
1145 void upgrade_stats_pwr_wghfreq(struct activity *act[], int p)
1146 {
1147         int i, k;
1148
1149         struct stats_pwr_wghfreq *spc, *spc_k;
1150         struct stats_pwr_wghfreq_8a *spp, *spp_k;
1151
1152         for (i = 0; i < act[p]->nr_ini; i++) {
1153                 spp = (struct stats_pwr_wghfreq_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize * act[p]->nr2);
1154                 spc = (struct stats_pwr_wghfreq *) ((char *) act[p]->buf[1] + i * act[p]->fsize * act[p]->nr2);
1155
1156                 for (k = 0; k < act[p]->nr2; k++) {
1157                         spp_k = (struct stats_pwr_wghfreq_8a *) ((char *) spp + k * act[p]->msize);
1158                         if (!spp_k->freq)
1159                                 break;
1160                         spc_k = (struct stats_pwr_wghfreq *) ((char *) spc + k * act[p]->fsize);
1161
1162                         spc_k->time_in_state = spp_k->time_in_state;
1163                         memcpy(&spc_k->freq, &spp_k->freq, 8);
1164                 }
1165         }
1166 }
1167
1168 /*
1169  ***************************************************************************
1170  * Upgrade stats_filesystem structure (from ACTIVITY_MAGIC_BASE format to
1171  * ACTIVITY_MAGIC_BASE + 1 format).
1172  *
1173  * IN:
1174  * @act         Array of activities.
1175  * @p           Position of activity in array.
1176  * @st_size     Size of the structure read from file.
1177  ***************************************************************************
1178  */
1179 void upgrade_stats_filesystem(struct activity *act[], int p, int st_size)
1180 {
1181         int i;
1182         struct stats_filesystem *sfc;
1183         struct stats_filesystem_8a *sfp;
1184
1185         for (i = 0; i < act[p]->nr_ini; i++) {
1186                 sfp = (struct stats_filesystem_8a *) ((char *) act[p]->buf[0] + i * act[p]->msize);
1187                 sfc = (struct stats_filesystem *)    ((char *) act[p]->buf[1] + i * act[p]->fsize);
1188
1189                 sfc->f_blocks = sfp->f_blocks;
1190                 sfc->f_bfree = sfp->f_bfree;
1191                 sfc->f_bavail = sfp->f_bavail;
1192                 sfc->f_files = sfp->f_files;
1193                 sfc->f_ffree = sfp->f_ffree;
1194                 strncpy(sfc->fs_name, sfp->fs_name, MAX_FS_LEN);
1195                 sfc->fs_name[MAX_FS_LEN - 1] = '\0';
1196
1197                 if (st_size <= STATS_FILESYSTEM_8A_1_SIZE) {
1198                         /* mountp didn't exist with older versions */
1199                         sfc->mountp[0] = '\0';
1200                 }
1201                 else {
1202                         strncpy(sfc->mountp, sfp->mountp, MAX_FS_LEN);
1203                         sfc->mountp[MAX_FS_LEN - 1] = '\0';
1204                 }
1205         }
1206 }
1207
1208 /*
1209  ***************************************************************************
1210  * Count number of stats_disk structures that need to be written.
1211  *
1212  * IN:
1213  * @act         Array of activities.
1214  * @p           Position of activity in array.
1215  ***************************************************************************
1216  */
1217 __nr_t count_stats_disk(struct activity *act[], int p)
1218 {
1219         int i;
1220         __nr_t nr_dsk = 0;
1221         struct stats_disk *sdc;
1222
1223         for (i = 0; i < act[p]->nr_ini; i++) {
1224                 sdc = (struct stats_disk *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1225                 if (!(sdc->major + sdc->minor))
1226                         break;
1227
1228                 nr_dsk++;
1229         }
1230
1231         return nr_dsk;
1232 }
1233
1234 /*
1235  ***************************************************************************
1236  * Count number of stats_net_dev structures that need to be written.
1237  *
1238  * IN:
1239  * @act         Array of activities.
1240  * @p           Position of activity in array.
1241  ***************************************************************************
1242  */
1243 __nr_t count_stats_net_dev(struct activity *act[], int p)
1244 {
1245         int i;
1246         __nr_t nr_dev = 0;
1247         struct stats_net_dev *sndc;
1248
1249         for (i = 0; i < act[p]->nr_ini; i++) {
1250                 sndc = (struct stats_net_dev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1251                 if (!strcmp(sndc->interface, ""))
1252                         break;
1253
1254                 nr_dev++;
1255         }
1256
1257         return nr_dev;
1258 }
1259
1260 /*
1261  ***************************************************************************
1262  * Count number of stats_net_edev structures that need to be written.
1263  *
1264  * IN:
1265  * @act         Array of activities.
1266  * @p           Position of activity in array.
1267  ***************************************************************************
1268  */
1269 __nr_t count_stats_net_edev(struct activity *act[], int p)
1270 {
1271         int i;
1272         __nr_t nr_edev = 0;
1273         struct stats_net_edev *snedc;
1274
1275         for (i = 0; i < act[p]->nr_ini; i++) {
1276                 snedc = (struct stats_net_edev *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1277                 if (!strcmp(snedc->interface, ""))
1278                         break;
1279
1280                 nr_edev++;
1281         }
1282
1283         return nr_edev;
1284 }
1285
1286 /*
1287  ***************************************************************************
1288  * Count number of stats_pwr_usb structures that need to be written.
1289  *
1290  * IN:
1291  * @act         Array of activities.
1292  * @p           Position of activity in array.
1293  ***************************************************************************
1294  */
1295 __nr_t count_stats_pwr_usb(struct activity *act[], int p)
1296 {
1297         int i;
1298         __nr_t nr_usb = 0;
1299         struct stats_pwr_usb *suc;
1300
1301         for (i = 0; i < act[p]->nr_ini; i++) {
1302                 suc = (struct stats_pwr_usb *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1303                 if (!suc->bus_nr)
1304                         break;
1305
1306                 nr_usb++;
1307         }
1308
1309         return nr_usb;
1310 }
1311
1312 /*
1313  ***************************************************************************
1314  * Count number of stats_filesystem structures that need to be written.
1315  *
1316  * IN:
1317  * @act         Array of activities.
1318  * @p           Position of activity in array.
1319  ***************************************************************************
1320  */
1321 __nr_t count_stats_filesystem(struct activity *act[], int p)
1322 {
1323         int i;
1324         __nr_t nr_fs = 0;
1325         struct stats_filesystem *sfc;
1326
1327         for (i = 0; i < act[p]->nr_ini; i++) {
1328                 sfc = (struct stats_filesystem *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1329                 if (!sfc->f_blocks)
1330                         break;
1331
1332                 nr_fs++;
1333         }
1334
1335         return nr_fs;
1336 }
1337
1338 /*
1339  ***************************************************************************
1340  * Count number of stats_fchost structures that need to be written.
1341  *
1342  * IN:
1343  * @act         Array of activities.
1344  * @p           Position of activity in array.
1345  ***************************************************************************
1346  */
1347 __nr_t count_stats_fchost(struct activity *act[], int p)
1348 {
1349         int i;
1350         __nr_t nr_fc = 0;
1351         struct stats_fchost *sfcc;
1352
1353         for (i = 0; i < act[p]->nr_ini; i++) {
1354                 sfcc = (struct stats_fchost *) ((char *) act[p]->buf[1] + i * act[p]->fsize);
1355                 if (!sfcc->fchost_name[0])
1356                         break;
1357
1358                 nr_fc++;
1359         }
1360
1361         return nr_fc;
1362 }
1363
1364 /*
1365  ***************************************************************************
1366  * Upgrade file's activity list section.
1367  *
1368  * IN:
1369  * @stdfd               File descriptor for STDOUT.
1370  * @act                 Array of activities.
1371  * @file_hdr            Pointer on file_header structure.
1372  * @ofile_actlst        Activity list in file.
1373  * @endian_mismatch
1374  *              TRUE if data read from file don't match current machine's
1375  *              endianness.
1376  * @arch_64     TRUE if file's data come from a 64-bit machine.
1377  *
1378  * OUT:
1379  * @file_actlst         Activity list with up-to-date format.
1380  *
1381  * RETURNS:
1382  * -1 on error, 0 otherwise.
1383 ***************************************************************************
1384  */
1385 int upgrade_activity_section(int stdfd, struct activity *act[],
1386                              struct file_header *file_hdr,
1387                              struct old_file_activity *ofile_actlst,
1388                              struct file_activity **file_actlst,
1389                              int endian_mismatch, int arch_64)
1390 {
1391         int i, j, p;
1392         struct old_file_activity *ofal;
1393         struct file_activity *fal, fa;
1394
1395         fprintf(stderr, "file_activity: ");
1396
1397         SREALLOC(*file_actlst, struct file_activity, FILE_ACTIVITY_SIZE * file_hdr->sa_act_nr);
1398         fal = *file_actlst;
1399         ofal = ofile_actlst;
1400
1401         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++, fal++) {
1402
1403                 /* Every activity should be known at the moment (may change in the future) */
1404                 p = get_activity_position(act, ofal->id, EXIT_IF_NOT_FOUND);
1405                 fal->id = ofal->id;
1406                 fal->nr = ofal->nr;
1407                 fal->nr2 = ofal->nr2;
1408                 fal->magic = act[p]->magic;     /* Update activity magic number */
1409                 fal->has_nr = HAS_COUNT_FUNCTION(act[p]->options);
1410                 /* Also update its size, which may have changed with recent versions */
1411                 fal->size = act[p]->fsize;
1412                 for (j = 0; j < 3; j++) {
1413                         fal->types_nr[j] = act[p]->gtypes_nr[j];
1414                 }
1415
1416                 memcpy(&fa, fal, FILE_ACTIVITY_SIZE);
1417                 /* Restore endianness before writing */
1418                 if (endian_mismatch) {
1419                         /* Start swapping at field "header_size" position */
1420                         swap_struct(act_types_nr, &fa, arch_64);
1421                 }
1422
1423                 /*
1424                  * Even unknown activities must be written
1425                  * (they are counted in sa_act_nr).
1426                  */
1427                 if (write(stdfd, &fa, FILE_ACTIVITY_SIZE) != FILE_ACTIVITY_SIZE) {
1428                         fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1429                         return -1;
1430                 }
1431                 fprintf(stderr, "%s ", act[p]->name);
1432         }
1433
1434         fprintf(stderr, "OK\n");
1435
1436         return 0;
1437 }
1438
1439 /*
1440  ***************************************************************************
1441  * Upgrade a record header.
1442  *
1443  * IN:
1444  * @fd          File descriptor for sa datafile to convert.
1445  * @stdfd       File descriptor for STDOUT.
1446  * @orec_hdr    Record's header structure to convert.
1447  * @endian_mismatch
1448  *              TRUE if data read from file don't match current machine's
1449  *              endianness.
1450  * @arch_64     TRUE if file's data come from a 64-bit machine.
1451  *
1452  * RETURNS:
1453  * -1 on error, 0 otherwise.
1454 ***************************************************************************
1455  */
1456 int upgrade_record_header(int fd, int stdfd, struct old_record_header *orec_hdr,
1457                           int endian_mismatch, int arch_64)
1458 {
1459         struct record_header rec_hdr;
1460
1461         /* Convert current record header */
1462         rec_hdr.uptime_cs = orec_hdr->uptime0 * 100 / HZ;       /* Uptime in cs, not jiffies */
1463         rec_hdr.ust_time = (unsigned long long) orec_hdr->ust_time;
1464         rec_hdr.record_type = orec_hdr->record_type;
1465         rec_hdr.hour = orec_hdr->hour;
1466         rec_hdr.minute = orec_hdr->minute;
1467         rec_hdr.second = orec_hdr->second;
1468
1469         /* Restore endianness before writing */
1470         if (endian_mismatch) {
1471                 swap_struct(rec_types_nr, &rec_hdr, arch_64);
1472         }
1473
1474         /* Write record header */
1475         if (write(stdfd, &rec_hdr, RECORD_HEADER_SIZE) != RECORD_HEADER_SIZE) {
1476                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1477                 return -1;
1478         }
1479
1480         fprintf(stderr, "H");
1481
1482         return 0;
1483 }
1484
1485 /*
1486  ***************************************************************************
1487  * Upgrade a COMMENT record.
1488  *
1489  * IN:
1490  * @fd          File descriptor for sa datafile to convert.
1491  * @stdfd       File descriptor for STDOUT.
1492  *
1493  * RETURNS:
1494  * -1 on error, 0 otherwise.
1495 ***************************************************************************
1496  */
1497 int upgrade_comment_record(int fd, int stdfd)
1498 {
1499         char file_comment[MAX_COMMENT_LEN];
1500
1501         /* Read the COMMENT record */
1502         sa_fread(fd, file_comment, MAX_COMMENT_LEN, HARD_SIZE);
1503         file_comment[MAX_COMMENT_LEN - 1] = '\0';
1504
1505         /* Then write it. No changes at this time */
1506         if (write(stdfd, file_comment, MAX_COMMENT_LEN) != MAX_COMMENT_LEN) {
1507                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1508                 return -1;
1509         }
1510
1511         fprintf(stderr, "C");
1512
1513         return 0;
1514 }
1515
1516 /*
1517  ***************************************************************************
1518  * Upgrade a RESTART record.
1519  *
1520  * IN:
1521  * @fd          File descriptor for sa datafile to convert.
1522  * @stdfd       File descriptor for STDOUT.
1523  * @act         Array of activities.
1524  * @file_hdr    Pointer on file_header structure.
1525  * @previous_format
1526  *              TRUE is sa datafile has an old format which is no longer
1527  *              compatible with current one.
1528  * @endian_mismatch
1529  *              TRUE if data read from file don't match current machine's
1530  *              endianness.
1531  * @arch_64     TRUE if file's data come from a 64-bit machine.
1532  * @vol_act_nr  Number of volatile activity structures.
1533  *
1534  * RETURNS:
1535  * -1 on error, 0 otherwise.
1536 ***************************************************************************
1537  */
1538 int upgrade_restart_record(int fd, int stdfd, struct activity *act[],
1539                            struct file_header *file_hdr, int previous_format,
1540                            int endian_mismatch, int arch_64, unsigned int vol_act_nr)
1541 {
1542
1543         int i, p;
1544         struct old_file_activity ofile_act;
1545         /* Number of cpu read in the activity list. See upgrade_header_section() */
1546         __nr_t cpu_nr = file_hdr->sa_cpu_nr;
1547
1548         if (previous_format == FORMAT_MAGIC_2173) {
1549                 /*
1550                  * For versions from 10.3.1 to 11.6.x,
1551                  * the restart record is followed by a list
1552                  * of volatile activity structures. Among them is A_CPU activity.
1553                  */
1554                 for (i = 0; i < vol_act_nr; i++) {
1555                         sa_fread(fd, &ofile_act, OLD_FILE_ACTIVITY_SIZE, HARD_SIZE);
1556
1557                         /* Normalize endianness for file_activity structures */
1558                         if (endian_mismatch) {
1559                                 swap_struct(oact_types_nr, &ofile_act, arch_64);
1560                         }
1561
1562                         if (ofile_act.id && (ofile_act.nr > 0)) {
1563                                 p = get_activity_position(act, ofile_act.id, EXIT_IF_NOT_FOUND);
1564                                 act[p]->nr_ini = ofile_act.nr;
1565
1566                                 if (ofile_act.id == A_CPU) {
1567                                         cpu_nr = ofile_act.nr;
1568                                 }
1569                         }
1570                 }
1571                 /* Reallocate structures */
1572                 allocate_structures(act);
1573         }
1574
1575         /* Restore endianness before writing */
1576         if (endian_mismatch) {
1577                 cpu_nr = __builtin_bswap32(cpu_nr);
1578         }
1579
1580         /* Write new number of CPU following the restart record */
1581         if (write(stdfd, &cpu_nr, sizeof(__nr_t)) != sizeof(__nr_t)) {
1582                 fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1583                 return -1;
1584         }
1585
1586         fprintf(stderr, "R");
1587
1588         return 0;
1589 }
1590
1591 /*
1592  ***************************************************************************
1593  * Upgrade a record which is not a COMMENT or a RESTART one.
1594  *
1595  * IN:
1596  * @fd          File descriptor for sa datafile to convert.
1597  * @stdfd       File descriptor for STDOUT.
1598  * @act         Array of activities.
1599  * @file_hdr    Pointer on file_header structure (up-to-date format).
1600  * @ofile_actlst
1601  *              Activity list in file.
1602  * @file_actlst Activity list in file (up-to-date format).
1603  * @endian_mismatch
1604  *              TRUE if data read from file don't match current machine's
1605  *              endianness.
1606  * @arch_64     TRUE if file's data come from a 64-bit machine.
1607  *
1608  * RETURNS:
1609  * -1 on error, 0 otherwise.
1610 ***************************************************************************
1611  */
1612 int upgrade_common_record(int fd, int stdfd, struct activity *act[], struct file_header *file_hdr,
1613                           struct old_file_activity *ofile_actlst, struct file_activity *file_actlst,
1614                           int endian_mismatch, int arch_64)
1615 {
1616         int i, j, k, p;
1617         __nr_t nr_struct, nr;
1618         struct old_file_activity *ofal = ofile_actlst;
1619         struct file_activity *fal = file_actlst;
1620         char cc;
1621
1622         /*
1623          * This is not a special record, so read the extra fields,
1624          * even if the format of the activity is unknown.
1625          */
1626         for (i = 0; i < file_hdr->sa_act_nr; i++, ofal++, fal++) {
1627
1628                 /* Every activity should be known at the moment (may change in the future) */
1629                 p = get_activity_position(act, fal->id, EXIT_IF_NOT_FOUND);
1630
1631                 /* Warning: Stats structures keep their original endianness here */
1632                 if ((act[p]->nr_ini > 0) &&
1633                     ((act[p]->nr_ini > 1) || (act[p]->nr2 > 1)) &&
1634                     (act[p]->msize > ofal->size)) {
1635                         for (j = 0; j < act[p]->nr_ini; j++) {
1636                                 for (k = 0; k < act[p]->nr2; k++) {
1637                                         sa_fread(fd,
1638                                                  (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize,
1639                                                  (size_t) ofal->size, HARD_SIZE);
1640                                 }
1641                         }
1642                 }
1643                 else if (act[p]->nr_ini > 0) {
1644                         sa_fread(fd, act[p]->buf[0],
1645                                  (size_t) ofal->size * (size_t) act[p]->nr_ini * (size_t) act[p]->nr2,
1646                                  HARD_SIZE);
1647                 }
1648
1649                 nr_struct = act[p]->nr_ini;
1650                 /*
1651                  * NB: Cannot upgrade a stats structure with
1652                  * a magic number higher than currently known.
1653                  */
1654                 if (ofal->magic < act[p]->magic) {
1655                         cc = 'u';
1656
1657                         /* Known activity but old format */
1658                         switch (fal->id) {
1659
1660                                 case A_CPU:
1661                                         upgrade_stats_cpu(act, p, ofal->size);
1662                                         break;
1663
1664                                 case A_PCSW:
1665                                         upgrade_stats_pcsw(act, p);
1666                                         break;
1667
1668                                 case A_IRQ:
1669                                         upgrade_stats_irq(act, p);
1670                                         break;
1671
1672                                 case A_IO:
1673                                         upgrade_stats_io(act, p, endian_mismatch);
1674                                         break;
1675
1676                                 case A_QUEUE:
1677                                         upgrade_stats_queue(act, p, ofal->magic,
1678                                                             endian_mismatch, arch_64);
1679                                         break;
1680
1681                                 case A_MEMORY:
1682                                         upgrade_stats_memory(act, p, ofal->size,
1683                                                              endian_mismatch, arch_64);
1684                                         break;
1685
1686                                 case A_KTABLES:
1687                                         upgrade_stats_ktables(act, p, endian_mismatch);
1688                                         break;
1689
1690                                 case A_SERIAL:
1691                                         nr_struct = upgrade_stats_serial(act, p, ofal->size,
1692                                                                          endian_mismatch);
1693                                         break;
1694
1695                                 case A_DISK:
1696                                         upgrade_stats_disk(act, p, ofal->magic,
1697                                                            endian_mismatch, arch_64);
1698                                         break;
1699
1700                                 case A_NET_DEV:
1701                                         upgrade_stats_net_dev(act, p, ofal->magic,
1702                                                               endian_mismatch, arch_64);
1703                                         break;
1704
1705                                 case A_NET_EDEV:
1706                                         upgrade_stats_net_edev(act, p, ofal->magic,
1707                                                                endian_mismatch, arch_64);
1708                                         break;
1709
1710                                 case A_NET_IP:
1711                                         upgrade_stats_net_ip(act, p, ofal->magic,
1712                                                              endian_mismatch, arch_64);
1713                                         break;
1714
1715                                 case A_NET_EIP:
1716                                         upgrade_stats_net_eip(act, p, ofal->magic,
1717                                                               endian_mismatch, arch_64);
1718                                         break;
1719
1720                                 case A_NET_IP6:
1721                                         upgrade_stats_net_ip6(act, p, ofal->magic,
1722                                                               endian_mismatch, arch_64);
1723                                         break;
1724
1725                                 case A_NET_EIP6:
1726                                         upgrade_stats_net_eip6(act, p, ofal->magic,
1727                                                                endian_mismatch, arch_64);
1728                                         break;
1729
1730                                 case A_HUGE:
1731                                         upgrade_stats_huge(act, p, endian_mismatch, arch_64);
1732                                         break;
1733
1734                                 case A_PWR_FREQ:
1735                                         upgrade_stats_pwr_wghfreq(act, p);
1736                                         break;
1737
1738                                 case A_FS:
1739                                         upgrade_stats_filesystem(act, p, ofal->size);
1740                                         break;
1741                                 }
1742                 }
1743                 else {
1744                         cc = '.';
1745                         /* Known activity with current up-to-date format */
1746                         for (j = 0; j < act[p]->nr_ini; j++) {
1747                                 for (k = 0; k < act[p]->nr2; k++) {
1748                                         memcpy((char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->msize,
1749                                                (char *) act[p]->buf[0] + (j * act[p]->nr2 + k) * act[p]->msize,
1750                                                fal->size);
1751                                 }
1752                         }
1753                 }
1754
1755                 if (fal->has_nr) {
1756
1757                         switch (fal->id) {
1758
1759                                 case A_SERIAL:
1760                                         /* Nothing to do: Already done in upgrade_stats_serial() */
1761                                         break;
1762
1763                                 case A_DISK:
1764                                         nr_struct = count_stats_disk(act, p);
1765                                         break;
1766
1767                                 case A_NET_DEV:
1768                                         nr_struct = count_stats_net_dev(act, p);
1769                                         break;
1770
1771                                 case A_NET_EDEV:
1772                                         nr_struct = count_stats_net_edev(act, p);
1773                                         break;
1774
1775                                 case A_PWR_USB:
1776                                         nr_struct = count_stats_pwr_usb(act, p);
1777                                         break;
1778
1779                                 case A_FS:
1780                                         nr_struct = count_stats_filesystem(act, p);
1781                                         break;
1782
1783                                 case A_NET_FC:
1784                                         nr_struct = count_stats_fchost(act, p);
1785                                         break;
1786                         }
1787
1788                         /* Restore endianness before writing */
1789                         if (endian_mismatch) {
1790                                 nr = __builtin_bswap32(nr_struct);
1791                         }
1792                         else {
1793                                 nr = nr_struct;
1794                         }
1795
1796                         /* Write number of structures for current activity */
1797                         if (write(stdfd, &nr, sizeof(__nr_t)) != sizeof(__nr_t))
1798                                 goto write_error;
1799
1800                         fprintf(stderr, "n");
1801                 }
1802
1803                 for (j = 0; j < nr_struct; j++) {
1804                         for (k = 0; k < act[p]->nr2; k++) {
1805                                 if (write(stdfd,
1806                                           (char *) act[p]->buf[1] + (j * act[p]->nr2 + k) * act[p]->fsize,
1807                                           act[p]->fsize) != act[p]->fsize)
1808                                         goto write_error;
1809                         }
1810                 }
1811                 fprintf(stderr, "%c", cc);
1812         }
1813
1814         return 0;
1815
1816 write_error:
1817
1818         fprintf(stderr, "\nwrite: %s\n", strerror(errno));
1819
1820         return -1;
1821
1822 }
1823
1824 /*
1825  ***************************************************************************
1826  * Upgrade statistics records.
1827  *
1828  * IN:
1829  * @fd          File descriptor for sa datafile to convert.
1830  * @stdfd       File descriptor for STDOUT.
1831  * @act         Array of activities.
1832  * @file_hdr    Pointer on file_header structure.
1833  * @ofile_actlst
1834  *              Activity list in file.
1835  * @file_actlst Activity list with up-to-date format.
1836  * @previous_format
1837  *              TRUE is sa datafile has an old format which is no longer * @endian_mismatch
1838  *              TRUE if data read from file don't match current machine's
1839  *              endianness.
1840  * @arch_64     TRUE if file's data come from a 64-bit machine.
1841
1842  *              compatible with current one.
1843  * @endian_mismatch
1844  *              TRUE if data read from file don't match current machine's
1845  *              endianness.
1846  * @arch_64     TRUE if file's data come from a 64-bit machine.
1847  * @vol_act_nr  Number of volatile activity structures.
1848  *
1849  * RETURNS:
1850  * -1 on error, 0 otherwise.
1851 ***************************************************************************
1852  */
1853 int upgrade_stat_records(int fd, int stdfd, struct activity *act[], struct file_header *file_hdr,
1854                          struct old_file_activity *ofile_actlst, struct file_activity *file_actlst,
1855                          int previous_format, int endian_mismatch, int arch_64,
1856                          unsigned int vol_act_nr)
1857 {
1858         int rtype;
1859         int eosaf;
1860         struct old_record_header orec_hdr;
1861         unsigned int orec_types_nr[] = {OLD_RECORD_HEADER_ULL_NR, OLD_RECORD_HEADER_UL_NR, OLD_RECORD_HEADER_U_NR};
1862
1863         fprintf(stderr, _("Statistics:\n"));
1864
1865         do {
1866                 eosaf = sa_fread(fd, &orec_hdr, OLD_RECORD_HEADER_SIZE, SOFT_SIZE);
1867
1868                 /* Normalize endianness */
1869                 if (endian_mismatch) {
1870                         swap_struct(orec_types_nr, &orec_hdr, arch_64);
1871                 }
1872                 rtype = orec_hdr.record_type;
1873
1874                 if (!eosaf) {
1875                         /* Upgrade current record header */
1876                         if (upgrade_record_header(fd, stdfd, &orec_hdr,
1877                                                   endian_mismatch, arch_64) < 0)
1878                                 return -1;
1879
1880                         if (rtype == R_COMMENT) {
1881                                 /* Upgrade the COMMENT record */
1882                                 if (upgrade_comment_record(fd, stdfd) < 0)
1883                                         return -1;
1884                         }
1885                         else if (rtype == R_RESTART) {
1886                                 /* Upgrade the RESTART record */
1887                                 if (upgrade_restart_record(fd, stdfd, act, file_hdr,
1888                                                            previous_format, endian_mismatch,
1889                                                            arch_64, vol_act_nr) < 0)
1890                                         return -1;
1891                         }
1892                         else {
1893                                 /* Upgrade current statistics record */
1894                                 if (upgrade_common_record(fd, stdfd, act, file_hdr, ofile_actlst,
1895                                                           file_actlst, endian_mismatch, arch_64) < 0)
1896                                         return -1;
1897                         }
1898                 }
1899         }
1900         while (!eosaf);
1901
1902         fprintf(stderr, "\n");
1903
1904         return 0;
1905 }
1906
1907 /*
1908  ***************************************************************************
1909  * Close file descriptors and exit.
1910  *
1911  * IN:
1912  * @fd          File descriptor for sa datafile to convert.
1913  * @stdfd       File descriptor for STDOUT.
1914  * @exit_code   Exit code.
1915  ***************************************************************************
1916  */
1917 void upgrade_exit(int fd, int stdfd, int exit_code)
1918 {
1919         if (fd) {
1920                 close(fd);
1921         }
1922         if (stdfd) {
1923                 close(stdfd);
1924         }
1925         if (exit_code) {
1926                 exit(exit_code);
1927         }
1928 }
1929
1930 /*
1931  ***************************************************************************
1932  * Convert a sysstat activity data file from a previous version to the
1933  * up-to-date format. Presently data files from sysstat version 9.1.6 and
1934  * later are converted to current sysstat version format.
1935  *
1936  * IN:
1937  * @dfile       System activity data file name.
1938  * @act         Array of activities.
1939  ***************************************************************************
1940  */
1941 void convert_file(char dfile[], struct activity *act[])
1942 {
1943         int fd = 0, stdfd = 0, previous_format = 0;
1944         int arch_64 = TRUE;
1945         unsigned int vol_act_nr = 0, hdr_size;
1946         struct file_magic file_magic;
1947         struct file_header file_hdr;
1948         struct file_activity *file_actlst = NULL;
1949         struct old_file_activity *ofile_actlst = NULL;
1950
1951         /* Open stdout */
1952         if ((stdfd = dup(STDOUT_FILENO)) < 0) {
1953                 perror("dup");
1954                 upgrade_exit(0, 0, 2);
1955         }
1956
1957         /* Upgrade file's magic section */
1958         if (upgrade_magic_section(dfile, &fd, stdfd, &file_magic, &hdr_size,
1959                                   &previous_format, &endian_mismatch) < 0) {
1960                 upgrade_exit(fd, stdfd, 2);
1961         }
1962         if (previous_format == FORMAT_MAGIC) {
1963                 /* Nothing to do at the present time */
1964                 fprintf(stderr, _("\nFile format already up-to-date\n"));
1965                 goto success;
1966         }
1967
1968         /* Get HZ */
1969         get_HZ();
1970         fprintf(stderr, _("HZ: Using current value: %lu\n"), HZ);
1971
1972         /* Upgrade file's header section */
1973         if (upgrade_header_section(dfile, fd, stdfd, act, &file_magic,
1974                                    &file_hdr, hdr_size, previous_format, &arch_64,
1975                                    endian_mismatch, &vol_act_nr, &ofile_actlst) < 0) {
1976                 upgrade_exit(fd, stdfd, 2);
1977         }
1978
1979         /* Upgrade file's activity list section */
1980         if (upgrade_activity_section(stdfd, act, &file_hdr,
1981                                      ofile_actlst, &file_actlst,
1982                                      endian_mismatch, arch_64) < 0) {
1983                 upgrade_exit(fd, stdfd, 2);
1984         }
1985
1986         /* Perform required allocations */
1987         allocate_structures(act);
1988
1989         /* Upgrade statistics records */
1990         if (upgrade_stat_records(fd, stdfd, act, &file_hdr, ofile_actlst, file_actlst,
1991                                  previous_format, endian_mismatch, arch_64,
1992                                  vol_act_nr) < 0) {
1993                 upgrade_exit(fd, stdfd, 2);
1994         }
1995
1996         free(file_actlst);
1997         free(ofile_actlst);
1998         free_structures(act);
1999
2000         fprintf(stderr,
2001                 _("File successfully converted to sysstat format version %s\n"),
2002                 VERSION);
2003
2004 success:
2005         upgrade_exit(fd, stdfd, 0);
2006 }