1 /* 2 * libqos driver framework 3 * 4 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License version 2.1 as published by the Free Software Foundation. 9 * 10 * This library is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public 16 * License along with this library; if not, see <http://www.gnu.org/licenses/> 17 */ 18 19 #ifndef QGRAPH_INTERNAL_H 20 #define QGRAPH_INTERNAL_H 21 22 /* This header is declaring additional helper functions defined in 23 * qgraph.c 24 * It should not be included in tests 25 */ 26 27 #include "qgraph.h" 28 29 typedef struct QOSGraphMachine QOSGraphMachine; 30 typedef enum QOSEdgeType QOSEdgeType; 31 typedef enum QOSNodeType QOSNodeType; 32 33 /* callback called when the walk path algorithm found a 34 * valid path 35 */ 36 typedef void (*QOSTestCallback) (QOSGraphNode *path, int len); 37 38 /* edge types*/ 39 enum QOSEdgeType { 40 QEDGE_CONTAINS, 41 QEDGE_PRODUCES, 42 QEDGE_CONSUMED_BY 43 }; 44 45 /* node types*/ 46 enum QOSNodeType { 47 QNODE_MACHINE, 48 QNODE_DRIVER, 49 QNODE_INTERFACE, 50 QNODE_TEST 51 }; 52 53 /* Graph Node */ 54 struct QOSGraphNode { 55 QOSNodeType type; 56 bool available; /* set by QEMU via QMP, used during graph walk */ 57 bool visited; /* used during graph walk */ 58 char *name; /* used to identify the node */ 59 char *qemu_name; /* optional: see qos_node_create_driver_named() */ 60 char *command_line; /* used to start QEMU at test execution */ 61 union { 62 struct { 63 QOSCreateDriverFunc constructor; 64 } driver; 65 struct { 66 QOSCreateMachineFunc constructor; 67 } machine; 68 struct { 69 QOSTestFunc function; 70 void *arg; 71 QOSBeforeTest before; 72 bool subprocess; 73 } test; 74 } u; 75 76 /** 77 * only used when traversing the path, never rely on that except in the 78 * qos_traverse_graph callback function 79 */ 80 QOSGraphEdge *path_edge; 81 }; 82 83 /** 84 * qos_graph_get_node(): returns the node mapped to that @key. 85 * It performs an hash map search O(1) 86 * 87 * Returns: on success: the %QOSGraphNode 88 * otherwise: #NULL 89 */ 90 QOSGraphNode *qos_graph_get_node(const char *key); 91 92 /** 93 * qos_graph_has_node(): returns #TRUE if the node 94 * has map has a node mapped to that @key. 95 */ 96 bool qos_graph_has_node(const char *node); 97 98 /** 99 * qos_graph_get_node_type(): returns the %QOSNodeType 100 * of the node @node. 101 * It performs an hash map search O(1) 102 * Returns: on success: the %QOSNodeType 103 * otherwise: #-1 104 */ 105 QOSNodeType qos_graph_get_node_type(const char *node); 106 107 /** 108 * qos_graph_get_node_availability(): returns the availability (boolean) 109 * of the node @node. 110 */ 111 bool qos_graph_get_node_availability(const char *node); 112 113 /** 114 * qos_graph_get_edge(): returns the edge 115 * linking of the node @node with @dest. 116 * 117 * Returns: on success: the %QOSGraphEdge 118 * otherwise: #NULL 119 */ 120 QOSGraphEdge *qos_graph_get_edge(const char *node, const char *dest); 121 122 /** 123 * qos_graph_edge_get_type(): returns the edge type 124 * of the edge @edge. 125 * 126 * Returns: on success: the %QOSEdgeType 127 * otherwise: #-1 128 */ 129 QOSEdgeType qos_graph_edge_get_type(QOSGraphEdge *edge); 130 131 /** 132 * qos_graph_edge_get_dest(): returns the name of the node 133 * pointed as destination of edge @edge. 134 * 135 * Returns: on success: the destination 136 * otherwise: #NULL 137 */ 138 char *qos_graph_edge_get_dest(QOSGraphEdge *edge); 139 140 /** 141 * qos_graph_has_edge(): returns #TRUE if there 142 * exists an edge from @start to @dest. 143 */ 144 bool qos_graph_has_edge(const char *start, const char *dest); 145 146 /** 147 * qos_graph_edge_get_arg(): returns the args assigned 148 * to that @edge. 149 * 150 * Returns: on success: the arg 151 * otherwise: #NULL 152 */ 153 void *qos_graph_edge_get_arg(QOSGraphEdge *edge); 154 155 /** 156 * qos_graph_edge_get_after_cmd_line(): returns the edge 157 * command line that will be added after all the node arguments 158 * and all the before_cmd_line arguments. 159 * 160 * Returns: on success: the char* arg 161 * otherwise: #NULL 162 */ 163 char *qos_graph_edge_get_after_cmd_line(QOSGraphEdge *edge); 164 165 /** 166 * qos_graph_edge_get_before_cmd_line(): returns the edge 167 * command line that will be added before the node command 168 * line argument. 169 * 170 * Returns: on success: the char* arg 171 * otherwise: #NULL 172 */ 173 char *qos_graph_edge_get_before_cmd_line(QOSGraphEdge *edge); 174 175 /** 176 * qos_graph_edge_get_extra_device_opts(): returns the arg 177 * command line that will be added to the node command 178 * line argument. 179 * 180 * Returns: on success: the char* arg 181 * otherwise: #NULL 182 */ 183 char *qos_graph_edge_get_extra_device_opts(QOSGraphEdge *edge); 184 185 /** 186 * qos_graph_edge_get_name(): returns the name 187 * assigned to the destination node (different only) 188 * if there are multiple devices with the same node name 189 * e.g. a node has two "generic-sdhci", "emmc" and "sdcard" 190 * there will be two edges with edge_name ="emmc" and "sdcard" 191 * 192 * Returns always the char* edge_name 193 */ 194 char *qos_graph_edge_get_name(QOSGraphEdge *edge); 195 196 /** 197 * qos_graph_get_machine(): returns the machine assigned 198 * to that @node name. 199 * 200 * It performs a search only trough the list of machines 201 * (i.e. the QOS_ROOT child). 202 * 203 * Returns: on success: the %QOSGraphNode 204 * otherwise: #NULL 205 */ 206 QOSGraphNode *qos_graph_get_machine(const char *node); 207 208 /** 209 * qos_graph_has_machine(): returns #TRUE if the node 210 * has map has a node mapped to that @node. 211 */ 212 bool qos_graph_has_machine(const char *node); 213 214 215 /** 216 * qos_print_graph(): walks the graph and prints 217 * all machine-to-test paths. 218 */ 219 void qos_print_graph(void); 220 221 /** 222 * qos_graph_foreach_test_path(): executes the Depth First search 223 * algorithm and applies @fn to all discovered paths. 224 * 225 * See qos_traverse_graph() in qgraph.c for more info on 226 * how it works. 227 */ 228 void qos_graph_foreach_test_path(QOSTestCallback fn); 229 230 /** 231 * qos_get_machine_type(): return QEMU machine type for a machine node. 232 * This function requires every machine @name to be in the form 233 * <arch>/<machine_name>, like "arm/raspi2b" or "x86_64/pc". 234 * 235 * The function will validate the format and return a pointer to 236 * @machine to <machine_name>. For example, when passed "x86_64/pc" 237 * it will return "pc". 238 * 239 * Note that this function *does not* allocate any new string. 240 */ 241 char *qos_get_machine_type(char *name); 242 243 /** 244 * qos_delete_cmd_line(): delete the 245 * command line present in node mapped with key @name. 246 * 247 * This function is called when the QMP query returns a node with 248 * { "abstract" : true } attribute. 249 */ 250 void qos_delete_cmd_line(const char *name); 251 252 /** 253 * qos_graph_node_set_availability(): sets the node identified 254 * by @node with availability @av. 255 */ 256 void qos_graph_node_set_availability(const char *node, bool av); 257 258 /* 259 * Prepends a '#' character in front for not breaking TAP output format. 260 */ 261 #define qos_printf(...) printf("# " __VA_ARGS__) 262 263 /* 264 * Intended for printing something literally, i.e. for appending text as is 265 * to a line already been started by qos_printf() before. 266 */ 267 #define qos_printf_literal printf 268 269 #endif 270