Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F137917874
D12545.id33567.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D12545.id33567.diff
View Options
Index: sys/kern/kern_linker.c
===================================================================
--- sys/kern/kern_linker.c
+++ sys/kern/kern_linker.c
@@ -288,7 +288,7 @@
}
static void
-linker_file_register_sysctls(linker_file_t lf)
+linker_file_register_sysctls(linker_file_t lf, bool enable)
{
struct sysctl_oid **start, **stop, **oidp;
@@ -303,8 +303,34 @@
sx_xunlock(&kld_sx);
sysctl_wlock();
+ for (oidp = start; oidp < stop; oidp++) {
+ if (enable)
+ sysctl_register_oid(*oidp);
+ else
+ sysctl_register_disabled_oid(*oidp);
+ }
+ sysctl_wunlock();
+ sx_xlock(&kld_sx);
+}
+
+static void
+linker_file_enable_sysctls(linker_file_t lf)
+{
+ struct sysctl_oid **start, **stop, **oidp;
+
+ KLD_DPF(FILE,
+ ("linker_file_enable_sysctls: enable SYSCTLs for %s\n",
+ lf->filename));
+
+ sx_assert(&kld_sx, SA_XLOCKED);
+
+ if (linker_file_lookup_set(lf, "sysctl_set", &start, &stop, NULL) != 0)
+ return;
+
+ sx_xunlock(&kld_sx);
+ sysctl_wlock();
for (oidp = start; oidp < stop; oidp++)
- sysctl_register_oid(*oidp);
+ sysctl_enable_oid(*oidp);
sysctl_wunlock();
sx_xlock(&kld_sx);
}
@@ -430,8 +456,9 @@
return (error);
}
modules = !TAILQ_EMPTY(&lf->modules);
- linker_file_register_sysctls(lf);
+ linker_file_register_sysctls(lf, false);
linker_file_sysinit(lf);
+ linker_file_enable_sysctls(lf);
lf->flags |= LINKER_FILE_LINKED;
/*
@@ -692,8 +719,8 @@
*/
if (file->flags & LINKER_FILE_LINKED) {
file->flags &= ~LINKER_FILE_LINKED;
- linker_file_sysuninit(file);
linker_file_unregister_sysctls(file);
+ linker_file_sysuninit(file);
}
TAILQ_REMOVE(&linker_files, file, link);
@@ -1642,7 +1669,7 @@
if (linker_file_lookup_set(lf, "sysinit_set", &si_start,
&si_stop, NULL) == 0)
sysinit_add(si_start, si_stop);
- linker_file_register_sysctls(lf);
+ linker_file_register_sysctls(lf, true);
lf->flags |= LINKER_FILE_LINKED;
continue;
fail:
Index: sys/kern/kern_sysctl.c
===================================================================
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -408,8 +408,8 @@
0, 0, sysctl_reuse_test, "-", "");
#endif
-void
-sysctl_register_oid(struct sysctl_oid *oidp)
+static void
+sysctl_register_oid_impl(struct sysctl_oid *oidp, bool enable)
{
struct sysctl_oid_list *parent = oidp->oid_parent;
struct sysctl_oid *p;
@@ -491,6 +491,17 @@
}
/* update the OID number, if any */
oidp->oid_number = oid_number;
+
+ /*
+ * Mark the leaf as dormant if it's not to be immediately enabled.
+ * We do not disable nodes as they can be shared between modules
+ * and it is always safe to access a node.
+ */
+ if (!enable && (oidp->oid_kind & CTLTYPE) != CTLTYPE_NODE) {
+ KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
+ ("internal flag is set in oid_kind"));
+ oidp->oid_kind |= CTLFLAG_DORMANT;
+ }
if (q != NULL)
SLIST_INSERT_AFTER(q, oidp, oid_link);
else
@@ -510,6 +521,35 @@
}
void
+sysctl_register_oid(struct sysctl_oid *oidp)
+{
+
+ sysctl_register_oid_impl(oidp, true);
+}
+
+void
+sysctl_register_disabled_oid(struct sysctl_oid *oidp)
+{
+
+ sysctl_register_oid_impl(oidp, false);
+}
+
+void
+sysctl_enable_oid(struct sysctl_oid *oidp)
+{
+
+ SYSCTL_ASSERT_WLOCKED();
+ if ((oidp->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
+ KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) == 0,
+ ("sysctl node is marked as dormant"));
+ return;
+ }
+ KASSERT((oidp->oid_kind & CTLFLAG_DORMANT) != 0,
+ ("enabling already enabled sysctl oid"));
+ oidp->oid_kind &= ~CTLFLAG_DORMANT;
+}
+
+void
sysctl_unregister_oid(struct sysctl_oid *oidp)
{
struct sysctl_oid *p;
@@ -1057,7 +1097,7 @@
*next = oidp->oid_number;
*oidpp = oidp;
- if (oidp->oid_kind & CTLFLAG_SKIP)
+ if ((oidp->oid_kind & (CTLFLAG_SKIP | CTLFLAG_DORMANT)) != 0)
continue;
if (!namelen) {
@@ -1878,6 +1918,8 @@
}
lsp = SYSCTL_CHILDREN(oid);
} else if (indx == namelen) {
+ if ((oid->oid_kind & CTLFLAG_DORMANT) != 0)
+ return (ENOENT);
*noid = oid;
if (nindx != NULL)
*nindx = indx;
Index: sys/sys/sysctl.h
===================================================================
--- sys/sys/sysctl.h
+++ sys/sys/sysctl.h
@@ -83,6 +83,7 @@
#define CTLFLAG_RD 0x80000000 /* Allow reads of variable */
#define CTLFLAG_WR 0x40000000 /* Allow writes to the variable */
#define CTLFLAG_RW (CTLFLAG_RD|CTLFLAG_WR)
+#define CTLFLAG_DORMANT 0x20000000 /* This sysctl is not active yet */
#define CTLFLAG_ANYBODY 0x10000000 /* All users can set this var */
#define CTLFLAG_SECURE 0x08000000 /* Permit set only if securelevel<=0 */
#define CTLFLAG_PRISON 0x04000000 /* Prisoned roots can fiddle */
@@ -219,6 +220,8 @@
* These functions are used to add/remove an oid from the mib.
*/
void sysctl_register_oid(struct sysctl_oid *oidp);
+void sysctl_register_disabled_oid(struct sysctl_oid *oidp);
+void sysctl_enable_oid(struct sysctl_oid *oidp);
void sysctl_unregister_oid(struct sysctl_oid *oidp);
/* Declare a static oid to allow child oids to be added to it. */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Nov 28, 5:37 AM (8 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26275507
Default Alt Text
D12545.id33567.diff (4 KB)
Attached To
Mode
D12545: sysctl-s in a module should be accessible only when the module is initialized
Attached
Detach File
Event Timeline
Log In to Comment