mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-11 05:17:44 +03:00
commit
0891c5ed0b
@ -26,6 +26,7 @@
|
|||||||
#include "sd-hwdb.h"
|
#include "sd-hwdb.h"
|
||||||
|
|
||||||
#include "hwdb-util.h"
|
#include "hwdb-util.h"
|
||||||
|
#include "udev-util.h"
|
||||||
|
|
||||||
static sd_hwdb *hwdb;
|
static sd_hwdb *hwdb;
|
||||||
|
|
||||||
@ -87,6 +88,9 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device
|
|||||||
|
|
||||||
assert(dev);
|
assert(dev);
|
||||||
|
|
||||||
|
if (!srcdev)
|
||||||
|
srcdev = dev;
|
||||||
|
|
||||||
for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
|
for (d = srcdev; d && !last; d = udev_device_get_parent(d)) {
|
||||||
const char *dsubsys;
|
const char *dsubsys;
|
||||||
const char *modalias = NULL;
|
const char *modalias = NULL;
|
||||||
@ -133,7 +137,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te
|
|||||||
const char *device = NULL;
|
const char *device = NULL;
|
||||||
const char *subsystem = NULL;
|
const char *subsystem = NULL;
|
||||||
const char *prefix = NULL;
|
const char *prefix = NULL;
|
||||||
struct udev_device *srcdev;
|
_cleanup_udev_device_unref_ struct udev_device *srcdev = NULL;
|
||||||
|
|
||||||
if (!hwdb)
|
if (!hwdb)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@ -176,8 +180,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te
|
|||||||
srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device);
|
srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device);
|
||||||
if (!srcdev)
|
if (!srcdev)
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
} else
|
}
|
||||||
srcdev = dev;
|
|
||||||
|
|
||||||
if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0)
|
if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0)
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -389,26 +389,44 @@ static int spawn_exec(struct udev_event *event,
|
|||||||
const char *cmd, char *const argv[], char **envp,
|
const char *cmd, char *const argv[], char **envp,
|
||||||
int fd_stdout, int fd_stderr) {
|
int fd_stdout, int fd_stderr) {
|
||||||
_cleanup_close_ int fd = -1;
|
_cleanup_close_ int fd = -1;
|
||||||
|
int r;
|
||||||
|
|
||||||
/* discard child output or connect to pipe */
|
/* discard child output or connect to pipe */
|
||||||
fd = open("/dev/null", O_RDWR);
|
fd = open("/dev/null", O_RDWR);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
dup2(fd, STDIN_FILENO);
|
r = dup2(fd, STDIN_FILENO);
|
||||||
if (fd_stdout < 0)
|
if (r < 0)
|
||||||
dup2(fd, STDOUT_FILENO);
|
log_warning_errno(errno, "redirecting stdin failed: %m");
|
||||||
if (fd_stderr < 0)
|
|
||||||
dup2(fd, STDERR_FILENO);
|
if (fd_stdout < 0) {
|
||||||
|
r = dup2(fd, STDOUT_FILENO);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(errno, "redirecting stdout failed: %m");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fd_stderr < 0) {
|
||||||
|
r = dup2(fd, STDERR_FILENO);
|
||||||
|
if (r < 0)
|
||||||
|
log_warning_errno(errno, "redirecting stderr failed: %m");
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
log_error_errno(errno, "open /dev/null failed: %m");
|
log_warning_errno(errno, "open /dev/null failed: %m");
|
||||||
|
|
||||||
/* connect pipes to std{out,err} */
|
/* connect pipes to std{out,err} */
|
||||||
if (fd_stdout >= 0) {
|
if (fd_stdout >= 0) {
|
||||||
dup2(fd_stdout, STDOUT_FILENO);
|
r = dup2(fd_stdout, STDOUT_FILENO);
|
||||||
safe_close(fd_stdout);
|
if (r < 0)
|
||||||
|
log_warning_errno(errno, "redirecting stdout failed: %m");
|
||||||
|
|
||||||
|
fd_stdout = safe_close(fd_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd_stderr >= 0) {
|
if (fd_stderr >= 0) {
|
||||||
dup2(fd_stderr, STDERR_FILENO);
|
r = dup2(fd_stderr, STDERR_FILENO);
|
||||||
safe_close(fd_stderr);
|
if (r < 0)
|
||||||
|
log_warning_errno(errno, "redirecting stdout failed: %m");
|
||||||
|
|
||||||
|
fd_stderr = safe_close(fd_stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* terminate child in case parent goes away */
|
/* terminate child in case parent goes away */
|
||||||
|
@ -116,7 +116,7 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
|||||||
} device_type = TYPE_DEVICES;
|
} device_type = TYPE_DEVICES;
|
||||||
const char *action = "change";
|
const char *action = "change";
|
||||||
_cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate = NULL;
|
_cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate = NULL;
|
||||||
int c;
|
int c, r;
|
||||||
|
|
||||||
udev_enumerate = udev_enumerate_new(udev);
|
udev_enumerate = udev_enumerate_new(udev);
|
||||||
if (udev_enumerate == NULL)
|
if (udev_enumerate == NULL)
|
||||||
@ -153,28 +153,56 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
udev_enumerate_add_match_subsystem(udev_enumerate, optarg);
|
r = udev_enumerate_add_match_subsystem(udev_enumerate, optarg);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add subsystem match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg);
|
r = udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add negative subsystem match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'a':
|
case 'a':
|
||||||
key = keyval(optarg, &val, buf, sizeof(buf));
|
key = keyval(optarg, &val, buf, sizeof(buf));
|
||||||
udev_enumerate_add_match_sysattr(udev_enumerate, key, val);
|
r = udev_enumerate_add_match_sysattr(udev_enumerate, key, val);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add sysattr match '%s=%s': %m", key, val);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'A':
|
case 'A':
|
||||||
key = keyval(optarg, &val, buf, sizeof(buf));
|
key = keyval(optarg, &val, buf, sizeof(buf));
|
||||||
udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val);
|
r = udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add negative sysattr match '%s=%s': %m", key, val);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
key = keyval(optarg, &val, buf, sizeof(buf));
|
key = keyval(optarg, &val, buf, sizeof(buf));
|
||||||
udev_enumerate_add_match_property(udev_enumerate, key, val);
|
r = udev_enumerate_add_match_property(udev_enumerate, key, val);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add property match '%s=%s': %m", key, val);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
udev_enumerate_add_match_tag(udev_enumerate, optarg);
|
r = udev_enumerate_add_match_tag(udev_enumerate, optarg);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add tag match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'y':
|
case 'y':
|
||||||
udev_enumerate_add_match_sysname(udev_enumerate, optarg);
|
r = udev_enumerate_add_match_sysname(udev_enumerate, optarg);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add sysname match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'b': {
|
case 'b': {
|
||||||
_cleanup_udev_device_unref_ struct udev_device *dev;
|
_cleanup_udev_device_unref_ struct udev_device *dev;
|
||||||
@ -185,7 +213,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_enumerate_add_match_parent(udev_enumerate, dev);
|
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add parent match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +230,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_enumerate_add_match_parent(udev_enumerate, dev);
|
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add parent match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +257,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) {
|
|||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
udev_enumerate_add_match_parent(udev_enumerate, dev);
|
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error_errno(r, "could not add tag match '%s': %m", optarg);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (device_type) {
|
switch (device_type) {
|
||||||
|
@ -327,6 +327,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
|
|||||||
struct udev *udev = event->udev;
|
struct udev *udev = event->udev;
|
||||||
_cleanup_udev_monitor_unref_ struct udev_monitor *worker_monitor = NULL;
|
_cleanup_udev_monitor_unref_ struct udev_monitor *worker_monitor = NULL;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
int r = 0;
|
||||||
|
|
||||||
/* listen for new events */
|
/* listen for new events */
|
||||||
worker_monitor = udev_monitor_new_from_netlink(udev, NULL);
|
worker_monitor = udev_monitor_new_from_netlink(udev, NULL);
|
||||||
@ -334,7 +335,9 @@ static void worker_spawn(Manager *manager, struct event *event) {
|
|||||||
return;
|
return;
|
||||||
/* allow the main daemon netlink address to send devices to the worker */
|
/* allow the main daemon netlink address to send devices to the worker */
|
||||||
udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
|
udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor);
|
||||||
udev_monitor_enable_receiving(worker_monitor);
|
r = udev_monitor_enable_receiving(worker_monitor);
|
||||||
|
if (r < 0)
|
||||||
|
log_error_errno(r, "worker: could not enable receiving of device: %m");
|
||||||
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
@ -346,7 +349,6 @@ static void worker_spawn(Manager *manager, struct event *event) {
|
|||||||
struct epoll_event ep_signal = { .events = EPOLLIN };
|
struct epoll_event ep_signal = { .events = EPOLLIN };
|
||||||
struct epoll_event ep_monitor = { .events = EPOLLIN };
|
struct epoll_event ep_monitor = { .events = EPOLLIN };
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
/* take initial device from queue */
|
/* take initial device from queue */
|
||||||
dev = event->dev;
|
dev = event->dev;
|
||||||
@ -528,7 +530,6 @@ out:
|
|||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
struct worker *worker;
|
struct worker *worker;
|
||||||
int r;
|
|
||||||
|
|
||||||
r = worker_new(&worker, manager, worker_monitor, pid);
|
r = worker_new(&worker, manager, worker_monitor, pid);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user