discover/sysinfo: Add system_info_reinit()
[petitboot] / discover / sysinfo.c
1
2 #include <string.h>
3
4 #include <talloc/talloc.h>
5 #include <process/process.h>
6 #include <log/log.h>
7
8 #include "discover-server.h"
9 #include "platform.h"
10 #include "sysinfo.h"
11
12 static struct system_info *sysinfo;
13 static struct discover_server *server;
14
15 const struct system_info *system_info_get(void)
16 {
17         return sysinfo;
18 }
19
20
21 void system_info_set_interface_address(unsigned int hwaddr_size,
22                 uint8_t *hwaddr, const char *address)
23 {
24         struct interface_info *if_info;
25         unsigned int i;
26         char mac[20];
27
28         for (i = 0; i < sysinfo->n_interfaces; i++) {
29                 if_info = sysinfo->interfaces[i];
30
31                 if (if_info->hwaddr_size != hwaddr_size)
32                         continue;
33
34                 if (memcmp(if_info->hwaddr, hwaddr, hwaddr_size))
35                         continue;
36
37                 /* Found an existing interface. Notify clients if a new address
38                  * is set */
39                 if (!if_info->address || strcmp(if_info->address, address)) {
40                         talloc_free(if_info->address);
41                         if_info->address = talloc_strdup(if_info, address);
42                         discover_server_notify_system_info(server, sysinfo);
43                         return;
44                 }
45         }
46
47         mac_str(hwaddr, hwaddr_size, mac, sizeof(mac));
48         pb_log("Couldn't find interface matching %s\n", mac);
49 }
50
51 void system_info_register_interface(unsigned int hwaddr_size, uint8_t *hwaddr,
52                 const char *name, bool link)
53 {
54         struct interface_info *if_info;
55         unsigned int i;
56
57         for (i = 0; i < sysinfo->n_interfaces; i++) {
58                 bool changed = false;
59
60                 if_info = sysinfo->interfaces[i];
61
62                 if (if_info->hwaddr_size != hwaddr_size)
63                         continue;
64
65                 if (memcmp(if_info->hwaddr, hwaddr, hwaddr_size))
66                         continue;
67
68                 /* Found an existing interface. Notify clients on any name or
69                  * link changes */
70                 if (strcmp(if_info->name, name)) {
71                         talloc_free(if_info->name);
72                         if_info->name = talloc_strdup(if_info, name);
73                         changed = true;
74                 }
75
76                 if (if_info->link != link) {
77                         if_info->link = link;
78                         changed = true;
79                 }
80
81                 if (changed)
82                         discover_server_notify_system_info(server, sysinfo);
83
84                 return;
85         }
86
87         if_info = talloc_zero(sysinfo, struct interface_info);
88         if_info->hwaddr_size = hwaddr_size;
89         if_info->hwaddr = talloc_memdup(if_info, hwaddr, hwaddr_size);
90         if_info->name = talloc_strdup(if_info, name);
91         if_info->link = link;
92
93         sysinfo->n_interfaces++;
94         sysinfo->interfaces = talloc_realloc(sysinfo, sysinfo->interfaces,
95                                                 struct interface_info *,
96                                                 sysinfo->n_interfaces);
97         sysinfo->interfaces[sysinfo->n_interfaces - 1] = if_info;
98
99         discover_server_notify_system_info(server, sysinfo);
100 }
101
102 void system_info_register_blockdev(const char *name, const char *uuid,
103                 const char *mountpoint)
104 {
105         struct blockdev_info *bd_info;
106         unsigned int i;
107
108         for (i = 0; i < sysinfo->n_blockdevs; i++) {
109                 bd_info = sysinfo->blockdevs[i];
110
111                 if (strcmp(bd_info->name, name))
112                         continue;
113
114                 /* update the mountpoint and UUID, and we're done */
115                 talloc_free(bd_info->mountpoint);
116                 bd_info->uuid = talloc_strdup(bd_info, uuid);
117                 bd_info->mountpoint = talloc_strdup(bd_info, mountpoint);
118                 discover_server_notify_system_info(server, sysinfo);
119                 return;
120         }
121
122         bd_info = talloc_zero(sysinfo, struct blockdev_info);
123         bd_info->name = talloc_strdup(bd_info, name);
124         bd_info->uuid = talloc_strdup(bd_info, uuid);
125         bd_info->mountpoint = talloc_strdup(bd_info, mountpoint);
126
127         sysinfo->n_blockdevs++;
128         sysinfo->blockdevs = talloc_realloc(sysinfo, sysinfo->blockdevs,
129                                                 struct blockdev_info *,
130                                                 sysinfo->n_blockdevs);
131         sysinfo->blockdevs[sysinfo->n_blockdevs - 1] = bd_info;
132
133         discover_server_notify_system_info(server, sysinfo);
134 }
135
136 void system_info_init(struct discover_server *s)
137 {
138         server = s;
139         sysinfo = talloc_zero(server, struct system_info);
140         platform_get_sysinfo(sysinfo);
141 }
142
143 /* Only reset device information. Platform information is static */
144 void system_info_reinit(void)
145 {
146         unsigned int i;
147
148         for (i = 0; i < sysinfo->n_blockdevs; i++)
149                 talloc_free(sysinfo->blockdevs[i]);
150         talloc_free(sysinfo->blockdevs);
151         sysinfo->blockdevs = NULL;
152         sysinfo->n_blockdevs = 0;
153
154         for (i = 0; i < sysinfo->n_interfaces; i++)
155                 talloc_free(sysinfo->interfaces[i]);
156         talloc_free(sysinfo->interfaces);
157         sysinfo->interfaces = NULL;
158         sysinfo->n_interfaces = 0;
159 }