Re: [PATCH v3] driver core: Fix device link device name collision

From: Saravana Kannan
Date: Sat Jan 09 2021 - 12:10:52 EST


On Sat, Jan 9, 2021 at 8:49 AM Michael Walle <michael@xxxxxxxx> wrote:
>
> Am 2021-01-08 18:22, schrieb Saravana Kannan:
> > On Fri, Jan 8, 2021 at 12:16 AM Michael Walle <michael@xxxxxxxx> wrote:
> >>
> >> Am 2021-01-08 02:24, schrieb Saravana Kannan:
> >> > The device link device's name was of the form:
> >> > <supplier-dev-name>--<consumer-dev-name>
> >> >
> >> > This can cause name collision as reported here [1] as device names are
> >> > not globally unique. Since device names have to be unique within the
> >> > bus/class, add the bus/class name as a prefix to the device names used
> >> > to
> >> > construct the device link device name.
> >> >
> >> > So the devuce link device's name will be of the form:
> >> > <supplier-bus-name>:<supplier-dev-name>--<consumer-bus-name>:<consumer-dev-name>
> >> >
> >> > [1] -
> >> > https://lore.kernel.org/lkml/20201229033440.32142-1-michael@xxxxxxxx/
> >> >
> >> > Cc: stable@xxxxxxxxxxxxxxx
> >> > Fixes: 287905e68dd2 ("driver core: Expose device link details in
> >> > sysfs")
> >> > Reported-by: Michael Walle <michael@xxxxxxxx>
> >> > Signed-off-by: Saravana Kannan <saravanak@xxxxxxxxxx>
> >> > ---
> >> [..]
> >>
> >> The changes are missing for the error path and
> >> devlink_remove_symlinks(),
> >> right?
> >
> > Removing symlinks doesn't need the name. Just needs the "handle". So
> > we are good there.
>
> I don't get it. What is the "handle"? Without the patch below
> kernfs_remove_by_name() in sysfs_remove_link will return -ENOENT. With
> the patch it will return 0.
>
> And even if it would work, how is this even logical:

Ah sorry, I confused it with removing device attrs. I need to fix up
the symlink remove path.

>
> snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con), dev_name(con));
> ret = sysfs_create_link(&sup->kobj, &link->link_dev.kobj, buf);
> if (ret)
> goto err_con_dev;
> snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup), dev_name(sup));
> ret = sysfs_create_link(&con->kobj, &link->link_dev.kobj, buf);
> if (ret)
> goto err_sup_dev;
> [..]
> err_sup_dev:
> snprintf(buf, len, "consumer:%s", dev_name(con));
> sysfs_remove_link(&sup->kobj, buf);
>
> You call sysfs_create_link("consumer:bus_name:dev_name") but the
> corresponding rollback is sysfs_remove_link("consumer:dev_name"), that
> is super confusing.
>
> >> diff --git a/drivers/base/core.c b/drivers/base/core.c
> >> index 4140a69dfe18..385e16d92874 100644
> >> --- a/drivers/base/core.c
> >> +++ b/drivers/base/core.c
> >> @@ -485,7 +485,7 @@ static int devlink_add_symlinks(struct device
> >> *dev,
> >> goto out;
> >>
> >> err_sup_dev:
> >> - snprintf(buf, len, "consumer:%s", dev_name(con));
> >> + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(con),
> >> dev_name(con));
> >> sysfs_remove_link(&sup->kobj, buf);
> >> err_con_dev:
> >> sysfs_remove_link(&link->link_dev.kobj, "consumer");
> >> @@ -508,7 +508,9 @@ static void devlink_remove_symlinks(struct device
> >> *dev,
> >> sysfs_remove_link(&link->link_dev.kobj, "consumer");
> >> sysfs_remove_link(&link->link_dev.kobj, "supplier");
> >>
> >> - len = max(strlen(dev_name(sup)), strlen(dev_name(con)));
> >> + len = max(strlen(dev_bus_name(sup)) + strlen(dev_name(sup)),
> >> + strlen(dev_bus_name(con)) + strlen(dev_name(con)));
> >> + len += strlen(":");
> >> len += strlen("supplier:") + 1;
> >> buf = kzalloc(len, GFP_KERNEL);
> >> if (!buf) {
> >> @@ -516,9 +518,9 @@ static void devlink_remove_symlinks(struct device
> >> *dev,
> >> return;
> >> }
> >>
> >> - snprintf(buf, len, "supplier:%s", dev_name(sup));
> >> + snprintf(buf, len, "supplier:%s:%s", dev_bus_name(sup),
> >> dev_name(sup));
> >> sysfs_remove_link(&con->kobj, buf);
> >> - snprintf(buf, len, "consumer:%s", dev_name(con));
> >> + snprintf(buf, len, "consumer:%s:%s", dev_bus_name(sup),
> >> dev_name(con));

Ah I completely skimmed over this code thinking it was code from my
patch. Like I said, I was struggling with the length of the email due
to the logs. Anyway, I'll fix up the remove symlink path too. Thanks
for catching that.

> btw this should be dev_bus_name(con).
>
> >> sysfs_remove_link(&sup->kobj, buf);
> >> kfree(buf);
> >> }
> >>
> >> With these changes:
> >>
> >> Tested-by: Michael Walle <michael@xxxxxxxx>
> >
> > Greg,
> >
> > I think it's good to pick up this version if you don't see any issues.
>
> Why so fast?

Sorry, didn't mean to rush. I was just trying to say I wasn't planning
on a v4 because I thought your Tested-by was for my unchanged v4, but
clearly I need to send a v4.

-Saravana