diff mbox

xen-blkfront: export backend vdev name via sysfs

Message ID 20160609164322.11552-1-olaf@aepfle.de (mailing list archive)
State New, archived
Headers show

Commit Message

Olaf Hering June 9, 2016, 4:43 p.m. UTC
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"

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Olaf Hering <olaf@aepfle.de>
---
 drivers/block/xen-blkfront.c | 61 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

Comments

Olaf Hering June 9, 2016, 4:47 p.m. UTC | #1
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
David Vrabel June 9, 2016, 4:47 p.m. UTC | #2
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
Olaf Hering June 9, 2016, 4:58 p.m. UTC | #3
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 mbox

Patch

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 ? :