From 9aabed2d5ae3621ff0989cdcec8a726970e04ea6 Mon Sep 17 00:00:00 2001 From: David Goulet Date: Thu, 27 Feb 2014 10:06:52 -0500 Subject: [PATCH] Fix: JUL agent connect to user and root sessiond 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 Signed-off-by: David Goulet --- liblttng-ust-jul/LTTngUst.c | 35 ++++++++- liblttng-ust-jul/lttng_ust_jul.h | 30 +++++++- .../org/lttng/ust/jul/LTTngAgent.java | 77 +++++++++++++------ .../org/lttng/ust/jul/LTTngLogHandler.java | 18 ++++- .../lttng/ust/jul/LTTngTCPSessiondClient.java | 6 +- .../org/lttng/ust/jul/LTTngUst.java | 8 +- 6 files changed, 141 insertions(+), 33 deletions(-) diff --git a/liblttng-ust-jul/LTTngUst.c b/liblttng-ust-jul/LTTngUst.c index fe07150f..e6837fbb 100644 --- a/liblttng-ust-jul/LTTngUst.c +++ b/liblttng-ust-jul/LTTngUst.c @@ -22,7 +22,10 @@ #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); diff --git a/liblttng-ust-jul/lttng_ust_jul.h b/liblttng-ust-jul/lttng_ust_jul.h index 442eda54..a45af396 100644 --- a/liblttng-ust-jul/lttng_ust_jul.h +++ b/liblttng-ust-jul/lttng_ust_jul.h @@ -24,7 +24,35 @@ #include -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, diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngAgent.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngAgent.java index c1834f58..72e60d23 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngAgent.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngAgent.java @@ -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(); } diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java index f61677d0..1ad11712 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngLogHandler.java @@ -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()); + } } } diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java index aab1d054..21c228f0 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngTCPSessiondClient.java @@ -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: { diff --git a/liblttng-ust-jul/org/lttng/ust/jul/LTTngUst.java b/liblttng-ust-jul/org/lttng/ust/jul/LTTngUst.java index 33c15eb7..10f2a8ca 100644 --- a/liblttng-ust-jul/org/lttng/ust/jul/LTTngUst.java +++ b/liblttng-ust-jul/org/lttng/ust/jul/LTTngUst.java @@ -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); } -- 2.34.1