]> granicus.if.org Git - sysstat/commitdiff
sadf: SVG: Fix function used to assess canvas height
authorSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 13 Jul 2018 13:55:18 +0000 (15:55 +0200)
committerSebastien GODARD <sysstat@users.noreply.github.com>
Fri, 13 Jul 2018 13:55:18 +0000 (15:55 +0200)
Make sure that we count all the items once and only once for those
which can be registered or unregistered by the system (network
interfaces, block devices...). This is needed to assess SVG canvas
height since each of them will have its own graph.

Signed-off-by: Sebastien GODARD <sysstat@users.noreply.github.com>
activity.c
sa.h
sadf.c
sadf.h
sadf_misc.c

index 067ca8fd5059d5c4e7859a295e0986844bf66b86..6eaedb3f3bdbf5f9443d285bb9c51e564f18df4d 100644 (file)
@@ -91,6 +91,8 @@ struct activity cpu_act = {
        .f_json_print   = json_print_cpu_stats,
        .f_svg_print    = svg_print_cpu_stats,
        .f_raw_print    = raw_print_cpu_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "CPU utilization",
 #endif
        .name           = "A_CPU",
@@ -133,6 +135,8 @@ struct activity pcsw_act = {
        .f_json_print   = json_print_pcsw_stats,
        .f_svg_print    = svg_print_pcsw_stats,
        .f_raw_print    = raw_print_pcsw_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Task creation and switching activity",
 #endif
        .name           = "A_PCSW",
@@ -175,6 +179,8 @@ struct activity irq_act = {
        .f_json_print   = json_print_irq_stats,
        .f_svg_print    = NULL,
        .f_raw_print    = raw_print_irq_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Interrupts statistics",
 #endif
        .name           = "A_IRQ",
@@ -217,6 +223,8 @@ struct activity swap_act = {
        .f_json_print   = json_print_swap_stats,
        .f_svg_print    = svg_print_swap_stats,
        .f_raw_print    = raw_print_swap_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Swap activity",
 #endif
        .name           = "A_SWAP",
@@ -260,6 +268,8 @@ struct activity paging_act = {
        .f_json_print   = json_print_paging_stats,
        .f_svg_print    = svg_print_paging_stats,
        .f_raw_print    = raw_print_paging_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Paging activity",
 #endif
        .name           = "A_PAGE",
@@ -302,6 +312,8 @@ struct activity io_act = {
        .f_json_print   = json_print_io_stats,
        .f_svg_print    = svg_print_io_stats,
        .f_raw_print    = raw_print_io_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "I/O and transfer rate statistics",
 #endif
        .name           = "A_IO",
@@ -345,6 +357,8 @@ struct activity memory_act = {
        .f_json_print   = json_print_memory_stats,
        .f_svg_print    = svg_print_memory_stats,
        .f_raw_print    = raw_print_memory_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Memory and/or swap utilization",
 #endif
        .name           = "A_MEMORY",
@@ -387,6 +401,8 @@ struct activity ktables_act = {
        .f_json_print   = json_print_ktables_stats,
        .f_svg_print    = svg_print_ktables_stats,
        .f_raw_print    = raw_print_ktables_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Kernel tables statistics",
 #endif
        .name           = "A_KTABLES",
@@ -429,6 +445,8 @@ struct activity queue_act = {
        .f_json_print   = json_print_queue_stats,
        .f_svg_print    = svg_print_queue_stats,
        .f_raw_print    = raw_print_queue_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Queue length and load average statistics",
 #endif
        .name           = "A_QUEUE",
@@ -471,6 +489,8 @@ struct activity serial_act = {
        .f_json_print   = json_print_serial_stats,
        .f_svg_print    = NULL,
        .f_raw_print    = raw_print_serial_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "TTY devices statistics",
 #endif
        .name           = "A_SERIAL",
@@ -513,6 +533,8 @@ struct activity disk_act = {
        .f_json_print   = json_print_disk_stats,
        .f_svg_print    = svg_print_disk_stats,
        .f_raw_print    = raw_print_disk_stats,
+       .f_count_new    = count_new_disk,
+       .item_list      = NULL,
        .desc           = "Block devices statistics",
 #endif
        .name           = "A_DISK",
@@ -555,6 +577,8 @@ struct activity net_dev_act = {
        .f_json_print   = json_print_net_dev_stats,
        .f_svg_print    = svg_print_net_dev_stats,
        .f_raw_print    = raw_print_net_dev_stats,
+       .f_count_new    = count_new_net_dev,
+       .item_list      = NULL,
        .desc           = "Network interfaces statistics",
 #endif
        .name           = "A_NET_DEV",
@@ -598,6 +622,8 @@ struct activity net_edev_act = {
        .f_json_print   = json_print_net_edev_stats,
        .f_svg_print    = svg_print_net_edev_stats,
        .f_raw_print    = raw_print_net_edev_stats,
+       .f_count_new    = count_new_net_edev,
+       .item_list      = NULL,
        .desc           = "Network interfaces errors statistics",
 #endif
        .name           = "A_NET_EDEV",
@@ -640,6 +666,8 @@ struct activity net_nfs_act = {
        .f_json_print   = json_print_net_nfs_stats,
        .f_svg_print    = svg_print_net_nfs_stats,
        .f_raw_print    = raw_print_net_nfs_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "NFS client statistics",
 #endif
        .name           = "A_NET_NFS",
@@ -683,6 +711,8 @@ struct activity net_nfsd_act = {
        .f_json_print   = json_print_net_nfsd_stats,
        .f_svg_print    = svg_print_net_nfsd_stats,
        .f_raw_print    = raw_print_net_nfsd_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "NFS server statistics",
 #endif
        .name           = "A_NET_NFSD",
@@ -725,6 +755,8 @@ struct activity net_sock_act = {
        .f_json_print   = json_print_net_sock_stats,
        .f_svg_print    = svg_print_net_sock_stats,
        .f_raw_print    = raw_print_net_sock_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv4 sockets statistics",
 #endif
        .name           = "A_NET_SOCK",
@@ -767,6 +799,8 @@ struct activity net_ip_act = {
        .f_json_print   = json_print_net_ip_stats,
        .f_svg_print    = svg_print_net_ip_stats,
        .f_raw_print    = raw_print_net_ip_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv4 traffic statistics",
 #endif
        .name           = "A_NET_IP",
@@ -809,6 +843,8 @@ struct activity net_eip_act = {
        .f_json_print   = json_print_net_eip_stats,
        .f_svg_print    = svg_print_net_eip_stats,
        .f_raw_print    = raw_print_net_eip_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv4 traffic errors statistics",
 #endif
        .name           = "A_NET_EIP",
@@ -852,6 +888,8 @@ struct activity net_icmp_act = {
        .f_json_print   = json_print_net_icmp_stats,
        .f_svg_print    = svg_print_net_icmp_stats,
        .f_raw_print    = raw_print_net_icmp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "ICMPv4 traffic statistics",
 #endif
        .name           = "A_NET_ICMP",
@@ -895,6 +933,8 @@ struct activity net_eicmp_act = {
        .f_json_print   = json_print_net_eicmp_stats,
        .f_svg_print    = svg_print_net_eicmp_stats,
        .f_raw_print    = raw_print_net_eicmp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "ICMPv4 traffic errors statistics",
 #endif
        .name           = "A_NET_EICMP",
@@ -937,6 +977,8 @@ struct activity net_tcp_act = {
        .f_json_print   = json_print_net_tcp_stats,
        .f_svg_print    = svg_print_net_tcp_stats,
        .f_raw_print    = raw_print_net_tcp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "TCPv4 traffic statistics",
 #endif
        .name           = "A_NET_TCP",
@@ -979,6 +1021,8 @@ struct activity net_etcp_act = {
        .f_json_print   = json_print_net_etcp_stats,
        .f_svg_print    = svg_print_net_etcp_stats,
        .f_raw_print    = raw_print_net_etcp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "TCPv4 traffic errors statistics",
 #endif
        .name           = "A_NET_ETCP",
@@ -1021,6 +1065,8 @@ struct activity net_udp_act = {
        .f_json_print   = json_print_net_udp_stats,
        .f_svg_print    = svg_print_net_udp_stats,
        .f_raw_print    = raw_print_net_udp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "UDPv4 traffic statistics",
 #endif
        .name           = "A_NET_UDP",
@@ -1063,6 +1109,8 @@ struct activity net_sock6_act = {
        .f_json_print   = json_print_net_sock6_stats,
        .f_svg_print    = svg_print_net_sock6_stats,
        .f_raw_print    = raw_print_net_sock6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv6 sockets statistics",
 #endif
        .name           = "A_NET_SOCK6",
@@ -1106,6 +1154,8 @@ struct activity net_ip6_act = {
        .f_json_print   = json_print_net_ip6_stats,
        .f_svg_print    = svg_print_net_ip6_stats,
        .f_raw_print    = raw_print_net_ip6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv6 traffic statistics",
 #endif
        .name           = "A_NET_IP6",
@@ -1149,6 +1199,8 @@ struct activity net_eip6_act = {
        .f_json_print   = json_print_net_eip6_stats,
        .f_svg_print    = svg_print_net_eip6_stats,
        .f_raw_print    = raw_print_net_eip6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "IPv6 traffic errors statistics",
 #endif
        .name           = "A_NET_EIP6",
@@ -1193,6 +1245,8 @@ struct activity net_icmp6_act = {
        .f_json_print   = json_print_net_icmp6_stats,
        .f_svg_print    = svg_print_net_icmp6_stats,
        .f_raw_print    = raw_print_net_icmp6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "ICMPv6 traffic statistics",
 #endif
        .name           = "A_NET_ICMP6",
@@ -1236,6 +1290,8 @@ struct activity net_eicmp6_act = {
        .f_json_print   = json_print_net_eicmp6_stats,
        .f_svg_print    = svg_print_net_eicmp6_stats,
        .f_raw_print    = raw_print_net_eicmp6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "ICMPv6 traffic errors statistics",
 #endif
        .name           = "A_NET_EICMP6",
@@ -1278,6 +1334,8 @@ struct activity net_udp6_act = {
        .f_json_print   = json_print_net_udp6_stats,
        .f_svg_print    = svg_print_net_udp6_stats,
        .f_raw_print    = raw_print_net_udp6_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "UDPv6 traffic statistics",
 #endif
        .name           = "A_NET_UDP6",
@@ -1320,6 +1378,8 @@ struct activity pwr_cpufreq_act = {
        .f_json_print   = json_print_pwr_cpufreq_stats,
        .f_svg_print    = svg_print_pwr_cpufreq_stats,
        .f_raw_print    = raw_print_pwr_cpufreq_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "CPU clock frequency",
 #endif
        .name           = "A_PWR_CPU",
@@ -1362,6 +1422,8 @@ struct activity pwr_fan_act = {
        .f_json_print   = json_print_pwr_fan_stats,
        .f_svg_print    = svg_print_pwr_fan_stats,
        .f_raw_print    = raw_print_pwr_fan_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Fans speed",
 #endif
        .name           = "A_PWR_FAN",
@@ -1404,6 +1466,8 @@ struct activity pwr_temp_act = {
        .f_json_print   = json_print_pwr_temp_stats,
        .f_svg_print    = svg_print_pwr_temp_stats,
        .f_raw_print    = raw_print_pwr_temp_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Devices temperature",
 #endif
        .name           = "A_PWR_TEMP",
@@ -1446,6 +1510,8 @@ struct activity pwr_in_act = {
        .f_json_print   = json_print_pwr_in_stats,
        .f_svg_print    = svg_print_pwr_in_stats,
        .f_raw_print    = raw_print_pwr_in_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Voltage inputs statistics",
 #endif
        .name           = "A_PWR_IN",
@@ -1488,6 +1554,8 @@ struct activity huge_act = {
        .f_json_print   = json_print_huge_stats,
        .f_svg_print    = svg_print_huge_stats,
        .f_raw_print    = raw_print_huge_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Huge pages utilization",
 #endif
        .name           = "A_HUGE",
@@ -1530,6 +1598,8 @@ struct activity pwr_wghfreq_act = {
        .f_json_print   = json_print_pwr_wghfreq_stats,
        .f_svg_print    = NULL,
        .f_raw_print    = raw_print_pwr_wghfreq_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "CPU weighted frequency",
 #endif
        .name           = "A_PWR_FREQ",
@@ -1572,6 +1642,8 @@ struct activity pwr_usb_act = {
        .f_json_print   = json_print_pwr_usb_stats,
        .f_svg_print    = NULL,
        .f_raw_print    = raw_print_pwr_usb_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "USB devices",
 #endif
        .name           = "A_PWR_USB",
@@ -1615,6 +1687,8 @@ struct activity filesystem_act = {
        .f_json_print   = json_print_filesystem_stats,
        .f_svg_print    = svg_print_filesystem_stats,
        .f_raw_print    = raw_print_filesystem_stats,
+       .f_count_new    = count_new_filesystem,
+       .item_list      = NULL,
        .desc           = "Filesystems statistics",
 #endif
        .name           = "A_FS",
@@ -1657,6 +1731,8 @@ struct activity fchost_act = {
        .f_json_print   = json_print_fchost_stats,
        .f_svg_print    = svg_print_fchost_stats,
        .f_raw_print    = raw_print_fchost_stats,
+       .f_count_new    = count_new_fchost,
+       .item_list      = NULL,
        .desc           = "Fibre Channel HBA statistics",
 #endif
        .name           = "A_NET_FC",
@@ -1700,6 +1776,8 @@ struct activity softnet_act = {
        .f_json_print   = json_print_softnet_stats,
        .f_svg_print    = svg_print_softnet_stats,
        .f_raw_print    = raw_print_softnet_stats,
+       .f_count_new    = NULL,
+       .item_list      = NULL,
        .desc           = "Software-based network processing statistics",
 #endif
        .name           = "A_NET_SOFT",
diff --git a/sa.h b/sa.h
index 0597838b2b1efbe05ca29a313205499a290e7774..b0dbb6fadb5a65cab5fd0205f1c8c5d7007abee7 100644 (file)
--- a/sa.h
+++ b/sa.h
@@ -801,6 +801,15 @@ struct activity {
         * This function is used by sadf to display activity statistics in raw format.
         */
        __print_funct_t (*f_raw_print) (struct activity *, char *, int);
+       /*
+        * This function is used by sadf to count the number of new items in current
+        * sample and add them to the linked list @item_list.
+        */
+       __nr_t (*f_count_new) (struct activity *, int);
+       /*
+        * Linked list containing all the different items found. Used by sadf.
+        */
+       void *item_list;
        /*
         * Header string displayed by sadf -d.
         * Header lines for each output (for activities with multiple outputs) are
@@ -1126,6 +1135,20 @@ struct sa_dlist {
  ***************************************************************************
  */
 
+/*
+ * Prototypes used to count new items
+ */
+__nr_t count_new_net_dev
+       (struct activity *, int);
+__nr_t count_new_net_edev
+       (struct activity *, int);
+__nr_t count_new_filesystem
+       (struct activity *, int);
+__nr_t count_new_fchost
+       (struct activity *, int);
+__nr_t count_new_disk
+       (struct activity *, int);
+
 /* Functions used to count number of items */
 __nr_t wrap_get_cpu_nr
        (struct activity *);
diff --git a/sadf.c b/sadf.c
index a650ddd04d3ee459072135333283967b2269de0e..55e4144317274433293816773e656ea93886f318 100644 (file)
--- a/sadf.c
+++ b/sadf.c
@@ -494,7 +494,10 @@ int get_svg_graph_nr(int ifd, char *file, struct file_magic *file_magic,
         */
        do {
                for (i = 0; i < NR_ACT; i++) {
-                       if (act[i]->nr[0] > id_nr_max[i]) {
+                       if (act[i]->f_count_new) {
+                               id_nr_max[i] += (*act[i]->f_count_new)(act[i], 0);
+                       }
+                       else if (act[i]->nr[0] > id_nr_max[i]) {
                                id_nr_max[i] = act[i]->nr[0];
                        }
                }
diff --git a/sadf.h b/sadf.h
index 558aef2ea4b058a007aadfd85f8d9e32e16ac5c2..bf00961476398e41e89b63c7279fa136604b09fe 100644 (file)
--- a/sadf.h
+++ b/sadf.h
 #define TEST_MARKUP(m)                 (((m) & FO_TEST_MARKUP)         == FO_TEST_MARKUP)
 #define REJECT_TRUE_TIME(m)            (((m) & FO_NO_TRUE_TIME)        == FO_NO_TRUE_TIME)
 
+/* Structure for items in list */
+struct interface_lst {
+       char name[MAX_IFACE_LEN];
+       struct interface_lst *next;
+};
+
+struct filesystem_lst {
+       char name[MAX_FS_LEN];
+       struct filesystem_lst *next;
+};
+
+struct fchost_lst {
+       char name[MAX_FCH_LEN];
+       struct fchost_lst *next;
+};
+
+struct disk_lst {
+       int major;
+       int minor;
+       struct disk_lst *next;
+};
 
 /*
  ***************************************************************************
index cea1cf8e40aac1ca251d2eab2e58f78aa5985864..db857c332641771b621b0349f9769c8c1cd04e6b 100644 (file)
@@ -999,3 +999,239 @@ __printf_funct_t print_svg_header(void *parm, int action, char *dfile,
                printf("</svg>\n");
        }
 }
+
+/*
+ ***************************************************************************
+ * Count the number of new network interfaces in current sample. If a new
+ * interface is found then add it to the linked list starting at
+ * @a->item_list.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ *
+ * RETURNS:
+ * Number of new interfaces identified in current sample that were not
+ * previously in the list.
+ ***************************************************************************
+ */
+__nr_t count_new_net_dev(struct activity *a, int curr)
+{
+       int i, nr = 0;
+       void **p;
+       struct interface_lst *e;
+       struct stats_net_dev *sndc;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+               sndc = (struct stats_net_dev *) ((char *) a->buf[curr] + i * a->msize);
+               p = &(a->item_list);
+
+               while (*p != NULL) {
+                       e = *p;
+                       if (!strcmp(e->name, sndc->interface))
+                               break;  /* Item found */
+                       p = &(e->next);
+               }
+               if (*p == NULL) {
+                       /*
+                        * Item not found: Increment total number
+                        * of new items found and add it to the list.
+                        */
+                       nr++;
+                       SREALLOC(*p, struct interface_lst, sizeof(struct interface_lst));
+                       e = *p;
+                       strcpy(e->name, sndc->interface);
+               }
+       }
+
+       return nr;
+}
+
+/*
+ ***************************************************************************
+ * Count the number of new network interfaces in current sample. If a new
+ * interface is found then add it to the linked list starting at
+ * @a->item_list.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ *
+ * RETURNS:
+ * Number of new interfaces identified in current sample that were not
+ * previously in the list.
+ ***************************************************************************
+ */
+__nr_t count_new_net_edev(struct activity *a, int curr)
+{
+       int i, nr = 0;
+       void **p;
+       struct interface_lst *e;
+       struct stats_net_edev *snedc;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+               snedc = (struct stats_net_edev *) ((char *) a->buf[curr] + i * a->msize);
+               p = &(a->item_list);
+
+               while (*p != NULL) {
+                       e = *p;
+                       if (!strcmp(e->name, snedc->interface))
+                               break;  /* Item found */
+                       p = &(e->next);
+               }
+               if (*p == NULL) {
+                       /*
+                        * Item not found: Increment total number
+                        * of new items found and add it to the list.
+                        */
+                       nr++;
+                       SREALLOC(*p, struct interface_lst, sizeof(struct interface_lst));
+                       e = *p;
+                       strcpy(e->name, snedc->interface);
+               }
+       }
+
+       return nr;
+}
+
+/*
+ ***************************************************************************
+ * Count the number of new filesystems in current sample. If a new
+ * filesystem is found then add it to the linked list starting at
+ * @a->item_list.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ *
+ * RETURNS:
+ * Number of new filesystems identified in current sample that were not
+ * previously in the list.
+ ***************************************************************************
+ */
+__nr_t count_new_filesystem(struct activity *a, int curr)
+{
+       int i, nr = 0;
+       void **p;
+       struct filesystem_lst *e;
+       struct stats_filesystem *sfc;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+               sfc = (struct stats_filesystem *) ((char *) a->buf[curr] + i * a->msize);
+               p = &(a->item_list);
+
+               while (*p != NULL) {
+                       e = *p;
+                       if (!strcmp(e->name, sfc->fs_name))
+                               break;  /* Item found */
+                       p = &(e->next);
+               }
+               if (*p == NULL) {
+                       /*
+                        * Item not found: Increment total number
+                        * of new items found and add it to the list.
+                        */
+                       nr++;
+                       SREALLOC(*p, struct filesystem_lst, sizeof(struct filesystem_lst));
+                       e = *p;
+                       strcpy(e->name, sfc->fs_name);
+               }
+       }
+
+       return nr;
+}
+
+/*
+ ***************************************************************************
+ * Count the number of new fchosts in current sample. If a new
+ * fchost is found then add it to the linked list starting at
+ * @a->item_list.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ *
+ * RETURNS:
+ * Number of new fchosts identified in current sample that were not
+ * previously in the list.
+ ***************************************************************************
+ */
+__nr_t count_new_fchost(struct activity *a, int curr)
+{
+       int i, nr = 0;
+       void **p;
+       struct fchost_lst *e;
+       struct stats_fchost *sfcc;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+               sfcc = (struct stats_fchost *) ((char *) a->buf[curr] + i * a->msize);
+               p = &(a->item_list);
+
+               while (*p != NULL) {
+                       e = *p;
+                       if (!strcmp(e->name, sfcc->fchost_name))
+                               break;  /* Item found */
+                       p = &(e->next);
+               }
+               if (*p == NULL) {
+                       /*
+                        * Item not found: Increment total number
+                        * of new items found and add it to the list.
+                        */
+                       nr++;
+                       SREALLOC(*p, struct fchost_lst, sizeof(struct fchost_lst));
+                       e = *p;
+                       strcpy(e->name, sfcc->fchost_name);
+               }
+       }
+
+       return nr;
+}
+
+/*
+ ***************************************************************************
+ * Count the number of new block devices in current sample. If a new
+ * block device is found then add it to the linked list starting at
+ * @a->item_list.
+ *
+ * IN:
+ * @a          Activity structure with statistics.
+ * @curr       Index in array for current sample statistics.
+ *
+ * RETURNS:
+ * Number of new block devices identified in current sample that were not
+ * previously in the list.
+ ***************************************************************************
+ */
+__nr_t count_new_disk(struct activity *a, int curr)
+{
+       int i, nr = 0;
+       void **p;
+       struct disk_lst *e;
+       struct stats_disk *sdc;
+
+       for (i = 0; i < a->nr[curr]; i++) {
+               sdc = (struct stats_disk *) ((char *) a->buf[curr] + i * a->msize);
+               p = &(a->item_list);
+
+               while (*p != NULL) {
+                       e = *p;
+                       if ((e->major == sdc->major) && (e->minor == sdc->minor))
+                               break;  /* Item found */
+                       p = &(e->next);
+               }
+               if (*p == NULL) {
+                       /*
+                        * Item not found: Increment total number
+                        * of new items found and add it to the list.
+                        */
+                       nr++;
+                       SREALLOC(*p, struct disk_lst, sizeof(struct disk_lst));
+                       e = *p;
+                       e->major = sdc->major;
+                       e->minor = sdc->minor;
+               }
+       }
+
+       return nr;
+}