]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkctl: create the sd_device structure just once
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 23 Oct 2019 15:02:18 +0000 (17:02 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Wed, 23 Oct 2019 22:02:43 +0000 (00:02 +0200)
This is mostly in preparation for future changes: a proper freeing function
is now called on the LinkInfo items.

src/network/networkctl.c

index df09f75c56936ff100143370eeecda2b3c7d5ec2..d64530089999969f6d79e7faa51b7e780ca64756 100644 (file)
@@ -125,6 +125,7 @@ typedef struct VxLanInfo {
 typedef struct LinkInfo {
         char name[IFNAMSIZ+1];
         char netdev_kind[NETDEV_KIND_MAX];
+        sd_device *sd_device;
         int ifindex;
         unsigned short iftype;
         struct ether_addr mac_address;
@@ -167,12 +168,23 @@ typedef struct LinkInfo {
         bool has_stats:1;
         bool has_bitrates:1;
         bool has_ethtool_link_info:1;
+
+        bool needs_freeing:1;
 } LinkInfo;
 
 static int link_info_compare(const LinkInfo *a, const LinkInfo *b) {
         return CMP(a->ifindex, b->ifindex);
 }
 
+static const LinkInfo* link_info_array_free(LinkInfo *array) {
+        for (unsigned i = 0; array && array[i].needs_freeing; i++) {
+                sd_device_unref(array[i].sd_device);
+        }
+
+        return mfree(array);
+}
+DEFINE_TRIVIAL_CLEANUP_FUNC(LinkInfo*, link_info_array_free);
+
 static int decode_netdev(sd_netlink_message *m, LinkInfo *info) {
         const char *received_kind;
         int r;
@@ -360,7 +372,7 @@ static void acquire_ether_link_info(int *fd, LinkInfo *link) {
 
 static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, LinkInfo **ret) {
         _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL, *reply = NULL;
-        _cleanup_free_ LinkInfo *links = NULL;
+        _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
         _cleanup_close_ int fd = -1;
         size_t allocated = 0, c = 0, j;
         sd_netlink_message *i;
@@ -382,7 +394,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
                 return log_error_errno(r, "Failed to enumerate links: %m");
 
         for (i = reply; i; i = sd_netlink_message_next(i)) {
-                if (!GREEDY_REALLOC0(links, allocated, c+1))
+                if (!GREEDY_REALLOC0(links, allocated, c + 2)) /* We keep one trailing one as marker */
                         return -ENOMEM;
 
                 r = decode_link(i, links + c, patterns);
@@ -391,6 +403,12 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
                 if (r == 0)
                         continue;
 
+                links[c].needs_freeing = true;
+
+                char devid[2 + DECIMAL_STR_MAX(int)];
+                xsprintf(devid, "n%i", links[c].ifindex);
+                (void) sd_device_new_from_device_id(&links[c].sd_device, devid);
+
                 acquire_ether_link_info(&fd, &links[c]);
 
                 c++;
@@ -409,7 +427,7 @@ static int acquire_link_info(sd_bus *bus, sd_netlink *rtnl, char **patterns, Lin
 
 static int list_links(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
-        _cleanup_free_ LinkInfo *links = NULL;
+        _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
         _cleanup_(table_unrefp) Table *table = NULL;
         TableCell *cell;
         int c, i, r;
@@ -441,10 +459,8 @@ static int list_links(int argc, char *argv[], void *userdata) {
 
         for (i = 0; i < c; i++) {
                 _cleanup_free_ char *setup_state = NULL, *operational_state = NULL;
-                _cleanup_(sd_device_unrefp) sd_device *d = NULL;
                 const char *on_color_operational, *off_color_operational,
                            *on_color_setup, *off_color_setup;
-                char devid[2 + DECIMAL_STR_MAX(int)];
                 _cleanup_free_ char *t = NULL;
 
                 (void) sd_network_link_get_operational_state(links[i].ifindex, &operational_state);
@@ -455,10 +471,7 @@ static int list_links(int argc, char *argv[], void *userdata) {
                         setup_state = strdup("unmanaged");
                 setup_state_to_color(setup_state, &on_color_setup, &off_color_setup);
 
-                xsprintf(devid, "n%i", links[i].ifindex);
-                (void) sd_device_new_from_device_id(&d, devid);
-
-                t = link_get_type_string(links[i].iftype, d);
+                t = link_get_type_string(links[i].iftype, links[i].sd_device);
 
                 r = table_add_many(table,
                                    TABLE_INT, links[i].ifindex,
@@ -1004,8 +1017,6 @@ static int link_status_one(
 
         _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **search_domains = NULL, **route_domains = NULL;
         _cleanup_free_ char *setup_state = NULL, *operational_state = NULL, *tz = NULL;
-        _cleanup_(sd_device_unrefp) sd_device *d = NULL;
-        char devid[2 + DECIMAL_STR_MAX(int)];
         _cleanup_free_ char *t = NULL, *network = NULL;
         const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL;
         const char *on_color_operational, *off_color_operational,
@@ -1031,23 +1042,19 @@ static int link_status_one(
         (void) sd_network_link_get_route_domains(info->ifindex, &route_domains);
         (void) sd_network_link_get_ntp(info->ifindex, &ntp);
 
-        xsprintf(devid, "n%i", info->ifindex);
-
-        (void) sd_device_new_from_device_id(&d, devid);
-
-        if (d) {
-                (void) sd_device_get_property_value(d, "ID_NET_LINK_FILE", &link);
-                (void) sd_device_get_property_value(d, "ID_NET_DRIVER", &driver);
-                (void) sd_device_get_property_value(d, "ID_PATH", &path);
+        if (info->sd_device) {
+                (void) sd_device_get_property_value(info->sd_device, "ID_NET_LINK_FILE", &link);
+                (void) sd_device_get_property_value(info->sd_device, "ID_NET_DRIVER", &driver);
+                (void) sd_device_get_property_value(info->sd_device, "ID_PATH", &path);
 
-                if (sd_device_get_property_value(d, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
-                        (void) sd_device_get_property_value(d, "ID_VENDOR", &vendor);
+                if (sd_device_get_property_value(info->sd_device, "ID_VENDOR_FROM_DATABASE", &vendor) < 0)
+                        (void) sd_device_get_property_value(info->sd_device, "ID_VENDOR", &vendor);
 
-                if (sd_device_get_property_value(d, "ID_MODEL_FROM_DATABASE", &model) < 0)
-                        (void) sd_device_get_property_value(d, "ID_MODEL", &model);
+                if (sd_device_get_property_value(info->sd_device, "ID_MODEL_FROM_DATABASE", &model) < 0)
+                        (void) sd_device_get_property_value(info->sd_device, "ID_MODEL", &model);
         }
 
-        t = link_get_type_string(info->iftype, d);
+        t = link_get_type_string(info->iftype, info->sd_device);
 
         (void) sd_network_link_get_network_file(info->ifindex, &network);
 
@@ -1430,7 +1437,7 @@ static int link_status(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
         _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
-        _cleanup_free_ LinkInfo *links = NULL;
+        _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
         int r, c, i;
 
         (void) pager_open(arg_pager_flags);
@@ -1518,7 +1525,7 @@ static void lldp_capabilities_legend(uint16_t x) {
 
 static int link_lldp_status(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
-        _cleanup_free_ LinkInfo *links = NULL;
+        _cleanup_(link_info_array_freep) LinkInfo *links = NULL;
         _cleanup_(table_unrefp) Table *table = NULL;
         int i, r, c, m = 0;
         uint16_t all = 0;