Browse code

Fix loading of containerized plugins

During daemon startup, all containers are registered before any are
started.
During container registration it was calling out to initialize volumes.
If the volume uses a plugin that is running in a container, this will
cause the restart of that container to fail since the plugin is not yet
running.
This also slowed down daemon startup since volume initialization was
happening sequentially, which can be slow (and is flat out slow since
initialization would fail but take 8 seconds for each volume to do it).

This fix holds off on volume initialization until after containers are
restarted and does the initialization in parallel.

The containers that are restarted will have thier volumes initialized
because they are being started. If any of these containers are using a
plugin they will just keep retrying to reach the plugin (up to the
timeout, which is 8seconds) until the container with the plugin is up
and running.

Signed-off-by: Brian Goff <cpuguy83@gmail.com>

Brian Goff authored on 2016/01/21 02:06:03
Showing 2 changed files
... ...
@@ -282,10 +282,6 @@ func (daemon *Daemon) Register(container *container.Container) error {
282 282
 		}
283 283
 	}
284 284
 
285
-	if err := daemon.prepareMountPoints(container); err != nil {
286
-		return err
287
-	}
288
-
289 285
 	return nil
290 286
 }
291 287
 
... ...
@@ -408,6 +404,23 @@ func (daemon *Daemon) restore() error {
408 408
 	}
409 409
 	group.Wait()
410 410
 
411
+	// any containers that were started above would already have had this done,
412
+	// however we need to now prepare the mountpoints for the rest of the containers as well.
413
+	// This shouldn't cause any issue running on the containers that already had this run.
414
+	// This must be run after any containers with a restart policy so that containerized plugins
415
+	// can have a chance to be running before we try to initialize them.
416
+	for _, c := range containers {
417
+		group.Add(1)
418
+		go func(c *container.Container) {
419
+			defer group.Done()
420
+			if err := daemon.prepareMountPoints(c); err != nil {
421
+				logrus.Error(err)
422
+			}
423
+		}(c)
424
+	}
425
+
426
+	group.Wait()
427
+
411 428
 	if !debug {
412 429
 		if logrus.GetLevel() == logrus.InfoLevel {
413 430
 			fmt.Println()
... ...
@@ -159,7 +159,6 @@ func (daemon *Daemon) registerMountPoints(container *container.Container, hostCo
159 159
 func (daemon *Daemon) lazyInitializeVolume(containerID string, m *volume.MountPoint) error {
160 160
 	if len(m.Driver) > 0 && m.Volume == nil {
161 161
 		v, err := daemon.volumes.GetWithRef(m.Name, m.Driver, containerID)
162
-
163 162
 		if err != nil {
164 163
 			return err
165 164
 		}