int __pmSendLabelReq(int fd, int from, int ident, int type) { label_req_t *pp; int sts; int nid; if (type & PM_LABEL_CONTEXT) nid = htonl(PM_ID_NULL); else if (type & PM_LABEL_DOMAIN) nid = htonl(ident); else if (type & PM_LABEL_INDOM) nid = __htonpmInDom((pmInDom)ident); else if (type & (PM_LABEL_CLUSTER|PM_LABEL_ITEM|PM_LABEL_INSTANCES)) nid = __htonpmID((pmID)ident); else return -EINVAL; if ((pp = (label_req_t *)__pmFindPDUBuf(sizeof(label_req_t))) == NULL) return -oserror(); pp->hdr.len = sizeof(label_req_t); pp->hdr.type = PDU_LABEL_REQ; pp->hdr.from = from; pp->ident = nid; pp->type = htonl(type); sts = __pmXmitPDU(fd, (__pmPDU *)pp); __pmUnpinPDUBuf(pp); return sts; }
int __pmSendInstanceReq(int fd, int from, const __pmTimeval *when, pmInDom indom, int inst, const char *name) { instance_req_t *pp; int need; int sts; need = sizeof(instance_req_t) - sizeof(int); if (name != NULL) need += PM_PDU_SIZE_BYTES(strlen(name)); if ((pp = (instance_req_t *)__pmFindPDUBuf(need)) == NULL) return -oserror(); pp->hdr.len = need; pp->hdr.type = PDU_INSTANCE_REQ; pp->hdr.from = from; pp->when.tv_sec = htonl((__int32_t)when->tv_sec); pp->when.tv_usec = htonl((__int32_t)when->tv_usec); pp->indom = __htonpmInDom(indom); pp->inst = htonl(inst); if (name == NULL) pp->namelen = 0; else { pp->namelen = (int)strlen(name); memcpy((void *)pp->name, (void *)name, pp->namelen); if ((pp->namelen % sizeof(__pmPDU)) != 0) { /* clear the padding bytes, lest they contain garbage */ int pad; char *padp = pp->name + pp->namelen; for (pad = sizeof(__pmPDU) - 1; pad >= (pp->namelen % sizeof(__pmPDU)); pad--) *padp++ = '~'; /* buffer end */ } pp->namelen = htonl(pp->namelen); } sts = __pmXmitPDU(fd, (__pmPDU *)pp); __pmUnpinPDUBuf(pp); return sts; }
int __pmSendDesc(int fd, int ctx, pmDesc *desc) { desc_t *pp; int sts; if ((pp = (desc_t *)__pmFindPDUBuf(sizeof(desc_t))) == NULL) return -oserror(); pp->hdr.len = sizeof(desc_t); pp->hdr.type = PDU_DESC; pp->hdr.from = ctx; pp->desc.type = htonl(desc->type); pp->desc.sem = htonl(desc->sem); pp->desc.indom = __htonpmInDom(desc->indom); pp->desc.units = __htonpmUnits(desc->units); pp->desc.pmid = __htonpmID(desc->pmid); sts =__pmXmitPDU(fd, (__pmPDU *)pp); __pmUnpinPDUBuf(pp); return sts; }
int __pmSendTextReq(int fd, int from, int ident, int type) { text_req_t *pp; int sts; if ((pp = (text_req_t *)__pmFindPDUBuf(sizeof(text_req_t))) == NULL) return -oserror(); pp->hdr.len = sizeof(text_req_t); pp->hdr.type = PDU_TEXT_REQ; pp->hdr.from = from; if (type & PM_TEXT_PMID) pp->ident = __htonpmID((pmID)ident); else /* (type & PM_TEXT_INDOM) */ pp->ident = __htonpmInDom((pmInDom)ident); type &= ~PM_TEXT_DIRECT; pp->type = htonl(type); sts = __pmXmitPDU(fd, (__pmPDU *)pp); __pmUnpinPDUBuf(pp); return sts; }
int __pmSendLabel(int fd, int from, int ident, int type, pmLabelSet *sets, int nsets) { size_t labels_offset; size_t labels_need; size_t json_offset; size_t json_need; labelset_t *lsp; labels_t *pp; pmLabel *lp; int sts; int i, j; if (nsets < 0) return -EINVAL; labels_need = sizeof(labels_t) + (sizeof(labelset_t) * (nsets - 1)); json_need = 0; for (i = 0; i < nsets; i++) { json_need += sets[i].jsonlen; if (sets[i].nlabels > 0) labels_need += sets[i].nlabels * sizeof(pmLabel); } if ((pp = (labels_t *)__pmFindPDUBuf((int)labels_need + json_need)) == NULL) return -oserror(); pp->hdr.len = (int)(labels_need + json_need); pp->hdr.type = PDU_LABEL; pp->hdr.from = from; if (type & PM_LABEL_DOMAIN) pp->ident = htonl(ident); else if (type & (PM_LABEL_CLUSTER | PM_LABEL_ITEM | PM_LABEL_INSTANCES)) pp->ident = __htonpmID((pmID)ident); else if (type & PM_LABEL_INDOM) pp->ident = __htonpmInDom((pmInDom)ident); else pp->ident = htonl(PM_ID_NULL); pp->type = htonl(type); pp->padding = 0; pp->nsets = htonl(nsets); labels_offset = (char *)&pp->sets[0] - (char *)pp; json_offset = labels_need; /* JSONB immediately follows labelsets */ for (i = 0; i < nsets; i++) { lsp = (labelset_t *)((char *)pp + labels_offset); lsp->inst = htonl(sets[i].inst); lsp->nlabels = htonl(sets[i].nlabels); lsp->json = htonl(json_offset); lsp->jsonlen = htonl(sets[i].jsonlen); if (sets[i].nlabels > 0) { for (j = 0; j < sets[i].nlabels; j++) { lp = &lsp->labels[j]; lp->name = htons(sets[i].labels[j].name); lp->namelen = sets[i].labels[j].namelen; /* byte copy */ lp->flags = sets[i].labels[j].flags; /* byte copy */ lp->value = htons(sets[i].labels[j].value); lp->valuelen = htons(sets[i].labels[j].valuelen); } labels_offset += sets[i].nlabels * sizeof(pmLabel); } labels_offset += sizeof(labelset_t); if (sets[i].jsonlen) { memcpy((char *)pp + json_offset, sets[i].json, sets[i].jsonlen); json_offset += sets[i].jsonlen; } } if (pmDebugOptions.labels) DumpLabelSets("__pmSendLabel", ident, type, sets, nsets); sts = __pmXmitPDU(fd, (__pmPDU *)pp); __pmUnpinPDUBuf(pp); return sts; }
int __pmSendProfile(int fd, int from, int ctxnum, __pmProfile *instprof) { __pmInDomProfile *prof, *p_end; profile_t *pduProfile; instprof_t *pduInstProf; __pmPDU *p; size_t need; __pmPDU *pdubuf; int sts; /* work out how much space we need and then alloc a pdu buf */ need = sizeof(profile_t) + instprof->profile_len * sizeof(instprof_t); for (prof = instprof->profile, p_end = prof + instprof->profile_len; prof < p_end; prof++) need += prof->instances_len * sizeof(int); if ((pdubuf = __pmFindPDUBuf((int)need)) == NULL) return -oserror(); p = (__pmPDU *)pdubuf; /* First the profile itself */ pduProfile = (profile_t *)p; pduProfile->hdr.len = (int)need; pduProfile->hdr.type = PDU_PROFILE; /* * note: context id may be sent twice due to protocol evolution and * backwards compatibility issues */ pduProfile->hdr.from = from; pduProfile->ctxnum = htonl(ctxnum); pduProfile->g_state = htonl(instprof->state); pduProfile->numprof = htonl(instprof->profile_len); pduProfile->pad = 0; p += sizeof(profile_t) / sizeof(__pmPDU); if (instprof->profile_len) { /* Next all the profile entries (if any) in one block */ for (prof = instprof->profile, p_end = prof + instprof->profile_len; prof < p_end; prof++) { pduInstProf = (instprof_t *)p; pduInstProf->indom = __htonpmInDom(prof->indom); pduInstProf->state = htonl(prof->state); pduInstProf->numinst = htonl(prof->instances_len); pduInstProf->pad = 0; p += sizeof(instprof_t) / sizeof(__pmPDU); } /* and then all the instances */ for (prof = instprof->profile, p_end = prof+instprof->profile_len; prof < p_end; prof++) { int j; /* and then the instances themselves (if any) */ for (j = 0; j < prof->instances_len; j++, p++) *p = htonl(prof->instances[j]); } } sts = __pmXmitPDU(fd, pdubuf); __pmUnpinPDUBuf(pdubuf); return sts; }
int __pmSendInstance(int fd, int from, __pmInResult *result) { instance_t *rp; instlist_t *ip; int need; int i; int j; int sts; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_INDOM) __pmDumpInResult(stderr, result); #endif need = sizeof(*rp) - sizeof(rp->rest); /* instlist_t + name rounded up to a __pmPDU boundary */ for (i = 0; i < result->numinst; i++) { need += sizeof(*ip) - sizeof(ip->name); if (result->namelist != NULL) need += PM_PDU_SIZE_BYTES(strlen(result->namelist[i])); } if ((rp = (instance_t *)__pmFindPDUBuf(need)) == NULL) return -oserror(); rp->hdr.len = need; rp->hdr.type = PDU_INSTANCE; rp->hdr.from = from; rp->indom = __htonpmInDom(result->indom); rp->numinst = htonl(result->numinst); for (i = j = 0; i < result->numinst; i++) { ip = (instlist_t *)&rp->rest[j/sizeof(__pmPDU)]; if (result->instlist != NULL) ip->inst = htonl(result->instlist[i]); else /* weird, but this is going to be ignored at the other end */ ip->inst = htonl(PM_IN_NULL); if (result->namelist != NULL) { ip->namelen = (int)strlen(result->namelist[i]); memcpy((void *)ip->name, (void *)result->namelist[i], ip->namelen); if ((ip->namelen % sizeof(__pmPDU)) != 0) { /* clear the padding bytes, lest they contain garbage */ int pad; char *padp = ip->name + ip->namelen; for (pad = sizeof(__pmPDU) - 1; pad >= (ip->namelen % sizeof(__pmPDU)); pad--) *padp++ = '~'; /* buffer end */ } j += sizeof(*ip) - sizeof(ip->name) + PM_PDU_SIZE_BYTES(ip->namelen); ip->namelen = htonl(ip->namelen); } else { ip->namelen = 0; j += sizeof(*ip) - sizeof(ip->name); } } sts = __pmXmitPDU(fd, (__pmPDU *)rp); __pmUnpinPDUBuf(rp); return sts; }