Project

General

Profile

Bug #1156 » 0001-Add-thread-to-monitor-udev.patch

faulty patch - Geneviève Bastien, 02/26/2018 02:55 PM

View differences:

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 */
    (1-1/1)