CS350 COS
COS
Loading...
Searching...
No Matches
sysctl.c
Go to the documentation of this file.
1
2#include <stdbool.h>
3#include <stdint.h>
4#include <string.h>
5#include <errno.h>
6
7#include <sys/kassert.h>
8#include <sys/kdebug.h>
9#include <sys/sysctl.h>
10
11typedef struct SysCtlEntry {
12 char path[64];
13 int type;
14 int flags;
15 char description[128];
16 void *node;
18
19#define SYSCTL_STR(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
20 { #_PATH, SYSCTL_TYPE_STR, _FLAGS, _DESCRIPTION, &SYSCTL_##_PATH },
21#define SYSCTL_INT(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
22 { #_PATH, SYSCTL_TYPE_INT, _FLAGS, _DESCRIPTION, &SYSCTL_##_PATH },
23#define SYSCTL_BOOL(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
24 { #_PATH, SYSCTL_TYPE_BOOL, _FLAGS, _DESCRIPTION, &SYSCTL_##_PATH },
27 { "", 0, 0, "", NULL },
28};
29#undef SYSCTL_STR
30#undef SYSCTL_INT
31#undef SYSCTL_BOOL
32
33#define SYSCTL_STR(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
34SysCtlString SYSCTL_##_PATH = { #_PATH, _DEFAULT };
35#define SYSCTL_INT(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
36SysCtlInt SYSCTL_##_PATH = { #_PATH, _DEFAULT };
37#define SYSCTL_BOOL(_PATH, _FLAGS, _DESCRIPTION, _DEFAULT) \
38SysCtlBool SYSCTL_##_PATH = { #_PATH, _DEFAULT };
40#undef SYSCTL_STR
41#undef SYSCTL_INT
42#undef SYSCTL_BOOL
43
44int
45SysCtl_Lookup(const char *path)
46{
47 int i;
48
49 for (i = 0; SYSCTLTable[i].path[0] != '\0'; i++) {
50 if (strcmp(path, SYSCTLTable[i].path) == 0)
51 return i;
52 }
53
54 return -1;
55}
56
58SysCtl_GetType(const char *node)
59{
60 int i = SysCtl_Lookup(node);
61 if (i == -1) {
63 }
64
65 return SYSCTLTable[i].type;
66}
67
68void *
69SysCtl_GetObject(const char *node)
70{
71 int i = SysCtl_Lookup(node);
72 if (i == -1) {
73 return NULL;
74 }
75
76 return SYSCTLTable[i].node;
77}
78
80SysCtl_SetObject(const char *node, void *obj)
81{
82 int i = SysCtl_Lookup(node);
83 if (i == -1) {
84 return ENOENT;
85 }
86
87 if (SYSCTLTable[i].flags == SYSCTL_FLAG_RO) {
88 kprintf("Sysctl node is read-only!\n");
89 return EACCES;
90 }
91
92 switch (SYSCTLTable[i].type) {
93 case SYSCTL_TYPE_STR: {
94 SysCtlString *val = (SysCtlString *)SYSCTLTable[i].node;
95 memcpy(val, obj, sizeof(*val));
96 }
97 case SYSCTL_TYPE_INT: {
98 SysCtlInt *val = (SysCtlInt *)SYSCTLTable[i].node;
99 memcpy(val, obj, sizeof(*val));
100 }
101 case SYSCTL_TYPE_BOOL: {
102 SysCtlBool *val = (SysCtlBool *)SYSCTLTable[i].node;
103 memcpy(val, obj, sizeof(*val));
104 }
105 }
106
107 return 0;
108}
109
110void
111Debug_SysCtl(int argc, const char *argv[])
112{
113 int i;
114
115 if (argc == 1) {
116 kprintf("%-20s %s\n", "Name", "Description");
117 for (i = 0; SYSCTLTable[i].path[0] != '\0'; i++) {
118 kprintf("%-20s %s\n", SYSCTLTable[i].path, SYSCTLTable[i].description);
119 }
120
121 return;
122 }
123
124 if (argc != 2 && argc != 3) {
125 kprintf("Usage: sysctl NODE [VALUE]\n");
126 return;
127 }
128
129 i = SysCtl_Lookup(argv[1]);
130 if (i == -1) {
131 kprintf("Unknown sysctl node!\n");
132 return;
133 }
134
135 if (argc == 2) {
136 switch (SYSCTLTable[i].type) {
137 case SYSCTL_TYPE_STR: {
138 SysCtlString *val = (SysCtlString *)SYSCTLTable[i].node;
139 kprintf("%s: %s\n", argv[1], val->value);
140 break;
141 }
142 case SYSCTL_TYPE_INT: {
143 SysCtlInt *val = (SysCtlInt *)SYSCTLTable[i].node;
144 kprintf("%s: %ld\n", argv[1], val->value);
145 break;
146 }
147 case SYSCTL_TYPE_BOOL: {
148 SysCtlBool *val = (SysCtlBool *)SYSCTLTable[i].node;
149 kprintf("%s: %s\n", argv[1], val->value ? "true" : "false");
150 break;
151 }
152 }
153
154 return;
155 }
156
157 if (argc == 3) {
158 if (SYSCTLTable[i].flags == SYSCTL_FLAG_RO) {
159 kprintf("Sysctl node is read-only!\n");
160 return;
161 }
162
163 switch (SYSCTLTable[i].type) {
164 case SYSCTL_TYPE_STR: {
165 SysCtlString *val = (SysCtlString *)SYSCTLTable[i].node;
166 strncpy(&val->value[0], argv[2], SYSCTL_STR_MAXLENGTH);
167 break;
168 }
169 case SYSCTL_TYPE_INT: {
170 SysCtlInt *val = (SysCtlInt *)SYSCTLTable[i].node;
171 val->value = Debug_StrToInt(argv[2]);
172 break;
173 }
174 case SYSCTL_TYPE_BOOL: {
175 SysCtlBool *val = (SysCtlBool *)SYSCTLTable[i].node;
176 if (strcmp(argv[2], "0") == 0) {
177 val->value = false;
178 } else if (strcmp(argv[2], "1") == 0) {
179 val->value = true;
180 } else {
181 kprintf("Invalid value!\n");
182 }
183 break;
184 }
185 }
186 }
187}
188
189REGISTER_DBGCMD(sysctl, "SYSCTL", Debug_SysCtl);
190
#define ENOENT
Definition: errno.h:15
#define EACCES
Definition: errno.h:26
int kprintf(const char *fmt,...)
Definition: printf.c:210
uint64_t Debug_StrToInt(const char *s)
Definition: debug.c:124
#define REGISTER_DBGCMD(_NAME, _DESC, _FUNC)
Definition: kdebug.h:11
uint32_t type
Definition: multiboot.h:8
SysCtlEntry SYSCTLTable[]
Definition: sysctl.c:23
struct SysCtlEntry SysCtlEntry
#define NULL
Definition: stddef.h:6
int strcmp(const char *s1, const char *s2)
Definition: string.c:81
char * strncpy(char *to, const char *from, size_t len)
Definition: string.c:34
void * memcpy(void *dst, const void *src, size_t len)
Definition: string.c:177
void * node
Definition: sysctl.c:16
uint64_t SysCtl_SetObject(const char *node, void *obj)
Definition: sysctl.c:80
uint64_t SysCtl_GetType(const char *node)
Definition: sysctl.c:58
int type
Definition: sysctl.c:12
void * SysCtl_GetObject(const char *node)
Definition: sysctl.c:69
int flags
Definition: sysctl.c:13
SYSCTL_LIST int SysCtl_Lookup(const char *path)
Definition: sysctl.c:45
void Debug_SysCtl(int argc, const char *argv[])
Definition: sysctl.c:111
char description[128]
Definition: sysctl.c:14
char path[64]
Definition: sysctl.c:11
#define SYSCTL_TYPE_INVALID
Definition: sysctl.h:15
int64_t value
Definition: sysctl.h:42
#define SYSCTL_STR_MAXLENGTH
Definition: sysctl.h:33
char value[SYSCTL_STR_MAXLENGTH]
Definition: sysctl.h:37
#define SYSCTL_TYPE_INT
Definition: sysctl.h:17
#define SYSCTL_TYPE_BOOL
Definition: sysctl.h:18
#define SYSCTL_FLAG_RO
Definition: sysctl.h:20
#define SYSCTL_TYPE_STR
Definition: sysctl.h:16
bool value
Definition: sysctl.h:47
#define SYSCTL_LIST
Definition: sysctl.h:23
unsigned long uint64_t
Definition: types.h:13