Right now we return the same value for both hrSWRunName and hrSWRunPath. hrSWRunPath should return the full path of the binary, and hrSWRunName a description of the running software.
Afaik there's no proper way to retrieve the full path of the running binary, However, in a lot of cases argv[0] can contain the full or relative path. But if argv[0] gets overwritten (like most of our daemons' children) it gives a more descriptive name, which is more in line with hrSWRunName. netsnmp's snmpd uses argv[0] for hrSWRunPath and kinfo_proc's p_comm for hrSWRunName, and snmptop defaults to hrSWRunName. top(1) also defaults to p_comm, but contrary to top(1), snmptop allows us to switch between hrSWRunName, and hrSWRunPath and toggling of hrSWRunParameters independently, where top(1) toggles between p_comm and argv[]. So there's an argument to be made either way, but for this diff I stuck with netsnmp's choices. While here, change the buffer length from 128 to 129. HOST-RESOURCES-MIB allows up to 128 characters in the response, so make room for the terminating NUL. Thoughts? OK? martijn@ Index: mib.c =================================================================== RCS file: /cvs/src/libexec/snmpd/snmpd_metrics/mib.c,v retrieving revision 1.4 diff -u -p -r1.4 mib.c --- mib.c 4 Jul 2023 11:34:19 -0000 1.4 +++ mib.c 18 Oct 2023 11:47:00 -0000 @@ -103,7 +103,9 @@ int kinfo_proc_comp(const void *, const int kinfo_proc(u_int32_t, struct kinfo_proc **); void kinfo_timer_cb(int, short, void *); void kinfo_proc_free(void); -int kinfo_args(struct kinfo_proc *, char **); +int kinfo_args(struct kinfo_proc *, char ***); +int kinfo_path(struct kinfo_proc *, char **); +int kinfo_parameters(struct kinfo_proc *, char **); /* IF-MIB */ struct agentx_index *ifIdx; @@ -669,13 +671,21 @@ mib_hrswrun(struct agentx_varbind *vb) if (obj == hrSWRunIndex) agentx_varbind_integer(vb, kinfo->p_pid); - else if (obj == hrSWRunName || obj == hrSWRunPath) + else if (obj == hrSWRunName) agentx_varbind_string(vb, kinfo->p_comm); - else if (obj == hrSWRunID) + else if (obj == hrSWRunPath) { + if (kinfo_path(kinfo, &s) == -1) { + log_warn("kinfo_path"); + agentx_varbind_error(vb); + return; + } + + agentx_varbind_string(vb, s); + } else if (obj == hrSWRunID) agentx_varbind_oid(vb, AGENTX_OID(0, 0)); else if (obj == hrSWRunParameters) { - if (kinfo_args(kinfo, &s) == -1) { - log_warn("kinfo_args"); + if (kinfo_parameters(kinfo, &s) == -1) { + log_warn("kinfo_parameters"); agentx_varbind_error(vb); return; } @@ -811,25 +821,22 @@ kinfo_proc_free(void) } int -kinfo_args(struct kinfo_proc *kinfo, char **s) +kinfo_args(struct kinfo_proc *kinfo, char ***s) { - static char str[128]; static char *buf = NULL; static size_t buflen = 128; int mib[] = { CTL_KERN, KERN_PROC_ARGS, kinfo->p_pid, KERN_PROC_ARGV }; - char *nbuf, **argv; + char *nbuf; + *s = NULL; if (buf == NULL) { buf = malloc(buflen); if (buf == NULL) return (-1); } - str[0] = '\0'; - *s = str; - while (sysctl(mib, nitems(mib), buf, &buflen, NULL, 0) == -1) { if (errno != ENOMEM) { /* some errors are expected, dont get too upset */ @@ -844,11 +851,41 @@ kinfo_args(struct kinfo_proc *kinfo, cha buflen += 128; } - argv = (char **)buf; - if (argv[0] == NULL) - return (0); + *s = (char **)buf; + return (0); +} + +int +kinfo_path(struct kinfo_proc *kinfo, char **s) +{ + static char str[129]; + char **argv; + + if (kinfo_args(kinfo, &argv) == -1) + return (-1); + str[0] = '\0'; + *s = str; + if (argv != NULL && argv[0] != NULL) + strlcpy(str, argv[0], sizeof(str)); + return (0); +} + +int +kinfo_parameters(struct kinfo_proc *kinfo, char **s) +{ + static char str[129]; + char **argv; + + if (kinfo_args(kinfo, &argv) == -1) + return (-1); + + str[0] = '\0'; + *s = str; + if (argv == NULL || argv[0] == NULL) + return (0); argv++; + while (*argv != NULL) { strlcat(str, *argv, sizeof(str)); argv++;