Skip to content

Commit 9e11413

Browse files
committed
retry instead of sleep; gc cleanup
1 parent 8ebc828 commit 9e11413

File tree

2 files changed

+88
-27
lines changed

2 files changed

+88
-27
lines changed

pkg/drivers/kvm/kvm.go

+13
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,8 @@ func (d *Driver) PreCommandCheck() error {
110110
if err != nil {
111111
return errors.Wrap(err, "error connecting to libvirt socket. Have you added yourself to the libvirtd group?")
112112
}
113+
defer conn.Close()
114+
113115
libVersion, err := conn.GetLibVersion()
114116
if err != nil {
115117
return errors.Wrap(err, "getting libvirt version")
@@ -482,3 +484,14 @@ func (d *Driver) undefineDomain(conn *libvirt.Connect, dom *libvirt.Domain) erro
482484

483485
return dom.Undefine()
484486
}
487+
488+
// lvErr will return libvirt Error struct containing specific libvirt error code, domain, message and level
489+
func lvErr(err error) libvirt.Error {
490+
if err != nil {
491+
if lverr, ok := err.(libvirt.Error); ok {
492+
return lverr
493+
}
494+
return libvirt.Error{Code: libvirt.ERR_INTERNAL_ERROR, Message: "internal error"}
495+
}
496+
return libvirt.Error{Code: libvirt.ERR_OK, Message: ""}
497+
}

pkg/drivers/kvm/network.go

+75-27
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/docker/machine/libmachine/log"
3232
libvirt "github.com/libvirt/libvirt-go"
3333
"github.com/pkg/errors"
34+
"k8s.io/minikube/pkg/util/retry"
3435
)
3536

3637
// Replace with hardcoded range with CIDR
@@ -47,16 +48,14 @@ const networkTmpl = `
4748
</network>
4849
`
4950

50-
// waiting time for libvirt ops to settle
51-
const nap = 100 * time.Microsecond
52-
5351
// setupNetwork ensures that the network with `name` is started (active)
5452
// and has the autostart feature set.
5553
func setupNetwork(conn *libvirt.Connect, name string) error {
5654
n, err := conn.LookupNetworkByName(name)
5755
if err != nil {
5856
return errors.Wrapf(err, "checking network %s", name)
5957
}
58+
defer func() { _ = n.Free() }()
6059

6160
// always ensure autostart is set on the network
6261
autostart, err := n.GetAutostart()
@@ -79,7 +78,6 @@ func setupNetwork(conn *libvirt.Connect, name string) error {
7978
return errors.Wrapf(err, "starting network %s", name)
8079
}
8180
}
82-
8381
return nil
8482
}
8583

@@ -110,17 +108,14 @@ func (d *Driver) ensureNetwork() error {
110108
return errors.Wrapf(err, "deleting inoperable network %s", d.PrivateNetwork)
111109
}
112110
log.Debugf("Successfully deleted %s network", d.PrivateNetwork)
113-
time.Sleep(nap)
114111
if err := d.createNetwork(); err != nil {
115112
return errors.Wrapf(err, "recreating inoperable network %s", d.PrivateNetwork)
116113
}
117114
log.Debugf("Successfully recreated %s network", d.PrivateNetwork)
118-
time.Sleep(nap)
119115
if err := setupNetwork(conn, d.PrivateNetwork); err != nil {
120116
return err
121117
}
122118
log.Debugf("Successfully activated %s network", d.PrivateNetwork)
123-
time.Sleep(nap)
124119
}
125120

126121
return nil
@@ -140,13 +135,16 @@ func (d *Driver) createNetwork() error {
140135

141136
// network: default
142137
// It is assumed that the libvirt/kvm installation has already created this network
143-
if _, err := conn.LookupNetworkByName(d.Network); err != nil {
138+
netd, err := conn.LookupNetworkByName(d.Network)
139+
if err != nil {
144140
return errors.Wrapf(err, "network %s doesn't exist", d.Network)
145141
}
142+
defer func() { _ = netd.Free() }()
146143

147144
// network: private
148145
// Only create the private network if it does not already exist
149-
if _, err := conn.LookupNetworkByName(d.PrivateNetwork); err != nil {
146+
netp, err := conn.LookupNetworkByName(d.PrivateNetwork)
147+
if err != nil {
150148
// create the XML for the private network from our networkTmpl
151149
tmpl := template.Must(template.New("network").Parse(networkTmpl))
152150
var networkXML bytes.Buffer
@@ -161,10 +159,26 @@ func (d *Driver) createNetwork() error {
161159
}
162160

163161
// and finally create it
164-
if err := network.Create(); err != nil {
162+
log.Debugf("Trying to create network %s...", d.PrivateNetwork)
163+
create := func() error {
164+
if err := network.Create(); err != nil {
165+
return err
166+
}
167+
active, err := network.IsActive()
168+
if err == nil && active {
169+
return nil
170+
}
171+
return errors.Errorf("retrying %v", err)
172+
}
173+
if err := retry.Local(create, 10*time.Second); err != nil {
165174
return errors.Wrapf(err, "creating network %s", d.PrivateNetwork)
166175
}
167176
}
177+
defer func() {
178+
if netp != nil {
179+
_ = netp.Free()
180+
}
181+
}()
168182

169183
return nil
170184
}
@@ -183,13 +197,13 @@ func (d *Driver) deleteNetwork() error {
183197
log.Debugf("Checking if network %s exists...", d.PrivateNetwork)
184198
network, err := conn.LookupNetworkByName(d.PrivateNetwork)
185199
if err != nil {
186-
if libvirtErr, ok := err.(libvirt.Error); ok && libvirtErr.Code == libvirt.ERR_NO_NETWORK {
200+
if lvErr(err).Code == libvirt.ERR_NO_NETWORK {
187201
log.Warnf("Network %s does not exist. Skipping deletion", d.PrivateNetwork)
188202
return nil
189203
}
190-
191204
return errors.Wrapf(err, "failed looking for network %s", d.PrivateNetwork)
192205
}
206+
defer func() { _ = network.Free() }()
193207
log.Debugf("Network %s exists", d.PrivateNetwork)
194208

195209
err = d.checkDomains(conn)
@@ -198,25 +212,59 @@ func (d *Driver) deleteNetwork() error {
198212
}
199213

200214
// when we reach this point, it means it is safe to delete the network
201-
log.Debugf("Trying to destroy network %s...", d.PrivateNetwork)
215+
202216
// cannot destroy an inactive network - try to activate it first
203-
active, err := network.IsActive()
204-
if err == nil && !active {
205-
log.Debugf("Trying to reactivate network %s first...", d.PrivateNetwork)
206-
_ = network.Create()
207-
time.Sleep(nap)
217+
log.Debugf("Trying to reactivate network %s first (if needed)...", d.PrivateNetwork)
218+
activate := func() error {
219+
active, err := network.IsActive()
220+
if err == nil && active {
221+
return nil
222+
}
223+
if err != nil {
224+
return err
225+
}
226+
// inactive, try to activate
227+
if err := network.Create(); err != nil {
228+
return err
229+
}
230+
return errors.Errorf("needs confirmation") // confirm in the next cycle
208231
}
209-
err = network.Destroy()
210-
if err != nil {
211-
return errors.Wrap(err, "network destroy")
232+
if err := retry.Local(activate, 10*time.Second); err != nil {
233+
log.Debugf("Reactivating network %s failed, will continue anyway...", d.PrivateNetwork)
234+
}
235+
236+
log.Debugf("Trying to destroy network %s...", d.PrivateNetwork)
237+
destroy := func() error {
238+
if err := network.Destroy(); err != nil {
239+
return err
240+
}
241+
active, err := network.IsActive()
242+
if err == nil && !active {
243+
return nil
244+
}
245+
return errors.Errorf("retrying %v", err)
246+
}
247+
if err := retry.Local(destroy, 10*time.Second); err != nil {
248+
return errors.Wrap(err, "destroying network")
212249
}
213-
time.Sleep(nap)
250+
214251
log.Debugf("Trying to undefine network %s...", d.PrivateNetwork)
215-
err = network.Undefine()
216-
if err != nil {
217-
return errors.Wrap(err, "network undefine")
252+
undefine := func() error {
253+
if err := network.Undefine(); err != nil {
254+
return err
255+
}
256+
netp, err := conn.LookupNetworkByName(d.PrivateNetwork)
257+
if netp != nil {
258+
_ = netp.Free()
259+
}
260+
if lvErr(err).Code == libvirt.ERR_NO_NETWORK {
261+
return nil
262+
}
263+
return errors.Errorf("retrying %v", err)
264+
}
265+
if err := retry.Local(undefine, 10*time.Second); err != nil {
266+
return errors.Wrap(err, "undefining network")
218267
}
219-
time.Sleep(nap)
220268

221269
return nil
222270
}
@@ -301,7 +349,6 @@ func (d *Driver) lookupIP() (string, error) {
301349
if err != nil {
302350
return "", errors.Wrap(err, "getting connection and domain")
303351
}
304-
305352
defer conn.Close()
306353

307354
libVersion, err := conn.GetLibVersion()
@@ -323,6 +370,7 @@ func (d *Driver) lookupIPFromStatusFile(conn *libvirt.Connect) (string, error) {
323370
if err != nil {
324371
return "", errors.Wrap(err, "looking up network by name")
325372
}
373+
defer func() { _ = network.Free() }()
326374

327375
bridge, err := network.GetBridgeName()
328376
if err != nil {

0 commit comments

Comments
 (0)