Em qua., 29 de jan. de 2020 às 08:38, Daniel P. Berrangé <berrange@xxxxxxxxxx> escreveu: > > On Tue, Jan 28, 2020 at 10:54:08PM -0300, Julio Faracco wrote: > > Struct lxcNetworkParseData is being used as a single pointer which > > iterates through LXC config lines. It means that it will be applied as a > > network each time that a new type appears. After, the same struct is > > used to populate a new network interface. This commit changes this logic > > to multiple lxcNetworkParseData to move this strcuture to an array. It > > makes more sense if we are using indexes to fill interface settings. > > This is better to improve code clarity. > > > > This commit still introduces *Legacy() functions to keep support of > > network old style definitions. > > > > Signed-off-by: Julio Faracco <jcfaracco@xxxxxxxxx> > > --- > > src/lxc/lxc_native.c | 129 +++++++++++++++++++++++-------------------- > > 1 file changed, 68 insertions(+), 61 deletions(-) > > > > diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c > > index dd2345c324..b101848c09 100644 > > --- a/src/lxc/lxc_native.c > > +++ b/src/lxc/lxc_native.c > > > @@ -702,35 +703,41 @@ static int > > lxcConvertNetworkSettings(virDomainDefPtr def, virConfPtr properties) > > { > > int status; > > - size_t i; > > - lxcNetworkParseData data = {def, NULL, NULL, NULL, NULL, > > - NULL, NULL, NULL, NULL, 0, > > - NULL, NULL, true, 0}; > > + bool privnet = true; > > + size_t i, j; > > + lxcNetworkParseDataArray networks = {0, NULL}; > > + > > + networks.parseData = g_new0(lxcNetworkParseDataPtr, 1); > > > > - if (virConfWalk(properties, lxcNetworkWalkCallback, &data) < 0) > > + if (virConfWalk(properties, lxcNetworkWalkCallback, &networks) < 0) > > goto error; > > > > + for (i = 0; i < networks.ndata; i++) { > > + lxcNetworkParseDataPtr data = networks.parseData[i]; > > + data->def = def; > > > > - /* Add the last network definition found */ > > - status = lxcAddNetworkDefinition(&data); > > + status = lxcAddNetworkDefinition(data); > > > > - if (status < 0) > > - goto error; > > - else if (status > 0) > > - data.networks++; > > - else if (data.type != NULL && STREQ(data.type, "none")) > > - data.privnet = false; > > + if (status < 0) > > + goto error; > > + else if (data->type != NULL && STREQ(data->type, "none")) > > + privnet = false; > > + } > > > > - if (data.networks == 0 && data.privnet) { > > + if (networks.ndata == 0 && privnet) { > > /* When no network type is provided LXC only adds loopback */ > > def->features[VIR_DOMAIN_FEATURE_PRIVNET] = VIR_TRISTATE_SWITCH_ON; > > } > > return 0; > > > > error: > > - for (i = 0; i < data.nips; i++) > > - VIR_FREE(data.ips[i]); > > - VIR_FREE(data.ips); > > + for (i = 0; i < networks.ndata; i++) { > > + lxcNetworkParseDataPtr data = networks.parseData[i]; > > + for (j = 0; j < data->nips; j++) > > + VIR_FREE(data->ips[j]); > > + VIR_FREE(data->ips); > > + } > > + VIR_FREE(networks.parseData); > > return -1; > > } > > Unfortunately I noticed some memory leaks in this method reported by > valgrind > > Check it with this: > > ./run valgrind --leak-check=full --show-possibly-lost=no \ > ./tests/lxcconf2xmltest > > > Essentially we're not free'ing c in the success > code path, only the failure code path. The failure codepath also > fails to free the 'lxcNetworkParseDataPtr' instance. I think the main problem here with success code path is loosing IPs when we free networks.parseData. The failure code path is not relevant. We can free everything. > > Regards, > Daniel > -- > |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| > |: https://libvirt.org -o- https://fstop138.berrange.com :| > |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :| >