use of org.onosproject.net.device.DeviceHandshaker in project onos by opennetworkinglab.
the class GeneralDeviceProvider method doCheckupAndRepair.
private void doCheckupAndRepair(DeviceId deviceId) {
if (!configIsPresent(deviceId)) {
// We should have a connection only for devices in the config.
submitTask(deviceId, TaskType.CONNECTION_TEARDOWN);
return;
}
final DeviceHandshaker handshaker = handshakersWithListeners.get(deviceId);
if (handshaker == null) {
// Device in config but we have not initiated a connection.
// Perhaps we missed the config event?
submitTask(deviceId, TaskType.CONNECTION_SETUP);
return;
}
// the device...
if (!handshaker.hasConnection()) {
// ... but now the driver reports there is NOT a connection.
// Perhaps the netcfg changed and we didn't pick the event?
log.warn("Re-establishing lost connection to {}", deviceId);
submitTask(deviceId, TaskType.CONNECTION_TEARDOWN);
submitTask(deviceId, TaskType.CONNECTION_SETUP);
return;
}
// If here, device should be registered in the core.
assertDeviceRegistered(deviceId);
if (!handshaker.isReachable() || !probeReachabilitySync(deviceId)) {
// Device appears to be offline.
markOfflineIfNeeded(deviceId);
// CHANNEL_OPEN events.
return;
}
// If here, device is reachable. Now do mastership and availability
// checkups. To avoid overload of checkup tasks which might involve
// sending messages over the network and triggering mastership
// elections. We require a minimum interval of 1/3 of the configured
// checkupInterval between consecutive checkup tasks when the device is
// known to be available.
final Long lastCheckup = lastCheckups.get(deviceId);
final boolean isAvailable = deviceService.isAvailable(deviceId);
if (isAvailable && lastCheckup != null && (currentTimeMillis() - lastCheckup) < (checkupInterval * 1000 / 3)) {
if (log.isDebugEnabled()) {
log.debug("Dropping checkup task for {} as it happened recently", deviceId);
}
return;
}
lastCheckups.put(deviceId, currentTimeMillis());
// Make sure device has a valid mastership role.
final MastershipRole expectedRole = mastershipService.getLocalRole(deviceId);
if (expectedRole == MastershipRole.NONE) {
log.debug("Detected invalid role ({}) for {}, waiting for mastership " + "service to fix this...", expectedRole, deviceId);
// Gentle nudge to fix things...
mastershipService.requestRoleForSync(deviceId);
return;
}
final MastershipRole deviceRole = handshaker.getRole();
// FIXME: we should be checking the mastership term as well.
if (expectedRole != deviceRole) {
// Let's be greedy, if the role is NONE likely is due to the lazy channel
if (deviceRole == MastershipRole.NONE) {
log.warn("Detected role mismatch for {}, core expects {}, " + "but device reports {}, reassert the role... ", deviceId, expectedRole, deviceRole);
// If we are experiencing a severe issue, eventually
// the DeviceManager will move the mastership
roleChanged(deviceId, expectedRole);
} else {
log.debug("Detected role mismatch for {}, core expects {}, " + "but device reports {}, waiting for mastership " + "service to fix this...", deviceId, expectedRole, deviceRole);
// Gentle nudge to fix things...
providerService.receivedRoleReply(deviceId, deviceRole);
}
return;
}
// describes the ability of the device to forward packets.
if (probeAvailability(handshaker)) {
// Device ready to do its job.
createOrUpdateDevice(deviceId, true);
} else {
markOfflineIfNeeded(deviceId);
if (isPipelineProgrammable(deviceId)) {
// If reachable, but not available, and pipeline programmable,
// there is a high chance it's because the pipeline is not READY
// (independently from what the pipeconf watchdog reports, as
// the status there might be outdated). Encourage pipeconf
// watchdog to perform a pipeline probe ASAP.
pipeconfWatchdogService.triggerProbe(deviceId);
}
}
}
use of org.onosproject.net.device.DeviceHandshaker in project onos by opennetworkinglab.
the class GeneralDeviceProvider method handleConnectionSetup.
private void handleConnectionSetup(DeviceId deviceId) {
assertConfig(deviceId);
// Bind pipeconf (if any and if device is capable).
bindPipeconfIfRequired(deviceId);
// Get handshaker.
final DeviceHandshaker handshaker = handshakerOrFail(deviceId);
if (handshaker.hasConnection() || handshakersWithListeners.containsKey(deviceId)) {
throw new DeviceTaskException("connection already exists");
}
// Add device agent listener.
handshakersWithListeners.put(deviceId, handshaker);
handshaker.addDeviceAgentListener(id(), deviceAgentListener);
// Start connection via handshaker.
if (!handshaker.connect()) {
// Failed! Remove listeners.
handshaker.removeDeviceAgentListener(id());
handshakersWithListeners.remove(deviceId);
// Clean up connection state leftovers.
handshaker.disconnect();
throw new DeviceTaskException("connection failed");
}
createOrUpdateDevice(deviceId, false);
// From here we expect a CHANNEL_OPEN event to update availability.
}
use of org.onosproject.net.device.DeviceHandshaker in project onos by opennetworkinglab.
the class GeneralDeviceProvider method handleConnectionTeardown.
private void handleConnectionTeardown(DeviceId deviceId) {
if (deviceService.getDevice(deviceId) != null && deviceService.isAvailable(deviceId)) {
providerService.deviceDisconnected(deviceId);
}
final DeviceHandshaker handshaker = handshakerOrFail(deviceId);
handshaker.removeDeviceAgentListener(id());
handshakersWithListeners.remove(deviceId);
handshaker.disconnect();
lastCheckups.remove(deviceId);
}
Aggregations