diff --git a/zdev/src/udev_ccwgroup.c b/zdev/src/udev_ccwgroup.c index c2f4bee4..465bd5b2 100644 --- a/zdev/src/udev_ccwgroup.c +++ b/zdev/src/udev_ccwgroup.c @@ -251,11 +251,12 @@ exit_code_t udev_ccwgroup_write_device(struct device *dev, bool autoconf) fprintf(fd, "# Generated by chzdev\n"); /* Triggers. */ - fprintf(fd, "ACTION==\"add\", SUBSYSTEM==\"drivers\", " + fprintf(fd, "ACTION!=\"add|change\", GOTO=\"%s\"\n", end_label); + fprintf(fd, "SUBSYSTEM==\"drivers\", " "KERNEL==\"%s\", GOTO=\"%s\"\n", drv, group_label); for (i = 0; i < devid.num; i++) { chan_id = ccw_devid_to_str(&devid.devid[i]); - fprintf(fd, "ACTION==\"add\", SUBSYSTEM==\"ccw\", " + fprintf(fd, "SUBSYSTEM==\"ccw\", " "KERNEL==\"%s\", DRIVER==\"%s\", " "GOTO=\"%s\"\n", chan_id, drv, group_label); free(chan_id); @@ -275,7 +276,19 @@ exit_code_t udev_ccwgroup_write_device(struct device *dev, bool autoconf) end_label); free(chan_id); } - fprintf(fd, "ATTR{[drivers/ccwgroup:%s]group}=\"", drv); + + /* Parallel execution of the ccwgroup devices udev rule can lead to + * udevadm warnings. To prevent this, serialize the execution. + */ + fprintf(fd, "\n# Note: Serialize add events on different devices to" + " change event on single\n# base device to prevent duplicate" + " concurrent grouping attempts\n"); + + /* The new change uevent should be generated to the base-device only */ + chan_id = ccw_devid_to_str(&devid.devid[0]); + fprintf(fd, "ACTION==\"add\", ATTR{[ccw/%s]uevent}=\"change\"\n", chan_id); + fprintf(fd, "ACTION==\"change\", ATTR{[drivers/ccwgroup:%s]group}=\"", drv); + free(chan_id); for (i = 0; i < devid.num; i++) { chan_id = ccw_devid_to_str(&devid.devid[i]); fprintf(fd, "%s%s", i > 0 ? "," : "", chan_id);