diff --git a/TODO b/TODO index 4bf66bd217..24cb6829ea 100644 --- a/TODO +++ b/TODO @@ -15,8 +15,6 @@ Janitorial Clean-ups: * rework mount.c and swap.c to follow proper state enumeration/deserialization semantics, like we do for device.c now -* udev: drop "collect", it's nonsense - Features: * optionally, if a per-partition GPT flag is set for the root/home/… partitions diff --git a/src/basic/strbuf.c b/src/basic/strbuf.c index e2ed776a09..275a012b28 100644 --- a/src/basic/strbuf.c +++ b/src/basic/strbuf.c @@ -66,6 +66,9 @@ void strbuf_complete(struct strbuf *str) { /* clean up everything */ void strbuf_cleanup(struct strbuf *str) { + if (!str) + return; + strbuf_complete(str); free(str->buf); free(str); diff --git a/src/libudev/libudev-private.h b/src/libudev/libudev-private.h index af24b7b423..60968b9a2e 100644 --- a/src/libudev/libudev-private.h +++ b/src/libudev/libudev-private.h @@ -123,11 +123,9 @@ int util_log_priority(const char *priority); size_t util_path_encode(const char *src, char *dest, size_t size); int util_replace_whitespace(const char *str, char *to, size_t len); int util_replace_chars(char *str, const char *white); -unsigned int util_string_hash32(const char *key); +uint32_t util_string_hash32(const char *key); uint64_t util_string_bloom64(const char *str); - -/* libudev-util-private.c */ -int util_resolve_subsys_kernel(struct udev *udev, const char *string, char *result, size_t maxsize, int read_value); +int util_resolve_subsys_kernel(const char *string, char *result, size_t maxsize, int read_value); /* Cleanup functions */ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev*, udev_unref); diff --git a/src/libudev/libudev-util.c b/src/libudev/libudev-util.c index f80af9705e..97aedda5da 100644 --- a/src/libudev/libudev-util.c +++ b/src/libudev/libudev-util.c @@ -23,9 +23,8 @@ */ /* handle "[/]" format */ -int util_resolve_subsys_kernel(struct udev *udev, const char *string, - char *result, size_t maxsize, int read_value) -{ +int util_resolve_subsys_kernel(const char *string, + char *result, size_t maxsize, int read_value) { char temp[UTIL_PATH_SIZE]; char *subsys; char *sysname; @@ -58,7 +57,7 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string, if (read_value && attr == NULL) return -1; - dev = udev_device_new_from_subsystem_sysname(udev, subsys, sysname); + dev = udev_device_new_from_subsystem_sysname(NULL, subsys, sysname); if (dev == NULL) return -1; @@ -85,8 +84,7 @@ int util_resolve_subsys_kernel(struct udev *udev, const char *string, return 0; } -int util_log_priority(const char *priority) -{ +int util_log_priority(const char *priority) { char *endptr; int prio; @@ -101,8 +99,7 @@ int util_log_priority(const char *priority) return log_level_from_string(priority); } -size_t util_path_encode(const char *src, char *dest, size_t size) -{ +size_t util_path_encode(const char *src, char *dest, size_t size) { size_t i, j; for (i = 0, j = 0; src[i] != '\0'; i++) { @@ -147,8 +144,7 @@ size_t util_path_encode(const char *src, char *dest, size_t size) * Note this may be called with 'str' == 'to', i.e. to replace whitespace * in-place in a buffer. This function can handle that situation. */ -int util_replace_whitespace(const char *str, char *to, size_t len) -{ +int util_replace_whitespace(const char *str, char *to, size_t len) { size_t i, j; /* strip trailing whitespace */ @@ -176,8 +172,7 @@ int util_replace_whitespace(const char *str, char *to, size_t len) } /* allow chars in whitelist, plain ascii, hex-escaping and valid utf8 */ -int util_replace_chars(char *str, const char *white) -{ +int util_replace_chars(char *str, const char *white) { size_t i = 0; int replaced = 0; @@ -230,21 +225,18 @@ int util_replace_chars(char *str, const char *white) * * Returns: 0 if the entire string was copied, non-zero otherwise. **/ -_public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len) -{ +_public_ int udev_util_encode_string(const char *str, char *str_enc, size_t len) { return encode_devnode_name(str, str_enc, len); } -unsigned int util_string_hash32(const char *str) -{ +uint32_t util_string_hash32(const char *str) { return MurmurHash2(str, strlen(str), 0); } /* get a bunch of bit numbers out of the hash, and set the bits in our bit field */ -uint64_t util_string_bloom64(const char *str) -{ +uint64_t util_string_bloom64(const char *str) { uint64_t bits = 0; - unsigned int hash = util_string_hash32(str); + uint32_t hash = util_string_hash32(str); bits |= 1LLU << (hash & 63); bits |= 1LLU << ((hash >> 6) & 63); diff --git a/src/test/test-udev.c b/src/test/test-udev.c index 93626d9b50..0973b2dfe7 100644 --- a/src/test/test-udev.c +++ b/src/test/test-udev.c @@ -52,7 +52,6 @@ static int fake_filesystems(void) { } int main(int argc, char *argv[]) { - _cleanup_(udev_unrefp) struct udev *udev = NULL; _cleanup_(udev_event_unrefp) struct udev_event *event = NULL; _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; _cleanup_(udev_rules_unrefp) struct udev_rules *rules = NULL; @@ -68,10 +67,6 @@ int main(int argc, char *argv[]) { if (err < 0) return EXIT_FAILURE; - udev = udev_new(); - if (udev == NULL) - return EXIT_FAILURE; - log_debug("version %s", PACKAGE_VERSION); mac_selinux_init(); @@ -87,10 +82,10 @@ int main(int argc, char *argv[]) { goto out; } - rules = udev_rules_new(udev, 1); + rules = udev_rules_new(1); strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL); - dev = udev_device_new_from_synthetic_event(udev, syspath, action); + dev = udev_device_new_from_synthetic_event(NULL, syspath, action); if (dev == NULL) { log_debug("unknown device '%s'", devpath); goto out; diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c index b08588baf7..9ec472824b 100644 --- a/src/udev/ata_id/ata_id.c +++ b/src/udev/ata_id/ata_id.c @@ -23,8 +23,6 @@ #include #include -#include "libudev.h" - #include "fd-util.h" #include "libudev-private.h" #include "log.h" @@ -32,14 +30,13 @@ #define COMMAND_TIMEOUT_MSEC (30 * 1000) -static int disk_scsi_inquiry_command(int fd, - void *buf, - size_t buf_len) -{ +static int disk_scsi_inquiry_command( + int fd, + void *buf, + size_t buf_len) { + uint8_t cdb[6] = { - /* - * INQUIRY, see SPC-4 section 6.4 - */ + /* INQUIRY, see SPC-4 section 6.4 */ [0] = 0x12, /* OPERATION CODE: INQUIRY */ [3] = (buf_len >> 8), /* ALLOCATION LENGTH */ [4] = (buf_len & 0xff), @@ -101,10 +98,11 @@ static int disk_scsi_inquiry_command(int fd, return 0; } -static int disk_identify_command(int fd, - void *buf, - size_t buf_len) -{ +static int disk_identify_command( + int fd, + void *buf, + size_t buf_len) { + uint8_t cdb[12] = { /* * ATA Pass-Through 12 byte command, as described in @@ -171,10 +169,11 @@ static int disk_identify_command(int fd, return 0; } -static int disk_identify_packet_device_command(int fd, - void *buf, - size_t buf_len) -{ +static int disk_identify_packet_device_command( + int fd, + void *buf, + size_t buf_len) { + uint8_t cdb[16] = { /* * ATA Pass-Through 16 byte command, as described in @@ -256,11 +255,12 @@ static int disk_identify_packet_device_command(int fd, * * Copies the ATA string from @identify located at @offset_words into @dest. */ -static void disk_identify_get_string(uint8_t identify[512], - unsigned int offset_words, - char *dest, - size_t dest_len) -{ +static void disk_identify_get_string( + uint8_t identify[512], + unsigned int offset_words, + char *dest, + size_t dest_len) { + unsigned int c1; unsigned int c2; @@ -276,16 +276,15 @@ static void disk_identify_get_string(uint8_t identify[512], } } -static void disk_identify_fixup_string(uint8_t identify[512], - unsigned int offset_words, - size_t len) -{ +static void disk_identify_fixup_string( + uint8_t identify[512], + unsigned int offset_words, + size_t len) { disk_identify_get_string(identify, offset_words, (char *) identify + offset_words * 2, len); } -static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words) -{ +static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offset_words) { uint16_t *p; p = (uint16_t *) identify; @@ -294,7 +293,6 @@ static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offs /** * disk_identify: - * @udev: The libudev context. * @fd: File descriptor for the block device. * @out_identify: Return location for IDENTIFY data. * @out_is_packet_device: Return location for whether returned data is from a IDENTIFY PACKET DEVICE. @@ -308,11 +306,9 @@ static void disk_identify_fixup_uint16 (uint8_t identify[512], unsigned int offs * Returns: 0 if the data was successfully obtained, otherwise * non-zero with errno set. */ -static int disk_identify(struct udev *udev, - int fd, +static int disk_identify(int fd, uint8_t out_identify[512], - int *out_is_packet_device) -{ + int *out_is_packet_device) { int ret; uint8_t inquiry_buf[36]; int peripheral_device_type; @@ -390,7 +386,6 @@ out: } int main(int argc, char *argv[]) { - _cleanup_(udev_unrefp) struct udev *udev = NULL; struct hd_driveid id; union { uint8_t byte[512]; @@ -416,10 +411,6 @@ int main(int argc, char *argv[]) { log_parse_environment(); log_open(); - udev = udev_new(); - if (udev == NULL) - return 0; - for (;;) { int option; @@ -451,7 +442,7 @@ int main(int argc, char *argv[]) { return 1; } - if (disk_identify(udev, fd, identify.byte, &is_packet_device) == 0) { + if (disk_identify(fd, identify.byte, &is_packet_device) == 0) { /* * fix up only the fields from the IDENTIFY data that we are going to * use and copy it into the hd_driveid struct for convenience diff --git a/src/udev/cdrom_id/cdrom_id.c b/src/udev/cdrom_id/cdrom_id.c index ee75bca37c..d95ee4dd5d 100644 --- a/src/udev/cdrom_id/cdrom_id.c +++ b/src/udev/cdrom_id/cdrom_id.c @@ -20,11 +20,10 @@ #include #include -#include "libudev.h" - -#include "libudev-private.h" +#include "log.h" #include "random-util.h" #include "udev-util.h" +#include "util.h" /* device info */ static unsigned int cd_cd_rom; @@ -86,8 +85,7 @@ static unsigned long long int cd_media_session_last_offset; #define ASC(errcode) (((errcode) >> 8) & 0xFF) #define ASCQ(errcode) ((errcode) & 0xFF) -static bool is_mounted(const char *device) -{ +static bool is_mounted(const char *device) { struct stat statbuf; FILE *fp; int maj, min; @@ -109,8 +107,7 @@ static bool is_mounted(const char *device) return mounted; } -static void info_scsi_cmd_err(struct udev *udev, const char *cmd, int err) -{ +static void info_scsi_cmd_err(const char *cmd, int err) { if (err == -1) { log_debug("%s failed", cmd); return; @@ -127,8 +124,7 @@ struct scsi_cmd { struct sg_io_hdr sg_io; }; -static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd) -{ +static void scsi_cmd_init(struct scsi_cmd *cmd) { memzero(cmd, sizeof(struct scsi_cmd)); cmd->cgc.quiet = 1; cmd->cgc.sense = &cmd->_sense.s; @@ -139,16 +135,14 @@ static void scsi_cmd_init(struct udev *udev, struct scsi_cmd *cmd) cmd->sg_io.flags = SG_FLAG_LUN_INHIBIT | SG_FLAG_DIRECT_IO; } -static void scsi_cmd_set(struct udev *udev, struct scsi_cmd *cmd, size_t i, unsigned char arg) -{ +static void scsi_cmd_set(struct scsi_cmd *cmd, size_t i, unsigned char arg) { cmd->sg_io.cmd_len = i + 1; cmd->cgc.cmd[i] = arg; } #define CHECK_CONDITION 0x01 -static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize) -{ +static int scsi_cmd_run(struct scsi_cmd *cmd, int fd, unsigned char *buf, size_t bufsize) { int ret = 0; if (bufsize > 0) { @@ -173,8 +167,7 @@ static int scsi_cmd_run(struct udev *udev, struct scsi_cmd *cmd, int fd, unsigne return ret; } -static int media_lock(struct udev *udev, int fd, bool lock) -{ +static int media_lock(int fd, bool lock) { int err; /* disable the kernel's lock logic */ @@ -189,25 +182,23 @@ static int media_lock(struct udev *udev, int fd, bool lock) return err; } -static int media_eject(struct udev *udev, int fd) -{ +static int media_eject(int fd) { struct scsi_cmd sc; int err; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x1b); - scsi_cmd_set(udev, &sc, 4, 0x02); - scsi_cmd_set(udev, &sc, 5, 0); - err = scsi_cmd_run(udev, &sc, fd, NULL, 0); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x1b); + scsi_cmd_set(&sc, 4, 0x02); + scsi_cmd_set(&sc, 5, 0); + err = scsi_cmd_run(&sc, fd, NULL, 0); if ((err != 0)) { - info_scsi_cmd_err(udev, "START_STOP_UNIT", err); + info_scsi_cmd_err("START_STOP_UNIT", err); return -1; } return 0; } -static int cd_capability_compat(struct udev *udev, int fd) -{ +static int cd_capability_compat(int fd) { int capability; capability = ioctl(fd, CDROM_GET_CAPABILITY, NULL); @@ -233,8 +224,7 @@ static int cd_capability_compat(struct udev *udev, int fd) return 0; } -static int cd_media_compat(struct udev *udev, int fd) -{ +static int cd_media_compat(int fd) { if (ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT) != CDS_DISC_OK) { log_debug("CDROM_DRIVE_STATUS != CDS_DISC_OK"); return -1; @@ -243,19 +233,18 @@ static int cd_media_compat(struct udev *udev, int fd) return 0; } -static int cd_inquiry(struct udev *udev, int fd) -{ +static int cd_inquiry(int fd) { struct scsi_cmd sc; unsigned char inq[128]; int err; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x12); - scsi_cmd_set(udev, &sc, 4, 36); - scsi_cmd_set(udev, &sc, 5, 0); - err = scsi_cmd_run(udev, &sc, fd, inq, 36); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x12); + scsi_cmd_set(&sc, 4, 36); + scsi_cmd_set(&sc, 5, 0); + err = scsi_cmd_run(&sc, fd, inq, 36); if ((err != 0)) { - info_scsi_cmd_err(udev, "INQUIRY", err); + info_scsi_cmd_err("INQUIRY", err); return -1; } @@ -268,8 +257,7 @@ static int cd_inquiry(struct udev *udev, int fd) return 0; } -static void feature_profile_media(struct udev *udev, int cur_profile) -{ +static void feature_profile_media(int cur_profile) { switch (cur_profile) { case 0x03: case 0x04: @@ -377,8 +365,7 @@ static void feature_profile_media(struct udev *udev, int cur_profile) } } -static int feature_profiles(struct udev *udev, const unsigned char *profiles, size_t size) -{ +static int feature_profiles(const unsigned char *profiles, size_t size) { unsigned int i; for (i = 0; i+4 <= size; i += 4) { @@ -467,20 +454,19 @@ static int feature_profiles(struct udev *udev, const unsigned char *profiles, si } /* returns 0 if media was detected */ -static int cd_profiles_old_mmc(struct udev *udev, int fd) -{ +static int cd_profiles_old_mmc(int fd) { struct scsi_cmd sc; int err; unsigned char header[32]; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x51); - scsi_cmd_set(udev, &sc, 8, sizeof(header)); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x51); + scsi_cmd_set(&sc, 8, sizeof(header)); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, header, sizeof(header)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); + info_scsi_cmd_err("READ DISC INFORMATION", err); if (cd_media == 1) { log_debug("no current profile, but disc is present; assuming CD-ROM"); cd_media_cd_rom = 1; @@ -509,8 +495,7 @@ static int cd_profiles_old_mmc(struct udev *udev, int fd) } /* returns 0 if media was detected */ -static int cd_profiles(struct udev *udev, int fd) -{ +static int cd_profiles(int fd) { struct scsi_cmd sc; unsigned char features[65530]; unsigned int cur_profile = 0; @@ -522,18 +507,18 @@ static int cd_profiles(struct udev *udev, int fd) ret = -1; /* First query the current profile */ - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x46); - scsi_cmd_set(udev, &sc, 8, 8); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, features, 8); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x46); + scsi_cmd_set(&sc, 8, 8); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, features, 8); if ((err != 0)) { - info_scsi_cmd_err(udev, "GET CONFIGURATION", err); + info_scsi_cmd_err("GET CONFIGURATION", err); /* handle pre-MMC2 drives which do not support GET CONFIGURATION */ if (SK(err) == 0x5 && IN_SET(ASC(err), 0x20, 0x24)) { log_debug("drive is pre-MMC2 and does not support 46h get configuration command"); log_debug("trying to work around the problem"); - ret = cd_profiles_old_mmc(udev, fd); + ret = cd_profiles_old_mmc(fd); } goto out; } @@ -541,7 +526,7 @@ static int cd_profiles(struct udev *udev, int fd) cur_profile = features[6] << 8 | features[7]; if (cur_profile > 0) { log_debug("current profile 0x%02x", cur_profile); - feature_profile_media (udev, cur_profile); + feature_profile_media(cur_profile); ret = 0; /* we have media */ } else { log_debug("no current profile, assuming no media"); @@ -557,14 +542,14 @@ static int cd_profiles(struct udev *udev, int fd) len = sizeof(features); /* Now get the full feature buffer */ - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x46); - scsi_cmd_set(udev, &sc, 7, ( len >> 8 ) & 0xff); - scsi_cmd_set(udev, &sc, 8, len & 0xff); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, features, len); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x46); + scsi_cmd_set(&sc, 7, ( len >> 8 ) & 0xff); + scsi_cmd_set(&sc, 8, len & 0xff); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, features, len); if ((err != 0)) { - info_scsi_cmd_err(udev, "GET CONFIGURATION", err); + info_scsi_cmd_err("GET CONFIGURATION", err); return -1; } @@ -586,7 +571,7 @@ static int cd_profiles(struct udev *udev, int fd) switch (feature) { case 0x00: log_debug("GET CONFIGURATION: feature 'profiles', with %i entries", features[i+3] / 4); - feature_profiles(udev, &features[i]+4, MIN(features[i+3], len - i - 4)); + feature_profiles(&features[i]+4, MIN(features[i+3], len - i - 4)); break; default: log_debug("GET CONFIGURATION: feature 0x%04x , with 0x%02x bytes", feature, features[i+3]); @@ -597,8 +582,7 @@ out: return ret; } -static int cd_media_info(struct udev *udev, int fd) -{ +static int cd_media_info(int fd) { struct scsi_cmd sc; unsigned char header[32]; static const char *media_status[] = { @@ -609,13 +593,13 @@ static int cd_media_info(struct udev *udev, int fd) }; int err; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x51); - scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x51); + scsi_cmd_set(&sc, 8, sizeof(header) & 0xff); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, header, sizeof(header)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ DISC INFORMATION", err); + info_scsi_cmd_err("READ DISC INFORMATION", err); return -1; }; @@ -647,14 +631,14 @@ static int cd_media_info(struct udev *udev, int fd) unsigned char dvdstruct[8]; unsigned char format[12]; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0xAD); - scsi_cmd_set(udev, &sc, 7, 0xC0); - scsi_cmd_set(udev, &sc, 9, sizeof(dvdstruct)); - scsi_cmd_set(udev, &sc, 11, 0); - err = scsi_cmd_run(udev, &sc, fd, dvdstruct, sizeof(dvdstruct)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0xAD); + scsi_cmd_set(&sc, 7, 0xC0); + scsi_cmd_set(&sc, 9, sizeof(dvdstruct)); + scsi_cmd_set(&sc, 11, 0); + err = scsi_cmd_run(&sc, fd, dvdstruct, sizeof(dvdstruct)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ DVD STRUCTURE", err); + info_scsi_cmd_err("READ DVD STRUCTURE", err); return -1; } if (dvdstruct[4] & 0x02) { @@ -664,13 +648,13 @@ static int cd_media_info(struct udev *udev, int fd) } /* let's make sure we don't try to read unformatted media */ - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x23); - scsi_cmd_set(udev, &sc, 8, sizeof(format)); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, format, sizeof(format)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x23); + scsi_cmd_set(&sc, 8, sizeof(format)); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, format, sizeof(format)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ DVD FORMAT CAPACITIES", err); + info_scsi_cmd_err("READ DVD FORMAT CAPACITIES", err); return -1; } @@ -705,15 +689,15 @@ static int cd_media_info(struct udev *udev, int fd) * has "blank" status", DVD-RAM was examined earlier) and check * for ISO and UDF PVDs or a fs superblock presence and do it * in one ioctl (we need just sectors 0 and 16) */ - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x28); - scsi_cmd_set(udev, &sc, 5, 0); - scsi_cmd_set(udev, &sc, 8, 32); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, buffer, sizeof(buffer)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x28); + scsi_cmd_set(&sc, 5, 0); + scsi_cmd_set(&sc, 8, 32); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, buffer, sizeof(buffer)); if ((err != 0)) { cd_media = 0; - info_scsi_cmd_err(udev, "READ FIRST 32 BLOCKS", err); + info_scsi_cmd_err("READ FIRST 32 BLOCKS", err); return -1; } @@ -750,8 +734,7 @@ determined: return 0; } -static int cd_media_toc(struct udev *udev, int fd) -{ +static int cd_media_toc(int fd) { struct scsi_cmd sc; unsigned char header[12]; unsigned char toc[65536]; @@ -759,14 +742,14 @@ static int cd_media_toc(struct udev *udev, int fd) unsigned char *p; int err; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x43); - scsi_cmd_set(udev, &sc, 6, 1); - scsi_cmd_set(udev, &sc, 8, sizeof(header) & 0xff); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x43); + scsi_cmd_set(&sc, 6, 1); + scsi_cmd_set(&sc, 8, sizeof(header) & 0xff); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, header, sizeof(header)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ TOC", err); + info_scsi_cmd_err("READ TOC", err); return -1; } @@ -783,15 +766,15 @@ static int cd_media_toc(struct udev *udev, int fd) if (len < 8) return 0; - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x43); - scsi_cmd_set(udev, &sc, 6, header[2]); /* First Track/Session Number */ - scsi_cmd_set(udev, &sc, 7, (len >> 8) & 0xff); - scsi_cmd_set(udev, &sc, 8, len & 0xff); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, toc, len); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x43); + scsi_cmd_set(&sc, 6, header[2]); /* First Track/Session Number */ + scsi_cmd_set(&sc, 7, (len >> 8) & 0xff); + scsi_cmd_set(&sc, 8, len & 0xff); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, toc, len); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ TOC (tracks)", err); + info_scsi_cmd_err("READ TOC (tracks)", err); return -1; } @@ -814,14 +797,14 @@ static int cd_media_toc(struct udev *udev, int fd) cd_media_track_count_audio++; } - scsi_cmd_init(udev, &sc); - scsi_cmd_set(udev, &sc, 0, 0x43); - scsi_cmd_set(udev, &sc, 2, 1); /* Session Info */ - scsi_cmd_set(udev, &sc, 8, sizeof(header)); - scsi_cmd_set(udev, &sc, 9, 0); - err = scsi_cmd_run(udev, &sc, fd, header, sizeof(header)); + scsi_cmd_init(&sc); + scsi_cmd_set(&sc, 0, 0x43); + scsi_cmd_set(&sc, 2, 1); /* Session Info */ + scsi_cmd_set(&sc, 8, sizeof(header)); + scsi_cmd_set(&sc, 9, 0); + err = scsi_cmd_run(&sc, fd, header, sizeof(header)); if ((err != 0)) { - info_scsi_cmd_err(udev, "READ TOC (multi session)", err); + info_scsi_cmd_err("READ TOC (multi session)", err); return -1; } len = header[4+4] << 24 | header[4+5] << 16 | header[4+6] << 8 | header[4+7]; @@ -831,7 +814,6 @@ static int cd_media_toc(struct udev *udev, int fd) } int main(int argc, char *argv[]) { - struct udev *udev; static const struct option options[] = { { "lock-media", no_argument, NULL, 'l' }, { "unlock-media", no_argument, NULL, 'u' }, @@ -853,10 +835,6 @@ int main(int argc, char *argv[]) { log_parse_environment(); log_open(); - udev = udev_new(); - if (udev == NULL) - goto exit; - for (;;) { int option; @@ -896,7 +874,6 @@ int main(int argc, char *argv[]) { node = argv[optind]; if (!node) { log_error("no device"); - fprintf(stderr, "no device\n"); rc = 1; goto exit; } @@ -914,55 +891,54 @@ int main(int argc, char *argv[]) { } if (fd < 0) { log_debug("unable to open '%s'", node); - fprintf(stderr, "unable to open '%s'\n", node); rc = 1; goto exit; } log_debug("probing: '%s'", node); /* same data as original cdrom_id */ - if (cd_capability_compat(udev, fd) < 0) { + if (cd_capability_compat(fd) < 0) { rc = 1; goto exit; } /* check for media - don't bail if there's no media as we still need to * to read profiles */ - cd_media_compat(udev, fd); + cd_media_compat(fd); /* check if drive talks MMC */ - if (cd_inquiry(udev, fd) < 0) + if (cd_inquiry(fd) < 0) goto work; /* read drive and possibly current profile */ - if (cd_profiles(udev, fd) != 0) + if (cd_profiles(fd) != 0) goto work; /* at this point we are guaranteed to have media in the drive - find out more about it */ /* get session/track info */ - cd_media_toc(udev, fd); + cd_media_toc(fd); /* get writable media state */ - cd_media_info(udev, fd); + cd_media_info(fd); work: /* lock the media, so we enable eject button events */ if (lock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (lock)"); - media_lock(udev, fd, true); + media_lock(fd, true); } if (unlock && cd_media) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); - media_lock(udev, fd, false); + media_lock(fd, false); } if (eject) { log_debug("PREVENT_ALLOW_MEDIUM_REMOVAL (unlock)"); - media_lock(udev, fd, false); + media_lock(fd, false); log_debug("START_STOP_UNIT (eject)"); - media_eject(udev, fd); + media_eject(fd); } printf("ID_CDROM=1\n"); @@ -1067,7 +1043,6 @@ work: exit: if (fd >= 0) close(fd); - udev_unref(udev); log_close(); return rc; } diff --git a/src/udev/collect/collect.c b/src/udev/collect/collect.c deleted file mode 100644 index 39fd03d152..0000000000 --- a/src/udev/collect/collect.c +++ /dev/null @@ -1,478 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Collect variables across events. - * - * usage: collect [--add|--remove] - * - * Adds ID to the list governed by . - * must be part of the ID list . - * If all IDs given by are listed (ie collect has been - * invoked for each ID in ) collect returns 0, the - * number of missing IDs otherwise. - * A negative number is returned on error. - * - * Copyright © 2007, Hannes Reinecke - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - */ - -#include -#include -#include -#include - -#include "alloc-util.h" -#include "libudev-private.h" -#include "macro.h" -#include "stdio-util.h" -#include "string-util.h" -#include "udev-util.h" - -#define BUFSIZE 16 -#define UDEV_ALARM_TIMEOUT 180 - -enum collect_state { - STATE_NONE, - STATE_OLD, - STATE_CONFIRMED, -}; - -struct _mate { - struct udev_list_node node; - char *name; - enum collect_state state; -}; - -static struct udev_list_node bunch; -static int debug; - -/* This can increase dynamically */ -static size_t bufsize = BUFSIZE; - -static inline struct _mate *node_to_mate(struct udev_list_node *node) -{ - return container_of(node, struct _mate, node); -} - -_noreturn_ static void sig_alrm(int signo) -{ - _exit(4); -} - -static void usage(void) -{ - printf("%s [options] \n\n" - "Collect variables across events.\n\n" - " -h --help Print this message\n" - " -a --add Add ID to the list \n" - " -r --remove Remove ID from the list \n" - " -d --debug Debug to stderr\n\n" - " Adds ID to the list governed by .\n" - " must be part of the list .\n" - " If all IDs given by are listed (ie collect has been\n" - " invoked for each ID in ) collect returns 0, the\n" - " number of missing IDs otherwise.\n" - " On error a negative number is returned.\n\n" - , program_invocation_short_name); -} - -/* - * prepare - * - * Prepares the database file - */ -static int prepare(char *dir, char *filename) -{ - char buf[PATH_MAX]; - int r, fd; - - r = mkdir(dir, 0700); - if (r < 0 && errno != EEXIST) - return -errno; - - snprintf(buf, sizeof buf, "%s/%s", dir, filename); - - fd = open(buf, O_RDWR|O_CREAT|O_CLOEXEC, S_IRUSR|S_IWUSR); - if (fd < 0) - fprintf(stderr, "Cannot open %s: %m\n", buf); - - if (lockf(fd,F_TLOCK,0) < 0) { - if (debug) - fprintf(stderr, "Lock taken, wait for %d seconds\n", UDEV_ALARM_TIMEOUT); - if (IN_SET(errno, EAGAIN, EACCES)) { - alarm(UDEV_ALARM_TIMEOUT); - lockf(fd, F_LOCK, 0); - if (debug) - fprintf(stderr, "Acquired lock on %s\n", buf); - } else { - if (debug) - fprintf(stderr, "Could not get lock on %s: %m\n", buf); - } - } - - return fd; -} - -/* - * Read checkpoint file - * - * Tricky reading this. We allocate a buffer twice as large - * as we're going to read. Then we read into the upper half - * of that buffer and start parsing. - * Once we do _not_ find end-of-work terminator (whitespace - * character) we move the upper half to the lower half, - * adjust the read pointer and read the next bit. - * Quite clever methinks :-) - * I should become a programmer ... - * - * Yes, one could have used fgets() for this. But then we'd - * have to use freopen etc which I found quite tedious. - */ -static int checkout(int fd) -{ - int len; - _cleanup_free_ char *buf = NULL; - char *ptr, *word = NULL; - struct _mate *him; - - restart: - len = bufsize >> 1; - buf = malloc(bufsize + 1); - if (!buf) - return log_oom(); - memset(buf, ' ', bufsize); - buf[bufsize] = '\0'; - - ptr = buf + len; - while ((read(fd, buf + len, len)) > 0) { - while (ptr && *ptr) { - word = ptr; - ptr = strpbrk(word," \n\t\r"); - if (!ptr && word < (buf + len)) { - bufsize = bufsize << 1; - if (debug) - fprintf(stderr, "ID overflow, restarting with size %zu\n", bufsize); - lseek(fd, 0, SEEK_SET); - goto restart; - } - if (ptr) { - *ptr = '\0'; - ptr++; - if (isempty(word)) - continue; - - if (debug) - fprintf(stderr, "Found word %s\n", word); - him = malloc(sizeof (struct _mate)); - if (!him) - return log_oom(); - him->name = strdup(word); - if (!him->name) { - free(him); - return log_oom(); - } - him->state = STATE_OLD; - udev_list_node_append(&him->node, &bunch); - word = NULL; - } - } - memcpy(buf, buf + len, len); - memset(buf + len, ' ', len); - - if (!ptr) - ptr = word; - ptr -= len; - } - - return 0; -} - -/* - * invite - * - * Adds a new ID 'us' to the internal list, - * marks it as confirmed. - */ -static void invite(char *us) -{ - struct udev_list_node *him_node; - struct _mate *who = NULL; - - if (debug) - fprintf(stderr, "Adding ID '%s'\n", us); - - udev_list_node_foreach(him_node, &bunch) { - struct _mate *him = node_to_mate(him_node); - - if (streq(him->name, us)) { - him->state = STATE_CONFIRMED; - who = him; - } - } - if (debug && !who) - fprintf(stderr, "ID '%s' not in database\n", us); - -} - -/* - * reject - * - * Marks the ID 'us' as invalid, - * causing it to be removed when the - * list is written out. - */ -static void reject(char *us) -{ - struct udev_list_node *him_node; - struct _mate *who = NULL; - - if (debug) - fprintf(stderr, "Removing ID '%s'\n", us); - - udev_list_node_foreach(him_node, &bunch) { - struct _mate *him = node_to_mate(him_node); - - if (streq(him->name, us)) { - him->state = STATE_NONE; - who = him; - } - } - if (debug && !who) - fprintf(stderr, "ID '%s' not in database\n", us); -} - -/* - * kickout - * - * Remove all IDs in the internal list which are not part - * of the list passed via the command line. - */ -static void kickout(void) -{ - struct udev_list_node *him_node; - struct udev_list_node *tmp; - - udev_list_node_foreach_safe(him_node, tmp, &bunch) { - struct _mate *him = node_to_mate(him_node); - - if (him->state == STATE_OLD) { - udev_list_node_remove(&him->node); - free(him->name); - free(him); - } - } -} - -/* - * missing - * - * Counts all missing IDs in the internal list. - */ -static int missing(int fd) -{ - char *buf; - int ret = 0; - struct udev_list_node *him_node; - - buf = malloc(bufsize); - if (!buf) - return log_oom(); - - udev_list_node_foreach(him_node, &bunch) { - struct _mate *him = node_to_mate(him_node); - - if (him->state == STATE_NONE) { - ret++; - } else { - while (strlen(him->name)+1 >= bufsize) { - char *tmpbuf; - - bufsize = bufsize << 1; - tmpbuf = realloc(buf, bufsize); - if (!tmpbuf) { - free(buf); - return log_oom(); - } - buf = tmpbuf; - } - snprintf(buf, strlen(him->name)+2, "%s ", him->name); - if (write(fd, buf, strlen(buf)) < 0) { - free(buf); - return -1; - } - } - } - - free(buf); - return ret; -} - -/* - * everybody - * - * Prints out the status of the internal list. - */ -static void everybody(void) -{ - struct udev_list_node *him_node; - const char *state = ""; - - udev_list_node_foreach(him_node, &bunch) { - struct _mate *him = node_to_mate(him_node); - - switch (him->state) { - case STATE_NONE: - state = "none"; - break; - case STATE_OLD: - state = "old"; - break; - case STATE_CONFIRMED: - state = "confirmed"; - break; - } - fprintf(stderr, "ID: %s=%s\n", him->name, state); - } -} - -int main(int argc, char **argv) { - static const struct option options[] = { - { "add", no_argument, NULL, 'a' }, - { "remove", no_argument, NULL, 'r' }, - { "debug", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - {} - }; - int argi; - char *checkpoint, *us; - int fd; - int i; - int ret = EXIT_SUCCESS; - int prune = 0; - char tmpdir[UTIL_PATH_SIZE]; - - log_set_target(LOG_TARGET_AUTO); - udev_parse_config(); - log_parse_environment(); - log_open(); - - for (;;) { - int option; - - option = getopt_long(argc, argv, "ardh", options, NULL); - if (option == -1) - break; - - switch (option) { - case 'a': - prune = 0; - break; - case 'r': - prune = 1; - break; - case 'd': - debug = 1; - break; - case 'h': - usage(); - return 0; - default: - return 1; - } - } - - argi = optind; - if (argi + 2 > argc) { - printf("Missing parameter(s)\n"); - return 1; - } - checkpoint = argv[argi++]; - us = argv[argi++]; - - if (signal(SIGALRM, sig_alrm) == SIG_ERR) { - fprintf(stderr, "Cannot set SIGALRM: %m\n"); - return 2; - } - - udev_list_node_init(&bunch); - - if (debug) - fprintf(stderr, "Using checkpoint '%s'\n", checkpoint); - - strscpyl(tmpdir, sizeof(tmpdir), "/run/udev/collect", NULL); - fd = prepare(tmpdir, checkpoint); - if (fd < 0) { - ret = 3; - goto out; - } - - if (checkout(fd) < 0) { - ret = 2; - goto out; - } - - for (i = argi; i < argc; i++) { - struct udev_list_node *him_node; - struct _mate *who; - - who = NULL; - udev_list_node_foreach(him_node, &bunch) { - struct _mate *him = node_to_mate(him_node); - - if (streq(him->name, argv[i])) - who = him; - } - if (!who) { - struct _mate *him; - - if (debug) - fprintf(stderr, "ID %s: not in database\n", argv[i]); - him = new(struct _mate, 1); - if (!him) { - ret = ENOMEM; - goto out; - } - - him->name = strdup(argv[i]); - if (!him->name) { - free(him); - ret = ENOMEM; - goto out; - } - - him->state = STATE_NONE; - udev_list_node_append(&him->node, &bunch); - } else { - if (debug) - fprintf(stderr, "ID %s: found in database\n", argv[i]); - who->state = STATE_CONFIRMED; - } - } - - if (prune) - reject(us); - else - invite(us); - - if (debug) { - everybody(); - fprintf(stderr, "Prune lists\n"); - } - kickout(); - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - ret = missing(fd); - - lockf(fd, F_ULOCK, 0); - close(fd); -out: - if (debug) - everybody(); - if (ret >= 0) - printf("COLLECT_%s=%d\n", checkpoint, ret); - return ret; -} diff --git a/src/udev/meson.build b/src/udev/meson.build index 3bcd2bd3d7..665cb83fb8 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -2,14 +2,15 @@ udevadm_sources = files(''' udevadm.c - udevadm-info.c + udevadm.h udevadm-control.c - udevadm-monitor.c udevadm-hwdb.c + udevadm-info.c + udevadm-monitor.c udevadm-settle.c - udevadm-trigger.c udevadm-test.c udevadm-test-builtin.c + udevadm-trigger.c udevadm-util.c udevadm-util.h '''.split()) @@ -159,7 +160,6 @@ libudev_core = static_library( foreach prog : [['ata_id/ata_id.c'], ['cdrom_id/cdrom_id.c'], - ['collect/collect.c'], ['scsi_id/scsi_id.c', 'scsi_id/scsi_id.h', 'scsi_id/scsi_serial.c', diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 7d0dee5902..e9f7e7429f 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -2,6 +2,7 @@ #include +#include "sd-device.h" #include "sd-netlink.h" #include "alloc-util.h" @@ -9,8 +10,6 @@ #include "conf-parser.h" #include "ethtool-util.h" #include "fd-util.h" -#include "libudev-device-internal.h" -#include "libudev-private.h" #include "link-config.h" #include "log.h" #include "missing.h" @@ -218,8 +217,7 @@ bool link_config_should_reload(link_config_ctx *ctx) { return paths_check_timestamp(link_dirs, &ctx->link_dirs_ts_usec, false); } -int link_config_get(link_config_ctx *ctx, struct udev_device *device, - link_config **ret) { +int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) { link_config *link; assert(ctx); @@ -227,43 +225,50 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device, assert(ret); LIST_FOREACH(links, link, ctx->links) { - const char* attr_value; + const char *address = NULL, *id_path = NULL, *parent_driver = NULL, *id_net_driver = NULL, *devtype = NULL, *sysname = NULL; + sd_device *parent; - attr_value = udev_device_get_sysattr_value(device, "address"); + (void) sd_device_get_sysattr_value(device, "address", &address); + (void) sd_device_get_property_value(device, "ID_PATH", &id_path); + if (sd_device_get_parent(device, &parent) >= 0) + (void) sd_device_get_driver(parent, &parent_driver); + (void) sd_device_get_property_value(device, "ID_NET_DRIVER", &id_net_driver); + (void) sd_device_get_devtype(device, &devtype); + (void) sd_device_get_sysname(device, &sysname); if (net_match_config(link->match_mac, link->match_path, link->match_driver, link->match_type, link->match_name, link->match_host, link->match_virt, link->match_kernel_cmdline, link->match_kernel_version, link->match_arch, - attr_value ? ether_aton(attr_value) : NULL, - udev_device_get_property_value(device, "ID_PATH"), - udev_device_get_driver(udev_device_get_parent(device)), - udev_device_get_property_value(device, "ID_NET_DRIVER"), - udev_device_get_devtype(device), - udev_device_get_sysname(device))) { + address ? ether_aton(address) : NULL, + id_path, + parent_driver, + id_net_driver, + devtype, + sysname)) { if (link->match_name) { unsigned char name_assign_type = NET_NAME_UNKNOWN; + const char *attr_value; - attr_value = udev_device_get_sysattr_value(device, "name_assign_type"); - if (attr_value) + if (sd_device_get_sysattr_value(device, "name_assign_type", &attr_value) >= 0) (void) safe_atou8(attr_value, &name_assign_type); if (name_assign_type == NET_NAME_ENUM) { log_warning("Config file %s applies to device based on potentially unpredictable interface name '%s'", - link->filename, udev_device_get_sysname(device)); + link->filename, sysname); *ret = link; return 0; } else if (name_assign_type == NET_NAME_RENAMED) { log_warning("Config file %s matches device based on renamed interface name '%s', ignoring", - link->filename, udev_device_get_sysname(device)); + link->filename, sysname); continue; } } log_debug("Config file %s applies to device %s", - link->filename, udev_device_get_sysname(device)); + link->filename, sysname); *ret = link; @@ -276,14 +281,13 @@ int link_config_get(link_config_ctx *ctx, struct udev_device *device, return -ENOENT; } -static bool mac_is_random(struct udev_device *device) { +static bool mac_is_random(sd_device *device) { const char *s; unsigned type; int r; /* if we can't get the assign type, assume it is not random */ - s = udev_device_get_sysattr_value(device, "addr_assign_type"); - if (!s) + if (sd_device_get_sysattr_value(device, "addr_assign_type", &s) < 0) return false; r = safe_atou(s, &type); @@ -293,14 +297,13 @@ static bool mac_is_random(struct udev_device *device) { return type == NET_ADDR_RANDOM; } -static bool should_rename(struct udev_device *device, bool respect_predictable) { +static bool should_rename(sd_device *device, bool respect_predictable) { const char *s; unsigned type; int r; /* if we can't get the assgin type, assume we should rename */ - s = udev_device_get_sysattr_value(device, "name_assign_type"); - if (!s) + if (sd_device_get_sysattr_value(device, "name_assign_type", &s) < 0) return true; r = safe_atou(s, &type); @@ -324,7 +327,7 @@ static bool should_rename(struct udev_device *device, bool respect_predictable) } } -static int get_mac(struct udev_device *device, bool want_random, +static int get_mac(sd_device *device, bool want_random, struct ether_addr *mac) { int r; @@ -333,7 +336,7 @@ static int get_mac(struct udev_device *device, bool want_random, else { uint64_t result; - r = net_get_unique_predictable_data(device->device, &result); + r = net_get_unique_predictable_data(device, &result); if (r < 0) return r; @@ -349,7 +352,7 @@ static int get_mac(struct udev_device *device, bool want_random, } int link_config_apply(link_config_ctx *ctx, link_config *config, - struct udev_device *device, const char **name) { + sd_device *device, const char **name) { bool respect_predictable = false; struct ether_addr generated_mac; struct ether_addr *mac = NULL; @@ -363,9 +366,9 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, assert(device); assert(name); - old_name = udev_device_get_sysname(device); - if (!old_name) - return -EINVAL; + r = sd_device_get_sysname(device, &old_name); + if (r < 0) + return r; r = ethtool_set_glinksettings(&ctx->ethtool_fd, old_name, config); if (r < 0) { @@ -397,11 +400,11 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, log_warning_errno(r, "Could not set channels of %s: %m", old_name); } - ifindex = udev_device_get_ifindex(device); - if (ifindex <= 0) { - log_warning("Could not find ifindex"); - return -ENODEV; - } + r = sd_device_get_ifindex(device, &ifindex); + if (r < 0) + return log_warning_errno(r, "Could not find ifindex: %m"); + if (ifindex <= 0) + return log_warning_errno(EINVAL, "Invalid ifindex '%d'", ifindex); if (ctx->enable_name_policy && config->name_policy) { NamePolicy *policy; @@ -413,19 +416,19 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, respect_predictable = true; break; case NAMEPOLICY_DATABASE: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE"); + (void) sd_device_get_property_value(device, "ID_NET_NAME_FROM_DATABASE", &new_name); break; case NAMEPOLICY_ONBOARD: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_ONBOARD"); + (void) sd_device_get_property_value(device, "ID_NET_NAME_ONBOARD", &new_name); break; case NAMEPOLICY_SLOT: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_SLOT"); + (void) sd_device_get_property_value(device, "ID_NET_NAME_SLOT", &new_name); break; case NAMEPOLICY_PATH: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_PATH"); + (void) sd_device_get_property_value(device, "ID_NET_NAME_PATH", &new_name); break; case NAMEPOLICY_MAC: - new_name = udev_device_get_property_value(device, "ID_NET_NAME_MAC"); + (void) sd_device_get_property_value(device, "ID_NET_NAME_MAC", &new_name); break; default: break; @@ -477,14 +480,14 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, return 0; } -int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret) { +int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret) { const char *name; char *driver = NULL; int r; - name = udev_device_get_sysname(device); - if (!name) - return -EINVAL; + r = sd_device_get_sysname(device, &name); + if (r < 0) + return r; r = ethtool_get_driver(&ctx->ethtool_fd, name, &driver); if (r < 0) diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index c8f4367921..3f78785faa 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #pragma once -#include "libudev.h" +#include "sd-device.h" #include "condition.h" #include "ethtool-util.h" @@ -68,10 +68,9 @@ void link_config_ctx_free(link_config_ctx *ctx); int link_config_load(link_config_ctx *ctx); bool link_config_should_reload(link_config_ctx *ctx); -int link_config_get(link_config_ctx *ctx, struct udev_device *device, struct link_config **ret); -int link_config_apply(link_config_ctx *ctx, struct link_config *config, struct udev_device *device, const char **name); - -int link_get_driver(link_config_ctx *ctx, struct udev_device *device, char **ret); +int link_config_get(link_config_ctx *ctx, sd_device *device, struct link_config **ret); +int link_config_apply(link_config_ctx *ctx, struct link_config *config, sd_device *device, const char **name); +int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret); const char *name_policy_to_string(NamePolicy p) _const_; NamePolicy name_policy_from_string(const char *p) _pure_; diff --git a/src/udev/scsi_id/scsi_id.c b/src/udev/scsi_id/scsi_id.c index 313ad74bf0..2cace552f2 100644 --- a/src/udev/scsi_id/scsi_id.c +++ b/src/udev/scsi_id/scsi_id.c @@ -17,8 +17,6 @@ #include #include -#include "libudev.h" - #include "alloc-util.h" #include "fd-util.h" #include "libudev-private.h" @@ -55,8 +53,7 @@ static char model_enc_str[256]; static char revision_str[16]; static char type_str[16]; -static void set_type(const char *from, char *to, size_t len) -{ +static void set_type(const char *from, char *to, size_t len) { int type_num; char *eptr; const char *type = "generic"; @@ -101,8 +98,7 @@ static void set_type(const char *from, char *to, size_t len) * Return a pointer to the NUL terminated string, returns NULL if no * matches. */ -static char *get_value(char **buffer) -{ +static char *get_value(char **buffer) { static const char *quote_string = "\"\n"; static const char *comma_string = ",\n"; char *val; @@ -130,8 +126,7 @@ static char *get_value(char **buffer) return val; } -static int argc_count(char *opts) -{ +static int argc_count(char *opts) { int i = 0; while (*opts != '\0') if (*opts++ == ' ') @@ -148,10 +143,8 @@ static int argc_count(char *opts) * * vendor and model can end in '\n'. */ -static int get_file_options(struct udev *udev, - const char *vendor, const char *model, - int *argc, char ***newargv) -{ +static int get_file_options(const char *vendor, const char *model, + int *argc, char ***newargv) { _cleanup_free_ char *buffer = NULL; _cleanup_fclose_ FILE *f; char *buf; @@ -311,10 +304,8 @@ static void help(void) { } -static int set_options(struct udev *udev, - int argc, char **argv, - char *maj_min_dev) -{ +static int set_options(int argc, char **argv, + char *maj_min_dev) { int option; /* @@ -400,9 +391,7 @@ static int set_options(struct udev *udev, return 0; } -static int per_dev_options(struct udev *udev, - struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) -{ +static int per_dev_options(struct scsi_id_device *dev_scsi, int *good_bad, int *page_code) { int retval; int newargc; char **newargv = NULL; @@ -411,7 +400,7 @@ static int per_dev_options(struct udev *udev, *good_bad = all_good; *page_code = default_page_code; - retval = get_file_options(udev, vendor_str, model_str, &newargc, &newargv); + retval = get_file_options(vendor_str, model_str, &newargc, &newargv); optind = 1; /* reset this global extern */ while (retval == 0) { @@ -455,13 +444,12 @@ static int per_dev_options(struct udev *udev, return retval; } -static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, const char *path) -{ +static int set_inq_values(struct scsi_id_device *dev_scsi, const char *path) { int retval; dev_scsi->use_sg = sg_version; - retval = scsi_std_inquiry(udev, dev_scsi, path); + retval = scsi_std_inquiry(dev_scsi, path); if (retval) return retval; @@ -482,27 +470,26 @@ static int set_inq_values(struct udev *udev, struct scsi_id_device *dev_scsi, co * scsi_id: try to get an id, if one is found, printf it to stdout. * returns a value passed to exit() - 0 if printed an id, else 1. */ -static int scsi_id(struct udev *udev, char *maj_min_dev) -{ +static int scsi_id(char *maj_min_dev) { struct scsi_id_device dev_scsi = {}; int good_dev; int page_code; int retval = 0; - if (set_inq_values(udev, &dev_scsi, maj_min_dev) < 0) { + if (set_inq_values(&dev_scsi, maj_min_dev) < 0) { retval = 1; goto out; } /* get per device (vendor + model) options from the config file */ - per_dev_options(udev, &dev_scsi, &good_dev, &page_code); + per_dev_options(&dev_scsi, &good_dev, &page_code); if (!good_dev) { retval = 1; goto out; } /* read serial number from mode pages (no values for optical drives) */ - scsi_get_serial(udev, &dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN); + scsi_get_serial(&dev_scsi, maj_min_dev, page_code, MAX_SERIAL_LEN); if (export) { char serial_str[MAX_SERIAL_LEN]; @@ -557,7 +544,6 @@ out: } int main(int argc, char **argv) { - _cleanup_(udev_unrefp) struct udev *udev; int retval = 0; char maj_min_dev[MAX_PATH_LEN]; int newargc; @@ -568,14 +554,10 @@ int main(int argc, char **argv) { log_parse_environment(); log_open(); - udev = udev_new(); - if (udev == NULL) - goto exit; - /* * Get config file options. */ - retval = get_file_options(udev, NULL, NULL, &newargc, &newargv); + retval = get_file_options(NULL, NULL, &newargc, &newargv); if (retval < 0) { retval = 1; goto exit; @@ -583,7 +565,7 @@ int main(int argc, char **argv) { if (retval == 0) { assert(newargv); - if (set_options(udev, newargc, newargv, maj_min_dev) < 0) { + if (set_options(newargc, newargv, maj_min_dev) < 0) { retval = 2; goto exit; } @@ -592,7 +574,7 @@ int main(int argc, char **argv) { /* * Get command line options (overriding any config file settings). */ - if (set_options(udev, argc, argv, maj_min_dev) < 0) + if (set_options(argc, argv, maj_min_dev) < 0) exit(EXIT_FAILURE); if (!dev_specified) { @@ -601,7 +583,7 @@ int main(int argc, char **argv) { goto exit; } - retval = scsi_id(udev, maj_min_dev); + retval = scsi_id(maj_min_dev); exit: if (newargv) { diff --git a/src/udev/scsi_id/scsi_id.h b/src/udev/scsi_id/scsi_id.h index 14e1663990..70e804fb75 100644 --- a/src/udev/scsi_id/scsi_id.h +++ b/src/udev/scsi_id/scsi_id.h @@ -48,8 +48,8 @@ struct scsi_id_device { char tgpt_group[8]; }; -int scsi_std_inquiry(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname); -int scsi_get_serial(struct udev *udev, struct scsi_id_device *dev_scsi, const char *devname, +int scsi_std_inquiry(struct scsi_id_device *dev_scsi, const char *devname); +int scsi_get_serial(struct scsi_id_device *dev_scsi, const char *devname, int page_code, int len); /* diff --git a/src/udev/scsi_id/scsi_serial.c b/src/udev/scsi_id/scsi_serial.c index 7329ae0682..dfdbb5f0aa 100644 --- a/src/udev/scsi_id/scsi_serial.c +++ b/src/udev/scsi_id/scsi_serial.c @@ -21,13 +21,11 @@ #include #include -#include "libudev.h" - -#include "libudev-private.h" #include "random-util.h" #include "scsi.h" #include "scsi_id.h" #include "string-util.h" +#include "util.h" /* * A priority based list of id, naa, and binary/ascii for the identifier @@ -85,15 +83,12 @@ static const char hex_str[]="0123456789abcdef"; #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, +static int do_scsi_page80_inquiry(struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int max_len); -static int sg_err_category_new(struct udev *udev, - int scsi_status, int msg_status, int +static int sg_err_category_new(int scsi_status, int msg_status, int host_status, int driver_status, const - unsigned char *sense_buffer, int sb_len) -{ + unsigned char *sense_buffer, int sb_len) { scsi_status &= 0x7e; /* @@ -140,35 +135,26 @@ static int sg_err_category_new(struct udev *udev, return SG_ERR_CAT_OTHER; } -static int sg_err_category3(struct udev *udev, struct sg_io_hdr *hp) -{ - return sg_err_category_new(udev, - hp->status, hp->msg_status, +static int sg_err_category3(struct sg_io_hdr *hp) { + return sg_err_category_new(hp->status, hp->msg_status, hp->host_status, hp->driver_status, hp->sbp, hp->sb_len_wr); } -static int sg_err_category4(struct udev *udev, struct sg_io_v4 *hp) -{ - return sg_err_category_new(udev, hp->device_status, 0, +static int sg_err_category4(struct sg_io_v4 *hp) { + return sg_err_category_new(hp->device_status, 0, hp->transport_status, hp->driver_status, (unsigned char *)(uintptr_t)hp->response, hp->response_len); } -static int scsi_dump_sense(struct udev *udev, - struct scsi_id_device *dev_scsi, - unsigned char *sense_buffer, int sb_len) -{ +static int scsi_dump_sense(struct scsi_id_device *dev_scsi, + unsigned char *sense_buffer, int sb_len) { int s; int code; int sense_class; int sense_key; int asc, ascq; -#ifdef DUMP_SENSE - char out_buffer[256]; - int i, j; -#endif /* * Figure out and print the sense key, asc and ascq. @@ -240,23 +226,10 @@ static int scsi_dump_sense(struct udev *udev, } -#ifdef DUMP_SENSE - for (i = 0, j = 0; (i < s) && (j < 254); i++) { - out_buffer[j++] = hex_str[(sense_buffer[i] & 0xf0) >> 4]; - out_buffer[j++] = hex_str[sense_buffer[i] & 0x0f]; - out_buffer[j++] = ' '; - } - out_buffer[j] = '\0'; - log_debug("%s: sense dump:", dev_scsi->kernel); - log_debug("%s: %s", dev_scsi->kernel, out_buffer); - -#endif return -1; } -static int scsi_dump(struct udev *udev, - struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) -{ +static int scsi_dump(struct scsi_id_device *dev_scsi, struct sg_io_hdr *io) { if (!io->status && !io->host_status && !io->msg_status && !io->driver_status) { /* @@ -269,14 +242,12 @@ 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); if (io->status == SCSI_CHECK_CONDITION) - return scsi_dump_sense(udev, dev_scsi, io->sbp, io->sb_len_wr); + return scsi_dump_sense(dev_scsi, io->sbp, io->sb_len_wr); else return -1; } -static int scsi_dump_v4(struct udev *udev, - struct scsi_id_device *dev_scsi, struct sg_io_v4 *io) -{ +static int scsi_dump_v4(struct scsi_id_device *dev_scsi, struct sg_io_v4 *io) { if (!io->device_status && !io->transport_status && !io->driver_status) { /* @@ -289,17 +260,15 @@ 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); if (io->device_status == SCSI_CHECK_CONDITION) - return scsi_dump_sense(udev, dev_scsi, (unsigned char *)(uintptr_t)io->response, + return scsi_dump_sense(dev_scsi, (unsigned char *)(uintptr_t)io->response, io->response_len); else return -1; } -static int scsi_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, int fd, +static int scsi_inquiry(struct scsi_id_device *dev_scsi, int fd, unsigned char evpd, unsigned char page, - unsigned char *buf, unsigned int buflen) -{ + unsigned char *buf, unsigned int buflen) { unsigned char inq_cmd[INQUIRY_CMDLEN] = { INQUIRY_CMD, evpd, page, 0, buflen, 0 }; unsigned char sense[SENSE_BUFF_LEN]; @@ -352,9 +321,9 @@ resend: } if (dev_scsi->use_sg == 4) - retval = sg_err_category4(udev, io_buf); + retval = sg_err_category4(io_buf); else - retval = sg_err_category3(udev, io_buf); + retval = sg_err_category3(io_buf); switch (retval) { case SG_ERR_CAT_NOTSUPPORTED: @@ -367,9 +336,9 @@ resend: default: if (dev_scsi->use_sg == 4) - retval = scsi_dump_v4(udev, dev_scsi, io_buf); + retval = scsi_dump_v4(dev_scsi, io_buf); else - retval = scsi_dump(udev, dev_scsi, io_buf); + retval = scsi_dump(dev_scsi, io_buf); } if (!retval) { @@ -389,14 +358,12 @@ error: } /* Get list of supported EVPD pages */ -static int do_scsi_page0_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, int fd, - unsigned char *buffer, unsigned int len) -{ +static int do_scsi_page0_inquiry(struct scsi_id_device *dev_scsi, int fd, + unsigned char *buffer, unsigned int len) { int retval; memzero(buffer, len); - retval = scsi_inquiry(udev, dev_scsi, fd, 1, 0x0, buffer, len); + retval = scsi_inquiry(dev_scsi, fd, 1, 0x0, buffer, len); if (retval < 0) return 1; @@ -433,9 +400,7 @@ static int do_scsi_page0_inquiry(struct udev *udev, * The caller checks that serial is long enough to include the vendor + * model. */ -static int prepend_vendor_model(struct udev *udev, - struct scsi_id_device *dev_scsi, char *serial) -{ +static int prepend_vendor_model(struct scsi_id_device *dev_scsi, char *serial) { int ind; strncpy(serial, dev_scsi->vendor, VENDOR_LENGTH); @@ -458,14 +423,12 @@ static int prepend_vendor_model(struct udev *udev, * check_fill_0x83_id - check the page 0x83 id, if OK allocate and fill * serial number. */ -static int check_fill_0x83_id(struct udev *udev, - struct scsi_id_device *dev_scsi, +static int check_fill_0x83_id(struct scsi_id_device *dev_scsi, unsigned char *page_83, const struct scsi_id_search_values *id_search, char *serial, char *serial_short, int max_len, char *wwn, - char *wwn_vendor_extension, char *tgpt_group) -{ + char *wwn_vendor_extension, char *tgpt_group) { int i, j, s, len; /* @@ -534,7 +497,7 @@ static int check_fill_0x83_id(struct udev *udev, * included in the identifier. */ if (id_search->id_type == SCSI_ID_VENDOR_SPECIFIC) - if (prepend_vendor_model(udev, dev_scsi, &serial[1]) < 0) + if (prepend_vendor_model(dev_scsi, &serial[1]) < 0) return 1; i = 4; /* offset to the start of the identifier */ @@ -569,12 +532,10 @@ static int check_fill_0x83_id(struct udev *udev, } /* Extract the raw binary from VPD 0x83 pre-SPC devices */ -static int check_fill_0x83_prespc3(struct udev *udev, - struct scsi_id_device *dev_scsi, +static int check_fill_0x83_prespc3(struct scsi_id_device *dev_scsi, unsigned char *page_83, const struct scsi_id_search_values - *id_search, char *serial, char *serial_short, int max_len) -{ + *id_search, char *serial, char *serial_short, int max_len) { int i, j; serial[0] = hex_str[SCSI_ID_NAA]; @@ -591,21 +552,19 @@ static int check_fill_0x83_prespc3(struct udev *udev, } /* Get device identification VPD page */ -static int do_scsi_page83_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, int fd, +static int do_scsi_page83_inquiry(struct scsi_id_device *dev_scsi, int fd, char *serial, char *serial_short, int len, char *unit_serial_number, char *wwn, - char *wwn_vendor_extension, char *tgpt_group) -{ + char *wwn_vendor_extension, char *tgpt_group) { int retval; unsigned int id_ind, j; unsigned char page_83[SCSI_INQ_BUFF_LEN]; /* also pick up the page 80 serial number */ - do_scsi_page80_inquiry(udev, dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN); + do_scsi_page80_inquiry(dev_scsi, fd, NULL, unit_serial_number, MAX_SERIAL_LEN); memzero(page_83, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); if (retval < 0) return 1; @@ -645,8 +604,7 @@ static int do_scsi_page83_inquiry(struct udev *udev, */ if (page_83[6] != 0) - return check_fill_0x83_prespc3(udev, - dev_scsi, page_83, id_search_list, + return check_fill_0x83_prespc3(dev_scsi, page_83, id_search_list, serial, serial_short, len); /* @@ -661,8 +619,7 @@ static int do_scsi_page83_inquiry(struct udev *udev, * one or a small number of descriptors. */ for (j = 4; j <= (unsigned int)page_83[3] + 3; j += page_83[j + 3] + 4) { - retval = check_fill_0x83_id(udev, - dev_scsi, &page_83[j], + retval = check_fill_0x83_id(dev_scsi, &page_83[j], &id_search_list[id_ind], serial, serial_short, len, wwn, wwn_vendor_extension, @@ -683,16 +640,14 @@ static int do_scsi_page83_inquiry(struct udev *udev, * Return the hard coded error code value 2 if the page 83 reply is not * conformant to the SCSI-2 format. */ -static int do_scsi_page83_prespc3_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, int fd, - char *serial, char *serial_short, int len) -{ +static int do_scsi_page83_prespc3_inquiry(struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int len) { int retval; int i, j; unsigned char page_83[SCSI_INQ_BUFF_LEN]; memzero(page_83, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_83, page_83, SCSI_INQ_BUFF_LEN); if (retval < 0) return 1; @@ -745,10 +700,8 @@ static int do_scsi_page83_prespc3_inquiry(struct udev *udev, } /* Get unit serial number VPD page */ -static int do_scsi_page80_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, int fd, - char *serial, char *serial_short, int max_len) -{ +static int do_scsi_page80_inquiry(struct scsi_id_device *dev_scsi, int fd, + char *serial, char *serial_short, int max_len) { int retval; int ser_ind; int i; @@ -756,7 +709,7 @@ static int do_scsi_page80_inquiry(struct udev *udev, unsigned char buf[SCSI_INQ_BUFF_LEN]; memzero(buf, SCSI_INQ_BUFF_LEN); - retval = scsi_inquiry(udev, dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN); + retval = scsi_inquiry(dev_scsi, fd, 1, PAGE_80, buf, SCSI_INQ_BUFF_LEN); if (retval < 0) return retval; @@ -778,7 +731,7 @@ static int do_scsi_page80_inquiry(struct udev *udev, len = buf[3]; if (serial != NULL) { serial[0] = 'S'; - ser_ind = prepend_vendor_model(udev, dev_scsi, &serial[1]); + ser_ind = prepend_vendor_model(dev_scsi, &serial[1]); if (ser_ind < 0) return 1; ser_ind++; /* for the leading 'S' */ @@ -792,9 +745,7 @@ static int do_scsi_page80_inquiry(struct udev *udev, return 0; } -int scsi_std_inquiry(struct udev *udev, - struct scsi_id_device *dev_scsi, const char *devname) -{ +int scsi_std_inquiry(struct scsi_id_device *dev_scsi, const char *devname) { int fd; unsigned char buf[SCSI_INQ_BUFF_LEN]; struct stat statbuf; @@ -815,7 +766,7 @@ int scsi_std_inquiry(struct udev *udev, minor(statbuf.st_rdev)); memzero(buf, SCSI_INQ_BUFF_LEN); - err = scsi_inquiry(udev, dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN); + err = scsi_inquiry(dev_scsi, fd, 0, 0, buf, SCSI_INQ_BUFF_LEN); if (err < 0) goto out; @@ -833,10 +784,8 @@ out: return err; } -int scsi_get_serial(struct udev *udev, - struct scsi_id_device *dev_scsi, const char *devname, - int page_code, int len) -{ +int scsi_get_serial(struct scsi_id_device *dev_scsi, const char *devname, + int page_code, int len) { unsigned char page0[SCSI_INQ_BUFF_LEN]; int fd = -1; int cnt; @@ -859,7 +808,7 @@ int scsi_get_serial(struct udev *udev, return 1; if (page_code == PAGE_80) { - if (do_scsi_page80_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) { + if (do_scsi_page80_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) { retval = 1; goto completed; } else { @@ -867,7 +816,7 @@ int scsi_get_serial(struct udev *udev, goto completed; } } else if (page_code == PAGE_83) { - if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { retval = 1; goto completed; } else { @@ -875,7 +824,7 @@ int scsi_get_serial(struct udev *udev, goto completed; } } else if (page_code == PAGE_83_PRE_SPC3) { - retval = do_scsi_page83_prespc3_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len); + retval = do_scsi_page83_prespc3_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len); if (retval) { /* * Fallback to servicing a SPC-2/3 compliant page 83 @@ -883,7 +832,7 @@ int scsi_get_serial(struct udev *udev, * conform to pre-SPC3 expectations. */ if (retval == 2) { - if (do_scsi_page83_inquiry(udev, dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { + if (do_scsi_page83_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { retval = 1; goto completed; } else { @@ -909,7 +858,7 @@ int scsi_get_serial(struct udev *udev, * Get page 0, the page of the pages. By default, try from best to * worst of supported pages: 0x83 then 0x80. */ - if (do_scsi_page0_inquiry(udev, dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) { + if (do_scsi_page0_inquiry(dev_scsi, fd, page0, SCSI_INQ_BUFF_LEN)) { /* * Don't try anything else. Black list if a specific page * should be used for this vendor+model, or maybe have an @@ -921,7 +870,7 @@ int scsi_get_serial(struct udev *udev, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_83) - if (!do_scsi_page83_inquiry(udev, dev_scsi, fd, + if (!do_scsi_page83_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len, dev_scsi->unit_serial_number, dev_scsi->wwn, dev_scsi->wwn_vendor_extension, dev_scsi->tgpt_group)) { /* * Success @@ -932,7 +881,7 @@ int scsi_get_serial(struct udev *udev, for (ind = 4; ind <= page0[3] + 3; ind++) if (page0[ind] == PAGE_80) - if (!do_scsi_page80_inquiry(udev, dev_scsi, fd, + if (!do_scsi_page80_inquiry(dev_scsi, fd, dev_scsi->serial, dev_scsi->serial_short, len)) { /* * Success diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 10155ad338..befb009b5c 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -160,7 +160,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te /* read data from another device than the device we will store the data */ if (device) { - srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device); + srcdev = udev_device_new_from_device_id(NULL, device); if (!srcdev) return EXIT_FAILURE; } @@ -171,7 +171,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te } /* called at udev startup and reload */ -static int builtin_hwdb_init(struct udev *udev) { +static int builtin_hwdb_init(void) { int r; if (hwdb) @@ -185,12 +185,12 @@ static int builtin_hwdb_init(struct udev *udev) { } /* called on udev shutdown and reload request */ -static void builtin_hwdb_exit(struct udev *udev) { +static void builtin_hwdb_exit(void) { hwdb = sd_hwdb_unref(hwdb); } /* called every couple of seconds during event activity; 'true' if config has changed */ -static bool builtin_hwdb_validate(struct udev *udev) { +static bool builtin_hwdb_validate(void) { return hwdb_validate(hwdb); } diff --git a/src/udev/udev-builtin-kmod.c b/src/udev/udev-builtin-kmod.c index f148d9c5f6..9436126dd8 100644 --- a/src/udev/udev-builtin-kmod.c +++ b/src/udev/udev-builtin-kmod.c @@ -39,7 +39,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te } /* called at udev startup and reload */ -static int builtin_kmod_init(struct udev *udev) { +static int builtin_kmod_init(void) { if (ctx) return 0; @@ -48,19 +48,19 @@ static int builtin_kmod_init(struct udev *udev) { return -ENOMEM; log_debug("Load module index"); - kmod_set_log_fn(ctx, udev_kmod_log, udev); + kmod_set_log_fn(ctx, udev_kmod_log, NULL); kmod_load_resources(ctx); return 0; } /* called on udev shutdown and reload request */ -static void builtin_kmod_exit(struct udev *udev) { +static void builtin_kmod_exit(void) { log_debug("Unload module index"); ctx = kmod_unref(ctx); } /* called every couple of seconds during event activity; 'true' if config has changed */ -static bool builtin_kmod_validate(struct udev *udev) { +static bool builtin_kmod_validate(void) { log_debug("Validate module index"); if (!ctx) return false; diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 21e1715306..cb49ade4d8 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -153,7 +153,6 @@ static struct udev_device *skip_virtio(struct udev_device *dev) { } static int get_virtfn_info(struct udev_device *dev, struct netnames *names, struct virtfn_info *vf_info) { - struct udev *udev; const char *physfn_link_file; _cleanup_free_ char *physfn_pci_syspath = NULL; _cleanup_free_ char *virtfn_pci_syspath = NULL; @@ -162,9 +161,6 @@ static int get_virtfn_info(struct udev_device *dev, struct netnames *names, stru struct virtfn_info vf_info_local = {}; int r; - udev = udev_device_get_udev(names->pcidev); - if (!udev) - return -ENOENT; /* Check if this is a virtual function. */ physfn_link_file = strjoina(udev_device_get_syspath(names->pcidev), "/physfn"); r = chase_symlinks(physfn_link_file, NULL, 0, &physfn_pci_syspath); @@ -172,7 +168,7 @@ static int get_virtfn_info(struct udev_device *dev, struct netnames *names, stru return r; /* Get physical function's pci device. */ - vf_info_local.physfn_pcidev = udev_device_new_from_syspath(udev, physfn_pci_syspath); + vf_info_local.physfn_pcidev = udev_device_new_from_syspath(NULL, physfn_pci_syspath); if (!vf_info_local.physfn_pcidev) return -ENOENT; @@ -288,7 +284,6 @@ static bool is_pci_ari_enabled(struct udev_device *dev) { } static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { - struct udev *udev = udev_device_get_udev(names->pcidev); unsigned domain, bus, slot, func, dev_port = 0, hotplug_slot = 0; size_t l; char *s; @@ -331,7 +326,7 @@ static int dev_pci_slot(struct udev_device *dev, struct netnames *names) { names->pci_path[0] = '\0'; /* ACPI _SUN — slot user number */ - pci = udev_device_new_from_subsystem_sysname(udev, "subsystem", "pci"); + pci = udev_device_new_from_subsystem_sysname(NULL, "subsystem", "pci"); if (!pci) return -ENOENT; diff --git a/src/udev/udev-builtin-net_setup_link.c b/src/udev/udev-builtin-net_setup_link.c index 8bed6399af..ca8c16df0a 100644 --- a/src/udev/udev-builtin-net_setup_link.c +++ b/src/udev/udev-builtin-net_setup_link.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ #include "alloc-util.h" +#include "libudev-device-internal.h" #include "link-config.h" #include "log.h" #include "udev.h" @@ -18,11 +19,11 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv return EXIT_FAILURE; } - r = link_get_driver(ctx, dev, &driver); + r = link_get_driver(ctx, dev->device, &driver); if (r >= 0) udev_builtin_add_property(dev, test, "ID_NET_DRIVER", driver); - r = link_config_get(ctx, dev, &link); + r = link_config_get(ctx, dev->device, &link); if (r < 0) { if (r == -ENOENT) { log_debug("No matching link configuration found."); @@ -33,7 +34,7 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv } } - r = link_config_apply(ctx, link, dev, &name); + r = link_config_apply(ctx, link, dev->device, &name); if (r < 0) log_warning_errno(r, "Could not apply link config to %s, ignoring: %m", udev_device_get_sysname(dev)); @@ -45,7 +46,7 @@ static int builtin_net_setup_link(struct udev_device *dev, int argc, char **argv return EXIT_SUCCESS; } -static int builtin_net_setup_link_init(struct udev *udev) { +static int builtin_net_setup_link_init(void) { int r; if (ctx) @@ -63,13 +64,13 @@ static int builtin_net_setup_link_init(struct udev *udev) { return 0; } -static void builtin_net_setup_link_exit(struct udev *udev) { +static void builtin_net_setup_link_exit(void) { link_config_ctx_free(ctx); ctx = NULL; log_debug("Unloaded link configuration context."); } -static bool builtin_net_setup_link_validate(struct udev *udev) { +static bool builtin_net_setup_link_validate(void) { log_debug("Check if link configuration needs reloading."); if (!ctx) return false; diff --git a/src/udev/udev-builtin-path_id.c b/src/udev/udev-builtin-path_id.c index 462729f5c8..12c340110f 100644 --- a/src/udev/udev-builtin-path_id.c +++ b/src/udev/udev-builtin-path_id.c @@ -86,7 +86,6 @@ static struct udev_device *skip_subsystem(struct udev_device *dev, const char *s } static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, char **path) { - struct udev *udev; struct udev_device *targetdev; _cleanup_(udev_device_unrefp) struct udev_device *fcdev = NULL; const char *port; @@ -95,13 +94,12 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, assert(parent); assert(path); - udev = udev_device_get_udev(parent); targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); if (!targetdev) return NULL; - fcdev = udev_device_new_from_subsystem_sysname(udev, "fc_transport", udev_device_get_sysname(targetdev)); + fcdev = udev_device_new_from_subsystem_sysname(NULL, "fc_transport", udev_device_get_sysname(targetdev)); if (!fcdev) return NULL; @@ -115,7 +113,6 @@ static struct udev_device *handle_scsi_fibre_channel(struct udev_device *parent, } static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, char **path) { - struct udev *udev; struct udev_device *targetdev, *target_parent; _cleanup_(udev_device_unrefp) struct udev_device *sasdev = NULL; const char *sas_address; @@ -124,7 +121,6 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, assert(parent); assert(path); - udev = udev_device_get_udev(parent); targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); if (!targetdev) @@ -134,7 +130,7 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, if (!target_parent) return NULL; - sasdev = udev_device_new_from_subsystem_sysname(udev, "sas_device", + sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", udev_device_get_sysname(target_parent)); if (!sasdev) return NULL; @@ -150,7 +146,6 @@ static struct udev_device *handle_scsi_sas_wide_port(struct udev_device *parent, static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **path) { - struct udev *udev; struct udev_device *targetdev, *target_parent, *port, *expander; _cleanup_(udev_device_unrefp) struct udev_device *target_sasdev = NULL, *expander_sasdev = NULL, *port_sasdev = NULL; @@ -162,7 +157,6 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa assert(parent); assert(path); - udev = udev_device_get_udev(parent); targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_target"); if (!targetdev) @@ -173,8 +167,7 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa return NULL; /* Get sas device */ - target_sasdev = udev_device_new_from_subsystem_sysname( - udev, "sas_device", udev_device_get_sysname(target_parent)); + target_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", udev_device_get_sysname(target_parent)); if (!target_sasdev) return NULL; @@ -184,8 +177,7 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa return NULL; /* Get port device */ - port_sasdev = udev_device_new_from_subsystem_sysname( - udev, "sas_port", udev_device_get_sysname(port)); + port_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_port", udev_device_get_sysname(port)); phy_count = udev_device_get_sysattr_value(port_sasdev, "num_phys"); if (!phy_count) @@ -206,12 +198,10 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa return NULL; /* Get expander device */ - expander_sasdev = udev_device_new_from_subsystem_sysname( - udev, "sas_device", udev_device_get_sysname(expander)); + expander_sasdev = udev_device_new_from_subsystem_sysname(NULL, "sas_device", udev_device_get_sysname(expander)); if (expander_sasdev) { /* Get expander's address */ - sas_address = udev_device_get_sysattr_value(expander_sasdev, - "sas_address"); + sas_address = udev_device_get_sysattr_value(expander_sasdev, "sas_address"); if (!sas_address) return NULL; } @@ -226,7 +216,6 @@ static struct udev_device *handle_scsi_sas(struct udev_device *parent, char **pa } static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char **path) { - struct udev *udev; struct udev_device *transportdev; _cleanup_(udev_device_unrefp) struct udev_device *sessiondev = NULL, *conndev = NULL; @@ -236,7 +225,6 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char ** assert(parent); assert(path); - udev = udev_device_get_udev(parent); /* find iscsi session */ transportdev = parent; @@ -249,7 +237,7 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char ** } /* find iscsi session device */ - sessiondev = udev_device_new_from_subsystem_sysname(udev, "iscsi_session", udev_device_get_sysname(transportdev)); + sessiondev = udev_device_new_from_subsystem_sysname(NULL, "iscsi_session", udev_device_get_sysname(transportdev)); if (!sessiondev) return NULL; @@ -258,7 +246,7 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char ** return NULL; connname = strjoina("connection", udev_device_get_sysnum(transportdev), ":0"); - conndev = udev_device_new_from_subsystem_sysname(udev, "iscsi_connection", connname); + conndev = udev_device_new_from_subsystem_sysname(NULL, "iscsi_connection", connname); if (!conndev) return NULL; @@ -273,7 +261,6 @@ static struct udev_device *handle_scsi_iscsi(struct udev_device *parent, char ** } static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **path) { - struct udev *udev; struct udev_device *targetdev, *target_parent; _cleanup_(udev_device_unrefp) struct udev_device *atadev = NULL; const char *port_no; @@ -281,7 +268,6 @@ static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **pa assert(parent); assert(path); - udev = udev_device_get_udev(parent); targetdev = udev_device_get_parent_with_subsystem_devtype(parent, "scsi", "scsi_host"); if (!targetdev) @@ -291,7 +277,7 @@ static struct udev_device *handle_scsi_ata(struct udev_device *parent, char **pa if (!target_parent) return NULL; - atadev = udev_device_new_from_subsystem_sysname(udev, "ata_port", udev_device_get_sysname(target_parent)); + atadev = udev_device_new_from_subsystem_sysname(NULL, "ata_port", udev_device_get_sysname(target_parent)); if (!atadev) return NULL; diff --git a/src/udev/udev-builtin.c b/src/udev/udev-builtin.c index 576d83d378..be7e995933 100644 --- a/src/udev/udev-builtin.c +++ b/src/udev/udev-builtin.c @@ -29,7 +29,7 @@ static const struct udev_builtin *builtins[] = { #endif }; -void udev_builtin_init(struct udev *udev) { +void udev_builtin_init(void) { unsigned int i; if (initialized) @@ -37,12 +37,12 @@ void udev_builtin_init(struct udev *udev) { for (i = 0; i < ELEMENTSOF(builtins); i++) if (builtins[i] && builtins[i]->init) - builtins[i]->init(udev); + builtins[i]->init(); initialized = true; } -void udev_builtin_exit(struct udev *udev) { +void udev_builtin_exit(void) { unsigned int i; if (!initialized) @@ -50,21 +50,21 @@ void udev_builtin_exit(struct udev *udev) { for (i = 0; i < ELEMENTSOF(builtins); i++) if (builtins[i] && builtins[i]->exit) - builtins[i]->exit(udev); + builtins[i]->exit(); initialized = false; } -bool udev_builtin_validate(struct udev *udev) { +bool udev_builtin_validate(void) { unsigned int i; for (i = 0; i < ELEMENTSOF(builtins); i++) - if (builtins[i] && builtins[i]->validate && builtins[i]->validate(udev)) + if (builtins[i] && builtins[i]->validate && builtins[i]->validate()) return true; return false; } -void udev_builtin_list(struct udev *udev) { +void udev_builtin_list(void) { unsigned int i; for (i = 0; i < ELEMENTSOF(builtins); i++) @@ -112,7 +112,7 @@ int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const c /* we need '0' here to reset the internal state */ optind = 0; strscpy(arg, sizeof(arg), command); - udev_build_argv(udev_device_get_udev(dev), arg, &argc, argv); + udev_build_argv(arg, &argc, argv); return builtins[cmd]->cmd(dev, argc, argv, test); } diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 420e841764..a9b19051bf 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -49,14 +49,13 @@ struct udev_ctrl_msg_wire { }; struct udev_ctrl_msg { - int refcount; + unsigned n_ref; struct udev_ctrl_connection *conn; struct udev_ctrl_msg_wire ctrl_msg_wire; }; struct udev_ctrl { - int refcount; - struct udev *udev; + unsigned n_ref; int sock; union sockaddr_union saddr; socklen_t addrlen; @@ -66,12 +65,12 @@ struct udev_ctrl { }; struct udev_ctrl_connection { - int refcount; + unsigned n_ref; struct udev_ctrl *uctrl; int sock; }; -struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { +struct udev_ctrl *udev_ctrl_new_from_fd(int fd) { struct udev_ctrl *uctrl; const int on = 1; int r; @@ -79,8 +78,7 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { uctrl = new0(struct udev_ctrl, 1); if (uctrl == NULL) return NULL; - uctrl->refcount = 1; - uctrl->udev = udev; + uctrl->n_ref = 1; if (fd < 0) { uctrl->sock = socket(AF_LOCAL, SOCK_SEQPACKET|SOCK_NONBLOCK|SOCK_CLOEXEC, 0); @@ -108,8 +106,8 @@ struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd) { return uctrl; } -struct udev_ctrl *udev_ctrl_new(struct udev *udev) { - return udev_ctrl_new_from_fd(udev, -1); +struct udev_ctrl *udev_ctrl_new(void) { + return udev_ctrl_new_from_fd(-1); } int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { @@ -135,26 +133,15 @@ int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl) { return 0; } -struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl) { - return uctrl->udev; +static struct udev_ctrl *udev_ctrl_free(struct udev_ctrl *uctrl) { + assert(uctrl); + + safe_close(uctrl->sock); + return mfree(uctrl); } -static struct udev_ctrl *udev_ctrl_ref(struct udev_ctrl *uctrl) { - if (uctrl) - uctrl->refcount++; - - return uctrl; -} - -struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl) { - if (uctrl && -- uctrl->refcount == 0) { - if (uctrl->sock >= 0) - close(uctrl->sock); - free(uctrl); - } - - return NULL; -} +DEFINE_PRIVATE_TRIVIAL_REF_FUNC(struct udev_ctrl, udev_ctrl); +DEFINE_TRIVIAL_UNREF_FUNC(struct udev_ctrl, udev_ctrl, udev_ctrl_free); int udev_ctrl_cleanup(struct udev_ctrl *uctrl) { if (uctrl == NULL) @@ -179,7 +166,7 @@ struct udev_ctrl_connection *udev_ctrl_get_connection(struct udev_ctrl *uctrl) { conn = new(struct udev_ctrl_connection, 1); if (conn == NULL) return NULL; - conn->refcount = 1; + conn->n_ref = 1; conn->uctrl = uctrl; conn->sock = accept4(uctrl->sock, NULL, NULL, SOCK_CLOEXEC|SOCK_NONBLOCK); @@ -213,25 +200,15 @@ err: return mfree(conn); } -struct udev_ctrl_connection *udev_ctrl_connection_ref(struct udev_ctrl_connection *conn) { - if (conn == NULL) - return NULL; - conn->refcount++; - return conn; +static struct udev_ctrl_connection *udev_ctrl_connection_free(struct udev_ctrl_connection *conn) { + assert(conn); + + safe_close(conn->sock); + udev_ctrl_unref(conn->uctrl); + return mfree(conn); } -struct udev_ctrl_connection *udev_ctrl_connection_unref(struct udev_ctrl_connection *conn) { - if (conn && -- conn->refcount == 0) { - if (conn->sock >= 0) - close(conn->sock); - - udev_ctrl_unref(conn->uctrl); - - free(conn); - } - - return NULL; -} +DEFINE_TRIVIAL_REF_UNREF_FUNC(struct udev_ctrl_connection, udev_ctrl_connection, udev_ctrl_connection_free); static int ctrl_send(struct udev_ctrl *uctrl, enum udev_ctrl_msg_type type, int intval, const char *buf, int timeout) { struct udev_ctrl_msg_wire ctrl_msg_wire; @@ -336,7 +313,7 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) { uctrl_msg = new0(struct udev_ctrl_msg, 1); if (uctrl_msg == NULL) return NULL; - uctrl_msg->refcount = 1; + uctrl_msg->n_ref = 1; uctrl_msg->conn = conn; udev_ctrl_connection_ref(conn); @@ -402,15 +379,15 @@ err: return NULL; } -struct udev_ctrl_msg *udev_ctrl_msg_unref(struct udev_ctrl_msg *ctrl_msg) { - if (ctrl_msg && -- ctrl_msg->refcount == 0) { - udev_ctrl_connection_unref(ctrl_msg->conn); - free(ctrl_msg); - } +static struct udev_ctrl_msg *udev_ctrl_msg_free(struct udev_ctrl_msg *ctrl_msg) { + assert(ctrl_msg); - return NULL; + udev_ctrl_connection_unref(ctrl_msg->conn); + return mfree(ctrl_msg); } +DEFINE_TRIVIAL_UNREF_FUNC(struct udev_ctrl_msg, udev_ctrl_msg, udev_ctrl_msg_free); + int udev_ctrl_get_set_log_level(struct udev_ctrl_msg *ctrl_msg) { if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SET_LOG_LEVEL) return ctrl_msg->ctrl_msg_wire.intval; diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 541aac2c3f..45ebdfc51f 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -33,16 +33,14 @@ typedef struct Spawn { } Spawn; struct udev_event *udev_event_new(struct udev_device *dev) { - struct udev *udev = udev_device_get_udev(dev); struct udev_event *event; event = new0(struct udev_event, 1); if (event == NULL) return NULL; event->dev = dev; - event->udev = udev; - udev_list_init(udev, &event->run_list, false); - udev_list_init(udev, &event->seclabel_list, false); + udev_list_init(NULL, &event->run_list, false); + udev_list_init(NULL, &event->seclabel_list, false); event->birth_usec = now(CLOCK_MONOTONIC); return event; } @@ -180,7 +178,7 @@ static size_t subst_format_var(struct udev_event *event, struct udev_device *dev } /* try to read the value specified by "[dmi/id]product_name" */ - if (util_resolve_subsys_kernel(event->udev, attr, vbuf, sizeof(vbuf), 1) == 0) + if (util_resolve_subsys_kernel(attr, vbuf, sizeof(vbuf), 1) == 0) value = vbuf; /* try to read the attribute the device */ @@ -698,7 +696,7 @@ static int spawn_wait(struct udev_event *event, return ret; } -int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]) { +int udev_build_argv(char *cmd, int *argc, char *argv[]) { int i = 0; char *pos; @@ -771,7 +769,7 @@ int udev_event_spawn(struct udev_event *event, errpipe[READ_END] = safe_close(errpipe[READ_END]); strscpy(arg, sizeof(arg), cmd); - udev_build_argv(event->udev, arg, NULL, argv); + udev_build_argv(arg, NULL, argv); /* allow programs in /usr/lib/udev/ to be called without the path */ if (argv[0][0] != '/') { @@ -845,7 +843,7 @@ void udev_event_execute_rules(struct udev_event *event, udev_device_delete_db(dev); if (major(udev_device_get_devnum(dev)) != 0) - udev_watch_end(event->udev, dev); + udev_watch_end(dev); udev_rules_apply_to_event(rules, event, timeout_usec, timeout_warn_usec, @@ -858,7 +856,7 @@ void udev_event_execute_rules(struct udev_event *event, if (event->dev_db != NULL) { /* disable watch during event processing */ if (major(udev_device_get_devnum(dev)) != 0) - udev_watch_end(event->udev, event->dev_db); + udev_watch_end(event->dev_db); if (major(udev_device_get_devnum(dev)) == 0 && streq(udev_device_get_action(dev), "move")) diff --git a/src/udev/udev-node.c b/src/udev/udev-node.c index c3bfe8b00c..4080471a51 100644 --- a/src/udev/udev-node.c +++ b/src/udev/udev-node.c @@ -113,7 +113,6 @@ exit: /* find device node of device with highest priority */ static const char *link_find_prioritized(struct udev_device *dev, bool add, const char *stackdir, char *buf, size_t bufsize) { - struct udev *udev = udev_device_get_udev(dev); DIR *dir; struct dirent *dent; int priority = 0; @@ -142,7 +141,7 @@ static const char *link_find_prioritized(struct udev_device *dev, bool add, cons if (streq(dent->d_name, udev_device_get_id_filename(dev))) continue; - dev_db = udev_device_new_from_device_id(udev, dent->d_name); + dev_db = udev_device_new_from_device_id(NULL, dent->d_name); if (dev_db != NULL) { const char *devnode; diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 58ce71c794..76baa0322b 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -50,7 +50,6 @@ static const char* const rules_dirs[] = { }; struct udev_rules { - struct udev *udev; usec_t dirs_ts_usec; int resolve_names; @@ -700,7 +699,7 @@ static void attr_subst_subdir(char *attr, size_t len) { } } -static int get_key(struct udev *udev, char **line, char **key, enum operation_type *op, char **value) { +static int get_key(char **line, char **key, enum operation_type *op, char **value) { char *linepos; char *temp; unsigned i, j; @@ -802,7 +801,7 @@ static int get_key(struct udev *udev, char **line, char **key, enum operation_ty } /* extract possible KEY{attr} */ -static const char *get_key_attribute(struct udev *udev, char *str) { +static const char *get_key_attribute(char *str) { char *pos; char *attr; @@ -1019,7 +1018,7 @@ static void add_rule(struct udev_rules *rules, char *line, char *value; enum operation_type op; - if (get_key(rules->udev, &linepos, &key, &op, &value) != 0) { + if (get_key(&linepos, &key, &op, &value) != 0) { /* Avoid erroring on trailing whitespace. This is probably rare * so save the work for the error case instead of always trying * to strip the trailing whitespace with strstrip(). */ @@ -1082,8 +1081,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_DRIVER, op, value, NULL); } else if (startswith(key, "ATTR{")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("ATTR")); + attr = get_key_attribute(key + STRLEN("ATTR")); if (attr == NULL) LOG_AND_RETURN("error parsing %s attribute", "ATTR"); @@ -1096,8 +1094,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_ATTR, op, value, attr); } else if (startswith(key, "SYSCTL{")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("SYSCTL")); + attr = get_key_attribute(key + STRLEN("SYSCTL")); if (attr == NULL) LOG_AND_RETURN("error parsing %s attribute", "ATTR"); @@ -1110,8 +1107,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_A_SYSCTL, op, value, attr); } else if (startswith(key, "SECLABEL{")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("SECLABEL")); + attr = get_key_attribute(key + STRLEN("SECLABEL")); if (attr == NULL) LOG_AND_RETURN("error parsing %s attribute", "SECLABEL"); @@ -1142,8 +1138,7 @@ static void add_rule(struct udev_rules *rules, char *line, if (op > OP_MATCH_MAX) LOG_AND_RETURN("invalid %s operation", "ATTRS"); - attr = get_key_attribute(rules->udev, - key + STRLEN("ATTRS")); + attr = get_key_attribute(key + STRLEN("ATTRS")); if (attr == NULL) LOG_AND_RETURN("error parsing %s attribute", "ATTRS"); @@ -1160,8 +1155,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_TAGS, op, value, NULL); } else if (startswith(key, "ENV{")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("ENV")); + attr = get_key_attribute(key + STRLEN("ENV")); if (attr == NULL) LOG_AND_RETURN("error parsing %s attribute", "ENV"); @@ -1207,8 +1201,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_RESULT, op, value, NULL); } else if (startswith(key, "IMPORT")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("IMPORT")); + attr = get_key_attribute(key + STRLEN("IMPORT")); if (attr == NULL) { LOG_RULE_WARNING("ignoring IMPORT{} with missing type"); continue; @@ -1252,8 +1245,7 @@ static void add_rule(struct udev_rules *rules, char *line, if (op > OP_MATCH_MAX) LOG_AND_RETURN("invalid %s operation", "TEST"); - attr = get_key_attribute(rules->udev, - key + STRLEN("TEST")); + attr = get_key_attribute(key + STRLEN("TEST")); if (attr != NULL) { mode = strtol(attr, NULL, 8); rule_add_key(&rule_tmp, TK_M_TEST, op, value, &mode); @@ -1261,8 +1253,7 @@ static void add_rule(struct udev_rules *rules, char *line, rule_add_key(&rule_tmp, TK_M_TEST, op, value, NULL); } else if (startswith(key, "RUN")) { - attr = get_key_attribute(rules->udev, - key + STRLEN("RUN")); + attr = get_key_attribute(key + STRLEN("RUN")); if (attr == NULL) attr = "program"; if (op == OP_REMOVE) @@ -1513,7 +1504,7 @@ static int parse_file(struct udev_rules *rules, const char *filename) { return 0; } -struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) { +struct udev_rules *udev_rules_new(int resolve_names) { struct udev_rules *rules; struct udev_list file_list; struct token end_token; @@ -1523,9 +1514,8 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names) { rules = new0(struct udev_rules, 1); if (rules == NULL) return NULL; - rules->udev = udev; rules->resolve_names = resolve_names; - udev_list_init(udev, &file_list, true); + udev_list_init(NULL, &file_list, true); /* init token array and string buffer */ rules->tokens = malloc_multiply(PREALLOC_TOKEN, sizeof(struct token)); @@ -1690,7 +1680,7 @@ static int match_attr(struct udev_rules *rules, struct udev_device *dev, struct return -1; break; case SB_SUBSYS: - if (util_resolve_subsys_kernel(event->udev, name, vbuf, sizeof(vbuf), 1) != 0) + if (util_resolve_subsys_kernel(name, vbuf, sizeof(vbuf), 1) != 0) return -1; value = vbuf; break; @@ -1923,7 +1913,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, int match; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename), false); - if (util_resolve_subsys_kernel(event->udev, filename, filename, sizeof(filename), 0) != 0) { + if (util_resolve_subsys_kernel(filename, filename, sizeof(filename), 0) != 0) { if (filename[0] != '/') { char tmp[UTIL_PATH_SIZE]; @@ -2356,7 +2346,7 @@ void udev_rules_apply_to_event(struct udev_rules *rules, char value[UTIL_NAME_SIZE]; _cleanup_fclose_ FILE *f = NULL; - if (util_resolve_subsys_kernel(event->udev, key_name, attr, sizeof(attr), 0) != 0) + if (util_resolve_subsys_kernel(key_name, attr, sizeof(attr), 0) != 0) strscpyl(attr, sizeof(attr), udev_device_get_syspath(event->dev), "/", key_name, NULL); attr_subst_subdir(attr, sizeof(attr)); diff --git a/src/udev/udev-watch.c b/src/udev/udev-watch.c index 1ae89334bb..439117181a 100644 --- a/src/udev/udev-watch.c +++ b/src/udev/udev-watch.c @@ -20,7 +20,7 @@ static int inotify_fd = -1; * set to cloexec since we need our children to be able to add * watches for us */ -int udev_watch_init(struct udev *udev) { +int udev_watch_init(void) { inotify_fd = inotify_init1(IN_CLOEXEC); if (inotify_fd < 0) log_error_errno(errno, "inotify_init failed: %m"); @@ -30,7 +30,7 @@ int udev_watch_init(struct udev *udev) { /* move any old watches directory out of the way, and then restore * the watches */ -void udev_watch_restore(struct udev *udev) { +void udev_watch_restore(void) { if (inotify_fd < 0) return; @@ -57,12 +57,12 @@ void udev_watch_restore(struct udev *udev) { goto unlink; device[len] = '\0'; - dev = udev_device_new_from_device_id(udev, device); + dev = udev_device_new_from_device_id(NULL, device); if (dev == NULL) goto unlink; log_debug("restoring old watch on '%s'", udev_device_get_devnode(dev)); - udev_watch_begin(udev, dev); + udev_watch_begin(dev); udev_device_unref(dev); unlink: (void) unlinkat(dirfd(dir), ent->d_name, 0); @@ -75,7 +75,7 @@ unlink: 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) { +void udev_watch_begin(struct udev_device *dev) { char filename[sizeof("/run/udev/watch/") + DECIMAL_STR_MAX(int)]; int wd; int r; @@ -101,7 +101,7 @@ void udev_watch_begin(struct udev *udev, struct udev_device *dev) { udev_device_set_watch_handle(dev, wd); } -void udev_watch_end(struct udev *udev, struct udev_device *dev) { +void udev_watch_end(struct udev_device *dev) { int wd; char filename[sizeof("/run/udev/watch/") + DECIMAL_STR_MAX(int)]; @@ -121,7 +121,7 @@ void udev_watch_end(struct udev *udev, struct udev_device *dev) { udev_device_set_watch_handle(dev, -1); } -struct udev_device *udev_watch_lookup(struct udev *udev, int wd) { +struct udev_device *udev_watch_lookup(int wd) { char filename[sizeof("/run/udev/watch/") + DECIMAL_STR_MAX(int)]; char device[UTIL_NAME_SIZE]; ssize_t len; @@ -135,5 +135,5 @@ struct udev_device *udev_watch_lookup(struct udev *udev, int wd) { return NULL; device[len] = '\0'; - return udev_device_new_from_device_id(udev, device); + return udev_device_new_from_device_id(NULL, device); } diff --git a/src/udev/udev.h b/src/udev/udev.h index e79b8ed0d9..b7b2c0420c 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -19,7 +19,6 @@ #include "util.h" struct udev_event { - struct udev *udev; struct udev_device *dev; struct udev_device *dev_parent; struct udev_device *dev_db; @@ -48,15 +47,9 @@ struct udev_event { bool run_final; }; -struct udev_watch { - struct udev_list_node node; - int handle; - char *name; -}; - /* udev-rules.c */ struct udev_rules; -struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names); +struct udev_rules *udev_rules_new(int resolve_names); struct udev_rules *udev_rules_unref(struct udev_rules *rules); bool udev_rules_check_timestamp(struct udev_rules *rules); void udev_rules_apply_to_event(struct udev_rules *rules, struct udev_event *event, @@ -82,14 +75,14 @@ void udev_event_execute_rules(struct udev_event *event, struct udev_list *properties_list, struct udev_rules *rules); void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec); -int udev_build_argv(struct udev *udev, char *cmd, int *argc, char *argv[]); +int udev_build_argv(char *cmd, int *argc, char *argv[]); /* udev-watch.c */ -int udev_watch_init(struct udev *udev); -void udev_watch_restore(struct udev *udev); -void udev_watch_begin(struct udev *udev, struct udev_device *dev); -void udev_watch_end(struct udev *udev, struct udev_device *dev); -struct udev_device *udev_watch_lookup(struct udev *udev, int wd); +int udev_watch_init(void); +void udev_watch_restore(void); +void udev_watch_begin(struct udev_device *dev); +void udev_watch_end(struct udev_device *dev); +struct udev_device *udev_watch_lookup(int wd); /* udev-node.c */ void udev_node_add(struct udev_device *dev, bool apply, @@ -100,12 +93,11 @@ void udev_node_update_old_links(struct udev_device *dev, struct udev_device *dev /* udev-ctrl.c */ struct udev_ctrl; -struct udev_ctrl *udev_ctrl_new(struct udev *udev); -struct udev_ctrl *udev_ctrl_new_from_fd(struct udev *udev, int fd); +struct udev_ctrl *udev_ctrl_new(void); +struct udev_ctrl *udev_ctrl_new_from_fd(int fd); int udev_ctrl_enable_receiving(struct udev_ctrl *uctrl); struct udev_ctrl *udev_ctrl_unref(struct udev_ctrl *uctrl); int udev_ctrl_cleanup(struct udev_ctrl *uctrl); -struct udev *udev_ctrl_get_udev(struct udev_ctrl *uctrl); int udev_ctrl_get_fd(struct udev_ctrl *uctrl); int udev_ctrl_send_set_log_level(struct udev_ctrl *uctrl, int priority, int timeout); int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl, int timeout); @@ -156,9 +148,9 @@ struct udev_builtin { const char *name; int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test); const char *help; - int (*init)(struct udev *udev); - void (*exit)(struct udev *udev); - bool (*validate)(struct udev *udev); + int (*init)(void); + void (*exit)(void); + bool (*validate)(void); bool run_once; }; #if HAVE_BLKID @@ -176,14 +168,14 @@ extern const struct udev_builtin udev_builtin_net_setup_link; extern const struct udev_builtin udev_builtin_path_id; extern const struct udev_builtin udev_builtin_usb_id; extern const struct udev_builtin udev_builtin_uaccess; -void udev_builtin_init(struct udev *udev); -void udev_builtin_exit(struct udev *udev); +void udev_builtin_init(void); +void udev_builtin_exit(void); enum udev_builtin_cmd udev_builtin_lookup(const char *command); const char *udev_builtin_name(enum udev_builtin_cmd cmd); bool udev_builtin_run_once(enum udev_builtin_cmd cmd); int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test); -void udev_builtin_list(struct udev *udev); -bool udev_builtin_validate(struct udev *udev); +void udev_builtin_list(void); +bool udev_builtin_validate(void); int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val); int udev_builtin_hwdb_lookup(struct udev_device *dev, const char *prefix, const char *modalias, const char *filter, bool test); @@ -194,19 +186,3 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_rules*, udev_rules_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl*, udev_ctrl_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl_connection*, udev_ctrl_connection_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(struct udev_ctrl_msg*, udev_ctrl_msg_unref); - -/* udevadm commands */ -struct udevadm_cmd { - const char *name; - int (*cmd)(struct udev *udev, int argc, char *argv[]); - const char *help; - int debug; -}; -extern const struct udevadm_cmd udevadm_info; -extern const struct udevadm_cmd udevadm_trigger; -extern const struct udevadm_cmd udevadm_settle; -extern const struct udevadm_cmd udevadm_control; -extern const struct udevadm_cmd udevadm_monitor; -extern const struct udevadm_cmd udevadm_hwdb; -extern const struct udevadm_cmd udevadm_test; -extern const struct udevadm_cmd udevadm_test_builtin; diff --git a/src/udev/udevadm-control.c b/src/udev/udevadm-control.c index fb8ebdd485..68c6b8104c 100644 --- a/src/udev/udevadm-control.c +++ b/src/udev/udevadm-control.c @@ -19,12 +19,13 @@ #include #include +#include "parse-util.h" #include "process-util.h" #include "time-util.h" #include "udev.h" -#include "udevadm-util.h" +#include "udevadm.h" -static void print_help(void) { +static int help(void) { printf("%s control OPTION\n\n" "Control the udev daemon.\n\n" " -h --help Show this help\n" @@ -38,12 +39,14 @@ static void print_help(void) { " -m --children-max=N Maximum number of children\n" " -t --timeout=SECONDS Maximum time to block for a reply\n" , program_invocation_short_name); + + return 0; } -static int adm_control(struct udev *udev, int argc, char *argv[]) { +int control_main(int argc, char *argv[], void *userdata) { _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; int timeout = 60; - int rc = 1, c; + int c, r; static const struct option options[] = { { "exit", no_argument, NULL, 'e' }, @@ -61,80 +64,73 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) { {} }; - if (must_be_root() < 0) - return 1; + r = must_be_root(); + if (r < 0) + return r; - uctrl = udev_ctrl_new(udev); - if (uctrl == NULL) - return 2; + if (argc <= 1) + log_error("Option missing"); + + uctrl = udev_ctrl_new(); + if (!uctrl) + return -ENOMEM; while ((c = getopt_long(argc, argv, "el:sSRp:m:t:Vh", options, NULL)) >= 0) switch (c) { case 'e': - if (udev_ctrl_send_exit(uctrl, timeout) < 0) - rc = 2; - else - rc = 0; + r = udev_ctrl_send_exit(uctrl, timeout); + if (r < 0) + return r; break; case 'l': { int i; i = util_log_priority(optarg); - if (i < 0) { - log_error("invalid number '%s'", optarg); - return rc; - } - if (udev_ctrl_send_set_log_level(uctrl, util_log_priority(optarg), timeout) < 0) - rc = 2; - else - rc = 0; + if (i < 0) + return log_error_errno(i, "invalid number '%s'", optarg); + + r = udev_ctrl_send_set_log_level(uctrl, i, timeout); + if (r < 0) + return r; break; } case 's': - if (udev_ctrl_send_stop_exec_queue(uctrl, timeout) < 0) - rc = 2; - else - rc = 0; + r = udev_ctrl_send_stop_exec_queue(uctrl, timeout); + if (r < 0) + return r; break; case 'S': - if (udev_ctrl_send_start_exec_queue(uctrl, timeout) < 0) - rc = 2; - else - rc = 0; + r = udev_ctrl_send_start_exec_queue(uctrl, timeout); + if (r < 0) + return r; break; case 'R': - if (udev_ctrl_send_reload(uctrl, timeout) < 0) - rc = 2; - else - rc = 0; + r = udev_ctrl_send_reload(uctrl, timeout); + if (r < 0) + return r; break; case 'p': - if (strchr(optarg, '=') == NULL) { + if (!strchr(optarg, '=')) { log_error("expect = instead of '%s'", optarg); - return rc; + return -EINVAL; } - if (udev_ctrl_send_set_env(uctrl, optarg, timeout) < 0) - rc = 2; - else - rc = 0; + r = udev_ctrl_send_set_env(uctrl, optarg, timeout); + if (r < 0) + return r; break; case 'm': { - char *endp; - int i; + unsigned i; - i = strtoul(optarg, &endp, 0); - if (endp[0] != '\0' || i < 1) { - log_error("invalid number '%s'", optarg); - return rc; - } - if (udev_ctrl_send_set_children_max(uctrl, i, timeout) < 0) - rc = 2; - else - rc = 0; + r = safe_atou(optarg, &i); + if (r < 0) + return log_error_errno(r, "Failed to parse maximum number of events '%s': %m", optarg); + + r = udev_ctrl_send_set_children_max(uctrl, i, timeout); + if (r < 0) + return r; break; } case 't': { - int r, seconds; usec_t s; r = parse_sec(optarg, &s); @@ -142,33 +138,28 @@ static int adm_control(struct udev *udev, int argc, char *argv[]) { return log_error_errno(r, "Failed to parse timeout value '%s'.", optarg); if (DIV_ROUND_UP(s, USEC_PER_SEC) > INT_MAX) - log_error("Timeout value is out of range."); - else { - seconds = s != USEC_INFINITY ? (int) DIV_ROUND_UP(s, USEC_PER_SEC) : INT_MAX; - timeout = seconds; - rc = 0; - } + log_error("Timeout value is out of range, ignoring."); + else + timeout = s != USEC_INFINITY ? (int) DIV_ROUND_UP(s, USEC_PER_SEC) : INT_MAX; break; } case 'V': - print_version(); - rc = 0; - break; + return version(); case 'h': - print_help(); - rc = 0; - break; + return help(); + case '?': + return -EINVAL; + default: + assert_not_reached("Unknown option."); } - if (optind < argc) + if (optind < argc) { log_error("Extraneous argument: %s", argv[optind]); - else if (optind == 1) + return -EINVAL; + } else if (optind == 1) { log_error("Option missing"); - return rc; -} + return -EINVAL; + } -const struct udevadm_cmd udevadm_control = { - .name = "control", - .cmd = adm_control, - .help = "Control the udev daemon", -}; + return 0; +} diff --git a/src/udev/udevadm-hwdb.c b/src/udev/udevadm-hwdb.c index 02408a4285..9dbbd1bf95 100644 --- a/src/udev/udevadm-hwdb.c +++ b/src/udev/udevadm-hwdb.c @@ -13,10 +13,11 @@ #include "hwdb-util.h" #include "label.h" #include "mkdir.h" +#include "path-util.h" #include "strbuf.h" #include "string-util.h" #include "udev.h" -#include "udevadm-util.h" +#include "udevadm.h" #include "util.h" /* @@ -24,6 +25,12 @@ * Uses a Patricia/radix trie to index all matches for efficient lookup. */ +static const char *arg_test = NULL; +static const char *arg_root = NULL; +static const char *arg_hwdb_bin_dir = "/etc/udev"; +static bool arg_update = false; +static bool arg_strict = false; + static const char * const conf_file_dirs[] = { "/etc/udev/hwdb.d", UDEVLIBEXECDIR "/hwdb.d", @@ -107,6 +114,9 @@ static struct trie_node *node_lookup(const struct trie_node *node, uint8_t c) { static void trie_node_cleanup(struct trie_node *node) { size_t i; + if (!node) + return; + for (i = 0; i < node->children_count; i++) trie_node_cleanup(node->children[i].child); free(node->children); @@ -114,6 +124,17 @@ static void trie_node_cleanup(struct trie_node *node) { free(node); } +static void trie_free(struct trie *trie) { + if (!trie) + return; + + trie_node_cleanup(trie->root); + strbuf_cleanup(trie->strings); + free(trie); +} + +DEFINE_TRIVIAL_CLEANUP_FUNC(struct trie*, trie_free); + static int trie_values_cmp(const void *v1, const void *v2, void *arg) { const struct trie_value_entry *val1 = v1; const struct trie_value_entry *val2 = v2; @@ -436,7 +457,7 @@ static int insert_data(struct trie *trie, struct udev_list *match_list, return 0; } -static int import_file(struct udev *udev, struct trie *trie, const char *filename) { +static int import_file(struct trie *trie, const char *filename) { enum { HW_MATCH, HW_DATA, @@ -447,7 +468,7 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam struct udev_list match_list; int r = 0, err; - udev_list_init(udev, &match_list, false); + udev_list_init(NULL, &match_list, false); f = fopen(filename, "re"); if (f == NULL) @@ -538,7 +559,87 @@ static int import_file(struct udev *udev, struct trie *trie, const char *filenam return r; } -static void help(void) { +static int hwdb_update(void) { + _cleanup_(trie_freep) struct trie *trie = NULL; + _cleanup_strv_free_ char **files = NULL; + _cleanup_free_ char *hwdb_bin = NULL; + char **f; + int r; + + trie = new0(struct trie, 1); + if (!trie) + return -ENOMEM; + + /* string store */ + trie->strings = strbuf_new(); + if (!trie->strings) + return -ENOMEM; + + /* index */ + trie->root = new0(struct trie_node, 1); + if (!trie->root) + return -ENOMEM; + + trie->nodes_count++; + + r = conf_files_list_strv(&files, ".hwdb", arg_root, 0, conf_file_dirs); + if (r < 0) + return log_error_errno(r, "failed to enumerate hwdb files: %m"); + + STRV_FOREACH(f, files) { + log_debug("Reading file '%s'", *f); + r = import_file(trie, *f); + if (r < 0 && arg_strict) + return r; + } + + strbuf_complete(trie->strings); + + log_debug("=== trie in-memory ==="); + log_debug("nodes: %8zu bytes (%8zu)", + trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); + log_debug("children arrays: %8zu bytes (%8zu)", + trie->children_count * sizeof(struct trie_child_entry), trie->children_count); + log_debug("values arrays: %8zu bytes (%8zu)", + trie->values_count * sizeof(struct trie_value_entry), trie->values_count); + log_debug("strings: %8zu bytes", + trie->strings->len); + log_debug("strings incoming: %8zu bytes (%8zu)", + trie->strings->in_len, trie->strings->in_count); + log_debug("strings dedup'ed: %8zu bytes (%8zu)", + trie->strings->dedup_len, trie->strings->dedup_count); + + hwdb_bin = path_join(arg_root, arg_hwdb_bin_dir, "/hwdb.bin"); + if (!hwdb_bin) + return -ENOMEM; + + mkdir_parents_label(hwdb_bin, 0755); + + r = trie_store(trie, hwdb_bin); + if (r < 0) + log_error_errno(r, "Failed to write database %s: %m", hwdb_bin); + + (void) label_fix(hwdb_bin, 0); + + return r; +} + +static int hwdb_test(void) { + _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; + const char *key, *value; + int r; + + r = sd_hwdb_new(&hwdb); + if (r < 0) + return r; + + SD_HWDB_FOREACH_PROPERTY(hwdb, arg_test, key, value) + printf("%s=%s\n", key, value); + + return 0; +} + +static int help(void) { printf("%s hwdb [OPTIONS]\n\n" " -h --help Print this message\n" " -V --version Print version of the program\n" @@ -551,9 +652,11 @@ static void help(void) { "The sub-command 'hwdb' is deprecated, and is left for backwards compatibility.\n" "Please use systemd-hwdb instead.\n" , program_invocation_short_name); + + return 0; } -static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { +static int parse_argv(int argc, char *argv[]) { enum { ARG_USR = 0x100, }; @@ -568,144 +671,59 @@ static int adm_hwdb(struct udev *udev, int argc, char *argv[]) { { "help", no_argument, NULL, 'h' }, {} }; - const char *test = NULL; - const char *root = ""; - const char *hwdb_bin_dir = "/etc/udev"; - bool update = false; - struct trie *trie = NULL; - int err, c; - int rc = EXIT_SUCCESS; - bool strict = false; + + int c; while ((c = getopt_long(argc, argv, "ust:r:Vh", options, NULL)) >= 0) switch(c) { case 'u': - update = true; + arg_update = true; break; case ARG_USR: - hwdb_bin_dir = UDEVLIBEXECDIR; + arg_hwdb_bin_dir = UDEVLIBEXECDIR; break; case 's': - strict = true; + arg_strict = true; break; case 't': - test = optarg; + arg_test = optarg; break; case 'r': - root = optarg; + arg_root = optarg; break; case 'V': - print_version(); - return EXIT_SUCCESS; + return version(); case 'h': - help(); - return EXIT_SUCCESS; + return help(); case '?': - return EXIT_FAILURE; + return -EINVAL; default: assert_not_reached("Unknown option"); } - if (!update && !test) { - log_error("Either --update or --test must be used"); - return EXIT_FAILURE; - } - - if (update) { - char **files, **f; - _cleanup_free_ char *hwdb_bin = NULL; - - trie = new0(struct trie, 1); - if (!trie) { - rc = EXIT_FAILURE; - goto out; - } - - /* string store */ - trie->strings = strbuf_new(); - if (!trie->strings) { - rc = EXIT_FAILURE; - goto out; - } - - /* index */ - trie->root = new0(struct trie_node, 1); - if (!trie->root) { - rc = EXIT_FAILURE; - goto out; - } - trie->nodes_count++; - - err = conf_files_list_strv(&files, ".hwdb", root, 0, conf_file_dirs); - if (err < 0) { - log_error_errno(err, "failed to enumerate hwdb files: %m"); - rc = EXIT_FAILURE; - goto out; - } - STRV_FOREACH(f, files) { - log_debug("reading file '%s'", *f); - if (import_file(udev, trie, *f) < 0 && strict) - rc = EXIT_FAILURE; - } - strv_free(files); - - strbuf_complete(trie->strings); - - log_debug("=== trie in-memory ==="); - log_debug("nodes: %8zu bytes (%8zu)", - trie->nodes_count * sizeof(struct trie_node), trie->nodes_count); - log_debug("children arrays: %8zu bytes (%8zu)", - trie->children_count * sizeof(struct trie_child_entry), trie->children_count); - log_debug("values arrays: %8zu bytes (%8zu)", - trie->values_count * sizeof(struct trie_value_entry), trie->values_count); - log_debug("strings: %8zu bytes", - trie->strings->len); - log_debug("strings incoming: %8zu bytes (%8zu)", - trie->strings->in_len, trie->strings->in_count); - log_debug("strings dedup'ed: %8zu bytes (%8zu)", - trie->strings->dedup_len, trie->strings->dedup_count); - - hwdb_bin = strjoin(root, "/", hwdb_bin_dir, "/hwdb.bin"); - if (!hwdb_bin) { - rc = EXIT_FAILURE; - goto out; - } - - 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; - } - - (void) label_fix(hwdb_bin, 0); - } - - if (test) { - _cleanup_(sd_hwdb_unrefp) sd_hwdb *hwdb = NULL; - int r; - - r = sd_hwdb_new(&hwdb); - if (r >= 0) { - const char *key, *value; - - SD_HWDB_FOREACH_PROPERTY(hwdb, test, key, value) - printf("%s=%s\n", key, value); - } - } -out: - if (trie) { - if (trie->root) - trie_node_cleanup(trie->root); - if (trie->strings) - strbuf_cleanup(trie->strings); - free(trie); - } - return rc; + return 1; } -const struct udevadm_cmd udevadm_hwdb = { - .name = "hwdb", - .cmd = adm_hwdb, -}; +int hwdb_main(int argc, char *argv[], void *userdata) { + int r; + + r = parse_argv(argc, argv); + if (r < 0) + return r; + + if (!arg_update && !arg_test) { + log_error("Either --update or --test must be used."); + return -EINVAL; + } + + if (arg_update) { + r = hwdb_update(); + if (r < 0) + return r; + } + + if (arg_test) + return hwdb_test(); + + return 0; +} diff --git a/src/udev/udevadm-info.c b/src/udev/udevadm-info.c index a7530e02e7..23a27d0a28 100644 --- a/src/udev/udevadm-info.c +++ b/src/udev/udevadm-info.c @@ -14,6 +14,7 @@ #include "fd-util.h" #include "string-util.h" #include "udev.h" +#include "udevadm.h" #include "udevadm-util.h" static bool skip_attribute(const char *name) { @@ -155,11 +156,11 @@ static int stat_device(const char *name, bool export, const char *prefix) { return 0; } -static int export_devices(struct udev *udev) { +static int export_devices(void) { _cleanup_(udev_enumerate_unrefp) struct udev_enumerate *udev_enumerate; struct udev_list_entry *list_entry; - udev_enumerate = udev_enumerate_new(udev); + udev_enumerate = udev_enumerate_new(NULL); if (udev_enumerate == NULL) return -ENOMEM; @@ -167,7 +168,7 @@ static int export_devices(struct udev *udev) { udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) { _cleanup_(udev_device_unrefp) struct udev_device *device; - device = udev_device_new_from_syspath(udev, udev_list_entry_get_name(list_entry)); + device = udev_device_new_from_syspath(NULL, udev_list_entry_get_name(list_entry)); if (device != NULL) print_record(device); } @@ -203,7 +204,7 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) { } } -static void cleanup_db(struct udev *udev) { +static void cleanup_db(void) { _cleanup_closedir_ DIR *dir1 = NULL, *dir2 = NULL, *dir3 = NULL, *dir4 = NULL, *dir5 = NULL; (void) unlink("/run/udev/queue.bin"); @@ -229,7 +230,7 @@ static void cleanup_db(struct udev *udev) { cleanup_dir(dir5, 0, 1); } -static void help(void) { +static int help(void) { printf("%s info [OPTIONS] [DEVPATH|FILE]\n\n" "Query sysfs or the udev database.\n\n" @@ -252,16 +253,18 @@ static void help(void) { " -e --export-db Export the content of the udev database\n" " -c --cleanup-db Clean up the udev database\n" , program_invocation_short_name); + + return 0; } -static int uinfo(struct udev *udev, int argc, char *argv[]) { +int info_main(int argc, char *argv[], void *userdata) { _cleanup_(udev_device_unrefp) struct udev_device *device = NULL; bool root = 0; bool export = 0; const char *export_prefix = NULL; char name[UTIL_PATH_SIZE]; struct udev_list_entry *list_entry; - int c; + int c, r; static const struct option options[] = { { "name", required_argument, NULL, 'n' }, @@ -295,30 +298,25 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { while ((c = getopt_long(argc, argv, "aced:n:p:q:rxP:RVh", options, NULL)) >= 0) switch (c) { - case 'n': { - if (device != NULL) { - fprintf(stderr, "device already specified\n"); - return 2; + case 'n': + if (device) { + log_error("device already specified"); + return -EINVAL; } - device = find_device(udev, optarg, "/dev/"); - if (device == NULL) { - fprintf(stderr, "device node not found\n"); - return 2; - } + device = find_device(optarg, "/dev/"); + if (!device) + return log_error_errno(errno, "device node not found: %m"); break; - } case 'p': - if (device != NULL) { - fprintf(stderr, "device already specified\n"); - return 2; + if (device) { + log_error("device already specified"); + return -EINVAL; } - device = find_device(udev, optarg, "/sys"); - if (device == NULL) { - fprintf(stderr, "syspath not found\n"); - return 2; - } + device = find_device(optarg, "/sys"); + if (!device) + return log_error_errno(errno, "syspath not found: %m"); break; case 'q': action = ACTION_QUERY; @@ -333,8 +331,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { else if (streq(optarg, "all")) query = QUERY_ALL; else { - fprintf(stderr, "unknown query type\n"); - return 3; + log_error("unknown query type"); + return -EINVAL; } break; case 'r': @@ -348,11 +346,9 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { action = ACTION_ATTRIBUTE_WALK; break; case 'e': - if (export_devices(udev) < 0) - return 1; - return 0; + return export_devices(); case 'c': - cleanup_db(udev); + cleanup_db(); return 0; case 'x': export = true; @@ -361,13 +357,13 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { export_prefix = optarg; break; case 'V': - print_version(); - return 0; + return version(); case 'h': - help(); - return 0; + return help(); + case '?': + return -EINVAL; default: - return 1; + assert_not_reached("Unknown option"); } switch (action) { @@ -375,12 +371,12 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { if (!device) { if (!argv[optind]) { help(); - return 2; + return -EINVAL; } - device = find_device(udev, argv[optind], NULL); + device = find_device(argv[optind], NULL); if (!device) { - fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); - return 4; + log_error("Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected."); + return -EINVAL; } } @@ -388,10 +384,8 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { case QUERY_NAME: { const char *node = udev_device_get_devnode(device); - if (node == NULL) { - fprintf(stderr, "no device node found\n"); - return 5; - } + if (!node) + return log_error_errno(errno, "no device node found"); if (root) printf("%s\n", udev_device_get_devnode(device)); @@ -402,14 +396,14 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { } case QUERY_SYMLINK: list_entry = udev_device_get_devlinks_list_entry(device); - while (list_entry != NULL) { + while (list_entry) { if (root) printf("%s", udev_list_entry_get_name(list_entry)); else printf("%s", udev_list_entry_get_name(list_entry) + STRLEN("/dev/")); list_entry = udev_list_entry_get_next(list_entry); - if (list_entry != NULL) + if (list_entry) printf(" "); } printf("\n"); @@ -419,7 +413,7 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { return 0; case QUERY_PROPERTY: list_entry = udev_device_get_properties_list_entry(device); - while (list_entry != NULL) { + while (list_entry) { if (export) printf("%s%s='%s'\n", strempty(export_prefix), udev_list_entry_get_name(list_entry), @@ -439,29 +433,24 @@ static int uinfo(struct udev *udev, int argc, char *argv[]) { break; case ACTION_ATTRIBUTE_WALK: if (!device && argv[optind]) { - device = find_device(udev, argv[optind], NULL); + device = find_device(argv[optind], NULL); if (!device) { - fprintf(stderr, "Unknown device, absolute path in /dev/ or /sys expected.\n"); - return 4; + log_error("Unknown device, absolute path in /dev/ or /sys expected."); + return -EINVAL; } } if (!device) { - fprintf(stderr, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.\n"); - return 4; + log_error("Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected."); + return -EINVAL; } print_device_chain(device); break; case ACTION_DEVICE_ID_FILE: - if (stat_device(name, export, export_prefix) != 0) - return 1; + r = stat_device(name, export, export_prefix); + if (r < 0) + return r; break; } return 0; } - -const struct udevadm_cmd udevadm_info = { - .name = "info", - .cmd = uinfo, - .help = "Query sysfs or the udev database", -}; diff --git a/src/udev/udevadm-monitor.c b/src/udev/udevadm-monitor.c index aa6600f6a5..ba6f30f17f 100644 --- a/src/udev/udevadm-monitor.c +++ b/src/udev/udevadm-monitor.c @@ -10,40 +10,113 @@ #include #include +#include "libudev.h" +#include "sd-device.h" + +#include "alloc-util.h" +#include "device-util.h" #include "fd-util.h" #include "format-util.h" -#include "udev.h" -#include "udevadm-util.h" +#include "hashmap.h" +#include "libudev-private.h" +#include "set.h" +#include "string-util.h" +#include "udevadm.h" -static bool udev_exit; +static bool udev_exit = false; +static bool arg_show_property = false; +static bool arg_print_kernel = false; +static bool arg_print_udev = false; +static Set *arg_tag_filter = NULL; +static Hashmap *arg_subsystem_filter = NULL; static void sig_handler(int signum) { if (IN_SET(signum, SIGINT, SIGTERM)) udev_exit = true; } -static void print_device(struct udev_device *device, const char *source, int prop) { +static int receive_and_print_device(struct udev_monitor *monitor, const char *source) { + const char *action = NULL, *devpath = NULL, *subsystem = NULL; + _cleanup_(sd_device_unrefp) sd_device *device = NULL; struct timespec ts; + int r; + + r = udev_monitor_receive_sd_device(monitor, &device); + if (r < 0) + return log_debug_errno(r, "Failed to receive device from %s, ignoring: %m", source); + + (void) sd_device_get_property_value(device, "ACTION", &action); + (void) sd_device_get_devpath(device, &devpath); + (void) sd_device_get_subsystem(device, &subsystem); assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0); + printf("%-6s[%"PRI_TIME".%06"PRI_NSEC"] %-8s %s (%s)\n", source, ts.tv_sec, (nsec_t)ts.tv_nsec/1000, - udev_device_get_action(device), - udev_device_get_devpath(device), - udev_device_get_subsystem(device)); - if (prop) { - struct udev_list_entry *list_entry; + action, devpath, subsystem); + + if (arg_show_property) { + const char *key, *value; + + FOREACH_DEVICE_PROPERTY(device, key, value) + printf("%s=%s\n", key, value); - udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device)) - printf("%s=%s\n", - udev_list_entry_get_name(list_entry), - udev_list_entry_get_value(list_entry)); printf("\n"); } + + return 0; } -static void help(void) { +static int setup_monitor(const char *sender, int fd_epoll, struct udev_monitor **ret) { + _cleanup_(udev_monitor_unrefp) struct udev_monitor *monitor = NULL; + const char *subsystem, *devtype, *tag; + struct epoll_event ep = {}; + Iterator i; + int fd, r; + + monitor = udev_monitor_new_from_netlink(NULL, sender); + if (!monitor) + return log_error_errno(errno, "Failed to create netlink socket: %m"); + + r = udev_monitor_set_receive_buffer_size(monitor, 128*1024*1024); + if (r < 0) + return log_error_errno(r, "Failed to set receive buffer size: %m"); + + fd = udev_monitor_get_fd(monitor); + if (fd < 0) + return log_error_errno(r, "Failed to get socket fd for monitoring: %m"); + + HASHMAP_FOREACH_KEY(devtype, subsystem, arg_subsystem_filter, i) { + r = udev_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, devtype); + if (r < 0) + return log_error_errno(r, "Failed to apply subsystem filter '%s%s%s': %m", + subsystem, devtype ? "/" : "", strempty(devtype)); + } + + SET_FOREACH(tag, arg_tag_filter, i) { + r = udev_monitor_filter_add_match_tag(monitor, tag); + if (r < 0) + return log_error_errno(r, "Failed to apply tag filter '%s': %m", tag); + } + + r = udev_monitor_enable_receiving(monitor); + if (r < 0) + return log_error_errno(r, "Failed to subscribe %s events: %m", sender); + + ep = (struct epoll_event) { + .events = EPOLLIN, + .data.fd = fd, + }; + + if (epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd, &ep) < 0) + return log_error_errno(errno, "Failed to add fd to epoll: %m"); + + *ret = TAKE_PTR(monitor); + return fd; +} + +static int help(void) { printf("%s monitor [OPTIONS]\n\n" "Listen to kernel and udev events.\n\n" " -h --help Show this help\n" @@ -54,23 +127,11 @@ static void help(void) { " -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n" " -t --tag-match=TAG Filter events by tag\n" , program_invocation_short_name); + + return 0; } -static int adm_monitor(struct udev *udev, int argc, char *argv[]) { - struct sigaction act = {}; - sigset_t mask; - bool prop = false; - bool print_kernel = false; - bool print_udev = false; - _cleanup_(udev_list_cleanup) struct udev_list subsystem_match_list; - _cleanup_(udev_list_cleanup) struct udev_list tag_match_list; - _cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor = NULL; - _cleanup_(udev_monitor_unrefp) struct udev_monitor *kernel_monitor = NULL; - _cleanup_close_ int fd_ep = -1; - int fd_kernel = -1, fd_udev = -1; - struct epoll_event ep_kernel, ep_udev; - int c; - +static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "property", no_argument, NULL, 'p' }, { "environment", no_argument, NULL, 'e' }, /* alias for -p */ @@ -83,56 +144,101 @@ 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); + int r, c; while ((c = getopt_long(argc, argv, "pekus:t:Vh", options, NULL)) >= 0) switch (c) { case 'p': case 'e': - prop = true; + arg_show_property = true; break; case 'k': - print_kernel = true; + arg_print_kernel = true; break; case 'u': - print_udev = true; + arg_print_udev = true; break; - case 's': - { - char subsys[UTIL_NAME_SIZE]; - char *devtype; + case 's': { + _cleanup_free_ char *subsystem = NULL, *devtype = NULL; + const char *slash; - strscpy(subsys, sizeof(subsys), optarg); - devtype = strchr(subsys, '/'); - if (devtype != NULL) { - devtype[0] = '\0'; - devtype++; - } - udev_list_entry_add(&subsystem_match_list, subsys, devtype); - break; - } - case 't': - udev_list_entry_add(&tag_match_list, optarg, NULL); + slash = strchr(optarg, '/'); + if (slash) { + devtype = strdup(devtype + 1); + if (!devtype) + return -ENOMEM; + + subsystem = strndup(optarg, devtype - optarg); + } else + subsystem = strdup(optarg); + + if (!subsystem) + return -ENOMEM; + + r = hashmap_ensure_allocated(&arg_subsystem_filter, NULL); + if (r < 0) + return r; + + r = hashmap_put(arg_subsystem_filter, subsystem, devtype); + if (r < 0) + return r; + + subsystem = devtype = NULL; break; + } + case 't': { + _cleanup_free_ char *tag = NULL; + + r = set_ensure_allocated(&arg_tag_filter, &string_hash_ops); + if (r < 0) + return r; + + tag = strdup(optarg); + if (!tag) + return -ENOMEM; + + r = set_put(arg_tag_filter, tag); + if (r < 0) + return r; + + tag = NULL; + break; + } case 'V': - print_version(); - return 0; + return version(); case 'h': - help(); - return 0; + return help(); + case '?': + return -EINVAL; default: - return 1; + assert_not_reached("Unknown option."); } - if (!print_kernel && !print_udev) { - print_kernel = true; - print_udev = true; + if (!arg_print_kernel && !arg_print_udev) { + arg_print_kernel = true; + arg_print_udev = true; } + return 1; +} + +int monitor_main(int argc, char *argv[], void *userdata) { + _cleanup_(udev_monitor_unrefp) struct udev_monitor *kernel_monitor = NULL, *udev_monitor = NULL; + int fd_kernel = -1, fd_udev = -1; + _cleanup_close_ int fd_ep = -1; + struct sigaction act; + sigset_t mask; + int r; + + r = parse_argv(argc, argv); + if (r <= 0) + goto finalize; + /* set signal handlers */ - act.sa_handler = sig_handler; - act.sa_flags = SA_RESTART; + act = (struct sigaction) { + .sa_handler = sig_handler, + .sa_flags = SA_RESTART, + }; assert_se(sigaction(SIGINT, &act, NULL) == 0); assert_se(sigaction(SIGTERM, &act, NULL) == 0); assert_se(sigemptyset(&mask) == 0); @@ -145,82 +251,26 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) { fd_ep = epoll_create1(EPOLL_CLOEXEC); if (fd_ep < 0) { - log_error_errno(errno, "error creating epoll fd: %m"); - return 1; + r = log_error_errno(errno, "Failed to create epoll fd: %m"); + goto finalize; } printf("monitor will print the received events for:\n"); - if (print_udev) { - struct udev_list_entry *entry; - - udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); - if (udev_monitor == NULL) { - fprintf(stderr, "error: unable to create netlink socket\n"); - return 1; - } - udev_monitor_set_receive_buffer_size(udev_monitor, 128*1024*1024); - fd_udev = udev_monitor_get_fd(udev_monitor); - - udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) { - const char *subsys = udev_list_entry_get_name(entry); - const char *devtype = udev_list_entry_get_value(entry); - - if (udev_monitor_filter_add_match_subsystem_devtype(udev_monitor, subsys, devtype) < 0) - fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys); - } - - udev_list_entry_foreach(entry, udev_list_get_entry(&tag_match_list)) { - const char *tag = udev_list_entry_get_name(entry); - - if (udev_monitor_filter_add_match_tag(udev_monitor, tag) < 0) - fprintf(stderr, "error: unable to apply tag filter '%s'\n", tag); - } - - if (udev_monitor_enable_receiving(udev_monitor) < 0) { - fprintf(stderr, "error: unable to subscribe to udev events\n"); - return 2; - } - - memzero(&ep_udev, sizeof(struct epoll_event)); - ep_udev.events = EPOLLIN; - ep_udev.data.fd = fd_udev; - if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) { - log_error_errno(errno, "fail to add fd to epoll: %m"); - return 2; + if (arg_print_udev) { + fd_udev = setup_monitor("udev", fd_ep, &udev_monitor); + if (fd_udev < 0) { + r = fd_udev; + goto finalize; } printf("UDEV - the event which udev sends out after rule processing\n"); } - if (print_kernel) { - struct udev_list_entry *entry; - - kernel_monitor = udev_monitor_new_from_netlink(udev, "kernel"); - if (kernel_monitor == NULL) { - fprintf(stderr, "error: unable to create netlink socket\n"); - return 3; - } - udev_monitor_set_receive_buffer_size(kernel_monitor, 128*1024*1024); - fd_kernel = udev_monitor_get_fd(kernel_monitor); - - udev_list_entry_foreach(entry, udev_list_get_entry(&subsystem_match_list)) { - const char *subsys = udev_list_entry_get_name(entry); - - if (udev_monitor_filter_add_match_subsystem_devtype(kernel_monitor, subsys, NULL) < 0) - fprintf(stderr, "error: unable to apply subsystem filter '%s'\n", subsys); - } - - if (udev_monitor_enable_receiving(kernel_monitor) < 0) { - fprintf(stderr, "error: unable to subscribe to kernel events\n"); - return 4; - } - - memzero(&ep_kernel, sizeof(struct epoll_event)); - ep_kernel.events = EPOLLIN; - ep_kernel.data.fd = fd_kernel; - if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_kernel, &ep_kernel) < 0) { - log_error_errno(errno, "fail to add fd to epoll: %m"); - return 5; + if (arg_print_kernel) { + fd_kernel = setup_monitor("kernel", fd_ep, &kernel_monitor); + if (fd_kernel < 0) { + r = fd_kernel; + goto finalize; } printf("KERNEL - the kernel uevent\n"); @@ -228,43 +278,28 @@ static int adm_monitor(struct udev *udev, int argc, char *argv[]) { printf("\n"); while (!udev_exit) { - int fdcount; struct epoll_event ev[4]; - int i; + int fdcount, i; fdcount = epoll_wait(fd_ep, ev, ELEMENTSOF(ev), -1); if (fdcount < 0) { if (errno != EINTR) - fprintf(stderr, "error receiving uevent message: %m\n"); + log_debug_errno(errno, "Failed to receive uevent message, ignoring: %m"); continue; } - for (i = 0; i < fdcount; i++) { - if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) { - struct udev_device *device; - - device = udev_monitor_receive_device(kernel_monitor); - if (device == NULL) - continue; - print_device(device, "KERNEL", prop); - udev_device_unref(device); - } else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) { - struct udev_device *device; - - device = udev_monitor_receive_device(udev_monitor); - if (device == NULL) - continue; - print_device(device, "UDEV", prop); - udev_device_unref(device); - } - } + for (i = 0; i < fdcount; i++) + if (ev[i].data.fd == fd_kernel && ev[i].events & EPOLLIN) + (void) receive_and_print_device(kernel_monitor, "KERNEL"); + else if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) + (void) receive_and_print_device(udev_monitor, "UDEV"); } - return 0; -} + r = 0; -const struct udevadm_cmd udevadm_monitor = { - .name = "monitor", - .cmd = adm_monitor, - .help = "Listen to kernel and udev events", -}; +finalize: + hashmap_free_free_free(arg_subsystem_filter); + set_free_free(arg_tag_filter); + + return r; +} diff --git a/src/udev/udevadm-settle.c b/src/udev/udevadm-settle.c index 33173522fe..a172b25ada 100644 --- a/src/udev/udevadm-settle.c +++ b/src/udev/udevadm-settle.c @@ -13,22 +13,26 @@ #include #include -#include "parse-util.h" +#include "time-util.h" +#include "udevadm.h" #include "udev.h" -#include "udevadm-util.h" -#include "util.h" -static void help(void) { +static usec_t arg_timeout = 120 * USEC_PER_SEC; +static const char *arg_exists = NULL; + +static int help(void) { printf("%s settle [OPTIONS]\n\n" "Wait for pending udev events.\n\n" " -h --help Show this help\n" " -V --version Show package version\n" - " -t --timeout=SECONDS Maximum time to wait for events\n" + " -t --timeout=SEC Maximum time to wait for events\n" " -E --exit-if-exists=FILE Stop waiting if file exists\n" , program_invocation_short_name); + + return 0; } -static int adm_settle(struct udev *udev, int argc, char *argv[]) { +static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "timeout", required_argument, NULL, 't' }, { "exit-if-exists", required_argument, NULL, 'E' }, @@ -39,117 +43,95 @@ static int adm_settle(struct udev *udev, int argc, char *argv[]) { { "quiet", no_argument, NULL, 'q' }, /* removed */ {} }; - usec_t deadline; - const char *exists = NULL; - unsigned int timeout = 120; - struct pollfd pfd[1] = { {.fd = -1}, }; - int c; - struct udev_queue *queue; - int rc = EXIT_FAILURE; + + int c, r; while ((c = getopt_long(argc, argv, "t:E:Vhs:e:q", options, NULL)) >= 0) { switch (c) { - - case 't': { - int r; - - r = safe_atou(optarg, &timeout); - if (r < 0) { - log_error_errno(r, "Invalid timeout value '%s': %m", optarg); - return EXIT_FAILURE; - } + case 't': + r = parse_sec(optarg, &arg_timeout); + if (r < 0) + return log_error_errno(r, "Failed to parse timeout value '%s': %m", optarg); break; - } - case 'E': - exists = optarg; + arg_exists = optarg; break; - case 'V': - print_version(); - return EXIT_SUCCESS; - + return version(); case 'h': - help(); - return EXIT_SUCCESS; - + return help(); case 's': case 'e': case 'q': log_info("Option -%c no longer supported.", c); - return EXIT_FAILURE; - + return -EINVAL; case '?': - return EXIT_FAILURE; - + return -EINVAL; default: - assert_not_reached("Unknown argument"); + assert_not_reached("Unknown option."); } } - if (optind < argc) { - fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]); - return EXIT_FAILURE; - } + return 1; +} - deadline = now(CLOCK_MONOTONIC) + timeout * USEC_PER_SEC; +int settle_main(int argc, char *argv[], void *userdata) { + _cleanup_(udev_queue_unrefp) struct udev_queue *queue = NULL; + struct pollfd pfd; + usec_t deadline; + int r; + + r = parse_argv(argc, argv); + if (r <= 0) + return r; + + deadline = now(CLOCK_MONOTONIC) + arg_timeout; /* guarantee that the udev daemon isn't pre-processing */ if (getuid() == 0) { - struct udev_ctrl *uctrl; + _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *uctrl = NULL; - uctrl = udev_ctrl_new(udev); - if (uctrl != NULL) { - if (udev_ctrl_send_ping(uctrl, MAX(5U, timeout)) < 0) { - log_debug("no connection to daemon"); - udev_ctrl_unref(uctrl); - return EXIT_SUCCESS; + uctrl = udev_ctrl_new(); + if (uctrl) { + r = udev_ctrl_send_ping(uctrl, MAX(5U, arg_timeout / USEC_PER_SEC)); + if (r < 0) { + log_debug_errno(r, "Failed to connect to udev daemon."); + return 0; } - udev_ctrl_unref(uctrl); } } - queue = udev_queue_new(udev); - if (!queue) { - log_error("unable to get udev queue"); - return EXIT_FAILURE; + queue = udev_queue_new(NULL); + if (!queue) + return log_error_errno(errno, "Failed to get udev queue: %m"); + + r = udev_queue_get_fd(queue); + if (r < 0) { + log_debug_errno(r, "Queue is empty, nothing to watch."); + return 0; } - pfd[0].events = POLLIN; - pfd[0].fd = udev_queue_get_fd(queue); - if (pfd[0].fd < 0) { - log_debug("queue is empty, nothing to watch"); - rc = EXIT_SUCCESS; - goto out; - } + pfd = (struct pollfd) { + .events = POLLIN, + .fd = r, + }; for (;;) { - if (exists && access(exists, F_OK) >= 0) { - rc = EXIT_SUCCESS; - break; - } + if (arg_exists && access(arg_exists, F_OK) >= 0) + return 0; /* exit if queue is empty */ - if (udev_queue_get_queue_is_empty(queue)) { - rc = EXIT_SUCCESS; - break; - } + if (udev_queue_get_queue_is_empty(queue)) + return 0; if (now(CLOCK_MONOTONIC) >= deadline) - break; + return -ETIMEDOUT; - /* wake up when queue is empty */ - if (poll(pfd, 1, MSEC_PER_SEC) > 0 && pfd[0].revents & POLLIN) - udev_queue_flush(queue); + /* wake up when queue becomes empty */ + if (poll(&pfd, 1, MSEC_PER_SEC) > 0 && pfd.revents & POLLIN) { + r = udev_queue_flush(queue); + if (r < 0) + return log_error_errno(r, "Failed to flush queue: %m"); + } } - -out: - udev_queue_unref(queue); - return rc; } - -const struct udevadm_cmd udevadm_settle = { - .name = "settle", - .cmd = adm_settle, - .help = "Wait for pending udev events", -}; diff --git a/src/udev/udevadm-test-builtin.c b/src/udev/udevadm-test-builtin.c index c19ba4b45f..ac1a8c2d7d 100644 --- a/src/udev/udevadm-test-builtin.c +++ b/src/udev/udevadm-test-builtin.c @@ -9,9 +9,12 @@ #include "path-util.h" #include "string-util.h" #include "udev.h" -#include "udevadm-util.h" +#include "udevadm.h" -static void help(struct udev *udev) { +static const char *arg_command = NULL; +static char arg_syspath[UTIL_PATH_SIZE] = {}; + +static int help(void) { printf("%s test-builtin [OPTIONS] COMMAND DEVPATH\n\n" "Test a built-in command.\n\n" " -h --help Print this message\n" @@ -19,85 +22,85 @@ static void help(struct udev *udev) { "Commands:\n" , program_invocation_short_name); - udev_builtin_list(udev); + udev_builtin_list(); + + return 0; } -static int adm_builtin(struct udev *udev, int argc, char *argv[]) { +static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "version", no_argument, NULL, 'V' }, { "help", no_argument, NULL, 'h' }, {} }; - char *command = NULL; - char *syspath = NULL; - char filename[UTIL_PATH_SIZE]; - struct udev_device *dev = NULL; - enum udev_builtin_cmd cmd; - int rc = EXIT_SUCCESS, c; + + const char *s; + int c; while ((c = getopt_long(argc, argv, "Vh", options, NULL)) >= 0) switch (c) { case 'V': - print_version(); - goto out; + return version(); case 'h': - help(udev); - goto out; + return help(); + case '?': + return -EINVAL; + default: + assert_not_reached("Unknown option"); } - command = argv[optind++]; - if (command == NULL) { - fprintf(stderr, "command missing\n"); - help(udev); - rc = 2; - goto out; + arg_command = argv[optind++]; + if (!arg_command) { + log_error("Command missing."); + return -EINVAL; } - syspath = argv[optind++]; - if (syspath == NULL) { - fprintf(stderr, "syspath missing\n"); - rc = 3; - goto out; - } - - udev_builtin_init(udev); - - cmd = udev_builtin_lookup(command); - if (cmd >= UDEV_BUILTIN_MAX) { - fprintf(stderr, "unknown command '%s'\n", command); - help(udev); - rc = 5; - goto out; + s = argv[optind++]; + if (!s) { + log_error("syspath missing."); + return -EINVAL; } /* add /sys if needed */ - if (!path_startswith(syspath, "/sys")) - strscpyl(filename, sizeof(filename), "/sys", syspath, NULL); + if (!path_startswith(s, "/sys")) + strscpyl(arg_syspath, sizeof(arg_syspath), "/sys", s, NULL); else - strscpy(filename, sizeof(filename), syspath); - delete_trailing_chars(filename, "/"); + strscpy(arg_syspath, sizeof(arg_syspath), s); - dev = udev_device_new_from_syspath(udev, filename); - if (dev == NULL) { - fprintf(stderr, "unable to open device '%s'\n\n", filename); - rc = 4; - goto out; - } - - rc = udev_builtin_run(dev, cmd, command, true); - if (rc < 0) { - fprintf(stderr, "error executing '%s', exit code %i\n\n", command, rc); - rc = 6; - } -out: - udev_device_unref(dev); - udev_builtin_exit(udev); - return rc; + return 1; } -const struct udevadm_cmd udevadm_test_builtin = { - .name = "test-builtin", - .cmd = adm_builtin, - .help = "Test a built-in command", - .debug = true, -}; +int builtin_main(int argc, char *argv[], void *userdata) { + _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; + enum udev_builtin_cmd cmd; + int r; + + log_set_max_level(LOG_DEBUG); + + r = parse_argv(argc, argv); + if (r <= 0) + return r; + + udev_builtin_init(); + + cmd = udev_builtin_lookup(arg_command); + if (cmd >= UDEV_BUILTIN_MAX) { + log_error("Unknown command '%s'", arg_command); + r = -EINVAL; + goto finish; + } + + dev = udev_device_new_from_syspath(NULL, arg_syspath); + if (!dev) { + r = log_error_errno(errno, "Failed to open device '%s'", arg_syspath); + goto finish; + } + + r = udev_builtin_run(dev, cmd, arg_command, true); + if (r < 0) + log_debug("error executing '%s', exit code %i", arg_command, r); + +finish: + udev_builtin_exit(); + return r; +} diff --git a/src/udev/udevadm-test.c b/src/udev/udevadm-test.c index cad462e281..65e14a8664 100644 --- a/src/udev/udevadm-test.c +++ b/src/udev/udevadm-test.c @@ -14,9 +14,13 @@ #include "string-util.h" #include "udev.h" -#include "udevadm-util.h" +#include "udevadm.h" -static void help(void) { +static const char *arg_action = "add"; +static int arg_resolve_names = 1; +static char arg_syspath[UTIL_PATH_SIZE] = {}; + +static int help(void) { printf("%s test [OPTIONS] DEVPATH\n\n" "Test an event run.\n\n" @@ -25,20 +29,11 @@ static void help(void) { " -a --action=ACTION Set action string\n" " -N --resolve-names=early|late|never When to resolve names\n" , program_invocation_short_name); + + return 0; } -static int adm_test(struct udev *udev, int argc, char *argv[]) { - int resolve_names = 1; - char filename[UTIL_PATH_SIZE]; - const char *action = "add"; - const char *syspath = NULL; - struct udev_list_entry *entry; - _cleanup_(udev_rules_unrefp) struct udev_rules *rules = NULL; - _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; - _cleanup_(udev_event_unrefp) struct udev_event *event = NULL; - sigset_t mask, sigmask_orig; - int rc = 0, c; - +static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { { "action", required_argument, NULL, 'a' }, { "resolve-names", required_argument, NULL, 'N' }, @@ -47,45 +42,63 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) { {} }; - log_debug("version %s", PACKAGE_VERSION); + int c; while ((c = getopt_long(argc, argv, "a:N:Vh", options, NULL)) >= 0) switch (c) { case 'a': - action = optarg; + arg_action = optarg; break; case 'N': if (streq (optarg, "early")) { - resolve_names = 1; + arg_resolve_names = 1; } else if (streq (optarg, "late")) { - resolve_names = 0; + arg_resolve_names = 0; } else if (streq (optarg, "never")) { - resolve_names = -1; + arg_resolve_names = -1; } else { - fprintf(stderr, "resolve-names must be early, late or never\n"); log_error("resolve-names must be early, late or never"); - exit(EXIT_FAILURE); + return -EINVAL; } break; case 'V': - print_version(); - exit(EXIT_SUCCESS); + return version(); case 'h': - help(); - exit(EXIT_SUCCESS); + return help(); case '?': - exit(EXIT_FAILURE); + return -EINVAL; default: assert_not_reached("Unknown option"); } - syspath = argv[optind]; - if (syspath == NULL) { - fprintf(stderr, "syspath parameter missing\n"); - rc = 2; - goto out; + if (!argv[optind]) { + log_error("syspath parameter missing."); + return -EINVAL; } + /* add /sys if needed */ + if (!startswith(argv[optind], "/sys")) + strscpyl(arg_syspath, sizeof(arg_syspath), "/sys", argv[optind], NULL); + else + strscpy(arg_syspath, sizeof(arg_syspath), argv[optind]); + + return 1; +} + +int test_main(int argc, char *argv[], void *userdata) { + _cleanup_(udev_rules_unrefp) struct udev_rules *rules = NULL; + _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; + _cleanup_(udev_event_unrefp) struct udev_event *event = NULL; + struct udev_list_entry *entry; + sigset_t mask, sigmask_orig; + int r; + + log_set_max_level(LOG_DEBUG); + + r = parse_argv(argc, argv); + if (r <= 0) + return r; + printf("This program is for debugging only, it does not run any program\n" "specified by a RUN key. It may show incorrect results, because\n" "some values may be different, or not available at a simulation run.\n" @@ -93,26 +106,18 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) { sigprocmask(SIG_SETMASK, NULL, &sigmask_orig); - udev_builtin_init(udev); + udev_builtin_init(); - rules = udev_rules_new(udev, resolve_names); - if (rules == NULL) { - fprintf(stderr, "error reading rules\n"); - rc = 3; + rules = udev_rules_new(arg_resolve_names); + if (!rules) { + log_error("Failed to read udev rules."); + r = -ENOMEM; goto out; } - /* add /sys if needed */ - if (!startswith(syspath, "/sys")) - strscpyl(filename, sizeof(filename), "/sys", syspath, NULL); - else - strscpy(filename, sizeof(filename), syspath); - delete_trailing_chars(filename, "/"); - - dev = udev_device_new_from_synthetic_event(udev, filename, action); + dev = udev_device_new_from_synthetic_event(NULL, arg_syspath, arg_action); if (dev == NULL) { - fprintf(stderr, "unable to open device '%s'\n", filename); - rc = 4; + r = log_error_errno(errno, "Failed to open device '%s': %m", arg_syspath); goto out; } @@ -138,14 +143,9 @@ static int adm_test(struct udev *udev, int argc, char *argv[]) { udev_event_apply_format(event, udev_list_entry_get_name(entry), program, sizeof(program), false); printf("run: '%s'\n", program); } -out: - udev_builtin_exit(udev); - return rc; -} -const struct udevadm_cmd udevadm_test = { - .name = "test", - .cmd = adm_test, - .help = "Test an event run", - .debug = true, -}; + r = 0; +out: + udev_builtin_exit(); + return r; +} diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index 5d90911894..84a977e094 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -12,6 +12,7 @@ #include "set.h" #include "string-util.h" #include "udev.h" +#include "udevadm.h" #include "udevadm-util.h" #include "util.h" @@ -64,7 +65,7 @@ static const char *keyval(const char *str, const char **val, char *buf, size_t s return buf; } -static void help(void) { +static int help(void) { printf("%s trigger [OPTIONS] DEVPATH\n\n" "Request events from the kernel.\n\n" " -h --help Show this help\n" @@ -86,9 +87,11 @@ static void help(void) { " -b --parent-match=NAME Trigger devices with that parent device\n" " -w --settle Wait for the triggered events to complete\n" , program_invocation_short_name); + + return 0; } -static int adm_trigger(struct udev *udev, int argc, char *argv[]) { +int trigger_main(int argc, char *argv[], void *userdata) { enum { ARG_NAME = 0x100, }; @@ -126,9 +129,9 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { _cleanup_set_free_free_ Set *settle_set = NULL; int c, r; - udev_enumerate = udev_enumerate_new(udev); + udev_enumerate = udev_enumerate_new(NULL); if (!udev_enumerate) - return 1; + return -errno; while ((c = getopt_long(argc, argv, "vnt:c:s:S:a:A:p:g:y:b:wVh", options, NULL)) >= 0) { const char *key; @@ -149,83 +152,66 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { device_type = TYPE_SUBSYSTEMS; else { log_error("unknown type --type=%s", optarg); - return 2; + return -EINVAL; } break; case 'c': - if (!STR_IN_SET(optarg, "add", "remove", "change")) { - log_error("unknown action '%s'", optarg); - return 2; - } else + if (STR_IN_SET(optarg, "add", "remove", "change")) action = optarg; + else { + log_error("unknown action '%s'", optarg); + return -EINVAL; + } break; case 's': r = udev_enumerate_add_match_subsystem(udev_enumerate, optarg); - if (r < 0) { - log_error_errno(r, "could not add subsystem match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add subsystem match '%s': %m", optarg); break; case 'S': r = udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg); - if (r < 0) { - log_error_errno(r, "could not add negative subsystem match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add negative subsystem match '%s': %m", optarg); break; case 'a': key = keyval(optarg, &val, buf, sizeof(buf)); r = udev_enumerate_add_match_sysattr(udev_enumerate, key, val); - if (r < 0) { - log_error_errno(r, "could not add sysattr match '%s=%s': %m", key, val); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add sysattr match '%s=%s': %m", key, val); break; case 'A': key = keyval(optarg, &val, buf, sizeof(buf)); r = udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val); - if (r < 0) { - log_error_errno(r, "could not add negative sysattr match '%s=%s': %m", key, val); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add negative sysattr match '%s=%s': %m", key, val); break; case 'p': key = keyval(optarg, &val, buf, sizeof(buf)); r = udev_enumerate_add_match_property(udev_enumerate, key, val); - if (r < 0) { - log_error_errno(r, "could not add property match '%s=%s': %m", key, val); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add property match '%s=%s': %m", key, val); break; case 'g': r = udev_enumerate_add_match_tag(udev_enumerate, optarg); - if (r < 0) { - log_error_errno(r, "could not add tag match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add tag match '%s': %m", optarg); break; case 'y': r = udev_enumerate_add_match_sysname(udev_enumerate, optarg); - if (r < 0) { - log_error_errno(r, "could not add sysname match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add sysname match '%s': %m", optarg); break; case 'b': { _cleanup_(udev_device_unrefp) struct udev_device *dev; - dev = find_device(udev, optarg, "/sys"); - if (!dev) { - log_error("unable to open the device '%s'", optarg); - return 2; - } + dev = find_device(optarg, "/sys"); + if (!dev) + return log_error_errno(errno, "unable to open the device '%s'", optarg); r = udev_enumerate_add_match_parent(udev_enumerate, dev); - if (r < 0) { - log_error_errno(r, "could not add parent match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add parent match '%s': %m", optarg); break; } case 'w': @@ -235,28 +221,22 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { case ARG_NAME: { _cleanup_(udev_device_unrefp) struct udev_device *dev; - dev = find_device(udev, optarg, "/dev/"); - if (!dev) { - log_error("unable to open the device '%s'", optarg); - return 2; - } + dev = find_device(optarg, "/dev/"); + if (!dev) + return log_error_errno(errno, "unable to open the device '%s'", optarg); r = udev_enumerate_add_match_parent(udev_enumerate, dev); - if (r < 0) { - log_error_errno(r, "could not add parent match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add parent match '%s': %m", optarg); break; } case 'V': - print_version(); - return 0; + return version(); case 'h': - help(); - return 0; + return help(); case '?': - return 1; + return -EINVAL; default: assert_not_reached("Unknown option"); } @@ -265,49 +245,39 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { for (; optind < argc; optind++) { _cleanup_(udev_device_unrefp) struct udev_device *dev; - dev = find_device(udev, argv[optind], NULL); + dev = find_device(argv[optind], NULL); if (!dev) { log_error("unable to open the device '%s'", argv[optind]); - return 2; + return -EINVAL; } r = udev_enumerate_add_match_parent(udev_enumerate, dev); - if (r < 0) { - log_error_errno(r, "could not add tag match '%s': %m", optarg); - return 2; - } + if (r < 0) + return log_error_errno(r, "could not add tag match '%s': %m", optarg); } if (settle) { fd_ep = epoll_create1(EPOLL_CLOEXEC); - if (fd_ep < 0) { - log_error_errno(errno, "error creating epoll fd: %m"); - return 1; - } + if (fd_ep < 0) + return log_error_errno(errno, "error creating epoll fd: %m"); + + udev_monitor = udev_monitor_new_from_netlink(NULL, "udev"); + if (!udev_monitor) + return log_error_errno(errno, "error: unable to create netlink socket: %m"); - udev_monitor = udev_monitor_new_from_netlink(udev, "udev"); - if (!udev_monitor) { - log_error("error: unable to create netlink socket"); - return 3; - } fd_udev = udev_monitor_get_fd(udev_monitor); - if (udev_monitor_enable_receiving(udev_monitor) < 0) { - log_error("error: unable to subscribe to udev events"); - return 4; - } + r = udev_monitor_enable_receiving(udev_monitor); + if (r < 0) + return log_error_errno(r, "error: unable to subscribe to udev events: %m"); ep_udev = (struct epoll_event) { .events = EPOLLIN, .data.fd = fd_udev }; - if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) { - log_error_errno(errno, "fail to add fd to epoll: %m"); - return 5; - } + if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0) + return log_error_errno(errno, "fail to add fd to epoll: %m"); settle_set = set_new(&string_hash_ops); - if (!settle_set) { - log_oom(); - return 1; - } + if (!settle_set) + return log_oom(); } switch (device_type) { @@ -322,7 +292,7 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { } r = exec_list(udev_enumerate, action, settle_set); if (r < 0) - return 1; + return r; while (!set_isempty(settle_set)) { int fdcount; @@ -356,9 +326,3 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { return 0; } - -const struct udevadm_cmd udevadm_trigger = { - .name = "trigger", - .cmd = adm_trigger, - .help = "Request events from the kernel", -}; diff --git a/src/udev/udevadm-util.c b/src/udev/udevadm-util.c index ff5e5d7675..867a6d94c2 100644 --- a/src/udev/udevadm-util.c +++ b/src/udev/udevadm-util.c @@ -4,8 +4,7 @@ #include "string-util.h" #include "udevadm-util.h" -struct udev_device *find_device(struct udev *udev, - const char *id, +struct udev_device *find_device(const char *id, const char *prefix) { assert(id); @@ -27,9 +26,9 @@ struct udev_device *find_device(struct udev *udev, else return NULL; - return udev_device_new_from_devnum(udev, type, statbuf.st_rdev); + return udev_device_new_from_devnum(NULL, type, statbuf.st_rdev); } else if (path_startswith(id, "/sys/")) - return udev_device_new_from_syspath(udev, id); + return udev_device_new_from_syspath(NULL, id); else return NULL; } diff --git a/src/udev/udevadm-util.h b/src/udev/udevadm-util.h index f843e60c61..0cb0a5ca9f 100644 --- a/src/udev/udevadm-util.h +++ b/src/udev/udevadm-util.h @@ -3,10 +3,5 @@ #include "udev.h" -struct udev_device *find_device(struct udev *udev, - const char *id, +struct udev_device *find_device(const char *id, const char *prefix); - -static inline void print_version(void) { - printf("%s\n", PACKAGE_VERSION); -} diff --git a/src/udev/udevadm.c b/src/udev/udevadm.c index 2edeb105f8..7c6eb3bf4c 100644 --- a/src/udev/udevadm.c +++ b/src/udev/udevadm.c @@ -5,43 +5,26 @@ #include #include +#include "alloc-util.h" #include "selinux-util.h" #include "string-util.h" #include "terminal-util.h" +#include "udevadm.h" #include "udev-util.h" -#include "udev.h" +#include "verbs.h" +#include "util.h" -static int adm_version(struct udev *udev, int argc, char *argv[]) { - printf("%s\n", PACKAGE_VERSION); - return 0; -} +static int help(void) { + static const char * short_descriptions[][2] = { + { "info", "Query sysfs or the udev database" }, + { "trigger", "Request events from the kernel" }, + { "settle", "Wait for pending udev events" }, + { "control", "Control the udev daemon" }, + { "monitor", "Listen to kernel and udev events" }, + { "test", "Test an event run" }, + { "test-builtin", "Test a built-in command" }, + }; -static const struct udevadm_cmd udevadm_version = { - .name = "version", - .cmd = adm_version, -}; - -static int adm_help(struct udev *udev, int argc, char *argv[]); - -static const struct udevadm_cmd udevadm_help = { - .name = "help", - .cmd = adm_help, -}; - -static const struct udevadm_cmd *udevadm_cmds[] = { - &udevadm_info, - &udevadm_trigger, - &udevadm_settle, - &udevadm_control, - &udevadm_monitor, - &udevadm_hwdb, - &udevadm_test, - &udevadm_test_builtin, - &udevadm_version, - &udevadm_help, -}; - -static int adm_help(struct udev *udev, int argc, char *argv[]) { _cleanup_free_ char *link = NULL; size_t i; int r; @@ -55,42 +38,24 @@ static int adm_help(struct udev *udev, int argc, char *argv[]) { "Commands:\n" , program_invocation_short_name); - for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) - if (udevadm_cmds[i]->help != NULL) - printf(" %-12s %s\n", udevadm_cmds[i]->name, udevadm_cmds[i]->help); + for (i = 0; i < ELEMENTSOF(short_descriptions); i++) + printf(" %-12s %s\n", short_descriptions[i][0], short_descriptions[i][1]); printf("\nSee the %s for details.\n", link); return 0; } -static int run_command(struct udev *udev, const struct udevadm_cmd *cmd, int argc, char *argv[]) { - if (cmd->debug) - log_set_max_level(LOG_DEBUG); - log_debug("calling: %s", cmd->name); - return cmd->cmd(udev, argc, argv); -} - -int main(int argc, char *argv[]) { - struct udev *udev; +static int parse_argv(int argc, char *argv[]) { static const struct option options[] = { - { "debug", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, 'V' }, {} }; - const char *command; - unsigned int i; - int rc = 1, c; + int c; - udev_parse_config(); - log_parse_environment(); - log_open(); - - mac_selinux_init(); - - udev = udev_new(); - if (udev == NULL) - goto out; + assert(argc >= 0); + assert(argv); while ((c = getopt_long(argc, argv, "+dhV", options, NULL)) >= 0) switch (c) { @@ -100,35 +65,66 @@ int main(int argc, char *argv[]) { break; case 'h': - rc = adm_help(udev, argc, argv); - goto out; + return help(); case 'V': - rc = adm_version(udev, argc, argv); - goto out; + return version(); + + case '?': + return -EINVAL; default: - goto out; + assert_not_reached("Unhandled option"); } - command = argv[optind]; - - if (command != NULL) - for (i = 0; i < ELEMENTSOF(udevadm_cmds); i++) - if (streq(udevadm_cmds[i]->name, command)) { - argc -= optind; - argv += optind; - /* we need '0' here to reset the internal state */ - optind = 0; - rc = run_command(udev, udevadm_cmds[i], argc, argv); - goto out; - } - - fprintf(stderr, "%s: missing or unknown command\n", program_invocation_short_name); - rc = 2; -out: - mac_selinux_finish(); - udev_unref(udev); - log_close(); - return rc; + return 1; /* work to do */ +} + +static int version_main(int argc, char *argv[], void *userdata) { + return version(); +} + +static int help_main(int argc, char *argv[], void *userdata) { + return help(); +} + +static int udevadm_main(int argc, char *argv[]) { + static const Verb verbs[] = { + { "info", VERB_ANY, VERB_ANY, 0, info_main }, + { "trigger", VERB_ANY, VERB_ANY, 0, trigger_main }, + { "settle", VERB_ANY, VERB_ANY, 0, settle_main }, + { "control", VERB_ANY, VERB_ANY, 0, control_main }, + { "monitor", VERB_ANY, VERB_ANY, 0, monitor_main }, + { "hwdb", VERB_ANY, VERB_ANY, 0, hwdb_main }, + { "test", VERB_ANY, VERB_ANY, 0, test_main }, + { "test-builtin", VERB_ANY, VERB_ANY, 0, builtin_main }, + { "version", VERB_ANY, VERB_ANY, 0, version_main }, + { "help", VERB_ANY, VERB_ANY, 0, help_main }, + {} + }; + + return dispatch_verb(argc, argv, verbs, NULL); +} + +int main(int argc, char *argv[]) { + int r; + + udev_parse_config(); + log_parse_environment(); + log_open(); + mac_selinux_init(); + + r = parse_argv(argc, argv); + if (r <= 0) + goto finish; + + r = udevadm_main(argc, argv); + +finish: + mac_selinux_finish(); + log_close(); + + /* TODO: fix this later. + * Currently, verbs return positive values on failure. */ + return r < 0 ? EXIT_FAILURE : r; } diff --git a/src/udev/udevadm.h b/src/udev/udevadm.h new file mode 100644 index 0000000000..7c20e0a8ff --- /dev/null +++ b/src/udev/udevadm.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +#pragma once + +int info_main(int argc, char *argv[], void *userdata); +int trigger_main(int argc, char *argv[], void *userdata); +int settle_main(int argc, char *argv[], void *userdata); +int control_main(int argc, char *argv[], void *userdata); +int monitor_main(int argc, char *argv[], void *userdata); +int hwdb_main(int argc, char *argv[], void *userdata); +int test_main(int argc, char *argv[], void *userdata); +int builtin_main(int argc, char *argv[], void *userdata); diff --git a/src/udev/udevd.c b/src/udev/udevd.c index e4c15eaded..40aa9650af 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -63,7 +63,6 @@ static usec_t arg_event_timeout_usec = 180 * USEC_PER_SEC; static usec_t arg_event_timeout_warn_usec = 180 * USEC_PER_SEC / 3; typedef struct Manager { - struct udev *udev; sd_event *event; Hashmap *workers; LIST_HEAD(struct event, events); @@ -98,7 +97,6 @@ enum event_state { struct event { LIST_FIELDS(struct event, event); Manager *manager; - struct udev *udev; struct udev_device *dev; struct udev_device *dev_kernel; struct worker *worker; @@ -126,7 +124,6 @@ enum worker_state { struct worker { Manager *manager; - int refcount; pid_t pid; struct udev_monitor *monitor; enum worker_state state; @@ -204,7 +201,6 @@ static int worker_new(struct worker **ret, Manager *manager, struct udev_monitor if (!worker) return -ENOMEM; - worker->refcount = 1; worker->manager = manager; /* close monitor, but keep address around */ udev_monitor_disconnect(worker_monitor); @@ -278,13 +274,12 @@ static void manager_free(Manager *manager) { if (!manager) return; - udev_builtin_exit(manager->udev); + udev_builtin_exit(); sd_event_source_unref(manager->ctrl_event); sd_event_source_unref(manager->uevent_event); sd_event_source_unref(manager->inotify_event); - udev_unref(manager->udev); sd_event_unref(manager->event); manager_workers_free(manager); event_queue_cleanup(manager, EVENT_UNDEF); @@ -323,13 +318,12 @@ static bool shall_lock_device(struct udev_device *dev) { } static void worker_spawn(Manager *manager, struct event *event) { - struct udev *udev = event->udev; _cleanup_(udev_monitor_unrefp) struct udev_monitor *worker_monitor = NULL; pid_t pid; int r = 0; /* listen for new events */ - worker_monitor = udev_monitor_new_from_netlink(udev, NULL); + worker_monitor = udev_monitor_new_from_netlink(NULL, NULL); if (worker_monitor == NULL) return; /* allow the main daemon netlink address to send devices to the worker */ @@ -457,7 +451,7 @@ static void worker_spawn(Manager *manager, struct event *event) { /* apply/restore inotify watch */ if (udev_event->inotify_watch) { - udev_watch_begin(udev, dev); + udev_watch_begin(dev); udev_device_update_db(dev); } @@ -591,7 +585,6 @@ static int event_queue_insert(Manager *manager, struct udev_device *dev) { if (!event) return -ENOMEM; - event->udev = udev_device_get_udev(dev); event->manager = manager; event->dev = dev; event->dev_kernel = udev_device_shallow_clone(dev); @@ -762,7 +755,7 @@ static void manager_reload(Manager *manager) { manager_kill_workers(manager); manager->rules = udev_rules_unref(manager->rules); - udev_builtin_exit(manager->udev); + udev_builtin_exit(); sd_notifyf(false, "READY=1\n" @@ -784,16 +777,16 @@ static void event_queue_start(Manager *manager) { 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)) + udev_builtin_validate()) manager_reload(manager); manager->last_usec = usec; } - udev_builtin_init(manager->udev); + udev_builtin_init(); if (!manager->rules) { - manager->rules = udev_rules_new(manager->udev, arg_resolve_names); + manager->rules = udev_rules_new(arg_resolve_names); if (!manager->rules) return; } @@ -1014,7 +1007,6 @@ static int synthesize_change(struct udev_device *dev) { bool part_table_read = false; bool has_partitions = false; int fd; - struct udev *udev = udev_device_get_udev(dev); _cleanup_(udev_enumerate_unrefp) struct udev_enumerate *e = NULL; struct udev_list_entry *item; @@ -1036,7 +1028,7 @@ static int synthesize_change(struct udev_device *dev) { } /* search for partitions */ - e = udev_enumerate_new(udev); + e = udev_enumerate_new(NULL); if (!e) return -ENOMEM; @@ -1055,7 +1047,7 @@ static int synthesize_change(struct udev_device *dev) { udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) { _cleanup_(udev_device_unrefp) struct udev_device *d = NULL; - d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + d = udev_device_new_from_syspath(NULL, udev_list_entry_get_name(item)); if (!d) continue; @@ -1085,7 +1077,7 @@ static int synthesize_change(struct udev_device *dev) { udev_list_entry_foreach(item, udev_enumerate_get_list_entry(e)) { _cleanup_(udev_device_unrefp) struct udev_device *d = NULL; - d = udev_device_new_from_syspath(udev, udev_list_entry_get_name(item)); + d = udev_device_new_from_syspath(NULL, udev_list_entry_get_name(item)); if (!d) continue; @@ -1127,7 +1119,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda FOREACH_INOTIFY_EVENT(e, buffer, l) { _cleanup_(udev_device_unrefp) struct udev_device *dev = NULL; - dev = udev_watch_lookup(manager->udev, e->wd); + dev = udev_watch_lookup(e->wd); if (!dev) continue; @@ -1142,7 +1134,7 @@ static int on_inotify(sd_event_source *s, int fd, uint32_t revents, void *userda */ on_uevent(NULL, -1, 0, manager); } else if (e->mask & IN_IGNORED) - udev_watch_end(manager->udev, dev); + udev_watch_end(dev); } return 1; @@ -1252,7 +1244,6 @@ static int on_post(sd_event_source *s, void *userdata) { } static int listen_fds(int *rctrl, int *rnetlink) { - _cleanup_(udev_unrefp) struct udev *udev = NULL; int ctrl_fd = -1, netlink_fd = -1; int fd, n, r; @@ -1284,11 +1275,7 @@ static int listen_fds(int *rctrl, int *rnetlink) { if (ctrl_fd < 0) { _cleanup_(udev_ctrl_unrefp) struct udev_ctrl *ctrl = NULL; - udev = udev_new(); - if (!udev) - return -ENOMEM; - - ctrl = udev_ctrl_new(udev); + ctrl = udev_ctrl_new(); if (!ctrl) return log_error_errno(EINVAL, "error initializing udev control socket"); @@ -1308,13 +1295,7 @@ static int listen_fds(int *rctrl, int *rnetlink) { if (netlink_fd < 0) { _cleanup_(udev_monitor_unrefp) struct udev_monitor *monitor = NULL; - if (!udev) { - udev = udev_new(); - if (!udev) - return -ENOMEM; - } - - monitor = udev_monitor_new_from_netlink(udev, "kernel"); + monitor = udev_monitor_new_from_netlink(NULL, "kernel"); if (!monitor) return log_error_errno(EINVAL, "error initializing netlink socket"); @@ -1516,26 +1497,22 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg manager->worker_watch[WRITE_END] = -1; manager->worker_watch[READ_END] = -1; - manager->udev = udev_new(); - if (!manager->udev) - return log_error_errno(errno, "could not allocate udev context: %m"); + udev_builtin_init(); - udev_builtin_init(manager->udev); - - manager->rules = udev_rules_new(manager->udev, arg_resolve_names); + manager->rules = udev_rules_new(arg_resolve_names); if (!manager->rules) return log_error_errno(ENOMEM, "error reading rules"); LIST_HEAD_INIT(manager->events); - udev_list_init(manager->udev, &manager->properties, true); + udev_list_init(NULL, &manager->properties, true); manager->cgroup = cgroup; - manager->ctrl = udev_ctrl_new_from_fd(manager->udev, fd_ctrl); + manager->ctrl = udev_ctrl_new_from_fd(fd_ctrl); if (!manager->ctrl) return log_error_errno(EINVAL, "error taking over udev control socket"); - manager->monitor = udev_monitor_new_from_netlink_fd(manager->udev, "kernel", fd_uevent); + manager->monitor = udev_monitor_new_from_netlink_fd(NULL, "kernel", fd_uevent); if (!manager->monitor) return log_error_errno(EINVAL, "error taking over netlink socket"); @@ -1550,11 +1527,11 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg if (r < 0) return log_error_errno(errno, "could not enable SO_PASSCRED: %m"); - manager->fd_inotify = udev_watch_init(manager->udev); + manager->fd_inotify = udev_watch_init(); if (manager->fd_inotify < 0) return log_error_errno(ENOMEM, "error initializing inotify"); - udev_watch_restore(manager->udev); + udev_watch_restore(); /* block and listen to all signals on signalfd */ assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0);