Skip to content

Commit

Permalink
Update kstata json status
Browse files Browse the repository at this point in the history
Signed-off-by: Umer Saleem <[email protected]>
  • Loading branch information
usaleem-ix committed Aug 15, 2024
1 parent c13b4da commit 1c39c9d
Show file tree
Hide file tree
Showing 3 changed files with 485 additions and 397 deletions.
3 changes: 3 additions & 0 deletions include/sys/nvpair.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,9 @@ _SYS_NVPAIR_H int nvlist_remove(nvlist_t *, const char *, data_type_t);
_SYS_NVPAIR_H int nvlist_remove_all(nvlist_t *, const char *);
_SYS_NVPAIR_H int nvlist_remove_nvpair(nvlist_t *, nvpair_t *);

_SYS_NVPAIR_H int nvlist_json(nvlist_t *, char **, size_t);
_SYS_NVPAIR_H int nvlist_json_string(const char *, char **, size_t);

_SYS_NVPAIR_H int nvlist_lookup_boolean(const nvlist_t *, const char *);
_SYS_NVPAIR_H int nvlist_lookup_boolean_value(const nvlist_t *, const char *,
boolean_t *);
Expand Down
360 changes: 360 additions & 0 deletions module/nvpair/nvpair.c
Original file line number Diff line number Diff line change
Expand Up @@ -994,6 +994,366 @@ nvlist_remove_nvpair(nvlist_t *nvl, nvpair_t *nvp)
return (0);
}

#define SNPRINTF(start, end, ...) \
do { \
if (start < end) \
start += snprintf(start, end - start, __VA_ARGS__); \
else \
return (ENOMEM); \
} while (0)

int
nvlist_json_string(const char *s, char **buf, size_t size)
{
char *p = *buf;
char *end = *buf + size;
static const char *hex = "0123456789ABCDEF";
int c;

if (s == NULL) {
SNPRINTF(p, end, "null");
*buf = p;
return (0);
}

SNPRINTF(p, end, "\"");
while (*s) {
c = (int)*s++;
/* formfeed, newline, return, tab, backspace */
if (c == 12)
SNPRINTF(p, end, "\\f");
else if (c == 10)
SNPRINTF(p, end, "\\n");
else if (c == 13)
SNPRINTF(p, end, "\\r");
else if (c == 9)
SNPRINTF(p, end, "\\t");
else if (c == 8)
SNPRINTF(p, end, "\\b");
/*
* all characters from 0x00 to 0x1f, and 0x7f are
* escaped as: \u00xx
*/
else if (((0 <= c) && (c <= 0x1f)) || (c == 0x7f)) {
SNPRINTF(p, end, "\\u00%c%c",
hex[(c >> 4) & 0x0f], hex[c & 0x0f]);
} else if (c == '"')
SNPRINTF(p, end, "\\\"");
else if (c == '\\')
SNPRINTF(p, end, "\\\\");
else if (c == '/')
SNPRINTF(p, end, "\\/");
/*
* all other printable characters ' ' to '~', and
* any utf-8 sequences (high bit set):
* 1xxxxxxx 10xxxxxx ...
* is a utf-8 sequence (10xxxxxx may occur 1 to 3 times).
* Note that this is simply distinguished here as high
* bit set.
*/
else
SNPRINTF(p, end, "%c", c);
}
SNPRINTF(p, end, "\"");
*buf = p;
return (0);
}

int
nvlist_json(nvlist_t *nvl, char **buf, size_t size)
{
boolean_t first = B_TRUE;
char *p = *buf;
char *end = *buf + size;
nvpair_t *curr = nvlist_next_nvpair(nvl, NULL);

SNPRINTF(p, end, "{");

while (curr) {
if (!first)
SNPRINTF(p, end, ",");
else
first = B_FALSE;

if (nvlist_json_string(nvpair_name(curr), &p, end - p) != 0)
return (ENOMEM);
SNPRINTF(p, end, ":");

switch (nvpair_type(curr)) {
case DATA_TYPE_STRING: {
if (nvlist_json_string(fnvpair_value_string(curr), &p,
end - p) != 0)
return (ENOMEM);
break;
}

case DATA_TYPE_BOOLEAN: {
SNPRINTF(p, end, "true");
break;
}

case DATA_TYPE_BOOLEAN_VALUE: {
SNPRINTF(p, end, "%s",
fnvpair_value_boolean_value(curr) == B_TRUE ?
"true" : "false");
break;
}

case DATA_TYPE_BYTE: {
SNPRINTF(p, end, "%hhu", fnvpair_value_byte(curr));
break;
}

case DATA_TYPE_INT8: {
SNPRINTF(p, end, "%hhd", fnvpair_value_int8(curr));
break;
}

case DATA_TYPE_UINT8: {
SNPRINTF(p, end, "%hhu", fnvpair_value_uint8(curr));
break;
}

case DATA_TYPE_INT16: {
SNPRINTF(p, end, "%hd", fnvpair_value_int16(curr));
break;
}

case DATA_TYPE_UINT16: {
SNPRINTF(p, end, "%hu", fnvpair_value_uint16(curr));
break;
}

case DATA_TYPE_INT32: {
SNPRINTF(p, end, "%d", fnvpair_value_int32(curr));
break;
}

case DATA_TYPE_UINT32: {
SNPRINTF(p, end, "%u", fnvpair_value_uint32(curr));
break;
}

case DATA_TYPE_INT64: {
SNPRINTF(p, end, "%lld",
(long long)fnvpair_value_int64(curr));
break;
}

case DATA_TYPE_UINT64: {
SNPRINTF(p, end, "%llu",
(unsigned long long)fnvpair_value_uint64(curr));
break;
}

case DATA_TYPE_HRTIME: {
hrtime_t val;
VERIFY0(nvpair_value_hrtime(curr, &val));
SNPRINTF(p, end, "%llu", (unsigned long long)val);
break;
}

#if !defined(_KERNEL)
case DATA_TYPE_DOUBLE: {
double val;
VERIFY0(nvpair_value_double(curr, &val));
SNPRINTF(p, end, "%f", val);
break;
}
#endif

case DATA_TYPE_NVLIST: {
if (nvlist_json(fnvpair_value_nvlist(curr), &p, end - p)
!= 0)
return (ENOMEM);
break;
}

case DATA_TYPE_STRING_ARRAY: {
const char **val;
uint_t valsz, i;
VERIFY0(nvpair_value_string_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
if (nvlist_json_string(val[i], &p,
end - p) != 0)
return (ENOMEM);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_NVLIST_ARRAY: {
nvlist_t **val;
uint_t valsz, i;
VERIFY0(nvpair_value_nvlist_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
if (nvlist_json(val[i], &p, end - p) != 0)
return (ENOMEM);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_BOOLEAN_ARRAY: {
boolean_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_boolean_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, val[i] == B_TRUE ?
"true" : "false");
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_BYTE_ARRAY: {
uchar_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_byte_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%hhu", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_UINT8_ARRAY: {
uint8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint8_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%hhu", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_INT8_ARRAY: {
int8_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int8_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%hhd", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_UINT16_ARRAY: {
uint16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint16_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%hu", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_INT16_ARRAY: {
int16_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int16_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0) {
SNPRINTF(p, end, ",");
}
SNPRINTF(p, end, "%hd", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_UINT32_ARRAY: {
uint32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint32_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%u", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_INT32_ARRAY: {
int32_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int32_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%d", val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_UINT64_ARRAY: {
uint64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_uint64_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%llu",
(unsigned long long)val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_INT64_ARRAY: {
int64_t *val;
uint_t valsz, i;
VERIFY0(nvpair_value_int64_array(curr, &val, &valsz));
SNPRINTF(p, end, "[");
for (i = 0; i < valsz; i++) {
if (i > 0)
SNPRINTF(p, end, ",");
SNPRINTF(p, end, "%lld", (long long)val[i]);
}
SNPRINTF(p, end, "]");
break;
}

case DATA_TYPE_UNKNOWN:
case DATA_TYPE_DONTCARE:
return (-1);
}
curr = nvlist_next_nvpair(nvl, curr);
}
SNPRINTF(p, end, "}");
*buf = p;
return (0);
}

/*
* This function calculates the size of an nvpair value.
*
Expand Down
Loading

0 comments on commit 1c39c9d

Please sign in to comment.