[Spice-devel] [PATCH spice-server] Make reds_stat utility work with both 32 and 64 bit architectures.
Frediano Ziglio
fziglio at redhat.com
Wed Oct 26 15:06:51 UTC 2016
Due to alignment problems the structure of statistics file is
different between 32 and 64 bit. This as on 32 bit uint64_t is
aligned to 4 bytes instead of 8 so sizeof(SpiceStat) can be either
20 (32 bit) or 24 (64 bit).
This cause reds_stat utility to be bit dependent.
Detect the correct SpiceStat size and use that information.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
---
tools/reds_stat.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/tools/reds_stat.c b/tools/reds_stat.c
index 3e966d4..69260bf 100644
--- a/tools/reds_stat.c
+++ b/tools/reds_stat.c
@@ -25,18 +25,22 @@
#include <string.h>
#include <unistd.h>
#include <inttypes.h>
+#include <sys/stat.h>
#include <spice/stats.h>
+#include <common/verify.h>
#define TAB_LEN 4
#define VALUE_TABS 7
#define INVALID_STAT_REF (~(uint32_t)0)
-static SpiceStat *reds_stat = (SpiceStat *)MAP_FAILED;
+verify(sizeof(SpiceStat) == 20 || sizeof(SpiceStat) == 24);
+
+static SpiceStatNode *reds_nodes = NULL;
static uint64_t *values = NULL;
static void print_stat_tree(int32_t node_index, int depth)
{
- SpiceStatNode *node = &reds_stat->nodes[node_index];
+ SpiceStatNode *node = &reds_nodes[node_index];
if ((node->flags & SPICE_STAT_NODE_MASK_SHOW) == SPICE_STAT_NODE_MASK_SHOW) {
printf("%*s%s", depth * TAB_LEN, "", node->name);
@@ -66,6 +70,9 @@ int main(int argc, char **argv)
int shm_name_len;
int ret = -1;
int fd;
+ struct stat st;
+ unsigned header_size = sizeof(SpiceStat);
+ SpiceStat *reds_stat = (SpiceStat *)MAP_FAILED;
if (argc != 2 || !(kvm_pid = atoi(argv[1]))) {
printf("usage: reds_stat [qemu_pid] (e.g. `pgrep qemu`)\n");
@@ -84,6 +91,12 @@ int main(int argc, char **argv)
}
shm_size = sizeof(SpiceStat);
reds_stat = (SpiceStat *)mmap(NULL, shm_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (fstat(fd, &st) == 0) {
+ unsigned size = st.st_size % sizeof(SpiceStatNode);
+ if (size == 20 || size == 24) {
+ header_size = size;
+ }
+ }
if (reds_stat == (SpiceStat *)MAP_FAILED) {
perror("mmap");
goto error;
@@ -104,12 +117,13 @@ int main(int argc, char **argv)
if (num_of_nodes != reds_stat->num_of_nodes) {
num_of_nodes = reds_stat->num_of_nodes;
shm_old_size = shm_size;
- shm_size = sizeof(SpiceStat) + num_of_nodes * sizeof(SpiceStatNode);
+ shm_size = header_size + num_of_nodes * sizeof(SpiceStatNode);
reds_stat = mremap(reds_stat, shm_old_size, shm_size, MREMAP_MAYMOVE);
if (reds_stat == (SpiceStat *)MAP_FAILED) {
perror("mremap");
goto error;
}
+ reds_nodes = (SpiceStatNode *)((char *) reds_stat + header_size);
values = (uint64_t *)realloc(values, num_of_nodes * sizeof(uint64_t));
if (values == NULL) {
perror("realloc");
--
2.7.4
More information about the Spice-devel
mailing list