Mercurial > illumos > illumos-gate
changeset 13642:8107b374f945
1844 xen: "disk_link: invalid disk device number"
Reviewed by: Dmitry.Yusupov@nexenta.com
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Garrett D'Amore <garrett@damore.org>
Approved by: Garrett D'Amore <garrett@damore.org>
author | Vitaliy Gusev <gusev.vitaliy@nexenta.com> |
---|---|
date | Tue, 20 Mar 2012 15:29:39 -0700 |
parents | 9efb7f317b8a |
children | 837d1b6404bf |
files | usr/src/cmd/devfsadm/disk_link.c |
diffstat | 1 files changed, 82 insertions(+), 30 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/cmd/devfsadm/disk_link.c Sat Mar 17 14:03:50 2012 -0500 +++ b/usr/src/cmd/devfsadm/disk_link.c Tue Mar 20 15:29:39 2012 -0700 @@ -19,6 +19,7 @@ * CDDL HEADER END */ /* + * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -319,51 +320,102 @@ /* * xVM virtual block device * - * VBDs are enumerated into xenstore by xend and named using - * the linux dev_t values for 'hd' and 'xvd' devices. Linux - * dev_t's are 16-bit values. The upper 8 bits identify the major # - * of the device (hd, xvd) and the lower 8 bits the instance and partition + * Xen passes device number in next format: * - * For PV guests, VBDs are named by the virt-tools using - * the form xvd[a-p][1-15]. The corresponding Solaris /dev/dsk name - * created by this generator will be c0t[0-15]d[0-15]sN, - * were the target (t) value represents [a-p] and the - * disk (d) value is either 0 (e.g. xvda) or contains the partition - * information if it has been specified [1-15] (e.g. xvda1) + * 1 << 28 | disk << 8 | partition xvd, disks or partitions 16 onwards + * 202 << 8 | disk << 4 | partition xvd, disks and partitions up to 15 + * 8 << 8 | disk << 4 | partition sd, disks and partitions up to 15 + * 3 << 8 | disk << 6 | partition hd, disks 0..1, partitions 0..63 + * 22 << 8 | (disk-2) << 6 | partition hd, disks 2..3, partitions 0..63 + * 2 << 28 onwards reserved for future use + * other values less than 1 << 28 deprecated / reserved + * + * The corresponding Solaris /dev/dsk name can be: + * + * c0tYdXsN + * + * where Y,X >= 0. * * For PV guests using the legacy naming (0, 1, 2, ...) * the Solaris disk names created will be c0d[0..767]sN - * The Solaris version of virt-install based on virtinst.101 - * named PV disks as sequential integers. With virtinst.300_1 and - * beyond, the virt-* tools will no longer create legacy disk - * names. + */ + +#define HD_BASE (3 << 8) +#define XEN_EXT_SHIFT (28) + +/* + * Return: Number of parsed and written parameters */ static int +decode_xen_device(uint_t device, uint_t *disk, uint_t *plun) +{ + uint_t dsk, lun = 0; + int ret = 1; + + if ((device >> XEN_EXT_SHIFT) > 1) + return (0); + + if (device < HD_BASE) { + /* legacy device address */ + dsk = device; + goto end; + } + + ret = 2; + if (device & (1 << XEN_EXT_SHIFT)) { + /* extended */ + dsk = device & (~0xff); + lun = device & 0xff; + goto end; + } + + switch (device >> 8) { + case 202: /* xvd */ + dsk = (device >> 4) & 0xf; + lun = device & 0xf; + break; + case 8: /* sd */ + dsk = device & (~0xf); + lun = device & 0xf; + break; + case 3: /* hd, disk 0..1 */ + dsk = device & (~0x3f); + lun = device & 0x3f; + break; + case 22: /* hd, disk 2..3 */ + dsk = device & (~0x3f); + lun = device & 0x3f; + break; + default: + return (0); + } +end: + *disk = dsk; + *plun = lun; + return (ret); +} + +static int disk_callback_xvmd(di_minor_t minor, di_node_t node) { -#define HD_BASE (3 << 8) -#define XVBDMAJ 202 - char *addr; char disk[16]; uint_t targ; - uint_t lun = 0; - uint_t fmaj; + uint_t dsk, lun; + int res; addr = di_bus_addr(node); targ = strtol(addr, (char **)NULL, 10); - fmaj = targ >> 8; + + res = decode_xen_device(targ, &dsk, &lun); + + /* HVM device names are generated using the standard generator */ - /* legacy device address */ - if (targ < HD_BASE) - (void) snprintf(disk, sizeof (disk), "d%d", targ); - /* PV VBD */ - else if (fmaj == XVBDMAJ) { - lun = targ & 0xf; - targ = (targ & 0xff) >> 4; - (void) snprintf(disk, sizeof (disk), "t%dd%d", targ, lun); - /* HVM device names are generated using the standard generator */ - } else { + if (res == 1) + (void) snprintf(disk, sizeof (disk), "d%d", dsk); + else if (res == 2) + (void) snprintf(disk, sizeof (disk), "t%dd%d", dsk, lun); + else { devfsadm_errprint("%s: invalid disk device number (%s)\n", modname, addr); return (DEVFSADM_CONTINUE);