qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

qos_external.c (4355B)


      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 #include "qemu/osdep.h"
     20 #include <getopt.h>
     21 #include "../libqtest.h"
     22 #include "qapi/qmp/qdict.h"
     23 #include "qapi/qmp/qbool.h"
     24 #include "qapi/qmp/qstring.h"
     25 #include "qemu/module.h"
     26 #include "qapi/qmp/qlist.h"
     27 #include "libqos-malloc.h"
     28 #include "qgraph.h"
     29 #include "qgraph_internal.h"
     30 #include "qos_external.h"
     31 
     32 static void machine_apply_to_node(const char *name)
     33 {
     34     char *machine_name = g_strconcat(qtest_get_arch(), "/", name, NULL);
     35 
     36     qos_graph_node_set_availability(machine_name, true);
     37     g_free(machine_name);
     38 }
     39 
     40 void machines_apply_to_node(MachineInfoList *mach_info)
     41 {
     42     MachineInfoList *tail;
     43 
     44     for (tail = mach_info; tail; tail = tail->next) {
     45         machine_apply_to_node(tail->value->name);
     46         if (tail->value->alias) {
     47             machine_apply_to_node(tail->value->alias);
     48         }
     49     }
     50 }
     51 
     52 static void type_apply_to_node(const char *name, bool is_abstract)
     53 {
     54     qos_graph_node_set_availability(name, true);
     55     if (is_abstract) {
     56         qos_delete_cmd_line(name);
     57     }
     58 }
     59 
     60 void types_apply_to_node(ObjectTypeInfoList *type_info)
     61 {
     62     ObjectTypeInfoList *tail;
     63 
     64     for (tail = type_info; tail; tail = tail->next) {
     65         type_apply_to_node(tail->value->name, tail->value->abstract);
     66     }
     67 }
     68 
     69 static QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
     70 {
     71     return obj->get_driver(obj, "memory");
     72 }
     73 
     74 /**
     75  * allocate_objects(): given an array of nodes @arg,
     76  * walks the path invoking all constructors and
     77  * passing the corresponding parameter in order to
     78  * continue the objects allocation.
     79  * Once the test is reached, return the object it consumes.
     80  *
     81  * Since the machine and QEDGE_CONSUMED_BY nodes allocate
     82  * memory in the constructor, g_test_queue_destroy is used so
     83  * that after execution they can be safely free'd.  (The test's
     84  * ->before callback is also welcome to use g_test_queue_destroy).
     85  *
     86  * Note: as specified in walk_path() too, @arg is an array of
     87  * char *, where arg[0] is a pointer to the command line
     88  * string that will be used to properly start QEMU when executing
     89  * the test, and the remaining elements represent the actual objects
     90  * that will be allocated.
     91  */
     92 void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc)
     93 {
     94     int current = 0;
     95     QGuestAllocator *alloc;
     96     QOSGraphObject *parent = NULL;
     97     QOSGraphEdge *edge;
     98     QOSGraphNode *node;
     99     void *edge_arg;
    100     void *obj;
    101 
    102     node = qos_graph_get_node(path[current]);
    103     g_assert(node->type == QNODE_MACHINE);
    104 
    105     obj = qos_machine_new(node, qts);
    106     qos_object_queue_destroy(obj);
    107 
    108     alloc = get_machine_allocator(obj);
    109     if (p_alloc) {
    110         *p_alloc = alloc;
    111     }
    112 
    113     for (;;) {
    114         if (node->type != QNODE_INTERFACE) {
    115             qos_object_start_hw(obj);
    116             parent = obj;
    117         }
    118 
    119         /* follow edge and get object for next node constructor */
    120         current++;
    121         edge = qos_graph_get_edge(path[current - 1], path[current]);
    122         node = qos_graph_get_node(path[current]);
    123 
    124         if (node->type == QNODE_TEST) {
    125             g_assert(qos_graph_edge_get_type(edge) == QEDGE_CONSUMED_BY);
    126             return obj;
    127         }
    128 
    129         switch (qos_graph_edge_get_type(edge)) {
    130         case QEDGE_PRODUCES:
    131             obj = parent->get_driver(parent, path[current]);
    132             break;
    133 
    134         case QEDGE_CONSUMED_BY:
    135             edge_arg = qos_graph_edge_get_arg(edge);
    136             obj = qos_driver_new(node, obj, alloc, edge_arg);
    137             qos_object_queue_destroy(obj);
    138             break;
    139 
    140         case QEDGE_CONTAINS:
    141             obj = parent->get_device(parent, path[current]);
    142             break;
    143         }
    144     }
    145 }
    146