Search in sources :

Example 6 with DeviceHandshaker

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);
        }
    }
}
Also used : DeviceHandshaker(org.onosproject.net.device.DeviceHandshaker) MastershipRole(org.onosproject.net.MastershipRole)

Example 7 with DeviceHandshaker

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.
}
Also used : DeviceHandshaker(org.onosproject.net.device.DeviceHandshaker) DeviceTaskException(org.onosproject.provider.general.device.impl.DeviceTaskExecutor.DeviceTaskException)

Example 8 with DeviceHandshaker

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);
}
Also used : DeviceHandshaker(org.onosproject.net.device.DeviceHandshaker)

Aggregations

DeviceHandshaker (org.onosproject.net.device.DeviceHandshaker)8 MastershipRole (org.onosproject.net.MastershipRole)2 ChassisId (org.onlab.packet.ChassisId)1 NodeId (org.onosproject.cluster.NodeId)1 MastershipInfo (org.onosproject.mastership.MastershipInfo)1 PiPipelineProgrammable (org.onosproject.net.behaviour.PiPipelineProgrammable)1 DefaultDeviceDescription (org.onosproject.net.device.DefaultDeviceDescription)1 Driver (org.onosproject.net.driver.Driver)1 PiPipeconf (org.onosproject.net.pi.model.PiPipeconf)1 PiPipeconfId (org.onosproject.net.pi.model.PiPipeconfId)1 DeviceTaskException (org.onosproject.provider.general.device.impl.DeviceTaskExecutor.DeviceTaskException)1