pmcd: fix endianness state extraction issue#2505
pmcd: fix endianness state extraction issue#2505lmchilton wants to merge 1 commit intoperformancecopilot:mainfrom
Conversation
wcohen
left a comment
There was a problem hiding this comment.
Looks like the idea is solid. Would like to the patch updated to eliminate the change to ExtractState().
src/libpcp_pmda/src/callback.c
Outdated
| if (byte) { | ||
| flags = (unsigned char *)&result->timestamp; | ||
| *flags |= byte; | ||
| result->timestamp.tv_sec |= (long)byte; |
There was a problem hiding this comment.
This change doesn't match up with the behavior listed in the comment for __pmdaEncodeStatus() as the byte will now be stored in the LSB of timestamp.tv_sec field and requires a change to ExtractState() in dofetch.c:
/*
* The first byte of the (unused) timestamp field has been
* co-opted as a flags byte - now indicating state changes
* that have happened within a PMDA and that need to later
* be propogated through to any connected clients.
*/
Is should be possible to rework __pmdaEncodeStatus() to always use the first byte of the timestamp field regardless of the endianess of the machine. This would make this patch more concise. Maybe also correct the mispelled "propagated" in the comment in the updated patch.
kmcdonell
left a comment
There was a problem hiding this comment.
I think there maybe a deeper issue here (that's my fault from the pmResult v2->v3 changes.
I was curious about the void *timestamp in the ExtractState prototype which did not seem right ... but ExtractState is called twice, once with timestamp pointing to a struct timeval (for a DSO PMDA) and once with timestamp pointing to a struct __pmTimestamp for daemon PMDAs. So there is no obvious re-casting of the timestamp pointer ... making it a struct timeval and using the tv_sec member is only "right" for one of the use cases.
I'd suggest we put the value into the first 32-bits of the "timestamp", ignoring any struct, so just cast timestamp to a __int32_t * and stuff the value in.
And changing the unsigned byte to a __unit32_t would avod the masking and provide some expansion space (we're already all of the available 8 bits in an unsigned byte).
Since this is a private protocol between pmcd and the PMDAs (via libpcp_pmda) we don't have any compatibility issues with making a change to the encoding.
On Big-Endian systems (s390x), the flags used by pmda fetch functions to signal a PMDA change were lost due to inconsistent byte-level memory manipulation Refactoring __pmdaEncodeStatus and ExtractState to treat the timestamp as a uint64_t rather than a character array allows the CPU's native endianness handling to store and retrieve flags. Adjustment to QA performancecopilot#1321 sleep time due to slight lag on s390x machines.
76683d4 to
6eca01f
Compare
On Big-Endian systems (s390x), the flags used by pmda fetch functions to signal a PMDA change fail to be sent and extracted by PMCD.
Raw memory access via memcpy and pointer aliasing correctly targets the most significant byte, causing the status flags to be misplaced or zeroed.
The proposed changes replace byte-level manipulation with numeric assignment to the tv_sec field, ensuring architecture-neutral behavoir.