Bug #1156 » 0001-Add-thread-to-monitor-udev.patch
configure.ac | ||
---|---|---|
)
|
||
AC_SUBST(DL_LIBS)
|
||
# Check libudev
|
||
PKG_CHECK_MODULES([UDEV], [libudev],
|
||
[
|
||
dnl PKG_CHECK_MODULES defines UDEV_LIBS
|
||
],
|
||
[
|
||
AC_MSG_WARN([pkg-config was unable to find a valid .pc for libudev. Set PKG_CONFIG_PATH to specify the pkgconfig configuration file location])
|
||
AC_MSG_WARN([Finding libudev without pkg-config.])
|
||
AC_CHECK_LIB([popt],
|
||
[udevGetContext],
|
||
[UDEV_LIBS="-ludev"],
|
||
[
|
||
AC_MSG_FAILURE([Cannot find libudev. Either set PKG_CONFIG_PATH to the configuration file location or use LDFLAGS=-Ldir to specify the library location])
|
||
]
|
||
)
|
||
]
|
||
)
|
||
AC_SUBST(UDEV_LIBS)
|
||
# Check for fmemopen
|
||
AC_CHECK_LIB([c], [fmemopen],
|
||
[
|
src/bin/lttng-sessiond/Makefile.am | ||
---|---|---|
trace-kernel.c trace-kernel.h \
|
||
kernel.c kernel.h \
|
||
ust-ctl.h ust-app.h trace-ust.h ust-thread.h \
|
||
ust-registry.h \
|
||
ust-registry.h udev-monitor.h \
|
||
context.c context.h \
|
||
channel.c channel.h \
|
||
event.c event.h \
|
||
... | ... | |
if HAVE_LIBLTTNG_UST_CTL
|
||
lttng_sessiond_SOURCES += trace-ust.c ust-registry.c ust-app.c \
|
||
ust-consumer.c ust-consumer.h ust-thread.c \
|
||
ust-metadata.c ust-clock.h agent-thread.c agent-thread.h
|
||
ust-metadata.c ust-clock.h agent-thread.c agent-thread.h \
|
||
udev-monitor-provider.h udev-monitor.c
|
||
endif
|
||
# Add main.c at the end for compile order
|
||
... | ... | |
if HAVE_LIBLTTNG_UST_CTL
|
||
lttng_sessiond_LDADD += -llttng-ust-ctl
|
||
lttng_sessiond_LDADD += -llttng-ust-ctl -ludev -llttng-ust
|
||
endif
|
src/bin/lttng-sessiond/health-sessiond.h | ||
---|---|---|
HEALTH_SESSIOND_TYPE_APP_MANAGE_NOTIFY = 6,
|
||
HEALTH_SESSIOND_TYPE_APP_REG_DISPATCH = 7,
|
||
HEALTH_SESSIOND_TYPE_NOTIFICATION = 8,
|
||
HEALTH_SESSIOND_TYPE_UDEV_MONITOR = 9,
|
||
NR_HEALTH_SESSIOND_TYPES,
|
||
};
|
src/bin/lttng-sessiond/main.c | ||
---|---|---|
#include "health-sessiond.h"
|
||
#include "testpoint.h"
|
||
#include "ust-thread.h"
|
||
#include "udev-monitor.h"
|
||
#include "agent-thread.h"
|
||
#include "save.h"
|
||
#include "load-session-thread.h"
|
||
... | ... | |
static pthread_t agent_reg_thread;
|
||
static pthread_t load_session_thread;
|
||
static pthread_t notification_thread;
|
||
static pthread_t monitor_udev_thread;
|
||
/*
|
||
* UST registration command queue. This queue is tied with a futex and uses a N
|
||
... | ... | |
}
|
||
}
|
||
/* Create the udev monitoring thread */
|
||
ret = pthread_create(&monitor_udev_thread, default_pthread_attr(),
|
||
ust_thread_monitor_udev, (void *) NULL);
|
||
if (ret) {
|
||
errno = ret;
|
||
PERROR("pthread_create udev_monitor_thread");
|
||
retval = -1;
|
||
stop_threads();
|
||
goto exit_load_session;
|
||
}
|
||
/* Create session loading thread. */
|
||
ret = pthread_create(&load_session_thread, default_pthread_attr(),
|
||
thread_load_session, load_info);
|
src/bin/lttng-sessiond/udev-monitor-provider.h | ||
---|---|---|
/*
|
||
* Copyright (C) 2018 Geneviève Bastien <gbastien@versatic.net>
|
||
*
|
||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
* of this software and associated documentation files (the "Software"), to deal
|
||
* in the Software without restriction, including without limitation the rights
|
||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
* copies of the Software, and to permit persons to whom the Software is
|
||
* furnished to do so, subject to the following conditions:
|
||
*
|
||
* The above copyright notice and this permission notice shall be included in
|
||
* all copies or substantial portions of the Software.
|
||
*
|
||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||
* SOFTWARE.
|
||
*/
|
||
|
||
/*
|
||
* udev_monitor lttng-ust tracepoint provider.
|
||
*/
|
||
#undef TRACEPOINT_PROVIDER
|
||
#define TRACEPOINT_PROVIDER udev_monitor
|
||
#undef TRACEPOINT_INCLUDE
|
||
#define TRACEPOINT_INCLUDE "./udev-monitor-provider.h"
|
||
#if !defined(_UDEV_MONITOR_PROVIDER_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||
#define _UDEV_MONITOR_PROVIDER_H
|
||
#include <lttng/tracepoint.h>
|
||
/*
|
||
* KVM creation tracepoint. Adds the pid of the newly created machine
|
||
* and its uuid to match it with an 'env'.'uuid' metadata in the guest
|
||
* trace
|
||
*/
|
||
TRACEPOINT_EVENT(
|
||
udev_monitor,
|
||
kvm_created,
|
||
TP_ARGS(unsigned int, pid, const char *, uuid),
|
||
TP_FIELDS(
|
||
ctf_integer(unsigned int, pid, pid)
|
||
ctf_string(uuid, uuid)
|
||
)
|
||
)
|
||
/*
|
||
* KVM destruction tracepoint. Adds the pid of the destroyed machine
|
||
*/
|
||
TRACEPOINT_EVENT(
|
||
udev_monitor,
|
||
kvm_destroyed,
|
||
TP_ARGS(unsigned int, pid),
|
||
TP_FIELDS(
|
||
ctf_integer(unsigned int, pid, pid)
|
||
)
|
||
)
|
||
#endif /* _UDEV_MONITOR_PROVIDER_H */
|
||
#include <lttng/tracepoint-event.h>
|
src/bin/lttng-sessiond/udev-monitor.c | ||
---|---|---|
/*
|
||
* Copyright (C) 2018 - Geneviève Bastien <gbastien@versatic.net>
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify it
|
||
* under the terms of the GNU General Public License, version 2 only, as
|
||
* published by the Free Software Foundation.
|
||
*
|
||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
* more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License along with
|
||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
*/
|
||
#define _LGPL_SOURCE
|
||
#include <assert.h>
|
||
#include <common/common.h>
|
||
#include <common/utils.h>
|
||
#include <libudev.h>
|
||
#include "fd-limit.h"
|
||
#include "lttng-sessiond.h"
|
||
#include "udev-monitor.h"
|
||
#include "health-sessiond.h"
|
||
#include "testpoint.h"
|
||
/*
|
||
* We need to define TRACEPOINT_DEFINE in one C file in the program
|
||
* before including provider headers.
|
||
*/
|
||
#define TRACEPOINT_DEFINE
|
||
//#define TRACEPOINT_CREATE_PROBES
|
||
#include "udev-monitor-provider.h"
|
||
#define KVM_NODE "/dev/kvm"
|
||
#define KVM_EVENT_CREATE "create"
|
||
#define KVM_EVENT_DESTROY "destroy"
|
||
#define KVM_UUID_PARAM "-uuid"
|
||
#define QEMU_KVM_UUID_LEN 37
|
||
int doTraceKvmCreate(int pid) {
|
||
FILE *file;
|
||
char *line = NULL, uuid[QEMU_KVM_UUID_LEN];
|
||
size_t len = 0;
|
||
char cmdline_file[64];
|
||
uuid[0] = '\0';
|
||
if (pid > 0) {
|
||
sprintf(cmdline_file, "/proc/%d/cmdline", pid);
|
||
file = fopen(cmdline_file, "r");
|
||
if (file) {
|
||
while (getdelim(&line, &len, '\0', file) != -1) {
|
||
if (!strcmp(KVM_UUID_PARAM, line)) {
|
||
// Read the next value in uuid
|
||
if (getdelim(&line, &len, '\0', file) != -1)
|
||
strcpy(uuid, line);
|
||
}
|
||
}
|
||
free(line);
|
||
fclose(file);
|
||
}
|
||
}
|
||
DBG("[udev-monitor-thread] kvm created %d: %s", pid, uuid);
|
||
// tracepoint(udev_monitor, kvm_created, pid, uuid);
|
||
return 0;
|
||
}
|
||
int doTraceKvmEvent(struct udev_device * dev) {
|
||
struct udev_list_entry *list, *current;
|
||
const char *event, *pidstr;
|
||
int pid = -1;
|
||
// if (!tracepoint_enabled(udev_monitor, kvm_created)) {
|
||
// // No need to do anything
|
||
// return 0;
|
||
// }
|
||
list = udev_device_get_properties_list_entry(dev);
|
||
current = udev_list_entry_get_by_name(list, "EVENT");
|
||
if (!current) {
|
||
return 0;
|
||
}
|
||
event = udev_list_entry_get_value(current);
|
||
current = udev_list_entry_get_by_name(list, "PID");
|
||
if (!current) {
|
||
return 0;
|
||
}
|
||
pidstr = udev_list_entry_get_value(current);
|
||
pid = strtoul(pidstr, NULL, 0);
|
||
if (!strcmp(KVM_EVENT_CREATE, event)) {
|
||
doTraceKvmCreate(pid);
|
||
} else if (!strcmp(KVM_EVENT_DESTROY, event)) {
|
||
DBG("[udev-monitor-thread] kvm destroyed %d", pid);
|
||
// tracepoint(udev_monitor, kvm_destroyed, pid);
|
||
}
|
||
return 0;
|
||
}
|
||
/*
|
||
* This thread manage application notify communication.
|
||
*/
|
||
void *ust_thread_monitor_udev(void *data)
|
||
{
|
||
int ret, err = -1;
|
||
struct udev *udev;
|
||
struct udev_device *dev;
|
||
struct udev_monitor *mon;
|
||
int fd;
|
||
const char *node;
|
||
DBG("[udev-monitor-thread] Monitoring udev events ");
|
||
rcu_register_thread();
|
||
rcu_thread_online();
|
||
health_register(health_sessiond,
|
||
HEALTH_SESSIOND_TYPE_UDEV_MONITOR);
|
||
// if (testpoint(sessiond_thread_app_manage_notify)) {
|
||
// goto error_testpoint;
|
||
// }
|
||
health_code_update();
|
||
/* Create the udev object */
|
||
udev = udev_new();
|
||
if (!udev) {
|
||
printf("[udev-monitor-thread] Can't create udev\n");
|
||
goto error;
|
||
}
|
||
/* Set up a monitor to monitor the misc devices */
|
||
mon = udev_monitor_new_from_netlink(udev, "udev");
|
||
udev_monitor_filter_add_match_subsystem_devtype(mon, "misc", NULL);
|
||
udev_monitor_enable_receiving(mon);
|
||
/* Get the file descriptor (fd) for the monitor.
|
||
This fd will get passed to select() */
|
||
fd = udev_monitor_get_fd(mon);
|
||
health_code_update();
|
||
/* This section will run continuously, calling usleep() at
|
||
the end of each pass. This is to demonstrate how to use
|
||
a udev_monitor in a non-blocking way. */
|
||
while (1) {
|
||
/* Set up the call to select(). In this case, select() will
|
||
only operate on a single file descriptor, the one
|
||
associated with our udev_monitor. Note that the timeval
|
||
object is set to 0, which will cause select() to not
|
||
block. */
|
||
fd_set fds;
|
||
struct timeval tv;
|
||
// TODO See if thread needs to be killed
|
||
FD_ZERO(&fds);
|
||
FD_SET(fd, &fds);
|
||
tv.tv_sec = 0;
|
||
tv.tv_usec = 0;
|
||
ret = select(fd+1, &fds, NULL, NULL, &tv);
|
||
/* Check if our file descriptor has received data. */
|
||
if (ret > 0 && FD_ISSET(fd, &fds)) {
|
||
DBG3("[udev-monitor-thread] Received events from udev");
|
||
/* Make the call to receive the device.
|
||
select() ensured that this will not block. */
|
||
dev = udev_monitor_receive_device(mon);
|
||
if (dev) {
|
||
node = udev_device_get_devnode(dev);
|
||
if (!strcmp(KVM_NODE, node)) {
|
||
DBG3("[udev-monitor-thread] Received events from udev for kvm node");
|
||
// doTraceKvmEvent(dev);
|
||
}
|
||
udev_device_unref(dev);
|
||
}
|
||
health_code_update();
|
||
}
|
||
usleep(250*1000);
|
||
}
|
||
error:
|
||
// utils_close_pipe(apps_cmd_notify_pipe);
|
||
// apps_cmd_notify_pipe[0] = apps_cmd_notify_pipe[1] = -1;
|
||
DBG("[udev-monitor-thread] Udev monitoring thread cleanup complete");
|
||
if (err) {
|
||
health_error();
|
||
ERR("[udev-monitor-thread] Health error occurred in %s", __func__);
|
||
}
|
||
health_unregister(health_sessiond);
|
||
rcu_thread_offline();
|
||
rcu_unregister_thread();
|
||
return NULL;
|
||
}
|
src/bin/lttng-sessiond/udev-monitor.h | ||
---|---|---|
/*
|
||
* Copyright (C) 2018 - Geneviève Bastien <gbastien@versatic.net>
|
||
*
|
||
* This program is free software; you can redistribute it and/or modify it
|
||
* under the terms of the GNU General Public License, version 2 only, as
|
||
* published by the Free Software Foundation.
|
||
*
|
||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
* more details.
|
||
*
|
||
* You should have received a copy of the GNU General Public License along with
|
||
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||
*/
|
||
#ifndef UDEV_MONITOR_H
|
||
#define UDEV_MONITOR_H
|
||
#ifdef HAVE_LIBLTTNG_UST_CTL
|
||
void *ust_thread_monitor_udev(void *data);
|
||
#else /* HAVE_LIBLTTNG_UST_CTL */
|
||
void *ust_thread_monitor_udev(void *data)
|
||
{
|
||
return NULL;
|
||
}
|
||
#endif /* HAVE_LIBLTTNG_UST_CTL */
|
||
#endif /* UDEV_MONITOR_H */
|