Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_swrun_tbl.c
109245 views
1
/*
2
* Copyright (c) 2005-2006 The FreeBSD Project
3
* All rights reserved.
4
*
5
* Author: Victor Cruceru <[email protected]>
6
*
7
* Redistribution of this software and documentation and use in source and
8
* binary forms, with or without modification, are permitted provided that
9
* the following conditions are met:
10
*
11
* 1. Redistributions of source code or documentation must retain the above
12
* copyright notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27
* SUCH DAMAGE.
28
*
29
* Host Resources MIB for SNMPd. Implementation for hrSWRunTable
30
*/
31
32
#include <sys/param.h>
33
#include <sys/proc.h>
34
#include <sys/sysctl.h>
35
#include <sys/user.h>
36
#include <sys/linker.h>
37
38
#include <assert.h>
39
#include <signal.h>
40
#include <stdlib.h>
41
#include <string.h>
42
#include <syslog.h>
43
44
#include "hostres_snmp.h"
45
#include "hostres_oid.h"
46
#include "hostres_tree.h"
47
48
/*
49
* Ugly thing: PID_MAX, NO_PID defined only in kernel
50
*/
51
#define NO_PID 100000
52
53
enum SWRunType {
54
SRT_UNKNOWN = 1,
55
SRT_OPERATING_SYSTEM = 2,
56
SRT_DEVICE_DRIVER = 3,
57
SRT_APPLICATION = 4
58
59
};
60
61
enum SWRunStatus {
62
SRS_RUNNING = 1,
63
SRS_RUNNABLE = 2,
64
SRS_NOT_RUNNABLE = 3,
65
SRS_INVALID = 4
66
};
67
68
/* Maximum lengths for the strings according to the MIB */
69
#define SWR_NAME_MLEN (64 + 1)
70
#define SWR_PATH_MLEN (128 + 1)
71
#define SWR_PARAM_MLEN (128 + 1)
72
73
/*
74
* This structure is used to hold a SNMP table entry
75
* for both hrSWRunTable and hrSWRunPerfTable because
76
* hrSWRunPerfTable AUGMENTS hrSWRunTable
77
*/
78
struct swrun_entry {
79
int32_t index;
80
u_char *name; /* it may be NULL */
81
const struct asn_oid *id;
82
u_char *path; /* it may be NULL */
83
u_char *parameters; /* it may be NULL */
84
int32_t type; /* enum SWRunType */
85
int32_t status; /* enum SWRunStatus */
86
int32_t perfCPU;
87
int32_t perfMemory;
88
#define HR_SWRUN_FOUND 0x001
89
uint32_t flags;
90
uint64_t r_tick; /* tick when entry refreshed */
91
TAILQ_ENTRY(swrun_entry) link;
92
};
93
TAILQ_HEAD(swrun_tbl, swrun_entry);
94
95
/* the head of the list with hrSWRunTable's entries */
96
static struct swrun_tbl swrun_tbl = TAILQ_HEAD_INITIALIZER(swrun_tbl);
97
98
/* last (agent) tick when hrSWRunTable and hrSWRunPerTable was updated */
99
static uint64_t swrun_tick;
100
101
/* maximum number of ticks between updates of SWRun and SWRunPerf table */
102
uint32_t swrun_tbl_refresh = HR_SWRUN_TBL_REFRESH * 100;
103
104
/* the value of the MIB object with the same name */
105
static int32_t SWOSIndex;
106
107
/**
108
* Malloc a new entry and add it to the list
109
* associated to this table. The item identified by
110
* the index parameter must not exist in this list.
111
*/
112
static struct swrun_entry *
113
swrun_entry_create(int32_t idx)
114
{
115
struct swrun_entry *entry;
116
117
if ((entry = malloc(sizeof(*entry))) == NULL) {
118
syslog(LOG_WARNING, "%s: %m", __func__);
119
return (NULL);
120
}
121
memset(entry, 0, sizeof(*entry));
122
entry->index = idx;
123
124
INSERT_OBJECT_INT(entry, &swrun_tbl);
125
return (entry);
126
}
127
128
/**
129
* Unlink the entry from the list and then free its heap memory
130
*/
131
static void
132
swrun_entry_delete(struct swrun_entry *entry)
133
{
134
135
assert(entry != NULL);
136
137
TAILQ_REMOVE(&swrun_tbl, entry, link);
138
139
free(entry->name);
140
free(entry->path);
141
free(entry->parameters);
142
free(entry);
143
}
144
145
/**
146
* Search one item by its index, return NULL if none found
147
*/
148
static struct swrun_entry *
149
swrun_entry_find_by_index(int32_t idx)
150
{
151
struct swrun_entry *entry;
152
153
TAILQ_FOREACH(entry, &swrun_tbl, link)
154
if (entry->index == idx)
155
return (entry);
156
return (NULL);
157
}
158
159
/**
160
* Translate the kernel's process status to SNMP.
161
*/
162
static enum SWRunStatus
163
swrun_OS_get_proc_status(const struct kinfo_proc *kp)
164
{
165
166
assert(kp != NULL);
167
if(kp == NULL) {
168
return (SRS_INVALID);
169
}
170
171
/*
172
* I'm using the old style flags - they look cleaner to me,
173
* at least for the purpose of this SNMP table
174
*/
175
switch (kp->ki_stat) {
176
177
case SSTOP:
178
return (SRS_NOT_RUNNABLE);
179
180
case SWAIT:
181
case SLOCK:
182
case SSLEEP:
183
return (SRS_RUNNABLE);
184
185
case SZOMB:
186
return (SRS_INVALID);
187
188
case SIDL:
189
case SRUN:
190
return (SRS_RUNNING);
191
192
default:
193
syslog(LOG_ERR,"Unknown process state: %d", kp->ki_stat);
194
return (SRS_INVALID);
195
}
196
}
197
198
/**
199
* Make an SNMP table entry from a kernel one.
200
*/
201
static void
202
kinfo_proc_to_swrun_entry(const struct kinfo_proc *kp,
203
struct swrun_entry *entry)
204
{
205
char **argv = NULL;
206
uint64_t cpu_time = 0;
207
size_t pname_len;
208
209
pname_len = strlen(kp->ki_comm) + 1;
210
entry->name = reallocf(entry->name, pname_len);
211
if (entry->name != NULL)
212
strlcpy(entry->name, kp->ki_comm, pname_len);
213
214
entry->id = &oid_zeroDotZero; /* unknown id - FIXME */
215
216
assert(hr_kd != NULL);
217
218
argv = kvm_getargv(hr_kd, kp, SWR_PARAM_MLEN - 1);
219
if(argv != NULL){
220
u_char param[SWR_PARAM_MLEN];
221
222
memset(param, '\0', sizeof(param));
223
224
/*
225
* FIXME
226
* Path seems to not be available.
227
* Try to hack the info in argv[0];
228
* this argv is under control of the program so this info
229
* is not realiable
230
*/
231
if(*argv != NULL && (*argv)[0] == '/') {
232
size_t path_len;
233
234
path_len = strlen(*argv) + 1;
235
if (path_len > SWR_PATH_MLEN)
236
path_len = SWR_PATH_MLEN;
237
238
entry->path = reallocf(entry->path, path_len);
239
if (entry->path != NULL) {
240
memset(entry->path, '\0', path_len);
241
strlcpy((char*)entry->path, *argv, path_len);
242
}
243
}
244
245
argv++; /* skip the first one which was used for path */
246
247
while (argv != NULL && *argv != NULL ) {
248
if (param[0] != 0) {
249
/*
250
* add a space between parameters,
251
* except before the first one
252
*/
253
strlcat((char *)param, " ", sizeof(param));
254
}
255
strlcat((char *)param, *argv, sizeof(param));
256
argv++;
257
}
258
/* reuse pname_len */
259
pname_len = strlen(param) + 1;
260
if (pname_len > SWR_PARAM_MLEN)
261
pname_len = SWR_PARAM_MLEN;
262
263
entry->parameters = reallocf(entry->parameters, pname_len);
264
strlcpy(entry->parameters, param, pname_len);
265
}
266
267
entry->type = (int32_t)(IS_KERNPROC(kp) ? SRT_OPERATING_SYSTEM :
268
SRT_APPLICATION);
269
270
entry->status = (int32_t)swrun_OS_get_proc_status(kp);
271
cpu_time = kp->ki_runtime / 100000; /* centi-seconds */
272
273
/* may overflow the snmp type */
274
entry->perfCPU = (cpu_time > (uint64_t)INT_MAX ? INT_MAX : cpu_time);
275
entry->perfMemory = kp->ki_size / 1024; /* in kilo-bytes */
276
entry->r_tick = get_ticks();
277
}
278
279
/**
280
* Create a table entry for a KLD
281
*/
282
static void
283
kld_file_stat_to_swrun(const struct kld_file_stat *kfs,
284
struct swrun_entry *entry)
285
{
286
size_t name_len;
287
288
assert(kfs != NULL);
289
assert(entry != NULL);
290
291
name_len = strlen(kfs->name) + 1;
292
if (name_len > SWR_NAME_MLEN)
293
name_len = SWR_NAME_MLEN;
294
295
entry->name = reallocf(entry->name, name_len);
296
if (entry->name != NULL)
297
strlcpy((char *)entry->name, kfs->name, name_len);
298
299
/* FIXME: can we find the location where the module was loaded from? */
300
entry->path = NULL;
301
302
/* no parameters for kernel files (.ko) of for the kernel */
303
entry->parameters = NULL;
304
305
entry->id = &oid_zeroDotZero; /* unknown id - FIXME */
306
307
if (strcmp(kfs->name, "kernel") == 0) {
308
entry->type = (int32_t)SRT_OPERATING_SYSTEM;
309
SWOSIndex = entry->index;
310
} else {
311
entry->type = (int32_t)SRT_DEVICE_DRIVER; /* well, not really */
312
}
313
entry->status = (int32_t)SRS_RUNNING;
314
entry->perfCPU = 0; /* Info not available */
315
entry->perfMemory = kfs->size / 1024; /* in kilo-bytes */
316
entry->r_tick = get_ticks();
317
}
318
319
/**
320
* Get all visible processes including the kernel visible threads
321
*/
322
static void
323
swrun_OS_get_procs(void)
324
{
325
struct kinfo_proc *plist, *kp;
326
int i;
327
int nproc;
328
struct swrun_entry *entry;
329
330
plist = kvm_getprocs(hr_kd, KERN_PROC_ALL, 0, &nproc);
331
if (plist == NULL || nproc < 0) {
332
syslog(LOG_ERR, "kvm_getprocs() failed: %m");
333
return;
334
}
335
for (i = 0, kp = plist; i < nproc; i++, kp++) {
336
/*
337
* The SNMP table's index must begin from 1 (as specified by
338
* this table definition), the PIDs are starting from 0
339
* so we are translating the PIDs to +1
340
*/
341
entry = swrun_entry_find_by_index((int32_t)kp->ki_pid + 1);
342
if (entry == NULL) {
343
/* new entry - get memory for it */
344
entry = swrun_entry_create((int32_t)kp->ki_pid + 1);
345
if (entry == NULL)
346
continue;
347
}
348
entry->flags |= HR_SWRUN_FOUND; /* mark it as found */
349
350
kinfo_proc_to_swrun_entry(kp, entry);
351
}
352
}
353
354
/*
355
* Get kernel items: first the kernel itself, then the loaded modules.
356
*/
357
static void
358
swrun_OS_get_kinfo(void)
359
{
360
int fileid;
361
struct swrun_entry *entry;
362
struct kld_file_stat stat;
363
364
for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) {
365
stat.version = sizeof(struct kld_file_stat);
366
if (kldstat(fileid, &stat) < 0) {
367
syslog(LOG_ERR, "kldstat() failed: %m");
368
continue;
369
}
370
371
/*
372
* kernel and kernel files (*.ko) will be indexed starting with
373
* NO_PID + 1; NO_PID is PID_MAX + 1 thus it will be no risk to
374
* overlap with real PIDs which are in range of 1 .. NO_PID
375
*/
376
entry = swrun_entry_find_by_index(NO_PID + 1 + stat.id);
377
if (entry == NULL) {
378
/* new entry - get memory for it */
379
entry = swrun_entry_create(NO_PID + 1 + stat.id);
380
if (entry == NULL)
381
continue;
382
}
383
entry->flags |= HR_SWRUN_FOUND; /* mark it as found */
384
385
kld_file_stat_to_swrun(&stat, entry);
386
}
387
}
388
389
/**
390
* Refresh the hrSWRun and hrSWRunPert tables.
391
*/
392
static void
393
refresh_swrun_tbl(void)
394
{
395
396
struct swrun_entry *entry, *entry_tmp;
397
398
if (this_tick - swrun_tick < swrun_tbl_refresh) {
399
HRDBG("no refresh needed ");
400
return;
401
}
402
403
/* mark each entry as missing */
404
TAILQ_FOREACH(entry, &swrun_tbl, link)
405
entry->flags &= ~HR_SWRUN_FOUND;
406
407
swrun_OS_get_procs();
408
swrun_OS_get_kinfo();
409
410
/*
411
* Purge items that disappeared
412
*/
413
TAILQ_FOREACH_SAFE(entry, &swrun_tbl, link, entry_tmp)
414
if (!(entry->flags & HR_SWRUN_FOUND))
415
swrun_entry_delete(entry);
416
417
swrun_tick = this_tick;
418
419
HRDBG("refresh DONE");
420
}
421
422
/**
423
* Update the information in this entry
424
*/
425
static void
426
fetch_swrun_entry(struct swrun_entry *entry)
427
{
428
struct kinfo_proc *plist;
429
int nproc;
430
struct kld_file_stat stat;
431
432
assert(entry != NULL);
433
434
if (entry->index >= NO_PID + 1) {
435
/*
436
* kernel and kernel files (*.ko) will be indexed
437
* starting with NO_PID + 1; NO_PID is PID_MAX + 1
438
* thus it will be no risk to overlap with real PIDs
439
* which are in range of 1 .. NO_PID
440
*/
441
stat.version = sizeof(stat);
442
if (kldstat(entry->index - NO_PID - 1, &stat) == -1) {
443
/*
444
* not found, it's gone. Mark it as invalid for now, it
445
* will be removed from the list at next global refersh
446
*/
447
HRDBG("missing item with kid=%d",
448
entry->index - NO_PID - 1);
449
entry->status = (int32_t)SRS_INVALID;
450
} else
451
kld_file_stat_to_swrun(&stat, entry);
452
453
} else {
454
/* this is a process */
455
assert(hr_kd != NULL);
456
plist = kvm_getprocs(hr_kd, KERN_PROC_PID,
457
entry->index - 1, &nproc);
458
if (plist == NULL || nproc != 1) {
459
HRDBG("missing item with PID=%d", entry->index - 1);
460
entry->status = (int32_t)SRS_INVALID;
461
} else
462
kinfo_proc_to_swrun_entry(plist, entry);
463
}
464
}
465
466
/**
467
* Invalidate entry. For KLDs we try to unload it, for processes we SIGKILL it.
468
*/
469
static int
470
invalidate_swrun_entry(struct swrun_entry *entry, int commit)
471
{
472
struct kinfo_proc *plist;
473
int nproc;
474
struct kld_file_stat stat;
475
476
assert(entry != NULL);
477
478
if (entry->index >= NO_PID + 1) {
479
/* this is a kernel item */
480
HRDBG("attempt to unload KLD %d",
481
entry->index - NO_PID - 1);
482
483
if (entry->index == SWOSIndex) {
484
/* can't invalidate the kernel itself */
485
return (SNMP_ERR_NOT_WRITEABLE);
486
}
487
488
stat.version = sizeof(stat);
489
if (kldstat(entry->index - NO_PID - 1, &stat) == -1) {
490
/*
491
* not found, it's gone. Mark it as invalid for now, it
492
* will be removed from the list at next global
493
* refresh
494
*/
495
HRDBG("missing item with kid=%d",
496
entry->index - NO_PID - 1);
497
entry->status = (int32_t)SRS_INVALID;
498
return (SNMP_ERR_NOERROR);
499
}
500
/*
501
* There is no way to try to unload a module. There seems
502
* also no way to find out whether it is busy without unloading
503
* it. We can assume that it is busy, if the reference count
504
* is larger than 2, but if it is 1 nothing helps.
505
*/
506
if (!commit) {
507
if (stat.refs > 1)
508
return (SNMP_ERR_NOT_WRITEABLE);
509
return (SNMP_ERR_NOERROR);
510
}
511
if (kldunload(stat.id) == -1) {
512
syslog(LOG_ERR,"kldunload for %d/%s failed: %m",
513
stat.id, stat.name);
514
if (errno == EBUSY)
515
return (SNMP_ERR_NOT_WRITEABLE);
516
else
517
return (SNMP_ERR_RES_UNAVAIL);
518
}
519
} else {
520
/* this is a process */
521
assert(hr_kd != NULL);
522
523
plist = kvm_getprocs(hr_kd, KERN_PROC_PID,
524
entry->index - 1, &nproc);
525
if (plist == NULL || nproc != 1) {
526
HRDBG("missing item with PID=%d", entry->index - 1);
527
entry->status = (int32_t)SRS_INVALID;
528
return (SNMP_ERR_NOERROR);
529
}
530
if (IS_KERNPROC(plist)) {
531
/* you don't want to do this */
532
return (SNMP_ERR_NOT_WRITEABLE);
533
}
534
if (kill(entry->index - 1, commit ? SIGKILL : 0) < 0) {
535
syslog(LOG_ERR,"kill (%d, SIGKILL) failed: %m",
536
entry->index - 1);
537
if (errno == ESRCH) {
538
/* race: just gone */
539
entry->status = (int32_t)SRS_INVALID;
540
return (SNMP_ERR_NOERROR);
541
}
542
return (SNMP_ERR_GENERR);
543
}
544
}
545
return (SNMP_ERR_NOERROR);
546
}
547
548
/**
549
* Populate the hrSWRunTable.
550
*/
551
void
552
init_swrun_tbl(void)
553
{
554
555
refresh_swrun_tbl();
556
HRDBG("done");
557
}
558
559
/**
560
* Finalize the hrSWRunTable.
561
*/
562
void
563
fini_swrun_tbl(void)
564
{
565
struct swrun_entry *n1;
566
567
while ((n1 = TAILQ_FIRST(&swrun_tbl)) != NULL) {
568
TAILQ_REMOVE(&swrun_tbl, n1, link);
569
free(n1);
570
}
571
}
572
573
/*
574
* This is the implementation for a generated (by a SNMP tool)
575
* function prototype, see hostres_tree.h
576
* It handles the SNMP operations for hrSWRunTable
577
*/
578
int
579
op_hrSWRunTable(struct snmp_context *ctx __unused, struct snmp_value *value,
580
u_int sub, u_int iidx __unused, enum snmp_op curr_op)
581
{
582
struct swrun_entry *entry;
583
int ret;
584
585
refresh_swrun_tbl();
586
587
switch (curr_op) {
588
589
case SNMP_OP_GETNEXT:
590
if ((entry = NEXT_OBJECT_INT(&swrun_tbl,
591
&value->var, sub)) == NULL)
592
return (SNMP_ERR_NOSUCHNAME);
593
value->var.len = sub + 1;
594
value->var.subs[sub] = entry->index;
595
goto get;
596
597
case SNMP_OP_GET:
598
if ((entry = FIND_OBJECT_INT(&swrun_tbl,
599
&value->var, sub)) == NULL)
600
return (SNMP_ERR_NOSUCHNAME);
601
goto get;
602
603
case SNMP_OP_SET:
604
if ((entry = FIND_OBJECT_INT(&swrun_tbl,
605
&value->var, sub)) == NULL)
606
return (SNMP_ERR_NO_CREATION);
607
608
if (entry->r_tick < this_tick)
609
fetch_swrun_entry(entry);
610
611
switch (value->var.subs[sub - 1]) {
612
613
case LEAF_hrSWRunStatus:
614
if (value->v.integer != (int32_t)SRS_INVALID)
615
return (SNMP_ERR_WRONG_VALUE);
616
617
if (entry->status == (int32_t)SRS_INVALID)
618
return (SNMP_ERR_NOERROR);
619
620
/*
621
* Here we have a problem with the entire SNMP
622
* model: if we kill now, we cannot rollback.
623
* If we kill in the commit code, we cannot
624
* return an error. Because things may change between
625
* SET and COMMIT this is impossible to handle
626
* correctly.
627
*/
628
return (invalidate_swrun_entry(entry, 0));
629
}
630
return (SNMP_ERR_NOT_WRITEABLE);
631
632
case SNMP_OP_ROLLBACK:
633
return (SNMP_ERR_NOERROR);
634
635
case SNMP_OP_COMMIT:
636
if ((entry = FIND_OBJECT_INT(&swrun_tbl,
637
&value->var, sub)) == NULL)
638
return (SNMP_ERR_NOERROR);
639
640
switch (value->var.subs[sub - 1]) {
641
642
case LEAF_hrSWRunStatus:
643
if (value->v.integer == (int32_t)SRS_INVALID &&
644
entry->status != (int32_t)SRS_INVALID)
645
(void)invalidate_swrun_entry(entry, 1);
646
return (SNMP_ERR_NOERROR);
647
}
648
abort();
649
}
650
abort();
651
652
get:
653
ret = SNMP_ERR_NOERROR;
654
switch (value->var.subs[sub - 1]) {
655
656
case LEAF_hrSWRunIndex:
657
value->v.integer = entry->index;
658
break;
659
660
case LEAF_hrSWRunName:
661
if (entry->name != NULL)
662
ret = string_get(value, entry->name, -1);
663
else
664
ret = string_get(value, "", -1);
665
break;
666
667
case LEAF_hrSWRunID:
668
assert(entry->id != NULL);
669
value->v.oid = *entry->id;
670
break;
671
672
case LEAF_hrSWRunPath:
673
if (entry->path != NULL)
674
ret = string_get(value, entry->path, -1);
675
else
676
ret = string_get(value, "", -1);
677
break;
678
679
case LEAF_hrSWRunParameters:
680
if (entry->parameters != NULL)
681
ret = string_get(value, entry->parameters, -1);
682
else
683
ret = string_get(value, "", -1);
684
break;
685
686
case LEAF_hrSWRunType:
687
value->v.integer = entry->type;
688
break;
689
690
case LEAF_hrSWRunStatus:
691
value->v.integer = entry->status;
692
break;
693
694
default:
695
abort();
696
}
697
return (ret);
698
}
699
700
/**
701
* Scalar(s) in the SWRun group
702
*/
703
int
704
op_hrSWRun(struct snmp_context *ctx __unused, struct snmp_value *value,
705
u_int sub, u_int iidx __unused, enum snmp_op curr_op)
706
{
707
708
/* only SNMP GET is possible */
709
switch (curr_op) {
710
711
case SNMP_OP_GET:
712
goto get;
713
714
case SNMP_OP_SET:
715
return (SNMP_ERR_NOT_WRITEABLE);
716
717
case SNMP_OP_ROLLBACK:
718
case SNMP_OP_COMMIT:
719
case SNMP_OP_GETNEXT:
720
abort();
721
}
722
abort();
723
724
get:
725
switch (value->var.subs[sub - 1]) {
726
727
case LEAF_hrSWOSIndex:
728
value->v.uint32 = SWOSIndex;
729
return (SNMP_ERR_NOERROR);
730
731
default:
732
abort();
733
}
734
}
735
736
/*
737
* This is the implementation for a generated (by a SNMP tool)
738
* function prototype, see hostres_tree.h
739
* It handles the SNMP operations for hrSWRunPerfTable
740
*/
741
int
742
op_hrSWRunPerfTable(struct snmp_context *ctx __unused,
743
struct snmp_value *value, u_int sub, u_int iidx __unused,
744
enum snmp_op curr_op )
745
{
746
struct swrun_entry *entry;
747
748
refresh_swrun_tbl();
749
750
switch (curr_op) {
751
752
case SNMP_OP_GETNEXT:
753
if ((entry = NEXT_OBJECT_INT(&swrun_tbl,
754
&value->var, sub)) == NULL)
755
return (SNMP_ERR_NOSUCHNAME);
756
value->var.len = sub + 1;
757
value->var.subs[sub] = entry->index;
758
goto get;
759
760
case SNMP_OP_GET:
761
if ((entry = FIND_OBJECT_INT(&swrun_tbl,
762
&value->var, sub)) == NULL)
763
return (SNMP_ERR_NOSUCHNAME);
764
goto get;
765
766
case SNMP_OP_SET:
767
if ((entry = FIND_OBJECT_INT(&swrun_tbl,
768
&value->var, sub)) == NULL)
769
return (SNMP_ERR_NO_CREATION);
770
return (SNMP_ERR_NOT_WRITEABLE);
771
772
case SNMP_OP_ROLLBACK:
773
case SNMP_OP_COMMIT:
774
abort();
775
}
776
abort();
777
778
get:
779
switch (value->var.subs[sub - 1]) {
780
781
case LEAF_hrSWRunPerfCPU:
782
value->v.integer = entry->perfCPU;
783
return (SNMP_ERR_NOERROR);
784
785
case LEAF_hrSWRunPerfMem:
786
value->v.integer = entry->perfMemory;
787
return (SNMP_ERR_NOERROR);
788
}
789
abort();
790
}
791
792