1 /*
2 * libosinfo:
3 *
4 * Copyright (C) 2009-2020 Red Hat, Inc.
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 as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library. If not, see
18 * <http://www.gnu.org/licenses/>.
19 */
20
21 #include <osinfo/osinfo.h>
22 #include "osinfo/osinfo_product_private.h"
23 #include <glib/gi18n-lib.h>
24
25 /**
26 * SECTION:osinfo_platform
27 * @short_description: An virtualization platform
28 * @see_also: #OsinfoOs, #OsinfoPlatform
29 *
30 * #OsinfoPlatform is an entity representing an virtualization
31 * platform. Platforms have a list of supported devices
32 */
33
34 struct _OsinfoPlatformPrivate
35 {
36 // Value: List of device_link structs
37 GList *deviceLinks;
38 };
39
40 G_DEFINE_TYPE_WITH_PRIVATE(OsinfoPlatform, osinfo_platform, OSINFO_TYPE_PRODUCT);
41
42 struct _OsinfoPlatformDeviceLink {
43 OsinfoDevice *dev;
44 gchar *driver;
45 };
46
47 static void
osinfo_platform_finalize(GObject * object)48 osinfo_platform_finalize(GObject *object)
49 {
50 OsinfoPlatform *platform = OSINFO_PLATFORM(object);
51
52 g_list_free_full(platform->priv->deviceLinks, g_object_unref);
53
54 /* Chain up to the parent class */
55 G_OBJECT_CLASS(osinfo_platform_parent_class)->finalize(object);
56 }
57
58 /* Init functions */
59 static void
osinfo_platform_class_init(OsinfoPlatformClass * klass)60 osinfo_platform_class_init(OsinfoPlatformClass *klass)
61 {
62 GObjectClass *g_klass = G_OBJECT_CLASS(klass);
63
64 g_klass->finalize = osinfo_platform_finalize;
65 }
66
67 static void
osinfo_platform_init(OsinfoPlatform * platform)68 osinfo_platform_init(OsinfoPlatform *platform)
69 {
70 platform->priv = osinfo_platform_get_instance_private(platform);
71 platform->priv->deviceLinks = NULL;
72 }
73
74
75 /**
76 * osinfo_platform_new:
77 * @id: a unique identifier
78 *
79 * Create a new platform entity
80 *
81 * Returns: (transfer full): A platform entity
82 */
osinfo_platform_new(const gchar * id)83 OsinfoPlatform *osinfo_platform_new(const gchar *id)
84 {
85 return g_object_new(OSINFO_TYPE_PLATFORM,
86 "id", id,
87 NULL);
88 }
89
90 struct GetAllDevicesData {
91 OsinfoFilter *filter;
92 OsinfoDeviceList *devices;
93 };
94
get_all_devices_cb(OsinfoProduct * product,gpointer user_data)95 static void get_all_devices_cb(OsinfoProduct *product, gpointer user_data)
96 {
97 OsinfoDeviceList *devices;
98 OsinfoList *tmp_list;
99 struct GetAllDevicesData *foreach_data = (struct GetAllDevicesData *)user_data;
100
101 g_return_if_fail(OSINFO_IS_PLATFORM(product));
102
103 devices = osinfo_platform_get_devices(OSINFO_PLATFORM(product),
104 foreach_data->filter);
105 tmp_list = osinfo_list_new_union(OSINFO_LIST(foreach_data->devices),
106 OSINFO_LIST(devices));
107 g_object_unref(foreach_data->devices);
108 g_object_unref(devices);
109 foreach_data->devices = OSINFO_DEVICELIST(tmp_list);
110 }
111
112
113 /**
114 * osinfo_platform_get_all_devices:
115 * @platform: a platform
116 * @filter: (allow-none)(transfer none): an optional device property filter
117 *
118 * Get all platforms matching a given filter but unlike
119 * osinfo_platform_get_devices this function also retrieves devices from
120 * all derived and upgraded platforms.
121 *
122 * Returns: (transfer full): A list of devices
123 *
124 * Since: 0.2.7
125 */
osinfo_platform_get_all_devices(OsinfoPlatform * platform,OsinfoFilter * filter)126 OsinfoDeviceList *osinfo_platform_get_all_devices(OsinfoPlatform *platform,
127 OsinfoFilter *filter)
128 {
129 struct GetAllDevicesData foreach_data = {
130 .filter = filter,
131 .devices = osinfo_devicelist_new()
132 };
133
134 osinfo_product_foreach_related(OSINFO_PRODUCT(platform),
135 OSINFO_PRODUCT_FOREACH_FLAG_UPGRADES |
136 OSINFO_PRODUCT_FOREACH_FLAG_DERIVES_FROM,
137 get_all_devices_cb,
138 &foreach_data);
139
140 return foreach_data.devices;
141 }
142
143 /**
144 * osinfo_platform_get_devices:
145 * @platform: a platform entity
146 * @filter: (transfer none)(allow-none): an optional filter
147 *
148 * Retrieve all the associated devices matching the filter.
149 * The filter matches against the device, not the link.
150 *
151 * Returns: (transfer full): a list of #OsinfoDevice entities
152 */
osinfo_platform_get_devices(OsinfoPlatform * platform,OsinfoFilter * filter)153 OsinfoDeviceList *osinfo_platform_get_devices(OsinfoPlatform *platform, OsinfoFilter *filter)
154 {
155 OsinfoDeviceList *newList;
156 GList *tmp;
157
158 g_return_val_if_fail(OSINFO_IS_PLATFORM(platform), NULL);
159 g_return_val_if_fail(!filter || OSINFO_IS_FILTER(filter), NULL);
160
161 newList = osinfo_devicelist_new();
162 tmp = platform->priv->deviceLinks;
163
164 while (tmp) {
165 OsinfoDeviceLink *devlink = OSINFO_DEVICELINK(tmp->data);
166 OsinfoDevice *dev = osinfo_devicelink_get_target(devlink);
167 if (!filter || osinfo_filter_matches(filter, OSINFO_ENTITY(dev)))
168 osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(dev));
169
170 tmp = tmp->next;
171 }
172
173 return newList;
174 }
175
176
177 /**
178 * osinfo_platform_get_device_links:
179 * @platform: a platform entity
180 * @filter: (transfer none)(allow-none): an optional filter
181 *
182 * Retrieve all the associated devices matching the filter.
183 * The filter matches against the link, not the device.
184 *
185 * Returns: (transfer full): a list of #OsinfoDevice entities
186 */
osinfo_platform_get_device_links(OsinfoPlatform * platform,OsinfoFilter * filter)187 OsinfoDeviceLinkList *osinfo_platform_get_device_links(OsinfoPlatform *platform, OsinfoFilter *filter)
188 {
189 OsinfoDeviceLinkList *newList;
190 GList *tmp;
191
192 g_return_val_if_fail(OSINFO_IS_PLATFORM(platform), NULL);
193 g_return_val_if_fail(!filter || OSINFO_IS_FILTER(filter), NULL);
194
195 newList = osinfo_devicelinklist_new();
196 tmp = platform->priv->deviceLinks;
197
198 while (tmp) {
199 OsinfoDeviceLink *devlink = OSINFO_DEVICELINK(tmp->data);
200
201 if (!filter || osinfo_filter_matches(filter, OSINFO_ENTITY(devlink)))
202 osinfo_list_add(OSINFO_LIST(newList), OSINFO_ENTITY(devlink));
203
204 tmp = tmp->next;
205 }
206
207 return newList;
208 }
209
210
211 /**
212 * osinfo_platform_add_device:
213 * @platform: a platform entity
214 * @dev: (transfer none): the device to associate
215 *
216 * Associate a device with a platform. The returned #OsinfoDeviceLink
217 * can be used to record extra metadata against the link
218 *
219 * Returns: (transfer none): the device association
220 */
osinfo_platform_add_device(OsinfoPlatform * platform,OsinfoDevice * dev)221 OsinfoDeviceLink *osinfo_platform_add_device(OsinfoPlatform *platform, OsinfoDevice *dev)
222 {
223 OsinfoDeviceLink *devlink;
224
225 g_return_val_if_fail(OSINFO_IS_PLATFORM(platform), NULL);
226 g_return_val_if_fail(OSINFO_IS_DEVICE(dev), NULL);
227
228 devlink = osinfo_devicelink_new(dev);
229
230 platform->priv->deviceLinks = g_list_prepend(platform->priv->deviceLinks,
231 devlink);
232
233 return devlink;
234 }
235