lttng: Update LTTng event matching to use event layout
[deliverable/tracecompass.git] / lttng / org.eclipse.tracecompass.lttng2.kernel.core / src / org / eclipse / tracecompass / internal / lttng2 / kernel / core / event / matching / TcpLttngEventMatching.java
index 01747fa27dbdecce2e26c5e2fcaa03d999fbab66..952c338a5a0d0bcc09d2a0cb90507d3333bf84ca 100644 (file)
@@ -1,5 +1,5 @@
 /*******************************************************************************
- * Copyright (c) 2013, 2015 École Polytechnique de Montréal
+ * Copyright (c) 2013, 2016 École Polytechnique de Montréal
  *
  * All rights reserved. This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License v1.0 which
 
 package org.eclipse.tracecompass.internal.lttng2.kernel.core.event.matching;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
+import java.util.WeakHashMap;
 
-import org.eclipse.jdt.annotation.NonNull;
-import org.eclipse.tracecompass.internal.lttng2.kernel.core.TcpEventStrings;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelAnalysisEventLayout;
+import org.eclipse.tracecompass.analysis.os.linux.core.trace.IKernelTrace;
 import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
-import org.eclipse.tracecompass.tmf.core.event.ITmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.TmfEventField;
 import org.eclipse.tracecompass.tmf.core.event.matching.IEventMatchingKey;
 import org.eclipse.tracecompass.tmf.core.event.matching.ITmfMatchEventDefinition;
@@ -28,48 +31,47 @@ import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
 import org.eclipse.tracecompass.tmf.core.trace.ITmfTraceWithPreDefinedEvents;
 import org.eclipse.tracecompass.tmf.core.trace.TmfEventTypeCollectionHelper;
 
-import com.google.common.collect.ImmutableSet;
-
 /**
- * Class to match tcp type events. This class applies to traces obtained with
- * the full network tracepoint data available from an experimental branch of
- * lttng-modules. This branch is often rebased on lttng-modules master and is
- * available at
- * http://git.dorsal.polymtl.ca/~gbastien?p=lttng-modules.git;a=summary
- * net_data_experimental branch.
+ * Class to match tcp events. They use the main kernel's tracepoints
+ * netif_receive_skb and net_dev_queue to check if they have a TCP header and
+ * use the sequence, acknowledge and flags fields to match packets
  *
  * @author Geneviève Bastien
  */
 public class TcpLttngEventMatching implements ITmfMatchEventDefinition {
 
-    private static final String @NonNull [] KEY_SEQ = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.SEQ };
-    private static final String @NonNull [] KEY_ACKSEQ = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.ACKSEQ };
-    private static final String @NonNull [] KEY_FLAGS = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP, TcpEventStrings.FLAGS };
-
-    private static final ImmutableSet<String> REQUIRED_EVENTS = ImmutableSet.of(
-            TcpEventStrings.NET_DEV_QUEUE,
-            TcpEventStrings.NETIF_RECEIVE_SKB);
-
-    private static boolean canMatchPacket(final ITmfEvent event) {
-        TmfEventField field = (TmfEventField) event.getContent();
+    private static final Map<IKernelAnalysisEventLayout, Set<String>> REQUIRED_EVENTS = new HashMap<>();
 
-        String[] tcp_data = { TcpEventStrings.TRANSPORT_FIELDS, TcpEventStrings.TYPE_TCP };
-        ITmfEventField data = field.getField(tcp_data);
-        if (data != null) {
-            return (data.getValue() != null);
-        }
-        return false;
-    }
+    /** Use a weak hash map so that traces can be garbage collected */
+    private static final Map<ITmfTrace, IKernelAnalysisEventLayout> TRACE_LAYOUTS = new WeakHashMap<>();
 
     @Override
     public boolean canMatchTrace(ITmfTrace trace) {
+        // Get the events that this trace needs to have
+        if (!(trace instanceof IKernelTrace)) {
+            // Not a kernel trace, we cannot know what events to use, return
+            // false
+            return false;
+        }
+        IKernelAnalysisEventLayout layout = ((IKernelTrace) trace).getKernelEventLayout();
+        TRACE_LAYOUTS.put(trace, layout);
+
+        Set<String> events = REQUIRED_EVENTS.get(layout);
+        if (events == null) {
+            events = new HashSet<>();
+            events.addAll(layout.eventsNetworkSend());
+            events.addAll(layout.eventsNetworkReceive());
+            REQUIRED_EVENTS.put(layout, events);
+        }
+
         if (!(trace instanceof ITmfTraceWithPreDefinedEvents)) {
+            // No predefined events, suppose events are present
             return true;
         }
         ITmfTraceWithPreDefinedEvents ktrace = (ITmfTraceWithPreDefinedEvents) trace;
 
         Set<String> traceEvents = TmfEventTypeCollectionHelper.getEventNames(ktrace.getContainedEventTypes());
-        traceEvents.retainAll(REQUIRED_EVENTS);
+        traceEvents.retainAll(events);
         return !traceEvents.isEmpty();
     }
 
@@ -78,12 +80,15 @@ public class TcpLttngEventMatching implements ITmfMatchEventDefinition {
      */
     @Override
     public Direction getDirection(ITmfEvent event) {
+        IKernelAnalysisEventLayout layout = TRACE_LAYOUTS.get(event.getTrace());
+        if (layout == null) {
+            return null;
+        }
         String evname = event.getName();
-
         /* Is the event a tcp socket in or out event */
-        if (evname.equals(TcpEventStrings.NETIF_RECEIVE_SKB) && canMatchPacket(event)) {
+        if (layout.eventsNetworkReceive().contains(evname)) {
             return Direction.EFFECT;
-        } else if (evname.equals(TcpEventStrings.NET_DEV_QUEUE) && canMatchPacket(event)) {
+        } else if (layout.eventsNetworkSend().contains(evname)) {
             return Direction.CAUSE;
         }
         return null;
@@ -91,32 +96,24 @@ public class TcpLttngEventMatching implements ITmfMatchEventDefinition {
 
     @Override
     public IEventMatchingKey getEventKey(ITmfEvent event) {
-        TmfEventField field = (TmfEventField) event.getContent();
-        ITmfEventField data;
-
-        long seq = -1, ackseq = -1, flags = -1;
-        data = field.getField(KEY_SEQ);
-        if (data != null) {
-            seq = (long) data.getValue();
-        } else {
+        IKernelAnalysisEventLayout layout = TRACE_LAYOUTS.get(event.getTrace());
+        if (layout == null) {
             return null;
         }
-        data = field.getField(KEY_ACKSEQ);
-        if (data != null) {
-            ackseq = (long) data.getValue();
-        } else {
-            return null;
-        }
-        data = field.getField(KEY_FLAGS);
-        if (data != null) {
-            flags = (long) data.getValue();
-        } else {
+
+        TmfEventField content = (TmfEventField) event.getContent();
+
+        Long sequence = content.getFieldValue(Long.class, layout.fieldPathTcpSeq());
+        Long ack = content.getFieldValue(Long.class, layout.fieldPathTcpAckSeq());
+        Long flags = content.getFieldValue(Long.class, layout.fieldPathTcpFlags());
+
+        if (sequence == null || ack == null || flags == null) {
             return null;
         }
 
-        IEventMatchingKey key = new TcpEventKey(seq, ackseq, flags);
-
+        IEventMatchingKey key = new TcpEventKey(sequence, ack, flags);
         return key;
+
     }
 
 }
This page took 0.026199 seconds and 5 git commands to generate.