For example, entering “sudo sysctl -a | grep ‘^dev'” gives me the following list:
dev.cdrom.autoclose = 1
dev.cdrom.autoeject = 0
dev.cdrom.check_media = 0
dev.cdrom.debug = 0dev.cdrom.info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
dev.cdrom.info =
dev.cdrom.info = drive name:
dev.cdrom.info = drive speed:
dev.cdrom.info = drive # of slots:
dev.cdrom.info = Can close tray:
dev.cdrom.lock = 0
dev.hpet.max-user-freq = 64
dev.mac_hid.mouse_button2_keycode = 97
dev.mac_hid.mouse_button3_keycode = 100
dev.mac_hid.mouse_button_emulation = 0
dev.parport.default.spintime = 500
dev.parport.default.timeslice = 200
dev.raid.speed_limit_max = 200000
dev.raid.speed_limit_min = 1000
dev.scsi.logging_level = 0
As you can see, under the “dev” branch are many different children. How is it done?
For example, under “dev” is “scsi”, which is achieved via register_sysctl_table(), and in this linux kernel file:
./scsi/scsi_sysctl.c:
scsi_table_header = register_sysctl_table(scsi_root_table);
static struct ctl_table scsi_root_table[] = {
{ .procname = “dev”,
.mode = 0555,
.child = scsi_dir_table },
{ }
};static struct ctl_table_header *scsi_table_header;
int __init scsi_init_sysctl(void)
{
scsi_table_header = register_sysctl_table(scsi_root_table);
if (!scsi_table_header)
return -ENOMEM;
return 0;
}
And under scsi_root_table:
static struct ctl_table scsi_root_table[] = {
{ .procname = “dev”,
.mode = 0555,
.child = scsi_dir_table },
{ }
};
And under scsi_dir_table:
static struct ctl_table scsi_dir_table[] = {
{ .procname = “scsi”,
.mode = 0555,
.child = scsi_table },
{ }
};
And under scsi_table:
static struct ctl_table scsi_table[] = {
{ .procname = “logging_level”,
.data = &scsi_logging_level,
.maxlen = sizeof(scsi_logging_level),
.mode = 0644,
.proc_handler = proc_dointvec },
{ }
};
So the multilevel tables is to implement:
dev.scsi.logging_level = 0
And similarly:
./cdrom/cdrom.c:
cdrom_sysctl_header = register_sysctl_table(cdrom_root_table);
So traversing from cdrom_root_table, all the way to “cdrom_table”:
static struct ctl_table cdrom_root_table[] = {
{
.procname = “dev”,
.maxlen = 0,
.mode = 0555,
.child = cdrom_cdrom_table,
},
{ }
};static struct ctl_table cdrom_table[] = {
{
.procname = “info”,
.data = &cdrom_sysctl_settings.info,
.maxlen = CDROM_STR_SIZE,
.mode = 0444,
.proc_handler = cdrom_sysctl_info,
},
{
.procname = “autoclose”,
.data = &cdrom_sysctl_settings.autoclose,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = cdrom_sysctl_handler,
},
And noticed the function cdrom_sysctl_info() above:
It is where all the information below is printed:
dev.cdrom.info = CD-ROM information, Id: cdrom.c 3.20 2003/12/17
dev.cdrom.info =
dev.cdrom.info = drive name:
dev.cdrom.info = drive speed:
dev.cdrom.info = drive # of slots:
dev.cdrom.info = Can close tray:
<…>
And the function snippets is here:
pos = sprintf(info, “CD-ROM information, ” VERSION “\n”);
if (cdrom_print_info(“\ndrive name:\t”, 0, info, &pos, CTL_NAME))
goto done;
if (cdrom_print_info(“\ndrive speed:\t”, 0, info, &pos, CTL_SPEED))
goto done;
if (cdrom_print_info(“\ndrive # of slots:”, 0, info, &pos, CTL_SLOTS))
goto done;
if (cdrom_print_info(“\nCan close tray:\t”,
CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY
And so that’s how multiple entries under the same root “dev” can be achieved.
This is also answering the question posted here:
http://stackoverflow.com/questions/20164041/dynamically-adding-entries-to-sysctl