summaryrefslogtreecommitdiff
path: root/src/udev
diff options
context:
space:
mode:
Diffstat (limited to 'src/udev')
-rw-r--r--src/udev/.gitignore1
-rw-r--r--src/udev/ata_id/ata_id.c47
-rw-r--r--src/udev/cdrom_id/cdrom_id.c32
-rw-r--r--src/udev/collect/collect.c11
-rw-r--r--src/udev/mtd_probe/mtd_probe.c8
-rw-r--r--src/udev/mtd_probe/mtd_probe.h4
-rw-r--r--src/udev/mtd_probe/probe_smartmedia.c11
-rw-r--r--src/udev/net/ethtool-util.c136
-rw-r--r--src/udev/net/ethtool-util.h15
-rw-r--r--src/udev/net/link-config-gperf.gperf43
-rw-r--r--src/udev/net/link-config.c59
-rw-r--r--src/udev/net/link-config.h9
-rw-r--r--src/udev/scsi_id/scsi.h66
-rw-r--r--src/udev/scsi_id/scsi_id.c34
-rw-r--r--src/udev/scsi_id/scsi_id.h4
-rw-r--r--src/udev/scsi_id/scsi_serial.c108
-rw-r--r--src/udev/udev-builtin-blkid.c21
-rw-r--r--src/udev/udev-builtin-btrfs.c4
-rw-r--r--src/udev/udev-builtin-hwdb.c10
-rw-r--r--src/udev/udev-builtin-input_id.c32
-rw-r--r--src/udev/udev-builtin-keyboard.c9
-rw-r--r--src/udev/udev-builtin-kmod.c7
-rw-r--r--src/udev/udev-builtin-net_id.c91
-rw-r--r--src/udev/udev-builtin-net_setup_link.c5
-rw-r--r--src/udev/udev-builtin-path_id.c158
-rw-r--r--src/udev/udev-builtin-uaccess.c12
-rw-r--r--src/udev/udev-builtin-usb_id.c13
-rw-r--r--src/udev/udev-builtin.c23
-rw-r--r--src/udev/udev-ctrl.c34
-rw-r--r--src/udev/udev-event.c66
-rw-r--r--src/udev/udev-node.c40
-rw-r--r--src/udev/udev-rules.c701
-rw-r--r--src/udev/udev-watch.c18
-rw-r--r--src/udev/udev.h22
-rw-r--r--src/udev/udevadm-control.c35
-rw-r--r--src/udev/udevadm-hwdb.c25
-rw-r--r--src/udev/udevadm-info.c88
-rw-r--r--src/udev/udevadm-monitor.c24
-rw-r--r--src/udev/udevadm-settle.c18
-rw-r--r--src/udev/udevadm-test-builtin.c7
-rw-r--r--src/udev/udevadm-test.c15
-rw-r--r--src/udev/udevadm-trigger.c11
-rw-r--r--src/udev/udevadm-util.c1
-rw-r--r--src/udev/udevadm-util.h4
-rw-r--r--src/udev/udevadm.c8
-rw-r--r--src/udev/udevd.c138
-rw-r--r--src/udev/v4l_id/v4l_id.c15
47 files changed, 1192 insertions, 1051 deletions
diff --git a/src/udev/.gitignore b/src/udev/.gitignore
index ba112ce218..f5d8be3dc1 100644
--- a/src/udev/.gitignore
+++ b/src/udev/.gitignore
@@ -1,5 +1,4 @@
/udev.pc
/keyboard-keys-from-name.gperf
/keyboard-keys-from-name.h
-/keyboard-keys-to-name.h
/keyboard-keys-list.txt
diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c
index 7ba0b7fc8f..1e414664ce 100644
--- a/src/udev/ata_id/ata_id.c
+++ b/src/udev/ata_id/ata_id.c
@@ -19,28 +19,30 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
#include <ctype.h>
-#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
+#include <linux/bsg.h>
+#include <linux/hdreg.h>
#include <scsi/scsi.h>
-#include <scsi/sg.h>
#include <scsi/scsi_ioctl.h>
+#include <scsi/sg.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/ioctl.h>
-#include <sys/types.h>
#include <sys/stat.h>
-#include <linux/hdreg.h>
-#include <linux/bsg.h>
+#include <sys/types.h>
+#include <unistd.h>
#include "libudev.h"
+
+#include "fd-util.h"
#include "libudev-private.h"
-#include "udev-util.h"
#include "log.h"
+#include "udev-util.h"
#define COMMAND_TIMEOUT_MSEC (30 * 1000)
@@ -409,7 +411,6 @@ int main(int argc, char *argv[])
union {
uint8_t byte[512];
uint16_t wyde[256];
- uint64_t octa[64];
} identify;
char model[41];
char model_enc[256];
@@ -433,7 +434,7 @@ int main(int argc, char *argv[])
if (udev == NULL)
return 0;
- while (1) {
+ for (;;) {
int option;
option = getopt_long(argc, argv, "xh", options, NULL);
@@ -474,7 +475,7 @@ int main(int argc, char *argv[])
disk_identify_fixup_string(identify.byte, 27, 40); /* model */
disk_identify_fixup_uint16(identify.byte, 0); /* configuration */
disk_identify_fixup_uint16(identify.byte, 75); /* queue depth */
- disk_identify_fixup_uint16(identify.byte, 75); /* SATA capabilities */
+ disk_identify_fixup_uint16(identify.byte, 76); /* SATA capabilities */
disk_identify_fixup_uint16(identify.byte, 82); /* command set supported */
disk_identify_fixup_uint16(identify.byte, 83); /* command set supported */
disk_identify_fixup_uint16(identify.byte, 84); /* command set supported */
@@ -485,6 +486,10 @@ int main(int argc, char *argv[])
disk_identify_fixup_uint16(identify.byte, 90); /* time required for enhanced SECURITY ERASE UNIT */
disk_identify_fixup_uint16(identify.byte, 91); /* current APM values */
disk_identify_fixup_uint16(identify.byte, 94); /* current AAM value */
+ disk_identify_fixup_uint16(identify.byte, 108); /* WWN */
+ disk_identify_fixup_uint16(identify.byte, 109); /* WWN */
+ disk_identify_fixup_uint16(identify.byte, 110); /* WWN */
+ disk_identify_fixup_uint16(identify.byte, 111); /* WWN */
disk_identify_fixup_uint16(identify.byte, 128); /* device lock function */
disk_identify_fixup_uint16(identify.byte, 217); /* nominal media rotation rate */
memcpy(&id, identify.byte, sizeof id);
@@ -638,10 +643,20 @@ int main(int argc, char *argv[])
* All other values are reserved.
*/
word = identify.wyde[108];
- if ((word & 0xf000) == 0x5000)
+ if ((word & 0xf000) == 0x5000) {
+ uint64_t wwwn;
+
+ wwwn = identify.wyde[108];
+ wwwn <<= 16;
+ wwwn |= identify.wyde[109];
+ wwwn <<= 16;
+ wwwn |= identify.wyde[110];
+ wwwn <<= 16;
+ wwwn |= identify.wyde[111];
printf("ID_WWN=0x%1$" PRIx64 "\n"
"ID_WWN_WITH_EXTENSION=0x%1$" PRIx64 "\n",
- identify.octa[108/4]);
+ wwwn);
+ }
/* from Linux's include/linux/ata.h */
if (identify.wyde[0] == 0x848a ||
diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c
index 3d74ae50f1..72f284f710 100644
--- a/src/udev/cdrom_id/cdrom_id.c
+++ b/src/udev/cdrom_id/cdrom_id.c
@@ -17,24 +17,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <limits.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
-#include <time.h>
+#include <limits.h>
+#include <linux/cdrom.h>
#include <scsi/sg.h>
-#include <sys/types.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/time.h>
-#include <sys/ioctl.h>
-#include <linux/cdrom.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
#include "libudev.h"
+
#include "libudev-private.h"
#include "random-util.h"
@@ -106,11 +107,11 @@ static bool is_mounted(const char *device)
bool mounted = false;
if (stat(device, &statbuf) < 0)
- return -ENODEV;
+ return false;
fp = fopen("/proc/self/mountinfo", "re");
if (fp == NULL)
- return -ENOSYS;
+ return false;
while (fscanf(fp, "%*s %*s %i:%i %*[^\n]", &maj, &min) == 2) {
if (makedev(maj, min) == statbuf.st_rdev) {
mounted = true;
@@ -565,9 +566,8 @@ static int cd_profiles(struct udev *udev, int fd)
if (len > sizeof(features)) {
log_debug("can not get features in a single query, truncating");
len = sizeof(features);
- } else if (len <= 8) {
+ } else if (len <= 8)
len = sizeof(features);
- }
/* Now get the full feature buffer */
scsi_cmd_init(udev, &sc);
@@ -869,7 +869,7 @@ int main(int argc, char *argv[])
if (udev == NULL)
goto exit;
- while (1) {
+ for (;;) {
int option;
option = getopt_long(argc, argv, "deluh", options, NULL);
diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c
index 6cf41c67bb..349585b634 100644
--- a/src/udev/collect/collect.c
+++ b/src/udev/collect/collect.c
@@ -19,13 +19,16 @@
*
*/
-#include <stdio.h>
-#include <stddef.h>
#include <errno.h>
#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include "alloc-util.h"
#include "libudev-private.h"
#include "macro.h"
+#include "stdio-util.h"
+#include "string-util.h"
#define BUFSIZE 16
#define UDEV_ALARM_TIMEOUT 180
@@ -89,7 +92,7 @@ static int prepare(char *dir, char *filename)
if (r < 0 && errno != EEXIST)
return -errno;
- snprintf(buf, sizeof(buf), "%s/%s", dir, filename);
+ xsprintf(buf, "%s/%s", dir, filename);
fd = open(buf,O_RDWR|O_CREAT|O_CLOEXEC, S_IRUSR|S_IWUSR);
if (fd < 0)
@@ -364,7 +367,7 @@ int main(int argc, char **argv)
goto exit;
}
- while (1) {
+ for (;;) {
int option;
option = getopt_long(argc, argv, "ardh", options, NULL);
diff --git a/src/udev/mtd_probe/mtd_probe.c b/src/udev/mtd_probe/mtd_probe.c
index 67b750c4b3..462fab7623 100644
--- a/src/udev/mtd_probe/mtd_probe.c
+++ b/src/udev/mtd_probe/mtd_probe.c
@@ -17,14 +17,14 @@
* Boston, MA 02110-1301 USA
*/
+#include <fcntl.h>
+#include <mtd/mtd-user.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/ioctl.h>
-#include <mtd/mtd-user.h>
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <stdlib.h>
#include "mtd_probe.h"
diff --git a/src/udev/mtd_probe/mtd_probe.h b/src/udev/mtd_probe/mtd_probe.h
index caea5c2693..68e4954537 100644
--- a/src/udev/mtd_probe/mtd_probe.h
+++ b/src/udev/mtd_probe/mtd_probe.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2010 - Maxim Levitsky
*
@@ -17,8 +19,6 @@
* Boston, MA 02110-1301 USA
*/
-#pragma once
-
#include <mtd/mtd-user.h>
#include "macro.h"
diff --git a/src/udev/mtd_probe/probe_smartmedia.c b/src/udev/mtd_probe/probe_smartmedia.c
index a007ccee2f..2a7ba17637 100644
--- a/src/udev/mtd_probe/probe_smartmedia.c
+++ b/src/udev/mtd_probe/probe_smartmedia.c
@@ -17,15 +17,16 @@
* Boston, MA 02110-1301 USA
*/
+#include <fcntl.h>
+#include <mtd/mtd-user.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include <mtd/mtd-user.h>
#include <string.h>
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <stdint.h>
+
#include "mtd_probe.h"
static const uint8_t cis_signature[] = {
@@ -72,7 +73,7 @@ void probe_smart_media(int mtd_fd, mtd_info_t* info)
for (offset = 0 ; offset < block_size * spare_count ;
offset += sector_size) {
lseek(mtd_fd, SEEK_SET, offset);
- if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE){
+ if (read(mtd_fd, cis_buffer, SM_SECTOR_SIZE) == SM_SECTOR_SIZE) {
cis_found = 1;
break;
}
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index 927b8abc64..708a665576 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
@@ -19,17 +17,18 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <sys/ioctl.h>
#include <net/if.h>
+#include <sys/ioctl.h>
#include <linux/ethtool.h>
#include <linux/sockios.h>
+#include "conf-parser.h"
#include "ethtool-util.h"
-
+#include "log.h"
+#include "socket-util.h"
+#include "string-table.h"
#include "strxcpyx.h"
#include "util.h"
-#include "log.h"
-#include "conf-parser.h"
static const char* const duplex_table[_DUP_MAX] = {
[DUP_FULL] = "full",
@@ -48,16 +47,22 @@ static const char* const wol_table[_WOL_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(wol, WakeOnLan);
DEFINE_CONFIG_PARSE_ENUM(config_parse_wol, wol, WakeOnLan, "Failed to parse WakeOnLan setting");
+static const char* const netdev_feature_table[_NET_DEV_FEAT_MAX] = {
+ [NET_DEV_FEAT_GSO] = "tx-generic-segmentation",
+ [NET_DEV_FEAT_GRO] = "rx-gro",
+ [NET_DEV_FEAT_LRO] = "rx-lro",
+ [NET_DEV_FEAT_TSO] = "tx-tcp-segmentation",
+ [NET_DEV_FEAT_UFO] = "tx-udp-fragmentation",
+};
+
int ethtool_connect(int *ret) {
int fd;
assert_return(ret, -EINVAL);
- fd = socket(PF_INET, SOCK_DGRAM, 0);
- if (fd < 0) {
- return -errno;
- }
-
+ fd = socket_ioctl_fd();
+ if (fd < 0)
+ return fd;
*ret = fd;
return 0;
@@ -209,3 +214,112 @@ int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol) {
return 0;
}
+
+static int ethtool_get_stringset(int *fd, struct ifreq *ifr, int stringset_id, struct ethtool_gstrings **gstrings) {
+ _cleanup_free_ struct ethtool_gstrings *strings = NULL;
+ struct {
+ struct ethtool_sset_info info;
+ uint32_t space;
+ } buffer = {
+ .info = {
+ .cmd = ETHTOOL_GSSET_INFO,
+ .sset_mask = UINT64_C(1) << stringset_id,
+ },
+ };
+ unsigned len;
+ int r;
+
+ ifr->ifr_data = (void *) &buffer.info;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ if (!buffer.info.sset_mask)
+ return -EINVAL;
+
+ len = buffer.info.data[0];
+
+ strings = malloc0(sizeof(struct ethtool_gstrings) + len * ETH_GSTRING_LEN);
+ if (!strings)
+ return -ENOMEM;
+
+ strings->cmd = ETHTOOL_GSTRINGS;
+ strings->string_set = stringset_id;
+ strings->len = len;
+
+ ifr->ifr_data = (void *) strings;
+
+ r = ioctl(*fd, SIOCETHTOOL, ifr);
+ if (r < 0)
+ return -errno;
+
+ *gstrings = strings;
+ strings = NULL;
+
+ return 0;
+}
+
+static int find_feature_index(struct ethtool_gstrings *strings, const char *feature) {
+ unsigned i;
+
+ for (i = 0; i < strings->len; i++) {
+ if (streq((char *) &strings->data[i * ETH_GSTRING_LEN], feature))
+ return i;
+ }
+
+ return -1;
+}
+
+int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features) {
+ _cleanup_free_ struct ethtool_gstrings *strings = NULL;
+ struct ethtool_sfeatures *sfeatures;
+ int block, bit, i, r;
+ struct ifreq ifr = {};
+
+ if (*fd < 0) {
+ r = ethtool_connect(fd);
+ if (r < 0)
+ return log_warning_errno(r, "link_config: could not connect to ethtool: %m");
+ }
+
+ strscpy(ifr.ifr_name, IFNAMSIZ, ifname);
+
+ r = ethtool_get_stringset(fd, &ifr, ETH_SS_FEATURES, &strings);
+ if (r < 0)
+ return log_warning_errno(r, "link_config: could not get ethtool features for %s", ifname);
+
+ sfeatures = alloca0(sizeof(struct ethtool_gstrings) + DIV_ROUND_UP(strings->len, 32U) * sizeof(sfeatures->features[0]));
+ sfeatures->cmd = ETHTOOL_SFEATURES;
+ sfeatures->size = DIV_ROUND_UP(strings->len, 32U);
+
+ for (i = 0; i < _NET_DEV_FEAT_MAX; i++) {
+
+ if (features[i] != -1) {
+
+ r = find_feature_index(strings, netdev_feature_table[i]);
+ if (r < 0) {
+ log_warning_errno(r, "link_config: could not find feature: %s", netdev_feature_table[i]);
+ continue;
+ }
+
+ block = r / 32;
+ bit = r % 32;
+
+ sfeatures->features[block].valid |= 1 << bit;
+
+ if (features[i])
+ sfeatures->features[block].requested |= 1 << bit;
+ else
+ sfeatures->features[block].requested &= ~(1 << bit);
+ }
+ }
+
+ ifr.ifr_data = (void *) sfeatures;
+
+ r = ioctl(*fd, SIOCETHTOOL, &ifr);
+ if (r < 0)
+ return log_warning_errno(r, "link_config: could not set ethtool features for %s", ifname);
+
+ return 0;
+}
diff --git a/src/udev/net/ethtool-util.h b/src/udev/net/ethtool-util.h
index 690b1a65aa..0744164653 100644
--- a/src/udev/net/ethtool-util.h
+++ b/src/udev/net/ethtool-util.h
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+#pragma once
/***
This file is part of systemd.
@@ -19,8 +19,6 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
-
#include <macro.h>
/* we can't use DUPLEX_ prefix, as it
@@ -40,11 +38,22 @@ typedef enum WakeOnLan {
_WOL_INVALID = -1
} WakeOnLan;
+typedef enum NetDevFeature {
+ NET_DEV_FEAT_GSO,
+ NET_DEV_FEAT_GRO,
+ NET_DEV_FEAT_LRO,
+ NET_DEV_FEAT_TSO,
+ NET_DEV_FEAT_UFO,
+ _NET_DEV_FEAT_MAX,
+ _NET_DEV_FEAT_INVALID = -1
+} NetDevFeature;
+
int ethtool_connect(int *ret);
int ethtool_get_driver(int *fd, const char *ifname, char **ret);
int ethtool_set_speed(int *fd, const char *ifname, unsigned int speed, Duplex duplex);
int ethtool_set_wol(int *fd, const char *ifname, WakeOnLan wol);
+int ethtool_set_features(int *fd, const char *ifname, NetDevFeature *features);
const char *duplex_to_string(Duplex d) _const_;
Duplex duplex_from_string(const char *d) _pure_;
diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf
index b25e4b3344..f8b85cbd13 100644
--- a/src/udev/net/link-config-gperf.gperf
+++ b/src/udev/net/link-config-gperf.gperf
@@ -16,22 +16,27 @@ struct ConfigPerfItem;
%struct-type
%includes
%%
-Match.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, match_mac)
-Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name)
-Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
-Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
-Match.Type, config_parse_strv, 0, offsetof(link_config, match_type)
-Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host)
-Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt)
-Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel)
-Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch)
-Link.Description, config_parse_string, 0, offsetof(link_config, description)
-Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)
-Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
-Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
-Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
-Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
-Link.MTUBytes, config_parse_iec_size, 0, offsetof(link_config, mtu)
-Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
-Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
-Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Match.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, match_mac)
+Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name)
+Match.Path, config_parse_strv, 0, offsetof(link_config, match_path)
+Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver)
+Match.Type, config_parse_strv, 0, offsetof(link_config, match_type)
+Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, match_host)
+Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, match_virt)
+Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, match_kernel)
+Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, match_arch)
+Link.Description, config_parse_string, 0, offsetof(link_config, description)
+Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy)
+Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac)
+Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy)
+Link.Name, config_parse_ifname, 0, offsetof(link_config, name)
+Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias)
+Link.MTUBytes, config_parse_iec_size, 0, offsetof(link_config, mtu)
+Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed)
+Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex)
+Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol)
+Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO])
+Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO])
+Link.UDPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_UFO])
+Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GRO])
+Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_LRO])
diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c
index 63e54db56e..ece9248c2a 100644
--- a/src/udev/net/link-config.c
+++ b/src/udev/net/link-config.c
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
@@ -20,24 +18,29 @@
***/
#include <netinet/ether.h>
-#include <linux/netdevice.h>
+#include "sd-netlink.h"
-#include "missing.h"
-#include "link-config.h"
+#include "alloc-util.h"
+#include "conf-files.h"
+#include "conf-parser.h"
#include "ethtool-util.h"
-
+#include "fd-util.h"
#include "libudev-private.h"
-#include "sd-netlink.h"
-#include "util.h"
+#include "link-config.h"
#include "log.h"
-#include "strv.h"
-#include "path-util.h"
-#include "conf-parser.h"
-#include "conf-files.h"
+#include "missing.h"
#include "netlink-util.h"
#include "network-internal.h"
+#include "parse-util.h"
+#include "path-util.h"
+#include "proc-cmdline.h"
#include "random-util.h"
+#include "stat-util.h"
+#include "string-table.h"
+#include "string-util.h"
+#include "strv.h"
+#include "util.h"
struct link_config_ctx {
LIST_HEAD(link_config, links);
@@ -165,6 +168,8 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
link->wol = _WOL_INVALID;
link->duplex = _DUP_INVALID;
+ memset(&link->features, -1, _NET_DEV_FEAT_MAX);
+
r = config_parse(NULL, filename, file,
"Match\0Link\0Ethernet\0",
config_item_perf_lookup, link_config_gperf_lookup,
@@ -186,20 +191,12 @@ static int load_link(link_config_ctx *ctx, const char *filename) {
}
static bool enable_name_policy(void) {
- _cleanup_free_ char *line = NULL;
- const char *word, *state;
+ _cleanup_free_ char *value = NULL;
int r;
- size_t l;
- r = proc_cmdline(&line);
- if (r < 0) {
- log_warning_errno(r, "Failed to read /proc/cmdline, ignoring: %m");
- return true;
- }
-
- FOREACH_WORD_QUOTED(word, l, line, state)
- if (strneq(word, "net.ifnames=0", l))
- return false;
+ r = get_proc_cmdline_key("net.ifnames=", &value);
+ if (r > 0 && streq(value, "0"))
+ return false;
return true;
}
@@ -348,14 +345,14 @@ static int get_mac(struct udev_device *device, bool want_random,
if (want_random)
random_bytes(mac->ether_addr_octet, ETH_ALEN);
else {
- uint8_t result[8];
+ uint64_t result;
- r = net_get_unique_predictable_data(device, result);
+ r = net_get_unique_predictable_data(device, &result);
if (r < 0)
return r;
assert_cc(ETH_ALEN <= sizeof(result));
- memcpy(mac->ether_addr_octet, result, ETH_ALEN);
+ memcpy(mac->ether_addr_octet, &result, ETH_ALEN);
}
/* see eth_random_addr in the kernel */
@@ -394,6 +391,10 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
log_warning_errno(r, "Could not set WakeOnLan of %s to %s: %m",
old_name, wol_to_string(config->wol));
+ r = ethtool_set_features(&ctx->ethtool_fd, old_name, config->features);
+ if (r < 0)
+ log_warning_errno(r, "Could not set offload features of %s: %m", old_name);
+
ifindex = udev_device_get_ifindex(device);
if (ifindex <= 0) {
log_warning("Could not find ifindex");
@@ -460,6 +461,7 @@ int link_config_apply(link_config_ctx *ctx, link_config *config,
mac = &generated_mac;
}
break;
+ case MACPOLICY_NONE:
default:
mac = config->mac;
}
@@ -492,7 +494,8 @@ int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret
static const char* const mac_policy_table[_MACPOLICY_MAX] = {
[MACPOLICY_PERSISTENT] = "persistent",
- [MACPOLICY_RANDOM] = "random"
+ [MACPOLICY_RANDOM] = "random",
+ [MACPOLICY_NONE] = "none"
};
DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy);
diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h
index 9875057e84..91cc0357c4 100644
--- a/src/udev/net/link-config.h
+++ b/src/udev/net/link-config.h
@@ -1,4 +1,4 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+#pragma once
/***
This file is part of systemd.
@@ -19,12 +19,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#pragma once
+#include "libudev.h"
-#include "ethtool-util.h"
#include "condition.h"
+#include "ethtool-util.h"
#include "list.h"
-#include "libudev.h"
typedef struct link_config_ctx link_config_ctx;
typedef struct link_config link_config;
@@ -32,6 +31,7 @@ typedef struct link_config link_config;
typedef enum MACPolicy {
MACPOLICY_PERSISTENT,
MACPOLICY_RANDOM,
+ MACPOLICY_NONE,
_MACPOLICY_MAX,
_MACPOLICY_INVALID = -1
} MACPolicy;
@@ -70,6 +70,7 @@ struct link_config {
size_t speed;
Duplex duplex;
WakeOnLan wol;
+ NetDevFeature features[_NET_DEV_FEAT_MAX];
LIST_FIELDS(link_config, links);
};
diff --git a/src/udev/scsi_id/scsi.h b/src/udev/scsi_id/scsi.h
index 3f99ae7724..a27a84a40a 100644
--- a/src/udev/scsi_id/scsi.h
+++ b/src/udev/scsi_id/scsi.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* scsi.h
*
@@ -10,8 +12,6 @@
* Free Software Foundation version 2 of the License.
*/
-#pragma once
-
#include <scsi/scsi.h>
struct scsi_ioctl_command {
@@ -24,25 +24,25 @@ struct scsi_ioctl_command {
/*
* Default 5 second timeout
*/
-#define DEF_TIMEOUT 5000
+#define DEF_TIMEOUT 5000
-#define SENSE_BUFF_LEN 32
+#define SENSE_BUFF_LEN 32
/*
* The request buffer size passed to the SCSI INQUIRY commands, use 254,
* as this is a nice value for some devices, especially some of the usb
* mass storage devices.
*/
-#define SCSI_INQ_BUFF_LEN 254
+#define SCSI_INQ_BUFF_LEN 254
/*
* SCSI INQUIRY vendor and model (really product) lengths.
*/
-#define VENDOR_LENGTH 8
-#define MODEL_LENGTH 16
+#define VENDOR_LENGTH 8
+#define MODEL_LENGTH 16
-#define INQUIRY_CMD 0x12
-#define INQUIRY_CMDLEN 6
+#define INQUIRY_CMD 0x12
+#define INQUIRY_CMDLEN 6
/*
* INQUIRY VPD page 0x83 identifier descriptor related values. Reference the
@@ -52,34 +52,34 @@ struct scsi_ioctl_command {
/*
* id type values of id descriptors. These are assumed to fit in 4 bits.
*/
-#define SCSI_ID_VENDOR_SPECIFIC 0
-#define SCSI_ID_T10_VENDOR 1
-#define SCSI_ID_EUI_64 2
-#define SCSI_ID_NAA 3
-#define SCSI_ID_RELPORT 4
+#define SCSI_ID_VENDOR_SPECIFIC 0
+#define SCSI_ID_T10_VENDOR 1
+#define SCSI_ID_EUI_64 2
+#define SCSI_ID_NAA 3
+#define SCSI_ID_RELPORT 4
#define SCSI_ID_TGTGROUP 5
#define SCSI_ID_LUNGROUP 6
-#define SCSI_ID_MD5 7
-#define SCSI_ID_NAME 8
+#define SCSI_ID_MD5 7
+#define SCSI_ID_NAME 8
/*
* Supported NAA values. These fit in 4 bits, so the "don't care" value
* cannot conflict with real values.
*/
-#define SCSI_ID_NAA_DONT_CARE 0xff
-#define SCSI_ID_NAA_IEEE_REG 5
-#define SCSI_ID_NAA_IEEE_REG_EXTENDED 6
+#define SCSI_ID_NAA_DONT_CARE 0xff
+#define SCSI_ID_NAA_IEEE_REG 0x05
+#define SCSI_ID_NAA_IEEE_REG_EXTENDED 0x06
/*
* Supported Code Set values.
*/
-#define SCSI_ID_BINARY 1
-#define SCSI_ID_ASCII 2
+#define SCSI_ID_BINARY 1
+#define SCSI_ID_ASCII 2
struct scsi_id_search_values {
- u_char id_type;
- u_char naa_type;
- u_char code_set;
+ u_char id_type;
+ u_char naa_type;
+ u_char code_set;
};
/*
@@ -87,13 +87,13 @@ struct scsi_id_search_values {
* used a 1 bit right and masked version of these. So now CHECK_CONDITION
* and friends (in <scsi/scsi.h>) are deprecated.
*/
-#define SCSI_CHECK_CONDITION 0x2
-#define SCSI_CONDITION_MET 0x4
-#define SCSI_BUSY 0x8
-#define SCSI_IMMEDIATE 0x10
+#define SCSI_CHECK_CONDITION 0x02
+#define SCSI_CONDITION_MET 0x04
+#define SCSI_BUSY 0x08
+#define SCSI_IMMEDIATE 0x10
#define SCSI_IMMEDIATE_CONDITION_MET 0x14
-#define SCSI_RESERVATION_CONFLICT 0x18
-#define SCSI_COMMAND_TERMINATED 0x22
-#define SCSI_TASK_SET_FULL 0x28
-#define SCSI_ACA_ACTIVE 0x30
-#define SCSI_TASK_ABORTED 0x40
+#define SCSI_RESERVATION_CONFLICT 0x18
+#define SCSI_COMMAND_TERMINATED 0x22
+#define SCSI_TASK_SET_FULL 0x28
+#define SCSI_ACA_ACTIVE 0x30
+#define SCSI_TASK_ABORTED 0x40
diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c
index a1b8e75fac..4655691642 100644
--- a/src/udev/scsi_id/scsi_id.c
+++ b/src/udev/scsi_id/scsi_id.c
@@ -16,22 +16,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
-#include <unistd.h>
-#include <signal.h>
-#include <fcntl.h>
-#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <getopt.h>
#include <sys/stat.h>
+#include <unistd.h>
#include "libudev.h"
+
+#include "fd-util.h"
#include "libudev-private.h"
#include "scsi_id.h"
+#include "string-util.h"
#include "udev-util.h"
static const struct option options[] = {
@@ -190,7 +193,7 @@ static int get_file_options(struct udev *udev,
*newargv = NULL;
lineno = 0;
- while (1) {
+ for (;;) {
vendor_in = model_in = options_in = NULL;
buf = fgets(buffer, MAX_BUFFER_LEN, f);
@@ -279,9 +282,9 @@ static int get_file_options(struct udev *udev,
strcpy(buffer, options_in);
c = argc_count(buffer) + 2;
*newargv = calloc(c, sizeof(**newargv));
- if (!*newargv) {
+ if (!*newargv)
retval = log_oom();
- } else {
+ else {
*argc = c;
c = 0;
/*
@@ -537,16 +540,13 @@ static int scsi_id(struct udev *udev, char *maj_min_dev)
if (dev_scsi.wwn_vendor_extension[0] != '\0') {
printf("ID_WWN_VENDOR_EXTENSION=0x%s\n", dev_scsi.wwn_vendor_extension);
printf("ID_WWN_WITH_EXTENSION=0x%s%s\n", dev_scsi.wwn, dev_scsi.wwn_vendor_extension);
- } else {
+ } else
printf("ID_WWN_WITH_EXTENSION=0x%s\n", dev_scsi.wwn);
- }
}
- if (dev_scsi.tgpt_group[0] != '\0') {
+ if (dev_scsi.tgpt_group[0] != '\0')
printf("ID_TARGET_PORT=%s\n", dev_scsi.tgpt_group);
- }
- if (dev_scsi.unit_serial_number[0] != '\0') {
+ if (dev_scsi.unit_serial_number[0] != '\0')
printf("ID_SCSI_SERIAL=%s\n", dev_scsi.unit_serial_number);
- }
goto out;
}
diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h
index 141b116a88..5c2e1c28ee 100644
--- a/src/udev/scsi_id/scsi_id.h
+++ b/src/udev/scsi_id/scsi_id.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) IBM Corp. 2003
*
@@ -15,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
#define MAX_PATH_LEN 512
/*
diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c
index 3691a69d48..e079e28698 100644
--- a/src/udev/scsi_id/scsi_serial.c
+++ b/src/udev/scsi_id/scsi_serial.c
@@ -17,27 +17,29 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <stdio.h>
#include <errno.h>
-#include <string.h>
#include <fcntl.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <time.h>
#include <inttypes.h>
+#include <linux/bsg.h>
+#include <linux/types.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
-#include <linux/types.h>
-#include <linux/bsg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
#include "libudev.h"
+
#include "libudev-private.h"
+#include "random-util.h"
#include "scsi.h"
#include "scsi_id.h"
-#include "random-util.h"
+#include "string-util.h"
/*
* A priority based list of id, naa, and binary/ascii for the identifier
@@ -48,11 +50,11 @@
* is normally one or some small number of descriptors.
*/
static const struct scsi_id_search_values id_search_list[] = {
- { SCSI_ID_TGTGROUP, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
- { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY },
- { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII },
- { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY },
- { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_ASCII },
+ { SCSI_ID_TGTGROUP, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
+ { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_BINARY },
+ { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG_EXTENDED, SCSI_ID_ASCII },
+ { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_BINARY },
+ { SCSI_ID_NAA, SCSI_ID_NAA_IEEE_REG, SCSI_ID_ASCII },
/*
* Devices already exist using NAA values that are now marked
* reserved. These should not conflict with other values, or it is
@@ -62,14 +64,14 @@ static const struct scsi_id_search_values id_search_list[] = {
* non-IEEE descriptors in a random order will get different
* names.
*/
- { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
- { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
- { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
- { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
- { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
- { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
- { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
- { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
+ { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
+ { SCSI_ID_NAA, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
+ { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
+ { SCSI_ID_EUI_64, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
+ { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
+ { SCSI_ID_T10_VENDOR, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
+ { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_BINARY },
+ { SCSI_ID_VENDOR_SPECIFIC, SCSI_ID_NAA_DONT_CARE, SCSI_ID_ASCII },
};
static const char hex_str[]="0123456789abcdef";
@@ -79,21 +81,21 @@ static const char hex_str[]="0123456789abcdef";
* are used here.
*/
-#define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */
-#define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */
-#define DID_TIME_OUT 0x03 /* Timed out for some other reason */
-#define DRIVER_TIMEOUT 0x06
-#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */
+#define DID_NO_CONNECT 0x01 /* Unable to connect before timeout */
+#define DID_BUS_BUSY 0x02 /* Bus remain busy until timeout */
+#define DID_TIME_OUT 0x03 /* Timed out for some other reason */
+#define DRIVER_TIMEOUT 0x06
+#define DRIVER_SENSE 0x08 /* Sense_buffer has been set */
/* The following "category" function returns one of the following */
#define SG_ERR_CAT_CLEAN 0 /* No errors or other information */
#define SG_ERR_CAT_MEDIA_CHANGED 1 /* interpreted from sense buffer */
#define SG_ERR_CAT_RESET 2 /* interpreted from sense buffer */
-#define SG_ERR_CAT_TIMEOUT 3
-#define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */
-#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */
-#define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */
-#define SG_ERR_CAT_OTHER 99 /* Some other error/warning */
+#define SG_ERR_CAT_TIMEOUT 3
+#define SG_ERR_CAT_RECOVERED 4 /* Successful command after recovered err */
+#define SG_ERR_CAT_NOTSUPPORTED 5 /* Illegal / unsupported command */
+#define SG_ERR_CAT_SENSE 98 /* Something else in the sense buffer */
+#define SG_ERR_CAT_OTHER 99 /* Some other error/warning */
static int do_scsi_page80_inquiry(struct udev *udev,
struct scsi_id_device *dev_scsi, int fd,
@@ -135,9 +137,8 @@ static int sg_err_category_new(struct udev *udev,
return SG_ERR_CAT_MEDIA_CHANGED;
if (0x29 == asc)
return SG_ERR_CAT_RESET;
- } else if (sense_key == ILLEGAL_REQUEST) {
+ } else if (sense_key == ILLEGAL_REQUEST)
return SG_ERR_CAT_NOTSUPPORTED;
- }
}
return SG_ERR_CAT_SENSE;
}
@@ -211,7 +212,7 @@ static int scsi_dump_sense(struct udev *udev,
s = sense_buffer[7] + 8;
if (sb_len < s) {
log_debug("%s: sense buffer too small %d bytes, %d bytes too short",
- dev_scsi->kernel, sb_len, s - sb_len);
+ dev_scsi->kernel, sb_len, s - sb_len);
return -1;
}
if ((code == 0x0) || (code == 0x1)) {
@@ -221,7 +222,7 @@ static int scsi_dump_sense(struct udev *udev,
* Possible?
*/
log_debug("%s: sense result too" " small %d bytes",
- dev_scsi->kernel, s);
+ dev_scsi->kernel, s);
return -1;
}
asc = sense_buffer[12];
@@ -232,15 +233,15 @@ static int scsi_dump_sense(struct udev *udev,
ascq = sense_buffer[3];
} else {
log_debug("%s: invalid sense code 0x%x",
- dev_scsi->kernel, code);
+ dev_scsi->kernel, code);
return -1;
}
log_debug("%s: sense key 0x%x ASC 0x%x ASCQ 0x%x",
- dev_scsi->kernel, sense_key, asc, ascq);
+ dev_scsi->kernel, sense_key, asc, ascq);
} else {
if (sb_len < 4) {
log_debug("%s: sense buffer too small %d bytes, %d bytes too short",
- dev_scsi->kernel, sb_len, 4 - sb_len);
+ dev_scsi->kernel, sb_len, 4 - sb_len);
return -1;
}
@@ -248,9 +249,9 @@ static int scsi_dump_sense(struct udev *udev,
log_debug("%s: old sense key: 0x%x", dev_scsi->kernel, sense_buffer[0] & 0x0f);
else
log_debug("%s: sense = %2x %2x",
- dev_scsi->kernel, sense_buffer[0], sense_buffer[2]);
+ dev_scsi->kernel, sense_buffer[0], sense_buffer[2]);
log_debug("%s: non-extended sense class %d code 0x%0x",
- dev_scsi->kernel, sense_class, code);
+ dev_scsi->kernel, sense_class, code);
}
@@ -281,7 +282,7 @@ static int scsi_dump(struct udev *udev,
}
log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x 0x%x",
- dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
+ dev_scsi->kernel, io->driver_status, io->host_status, io->msg_status, io->status);
if (io->status == SCSI_CHECK_CONDITION)
return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr);
else
@@ -301,8 +302,7 @@ static int scsi_dump_v4(struct udev *udev,
}
log_debug("%s: sg_io failed status 0x%x 0x%x 0x%x",
- dev_scsi->kernel, io->driver_status, io->transport_status,
- io->device_status);
+ dev_scsi->kernel, io->driver_status, io->transport_status, io->device_status);
if (io->device_status == SCSI_CHECK_CONDITION)
return scsi_dump_sense(udev, dev_scsi, (unsigned char *)(uintptr_t)io->response,
io->response_len);
@@ -398,7 +398,7 @@ resend:
error:
if (retval < 0)
log_debug("%s: Unable to get INQUIRY vpd %d page 0x%x.",
- dev_scsi->kernel, evpd, page);
+ dev_scsi->kernel, evpd, page);
return retval;
}
@@ -420,7 +420,7 @@ static int do_scsi_page0_inquiry(struct udev *udev,
return 1;
}
if (buffer[3] > len) {
- log_debug("%s: page 0 buffer too long %d", dev_scsi->kernel, buffer[3]);
+ log_debug("%s: page 0 buffer too long %d", dev_scsi->kernel, buffer[3]);
return 1;
}
@@ -463,7 +463,7 @@ static int prepend_vendor_model(struct udev *udev,
*/
if (ind != (VENDOR_LENGTH + MODEL_LENGTH)) {
log_debug("%s: expected length %d, got length %d",
- dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind);
+ dev_scsi->kernel, (VENDOR_LENGTH + MODEL_LENGTH), ind);
return -1;
}
return ind;
@@ -490,9 +490,8 @@ static int check_fill_0x83_id(struct udev *udev,
if ((page_83[1] & 0x30) == 0x10) {
if (id_search->id_type != SCSI_ID_TGTGROUP)
return 1;
- } else if ((page_83[1] & 0x30) != 0) {
+ } else if ((page_83[1] & 0x30) != 0)
return 1;
- }
if ((page_83[1] & 0x0f) != id_search->id_type)
return 1;
@@ -529,7 +528,7 @@ static int check_fill_0x83_id(struct udev *udev,
if (max_len < len) {
log_debug("%s: length %d too short - need %d",
- dev_scsi->kernel, max_len, len);
+ dev_scsi->kernel, max_len, len);
return 1;
}
@@ -577,9 +576,8 @@ static int check_fill_0x83_id(struct udev *udev,
if (id_search->id_type == SCSI_ID_NAA && wwn != NULL) {
strncpy(wwn, &serial[s], 16);
- if (wwn_vendor_extension != NULL) {
+ if (wwn_vendor_extension != NULL)
strncpy(wwn_vendor_extension, &serial[s + 16], 16);
- }
}
return 0;
@@ -786,7 +784,7 @@ static int do_scsi_page80_inquiry(struct udev *udev,
len = 1 + VENDOR_LENGTH + MODEL_LENGTH + buf[3];
if (max_len < len) {
log_debug("%s: length %d too short - need %d",
- dev_scsi->kernel, max_len, len);
+ dev_scsi->kernel, max_len, len);
return 1;
}
/*
diff --git a/src/udev/udev-builtin-blkid.c b/src/udev/udev-builtin-blkid.c
index 1dad4476f3..3c58445836 100644
--- a/src/udev/udev-builtin-blkid.c
+++ b/src/udev/udev-builtin-blkid.c
@@ -18,18 +18,22 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#include <blkid/blkid.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
-#include <blkid/blkid.h>
#include "sd-id128.h"
-#include "gpt.h"
+
+#include "alloc-util.h"
#include "efivars.h"
+#include "fd-util.h"
+#include "gpt.h"
+#include "string-util.h"
#include "udev.h"
static void print_property(struct udev_device *dev, bool test, const char *name, const char *value) {
@@ -118,7 +122,7 @@ static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
errno = 0;
pl = blkid_probe_get_partitions(pr);
if (!pl)
- return errno ? -errno : -ENOMEM;
+ return errno > 0 ? -errno : -ENOMEM;
nvals = blkid_partlist_numof_partitions(pl);
for (i = 0; i < nvals; i++) {
@@ -158,6 +162,11 @@ static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {
found_esp = true;
} else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {
+ unsigned long long flags;
+
+ flags = blkid_partition_get_flags(pp);
+ if (flags & GPT_FLAG_NO_AUTO)
+ continue;
/* We found a suitable root partition, let's
* remember the first one. */
diff --git a/src/udev/udev-builtin-btrfs.c b/src/udev/udev-builtin-btrfs.c
index 3352821567..cfaa463804 100644
--- a/src/udev/udev-builtin-btrfs.c
+++ b/src/udev/udev-builtin-btrfs.c
@@ -17,15 +17,17 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
#include <fcntl.h>
+#include <stdlib.h>
#include <sys/ioctl.h>
#ifdef HAVE_LINUX_BTRFS_H
#include <linux/btrfs.h>
#endif
+#include "fd-util.h"
#include "missing.h"
+#include "string-util.h"
#include "udev.h"
static int builtin_btrfs(struct udev_device *dev, int argc, char *argv[], bool test) {
diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c
index b656204c46..f4a065a97d 100644
--- a/src/udev/udev-builtin-hwdb.c
+++ b/src/udev/udev-builtin-hwdb.c
@@ -17,23 +17,25 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdio.h>
-#include <stdlib.h>
#include <fnmatch.h>
#include <getopt.h>
+#include <stdio.h>
+#include <stdlib.h>
-#include "udev.h"
#include "sd-hwdb.h"
+#include "alloc-util.h"
#include "hwdb-util.h"
+#include "string-util.h"
#include "udev-util.h"
+#include "udev.h"
static sd_hwdb *hwdb;
int udev_builtin_hwdb_lookup(struct udev_device *dev,
const char *prefix, const char *modalias,
const char *filter, bool test) {
- _cleanup_free_ const char *lookup = NULL;
+ _cleanup_free_ char *lookup = NULL;
const char *key, *value;
int n = 0;
diff --git a/src/udev/udev-builtin-input_id.c b/src/udev/udev-builtin-input_id.c
index e3fa4bc162..59b9804dc4 100644
--- a/src/udev/udev-builtin-input_id.c
+++ b/src/udev/udev-builtin-input_id.c
@@ -21,15 +21,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <errno.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
#include <string.h>
-#include <errno.h>
+#include <unistd.h>
#include <linux/limits.h>
#include <linux/input.h>
+#include "fd-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
#include "udev.h"
#include "util.h"
@@ -62,8 +65,8 @@ static void extract_info(struct udev_device *dev, const char *devpath, bool test
if (xabsinfo.resolution <= 0 || yabsinfo.resolution <= 0)
return;
- snprintf(width, sizeof(width), "%d", abs_size_mm(&xabsinfo));
- snprintf(height, sizeof(height), "%d", abs_size_mm(&yabsinfo));
+ xsprintf(width, "%d", abs_size_mm(&xabsinfo));
+ xsprintf(height, "%d", abs_size_mm(&yabsinfo));
udev_builtin_add_property(dev, test, "ID_INPUT_WIDTH_MM", width);
udev_builtin_add_property(dev, test, "ID_INPUT_HEIGHT_MM", height);
@@ -89,7 +92,7 @@ static void get_cap_mask(struct udev_device *dev,
if (!v)
v = "";
- snprintf(text, sizeof(text), "%s", v);
+ xsprintf(text, "%s", v);
log_debug("%s raw kernel attribute: %s", attr, text);
memzero(bitmask, bitmask_size);
@@ -111,7 +114,8 @@ static void get_cap_mask(struct udev_device *dev,
if (test) {
/* printf pattern with the right unsigned long number of hex chars */
- snprintf(text, sizeof(text), " bit %%4u: %%0%zulX\n", 2 * sizeof(unsigned long));
+ xsprintf(text, " bit %%4u: %%0%zulX\n",
+ 2 * sizeof(unsigned long));
log_debug("%s decoded bit map:", attr);
val = bitmask_size / sizeof (unsigned long);
/* skip over leading zeros */
@@ -173,7 +177,7 @@ static bool test_pointers(struct udev_device *dev,
has_mt_coordinates = test_bit(ABS_MT_POSITION_X, bitmask_abs) && test_bit(ABS_MT_POSITION_Y, bitmask_abs);
/* unset has_mt_coordinates if devices claims to have all abs axis */
- if(has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
+ if (has_mt_coordinates && test_bit(ABS_MT_SLOT, bitmask_abs) && test_bit(ABS_MT_SLOT - 1, bitmask_abs))
has_mt_coordinates = false;
is_direct = test_bit(INPUT_PROP_DIRECT, bitmask_props);
has_touch = test_bit(BTN_TOUCH, bitmask_key);
@@ -201,13 +205,19 @@ static bool test_pointers(struct udev_device *dev,
/* This path is taken by VMware's USB mouse, which has
* absolute axes, but no touch/pressure button. */
is_mouse = true;
- else if (has_touch)
+ else if (has_touch || is_direct)
is_touchscreen = true;
else if (has_joystick_axes_or_buttons)
is_joystick = true;
}
- if (has_mt_coordinates && is_direct)
- is_touchscreen = true;
+ if (has_mt_coordinates) {
+ if (stylus_or_pen)
+ is_tablet = true;
+ else if (finger_but_no_pen && !is_direct)
+ is_touchpad = true;
+ else if (has_touch || is_direct)
+ is_touchscreen = true;
+ }
if (has_rel_coordinates && has_mouse_button)
is_mouse = true;
diff --git a/src/udev/udev-builtin-keyboard.c b/src/udev/udev-builtin-keyboard.c
index 01f3879f37..aa10beafb0 100644
--- a/src/udev/udev-builtin-keyboard.c
+++ b/src/udev/udev-builtin-keyboard.c
@@ -18,11 +18,15 @@
***/
#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/ioctl.h>
#include <linux/input.h>
+#include "fd-util.h"
+#include "parse-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
#include "udev.h"
static const struct key *keyboard_lookup_key(const char *str, unsigned len);
@@ -255,9 +259,8 @@ static int builtin_keyboard(struct udev_device *dev, int argc, char *argv[], boo
}
override_abs(fd, node, evcode, udev_list_entry_get_value(entry));
- } else if (streq(key, "POINTINGSTICK_SENSITIVITY")) {
+ } else if (streq(key, "POINTINGSTICK_SENSITIVITY"))
set_trackpoint_sensitivity(dev, udev_list_entry_get_value(entry));
- }
}
/* install list of force-release codes */
diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c
index 81e78a8aa3..9665f678fd 100644
--- a/src/udev/udev-builtin-kmod.c
+++ b/src/udev/udev-builtin-kmod.c
@@ -18,12 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
#include <errno.h>
#include <libkmod.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "string-util.h"
#include "udev.h"
static struct kmod_ctx *ctx = NULL;
diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c
index 6e7e1271fb..a7be2a4eed 100644
--- a/src/udev/udev-builtin-net_id.c
+++ b/src/udev/udev-builtin-net_id.c
@@ -27,21 +27,21 @@
* http://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames
*
* Two character prefixes based on the type of interface:
- * en -- ethernet
- * sl -- serial line IP (slip)
- * wl -- wlan
- * ww -- wwan
+ * en — Ethernet
+ * sl — serial line IP (slip)
+ * wl — wlan
+ * ww — wwan
*
* Type of names:
- * b<number> -- BCMA bus core number
- * ccw<name> -- CCW bus group name
- * o<index>[d<dev_port>] -- on-board device index number
- * s<slot>[f<function>][d<dev_port>] -- hotplug slot index number
- * x<MAC> -- MAC address
+ * b<number> — BCMA bus core number
+ * c<bus_id> — CCW bus group name, without leading zeros [s390]
+ * o<index>[d<dev_port>] — on-board device index number
+ * s<slot>[f<function>][d<dev_port>] — hotplug slot index number
+ * x<MAC> — MAC address
* [P<domain>]p<bus>s<slot>[f<function>][d<dev_port>]
- * -- PCI geographical location
+ * — PCI geographical location
* [P<domain>]p<bus>s<slot>[f<function>][u<port>][..][c<config>][i<interface>]
- * -- USB port number chain
+ * — USB port number chain
*
* All multi-function PCI devices will carry the [f<function>] number in the
* device name, including the function 0 device.
@@ -53,17 +53,17 @@
* exported.
* The usual USB configuration == 1 and interface == 0 values are suppressed.
*
- * PCI ethernet card with firmware index "1":
+ * PCI Ethernet card with firmware index "1":
* ID_NET_NAME_ONBOARD=eno1
* ID_NET_NAME_ONBOARD_LABEL=Ethernet Port 1
*
- * PCI ethernet card in hotplug slot with firmware index number:
+ * PCI Ethernet card in hotplug slot with firmware index number:
* /sys/devices/pci0000:00/0000:00:1c.3/0000:05:00.0/net/ens1
* ID_NET_NAME_MAC=enx000000000466
* ID_NET_NAME_PATH=enp5s0
* ID_NET_NAME_SLOT=ens1
*
- * PCI ethernet multi-function card with 2 ports:
+ * PCI Ethernet multi-function card with 2 ports:
* /sys/devices/pci0000:00/0000:00:1c.0/0000:02:00.0/net/enp2s0f0
* ID_NET_NAME_MAC=enx78e7d1ea46da
* ID_NET_NAME_PATH=enp2s0f0
@@ -87,19 +87,24 @@
* ID_NET_NAME_PATH=enp0s29u1u2
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
#include <errno.h>
+#include <fcntl.h>
#include <net/if.h>
#include <net/if_arp.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
#include <linux/pci_regs.h>
-#include "udev.h"
+#include "fd-util.h"
#include "fileio.h"
+#include "stdio-util.h"
+#include "string-util.h"
+#include "udev.h"
+
+#define ONBOARD_INDEX_MAX (16*1024-1)
enum netname_type{
NET_UNDEF,
@@ -135,9 +140,9 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
const char *attr;
int idx;
- /* ACPI _DSM -- device specific method for naming a PCI or PCI Express device */
+ /* ACPI _DSM — device specific method for naming a PCI or PCI Express device */
attr = udev_device_get_sysattr_value(names->pcidev, "acpi_index");
- /* SMBIOS type 41 -- Onboard Devices Extended Information */
+ /* SMBIOS type 41 — Onboard Devices Extended Information */
if (!attr)
attr = udev_device_get_sysattr_value(names->pcidev, "index");
if (!attr)
@@ -147,6 +152,13 @@ static int dev_pci_onboard(struct udev_device *dev, struct netnames *names) {
if (idx <= 0)
return -EINVAL;
+ /* Some BIOSes report rubbish indexes that are excessively high (2^24-1 is an index VMware likes to report for
+ * example). Let's define a cut-off where we don't consider the index reliable anymore. We pick some arbitrary
+ * cut-off, which is somewhere beyond the realistic number of physical network interface a system might
+ * have. Ideally the kernel would already filter his crap for us, but it doesn't currently. */
+ if (idx > ONBOARD_INDEX_MAX)
+ return -ENOENT;
+
/* kernel provided port index for multiple ports on a single PCI function */
attr = udev_device_get_sysattr_value(dev, "dev_port");
if (attr)
@@ -218,13 +230,13 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
if (l == 0)
names->pci_path[0] = '\0';
- /* ACPI _SUN -- slot user number */
+ /* ACPI _SUN — slot user number */
pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci");
if (!pci) {
err = -ENOENT;
goto out;
}
- snprintf(slots, sizeof(slots), "%s/slots", udev_device_get_syspath(pci));
+ xsprintf(slots, "%s/slots", udev_device_get_syspath(pci));
dir = opendir(slots);
if (!dir) {
err = -errno;
@@ -243,7 +255,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) {
continue;
if (i < 1)
continue;
- snprintf(str, sizeof(str), "%s/%s/address", slots, dent->d_name);
+ xsprintf(str, "%s/%s/address", slots, dent->d_name);
if (read_one_line_file(str, &address) >= 0) {
/* match slot address with device by stripping the function */
if (strneq(address, udev_device_get_sysname(names->pcidev), strlen(address)))
@@ -280,8 +292,16 @@ static int names_pci(struct udev_device *dev, struct netnames *names) {
assert(names);
parent = udev_device_get_parent(dev);
+
+ /* there can only ever be one virtio bus per parent device, so we can
+ safely ignore any virtio buses. see
+ <http://lists.linuxfoundation.org/pipermail/virtualization/2015-August/030331.html> */
+ while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
+ parent = udev_device_get_parent(parent);
+
if (!parent)
return -ENOENT;
+
/* check if our direct parent is a PCI device with no other bus in-between */
if (streq_ptr("pci", udev_device_get_subsystem(parent))) {
names->type = NET_PCI;
@@ -368,7 +388,7 @@ static int names_bcma(struct udev_device *dev, struct netnames *names) {
return -EINVAL;
/* suppress the common core == 0 */
if (core > 0)
- snprintf(names->bcma_core, sizeof(names->bcma_core), "b%u", core);
+ xsprintf(names->bcma_core, "b%u", core);
names->type = NET_BCMA;
return 0;
@@ -408,8 +428,15 @@ static int names_ccw(struct udev_device *dev, struct netnames *names) {
if (!bus_id_len || bus_id_len < 8 || bus_id_len > 9)
return -EINVAL;
+ /* Strip leading zeros from the bus id for aesthetic purposes. This
+ * keeps the ccw names stable, yet much shorter in general case of
+ * bus_id 0.0.0600 -> 600. This is similar to e.g. how PCI domain is
+ * not prepended when it is zero.
+ */
+ bus_id += strspn(bus_id, ".0");
+
/* Store the CCW bus-ID for use as network device name */
- rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "ccw%s", bus_id);
+ rc = snprintf(names->ccw_group, sizeof(names->ccw_group), "c%s", bus_id);
if (rc >= 0 && rc < (int)sizeof(names->ccw_group))
names->type = NET_CCWGROUP;
return 0;
@@ -457,9 +484,9 @@ static int ieee_oui(struct udev_device *dev, struct netnames *names, bool test)
/* skip commonly misused 00:00:00 (Xerox) prefix */
if (memcmp(names->mac, "\0\0\0", 3) == 0)
return -EINVAL;
- snprintf(str, sizeof(str), "OUI:%02X%02X%02X%02X%02X%02X",
- names->mac[0], names->mac[1], names->mac[2],
- names->mac[3], names->mac[4], names->mac[5]);
+ xsprintf(str, "OUI:%02X%02X%02X%02X%02X%02X", names->mac[0],
+ names->mac[1], names->mac[2], names->mac[3], names->mac[4],
+ names->mac[5]);
udev_builtin_hwdb_lookup(dev, NULL, str, NULL, test);
return 0;
}
@@ -511,7 +538,7 @@ static int builtin_net_id(struct udev_device *dev, int argc, char *argv[], bool
if (err >= 0 && names.mac_valid) {
char str[IFNAMSIZ];
- snprintf(str, sizeof(str), "%sx%02x%02x%02x%02x%02x%02x", prefix,
+ xsprintf(str, "%sx%02x%02x%02x%02x%02x%02x", prefix,
names.mac[0], names.mac[1], names.mac[2],
names.mac[3], names.mac[4], names.mac[5]);
udev_builtin_add_property(dev, test, "ID_NET_NAME_MAC", str);
diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c
index d4589470fb..8e47775135 100644
--- a/src/udev/udev-builtin-net_setup_link.c
+++ b/src/udev/udev-builtin-net_setup_link.c
@@ -1,5 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
/***
This file is part of systemd.
@@ -19,9 +17,10 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include "alloc-util.h"
#include "link-config.h"
-#include "udev.h"
#include "log.h"
+#include "udev.h"
static link_config_ctx *ctx = NULL;
diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c
index 4ca0a69d7d..1825ee75a7 100644
--- a/src/udev/udev-builtin-path_id.c
+++ b/src/udev/udev-builtin-path_id.c
@@ -19,17 +19,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
-#include <string.h>
#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
#include <getopt.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "alloc-util.h"
+#include "string-util.h"
#include "udev.h"
_printf_(2,3)
@@ -117,8 +119,7 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent,
format_lun_number(parent, &lun);
path_prepend(path, "fc-%s-%s", port, lun);
- if (lun)
- free(lun);
+ free(lun);
out:
udev_device_unref(fcdev);
return parent;
@@ -156,8 +157,7 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent,
format_lun_number(parent, &lun);
path_prepend(path, "sas-%s-%s", sas_address, lun);
- if (lun)
- free(lun);
+ free(lun);
out:
udev_device_unref(sasdev);
return parent;
@@ -251,8 +251,7 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa
else
path_prepend(path, "sas-phy%s-%s", phy_id, lun);
- if (lun)
- free(lun);
+ free(lun);
out:
udev_device_unref(target_sasdev);
udev_device_unref(expander_sasdev);
@@ -313,14 +312,46 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **
format_lun_number(parent, &lun);
path_prepend(path, "ip-%s:%s-iscsi-%s-%s", addr, port, target, lun);
- if (lun)
- free(lun);
+ free(lun);
out:
udev_device_unref(sessiondev);
udev_device_unref(conndev);
return parent;
}
+static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **path) {
+ struct udev *udev = udev_device_get_udev(parent);
+ struct udev_device *targetdev;
+ struct udev_device *target_parent;
+ struct udev_device *atadev;
+ const char *port_no;
+
+ assert(parent);
+ assert(path);
+
+ targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host");
+ if (!targetdev)
+ return NULL;
+
+ target_parent = udev_device_get_parent(targetdev);
+ if (!target_parent)
+ return NULL;
+
+ atadev = udev_device_new_from_subsystem_sysname(udev, "ata_port", udev_device_get_sysname(target_parent));
+ if (!atadev)
+ return NULL;
+
+ port_no = udev_device_get_sysattr_value(atadev, "port_no");
+ if (!port_no) {
+ parent = NULL;
+ goto out;
+ }
+ path_prepend(path, "ata-%s", port_no);
+out:
+ udev_device_unref(atadev);
+ return parent;
+}
+
static struct udev_device *handle_scsi_default(struct udev_device *parent, char **path) {
struct udev_device *hostdev;
int host, bus, target, lun;
@@ -486,19 +517,8 @@ static struct udev_device *handle_scsi(struct udev_device *parent, char **path,
goto out;
}
- /*
- * We do not support the ATA transport class, it uses global counters
- * to name the ata devices which numbers spread across multiple
- * controllers.
- *
- * The real link numbers are not exported. Also, possible chains of ports
- * behind port multipliers cannot be composed that way.
- *
- * Until all that is solved at the kernel level, there are no by-path/
- * links for ATA devices.
- */
if (strstr(name, "/ata") != NULL) {
- parent = NULL;
+ parent = handle_scsi_ata(parent, path);
goto out;
}
@@ -573,31 +593,23 @@ static struct udev_device *handle_bcma(struct udev_device *parent, char **path)
return parent;
}
-static struct udev_device *handle_ccw(struct udev_device *parent, struct udev_device *dev, char **path) {
- struct udev_device *scsi_dev;
+/* Handle devices of AP bus in System z platform. */
+static struct udev_device *handle_ap(struct udev_device *parent, char **path) {
+ const char *type, *func;
assert(parent);
- assert(dev);
assert(path);
- scsi_dev = udev_device_get_parent_with_subsystem_devtype(dev, "scsi", "scsi_device");
- if (scsi_dev != NULL) {
- const char *wwpn;
- const char *lun;
- const char *hba_id;
-
- hba_id = udev_device_get_sysattr_value(scsi_dev, "hba_id");
- wwpn = udev_device_get_sysattr_value(scsi_dev, "wwpn");
- lun = udev_device_get_sysattr_value(scsi_dev, "fcp_lun");
- if (hba_id != NULL && lun != NULL && wwpn != NULL) {
- path_prepend(path, "ccw-%s-zfcp-%s:%s", hba_id, wwpn, lun);
- goto out;
- }
- }
+ type = udev_device_get_sysattr_value(parent, "type");
+ func = udev_device_get_sysattr_value(parent, "ap_functions");
- path_prepend(path, "ccw-%s", udev_device_get_sysname(parent));
+ if (type != NULL && func != NULL) {
+ path_prepend(path, "ap-%s-%s", type, func);
+ goto out;
+ }
+ path_prepend(path, "ap-%s", udev_device_get_sysname(parent));
out:
- parent = skip_subsystem(parent, "ccw");
+ parent = skip_subsystem(parent, "ap");
return parent;
}
@@ -609,13 +621,6 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
assert(dev);
- /* S390 ccw bus */
- parent = udev_device_get_parent_with_subsystem_devtype(dev, "ccw", NULL);
- if (parent != NULL) {
- handle_ccw(parent, dev, &path);
- goto out;
- }
-
/* walk up the chain of devices and compose path */
parent = dev;
while (parent != NULL) {
@@ -658,11 +663,45 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
path_prepend(&path, "xen-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "xen");
supported_parent = true;
+ } else if (streq(subsys, "virtio")) {
+ while (parent && streq_ptr("virtio", udev_device_get_subsystem(parent)))
+ parent = udev_device_get_parent(parent);
+ path_prepend(&path, "virtio-pci-%s", udev_device_get_sysname(parent));
+ supported_transport = true;
+ supported_parent = true;
} else if (streq(subsys, "scm")) {
path_prepend(&path, "scm-%s", udev_device_get_sysname(parent));
parent = skip_subsystem(parent, "scm");
supported_transport = true;
supported_parent = true;
+ } else if (streq(subsys, "ccw")) {
+ path_prepend(&path, "ccw-%s", udev_device_get_sysname(parent));
+ parent = skip_subsystem(parent, "ccw");
+ supported_transport = true;
+ supported_parent = true;
+ } else if (streq(subsys, "ccwgroup")) {
+ path_prepend(&path, "ccwgroup-%s", udev_device_get_sysname(parent));
+ parent = skip_subsystem(parent, "ccwgroup");
+ supported_transport = true;
+ supported_parent = true;
+ } else if (streq(subsys, "ap")) {
+ parent = handle_ap(parent, &path);
+ supported_transport = true;
+ supported_parent = true;
+ } else if (streq(subsys, "iucv")) {
+ path_prepend(&path, "iucv-%s", udev_device_get_sysname(parent));
+ parent = skip_subsystem(parent, "iucv");
+ supported_transport = true;
+ supported_parent = true;
+ } else if (streq(subsys, "nvme")) {
+ const char *nsid = udev_device_get_sysattr_value(dev, "nsid");
+
+ if (nsid) {
+ path_prepend(&path, "nvme-%s", nsid);
+ parent = skip_subsystem(parent, "nvme");
+ supported_parent = true;
+ supported_transport = true;
+ }
}
if (parent)
@@ -674,22 +713,17 @@ static int builtin_path_id(struct udev_device *dev, int argc, char *argv[], bool
* might produce conflicting IDs if the parent does not provide a
* unique and predictable name.
*/
- if (!supported_parent) {
- free(path);
- path = NULL;
- }
+ if (!supported_parent)
+ path = mfree(path);
/*
* Do not return block devices without a well-known transport. Some
* devices do not expose their buses and do not provide a unique
* and predictable name that way.
*/
- if (streq(udev_device_get_subsystem(dev), "block") && !supported_transport) {
- free(path);
- path = NULL;
- }
+ if (streq_ptr(udev_device_get_subsystem(dev), "block") && !supported_transport)
+ path = mfree(path);
-out:
if (path != NULL) {
char tag[UTIL_NAME_SIZE];
size_t i;
diff --git a/src/udev/udev-builtin-uaccess.c b/src/udev/udev-builtin-uaccess.c
index 99bb91ae57..3ebe36f043 100644
--- a/src/udev/udev-builtin-uaccess.c
+++ b/src/udev/udev-builtin-uaccess.c
@@ -18,11 +18,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
-#include <errno.h>
-#include "systemd/sd-login.h"
+#include "sd-login.h"
+
+#include "login-util.h"
#include "logind-acl.h"
#include "udev.h"
#include "util.h"
@@ -45,7 +47,7 @@ static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool
seat = "seat0";
r = sd_seat_get_active(seat, NULL, &uid);
- if (r == -ENOENT) {
+ if (r == -ENXIO || r == -ENODATA) {
/* No active session on this seat */
r = 0;
goto finish;
@@ -56,7 +58,7 @@ static int builtin_uaccess(struct udev_device *dev, int argc, char *argv[], bool
r = devnode_acl(path, true, false, 0, true, uid);
if (r < 0) {
- log_error_errno(r, "Failed to apply ACL on %s: %m", path);
+ log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_ERR, r, "Failed to apply ACL on %s: %m", path);
goto finish;
}
@@ -70,7 +72,7 @@ finish:
/* Better be safe than sorry and reset ACL */
k = devnode_acl(path, true, false, 0, false, 0);
if (k < 0) {
- log_error_errno(k, "Failed to apply ACL on %s: %m", path);
+ log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_ERR, k, "Failed to apply ACL on %s: %m", path);
if (r >= 0)
r = k;
}
diff --git a/src/udev/udev-builtin-usb_id.c b/src/udev/udev-builtin-usb_id.c
index d309dc31cb..587649eff0 100644
--- a/src/udev/udev-builtin-usb_id.c
+++ b/src/udev/udev-builtin-usb_id.c
@@ -20,15 +20,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdarg.h>
-#include <unistd.h>
#include <string.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <errno.h>
+#include <unistd.h>
+#include "alloc-util.h"
+#include "fd-util.h"
+#include "string-util.h"
#include "udev.h"
static void set_usb_iftype(char *to, int if_class_num, size_t len) {
diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c
index fabc653800..e6b36f124f 100644
--- a/src/udev/udev-builtin.c
+++ b/src/udev/udev-builtin.c
@@ -17,10 +17,11 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+#include <getopt.h>
#include <stdio.h>
#include <string.h>
-#include <getopt.h>
+#include "string-util.h"
#include "udev.h"
static bool initialized;
@@ -52,7 +53,7 @@ void udev_builtin_init(struct udev *udev) {
return;
for (i = 0; i < ELEMENTSOF(builtins); i++)
- if (builtins[i]->init)
+ if (builtins[i] && builtins[i]->init)
builtins[i]->init(udev);
initialized = true;
@@ -65,7 +66,7 @@ void udev_builtin_exit(struct udev *udev) {
return;
for (i = 0; i < ELEMENTSOF(builtins); i++)
- if (builtins[i]->exit)
+ if (builtins[i] && builtins[i]->exit)
builtins[i]->exit(udev);
initialized = false;
@@ -75,7 +76,7 @@ bool udev_builtin_validate(struct udev *udev) {
unsigned int i;
for (i = 0; i < ELEMENTSOF(builtins); i++)
- if (builtins[i]->validate && builtins[i]->validate(udev))
+ if (builtins[i] && builtins[i]->validate && builtins[i]->validate(udev))
return true;
return false;
}
@@ -84,14 +85,21 @@ void udev_builtin_list(struct udev *udev) {
unsigned int i;
for (i = 0; i < ELEMENTSOF(builtins); i++)
- fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help);
+ if (builtins[i])
+ fprintf(stderr, " %-14s %s\n", builtins[i]->name, builtins[i]->help);
}
const char *udev_builtin_name(enum udev_builtin_cmd cmd) {
+ if (!builtins[cmd])
+ return NULL;
+
return builtins[cmd]->name;
}
bool udev_builtin_run_once(enum udev_builtin_cmd cmd) {
+ if (!builtins[cmd])
+ return false;
+
return builtins[cmd]->run_once;
}
@@ -105,7 +113,7 @@ enum udev_builtin_cmd udev_builtin_lookup(const char *command) {
if (pos)
pos[0] = '\0';
for (i = 0; i < ELEMENTSOF(builtins); i++)
- if (streq(builtins[i]->name, name))
+ if (builtins[i] && streq(builtins[i]->name, name))
return i;
return UDEV_BUILTIN_MAX;
}
@@ -115,6 +123,9 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c
int argc;
char *argv[128];
+ if (!builtins[cmd])
+ return -EOPNOTSUPP;
+
/* we need '0' here to reset the internal state */
optind = 0;
strscpy(arg, sizeof(arg), command);
diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c
index b0ad277f73..f68a09d7a8 100644
--- a/src/udev/udev-ctrl.c
+++ b/src/udev/udev-ctrl.c
@@ -10,16 +10,18 @@
*/
#include <errno.h>
-#include <stdlib.h>
+#include <poll.h>
#include <stddef.h>
+#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <poll.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <unistd.h>
-#include "socket-util.h"
+#include "alloc-util.h"
+#include "fd-util.h"
#include "formats-util.h"
+#include "socket-util.h"
#include "udev.h"
/* wire protocol magic must match */
@@ -92,13 +94,18 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) {
uctrl->bound = true;
uctrl->sock = fd;
}
+
+ /*
+ * FIXME: remove it as soon as we can depend on this:
+ * http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=90c6bd34f884cd9cee21f1d152baf6c18bcac949
+ */
r = setsockopt(uctrl->sock, SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
if (r < 0)
log_warning_errno(errno, "could not set SO_PASSCRED: %m");
uctrl->saddr.un.sun_family = AF_LOCAL;
strscpy(uctrl->saddr.un.sun_path, sizeof(uctrl->saddr.un.sun_path), "/run/udev/control");
- uctrl->addrlen = offsetof(struct sockaddr_un, sun_path) + strlen(uctrl->saddr.un.sun_path);
+ uctrl->addrlen = SOCKADDR_UN_LEN(uctrl->saddr.un);
return uctrl;
}
@@ -116,18 +123,12 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) {
err = bind(uctrl->sock, &uctrl->saddr.sa, uctrl->addrlen);
}
- if (err < 0) {
- err = -errno;
- log_error_errno(errno, "bind failed: %m");
- return err;
- }
+ if (err < 0)
+ return log_error_errno(errno, "bind failed: %m");
err = listen(uctrl->sock, 0);
- if (err < 0) {
- err = -errno;
- log_error_errno(errno, "listen failed: %m");
- return err;
- }
+ if (err < 0)
+ return log_error_errno(errno, "listen failed: %m");
uctrl->bound = true;
uctrl->cleanup_socket = true;
@@ -379,13 +380,14 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) {
cmsg_close_all(&smsg);
cmsg = CMSG_FIRSTHDR(&smsg);
- cred = (struct ucred *) CMSG_DATA(cmsg);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
log_error("no sender credentials received, message ignored");
goto err;
}
+ cred = (struct ucred *) CMSG_DATA(cmsg);
+
if (cred->uid != 0) {
log_error("sender uid="UID_FMT", message ignored", cred->uid);
goto err;
diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c
index 4761222786..54cd741bb1 100644
--- a/src/udev/udev-event.c
+++ b/src/udev/udev-event.c
@@ -15,26 +15,28 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <errno.h>
#include <ctype.h>
-#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
#include <net/if.h>
-#include <sys/prctl.h>
#include <poll.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/epoll.h>
-#include <sys/wait.h>
+#include <sys/prctl.h>
#include <sys/signalfd.h>
+#include <sys/wait.h>
+#include <unistd.h>
-#include "netlink-util.h"
-#include "event-util.h"
+#include "alloc-util.h"
+#include "fd-util.h"
#include "formats-util.h"
+#include "netlink-util.h"
#include "process-util.h"
#include "signal-util.h"
+#include "string-util.h"
#include "udev.h"
typedef struct Spawn {
@@ -247,7 +249,7 @@ subst:
if (event->program_result == NULL)
break;
- /* get part part of the result string */
+ /* get part of the result string */
i = 0;
if (attr != NULL)
i = strtoul(attr, &rest, 10);
@@ -438,9 +440,7 @@ static int spawn_exec(struct udev_event *event,
execve(argv[0], argv, envp);
/* exec failed */
- log_error_errno(errno, "failed to execute '%s' '%s': %m", argv[0], cmd);
-
- return -errno;
+ return log_error_errno(errno, "failed to execute '%s' '%s': %m", argv[0], cmd);
}
static void spawn_read(struct udev_event *event,
@@ -637,7 +637,7 @@ static int spawn_wait(struct udev_event *event,
.pid = pid,
.accept_failure = accept_failure,
};
- _cleanup_event_unref_ sd_event *e = NULL;
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
int r, ret;
r = sd_event_new(&e);
@@ -731,15 +731,13 @@ int udev_event_spawn(struct udev_event *event,
/* pipes from child to parent */
if (result != NULL || log_get_max_level() >= LOG_INFO) {
if (pipe2(outpipe, O_NONBLOCK) != 0) {
- err = -errno;
- log_error_errno(errno, "pipe failed: %m");
+ err = log_error_errno(errno, "pipe failed: %m");
goto out;
}
}
if (log_get_max_level() >= LOG_INFO) {
if (pipe2(errpipe, O_NONBLOCK) != 0) {
- err = -errno;
- log_error_errno(errno, "pipe failed: %m");
+ err = log_error_errno(errno, "pipe failed: %m");
goto out;
}
}
@@ -753,14 +751,8 @@ int udev_event_spawn(struct udev_event *event,
char program[UTIL_PATH_SIZE];
/* child closes parent's ends of pipes */
- if (outpipe[READ_END] >= 0) {
- close(outpipe[READ_END]);
- outpipe[READ_END] = -1;
- }
- if (errpipe[READ_END] >= 0) {
- close(errpipe[READ_END]);
- errpipe[READ_END] = -1;
- }
+ outpipe[READ_END] = safe_close(outpipe[READ_END]);
+ errpipe[READ_END] = safe_close(errpipe[READ_END]);
strscpy(arg, sizeof(arg), cmd);
udev_build_argv(event->udev, arg, NULL, argv);
@@ -784,14 +776,8 @@ int udev_event_spawn(struct udev_event *event,
goto out;
default:
/* parent closed child's ends of pipes */
- if (outpipe[WRITE_END] >= 0) {
- close(outpipe[WRITE_END]);
- outpipe[WRITE_END] = -1;
- }
- if (errpipe[WRITE_END] >= 0) {
- close(errpipe[WRITE_END]);
- errpipe[WRITE_END] = -1;
- }
+ outpipe[WRITE_END] = safe_close(outpipe[WRITE_END]);
+ errpipe[WRITE_END] = safe_close(errpipe[WRITE_END]);
spawn_read(event,
timeout_usec,
@@ -862,11 +848,11 @@ void udev_event_execute_rules(struct udev_event *event,
/* disable watch during event processing */
if (major(udev_device_get_devnum(dev)) != 0)
udev_watch_end(event->udev, event->dev_db);
- }
- if (major(udev_device_get_devnum(dev)) == 0 &&
- streq(udev_device_get_action(dev), "move"))
- udev_device_copy_properties(dev, event->dev_db);
+ if (major(udev_device_get_devnum(dev)) == 0 &&
+ streq(udev_device_get_action(dev), "move"))
+ udev_device_copy_properties(dev, event->dev_db);
+ }
udev_rules_apply_to_event(rules, event,
timeout_usec, timeout_warn_usec,
diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c
index d824172b89..5d2997fd8f 100644
--- a/src/udev/udev-node.c
+++ b/src/udev/udev-node.c
@@ -15,20 +15,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <stdbool.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <errno.h>
#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/stat.h>
+#include <unistd.h>
-#include "udev.h"
-#include "smack-util.h"
-#include "selinux-util.h"
#include "formats-util.h"
+#include "fs-util.h"
+#include "selinux-util.h"
+#include "smack-util.h"
+#include "stdio-util.h"
+#include "string-util.h"
+#include "udev.h"
static int node_symlink(struct udev_device *dev, const char *node, const char *slink) {
struct stat stats;
@@ -261,8 +264,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
mode |= S_IFCHR;
if (lstat(devnode, &stats) != 0) {
- err = -errno;
- log_debug_errno(errno, "can not stat() node '%s' (%m)", devnode);
+ err = log_debug_errno(errno, "can not stat() node '%s' (%m)", devnode);
goto out;
}
@@ -309,7 +311,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
} else if (streq(name, "smack")) {
smack = true;
- r = mac_smack_apply(devnode, label);
+ r = mac_smack_apply(devnode, SMACK_ATTR_ACCESS, label);
if (r < 0)
log_error_errno(r, "SECLABEL: failed to set SMACK label '%s': %m", label);
else
@@ -323,7 +325,7 @@ static int node_permissions_apply(struct udev_device *dev, bool apply,
if (!selinux)
mac_selinux_fix(devnode, true, false);
if (!smack)
- mac_smack_apply(devnode, NULL);
+ mac_smack_apply(devnode, SMACK_ATTR_ACCESS, NULL);
}
/* always update timestamp when we re-use the node, like on media change events */
@@ -345,9 +347,10 @@ void udev_node_add(struct udev_device *dev, bool apply,
return;
/* always add /dev/{block,char}/$major:$minor */
- snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
+ xsprintf(filename, "/dev/%s/%u:%u",
streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
- major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+ major(udev_device_get_devnum(dev)),
+ minor(udev_device_get_devnum(dev)));
node_symlink(dev, udev_device_get_devnode(dev), filename);
/* create/update symlinks, add symlinks to name index */
@@ -364,8 +367,9 @@ void udev_node_remove(struct udev_device *dev) {
link_update(dev, udev_list_entry_get_name(list_entry), false);
/* remove /dev/{block,char}/$major:$minor */
- snprintf(filename, sizeof(filename), "/dev/%s/%u:%u",
+ xsprintf(filename, "/dev/%s/%u:%u",
streq(udev_device_get_subsystem(dev), "block") ? "block" : "char",
- major(udev_device_get_devnum(dev)), minor(udev_device_get_devnum(dev)));
+ major(udev_device_get_devnum(dev)),
+ minor(udev_device_get_devnum(dev)));
unlink(filename);
}
diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c
index d00f90afa6..26fa52cf6c 100644
--- a/src/udev/udev-rules.c
+++ b/src/udev/udev-rules.c
@@ -15,27 +15,36 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stddef.h>
-#include <limits.h>
-#include <stdlib.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
#include <ctype.h>
-#include <unistd.h>
-#include <errno.h>
#include <dirent.h>
+#include <errno.h>
+#include <fcntl.h>
#include <fnmatch.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <time.h>
+#include <unistd.h>
-#include "udev.h"
-#include "path-util.h"
+#include "alloc-util.h"
#include "conf-files.h"
+#include "escape.h"
+#include "fd-util.h"
+#include "fs-util.h"
+#include "glob-util.h"
+#include "path-util.h"
+#include "stat-util.h"
+#include "stdio-util.h"
#include "strbuf.h"
+#include "string-util.h"
#include "strv.h"
-#include "util.h"
#include "sysctl-util.h"
+#include "udev.h"
+#include "user-util.h"
+#include "util.h"
#define PREALLOC_TOKEN 2048
@@ -51,7 +60,8 @@ static const char* const rules_dirs[] = {
"/etc/udev/rules.d",
"/run/udev/rules.d",
UDEVLIBEXECDIR "/rules.d",
- NULL};
+ NULL
+};
struct udev_rules {
struct udev *udev;
@@ -319,8 +329,8 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
enum token_type type = token->type;
enum operation_type op = token->key.op;
enum string_glob_type glob = token->key.glob;
- const char *value = str(rules, token->key.value_off);
- const char *attr = &rules->buf[token->key.attr_off];
+ const char *value = rules_str(rules, token->key.value_off);
+ const char *attr = &rules->strbuf->buf[token->key.attr_off];
switch (type) {
case TK_RULE:
@@ -330,9 +340,9 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
unsigned int idx = (tk_ptr - tks_ptr) / sizeof(struct token);
log_debug("* RULE %s:%u, token: %u, count: %u, label: '%s'",
- &rules->buf[token->rule.filename_off], token->rule.filename_line,
+ &rules->strbuf->buf[token->rule.filename_off], token->rule.filename_line,
idx, token->rule.token_count,
- &rules->buf[token->rule.label_off]);
+ &rules->strbuf->buf[token->rule.label_off]);
break;
}
case TK_M_ACTION:
@@ -429,11 +439,11 @@ static void dump_token(struct udev_rules *rules, struct token *token) {
static void dump_rules(struct udev_rules *rules) {
unsigned int i;
- log_debug("dumping %u (%zu bytes) tokens, %u (%zu bytes) strings",
+ log_debug("dumping %u (%zu bytes) tokens, %zu (%zu bytes) strings",
rules->token_cur,
rules->token_cur * sizeof(struct token),
- rules->buf_count,
- rules->buf_cur);
+ rules->strbuf->nodes_count,
+ rules->strbuf->len);
for (i = 0; i < rules->token_cur; i++)
dump_token(rules, &rules->tokens[i]);
}
@@ -672,48 +682,37 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi
const char *key = udev_list_entry_get_name(list_entry);
const char *val = udev_list_entry_get_value(list_entry);
- if (fnmatch(filter, key, 0) == 0) {
+ if (fnmatch(filter, key, 0) == 0)
udev_device_add_property(dev, key, val);
- }
}
return 0;
}
-static int attr_subst_subdir(char *attr, size_t len) {
- bool found = false;
+static void attr_subst_subdir(char *attr, size_t len) {
+ const char *pos, *tail, *path;
+ _cleanup_closedir_ DIR *dir = NULL;
+ struct dirent *dent;
- if (strstr(attr, "/*/")) {
- char *pos;
- char dirname[UTIL_PATH_SIZE];
- const char *tail;
- DIR *dir;
+ pos = strstr(attr, "/*/");
+ if (!pos)
+ return;
- strscpy(dirname, sizeof(dirname), attr);
- pos = strstr(dirname, "/*/");
- if (pos == NULL)
- return -1;
- pos[0] = '\0';
- tail = &pos[2];
- dir = opendir(dirname);
- if (dir != NULL) {
- struct dirent *dent;
+ tail = pos + 2;
+ path = strndupa(attr, pos - attr + 1); /* include slash at end */
+ dir = opendir(path);
+ if (dir == NULL)
+ return;
- for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
- struct stat stats;
+ for (dent = readdir(dir); dent != NULL; dent = readdir(dir))
+ if (dent->d_name[0] != '.') {
+ char n[strlen(dent->d_name) + strlen(tail) + 1];
- if (dent->d_name[0] == '.')
- continue;
- strscpyl(attr, len, dirname, "/", dent->d_name, tail, NULL);
- if (stat(attr, &stats) == 0) {
- found = true;
- break;
- }
+ strscpyl(n, sizeof n, dent->d_name, tail, NULL);
+ if (faccessat(dirfd(dir), n, F_OK, 0) == 0) {
+ strscpyl(attr, len, path, n, NULL);
+ break;
}
- closedir(dir);
}
- }
-
- return found;
}
static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) {
@@ -824,12 +823,13 @@ static const char *get_key_attribute(struct udev *udev, char *str) {
return NULL;
}
-static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
- enum operation_type op,
- const char *value, const void *data) {
- struct token *token = &rule_tmp->token[rule_tmp->token_cur];
+static void rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
+ enum operation_type op,
+ const char *value, const void *data) {
+ struct token *token = rule_tmp->token + rule_tmp->token_cur;
const char *attr = NULL;
+ assert(rule_tmp->token_cur < ELEMENTSOF(rule_tmp->token));
memzero(token, sizeof(struct token));
switch (type) {
@@ -912,8 +912,7 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
case TK_M_MAX:
case TK_END:
case TK_UNSET:
- log_error("wrong type %u", type);
- return -1;
+ assert_not_reached("wrong type");
}
if (value != NULL && type < TK_M_MAX) {
@@ -962,11 +961,6 @@ static int rule_add_key(struct rule_tmp *rule_tmp, enum token_type type,
token->key.type = type;
token->key.op = op;
rule_tmp->token_cur++;
- if (rule_tmp->token_cur >= ELEMENTSOF(rule_tmp->token)) {
- log_error("temporary rule array too small");
- return -1;
- }
- return 0;
}
static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
@@ -1003,8 +997,13 @@ static int sort_token(struct udev_rules *rules, struct rule_tmp *rule_tmp) {
return 0;
}
-static int add_rule(struct udev_rules *rules, char *line,
- const char *filename, unsigned int filename_off, unsigned int lineno) {
+#define LOG_RULE_ERROR(fmt, ...) log_error("Invalid rule %s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_RULE_WARNING(fmt, ...) log_warning("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_RULE_DEBUG(fmt, ...) log_debug("%s:%u: " fmt, filename, lineno, ##__VA_ARGS__)
+#define LOG_AND_RETURN(fmt, ...) { LOG_RULE_ERROR(fmt, __VA_ARGS__); return; }
+
+static void add_rule(struct udev_rules *rules, char *line,
+ const char *filename, unsigned int filename_off, unsigned int lineno) {
char *linepos;
const char *attr;
struct rule_tmp rule_tmp = {
@@ -1045,427 +1044,322 @@ static int add_rule(struct udev_rules *rules, char *line,
break;
}
+ if (rule_tmp.token_cur >= ELEMENTSOF(rule_tmp.token))
+ LOG_AND_RETURN("temporary rule array too small, aborting event processing with %u items", rule_tmp.token_cur);
+
if (streq(key, "ACTION")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid ACTION operation");
- goto invalid;
- }
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_ACTION, op, value, NULL);
- continue;
- }
- if (streq(key, "DEVPATH")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DEVPATH operation");
- goto invalid;
- }
+ } else if (streq(key, "DEVPATH")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DEVPATH, op, value, NULL);
- continue;
- }
- if (streq(key, "KERNEL")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid KERNEL operation");
- goto invalid;
- }
+ } else if (streq(key, "KERNEL")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_KERNEL, op, value, NULL);
- continue;
- }
- if (streq(key, "SUBSYSTEM")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid SUBSYSTEM operation");
- goto invalid;
- }
+ } else if (streq(key, "SUBSYSTEM")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
/* bus, class, subsystem events should all be the same */
- if (streq(value, "subsystem") ||
- streq(value, "bus") ||
- streq(value, "class")) {
- if (streq(value, "bus") || streq(value, "class"))
- log_error("'%s' must be specified as 'subsystem' "
- "please fix it in %s:%u", value, filename, lineno);
+ if (STR_IN_SET(value, "subsystem", "bus", "class")) {
+ if (!streq(value, "subsystem"))
+ LOG_RULE_WARNING("'%s' must be specified as 'subsystem'; please fix", value);
+
rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, "subsystem|class|bus", NULL);
} else
rule_add_key(&rule_tmp, TK_M_SUBSYSTEM, op, value, NULL);
- continue;
- }
- if (streq(key, "DRIVER")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DRIVER operation");
- goto invalid;
- }
+ } else if (streq(key, "DRIVER")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL);
- continue;
- }
- if (startswith(key, "ATTR{")) {
+ } else if (startswith(key, "ATTR{")) {
attr = get_key_attribute(rules->udev, key + strlen("ATTR"));
- if (attr == NULL) {
- log_error("error parsing ATTR attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid ATTR operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTR");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ATTR");
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_ATTR, op, value, attr);
else
rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr);
- continue;
- }
- if (startswith(key, "SYSCTL{")) {
+ } else if (startswith(key, "SYSCTL{")) {
attr = get_key_attribute(rules->udev, key + strlen("SYSCTL"));
- if (attr == NULL) {
- log_error("error parsing SYSCTL attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid SYSCTL operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTR");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ATTR");
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_SYSCTL, op, value, attr);
else
rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr);
- continue;
- }
- if (startswith(key, "SECLABEL{")) {
+ } else if (startswith(key, "SECLABEL{")) {
attr = get_key_attribute(rules->udev, key + strlen("SECLABEL"));
- if (!attr) {
- log_error("error parsing SECLABEL attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid SECLABEL operation");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "SECLABEL");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "SECLABEL");
rule_add_key(&rule_tmp, TK_A_SECLABEL, op, value, attr);
- continue;
- }
- if (streq(key, "KERNELS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid KERNELS operation");
- goto invalid;
- }
+ } else if (streq(key, "KERNELS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_KERNELS, op, value, NULL);
- continue;
- }
- if (streq(key, "SUBSYSTEMS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid SUBSYSTEMS operation");
- goto invalid;
- }
+ } else if (streq(key, "SUBSYSTEMS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_SUBSYSTEMS, op, value, NULL);
- continue;
- }
- if (streq(key, "DRIVERS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid DRIVERS operation");
- goto invalid;
- }
+ } else if (streq(key, "DRIVERS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_DRIVERS, op, value, NULL);
- continue;
- }
- if (startswith(key, "ATTRS{")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid ATTRS operation");
- goto invalid;
- }
+ } else if (startswith(key, "ATTRS{")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", "ATTRS");
+
attr = get_key_attribute(rules->udev, key + strlen("ATTRS"));
- if (attr == NULL) {
- log_error("error parsing ATTRS attribute");
- goto invalid;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ATTRS");
+
if (startswith(attr, "device/"))
- log_error("the 'device' link may not be available in a future kernel, "
- "please fix it in %s:%u", filename, lineno);
- else if (strstr(attr, "../") != NULL)
- log_error("do not reference parent sysfs directories directly, "
- "it may break with a future kernel, please fix it in %s:%u", filename, lineno);
+ LOG_RULE_WARNING("'device' link may not be available in future kernels; please fix");
+ if (strstr(attr, "../") != NULL)
+ LOG_RULE_WARNING("direct reference to parent sysfs directory, may break in future kernels; please fix");
rule_add_key(&rule_tmp, TK_M_ATTRS, op, value, attr);
- continue;
- }
- if (streq(key, "TAGS")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid TAGS operation");
- goto invalid;
- }
+ } else if (streq(key, "TAGS")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL);
- continue;
- }
- if (startswith(key, "ENV{")) {
+ } else if (startswith(key, "ENV{")) {
attr = get_key_attribute(rules->udev, key + strlen("ENV"));
- if (attr == NULL) {
- log_error("error parsing ENV attribute");
- goto invalid;
- }
- if (op == OP_REMOVE) {
- log_error("invalid ENV operation");
- goto invalid;
- }
- if (op < OP_MATCH_MAX) {
- if (rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr) != 0)
- goto invalid;
- } else {
- static const char *blacklist[] = {
- "ACTION",
- "SUBSYSTEM",
- "DEVTYPE",
- "MAJOR",
- "MINOR",
- "DRIVER",
- "IFINDEX",
- "DEVNAME",
- "DEVLINKS",
- "DEVPATH",
- "TAGS",
- };
- unsigned int i;
-
- for (i = 0; i < ELEMENTSOF(blacklist); i++) {
- if (!streq(attr, blacklist[i]))
- continue;
- log_error("invalid ENV attribute, '%s' can not be set %s:%u", attr, filename, lineno);
- goto invalid;
- }
- if (rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr) != 0)
- goto invalid;
- }
- continue;
- }
+ if (attr == NULL)
+ LOG_AND_RETURN("error parsing %s attribute", "ENV");
+
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "ENV");
- if (streq(key, "TAG")) {
+ if (op < OP_MATCH_MAX)
+ rule_add_key(&rule_tmp, TK_M_ENV, op, value, attr);
+ else {
+ if (STR_IN_SET(attr,
+ "ACTION",
+ "SUBSYSTEM",
+ "DEVTYPE",
+ "MAJOR",
+ "MINOR",
+ "DRIVER",
+ "IFINDEX",
+ "DEVNAME",
+ "DEVLINKS",
+ "DEVPATH",
+ "TAGS"))
+ LOG_AND_RETURN("invalid ENV attribute, '%s' cannot be set", attr);
+
+ rule_add_key(&rule_tmp, TK_A_ENV, op, value, attr);
+ }
+
+ } else if (streq(key, "TAG")) {
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_TAG, op, value, NULL);
else
rule_add_key(&rule_tmp, TK_A_TAG, op, value, NULL);
- continue;
- }
- if (streq(key, "PROGRAM")) {
- if (op == OP_REMOVE) {
- log_error("invalid PROGRAM operation");
- goto invalid;
- }
+ } else if (streq(key, "PROGRAM")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_PROGRAM, op, value, NULL);
- continue;
- }
- if (streq(key, "RESULT")) {
- if (op > OP_MATCH_MAX) {
- log_error("invalid RESULT operation");
- goto invalid;
- }
+ } else if (streq(key, "RESULT")) {
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL);
- continue;
- }
- if (startswith(key, "IMPORT")) {
+ } else if (startswith(key, "IMPORT")) {
attr = get_key_attribute(rules->udev, key + strlen("IMPORT"));
if (attr == NULL) {
- log_error("IMPORT{} type missing, ignoring IMPORT %s:%u", filename, lineno);
+ LOG_RULE_WARNING("ignoring IMPORT{} with missing type");
continue;
}
- if (op == OP_REMOVE) {
- log_error("invalid IMPORT operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "IMPORT");
+
if (streq(attr, "program")) {
/* find known built-in command */
if (value[0] != '/') {
- enum udev_builtin_cmd cmd;
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
- cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX) {
- log_debug("IMPORT found builtin '%s', replacing %s:%u",
- value, filename, lineno);
+ LOG_RULE_DEBUG("IMPORT found builtin '%s', replacing", value);
rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
continue;
}
}
rule_add_key(&rule_tmp, TK_M_IMPORT_PROG, op, value, NULL);
} else if (streq(attr, "builtin")) {
- enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
- if (cmd < UDEV_BUILTIN_MAX)
- rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+ if (cmd >= UDEV_BUILTIN_MAX)
+ LOG_RULE_WARNING("IMPORT{builtin} '%s' unknown", value);
else
- log_error("IMPORT{builtin}: '%s' unknown %s:%u", value, filename, lineno);
- } else if (streq(attr, "file")) {
+ rule_add_key(&rule_tmp, TK_M_IMPORT_BUILTIN, op, value, &cmd);
+ } else if (streq(attr, "file"))
rule_add_key(&rule_tmp, TK_M_IMPORT_FILE, op, value, NULL);
- } else if (streq(attr, "db")) {
+ else if (streq(attr, "db"))
rule_add_key(&rule_tmp, TK_M_IMPORT_DB, op, value, NULL);
- } else if (streq(attr, "cmdline")) {
+ else if (streq(attr, "cmdline"))
rule_add_key(&rule_tmp, TK_M_IMPORT_CMDLINE, op, value, NULL);
- } else if (streq(attr, "parent")) {
+ else if (streq(attr, "parent"))
rule_add_key(&rule_tmp, TK_M_IMPORT_PARENT, op, value, NULL);
- } else
- log_error("IMPORT{} unknown type, ignoring IMPORT %s:%u", filename, lineno);
- continue;
- }
+ else
+ LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "IMPORT", attr);
- if (startswith(key, "TEST")) {
+ } else if (startswith(key, "TEST")) {
mode_t mode = 0;
- if (op > OP_MATCH_MAX) {
- log_error("invalid TEST operation");
- goto invalid;
- }
+ if (op > OP_MATCH_MAX)
+ LOG_AND_RETURN("invalid %s operation", "TEST");
+
attr = get_key_attribute(rules->udev, key + strlen("TEST"));
if (attr != NULL) {
mode = strtol(attr, NULL, 8);
rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode);
- } else {
+ } else
rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL);
- }
- continue;
- }
- if (startswith(key, "RUN")) {
+ } else if (startswith(key, "RUN")) {
attr = get_key_attribute(rules->udev, key + strlen("RUN"));
if (attr == NULL)
attr = "program";
- if (op == OP_REMOVE) {
- log_error("invalid RUN operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", "RUN");
if (streq(attr, "builtin")) {
- enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
+ const enum udev_builtin_cmd cmd = udev_builtin_lookup(value);
if (cmd < UDEV_BUILTIN_MAX)
rule_add_key(&rule_tmp, TK_A_RUN_BUILTIN, op, value, &cmd);
else
- log_error("RUN{builtin}: '%s' unknown %s:%u", value, filename, lineno);
+ LOG_RULE_ERROR("RUN{builtin}: '%s' unknown", value);
} else if (streq(attr, "program")) {
- enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
+ const enum udev_builtin_cmd cmd = UDEV_BUILTIN_MAX;
rule_add_key(&rule_tmp, TK_A_RUN_PROGRAM, op, value, &cmd);
- } else {
- log_error("RUN{} unknown type, ignoring RUN %s:%u", filename, lineno);
- }
+ } else
+ LOG_RULE_ERROR("ignoring unknown %s{} type '%s'", "RUN", attr);
- continue;
- }
+ } else if (streq(key, "LABEL")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
- if (streq(key, "LABEL")) {
- if (op == OP_REMOVE) {
- log_error("invalid LABEL operation");
- goto invalid;
- }
rule_tmp.rule.rule.label_off = rules_add_string(rules, value);
- continue;
- }
- if (streq(key, "GOTO")) {
- if (op == OP_REMOVE) {
- log_error("invalid GOTO operation");
- goto invalid;
- }
+ } else if (streq(key, "GOTO")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
rule_add_key(&rule_tmp, TK_A_GOTO, 0, value, NULL);
- continue;
- }
- if (startswith(key, "NAME")) {
- if (op == OP_REMOVE) {
- log_error("invalid NAME operation");
- goto invalid;
- }
- if (op < OP_MATCH_MAX) {
+ } else if (startswith(key, "NAME")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
+ if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_NAME, op, value, NULL);
- } else {
+ else {
if (streq(value, "%k")) {
- log_error("NAME=\"%%k\" is ignored, because it breaks kernel supplied names, "
- "please remove it from %s:%u\n", filename, lineno);
+ LOG_RULE_WARNING("NAME=\"%%k\" is ignored, because it breaks kernel supplied names; please remove");
continue;
}
- if (value[0] == '\0') {
- log_debug("NAME=\"\" is ignored, because udev will not delete any device nodes, "
- "please remove it from %s:%u\n", filename, lineno);
+ if (isempty(value)) {
+ LOG_RULE_DEBUG("NAME=\"\" is ignored, because udev will not delete any device nodes; please remove");
continue;
}
rule_add_key(&rule_tmp, TK_A_NAME, op, value, NULL);
}
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "SYMLINK")) {
- if (op == OP_REMOVE) {
- log_error("invalid SYMLINK operation");
- goto invalid;
- }
+ } else if (streq(key, "SYMLINK")) {
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
+
if (op < OP_MATCH_MAX)
rule_add_key(&rule_tmp, TK_M_DEVLINK, op, value, NULL);
else
rule_add_key(&rule_tmp, TK_A_DEVLINK, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "OWNER")) {
+ } else if (streq(key, "OWNER")) {
uid_t uid;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid OWNER operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
uid = strtoul(value, &endptr, 10);
- if (endptr[0] == '\0') {
+ if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
- } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+ else if (rules->resolve_names > 0 && strchr("$%", value[0]) == NULL) {
uid = add_uid(rules, value);
rule_add_key(&rule_tmp, TK_A_OWNER_ID, op, NULL, &uid);
- } else if (rules->resolve_names >= 0) {
+ } else if (rules->resolve_names >= 0)
rule_add_key(&rule_tmp, TK_A_OWNER, op, value, NULL);
- }
+
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "GROUP")) {
+ } else if (streq(key, "GROUP")) {
gid_t gid;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid GROUP operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
gid = strtoul(value, &endptr, 10);
- if (endptr[0] == '\0') {
+ if (endptr[0] == '\0')
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
- } else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
+ else if ((rules->resolve_names > 0) && strchr("$%", value[0]) == NULL) {
gid = add_gid(rules, value);
rule_add_key(&rule_tmp, TK_A_GROUP_ID, op, NULL, &gid);
- } else if (rules->resolve_names >= 0) {
+ } else if (rules->resolve_names >= 0)
rule_add_key(&rule_tmp, TK_A_GROUP, op, value, NULL);
- }
+
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "MODE")) {
+ } else if (streq(key, "MODE")) {
mode_t mode;
char *endptr;
- if (op == OP_REMOVE) {
- log_error("invalid MODE operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
mode = strtol(value, &endptr, 8);
if (endptr[0] == '\0')
@@ -1473,27 +1367,23 @@ static int add_rule(struct udev_rules *rules, char *line,
else
rule_add_key(&rule_tmp, TK_A_MODE, op, value, NULL);
rule_tmp.rule.rule.can_set_name = true;
- continue;
- }
- if (streq(key, "OPTIONS")) {
+ } else if (streq(key, "OPTIONS")) {
const char *pos;
- if (op == OP_REMOVE) {
- log_error("invalid OPTIONS operation");
- goto invalid;
- }
+ if (op == OP_REMOVE)
+ LOG_AND_RETURN("invalid %s operation", key);
pos = strstr(value, "link_priority=");
if (pos != NULL) {
- int prio = atoi(&pos[strlen("link_priority=")]);
+ int prio = atoi(pos + strlen("link_priority="));
rule_add_key(&rule_tmp, TK_A_DEVLINK_PRIO, op, NULL, &prio);
}
pos = strstr(value, "string_escape=");
if (pos != NULL) {
- pos = &pos[strlen("string_escape=")];
+ pos += strlen("string_escape=");
if (startswith(pos, "none"))
rule_add_key(&rule_tmp, TK_A_STRING_ESCAPE_NONE, op, NULL, NULL);
else if (startswith(pos, "replace"))
@@ -1520,30 +1410,19 @@ static int add_rule(struct udev_rules *rules, char *line,
pos = strstr(value, "static_node=");
if (pos != NULL) {
- rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, &pos[strlen("static_node=")], NULL);
+ pos += strlen("static_node=");
+ rule_add_key(&rule_tmp, TK_A_STATIC_NODE, op, pos, NULL);
rule_tmp.rule.rule.has_static_node = true;
}
- continue;
- }
-
- log_error("unknown key '%s' in %s:%u", key, filename, lineno);
- goto invalid;
+ } else
+ LOG_AND_RETURN("unknown key '%s'", key);
}
- /* add rule token */
+ /* add rule token and sort tokens */
rule_tmp.rule.rule.token_count = 1 + rule_tmp.token_cur;
- if (add_token(rules, &rule_tmp.rule) != 0)
- goto invalid;
-
- /* add tokens to list, sorted by type */
- if (sort_token(rules, &rule_tmp) != 0)
- goto invalid;
-
- return 0;
-invalid:
- log_error("invalid rule '%s:%u'", filename, lineno);
- return -1;
+ if (add_token(rules, &rule_tmp.rule) != 0 || sort_token(rules, &rule_tmp) != 0)
+ LOG_RULE_ERROR("failed to add rule token");
}
static int parse_file(struct udev_rules *rules, const char *filename) {
@@ -1686,12 +1565,10 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) {
strbuf_complete(rules->strbuf);
/* cleanup uid/gid cache */
- free(rules->uids);
- rules->uids = NULL;
+ rules->uids = mfree(rules->uids);
rules->uids_cur = 0;
rules->uids_max = 0;
- free(rules->gids);
- rules->gids = NULL;
+ rules->gids = mfree(rules->gids);
rules->gids_cur = 0;
rules->gids_max = 0;
@@ -1844,18 +1721,18 @@ enum escape_type {
ESCAPE_REPLACE,
};
-int udev_rules_apply_to_event(struct udev_rules *rules,
- struct udev_event *event,
- usec_t timeout_usec,
- usec_t timeout_warn_usec,
- struct udev_list *properties_list) {
+void udev_rules_apply_to_event(struct udev_rules *rules,
+ struct udev_event *event,
+ usec_t timeout_usec,
+ usec_t timeout_warn_usec,
+ struct udev_list *properties_list) {
struct token *cur;
struct token *rule;
enum escape_type esc = ESCAPE_UNSET;
bool can_set_name;
if (rules->tokens == NULL)
- return -1;
+ return;
can_set_name = ((!streq(udev_device_get_action(event->dev), "remove")) &&
(major(udev_device_get_devnum(event->dev)) > 0 ||
@@ -1940,7 +1817,8 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
break;
}
}
- if (!match && (cur->key.op != OP_NOMATCH))
+ if ((!match && (cur->key.op != OP_NOMATCH)) ||
+ (match && (cur->key.op == OP_NOMATCH)))
goto nomatch;
break;
}
@@ -2064,8 +1942,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
char program[UTIL_PATH_SIZE];
char result[UTIL_LINE_SIZE];
- free(event->program_result);
- event->program_result = NULL;
+ event->program_result = mfree(event->program_result);
udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program));
log_debug("PROGRAM '%s' %s:%u",
program,
@@ -2125,7 +2002,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rule->rule.filename_line);
/* return the result from earlier run */
if (event->builtin_ret & (1 << cur->key.builtin_cmd))
- if (cur->key.op != OP_NOMATCH)
+ if (cur->key.op != OP_NOMATCH)
goto nomatch;
break;
}
@@ -2163,7 +2040,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
break;
}
case TK_M_IMPORT_CMDLINE: {
- FILE *f;
+ _cleanup_fclose_ FILE *f = NULL;
bool imported = false;
f = fopen("/proc/cmdline", "re");
@@ -2176,12 +2053,12 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
pos = strstr(cmdline, key);
if (pos != NULL) {
+ imported = true;
pos += strlen(key);
- if (pos[0] == '\0' || isspace(pos[0])) {
+ if (pos[0] == '\0' || isspace(pos[0]))
/* we import simple flags as 'FLAG=1' */
udev_device_add_property(event->dev, key, "1");
- imported = true;
- } else if (pos[0] == '=') {
+ else if (pos[0] == '=') {
const char *value;
pos++;
@@ -2190,11 +2067,9 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
pos++;
pos[0] = '\0';
udev_device_add_property(event->dev, key, value);
- imported = true;
}
}
}
- fclose(f);
}
if (!imported && cur->key.op != OP_NOMATCH)
goto nomatch;
@@ -2423,14 +2298,17 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
log_debug("%i character(s) replaced", count);
}
if (major(udev_device_get_devnum(event->dev)) &&
- (!streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/")))) {
- log_error("NAME=\"%s\" ignored, kernel device nodes "
- "can not be renamed; please fix it in %s:%u\n", name,
- rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
+ !streq(name_str, udev_device_get_devnode(event->dev) + strlen("/dev/"))) {
+ log_error("NAME=\"%s\" ignored, kernel device nodes cannot be renamed; please fix it in %s:%u\n",
+ name,
+ rules_str(rules, rule->rule.filename_off),
+ rule->rule.filename_line);
break;
}
- free(event->name);
- event->name = strdup(name_str);
+ if (free_and_strdup(&event->name, name_str) < 0) {
+ log_oom();
+ return;
+ }
log_debug("NAME '%s' %s:%u",
event->name,
rules_str(rules, rule->rule.filename_off),
@@ -2487,7 +2365,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
const char *key_name = rules_str(rules, cur->key.attr_off);
char attr[UTIL_PATH_SIZE];
char value[UTIL_NAME_SIZE];
- FILE *f;
+ _cleanup_fclose_ FILE *f = NULL;
if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0)
strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL);
@@ -2498,13 +2376,10 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off),
rule->rule.filename_line);
f = fopen(attr, "we");
- if (f != NULL) {
- if (fprintf(f, "%s", value) <= 0)
- log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
- fclose(f);
- } else {
+ if (f == NULL)
log_error_errno(errno, "error opening ATTR{%s} for writing: %m", attr);
- }
+ else if (fprintf(f, "%s", value) <= 0)
+ log_error_errno(errno, "error writing ATTR{%s}: %m", attr);
break;
}
case TK_A_SYSCTL: {
@@ -2519,7 +2394,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
rules_str(rules, rule->rule.filename_off), rule->rule.filename_line);
r = sysctl_write(filename, value);
if (r < 0)
- log_error("error writing SYSCTL{%s}='%s': %s", filename, value, strerror(-r));
+ log_error_errno(r, "error writing SYSCTL{%s}='%s': %m", filename, value);
break;
}
case TK_A_RUN_BUILTIN:
@@ -2542,7 +2417,7 @@ int udev_rules_apply_to_event(struct udev_rules *rules,
cur = &rules->tokens[cur->key.rule_goto];
continue;
case TK_END:
- return 0;
+ return;
case TK_M_PARENTS_MIN:
case TK_M_PARENTS_MAX:
@@ -2570,7 +2445,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
char **t;
FILE *f = NULL;
_cleanup_free_ char *path = NULL;
- int r = 0;
+ int r;
if (rules->tokens == NULL)
return 0;
@@ -2590,8 +2465,7 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
uid = 0;
gid = 0;
mode = 0;
- strv_free(tags);
- tags = NULL;
+ tags = strv_free(tags);
break;
case TK_A_OWNER_ID:
uid = cur->key.uid;
@@ -2642,8 +2516,6 @@ int udev_rules_apply_static_dev_perms(struct udev_rules *rules) {
if (r < 0 && errno != EEXIST)
return log_error_errno(errno, "failed to create symlink %s -> %s: %m",
tag_symlink, device_node);
- else
- r = 0;
}
}
@@ -2695,12 +2567,11 @@ finish:
fflush(f);
fchmod(fileno(f), 0644);
if (ferror(f) || rename(path, "/run/udev/static_node-tags") < 0) {
- r = -errno;
- unlink("/run/udev/static_node-tags");
- unlink(path);
+ unlink_noerrno("/run/udev/static_node-tags");
+ unlink_noerrno(path);
+ return -errno;
}
- fclose(f);
}
- return r;
+ return 0;
}
diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c
index 15b76dd6ab..9ce5e975de 100644
--- a/src/udev/udev-watch.c
+++ b/src/udev/udev-watch.c
@@ -17,13 +17,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <errno.h>
-#include <stdio.h>
#include <dirent.h>
+#include <errno.h>
#include <stddef.h>
-#include <unistd.h>
+#include <stdio.h>
#include <sys/inotify.h>
+#include <unistd.h>
+#include "stdio-util.h"
#include "udev.h"
static int inotify_fd = -1;
@@ -83,9 +84,8 @@ unlink:
closedir(dir);
rmdir("/run/udev/watch.old");
- } else if (errno != ENOENT) {
+ } else if (errno != ENOENT)
log_error_errno(errno, "unable to move watches dir /run/udev/watch; old watches will not be restored: %m");
- }
}
void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
@@ -100,11 +100,11 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) {
wd = inotify_add_watch(inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
if (wd < 0) {
log_error_errno(errno, "inotify_add_watch(%d, %s, %o) failed: %m",
- inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
+ inotify_fd, udev_device_get_devnode(dev), IN_CLOSE_WRITE);
return;
}
- snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+ xsprintf(filename, "/run/udev/watch/%d", wd);
mkdir_parents(filename, 0755);
unlink(filename);
r = symlink(udev_device_get_id_filename(dev), filename);
@@ -128,7 +128,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev) {
log_debug("removing watch on '%s'", udev_device_get_devnode(dev));
inotify_rm_watch(inotify_fd, wd);
- snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+ xsprintf(filename, "/run/udev/watch/%d", wd);
unlink(filename);
udev_device_set_watch_handle(dev, -1);
@@ -142,7 +142,7 @@ struct udev_device *udev_watch_lookup(struct udev *udev, int wd) {
if (inotify_fd < 0 || wd < 0)
return NULL;
- snprintf(filename, sizeof(filename), "/run/udev/watch/%d", wd);
+ xsprintf(filename, "/run/udev/watch/%d", wd);
len = readlink(filename, device, sizeof(device));
if (len <= 0 || (size_t)len == sizeof(device))
return NULL;
diff --git a/src/udev/udev.h b/src/udev/udev.h
index d17fc8c1ea..8433e8d9f2 100644
--- a/src/udev/udev.h
+++ b/src/udev/udev.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2003 Greg Kroah-Hartman <greg@kroah.com>
* Copyright (C) 2003-2010 Kay Sievers <kay@vrfy.org>
@@ -16,18 +18,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
-#include <sys/types.h>
#include <sys/param.h>
+#include <sys/sysmacros.h>
+#include <sys/types.h>
-#include "macro.h"
-#include "sd-netlink.h"
#include "libudev.h"
-#include "libudev-private.h"
-#include "util.h"
+#include "sd-netlink.h"
+
#include "label.h"
+#include "libudev-private.h"
+#include "macro.h"
#include "strv.h"
+#include "util.h"
struct udev_event {
struct udev *udev;
@@ -70,9 +72,9 @@ struct udev_rules;
struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names);
struct udev_rules *udev_rules_unref(struct udev_rules *rules);
bool udev_rules_check_timestamp(struct udev_rules *rules);
-int udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
- usec_t timeout_usec, usec_t timeout_warn_usec,
- struct udev_list *properties_list);
+void udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event,
+ usec_t timeout_usec, usec_t timeout_warn_usec,
+ struct udev_list *properties_list);
int udev_rules_apply_static_dev_perms(struct udev_rules *rules);
/* udev-event.c */
diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c
index 78170463b6..6f8e96a123 100644
--- a/src/udev/udevadm-control.c
+++ b/src/udev/udevadm-control.c
@@ -13,15 +13,16 @@
*/
#include <errno.h>
+#include <getopt.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stddef.h>
#include <string.h>
#include <unistd.h>
-#include <getopt.h>
-#include "udev.h"
+#include "time-util.h"
#include "udev-util.h"
+#include "udev.h"
static void print_help(void) {
printf("%s control COMMAND\n\n"
@@ -60,7 +61,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
};
if (getuid() != 0) {
- fprintf(stderr, "root privileges required\n");
+ log_error("root privileges required");
return 1;
}
@@ -81,7 +82,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
i = util_log_priority(optarg);
if (i < 0) {
- fprintf(stderr, "invalid number '%s'\n", optarg);
+ log_error("invalid number '%s'", optarg);
return rc;
}
if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0)
@@ -110,7 +111,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
break;
case 'p':
if (strchr(optarg, '=') == NULL) {
- fprintf(stderr, "expect <KEY>=<value> instead of '%s'\n", optarg);
+ log_error("expect <KEY>=<value> instead of '%s'", optarg);
return rc;
}
if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0)
@@ -124,7 +125,7 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
i = strtoul(optarg, &endp, 0);
if (endp[0] != '\0' || i < 1) {
- fprintf(stderr, "invalid number '%s'\n", optarg);
+ log_error("invalid number '%s'", optarg);
return rc;
}
if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0)
@@ -134,13 +135,21 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
break;
}
case 't': {
+ usec_t s;
int seconds;
+ int r;
+
+ r = parse_sec(optarg, &s);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse timeout value '%s'.", optarg);
- seconds = atoi(optarg);
- if (seconds >= 0)
+ if (((s + USEC_PER_SEC - 1) / USEC_PER_SEC) > INT_MAX)
+ log_error("Timeout value is out of range.");
+ else {
+ seconds = s != USEC_INFINITY ? (int) ((s + USEC_PER_SEC - 1) / USEC_PER_SEC) : INT_MAX;
timeout = seconds;
- else
- fprintf(stderr, "invalid timeout value\n");
+ rc = 0;
+ }
break;
}
case 'h':
@@ -150,9 +159,9 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) {
}
if (optind < argc)
- fprintf(stderr, "Extraneous argument: %s\n", argv[optind]);
+ log_error("Extraneous argument: %s", argv[optind]);
else if (optind == 1)
- fprintf(stderr, "Option missing\n");
+ log_error("Option missing");
return rc;
}
diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c
index 00609e31b5..1bffe8e8ab 100644
--- a/src/udev/udevadm-hwdb.c
+++ b/src/udev/udevadm-hwdb.c
@@ -17,18 +17,23 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
-#include <stdlib.h>
+#include <ctype.h>
#include <getopt.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include "util.h"
-#include "strbuf.h"
+#include "alloc-util.h"
#include "conf-files.h"
-
-#include "udev.h"
+#include "fileio.h"
+#include "fs-util.h"
#include "hwdb-internal.h"
#include "hwdb-util.h"
+#include "label.h"
+#include "mkdir.h"
+#include "strbuf.h"
+#include "string-util.h"
+#include "udev.h"
+#include "util.h"
/*
* Generic udev properties, key/value database based on modalias strings.
@@ -653,16 +658,20 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) {
rc = EXIT_FAILURE;
goto out;
}
- mkdir_parents(hwdb_bin, 0755);
+
+ mkdir_parents_label(hwdb_bin, 0755);
+
err = trie_store(trie, hwdb_bin);
if (err < 0) {
log_error_errno(err, "Failure writing database %s: %m", hwdb_bin);
rc = EXIT_FAILURE;
}
+
+ label_fix(hwdb_bin, false, false);
}
if (test) {
- _cleanup_hwdb_unref_ sd_hwdb *hwdb = NULL;
+ _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL;
int r;
r = sd_hwdb_new(&hwdb);
diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c
index b3d5565c48..6753c52005 100644
--- a/src/udev/udevadm-info.c
+++ b/src/udev/udevadm-info.c
@@ -15,19 +15,21 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
#include <ctype.h>
-#include <unistd.h>
#include <dirent.h>
#include <errno.h>
-#include <getopt.h>
#include <fcntl.h>
+#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/stat.h>
+#include <unistd.h>
-#include "udev.h"
+#include "fd-util.h"
+#include "string-util.h"
#include "udev-util.h"
+#include "udev.h"
#include "udevadm-util.h"
static bool skip_attribute(const char *name) {
@@ -154,7 +156,7 @@ static int stat_device(const char *name, bool export, const char *prefix) {
struct stat statbuf;
if (stat(name, &statbuf) != 0)
- return -1;
+ return -errno;
if (export) {
if (prefix == NULL)
@@ -169,23 +171,22 @@ static int stat_device(const char *name, bool export, const char *prefix) {
}
static int export_devices(struct udev *udev) {
- struct udev_enumerate *udev_enumerate;
+ _cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate;
struct udev_list_entry *list_entry;
udev_enumerate = udev_enumerate_new(udev);
if (udev_enumerate == NULL)
- return -1;
+ return -ENOMEM;
+
udev_enumerate_scan_devices(udev_enumerate);
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
- struct udev_device *device;
+ _cleanup_udev_device_unref_ struct udev_device *device;
device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry));
- if (device != NULL) {
+ if (device != NULL)
print_record(device);
- udev_device_unref(device);
- }
}
- udev_enumerate_unref(udev_enumerate);
+
return 0;
}
@@ -218,39 +219,29 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
}
static void cleanup_db(struct udev *udev) {
- DIR *dir;
+ _cleanup_closedir_ DIR *dir1 = NULL, *dir2 = NULL, *dir3 = NULL, *dir4 = NULL, *dir5 = NULL;
- unlink("/run/udev/queue.bin");
+ (void) unlink("/run/udev/queue.bin");
- dir = opendir("/run/udev/data");
- if (dir != NULL) {
- cleanup_dir(dir, S_ISVTX, 1);
- closedir(dir);
- }
+ dir1 = opendir("/run/udev/data");
+ if (dir1 != NULL)
+ cleanup_dir(dir1, S_ISVTX, 1);
- dir = opendir("/run/udev/links");
- if (dir != NULL) {
- cleanup_dir(dir, 0, 2);
- closedir(dir);
- }
+ dir2 = opendir("/run/udev/links");
+ if (dir2 != NULL)
+ cleanup_dir(dir2, 0, 2);
- dir = opendir("/run/udev/tags");
- if (dir != NULL) {
- cleanup_dir(dir, 0, 2);
- closedir(dir);
- }
+ dir3 = opendir("/run/udev/tags");
+ if (dir3 != NULL)
+ cleanup_dir(dir3, 0, 2);
- dir = opendir("/run/udev/static_node-tags");
- if (dir != NULL) {
- cleanup_dir(dir, 0, 2);
- closedir(dir);
- }
+ dir4 = opendir("/run/udev/static_node-tags");
+ if (dir4 != NULL)
+ cleanup_dir(dir4, 0, 2);
- dir = opendir("/run/udev/watch");
- if (dir != NULL) {
- cleanup_dir(dir, 0, 1);
- closedir(dir);
- }
+ dir5 = opendir("/run/udev/watch");
+ if (dir5 != NULL)
+ cleanup_dir(dir5, 0, 1);
}
static void help(void) {
@@ -372,7 +363,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
action = ACTION_ATTRIBUTE_WALK;
break;
case 'e':
- export_devices(udev);
+ if (export_devices(udev) < 0)
+ return 1;
return 0;
case 'c':
cleanup_db(udev);
@@ -441,17 +433,13 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) {
case QUERY_PROPERTY:
list_entry = udev_device_get_properties_list_entry(device);
while (list_entry != NULL) {
- if (export) {
- const char *prefix = export_prefix;
-
- if (prefix == NULL)
- prefix = "";
- printf("%s%s='%s'\n", prefix,
+ if (export)
+ printf("%s%s='%s'\n", strempty(export_prefix),
udev_list_entry_get_name(list_entry),
udev_list_entry_get_value(list_entry));
- } else {
+ else
printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
- }
+
list_entry = udev_list_entry_get_next(list_entry);
}
break;
diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c
index 5e93955186..f656c2198e 100644
--- a/src/udev/udevadm-monitor.c
+++ b/src/udev/udevadm-monitor.c
@@ -15,19 +15,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stddef.h>
-#include <string.h>
#include <errno.h>
-#include <signal.h>
#include <getopt.h>
-#include <time.h>
-#include <sys/time.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
#include <sys/epoll.h>
+#include <sys/time.h>
+#include <time.h>
-#include "udev.h"
-#include "udev-util.h"
+#include "fd-util.h"
#include "formats-util.h"
+#include "udev-util.h"
+#include "udev.h"
static bool udev_exit;
@@ -39,7 +40,7 @@ static void sig_handler(int signum) {
static void print_device(struct udev_device *device, const char *source, int prop) {
struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
+ assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
printf("%-6s[%"PRI_TIME".%06ld] %-8s %s (%s)\n",
source,
ts.tv_sec, ts.tv_nsec/1000,
@@ -99,7 +100,7 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
udev_list_init(udev, &subsystem_match_list, true);
udev_list_init(udev, &tag_match_list, true);
- while((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "pekus:t:h", options, NULL)) >= 0)
switch (c) {
case 'p':
case 'e':
@@ -150,6 +151,9 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) {
sigaddset(&mask, SIGTERM);
sigprocmask(SIG_UNBLOCK, &mask, NULL);
+ /* Callers are expecting to see events as they happen: Line buffering */
+ setlinebuf(stdout);
+
fd_ep = epoll_create1(EPOLL_CLOEXEC);
if (fd_ep < 0) {
log_error_errno(errno, "error creating epoll fd: %m");
diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c
index 79f45610db..6a5dc6e9e4 100644
--- a/src/udev/udevadm-settle.c
+++ b/src/udev/udevadm-settle.c
@@ -17,15 +17,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stddef.h>
-#include <string.h>
-#include <stdio.h>
-#include <unistd.h>
#include <errno.h>
#include <getopt.h>
#include <poll.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "parse-util.h"
#include "udev.h"
#include "util.h"
@@ -65,10 +66,9 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) {
r = safe_atou(optarg, &timeout);
if (r < 0) {
- fprintf(stderr, "Invalid timeout value '%s': %s\n",
- optarg, strerror(-r));
- exit(EXIT_FAILURE);
- };
+ log_error_errno(r, "Invalid timeout value '%s': %m", optarg);
+ return EXIT_FAILURE;
+ }
break;
}
diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c
index 35a7349439..0b180d03eb 100644
--- a/src/udev/udevadm-test-builtin.c
+++ b/src/udev/udevadm-test-builtin.c
@@ -15,12 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdio.h>
#include <errno.h>
#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "string-util.h"
#include "udev.h"
static void help(struct udev *udev) {
diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c
index d04e618d0d..702dbe5282 100644
--- a/src/udev/udevadm-test.c
+++ b/src/udev/udevadm-test.c
@@ -16,17 +16,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdlib.h>
-#include <stdio.h>
-#include <stddef.h>
-#include <unistd.h>
#include <errno.h>
-#include <signal.h>
#include <getopt.h>
+#include <signal.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <sys/signalfd.h>
+#include <unistd.h>
-#include "udev.h"
+#include "string-util.h"
#include "udev-util.h"
+#include "udev.h"
static void help(void) {
@@ -60,7 +61,7 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) {
log_debug("version %s", VERSION);
- while((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
+ while ((c = getopt_long(argc, argv, "a:N:h", options, NULL)) >= 0)
switch (c) {
case 'a':
action = optarg;
diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c
index 7af9665f8a..9d52345d92 100644
--- a/src/udev/udevadm-trigger.c
+++ b/src/udev/udevadm-trigger.c
@@ -15,16 +15,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
#include <stddef.h>
-#include <string.h>
#include <stdio.h>
+#include <string.h>
#include <unistd.h>
-#include <getopt.h>
-#include <errno.h>
-#include <fcntl.h>
-#include "udev.h"
+#include "string-util.h"
#include "udev-util.h"
+#include "udev.h"
#include "udevadm-util.h"
#include "util.h"
diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c
index 3f0e45e26c..3539c1d6ab 100644
--- a/src/udev/udevadm-util.c
+++ b/src/udev/udevadm-util.c
@@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "string-util.h"
#include "udevadm-util.h"
struct udev_device *find_device(struct udev *udev,
diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h
index 37e4fe8369..dc712b0d93 100644
--- a/src/udev/udevadm-util.h
+++ b/src/udev/udevadm-util.h
@@ -1,3 +1,5 @@
+#pragma once
+
/*
* Copyright (C) 2014 Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
*
@@ -15,8 +17,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#pragma once
-
#include "udev.h"
struct udev_device *find_device(struct udev *udev,
diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c
index b86d8921f3..a6a873e5de 100644
--- a/src/udev/udevadm.c
+++ b/src/udev/udevadm.c
@@ -1,4 +1,3 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
/*
* Copyright (C) 2007-2012 Kay Sievers <kay@vrfy.org>
*
@@ -16,12 +15,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stdio.h>
-#include <stddef.h>
#include <errno.h>
#include <getopt.h>
+#include <stddef.h>
+#include <stdio.h>
#include "selinux-util.h"
+#include "string-util.h"
#include "udev.h"
static int adm_version(struct udev *udev, int argc, char *argv[]) {
@@ -93,7 +93,7 @@ int main(int argc, char *argv[]) {
log_parse_environment();
log_open();
- mac_selinux_init("/dev");
+ mac_selinux_init();
while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0)
switch (c) {
diff --git a/src/udev/udevd.c b/src/udev/udevd.c
index 945845d72c..535d317c27 100644
--- a/src/udev/udevd.c
+++ b/src/udev/udevd.c
@@ -18,44 +18,53 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <stddef.h>
-#include <signal.h>
-#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
-#include <stdbool.h>
#include <string.h>
-#include <fcntl.h>
-#include <getopt.h>
+#include <sys/epoll.h>
#include <sys/file.h>
-#include <sys/time.h>
+#include <sys/inotify.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
#include <sys/prctl.h>
-#include <sys/socket.h>
#include <sys/signalfd.h>
-#include <sys/epoll.h>
-#include <sys/mount.h>
-#include <sys/wait.h>
+#include <sys/socket.h>
#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/inotify.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <unistd.h>
#include "sd-daemon.h"
#include "sd-event.h"
-#include "terminal-util.h"
-#include "signal-util.h"
-#include "event-util.h"
-#include "netlink-util.h"
+#include "alloc-util.h"
#include "cgroup-util.h"
-#include "process-util.h"
+#include "cpu-set-util.h"
#include "dev-setup.h"
+#include "fd-util.h"
#include "fileio.h"
-#include "selinux-util.h"
-#include "udev.h"
-#include "udev-util.h"
#include "formats-util.h"
+#include "fs-util.h"
#include "hashmap.h"
+#include "io-util.h"
+#include "netlink-util.h"
+#include "parse-util.h"
+#include "proc-cmdline.h"
+#include "process-util.h"
+#include "selinux-util.h"
+#include "signal-util.h"
+#include "socket-util.h"
+#include "string-util.h"
+#include "terminal-util.h"
+#include "udev-util.h"
+#include "udev.h"
+#include "user-util.h"
static bool arg_debug = false;
static int arg_daemonize = false;
@@ -181,7 +190,7 @@ static void worker_free(struct worker *worker) {
assert(worker->manager);
- hashmap_remove(worker->manager->workers, UINT_TO_PTR(worker->pid));
+ hashmap_remove(worker->manager->workers, PID_TO_PTR(worker->pid));
udev_monitor_unref(worker->monitor);
event_free(worker->event);
@@ -224,7 +233,7 @@ static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor
if (r < 0)
return r;
- r = hashmap_put(manager->workers, UINT_TO_PTR(pid), worker);
+ r = hashmap_put(manager->workers, PID_TO_PTR(pid), worker);
if (r < 0)
return r;
@@ -261,7 +270,6 @@ static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *use
static void worker_attach_event(struct worker *worker, struct event *event) {
sd_event *e;
uint64_t usec;
- int r;
assert(worker);
assert(worker->manager);
@@ -276,9 +284,7 @@ static void worker_attach_event(struct worker *worker, struct event *event) {
e = worker->manager->event;
- r = sd_event_now(e, clock_boottime_or_monotonic(), &usec);
- if (r < 0)
- return;
+ assert_se(sd_event_now(e, clock_boottime_or_monotonic(), &usec) >= 0);
(void) sd_event_add_time(e, &event->timeout_warning, clock_boottime_or_monotonic(),
usec + arg_event_timeout_warn_usec, USEC_PER_SEC, on_event_timeout_warning, event);
@@ -343,7 +349,7 @@ static void worker_spawn(Manager *manager, struct event *event) {
switch (pid) {
case 0: {
struct udev_device *dev = NULL;
- _cleanup_netlink_unref_ sd_netlink *rtnl = NULL;
+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
int fd_monitor;
_cleanup_close_ int fd_signal = -1, fd_ep = -1;
struct epoll_event ep_signal = { .events = EPOLLIN };
@@ -362,7 +368,6 @@ static void worker_spawn(Manager *manager, struct event *event) {
manager->monitor = udev_monitor_unref(manager->monitor);
manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
manager->ctrl = udev_ctrl_unref(manager->ctrl);
- manager->ctrl_conn_blocking = udev_ctrl_connection_unref(manager->ctrl_conn_blocking);
manager->worker_watch[READ_END] = safe_close(manager->worker_watch[READ_END]);
manager->ctrl_event = sd_event_source_unref(manager->ctrl_event);
@@ -394,10 +399,11 @@ static void worker_spawn(Manager *manager, struct event *event) {
goto out;
}
- /* request TERM signal if parent exits */
- prctl(PR_SET_PDEATHSIG, SIGTERM);
+ /* Request TERM signal if parent exits.
+ Ignore error, not much we can do in that case. */
+ (void) prctl(PR_SET_PDEATHSIG, SIGTERM);
- /* reset OOM score, we only protect the main daemon */
+ /* Reset OOM score, we only protect the main daemon. */
write_string_file("/proc/self/oom_score_adj", "0", 0);
for (;;) {
@@ -749,9 +755,7 @@ static void manager_exit(Manager *manager) {
event_queue_cleanup(manager, EVENT_QUEUED);
manager_kill_workers(manager);
- r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
- if (r < 0)
- return;
+ assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
r = sd_event_add_time(manager->event, NULL, clock_boottime_or_monotonic(),
usec + 30 * USEC_PER_SEC, USEC_PER_SEC, on_exit_timeout, manager);
@@ -772,15 +776,14 @@ static void manager_reload(Manager *manager) {
manager->rules = udev_rules_unref(manager->rules);
udev_builtin_exit(manager->udev);
- sd_notify(false,
- "READY=1\n"
- "STATUS=Processing...");
+ sd_notifyf(false,
+ "READY=1\n"
+ "STATUS=Processing with %u children at max", arg_children_max);
}
static void event_queue_start(Manager *manager) {
struct udev_list_node *loop;
usec_t usec;
- int r;
assert(manager);
@@ -788,17 +791,15 @@ static void event_queue_start(Manager *manager) {
manager->exit || manager->stop_exec_queue)
return;
- r = sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec);
- if (r >= 0) {
- /* check for changed config, every 3 seconds at most */
- if (manager->last_usec == 0 ||
- (usec - manager->last_usec) > 3 * USEC_PER_SEC) {
- if (udev_rules_check_timestamp(manager->rules) ||
- udev_builtin_validate(manager->udev))
- manager_reload(manager);
+ assert_se(sd_event_now(manager->event, clock_boottime_or_monotonic(), &usec) >= 0);
+ /* check for changed config, every 3 seconds at most */
+ if (manager->last_usec == 0 ||
+ (usec - manager->last_usec) > 3 * USEC_PER_SEC) {
+ if (udev_rules_check_timestamp(manager->rules) ||
+ udev_builtin_validate(manager->udev))
+ manager_reload(manager);
- manager->last_usec = usec;
- }
+ manager->last_usec = usec;
}
udev_builtin_init(manager->udev);
@@ -889,7 +890,7 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
}
/* lookup worker who sent the signal */
- worker = hashmap_get(manager->workers, UINT_TO_PTR(ucred->pid));
+ worker = hashmap_get(manager->workers, PID_TO_PTR(ucred->pid));
if (!worker) {
log_debug("worker ["PID_FMT"] returned, but is no longer tracked", ucred->pid);
continue;
@@ -999,6 +1000,10 @@ static int on_ctrl_msg(sd_event_source *s, int fd, uint32_t revents, void *userd
if (i >= 0) {
log_debug("udevd message (SET_MAX_CHILDREN) received, children_max=%i", i);
arg_children_max = i;
+
+ (void) sd_notifyf(false,
+ "READY=1\n"
+ "STATUS=Processing with %u children at max", arg_children_max);
}
if (udev_ctrl_get_ping(ctrl_msg) > 0)
@@ -1193,7 +1198,7 @@ static int on_sigchld(sd_event_source *s, const struct signalfd_siginfo *si, voi
if (pid <= 0)
break;
- worker = hashmap_get(manager->workers, UINT_TO_PTR(pid));
+ worker = hashmap_get(manager->workers, PID_TO_PTR(pid));
if (!worker) {
log_warning("worker ["PID_FMT"] is unknown, ignoring", pid);
continue;
@@ -1255,7 +1260,7 @@ static int on_post(sd_event_source *s, void *userdata) {
return r;
} else if (manager->cgroup)
/* cleanup possible left-over processes in our cgroup */
- cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, false, true, NULL);
+ cg_kill(SYSTEMD_CGROUP_CONTROLLER, manager->cgroup, SIGKILL, CGROUP_IGNORE_SELF, NULL, NULL, NULL);
}
}
@@ -1436,7 +1441,7 @@ static int parse_argv(int argc, char *argv[]) {
assert(argc >= 0);
assert(argv);
- while ((c = getopt_long(argc, argv, "c:de:DtN:hV", options, NULL)) >= 0) {
+ while ((c = getopt_long(argc, argv, "c:de:Dt:N:hV", options, NULL)) >= 0) {
int r;
switch (c) {
@@ -1556,7 +1561,7 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg
r = sd_event_default(&manager->event);
if (r < 0)
- return log_error_errno(errno, "could not allocate event loop: %m");
+ return log_error_errno(r, "could not allocate event loop: %m");
r = sd_event_add_signal(manager->event, NULL, SIGINT, on_sigterm, manager);
if (r < 0)
@@ -1626,9 +1631,9 @@ static int run(int fd_ctrl, int fd_uevent, const char *cgroup) {
if (r < 0)
log_error_errno(r, "failed to apply permissions on static device nodes: %m");
- (void) sd_notify(false,
- "READY=1\n"
- "STATUS=Processing...");
+ (void) sd_notifyf(false,
+ "READY=1\n"
+ "STATUS=Processing with %u children at max", arg_children_max);
r = sd_event_loop(manager->event);
if (r < 0) {
@@ -1649,7 +1654,8 @@ exit:
int main(int argc, char *argv[]) {
_cleanup_free_ char *cgroup = NULL;
- int r, fd_ctrl, fd_uevent;
+ int fd_ctrl = -1, fd_uevent = -1;
+ int r;
log_set_target(LOG_TARGET_AUTO);
log_parse_environment();
@@ -1678,9 +1684,8 @@ int main(int argc, char *argv[]) {
arg_children_max = 8;
- if (sched_getaffinity(0, sizeof (cpu_set), &cpu_set) == 0) {
+ if (sched_getaffinity(0, sizeof(cpu_set), &cpu_set) == 0)
arg_children_max += CPU_COUNT(&cpu_set) * 2;
- }
log_debug("set children_max to %u", arg_children_max);
}
@@ -1694,7 +1699,7 @@ int main(int argc, char *argv[]) {
umask(022);
- r = mac_selinux_init("/dev");
+ r = mac_selinux_init();
if (r < 0) {
log_error_errno(r, "could not initialize labelling: %m");
goto exit;
@@ -1714,7 +1719,7 @@ int main(int argc, char *argv[]) {
by PID1. otherwise we are not guaranteed to have a dedicated cgroup */
r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup);
if (r < 0) {
- if (r == -ENOENT)
+ if (r == -ENOENT || r == -ENOMEDIUM)
log_debug_errno(r, "did not find dedicated cgroup: %m");
else
log_warning_errno(r, "failed to get cgroup: %m");
@@ -1733,8 +1738,13 @@ int main(int argc, char *argv[]) {
log_info("starting version " VERSION);
/* connect /dev/null to stdin, stdout, stderr */
- if (log_get_max_level() < LOG_DEBUG)
- (void) make_null_stdio();
+ if (log_get_max_level() < LOG_DEBUG) {
+ r = make_null_stdio();
+ if (r < 0)
+ log_warning_errno(r, "Failed to redirect standard streams to /dev/null: %m");
+ }
+
+
pid = fork();
switch (pid) {
diff --git a/src/udev/v4l_id/v4l_id.c b/src/udev/v4l_id/v4l_id.c
index 5c57db44c1..aec6676a33 100644
--- a/src/udev/v4l_id/v4l_id.c
+++ b/src/udev/v4l_id/v4l_id.c
@@ -13,19 +13,20 @@
* General Public License for more details:
*/
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
#include <ctype.h>
-#include <stdlib.h>
-#include <unistd.h>
+#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
-#include <sys/types.h>
-#include <sys/time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <linux/videodev2.h>
+#include "fd-util.h"
#include "util.h"
int main(int argc, char *argv[]) {