Fix: JUL agent connect to user and root sessiond
authorDavid Goulet <dgoulet@efficios.com>
Thu, 27 Feb 2014 15:06:52 +0000 (10:06 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 27 Feb 2014 17:29:49 +0000 (12:29 -0500)
In order to achieve such a thing, two tracepoints are used where one is
for the regular user and the other one for root. This is to avoid
duplicating the payload in the user and root traces.

Furthermore, if a root port is found, a new thread is started to handle
the second session daemon.

This is lockstep commit with lttng-tools:
f43f95a9a82e01eed34593260d510bd32e2083ec

Fixes #732

Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Signed-off-by: David Goulet <dgoulet@efficios.com>
liblttng-ust-jul/LTTngUst.c
liblttng-ust-jul/lttng_ust_jul.h
liblttng-ust-jul/org/lttng/ust/jul/LTTngAgent.java
liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java
liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java
liblttng-ust-jul/org/lttng/ust/jul/LTTngUst.java

index fe07150ff56cb5082be7810bebfee51915cbb499..e6837fbb417b425b30ccd5406045232b1f71c1c5 100644 (file)
 #define TRACEPOINT_CREATE_PROBES
 #include "lttng_ust_jul.h"
 
-JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepoint(JNIEnv *env,
+/*
+ * System tracepoint meaning only root agent will fire this.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepointS(JNIEnv *env,
                                                jobject jobj,
                                                jstring msg,
                                                jstring logger_name,
@@ -38,7 +41,35 @@ JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepoint(JNIEnv *env,
        const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
        const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
 
-       tracepoint(lttng_jul, jul_event, msg_cstr, logger_name_cstr,
+       tracepoint(lttng_jul, sys_event, msg_cstr, logger_name_cstr,
+                       class_name_cstr, method_name_cstr, millis, log_level, thread_id);
+
+       (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
+       (*env)->ReleaseStringUTFChars(env, logger_name, logger_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, class_name, class_name_cstr);
+       (*env)->ReleaseStringUTFChars(env, method_name, method_name_cstr);
+}
+
+/*
+ * User tracepoint meaning only a non root agent will fire this.
+ */
+JNIEXPORT void JNICALL Java_org_lttng_ust_jul_LTTngUst_tracepointU(JNIEnv *env,
+               jobject jobj,
+               jstring msg,
+               jstring logger_name,
+               jstring class_name,
+               jstring method_name,
+               jlong millis,
+               jint log_level,
+               jint thread_id)
+{
+       jboolean iscopy;
+       const char *msg_cstr = (*env)->GetStringUTFChars(env, msg, &iscopy);
+       const char *logger_name_cstr = (*env)->GetStringUTFChars(env, logger_name, &iscopy);
+       const char *class_name_cstr = (*env)->GetStringUTFChars(env, class_name, &iscopy);
+       const char *method_name_cstr = (*env)->GetStringUTFChars(env, method_name, &iscopy);
+
+       tracepoint(lttng_jul, user_event, msg_cstr, logger_name_cstr,
                        class_name_cstr, method_name_cstr, millis, log_level, thread_id);
 
        (*env)->ReleaseStringUTFChars(env, msg, msg_cstr);
index 442eda54b2cec35b17c3c880a72fe469824db3ad..a45af396e6c2aff69cf953ce8be6694dfbc7c3b6 100644 (file)
 
 #include <lttng/tracepoint.h>
 
-TRACEPOINT_EVENT(lttng_jul, jul_event,
+/*
+ * Privileged tracepoint meaning that this is only enable and fired by the root
+ * session daemon.
+ */
+TRACEPOINT_EVENT(lttng_jul, sys_event,
+       TP_ARGS(
+               const char *, msg,
+               const char *, logger_name,
+               const char *, class_name,
+               const char *, method_name,
+               long, millis,
+               int, log_level,
+               int, thread_id),
+       TP_FIELDS(
+               ctf_string(msg, msg)
+               ctf_string(logger_name, logger_name)
+               ctf_string(class_name, class_name)
+               ctf_string(method_name, method_name)
+               ctf_integer(long, long_millis, millis)
+               ctf_integer(int, int_loglevel, log_level)
+               ctf_integer(int, int_threadid, thread_id)
+       )
+)
+
+/*
+ * User tracepoint meaning that this is only enable and fired by a non root
+ * session daemon.
+ */
+TRACEPOINT_EVENT(lttng_jul, user_event,
        TP_ARGS(
                const char *, msg,
                const char *, logger_name,
index c1834f5869a551b3d61a5ddeb752d85b18b5777e..72e60d235574fa1d3fa188ff405adbfaafcfbaee 100644 (file)
@@ -31,10 +31,15 @@ import java.util.logging.LogManager;
 import java.util.Enumeration;
 
 public class LTTngAgent {
-       private static LTTngLogHandler lttngHandler;
        private static LogManager logManager;
-       private static LTTngThread lttngThread;
-       private static Thread sessiondTh;
+
+       /* Possible that we have to threads handling two sessiond. */
+       private static LTTngLogHandler lttngHandlerRoot;
+       private static LTTngLogHandler lttngHandlerUser;
+       private static LTTngThread lttngThreadRoot;
+       private static LTTngThread lttngThreadUser;
+       private static Thread sessiondThRoot;
+       private static Thread sessiondThUser;
 
        /* Singleton agent object. */
        private static LTTngAgent curAgent = null;
@@ -56,7 +61,9 @@ public class LTTngAgent {
         */
        private LTTngAgent() throws IOException {
                this.logManager = LogManager.getLogManager();
-               this.lttngHandler = new LTTngLogHandler(this.logManager);
+               this.lttngHandlerUser = new LTTngLogHandler(this.logManager);
+               this.lttngHandlerRoot = new LTTngLogHandler(this.logManager);
+               this.lttngHandlerRoot.is_root = 1;
                this.registerSem = new Semaphore(0, true);
        }
 
@@ -73,7 +80,8 @@ public class LTTngAgent {
                        }
 
                        logger = this.logManager.getLogger(loggerName);
-                       logger.removeHandler(this.lttngHandler);
+                       logger.removeHandler(this.lttngHandlerUser);
+                       logger.removeHandler(this.lttngHandlerRoot);
                }
        }
 
@@ -96,19 +104,10 @@ public class LTTngAgent {
                return System.getProperty("user.home");
        }
 
-       private int getPortFromFile() throws IOException {
+       private int getPortFromFile(String path) throws IOException {
                int port;
-               int uid = getUID();
-               String path;
                BufferedReader br;
 
-               /* Check if root or not, it tells where to get the port file. */
-               if (uid == 0) {
-                       path = rootPortFile;
-               } else {
-                       path = new String(getHomePath() + userPortFile);
-               }
-
                try {
                        br = new BufferedReader(new FileReader(path));
                        String line = br.readLine();
@@ -141,33 +140,63 @@ public class LTTngAgent {
         * returned by the logManager.
         */
        private synchronized void init() throws SecurityException, IOException {
+               int user_port, root_port;
+               int nr_acquires = 0;
+
                if (this.initialized) {
                        return;
                }
 
-               this.lttngThread = new LTTngThread(this.sessiondAddr,
-                               getPortFromFile(), this.lttngHandler, this.registerSem);
-               this.sessiondTh = new Thread(lttngThread);
-               this.sessiondTh.start();
+               root_port = getPortFromFile(rootPortFile);
+               if (getUID() == 0) {
+                       user_port = root_port;
+               } else {
+                       user_port = getPortFromFile(getHomePath() + userPortFile);
+               }
 
-               this.initialized = true;
+               /* Handle user session daemon if any. */
+               this.lttngThreadUser = new LTTngThread(this.sessiondAddr, user_port,
+                               this.lttngHandlerUser, this.registerSem);
+               this.sessiondThUser = new Thread(lttngThreadUser);
+               this.sessiondThUser.start();
+               /* Wait for registration done of per-user sessiond */
+               nr_acquires++;
+
+               /* Having two different ports, we have to try both. */
+               if (root_port != user_port) {
+                       /* Handle root session daemon. */
+                       this.lttngThreadRoot = new LTTngThread(this.sessiondAddr,
+                                       root_port, this.lttngHandlerRoot, this.registerSem);
+                       this.sessiondThRoot = new Thread(lttngThreadRoot);
+                       this.sessiondThRoot.start();
+                       /* Wait for registration done of system-wide sessiond */
+                       nr_acquires++;
+               }
 
-               /* Wait for the registration to end. */
+               /* Wait for each registration to end. */
                try {
-                       this.registerSem.acquire();
+                       this.registerSem.acquire(nr_acquires);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
+
+               this.initialized = true;
        }
 
        public void dispose() throws IOException {
-               this.lttngThread.dispose();
+               this.lttngThreadUser.dispose();
+               if (this.lttngThreadRoot != null) {
+                       this.lttngThreadRoot.dispose();
+               }
 
                /* Make sure there is no more LTTng handler attach to logger(s). */
                this.removeHandlers();
 
                try {
-                       this.sessiondTh.join();
+                       this.sessiondThUser.join();
+                       if (this.sessiondThRoot != null) {
+                               this.sessiondThRoot.join();
+                       }
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
index f61677d0b3b270e96a07fef07a817ef73f00c33c..1ad1171279b271f60d64f2a8a8c22cae1b79a2e5 100644 (file)
@@ -43,6 +43,9 @@ public class LTTngLogHandler extends Handler {
        public int logLevelAll = 0;
        public int logLevelTypeAll;
 
+       /* Am I a root Log Handler. */
+       public int is_root = 0;
+
        public LogManager logManager;
 
        /* Indexed by name and corresponding LTTngEvent. */
@@ -111,9 +114,16 @@ public class LTTngLogHandler extends Handler {
                 * caller is used for the event name, the raw message is taken, the
                 * loglevel of the record and the thread ID.
                 */
-               LTTngUst.tracepoint(record.getMessage(), record.getLoggerName(),
-                               record.getSourceClassName(), record.getSourceMethodName(),
-                               record.getMillis(), record.getLevel().intValue(),
-                               record.getThreadID());
+               if (this.is_root == 1) {
+                       LTTngUst.tracepointS(record.getMessage(),
+                                       record.getLoggerName(), record.getSourceClassName(),
+                                       record.getSourceMethodName(), record.getMillis(),
+                                       record.getLevel().intValue(), record.getThreadID());
+               } else {
+                       LTTngUst.tracepointU(record.getMessage(),
+                                       record.getLoggerName(), record.getSourceClassName(),
+                                       record.getSourceMethodName(), record.getMillis(),
+                                       record.getLevel().intValue(), record.getThreadID());
+               }
        }
 }
index aab1d05418b2f0d576248aa39950003b399aed58..21c228f00bdde7a2428f4090213a28bfee6381bd 100644 (file)
@@ -280,7 +280,11 @@ public class LTTngTCPSessiondClient {
                                         * can proceed to continue tracing.
                                         */
                                        this.registerSem.release();
-                                       break;
+                                       /*
+                                        * We don't send any reply to the registration done command.
+                                        * This just marks the end of the initial session setup.
+                                        */
+                                       continue;
                                }
                                case CMD_LIST:
                                {
index 33c15eb76689042b53d40ddb921d5b684e98db57..10f2a8caec370568e3aaf9f546dcfe252c5e0425 100644 (file)
@@ -63,6 +63,12 @@ public abstract class LTTngUst {
         * @param thread_id
         *            Identifier for the thread where the message originated.
         */
-    public static native void tracepoint(String msg, String logger_name, String class_name,
+
+       /* Use for a user session daemon. */
+       public static native void tracepointU(String msg, String logger_name, String class_name,
+                       String method_name, long millis, int log_level, int thread_id);
+
+       /* Use for a root session daemon. */
+       public static native void tracepointS(String msg, String logger_name, String class_name,
                        String method_name, long millis, int log_level, int thread_id);
 }
This page took 0.029393 seconds and 4 git commands to generate.