1 /* $NetBSD: k_helper.c,v 1.7 2020/02/22 19:54:35 pgoyette Exp $ */ 2 /* 3 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 16 * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 17 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 24 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: k_helper.c,v 1.7 2020/02/22 19:54:35 pgoyette Exp $"); 31 32 #include <sys/param.h> 33 #include <sys/kernel.h> 34 #include <sys/module.h> 35 #include <sys/sysctl.h> 36 #include <sys/evcnt.h> 37 38 #include <prop/proplib.h> 39 40 MODULE(MODULE_CLASS_MISC, k_helper, NULL); 41 42 /* --------------------------------------------------------------------- */ 43 /* Sysctl interface to query information about the module. */ 44 /* --------------------------------------------------------------------- */ 45 46 /* TODO: Change the integer variables below that represent booleans to 47 * bools, once sysctl(8) supports CTLTYPE_BOOL nodes. */ 48 49 static int present = 1; 50 static int prop_str_ok; 51 static char prop_str_val[128]; 52 static int prop_int_ok; 53 static int64_t prop_int_val; 54 static int prop_int_load; 55 56 static struct evcnt my_counter = 57 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL, "k_helper", "my_counter"); 58 59 EVCNT_ATTACH_STATIC(my_counter); 60 61 #define K_HELPER 0x12345678 62 #define K_HELPER_PRESENT 0 63 #define K_HELPER_PROP_STR_OK 1 64 #define K_HELPER_PROP_STR_VAL 2 65 #define K_HELPER_PROP_INT_OK 3 66 #define K_HELPER_PROP_INT_VAL 4 67 #define K_HELPER_PROP_INT_LOAD 5 68 69 SYSCTL_SETUP(sysctl_k_helper_setup, "sysctl k_helper subtree setup") 70 { 71 72 sysctl_createv(clog, 0, NULL, NULL, 73 CTLFLAG_PERMANENT, 74 CTLTYPE_NODE, "k_helper", NULL, 75 NULL, 0, NULL, 0, 76 CTL_VENDOR, K_HELPER, CTL_EOL); 77 78 sysctl_createv(clog, 0, NULL, NULL, 79 CTLFLAG_PERMANENT, 80 CTLTYPE_INT, "present", 81 SYSCTL_DESCR("Whether the module was loaded or not"), 82 NULL, 0, &present, 0, 83 CTL_VENDOR, K_HELPER, K_HELPER_PRESENT, CTL_EOL); 84 85 sysctl_createv(clog, 0, NULL, NULL, 86 CTLFLAG_PERMANENT, 87 CTLTYPE_INT, "prop_str_ok", 88 SYSCTL_DESCR("String property's validity"), 89 NULL, 0, &prop_str_ok, 0, 90 CTL_VENDOR, K_HELPER, K_HELPER_PROP_STR_OK, CTL_EOL); 91 92 sysctl_createv(clog, 0, NULL, NULL, 93 CTLFLAG_PERMANENT, 94 CTLTYPE_STRING, "prop_str_val", 95 SYSCTL_DESCR("String property's value"), 96 NULL, 0, prop_str_val, 0, 97 CTL_VENDOR, K_HELPER, K_HELPER_PROP_STR_VAL, CTL_EOL); 98 99 sysctl_createv(clog, 0, NULL, NULL, 100 CTLFLAG_PERMANENT, 101 CTLTYPE_INT, "prop_int_ok", 102 SYSCTL_DESCR("String property's validity"), 103 NULL, 0, &prop_int_ok, 0, 104 CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_OK, CTL_EOL); 105 106 sysctl_createv(clog, 0, NULL, NULL, 107 CTLFLAG_PERMANENT, 108 CTLTYPE_QUAD, "prop_int_val", 109 SYSCTL_DESCR("String property's value"), 110 NULL, 0, &prop_int_val, 0, 111 CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_VAL, CTL_EOL); 112 113 sysctl_createv(clog, 0, NULL, NULL, 114 CTLFLAG_PERMANENT, 115 CTLTYPE_INT, "prop_int_load", 116 SYSCTL_DESCR("Status of recursive modload"), 117 NULL, 0, &prop_int_load, 0, 118 CTL_VENDOR, K_HELPER, K_HELPER_PROP_INT_LOAD, CTL_EOL); 119 } 120 121 /* --------------------------------------------------------------------- */ 122 /* Module management. */ 123 /* --------------------------------------------------------------------- */ 124 125 static 126 int 127 k_helper_init(prop_dictionary_t props) 128 { 129 prop_object_t p; 130 131 p = prop_dictionary_get(props, "prop_str"); 132 if (p == NULL) 133 prop_str_ok = 0; 134 else if (prop_object_type(p) != PROP_TYPE_STRING) 135 prop_str_ok = 0; 136 else { 137 const char *msg = prop_string_cstring_nocopy(p); 138 if (msg == NULL) 139 prop_str_ok = 0; 140 else { 141 strlcpy(prop_str_val, msg, sizeof(prop_str_val)); 142 prop_str_ok = 1; 143 } 144 } 145 if (!prop_str_ok) 146 strlcpy(prop_str_val, "", sizeof(prop_str_val)); 147 148 p = prop_dictionary_get(props, "prop_int"); 149 if (p == NULL) 150 prop_int_ok = 0; 151 else if (prop_object_type(p) != PROP_TYPE_NUMBER) 152 prop_int_ok = 0; 153 else { 154 prop_int_val = prop_number_integer_value(p); 155 prop_int_ok = 1; 156 } 157 if (!prop_int_ok) 158 prop_int_val = -1; 159 160 p = prop_dictionary_get(props, "prop_recurse"); 161 if (p != NULL && prop_object_type(p) == PROP_TYPE_STRING) { 162 const char *recurse_name = prop_string_cstring_nocopy(p); 163 if (recurse_name != NULL) 164 prop_int_load = module_load(recurse_name, 165 MODCTL_NO_PROP, NULL, MODULE_CLASS_ANY); 166 else 167 prop_int_load = -1; 168 } else 169 prop_int_load = -2; 170 171 return 0; 172 } 173 174 static 175 int 176 k_helper_fini(void *arg) 177 { 178 179 return 0; 180 } 181 182 static 183 int 184 k_helper_modcmd(modcmd_t cmd, void *arg) 185 { 186 int ret; 187 188 switch (cmd) { 189 case MODULE_CMD_INIT: 190 ret = k_helper_init(arg); 191 break; 192 193 case MODULE_CMD_FINI: 194 ret = k_helper_fini(arg); 195 break; 196 197 case MODULE_CMD_STAT: 198 default: 199 ret = ENOTTY; 200 } 201 202 return ret; 203 } 204