From: Florian Forster Date: Thu, 24 Sep 2009 07:08:35 +0000 (+0200) Subject: netapp plugin: collect_perf_disk_data: Only query "percentage-saved" if required. X-Git-Tag: collectd-4.9.0~73^2~52 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=533654d1d05fb65a7a9d97ad7b5f34f8cf3cdc67;p=collectd.git netapp plugin: collect_perf_disk_data: Only query "percentage-saved" if required. Also, add support for "sis_saved_percent == 100". Probably not useful, but better than simply skipping that case. --- diff --git a/src/netapp.c b/src/netapp.c index cbba8d6c..96ca5a4b 100644 --- a/src/netapp.c +++ b/src/netapp.c @@ -452,7 +452,7 @@ static void collect_perf_disk_data(host_config_t *host, na_elem_t *out, void *da } /* }}} void collect_perf_disk_data */ static void collect_volume_data(host_config_t *host, na_elem_t *out, void *data) { /* {{{ */ - na_elem_t *inst, *sis; + na_elem_t *inst; volume_t *volume; volume_data_t *volume_data = data; @@ -460,9 +460,10 @@ static void collect_volume_data(host_config_t *host, na_elem_t *out, void *data) na_elem_iter_t inst_iter = na_child_iterator(out); for (inst = na_iterator_next(&inst_iter); inst; inst = na_iterator_next(&inst_iter)) { uint64_t size_free = 0, size_used = 0, snap_reserved = 0; + + na_elem_t *sis; const char *sis_state; uint64_t sis_saved_reported; - uint64_t sis_saved_percent; uint64_t sis_saved; volume = get_volume(host, na_child_get_string(inst, "name")); @@ -477,17 +478,16 @@ static void collect_volume_data(host_config_t *host, na_elem_t *out, void *data) /* 2^4 exa-bytes? This will take a while ;) */ size_free = na_child_get_uint64(inst, "size-available", UINT64_MAX); - size_used = na_child_get_uint64(inst, "size-used", UINT64_MAX); - snap_reserved = na_child_get_uint64(inst, "snapshot-blocks-reserved", UINT64_MAX); - if (size_free != UINT64_MAX) submit_double (host->name, volume->name, "df_complex", "used", (double) size_used, /* time = */ 0); + size_used = na_child_get_uint64(inst, "size-used", UINT64_MAX); if (size_free != UINT64_MAX) submit_double (host->name, volume->name, "df_complex", "free", (double) size_free, /* time = */ 0); + snap_reserved = na_child_get_uint64(inst, "snapshot-blocks-reserved", UINT64_MAX); if (snap_reserved != UINT64_MAX) /* 1 block == 1024 bytes as per API docs */ submit_double (host->name, volume->name, "df_complex", "snap_reserved", @@ -503,10 +503,7 @@ static void collect_volume_data(host_config_t *host, na_elem_t *out, void *data) continue; sis_saved_reported = na_child_get_uint64(sis, "size-saved", UINT64_MAX); - sis_saved_percent = na_child_get_uint64(sis, "percentage-saved", UINT64_MAX); - - /* sis_saved_percent == 100 leads to division by zero below */ - if ((sis_saved_reported == UINT64_MAX) || (sis_saved_percent > 99)) + if (sis_saved_reported == UINT64_MAX) continue; /* size-saved is actually a 32 bit number, so ... time for some guesswork. */ @@ -514,30 +511,44 @@ static void collect_volume_data(host_config_t *host, na_elem_t *out, void *data) /* In case they ever fix this bug. */ sis_saved = sis_saved_reported; } else { + uint64_t sis_saved_percent; + uint64_t sis_saved_guess; + uint64_t overflow_guess; + uint64_t guess1, guess2, guess3; + + sis_saved_percent = na_child_get_uint64(sis, "percentage-saved", UINT64_MAX); + if (sis_saved_percent > 100) + continue; + /* The "size-saved" value is a 32bit unsigned integer. This is a bug and * will hopefully be fixed in later versions. To work around the bug, try * to figure out how often the 32bit integer wrapped around by using the * "percentage-saved" value. Because the percentage is in the range * [0-100], this should work as long as the saved space does not exceed * 400 GBytes. */ - uint64_t real_saved = sis_saved_percent * size_used / (100 - sis_saved_percent); - uint64_t overflow_guess = real_saved >> 32; - uint64_t guess1 = overflow_guess ? ((overflow_guess - 1) << 32) + sis_saved_reported : sis_saved_reported; - uint64_t guess2 = (overflow_guess << 32) + sis_saved_reported; - uint64_t guess3 = ((overflow_guess + 1) << 32) + sis_saved_reported; - - if (real_saved < guess2) { - if ((real_saved - guess1) < (guess2 - real_saved)) + /* percentage-saved = size-saved / (size-saved + size-used) */ + if (sis_saved_percent < 100) + sis_saved_guess = size_used * sis_saved_percent / (100 - sis_saved_percent); + else + sis_saved_guess = size_used; + + overflow_guess = sis_saved_guess >> 32; + guess1 = overflow_guess ? ((overflow_guess - 1) << 32) + sis_saved_reported : sis_saved_reported; + guess2 = (overflow_guess << 32) + sis_saved_reported; + guess3 = ((overflow_guess + 1) << 32) + sis_saved_reported; + + if (sis_saved_guess < guess2) { + if ((sis_saved_guess - guess1) < (guess2 - sis_saved_guess)) sis_saved = guess1; else sis_saved = guess2; } else { - if ((real_saved - guess2) < (guess3 - real_saved)) + if ((sis_saved_guess - guess2) < (guess3 - sis_saved_guess)) sis_saved = guess2; else sis_saved = guess3; } - } + } /* end of 32-bit workaround */ submit_double (host->name, volume->name, "df_complex", "sis_saved", (double) sis_saved, /* time = */ 0);