Activities can now have multiple items and sub-items.
This patch breaks current datafile format, which becomes
no longer compatible with previous one.
Changes:
xxxx/xx/xx: Version 9.1.6 - Sebastien Godard (sysstat <at> orange.fr)
+ WARNING: Daily data files format has changed, and is *not*
+ compatible with the previous one! [0x2171]
* Added hugepages utilization statistics to sar.
* [Ivana Varekova]: Moved manual pages to $prefix/share/man
instead of $prefix/man.
.options = AO_COLLECTED + AO_REMANENT + AO_GLOBAL_ITV + AO_MULTIPLE_OUTPUTS,
#ifdef SOURCE_SADC
.f_count = wrap_get_cpu_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_stat_cpu,
#endif
#ifdef SOURCE_SAR
.name = "A_CPU",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_CPU_SIZE,
.msize = STATS_CPU_SIZE,
.opt_flags = AO_F_CPU_DEF,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_stat_pcsw,
#endif
#ifdef SOURCE_SAR
.name = "A_PCSW",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_PCSW_SIZE,
.msize = STATS_PCSW_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = wrap_get_irq_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_stat_irq,
#endif
#ifdef SOURCE_SAR
.name = "A_IRQ",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_IRQ_SIZE,
.msize = STATS_IRQ_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_swap,
#endif
#ifdef SOURCE_SAR
.name = "A_SWAP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_SWAP_SIZE,
.msize = STATS_SWAP_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_paging,
#endif
#ifdef SOURCE_SAR
.name = "A_PAGE",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_PAGING_SIZE,
.msize = STATS_PAGING_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_io,
#endif
#ifdef SOURCE_SAR
.name = "A_IO",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_IO_SIZE,
.msize = STATS_IO_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED + AO_MULTIPLE_OUTPUTS,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_meminfo,
#endif
#ifdef SOURCE_SAR
.name = "A_MEMORY",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_MEMORY_SIZE,
.msize = STATS_MEMORY_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_kernel_tables,
#endif
#ifdef SOURCE_SAR
.name = "A_KTABLES",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_KTABLES_SIZE,
.msize = STATS_KTABLES_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_loadavg,
#endif
#ifdef SOURCE_SAR
.name = "A_QUEUE",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_QUEUE_SIZE,
.msize = STATS_QUEUE_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = wrap_get_serial_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_tty_driver_serial,
#endif
#ifdef SOURCE_SAR
.name = "A_SERIAL",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_SERIAL_SIZE,
.msize = STATS_SERIAL_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = wrap_get_disk_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_disk,
#endif
#ifdef SOURCE_SAR
.name = "A_DISK",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_DISK_SIZE,
.msize = STATS_DISK_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = wrap_get_iface_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_net_dev,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_DEV",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_NET_DEV_SIZE,
.msize = STATS_NET_DEV_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = wrap_get_iface_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_net_edev,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_EDEV",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_NET_EDEV_SIZE,
.msize = STATS_NET_EDEV_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_nfs,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_NFS",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_NFS_SIZE,
.msize = STATS_NET_NFS_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_nfsd,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_NFSD",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_NFSD_SIZE,
.msize = STATS_NET_NFSD_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_sock,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_SOCK",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_SOCK_SIZE,
.msize = STATS_NET_SOCK_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_ip,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_IP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_IP_SIZE,
.msize = STATS_NET_IP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_eip,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_EIP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_EIP_SIZE,
.msize = STATS_NET_EIP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_icmp,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_ICMP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_ICMP_SIZE,
.msize = STATS_NET_ICMP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_eicmp,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_EICMP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_EICMP_SIZE,
.msize = STATS_NET_EICMP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_tcp,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_TCP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_TCP_SIZE,
.msize = STATS_NET_TCP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_etcp,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_ETCP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_ETCP_SIZE,
.msize = STATS_NET_ETCP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_udp,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_UDP",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_UDP_SIZE,
.msize = STATS_NET_UDP_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_sock6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_SOCK6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_SOCK6_SIZE,
.msize = STATS_NET_SOCK6_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_ip6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_IP6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_IP6_SIZE,
.msize = STATS_NET_IP6_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_eip6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_EIP6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_EIP6_SIZE,
.msize = STATS_NET_EIP6_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_icmp6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_ICMP6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_ICMP6_SIZE,
.msize = STATS_NET_ICMP6_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_eicmp6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_EICMP6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_EICMP6_SIZE,
.msize = STATS_NET_EICMP6_SIZE,
.opt_flags = 0,
.options = AO_CLOSE_MARKUP,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_net_udp6,
#endif
#ifdef SOURCE_SAR
.name = "A_NET_UDP6",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_NET_UDP6_SIZE,
.msize = STATS_NET_UDP6_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = wrap_get_cpu_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_cpuinfo,
#endif
#ifdef SOURCE_SAR
.name = "A_PWR_CPUFREQ",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_PWR_CPUFREQ_SIZE,
.msize = STATS_PWR_CPUFREQ_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = wrap_get_fan_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_fan,
#endif
#ifdef SOURCE_SAR
.name = "A_PWR_FAN",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_PWR_FAN_SIZE,
.msize = STATS_PWR_FAN_SIZE,
.opt_flags = 0,
.options = AO_NULL,
#ifdef SOURCE_SADC
.f_count = wrap_get_temp_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_temp,
#endif
#ifdef SOURCE_SAR
.name = "A_PWR_TEMP",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_PWR_TEMP_SIZE,
.msize = STATS_PWR_TEMP_SIZE,
.opt_flags = 0,
.options = AO_CLOSE_MARKUP,
#ifdef SOURCE_SADC
.f_count = wrap_get_in_nr,
+ .f_count2 = NULL,
.f_read = wrap_read_in,
#endif
#ifdef SOURCE_SAR
.name = "A_PWR_IN",
#endif
.nr = -1,
+ .nr2 = 1,
.fsize = STATS_PWR_IN_SIZE,
.msize = STATS_PWR_IN_SIZE,
.opt_flags = 0,
.options = AO_COLLECTED,
#ifdef SOURCE_SADC
.f_count = NULL,
+ .f_count2 = NULL,
.f_read = wrap_read_meminfo_huge,
#endif
#ifdef SOURCE_SAR
.name = "A_HUGE",
#endif
.nr = 1,
+ .nr2 = 1,
.fsize = STATS_HUGE_SIZE,
.msize = STATS_HUGE_SIZE,
.opt_flags = 0,
#define CLOSE_MARKUP(m) (((m) & AO_CLOSE_MARKUP) == AO_CLOSE_MARKUP)
#define HAS_MULTIPLE_OUTPUTS(m) (((m) & AO_MULTIPLE_OUTPUTS) == AO_MULTIPLE_OUTPUTS)
-
/* Type for all functions counting items */
#define __nr_t int
/* Type for all functions reading statistics */
unsigned int options;
/*
* The f_count() function is used to count the number of
- * items (serial lines, network interfaces, etc.).
+ * items (serial lines, network interfaces, etc.) -> @nr
* Such a function should _always_ return a value greater than
* or equal to 0.
*
* sure that all items have been calculated (including #CPU, etc.)
*/
__nr_t (*f_count) (struct activity *);
+ /*
+ * The f_count2() function is used to count the number of
+ * sub-items -> @nr2
+ * Such a function should _always_ return a value greater than
+ * or equal to 0.
+ *
+ * A NULL value for this function pointer indicates that the number of items
+ * is a constant (and @nr2 is set to this value).
+ */
+ __nr_t (*f_count2) (struct activity *);
/*
* This function reads the relevant file and fill the buffer
* with statistics corresponding to given activity.
* has still not been calculated by the f_count() function.
* A value of 0 means that this number has been calculated, but no items have
* been found.
+ * A positive value (>0) has either been calculated or is a constant.
*/
__nr_t nr;
+ /*
+ * Number of sub-items on the system.
+ * @nr2 is in fact the second dimension of a matrix of items, the first
+ * one being @nr. @nr is the number of lines, and @nr2 the number of columns.
+ * A negative value (-1) is the default value and indicates that this number
+ * has still not been calculated by the f_count2() function.
+ * A value of 0 means that this number has been calculated, but no sub-items have
+ * been found.
+ * A positive value (>0) has either been calculated or is a constant.
+ * Rules:
+ * 1) IF @nr2 = 0 THEN @nr = 0
+ * Note: If @nr = 0, then @nr2 is undetermined (may be -1, 0 or >0).
+ * 2) IF @nr > 0 THEN @nr2 > 0.
+ * Note: If @nr2 > 0 then @nr is undetermined (may be -1, 0 or >0).
+ */
+ __nr_t nr2;
/*
* Size of an item.
* This is the size of the corresponding structure, as read from or written
struct act_bitmap *bitmap;
};
-
/*
***************************************************************************
* Definitions of header structures.
* Modified to indicate that the format of the file is
* no longer compatible with that of previous sysstat versions.
*/
-#define FORMAT_MAGIC 0x2170
+#define FORMAT_MAGIC 0x2171
/* Structure for file magic header data */
struct file_magic {
* Number of items for this activity.
*/
__nr_t nr __attribute__ ((packed));
+ /*
+ * Number of sub-items for this activity.
+ */
+ __nr_t nr2 __attribute__ ((packed));
/*
* Size of an item structure.
*/
for (i = 0; i < NR_ACT; i++) {
if (act[i]->nr > 0) {
for (j = 0; j < 3; j++) {
- SREALLOC(act[i]->buf[j], void, act[i]->msize * act[i]->nr);
+ SREALLOC(act[i]->buf[j], void, act[i]->msize * act[i]->nr * act[i]->nr2);
}
}
}
continue;
if (((p = get_activity_position(act, id_seq[i])) < 0) ||
- (act[p]->nr < 1)) {
+ (act[p]->nr < 1) || (act[p]->nr2 < 1)) {
PANIC(1);
}
-
- memcpy(act[p]->buf[dest], act[p]->buf[src], act[p]->msize * act[p]->nr);
-
+
+ memcpy(act[p]->buf[dest], act[p]->buf[src], act[p]->msize * act[p]->nr * act[p]->nr2);
}
}
void read_file_stat_bunch(struct activity *act[], int curr, int ifd, int act_nr,
struct file_activity *file_actlst)
{
- int i, j, p;
+ int i, j, k, p;
struct file_activity *fal = file_actlst;
for (i = 0; i < act_nr; i++, fal++) {
* Ignore current activity in file, which is unknown to
* current sysstat version.
*/
- if (lseek(ifd, fal->size * fal->nr, SEEK_CUR) < (fal->size * fal->nr)) {
+ if (lseek(ifd, fal->size * fal->nr * fal->nr2, SEEK_CUR) < (fal->size * fal->nr * fal->nr2)) {
close(ifd);
perror("lseek");
exit(2);
}
}
- else if ((act[p]->nr > 1) && (act[p]->msize > act[p]->fsize)) {
+ else if ((act[p]->nr > 0) &&
+ ((act[p]->nr > 1) || (act[p]->nr2 > 1)) &&
+ (act[p]->msize > act[p]->fsize)) {
for (j = 0; j < act[p]->nr; j++) {
- sa_fread(ifd, (char *) act[p]->buf[curr] + j * act[p]->msize,
- act[p]->fsize, HARD_SIZE);
+ for (k = 0; k < act[p]->nr2; k++) {
+ sa_fread(ifd,
+ (char *) act[p]->buf[curr] + (j * act[p]->nr2 + k) * act[p]->msize,
+ act[p]->fsize, HARD_SIZE);
+ }
}
}
else if (act[p]->nr > 0) {
- sa_fread(ifd, act[p]->buf[curr], act[p]->fsize * act[p]->nr, HARD_SIZE);
+ sa_fread(ifd, act[p]->buf[curr], act[p]->fsize * act[p]->nr * act[p]->nr2, HARD_SIZE);
}
else {
PANIC(act[p]->nr);
sa_fread(*ifd, fal, FILE_ACTIVITY_SIZE, HARD_SIZE);
- if (fal->nr < 1) {
+ if ((fal->nr < 1) || (fal->nr2 < 1)) {
/*
* Every activity, known or unknown,
- * should have at least one item.
+ * should have at least one item and sub-item.
*/
handle_invalid_sa_file(ifd, file_magic, dfile, 0);
}
}
act[p]->fsize = fal->size;
act[p]->nr = fal->nr;
+ act[p]->nr2 = fal->nr2;
id_seq[j++] = fal->id;
}
}
for (i = 0; i < NR_ACT; i++) {
if ((act[i]->nr > 0) && act[i]->_buf0) {
- memset(act[i]->_buf0, 0, act[i]->msize * act[i]->nr);
+ memset(act[i]->_buf0, 0, act[i]->msize * act[i]->nr * act[i]->nr2);
}
}
}
act[i]->nr = (*act[i]->f_count)(act[i]);
}
+ if (act[i]->nr > 0) {
+ if (act[i]->f_count2) {
+ act[i]->nr2 = (*act[i]->f_count2)(act[i]);
+ }
+ /* else act[i]->nr2 is a constant and doesn't need to be calculated */
+ if (!act[i]->nr2) {
+ act[i]->nr = 0;
+ }
+ }
+
if (act[i]->nr > 0) {
/* Allocate structures for current activity */
- SREALLOC(act[i]->_buf0, void, act[i]->msize * act[i]->nr);
+ SREALLOC(act[i]->_buf0, void, act[i]->msize * act[i]->nr * act[i]->nr2);
}
else {
/* No items found: Invalidate current activity */
if (IS_COLLECTED(act[p]->options)) {
file_act.id = act[p]->id;
file_act.nr = act[p]->nr;
+ file_act.nr2 = act[p]->nr2;
file_act.size = act[p]->fsize;
if ((n = write_all(fd, &file_act, FILE_ACTIVITY_SIZE))
continue;
if (IS_COLLECTED(act[p]->options)) {
- if ((n = write_all(ofd, act[p]->_buf0, act[p]->fsize * act[p]->nr)) !=
- (act[p]->fsize * act[p]->nr)) {
+ if ((n = write_all(ofd, act[p]->_buf0, act[p]->fsize * act[p]->nr * act[p]->nr2)) !=
+ (act[p]->fsize * act[p]->nr * act[p]->nr2)) {
p_write_error();
}
}
/* Unknown activity in list or item size has changed */
goto append_error;
- if (act[p]->nr != file_act.nr) {
- if (IS_REMANENT(act[p]->options) || !file_act.nr)
+ if ((act[p]->nr != file_act.nr) || (act[p]->nr2 != file_act.nr2)) {
+ if (IS_REMANENT(act[p]->options) || !file_act.nr || !file_act.nr2)
/*
* Remanent structures cannot have a different number of items.
- * Also number of items should never be null.
+ * Also number of items and subitems should never be null.
*/
goto append_error;
else {
/*
* Force number of items (serial lines, network interfaces...)
- * to that of the file, and reallocate structures.
+ * and sub-items to that of the file, and reallocate structures.
*/
- act[p]->nr = file_act.nr;
- SREALLOC(act[p]->_buf0, void, act[p]->msize * act[p]->nr);
+ act[p]->nr = file_act.nr;
+ act[p]->nr2 = file_act.nr2;
+ SREALLOC(act[p]->_buf0, void, act[p]->msize * act[p]->nr * act[p]->nr2);
}
}
/* Save activity sequence */
if ((p = get_activity_position(act, id_seq[i])) < 0) {
PANIC(id_seq[i]);
}
- printf("%02d: %s\t(x%d)\n", act[p]->id, act[p]->name, act[p]->nr);
+ printf("%02d: %s\t(x%d)", act[p]->id, act[p]->name, act[p]->nr);
+ if (act[p]->f_count2 || (act[p]->nr2 > 1)) {
+ printf(" (x%d)", act[p]->nr2);
+ }
+ printf("\n");
}
exit(0);
***************************************************************************
* Check that every selected activity actually belongs to the sequence list.
* If not, then the activity should be unselected since it will not be sent
- * by sadc. An activity can be unsent if its number of items is null.
+ * by sadc. An activity can be not sent if its number of items is null.
*
* IN:
* @act_nr Size of sequence list.
record_hdr[!curr].ust_time = record_hdr[curr].ust_time;
for (i = 0; i < NR_ACT; i++) {
- if (IS_SELECTED(act[i]->options) && (act[i]->nr > 0))
- memset(act[i]->buf[!curr], 0, act[i]->msize * act[i]->nr);
+ if (IS_SELECTED(act[i]->options) && (act[i]->nr > 0)) {
+ memset(act[i]->buf[!curr], 0, act[i]->msize * act[i]->nr * act[i]->nr2);
+ }
}
flags |= S_F_SINCE_BOOT;
void read_sadc_stat_bunch(int curr)
{
int i, p;
-
+
/* Read record header (type is always R_STATS since it is read from sadc) */
if (sa_read(&record_hdr[curr], RECORD_HEADER_SIZE)) {
print_read_error();
if ((p = get_activity_position(act, id_seq[i])) < 0) {
PANIC(1);
}
-
- if (sa_read(act[p]->buf[curr], act[p]->fsize * act[p]->nr)) {
+
+ if (sa_read(act[p]->buf[curr], act[p]->fsize * act[p]->nr * act[p]->nr2)) {
print_read_error();
}
}
p = get_activity_position(act, file_act.id);
- if ((p < 0) || (act[p]->fsize != file_act.size) || !file_act.nr) {
+ if ((p < 0) || (act[p]->fsize != file_act.size)
+ || !file_act.nr
+ || !file_act.nr2) {
fprintf(stderr, _("Inconsistent input data\n"));
exit(3);
}
id_seq[i] = file_act.id; /* We necessarily have "i < NR_ACT" */
act[p]->nr = file_act.nr;
+ act[p]->nr2 = file_act.nr2;
}
while (i < NR_ACT) {