mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
virsh: Refactor str2DiskAddress
Rewrite and rename the address parser. As a fallout the use of the removed 'str2PCIAddress' is replaced by virshAddressParse and virshAddressFormat. Signed-off-by: Peter Krempa <pkrempa@redhat.com> Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
This commit is contained in:
parent
565d922b5b
commit
67bf91e1c3
@ -306,15 +306,26 @@ static const vshCmdOptDef opts_attach_disk[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum diskAddrType {
|
enum diskAddrType {
|
||||||
DISK_ADDR_TYPE_INVALID,
|
|
||||||
DISK_ADDR_TYPE_PCI,
|
DISK_ADDR_TYPE_PCI,
|
||||||
DISK_ADDR_TYPE_SCSI,
|
DISK_ADDR_TYPE_SCSI,
|
||||||
DISK_ADDR_TYPE_IDE,
|
DISK_ADDR_TYPE_IDE,
|
||||||
DISK_ADDR_TYPE_CCW,
|
DISK_ADDR_TYPE_CCW,
|
||||||
DISK_ADDR_TYPE_USB,
|
DISK_ADDR_TYPE_USB,
|
||||||
DISK_ADDR_TYPE_SATA,
|
DISK_ADDR_TYPE_SATA,
|
||||||
|
|
||||||
|
DISK_ADDR_TYPE_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
|
VIR_ENUM_DECL(diskAddr);
|
||||||
|
VIR_ENUM_IMPL(diskAddr,
|
||||||
|
DISK_ADDR_TYPE_LAST,
|
||||||
|
"pci",
|
||||||
|
"scsi",
|
||||||
|
"ide",
|
||||||
|
"ccw",
|
||||||
|
"usb",
|
||||||
|
"sata");
|
||||||
|
|
||||||
struct PCIAddress {
|
struct PCIAddress {
|
||||||
unsigned int domain;
|
unsigned int domain;
|
||||||
unsigned int bus;
|
unsigned int bus;
|
||||||
@ -350,105 +361,6 @@ struct DiskAddress {
|
|||||||
} addr;
|
} addr;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int str2PCIAddress(const char *str, struct PCIAddress *pciAddr)
|
|
||||||
{
|
|
||||||
char *domain, *bus, *slot, *function;
|
|
||||||
|
|
||||||
if (!pciAddr)
|
|
||||||
return -1;
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
domain = (char *)str;
|
|
||||||
|
|
||||||
if (virStrToLong_uip(domain, &bus, 16, &pciAddr->domain) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
bus++;
|
|
||||||
if (virStrToLong_uip(bus, &slot, 16, &pciAddr->bus) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
slot++;
|
|
||||||
if (virStrToLong_uip(slot, &function, 16, &pciAddr->slot) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
function++;
|
|
||||||
if (virStrToLong_uip(function, NULL, 16, &pciAddr->function) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int str2DriveAddress(const char *str, struct DriveAddress *scsiAddr)
|
|
||||||
{
|
|
||||||
char *controller, *bus, *unit;
|
|
||||||
|
|
||||||
if (!scsiAddr)
|
|
||||||
return -1;
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
controller = (char *)str;
|
|
||||||
|
|
||||||
if (virStrToLong_uip(controller, &bus, 10, &scsiAddr->controller) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
bus++;
|
|
||||||
if (virStrToLong_uip(bus, &unit, 10, &scsiAddr->bus) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
unit++;
|
|
||||||
if (virStrToLong_ullp(unit, NULL, 10, &scsiAddr->unit) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int str2CCWAddress(const char *str, struct CCWAddress *ccwAddr)
|
|
||||||
{
|
|
||||||
char *cssid, *ssid, *devno;
|
|
||||||
|
|
||||||
if (!ccwAddr)
|
|
||||||
return -1;
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cssid = (char *)str;
|
|
||||||
|
|
||||||
if (virStrToLong_uip(cssid, &ssid, 16, &ccwAddr->cssid) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ssid++;
|
|
||||||
if (virStrToLong_uip(ssid, &devno, 16, &ccwAddr->ssid) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
devno++;
|
|
||||||
if (virStrToLong_uip(devno, NULL, 16, &ccwAddr->devno) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int str2USBAddress(const char *str, struct USBAddress *usbAddr)
|
|
||||||
{
|
|
||||||
char *bus, *port;
|
|
||||||
|
|
||||||
if (!usbAddr)
|
|
||||||
return -1;
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
bus = (char *)str;
|
|
||||||
|
|
||||||
if (virStrToLong_uip(bus, &port, 10, &usbAddr->bus) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
port++;
|
|
||||||
if (virStrToLong_uip(port, NULL, 10, &usbAddr->port) != 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pci address pci:0000.00.0x0a.0 (domain:bus:slot:function)
|
/* pci address pci:0000.00.0x0a.0 (domain:bus:slot:function)
|
||||||
* ide disk address: ide:00.00.0 (controller:bus:unit)
|
* ide disk address: ide:00.00.0 (controller:bus:unit)
|
||||||
@ -457,43 +369,60 @@ static int str2USBAddress(const char *str, struct USBAddress *usbAddr)
|
|||||||
* usb disk address: usb:00.00 (bus:port)
|
* usb disk address: usb:00.00 (bus:port)
|
||||||
* sata disk address: sata:00.00.0 (controller:bus:unit)
|
* sata disk address: sata:00.00.0 (controller:bus:unit)
|
||||||
*/
|
*/
|
||||||
|
static int
|
||||||
static int str2DiskAddress(const char *str, struct DiskAddress *diskAddr, bool multifunction)
|
virshAddressParse(const char *str,
|
||||||
|
bool multifunction,
|
||||||
|
struct DiskAddress *addr)
|
||||||
{
|
{
|
||||||
char *type, *addr;
|
g_autofree char *type = g_strdup(str);
|
||||||
|
char *a = strchr(type, ':');
|
||||||
|
|
||||||
if (!diskAddr)
|
|
||||||
return -1;
|
|
||||||
if (!str)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
type = (char *)str;
|
|
||||||
addr = strchr(type, ':');
|
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (STREQLEN(type, "pci", addr - type)) {
|
*a = '\0';
|
||||||
diskAddr->type = DISK_ADDR_TYPE_PCI;
|
|
||||||
diskAddr->addr.pci.multifunction = multifunction;
|
addr->type = diskAddrTypeFromString(type);
|
||||||
return str2PCIAddress(addr + 1, &diskAddr->addr.pci);
|
|
||||||
} else if (STREQLEN(type, "scsi", addr - type)) {
|
switch ((enum diskAddrType) addr->type) {
|
||||||
diskAddr->type = DISK_ADDR_TYPE_SCSI;
|
case DISK_ADDR_TYPE_PCI:
|
||||||
return str2DriveAddress(addr + 1, &diskAddr->addr.drive);
|
addr->addr.pci.multifunction = multifunction;
|
||||||
} else if (STREQLEN(type, "ide", addr - type)) {
|
|
||||||
diskAddr->type = DISK_ADDR_TYPE_IDE;
|
if (virStrToLong_uip(++a, &a, 16, &addr->addr.pci.domain) < 0 ||
|
||||||
return str2DriveAddress(addr + 1, &diskAddr->addr.drive);
|
virStrToLong_uip(++a, &a, 16, &addr->addr.pci.bus) < 0 ||
|
||||||
} else if (STREQLEN(type, "ccw", addr - type)) {
|
virStrToLong_uip(++a, &a, 16, &addr->addr.pci.slot) < 0 ||
|
||||||
diskAddr->type = DISK_ADDR_TYPE_CCW;
|
virStrToLong_uip(++a, &a, 16, &addr->addr.pci.function) < 0)
|
||||||
return str2CCWAddress(addr + 1, &diskAddr->addr.ccw);
|
return -1;
|
||||||
} else if (STREQLEN(type, "usb", addr - type)) {
|
break;
|
||||||
diskAddr->type = DISK_ADDR_TYPE_USB;
|
|
||||||
return str2USBAddress(addr + 1, &diskAddr->addr.usb);
|
case DISK_ADDR_TYPE_SATA:
|
||||||
} else if (STREQLEN(type, "sata", addr - type)) {
|
case DISK_ADDR_TYPE_IDE:
|
||||||
diskAddr->type = DISK_ADDR_TYPE_SATA;
|
case DISK_ADDR_TYPE_SCSI:
|
||||||
return str2DriveAddress(addr + 1, &diskAddr->addr.drive);
|
if (virStrToLong_uip(++a, &a, 10, &addr->addr.drive.controller) < 0 ||
|
||||||
|
virStrToLong_uip(++a, &a, 10, &addr->addr.drive.bus) < 0 ||
|
||||||
|
virStrToLong_ullp(++a, &a, 10, &addr->addr.drive.unit) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISK_ADDR_TYPE_CCW:
|
||||||
|
if (virStrToLong_uip(++a, &a, 16, &addr->addr.ccw.cssid) < 0 ||
|
||||||
|
virStrToLong_uip(++a, &a, 16, &addr->addr.ccw.ssid) < 0 ||
|
||||||
|
virStrToLong_uip(++a, &a, 16, &addr->addr.ccw.devno) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISK_ADDR_TYPE_USB:
|
||||||
|
if (virStrToLong_uip(++a, &a, 10, &addr->addr.usb.bus) < 0 ||
|
||||||
|
virStrToLong_uip(++a, &a, 10, &addr->addr.usb.port) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DISK_ADDR_TYPE_LAST:
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -541,7 +470,7 @@ virshAddressFormat(virBufferPtr buf,
|
|||||||
addr->addr.usb.port);
|
addr->addr.usb.port);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DISK_ADDR_TYPE_INVALID:
|
case DISK_ADDR_TYPE_LAST:
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -557,7 +486,7 @@ cmdAttachDiskFormatAddress(vshControl *ctl,
|
|||||||
{
|
{
|
||||||
struct DiskAddress diskAddr;
|
struct DiskAddress diskAddr;
|
||||||
|
|
||||||
if (str2DiskAddress(straddr, &diskAddr, multifunction) != 0) {
|
if (virshAddressParse(straddr, multifunction, &diskAddr) < 0) {
|
||||||
vshError(ctl, _("Invalid address."));
|
vshError(ctl, _("Invalid address."));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -962,20 +891,18 @@ cmdAttachInterface(vshControl *ctl, const vshCmd *cmd)
|
|||||||
break;
|
break;
|
||||||
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
|
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
|
||||||
{
|
{
|
||||||
struct PCIAddress pciAddr = {0, 0, 0, 0, false};
|
g_autofree char *pciaddrstr = g_strdup_printf("pci:%s", source);
|
||||||
|
struct DiskAddress addr = { 0 };
|
||||||
|
|
||||||
if (str2PCIAddress(source, &pciAddr) < 0) {
|
if (virshAddressParse(pciaddrstr, false, &addr) < 0) {
|
||||||
vshError(ctl, _("cannot parse pci address '%s' for network "
|
vshError(ctl, _("cannot parse pci address '%s' for network interface"),
|
||||||
"interface"), source);
|
source);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
virBufferAddLit(&buf, "<source>\n");
|
virBufferAddLit(&buf, "<source>\n");
|
||||||
virBufferAdjustIndent(&buf, 2);
|
virBufferAdjustIndent(&buf, 2);
|
||||||
virBufferAsprintf(&buf, "<address type='pci' domain='0x%04x'"
|
virshAddressFormat(&buf, &addr);
|
||||||
" bus='0x%02x' slot='0x%02x' function='0x%d'/>\n",
|
|
||||||
pciAddr.domain, pciAddr.bus,
|
|
||||||
pciAddr.slot, pciAddr.function);
|
|
||||||
virBufferAdjustIndent(&buf, -2);
|
virBufferAdjustIndent(&buf, -2);
|
||||||
virBufferAddLit(&buf, "</source>\n");
|
virBufferAddLit(&buf, "</source>\n");
|
||||||
break;
|
break;
|
||||||
|
Loading…
Reference in New Issue
Block a user