Skip to content

Commit

Permalink
Fix recording of USB devices on recent kernels
Browse files Browse the repository at this point in the history
Pass device as major:minor instead of assuming that they are only 8 bit (which
is not true any more).
  • Loading branch information
martinpitt committed May 22, 2015
1 parent b6219cd commit 7165cd1
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 15 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
------------------
- umockdev-record: Ignore stderr from udevadm info, to avoid udev debug
message spew on stderr if udev debugging is enabled. (Debian #767909)
- Fix recording of USB devices on recent kernels: Pass device as major:minor
instead of assuming that they are only 8 bit (which is not true any more).

0.8.8 (2014-09-22)
------------------
Expand Down
41 changes: 32 additions & 9 deletions src/libumockdev-preload.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,30 @@ get_rdev(const char *nodename)
return makedev(major, minor);
}

static dev_t
parse_dev_t(const char *value, const char *source, int error)
{
unsigned long minor, major;
char *endptr;
major = strtoul(value, &endptr, 10);
if (endptr[0] != ':') {
if (error) {
fprintf(stderr, "umockdev: $%s (%s) contains no ':'\n", source, value);
abort();
} else
return (dev_t) -1;
}
minor = strtoul(endptr + 1, &endptr, 10);
if (endptr[0] != '\0') {
if (error) {
fprintf(stderr, "umockdev: %s (%s) has invalid minor\n", source, value);
abort();
} else
return (dev_t) -1;
}
return makedev(major, minor);
}

static int
is_emulated_device(const char *path, const mode_t st_mode)
{
Expand Down Expand Up @@ -393,9 +417,9 @@ ioctl_record_open(int fd)
if (record_rdev == (dev_t) - 1) {
const char *dev = getenv("UMOCKDEV_IOCTL_RECORD_DEV");

if (dev != NULL) {
record_rdev = (dev_t) atoi(dev);
} else {
if (dev != NULL)
record_rdev = parse_dev_t(dev, "$UMOCKDEV_IOCTL_RECORD_DEV", 1);
else {
/* not recording */
record_rdev = 0;
}
Expand Down Expand Up @@ -660,10 +684,10 @@ struct script_record_info {
static void
init_script_dev_logfile_map(void)
{
int i, dev;
int i;
dev_t dev;
char varname[100];
const char *devname, *logname, *format;
char *endptr;

script_dev_logfile_map_inited = 1;

Expand All @@ -684,10 +708,9 @@ init_script_dev_logfile_map(void)
fprintf(stderr, "umockdev: $%s not set\n", varname);
exit(1);
}
dev = strtol(devname, &endptr, 10);
if (dev != 0 && *endptr == '\0') {
/* if it's a number, then it is an rdev of a device */
/* ...and we should record its path */
dev = parse_dev_t(devname, NULL, 0);
if (dev != (dev_t) -1) {
/* if it's a dev_t, we should record its path */
const char *devpath;
snprintf(varname, sizeof(varname), "UMOCKDEV_SCRIPT_RECORD_DEVICE_PATH_%i", i);
devpath = getenv(varname);
Expand Down
8 changes: 2 additions & 6 deletions src/umockdev-record.vala
Original file line number Diff line number Diff line change
Expand Up @@ -297,21 +297,17 @@ split_devfile_arg(string arg, out string dev, out string devnum, out string fnam

if (Posix.S_ISCHR(st.st_mode) || Posix.S_ISBLK(st.st_mode)) {
// if we have a device node, get devnum from stat
devnum = ((Posix.major(st.st_rdev) << 8) + Posix.minor(st.st_rdev)).to_string();
devnum = Posix.major(st.st_rdev).to_string() + ":" + Posix.minor(st.st_rdev).to_string();
} else if (Posix.S_ISSOCK(st.st_mode)) {
// Unix sockets are passed by name
devnum = dev;
} else {
// otherwise we assume that we have a sysfs device, resolve via dev attribute
string contents;
try {
FileUtils.get_contents(Path.build_filename(dev, "dev"), out contents);
FileUtils.get_contents(Path.build_filename(dev, "dev"), out devnum);
} catch (Error e) {
exit_error("Cannot open %s/dev: %s", dev, e.message);
}
string[] fields = contents.strip().split(":");
assert(fields.length == 2);
devnum = ((int.parse(fields[0]) << 8) | int.parse(fields[1])).to_string();
}
}

Expand Down

0 comments on commit 7165cd1

Please sign in to comment.