mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
xrt: Add u_process, backed by libbsd's pidfile
Delete stale ipc files in ipc server when not already running. If built without libbsd, fall back to previous behavior of complaining about existing ipc files and exit.
This commit is contained in:
parent
c92bc0a704
commit
4ea68b89a4
|
@ -107,6 +107,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|||
endif()
|
||||
find_package(OpenGL COMPONENTS GLX)
|
||||
pkg_search_module(DBUS dbus-1)
|
||||
pkg_search_module(LIBBSD libbsd)
|
||||
|
||||
pkg_check_modules(GST
|
||||
gstreamer-1.0
|
||||
|
@ -143,6 +144,7 @@ cmake_dependent_option(XRT_HAVE_OPENGLES "Enable OpenGL-ES Graphics API support"
|
|||
cmake_dependent_option(XRT_HAVE_EGL "Enable OpenGL on EGL Graphics API support" ON "EGL_FOUND; XRT_HAVE_OPENGL OR XRT_HAVE_OPENGLES" OFF)
|
||||
cmake_dependent_option(XRT_HAVE_DBUS "Enable dbus support (for BLE support)" ON "DBUS_FOUND" OFF)
|
||||
cmake_dependent_option(XRT_FEATURE_COMPOSITOR_MAIN "Build main compositor host functionality" ON "XRT_HAVE_VULKAN; XRT_HAVE_WAYLAND OR XRT_HAVE_XCB OR ANDROID OR WIN32" OFF)
|
||||
cmake_dependent_option(XRT_HAVE_LIBBSD "Enable libbsd support" ON "LIBBSD_FOUND" OFF)
|
||||
cmake_dependent_option(XRT_FEATURE_OPENXR "Build OpenXR runtime target" ON "XRT_FEATURE_COMPOSITOR_MAIN" OFF)
|
||||
cmake_dependent_option(XRT_FEATURE_SERVICE "Enable separate service module for OpenXR runtime" ON "NOT WIN32 AND XRT_FEATURE_OPENXR" OFF)
|
||||
cmake_dependent_option(XRT_HAVE_SYSTEMD "Enable systemd support (for socket activation of service)" ON "Systemd_FOUND AND XRT_FEATURE_SERVICE" OFF)
|
||||
|
@ -335,6 +337,7 @@ message(STATUS "# OPENGLES: ${XRT_HAVE_OPENGLES}")
|
|||
message(STATUS "# EGL: ${XRT_HAVE_EGL}")
|
||||
message(STATUS "# DBUS: ${XRT_HAVE_DBUS}")
|
||||
message(STATUS "# VF: ${XRT_HAVE_VF}")
|
||||
message(STATUS "# LIBBSD: ${XRT_HAVE_LIBBSD}")
|
||||
message(STATUS "# SYSTEMD: ${XRT_HAVE_SYSTEMD}")
|
||||
message(STATUS "# LIBUSB: ${XRT_HAVE_LIBUSB}")
|
||||
message(STATUS "# JPEG: ${XRT_HAVE_JPEG}")
|
||||
|
|
|
@ -72,6 +72,7 @@ zlib = dependency('zlib', required: false)
|
|||
survive = dependency('survive', required: false)
|
||||
dbus = dependency('dbus-1', required: get_option('dbus'))
|
||||
systemd = dependency('libsystemd', required: get_option('systemd'))
|
||||
libbsd = dependency('libbsd', required: get_option('libbsd'))
|
||||
gst = dependency('gstreamer-1.0', required: false)
|
||||
gst_app = dependency('gstreamer-app-1.0', required: false)
|
||||
gst_video= dependency('gstreamer-video-1.0', required: false)
|
||||
|
@ -335,3 +336,9 @@ if not get_option('dbus').disabled() and dbus.found()
|
|||
else
|
||||
message(' dbus: no')
|
||||
endif
|
||||
|
||||
if not get_option('libbsd').disabled() and libbsd.found()
|
||||
message(' libbsd: yes')
|
||||
else
|
||||
message(' libbsd: no')
|
||||
endif
|
||||
|
|
|
@ -77,6 +77,11 @@ option('dbus',
|
|||
value: 'auto',
|
||||
description: 'Enable support for dbus.')
|
||||
|
||||
option('libbsd',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
description: 'Enable support for libbsd.')
|
||||
|
||||
option('systemd',
|
||||
type: 'feature',
|
||||
value: 'auto',
|
||||
|
|
|
@ -159,6 +159,8 @@ set(UTIL_SOURCE_FILES
|
|||
util/u_config_json.c
|
||||
util/u_config_json.h
|
||||
util/u_verify.h
|
||||
util/u_process.c
|
||||
util/u_process.h
|
||||
)
|
||||
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/util/u_git_tag.c.in" "${CMAKE_CURRENT_BINARY_DIR}/u_git_tag.c" @ONLY)
|
||||
|
@ -225,6 +227,10 @@ if(XRT_HAVE_SYSTEM_CJSON)
|
|||
else()
|
||||
target_link_libraries(aux_util PUBLIC xrt-external-cjson)
|
||||
endif()
|
||||
if(XRT_HAVE_LIBBSD)
|
||||
target_include_directories(aux_util SYSTEM PRIVATE ${LIBBSD_INCLUDE_DIRS})
|
||||
target_link_libraries(aux_util PUBLIC ${LIBBSD_LIBRARIES})
|
||||
endif()
|
||||
if(ANDROID)
|
||||
target_link_libraries(aux_util PUBLIC ${ANDROID_LOG_LIBRARY})
|
||||
endif()
|
||||
|
|
|
@ -11,6 +11,11 @@ u_git_tag_c = vcs_tag(
|
|||
replace_string: '@GIT_DESC@',
|
||||
)
|
||||
|
||||
aux_util_deps = [ xrt_config_have ]
|
||||
if libbsd.found() and not get_option('libbsd').disabled()
|
||||
aux_util_deps += libbsd
|
||||
endif
|
||||
|
||||
lib_aux_util = static_library(
|
||||
'aux_util',
|
||||
files(
|
||||
|
@ -65,6 +70,8 @@ lib_aux_util = static_library(
|
|||
'util/u_config_json.c',
|
||||
'util/u_config_json.h',
|
||||
'util/u_verify.h',
|
||||
'util/u_process.c',
|
||||
'util/u_process.h',
|
||||
) + [
|
||||
u_git_tag_c,
|
||||
],
|
||||
|
@ -73,6 +80,7 @@ lib_aux_util = static_library(
|
|||
cjson_include,
|
||||
],
|
||||
dependencies: [
|
||||
aux_util_deps,
|
||||
xrt_config_have,
|
||||
]
|
||||
)
|
||||
|
|
105
src/xrt/auxiliary/util/u_process.c
Normal file
105
src/xrt/auxiliary/util/u_process.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
|
||||
// Copyright 2019-2020, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Simple process handling
|
||||
* @author Christoph Haag <christoph.haag@collabora.com>
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
|
||||
#include "xrt/xrt_config.h"
|
||||
|
||||
#ifdef XRT_OS_LINUX
|
||||
|
||||
#define PID_FILE_NAME "monado.pid"
|
||||
|
||||
#ifdef XRT_HAVE_LIBBSD
|
||||
#include <bsd/libutil.h>
|
||||
#endif
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include "u_misc.h"
|
||||
#include "u_file.h"
|
||||
#include "u_logging.h"
|
||||
|
||||
struct u_process
|
||||
{
|
||||
#ifdef XRT_HAVE_LIBBSD
|
||||
struct pidfh *pfh;
|
||||
#else
|
||||
int pid;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline int
|
||||
get_pidfile_path(char *buf)
|
||||
{
|
||||
int size = u_file_get_path_in_runtime_dir(PID_FILE_NAME, buf, PATH_MAX);
|
||||
if (size == -1) {
|
||||
U_LOG_W("Failed to determine runtime dir, not creating pidfile");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct u_process *
|
||||
u_process_create_if_not_running()
|
||||
{
|
||||
#ifdef XRT_HAVE_LIBBSD
|
||||
|
||||
char tmp[PATH_MAX];
|
||||
if (get_pidfile_path(tmp) < 0) {
|
||||
U_LOG_W("Failed to determine runtime dir, not creating pidfile");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U_LOG_T("Using pidfile %s", tmp);
|
||||
|
||||
pid_t otherpid;
|
||||
|
||||
struct pidfh *pfh = pidfile_open(tmp, 0600, &otherpid);
|
||||
if (errno == EEXIST || pfh == NULL) {
|
||||
U_LOG_T("Failed to create pidfile (%s): Another Monado instance may be running", strerror(errno));
|
||||
// other process is locking pid file
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// either new or stale pidfile opened
|
||||
|
||||
int write_ret = pidfile_write(pfh);
|
||||
if (write_ret != 0) {
|
||||
pidfile_close(pfh);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct u_process *ret = U_TYPED_CALLOC(struct u_process);
|
||||
ret->pfh = pfh;
|
||||
|
||||
U_LOG_T("No other Monado instance was running, got new pidfile");
|
||||
return ret;
|
||||
#else
|
||||
struct u_process *ret = U_TYPED_CALLOC(struct u_process);
|
||||
//! @todo alternative implementation
|
||||
ret->pid = 0;
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
u_process_destroy(struct u_process *proc)
|
||||
{
|
||||
if (proc == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef XRT_HAVE_LIBBSD
|
||||
pidfile_close(proc->pfh);
|
||||
#endif
|
||||
free(proc);
|
||||
}
|
||||
|
||||
#endif
|
42
src/xrt/auxiliary/util/u_process.h
Normal file
42
src/xrt/auxiliary/util/u_process.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2020, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Simple process handling
|
||||
* @author Christoph Haag <christoph.haag@collabora.com>
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct u_process;
|
||||
|
||||
/*!
|
||||
* Creates a handle for this process that is unique to the operating system user. Returns NULL if another process
|
||||
* holding a handle is already running.
|
||||
*
|
||||
* @todo If built without libbsd support, a dummy value is returned that needs to be handled by the caller.
|
||||
*
|
||||
* @return a new u_process handle if no monado instance is running, NULL if another instance is already running.
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
struct u_process *
|
||||
u_process_create_if_not_running();
|
||||
|
||||
/*!
|
||||
* Releases the unique handle of the operating system user.
|
||||
*
|
||||
* @ingroup aux_util
|
||||
*/
|
||||
void
|
||||
u_process_destroy(struct u_process *proc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -100,6 +100,10 @@ if get_option('layer_equirect2')
|
|||
have_conf.set('XRT_FEATURE_OPENXR_LAYER_EQUIRECT2', true)
|
||||
endif
|
||||
|
||||
if libbsd.found() and not get_option('libbsd').disabled()
|
||||
have_conf.set('XRT_HAVE_LIBBSD', true)
|
||||
endif
|
||||
|
||||
xrt_config_have_h = configure_file(
|
||||
output: 'xrt_config_have.h',
|
||||
configuration: have_conf,
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#pragma once
|
||||
|
||||
#cmakedefine XRT_HAVE_DBUS
|
||||
#cmakedefine XRT_HAVE_LIBBSD
|
||||
#cmakedefine XRT_HAVE_EGL
|
||||
#cmakedefine XRT_HAVE_FFMPEG
|
||||
#cmakedefine XRT_HAVE_GST
|
||||
|
|
|
@ -268,6 +268,9 @@ struct ipc_server
|
|||
{
|
||||
struct xrt_instance *xinst;
|
||||
|
||||
//! Handle for the current process, e.g. pidfile on linux
|
||||
struct u_process *process;
|
||||
|
||||
/* ---- HACK ---- */
|
||||
void *hack;
|
||||
/* ---- HACK ---- */
|
||||
|
|
|
@ -88,15 +88,26 @@ create_listen_socket(struct ipc_server_mainloop *ml, int *out_fd)
|
|||
strcpy(addr.sun_path, IPC_MSG_SOCK_FILE);
|
||||
|
||||
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
|
||||
#ifdef XRT_HAVE_LIBBSD
|
||||
// no other instance is running, or we would have never arrived here
|
||||
if (ret < 0 && errno == EADDRINUSE) {
|
||||
U_LOG_W("Removing stale socket file %s", IPC_MSG_SOCK_FILE);
|
||||
|
||||
ret = unlink(IPC_MSG_SOCK_FILE);
|
||||
if (ret < 0) {
|
||||
U_LOG_E("Failed to remove stale socket file %s: %s", IPC_MSG_SOCK_FILE, strerror(errno));
|
||||
return ret;
|
||||
}
|
||||
ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
U_LOG_E(
|
||||
"Could not bind socket to path %s: is the "
|
||||
"service running already?",
|
||||
IPC_MSG_SOCK_FILE);
|
||||
U_LOG_E("Could not bind socket to path %s: %s. Is the service running already?", IPC_MSG_SOCK_FILE,
|
||||
strerror(errno));
|
||||
#ifdef XRT_HAVE_SYSTEMD
|
||||
U_LOG_E(
|
||||
"Or, is the systemd unit monado.socket or "
|
||||
"monado-dev.socket active?");
|
||||
U_LOG_E("Or, is the systemd unit monado.socket or monado-dev.socket active?");
|
||||
#endif
|
||||
if (errno == EADDRINUSE) {
|
||||
U_LOG_E("If monado-service is not running, delete %s before starting a new instance",
|
||||
|
@ -113,7 +124,7 @@ create_listen_socket(struct ipc_server_mainloop *ml, int *out_fd)
|
|||
close(fd);
|
||||
return ret;
|
||||
}
|
||||
U_LOG_D("Created listening socket.");
|
||||
U_LOG_D("Created listening socket %s.", IPC_MSG_SOCK_FILE);
|
||||
*out_fd = fd;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "util/u_debug.h"
|
||||
#include "util/u_trace_marker.h"
|
||||
#include "util/u_verify.h"
|
||||
#include "util/u_process.h"
|
||||
|
||||
#include "shared/ipc_shmem.h"
|
||||
#include "server/ipc_server.h"
|
||||
|
@ -109,6 +110,7 @@ teardown_all(struct ipc_server *s)
|
|||
ipc_server_mainloop_deinit(&s->ml);
|
||||
|
||||
os_mutex_destroy(&s->global_state.lock);
|
||||
u_process_destroy(s->process);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -394,6 +396,14 @@ ipc_server_start_client_listener_thread(struct ipc_server *vs, int fd)
|
|||
static int
|
||||
init_all(struct ipc_server *s)
|
||||
{
|
||||
s->process = u_process_create_if_not_running();
|
||||
|
||||
if (!s->process) {
|
||||
U_LOG_E("monado-service is already running! Use XRT_LOG=trace for more information.");
|
||||
teardown_all(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Yes we should be running.
|
||||
s->running = true;
|
||||
s->exit_on_disconnect = debug_get_bool_option_exit_on_disconnect();
|
||||
|
|
Loading…
Reference in a new issue