Message ID | 20160609164322.11552-1-olaf@aepfle.de (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Thu, Jun 09, Olaf Hering wrote: > The value of "vdev" is cached to avoid the load caused by constant > rereading from the sysfs file. For some reason I sent an earlier variant of the patch without caching. If the approach is acceptable I will resend. Olaf
On 09/06/16 17:43, Olaf Hering wrote: > From: Jeff Mahoney <jeffm@suse.com> > > This patch creates a sysfs group to export blkfront attribute via sysfs. > For now, we just export the backend device name. > > This helps with migrating existing domU installation from a xenlinux > based kernel to a pvops based kernel. The old blkfront driver did > respect the vdev=hd|sd|xvd setting in domU.cfg, while the pvops blkfront > driver enforce xvd as kernel device name. > > If for some reason the domU uses kernel devices names in configuration > files like fstab, menu.lst, grub.cfg etc. the system may not startup > properly after upgrading from a dist version with xenlinux based kernel > to a newer one with pvops based kernel. With the new sysfs attribute > /sys/block/*/blkfront/backend_dev udev can create a symlink /dev/hda to > /dev/xvda using rules as shown below. > > The value of "vdev" is cached to avoid the load caused by constant > rereading from the sysfs file. > > This might be added to systemd/rules/60-persistent-storage.rules: > KERNEL=="xvd*[!0-9]", ATTRS{blkfront/backend_dev}=="hd[a-d]", SYMLINK+="$attr{blkfront/backend_dev}" > KERNEL=="xvd*[0-9]", ATTRS{blkfront/backend_dev}=="hd[a-d]", SYMLINK+="$attr{blkfront/backend_dev}%n" Why don't you get the udev rule to read the xenstore key directly instead? David
On Thu, Jun 09, David Vrabel wrote:
> Why don't you get the udev rule to read the xenstore key directly instead?
Good point. Something like this does indeed work:
c170:~ # cd -P /sys/block/xvda/device ; d=${PWD##*/} ; xenstore-read `xenstore-read device/${d/-/\/}/backend`/dev
hda
c170:/sys/devices/vbd-768 #
Olaf
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 6405b65..3c12644 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c @@ -1066,6 +1066,66 @@ static int xen_translate_vdev(int vdevice, int *minor, unsigned int *offset) return 0; } +/* xlvbd sysfs attributes */ +static ssize_t xlvbd_attr_show(struct device *dev, char *page, + ssize_t (*callback)(struct blkfront_info *, char *)) +{ + struct gendisk *disk = dev_to_disk(dev); + struct blkfront_info *lo = disk->private_data; + + return callback(lo, page); +} + +#define XLVBD_ATTR_RO(_name) \ +static ssize_t xlvbd_attr_##_name##_show(struct blkfront_info *, char *);\ +static ssize_t xlvbd_attr_do_show_##_name(struct device *d, \ + struct device_attribute *attr, char *b) \ +{ \ + return xlvbd_attr_show(d, b, xlvbd_attr_##_name##_show); \ +} \ +static struct device_attribute xlvbd_attr_##_name = \ + __ATTR(_name, S_IRUGO, xlvbd_attr_do_show_##_name, NULL); + + +static ssize_t xlvbd_attr_backend_dev_show(struct blkfront_info *info, + char *buf) +{ + const char *nodename = info->xbdev->nodename; + const char *backend; + const char *dev; + + backend = xenbus_read(XBT_NIL, nodename, "backend", NULL); + if (IS_ERR(backend)) + return PTR_ERR(backend); + + dev = xenbus_read(XBT_NIL, backend, "dev", NULL); + kfree(backend); + if (IS_ERR(dev)) + return PTR_ERR(dev); + + ret = snprintf(buf, PAGE_SIZE, "%s\n", dev); + + kfree(dev); + return ret; +} + +XLVBD_ATTR_RO(backend_dev); + +static struct attribute *xlvbd_attrs[] = { + &xlvbd_attr_backend_dev.attr, + NULL, +}; + +static const struct attribute_group xlvbd_attribute_group = { + .name = "blkfront", + .attrs = xlvbd_attrs, +}; + +static const struct attribute_group *xlvbd_attribute_groups[] = { + &xlvbd_attribute_group, + NULL, +}; + static char *encode_disk_name(char *ptr, unsigned int n) { if (n >= 26) @@ -1143,6 +1203,7 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity, gd->private_data = info; gd->driverfs_dev = &(info->xbdev->dev); set_capacity(gd, capacity); + disk_to_dev(gd)->groups = xlvbd_attribute_groups; if (xlvbd_init_blk_queue(gd, sector_size, physical_sector_size, info->max_indirect_segments ? :