Skip to content

Instantly share code, notes, and snippets.

@mgerdts
Created February 7, 2018 12:33
Show Gist options
  • Save mgerdts/6454847d400fc6691a0baaf4f7de2605 to your computer and use it in GitHub Desktop.
Save mgerdts/6454847d400fc6691a0baaf4f7de2605 to your computer and use it in GitHub Desktop.
cloud-init retry serial open
diff --git a/cloudinit/sources/DataSourceSmartOS.py b/cloudinit/sources/DataSourceSmartOS.py
index 32655131..b1676f92 100644
--- a/cloudinit/sources/DataSourceSmartOS.py
+++ b/cloudinit/sources/DataSourceSmartOS.py
@@ -28,6 +29,7 @@ import os
import random
import re
import socket
+import time
from cloudinit import log as logging
from cloudinit import serial
@@ -492,7 +494,23 @@ class JoyentMetadataSerialClient(JoyentMetadataClient):
def open_transport(self):
ser = serial.Serial(self.device, timeout=self.timeout)
if not ser.isOpen():
- raise SystemError("Unable to open %s" % self.device)
+ # There is some sort of a race between cloud-init and mdata-get
+ # that can cause the serial device to not open on the initial
+ # attempt.
+ for tries in range(1, 11):
+ try:
+ ser.open()
+ assert(ser.isOpen())
+ break
+ except OSError as exc:
+ # This is probably a SerialException, which is a subclass
+ # of OSError. SerialException is not used becasue of
+ # existing efforts to make pyserial optional.
+ LOG.debug("Failed to open %s on try %d: %s", self.device,
+ tries, exc)
+ time.sleep(0.1)
+ else:
+ raise SystemError("Unable to open %s" % self.device)
fcntl.lockf(ser, fcntl.LOCK_EX)
self.fp = ser
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment