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