diff mbox series

scripts: add a script to list virtio devices in a system

Message ID 20210506193341.140141-1-lvivier@redhat.com (mailing list archive)
State New, archived
Headers show
Series scripts: add a script to list virtio devices in a system | expand

Commit Message

Laurent Vivier May 6, 2021, 7:33 p.m. UTC
Add "lsvirtio" that lists all virtio devices in a system
the same way lspci does for the PCI cards.

For instance:

 $ ./lsvirtio
 0000:01:00.0 virtio0 Red Hat, Inc. (PCI) Virtio Network Card
	 Subsystem: virtio
	 Modalias: virtio:d00000001v00001AF4
	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
	 Feature: CSUM
	 Feature: GUEST_CSUM
	 Feature: CTRL_GUEST_OFFLOADS
	 Feature: MAC
	 Feature: GUEST_TSO4
	 Feature: GUEST_TSO6
	 Feature: GUEST_ECN
	 Feature: GUEST_UFO
	 Feature: HOST_TSO4
	 Feature: HOST_TSO6
	 Feature: HOST_ECN
	 Feature: HOST_UFO
	 Feature: MRG_RXBUF
	 Feature: STATUS
	 Feature: CTRL_VQ
	 Feature: CTRL_RX
	 Feature: CTRL_VLAN
	 Feature: GUEST_ANNOUNCE
	 Feature: CTRL_MAC_ADDR
	 Feature: RING_INDIRECT_DESC
	 Feature: RING_EVENT_IDX
	 Feature: VERSION_1
	 Kernel driver in use: virtio_net
         Interfaces: enp1s0

 0000:03:00.0 virtio1 Red Hat, Inc. (PCI) Virtio Console
	 Subsystem: virtio
	 Modalias: virtio:d00000003v00001AF4
	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
	 Feature: MULTIPORT
	 Feature: RING_INDIRECT_DESC
	 Feature: RING_EVENT_IDX
	 Feature: VERSION_1
	 Kernel driver in use: virtio_console
         Interfaces: vport1p1
 ...

This is useful to have the list of virtio devices when they are not
mapped by a PCI card:

 $ ./lsvirtio
 virtio-mmio.121 virtio0 Virt (MMIO) Virtio 9P transport
	 Subsystem: virtio
	 Modalias: virtio:d00000009v554D4551
	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
	 Feature: MOUNT_TAG
	 Feature: RING_INDIRECT_DESC
	 Feature: RING_EVENT_IDX
	 Feature: VERSION_1
	 Kernel driver in use: 9pnet_virtio
         Interfaces: home0

 virtio-mmio.122 virtio1 Virt (MMIO) Virtio GPU Device
	 Subsystem: virtio
	 Modalias: virtio:d00000010v554D4551
	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
	 Feature: EDID
	 Feature: RING_INDIRECT_DESC
	 Feature: RING_EVENT_IDX
	 Feature: VERSION_1
	 Kernel driver in use: virtio_gpu
         Interfaces: fb0
 ...

Signed-off-by: Laurent Vivier <lvivier@redhat.com>
---
 scripts/lsvirtio | 317 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 317 insertions(+)
 create mode 100755 scripts/lsvirtio

Comments

Philippe Mathieu-Daudé May 6, 2021, 7:50 p.m. UTC | #1
On 5/6/21 9:33 PM, Laurent Vivier wrote:
> Add "lsvirtio" that lists all virtio devices in a system
> the same way lspci does for the PCI cards.
> 
> For instance:
> 
>  $ ./lsvirtio
>  0000:01:00.0 virtio0 Red Hat, Inc. (PCI) Virtio Network Card
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000001v00001AF4

"ModAlias" maybe?

> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> 	 Feature: CSUM
> 	 Feature: GUEST_CSUM
> 	 Feature: CTRL_GUEST_OFFLOADS
> 	 Feature: MAC
> 	 Feature: GUEST_TSO4
> 	 Feature: GUEST_TSO6
> 	 Feature: GUEST_ECN
> 	 Feature: GUEST_UFO
> 	 Feature: HOST_TSO4
> 	 Feature: HOST_TSO6
> 	 Feature: HOST_ECN
> 	 Feature: HOST_UFO
> 	 Feature: MRG_RXBUF
> 	 Feature: STATUS
> 	 Feature: CTRL_VQ
> 	 Feature: CTRL_RX
> 	 Feature: CTRL_VLAN
> 	 Feature: GUEST_ANNOUNCE
> 	 Feature: CTRL_MAC_ADDR
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_net
>          Interfaces: enp1s0
> 
>  0000:03:00.0 virtio1 Red Hat, Inc. (PCI) Virtio Console
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000003v00001AF4
> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> 	 Feature: MULTIPORT
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_console
>          Interfaces: vport1p1
>  ...
> 
> This is useful to have the list of virtio devices when they are not
> mapped by a PCI card:
> 
>  $ ./lsvirtio
>  virtio-mmio.121 virtio0 Virt (MMIO) Virtio 9P transport
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000009v554D4551
> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> 	 Feature: MOUNT_TAG
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: 9pnet_virtio
>          Interfaces: home0
> 
>  virtio-mmio.122 virtio1 Virt (MMIO) Virtio GPU Device
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000010v554D4551
> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> 	 Feature: EDID
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_gpu
>          Interfaces: fb0
>  ...
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  scripts/lsvirtio | 317 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 317 insertions(+)
>  create mode 100755 scripts/lsvirtio

Can you add an entry for the file in MAINTAINERS?

Otherwise:
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Laurent Vivier May 7, 2021, 6:17 a.m. UTC | #2
On 06/05/2021 21:50, Philippe Mathieu-Daudé wrote:
> On 5/6/21 9:33 PM, Laurent Vivier wrote:
>> Add "lsvirtio" that lists all virtio devices in a system
>> the same way lspci does for the PCI cards.
>>
>> For instance:
>>
>>  $ ./lsvirtio
>>  0000:01:00.0 virtio0 Red Hat, Inc. (PCI) Virtio Network Card
>> 	 Subsystem: virtio
>> 	 Modalias: virtio:d00000001v00001AF4
> 
> "ModAlias" maybe?
> 
>> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
>> 	 Feature: CSUM
>> 	 Feature: GUEST_CSUM
>> 	 Feature: CTRL_GUEST_OFFLOADS
>> 	 Feature: MAC
>> 	 Feature: GUEST_TSO4
>> 	 Feature: GUEST_TSO6
>> 	 Feature: GUEST_ECN
>> 	 Feature: GUEST_UFO
>> 	 Feature: HOST_TSO4
>> 	 Feature: HOST_TSO6
>> 	 Feature: HOST_ECN
>> 	 Feature: HOST_UFO
>> 	 Feature: MRG_RXBUF
>> 	 Feature: STATUS
>> 	 Feature: CTRL_VQ
>> 	 Feature: CTRL_RX
>> 	 Feature: CTRL_VLAN
>> 	 Feature: GUEST_ANNOUNCE
>> 	 Feature: CTRL_MAC_ADDR
>> 	 Feature: RING_INDIRECT_DESC
>> 	 Feature: RING_EVENT_IDX
>> 	 Feature: VERSION_1
>> 	 Kernel driver in use: virtio_net
>>          Interfaces: enp1s0
>>
>>  0000:03:00.0 virtio1 Red Hat, Inc. (PCI) Virtio Console
>> 	 Subsystem: virtio
>> 	 Modalias: virtio:d00000003v00001AF4
>> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
>> 	 Feature: MULTIPORT
>> 	 Feature: RING_INDIRECT_DESC
>> 	 Feature: RING_EVENT_IDX
>> 	 Feature: VERSION_1
>> 	 Kernel driver in use: virtio_console
>>          Interfaces: vport1p1
>>  ...
>>
>> This is useful to have the list of virtio devices when they are not
>> mapped by a PCI card:
>>
>>  $ ./lsvirtio
>>  virtio-mmio.121 virtio0 Virt (MMIO) Virtio 9P transport
>> 	 Subsystem: virtio
>> 	 Modalias: virtio:d00000009v554D4551
>> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
>> 	 Feature: MOUNT_TAG
>> 	 Feature: RING_INDIRECT_DESC
>> 	 Feature: RING_EVENT_IDX
>> 	 Feature: VERSION_1
>> 	 Kernel driver in use: 9pnet_virtio
>>          Interfaces: home0
>>
>>  virtio-mmio.122 virtio1 Virt (MMIO) Virtio GPU Device
>> 	 Subsystem: virtio
>> 	 Modalias: virtio:d00000010v554D4551
>> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
>> 	 Feature: EDID
>> 	 Feature: RING_INDIRECT_DESC
>> 	 Feature: RING_EVENT_IDX
>> 	 Feature: VERSION_1
>> 	 Kernel driver in use: virtio_gpu
>>          Interfaces: fb0
>>  ...
>>
>> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
>> ---
>>  scripts/lsvirtio | 317 +++++++++++++++++++++++++++++++++++++++++++++++
>>  1 file changed, 317 insertions(+)
>>  create mode 100755 scripts/lsvirtio
> 
> Can you add an entry for the file in MAINTAINERS?

Yes, but where?

It would go under virtio section, but I'm not sure Michael wants to maintain it.

Perhaps "Python scripts" section?

> Otherwise:
> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> 

Thanks,
Laurent
Michael S. Tsirkin May 11, 2021, 8:32 a.m. UTC | #3
On Thu, May 06, 2021 at 09:33:41PM +0200, Laurent Vivier wrote:
> Add "lsvirtio" that lists all virtio devices in a system
> the same way lspci does for the PCI cards.
> 
> For instance:
> 
>  $ ./lsvirtio
>  0000:01:00.0 virtio0 Red Hat, Inc. (PCI) Virtio Network Card
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000001v00001AF4
> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> 	 Feature: CSUM
> 	 Feature: GUEST_CSUM
> 	 Feature: CTRL_GUEST_OFFLOADS
> 	 Feature: MAC
> 	 Feature: GUEST_TSO4
> 	 Feature: GUEST_TSO6
> 	 Feature: GUEST_ECN
> 	 Feature: GUEST_UFO
> 	 Feature: HOST_TSO4
> 	 Feature: HOST_TSO6
> 	 Feature: HOST_ECN
> 	 Feature: HOST_UFO
> 	 Feature: MRG_RXBUF
> 	 Feature: STATUS
> 	 Feature: CTRL_VQ
> 	 Feature: CTRL_RX
> 	 Feature: CTRL_VLAN
> 	 Feature: GUEST_ANNOUNCE
> 	 Feature: CTRL_MAC_ADDR
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_net
>          Interfaces: enp1s0
> 
>  0000:03:00.0 virtio1 Red Hat, Inc. (PCI) Virtio Console
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000003v00001AF4
> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> 	 Feature: MULTIPORT
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_console
>          Interfaces: vport1p1
>  ...
> 
> This is useful to have the list of virtio devices when they are not
> mapped by a PCI card:
> 
>  $ ./lsvirtio
>  virtio-mmio.121 virtio0 Virt (MMIO) Virtio 9P transport
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000009v554D4551
> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> 	 Feature: MOUNT_TAG
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: 9pnet_virtio
>          Interfaces: home0
> 
>  virtio-mmio.122 virtio1 Virt (MMIO) Virtio GPU Device
> 	 Subsystem: virtio
> 	 Modalias: virtio:d00000010v554D4551
> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> 	 Feature: EDID
> 	 Feature: RING_INDIRECT_DESC
> 	 Feature: RING_EVENT_IDX
> 	 Feature: VERSION_1
> 	 Kernel driver in use: virtio_gpu
>          Interfaces: fb0
>  ...
> 
> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> ---
>  scripts/lsvirtio | 317 +++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 317 insertions(+)
>  create mode 100755 scripts/lsvirtio
> 
> diff --git a/scripts/lsvirtio b/scripts/lsvirtio
> new file mode 100755
> index 000000000000..f457d5b7344d
> --- /dev/null
> +++ b/scripts/lsvirtio
> @@ -0,0 +1,317 @@
> +#!/usr/bin/env python3
> +#
> +# Copyright (C) 2021 Red Hat, Inc.
> +#
> +# SPDX-License-Identifier: GPL-2.0-or-later
> +
> +import os
> +
> +# Virtual I/O Device (VIRTIO) Version 1.1
> +
> +# 2.1 Device Status Field
> +status_name = {
> +    ( 1, 'ACKNOWLEDGE' ),
> +    ( 2, 'DRIVER') ,
> +    ( 4, 'DRIVER_OK' ),
> +    ( 8, 'FEATURES_OK' ),
> +    ( 64, 'DEVICE_NEEDS_RESET' ),
> +    ( 128, 'FAILED' )
> +}
> +
> +# 5 Device Types
> +device_name = {
> +    1:'Network Card',
> +    2:'Block Device',
> +    3:'Console',
> +    4:'Entropy Source',
> +    5:'Memory Ballooning (traditional)',
> +    6:'ioMemory',
> +    7:'rpmsg',
> +    8:'SCSI host',
> +    9:'9P transport',
> +    10:'MAC80211 WLAN',
> +    11:'rproc serial',
> +    12:'CAIF',
> +    13:'Memory Balloon',
> +    16:'GPU Device',
> +    17:'Timer/Clock Device',
> +    18:'Input Device',
> +    19:'Socket Device',
> +    20:'Crypto Device',
> +    21:'Signal Distribution Module',
> +    22:'pstore Device',
> +    23:'IOMMU Device',
> +    24:'Memory Device',
> +# From linux headers
> +    26:'Filesystem',
> +    27:'pmem',
> +    29:'mac80211-hwsim',
> +}
> +
> +# 5.1 Network Device
> +# 5.1.3 Feature bits
> +net_feature_name = {
> +    0:'CSUM',
> +    1:'GUEST_CSUM',
> +    2:'CTRL_GUEST_OFFLOADS',
> +    3:'MTU',
> +    5:'MAC',
> +    6:'GSO',
> +    7:'GUEST_TSO4',
> +    8:'GUEST_TSO6',
> +    9:'GUEST_ECN',
> +    10:'GUEST_UFO',
> +    11:'HOST_TSO4',
> +    12:'HOST_TSO6',
> +    13:'HOST_ECN',
> +    14:'HOST_UFO',
> +    15:'MRG_RXBUF',
> +    16:'STATUS',
> +    17:'CTRL_VQ',
> +    18:'CTRL_RX',
> +    19:'CTRL_VLAN',
> +    21:'GUEST_ANNOUNCE',
> +    22:'MQ',
> +    23:'CTRL_MAC_ADDR',
> +    41:'GUEST_RSC4',
> +    42:'GUEST_RSC6',
> +    61:'RSC_EXT',
> +    62:'STANDBY',
> +}
> +
> +def get_feature_net(feature):
> +    return net_feature_name[feature]
> +
> +# 5.2 Block Device
> +# 5.2.3 Feature bits
> +block_feature_name = {
> +    0:'BARRIER',
> +    1:'SIZE_MAX',
> +    2:'SEG_MAX',
> +    4:'GEOMETRY',
> +    5:'RO',
> +    6:'BLK_SIZE',
> +    7:'SCSI',
> +    9:'FLUSH',
> +    10:'TOPOLOGY',
> +    11:'CONFIG_WCE',
> +    13:'DISCARD',
> +    14:'WRITE_ZEROES',
> +}
> +
> +def get_feature_block(feature):
> +    return block_feature_name[feature]
> +
> +# 5.3 Console Device
> +# 5.3.3 Feature bits
> +console_feature_name = {
> +    0:'SIZE',
> +    1:'MULTIPORT',
> +    2:'EMERG_WRITE',
> +}
> +
> +def get_feature_console(feature):
> +    return console_feature_name[feature]
> +
> +# 5.4 Entropy Device
> +# 5.4.3 Feature bits
> +# No feature bits
> +
> +# 5.5 Traditional Memory Balloon Device
> +# 5.5.3 Feature bits
> +balloon_traditional_feature_name = {
> +    0:'MUST_TELL_HOST',
> +    1:'STATS_VQ',
> +    2:'DEFLATE_ON_OOM',
> +# from linux headers
> +    3:'FREE_PAGE_HINT',
> +    4:'PAGE_POISON',
> +    5:'REPORTING',
> +}
> +
> +def get_feature_balloon_traditional(feature):
> +    return balloon_traditional_feature_name[feature]
> +
> +# 5.6 SCSI Host Device
> +# 5.6.3 Feature bits
> +scsi_feature_name = {
> +    0:'INOUT',
> +    1:'HOTPLUG',
> +    2:'CHANGE',
> +    3:'T10_PI',
> +}
> +
> +def get_feature_scsi_host(feature):
> +    return scsi_feature_name[feature]
> +
> +# 5.7 GPU Device
> +# 5.7.3 Feature bits
> +gpu_feature_name = {
> +    0:'VIRGL',
> +    1:'EDID',
> +}
> +
> +def get_feature_gpu(feature):
> +    return gpu_feature_name[feature]
> +
> +# 5.8 Input Device
> +# 5.8.3 Feature bits
> +# No feature bits
> +
> +# 5.9 Crypto Device
> +# 5.9.3 Feature bits
> +crypto_feature_name = {
> +    0:'REVISION_1',
> +    1:'CIPHER_STATELESS_MODE',
> +    2:'HASH_STATELESS_MODE',
> +    3:'MAC_STATELESS_MODE',
> +    4:'AEAD_STATELESS_MODE',
> +}
> +
> +def get_feature_crypto(feature):
> +    return crypto_feature_name[feature]
> +
> +# 5.10 Socket Device
> +# 5.10.3 Feature bits
> +# No feature bits
> +
> +# following feature bits from linux headers
> +# 9P
> +ninep_feature_name = {
> +    0:'MOUNT_TAG',
> +}
> +
> +def get_feature_9p(feature):
> +    return ninep_feature_name[feature]
> +
> +# IOMMU
> +iommu_feature_name = {
> +    0:'INPUT_RANGE',
> +    1:'DOMAIN_RANGE',
> +    2:'MAP_UNMAP',
> +    3:'BYPASS',
> +    4:'PROBE',
> +    5:'MMIO',
> +}
> +
> +def get_feature_iommu(feature):
> +    return iommu_feature_name[feature]
> +
> +# MEM
> +
> +mem_feature_name = {
> +    0:'ACPI_PXM',
> +}
> +
> +def get_feature_memory(feature):
> +    return mem_feature_name[feature]
> +
> +get_feature = {
> +    1:get_feature_net,
> +    2:get_feature_block,
> +    3:get_feature_console,
> +    5:get_feature_balloon_traditional,
> +    8:get_feature_scsi_host,
> +    9:get_feature_9p,
> +    16:get_feature_gpu,
> +    20:get_feature_crypto,
> +    23:get_feature_iommu,
> +    24:get_feature_memory,
> +}
> +
> +# 6 Reserved Feature Bits
> +reserved_feature_name = {
> +    24:'NOTIFY_ON_EMPTY',
> +    27:'ANY_LAYOUT',
> +    28:'RING_INDIRECT_DESC',
> +    29:'RING_EVENT_IDX',
> +    30:'BAD_FEATURE',
> +    32:'VERSION_1',
> +    33:'ACCESS_PLATFORM',
> +    34:'RING_PACKED',
> +    35:'IN_ORDER',
> +    36:'ORDER_PLATFORM',
> +    37:'SR_IOV',
> +    38:'NOTIFICATION_DATA'
> +}


I worry about maintaining all these feature bits though.

Can we somehow script this in scripts/update-linux-headers.sh ?


> +
> +vendor_name = {
> +    0x554D4551:'Virt (MMIO)',
> +    0x1AF4:'Red Hat, Inc. (PCI)',
> +}
> +
> +def get_status_name(status):
> +    result = ''
> +    for name in status_name:
> +        if name[0] & status:
> +            result = result + name[1] + ' '
> +    return result
> +
> +def list_interfaces(path):
> +    interfaces = ''
> +    for interface in sorted(os.listdir(path)):
> +        interfaces = interfaces + interface + ' '
> +    return interfaces
> +
> +def get_net_interfaces(path):
> +    return list_interfaces(path + '/net')
> +
> +def get_block_interfaces(path):
> +    return list_interfaces(path + '/block')
> +
> +def get_console_interfaces(path):
> +    return list_interfaces(path + '/block')
> +
> +def get_9p_interfaces(path):
> +    return open(path + '/mount_tag').read().rstrip()
> +
> +def get_gpu_interfaces(path):
> +    return list_interfaces(path + '/graphics')
> +
> +def get_input_interaces(path):
> +    return list_interfaces(path + '/input')
> +
> +get_interfaces = {
> +    1:get_net_interfaces,
> +    2:get_block_interfaces,
> +    3:get_console_interfaces,
> +    9:get_9p_interfaces,
> +    16:get_gpu_interfaces,
> +    18:get_input_interaces,
> +}
> +
> +busses = '/sys/bus/virtio'
> +devices = busses + '/devices'
> +
> +for device in sorted(os.listdir(devices)):
> +    bus = os.path.basename(os.path.dirname(os.readlink(devices + '/' + device)))
> +    path = devices + '/' + device
> +    subsystem = os.path.basename(os.readlink(path + '/subsystem'))
> +    device_id = int(open(path + '/device').read(), base = 0)
> +    vendor = int(open(path + '/vendor').read(), base = 0)
> +    driver = os.path.basename(os.readlink(path + '/driver'))
> +    modalias = open(path + '/modalias').read().rstrip()
> +    features = open(path + '/features').read().rstrip()
> +    status = open(path + '/status').read().rstrip()
> +
> +    print(bus + ' ' + device + ' ' + vendor_name[vendor] + ' Virtio ' + device_name[device_id])
> +    print('\tSubsystem: ' + subsystem)
> +    print('\tModalias: ' + modalias)
> +    print('\tStatus: ' + get_status_name(int(status, base=0)))
> +    bit=0
> +    for feature in features:
> +        if feature == '1':
> +            try:
> +                if bit >= 24:
> +                    print('\tFeature: ' + reserved_feature_name[bit])
> +                else:
> +                    print('\tFeature: ' + get_feature[device_id](bit))
> +            except:
> +                print('\tFeature: ' + str(bit))
> +        bit += 1
> +    print('\tKernel driver in use: ' + driver)
> +    try:
> +        print('\tInterfaces: ' + get_interfaces[device_id](path))
> +    except:
> +        print('\tNo interface')
> +    print('')
> -- 
> 2.31.1
> 
>
Michael S. Tsirkin May 11, 2021, 8:33 a.m. UTC | #4
On Fri, May 07, 2021 at 08:17:33AM +0200, Laurent Vivier wrote:
> On 06/05/2021 21:50, Philippe Mathieu-Daudé wrote:
> > On 5/6/21 9:33 PM, Laurent Vivier wrote:
> >> Add "lsvirtio" that lists all virtio devices in a system
> >> the same way lspci does for the PCI cards.
> >>
> >> For instance:
> >>
> >>  $ ./lsvirtio
> >>  0000:01:00.0 virtio0 Red Hat, Inc. (PCI) Virtio Network Card
> >> 	 Subsystem: virtio
> >> 	 Modalias: virtio:d00000001v00001AF4
> > 
> > "ModAlias" maybe?
> > 
> >> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> >> 	 Feature: CSUM
> >> 	 Feature: GUEST_CSUM
> >> 	 Feature: CTRL_GUEST_OFFLOADS
> >> 	 Feature: MAC
> >> 	 Feature: GUEST_TSO4
> >> 	 Feature: GUEST_TSO6
> >> 	 Feature: GUEST_ECN
> >> 	 Feature: GUEST_UFO
> >> 	 Feature: HOST_TSO4
> >> 	 Feature: HOST_TSO6
> >> 	 Feature: HOST_ECN
> >> 	 Feature: HOST_UFO
> >> 	 Feature: MRG_RXBUF
> >> 	 Feature: STATUS
> >> 	 Feature: CTRL_VQ
> >> 	 Feature: CTRL_RX
> >> 	 Feature: CTRL_VLAN
> >> 	 Feature: GUEST_ANNOUNCE
> >> 	 Feature: CTRL_MAC_ADDR
> >> 	 Feature: RING_INDIRECT_DESC
> >> 	 Feature: RING_EVENT_IDX
> >> 	 Feature: VERSION_1
> >> 	 Kernel driver in use: virtio_net
> >>          Interfaces: enp1s0
> >>
> >>  0000:03:00.0 virtio1 Red Hat, Inc. (PCI) Virtio Console
> >> 	 Subsystem: virtio
> >> 	 Modalias: virtio:d00000003v00001AF4
> >> 	 Status: ACKNOWLEDGE DRIVER_OK DRIVER FEATURES_OK
> >> 	 Feature: MULTIPORT
> >> 	 Feature: RING_INDIRECT_DESC
> >> 	 Feature: RING_EVENT_IDX
> >> 	 Feature: VERSION_1
> >> 	 Kernel driver in use: virtio_console
> >>          Interfaces: vport1p1
> >>  ...
> >>
> >> This is useful to have the list of virtio devices when they are not
> >> mapped by a PCI card:
> >>
> >>  $ ./lsvirtio
> >>  virtio-mmio.121 virtio0 Virt (MMIO) Virtio 9P transport
> >> 	 Subsystem: virtio
> >> 	 Modalias: virtio:d00000009v554D4551
> >> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> >> 	 Feature: MOUNT_TAG
> >> 	 Feature: RING_INDIRECT_DESC
> >> 	 Feature: RING_EVENT_IDX
> >> 	 Feature: VERSION_1
> >> 	 Kernel driver in use: 9pnet_virtio
> >>          Interfaces: home0
> >>
> >>  virtio-mmio.122 virtio1 Virt (MMIO) Virtio GPU Device
> >> 	 Subsystem: virtio
> >> 	 Modalias: virtio:d00000010v554D4551
> >> 	 Status: FEATURES_OK ACKNOWLEDGE DRIVER DRIVER_OK
> >> 	 Feature: EDID
> >> 	 Feature: RING_INDIRECT_DESC
> >> 	 Feature: RING_EVENT_IDX
> >> 	 Feature: VERSION_1
> >> 	 Kernel driver in use: virtio_gpu
> >>          Interfaces: fb0
> >>  ...
> >>
> >> Signed-off-by: Laurent Vivier <lvivier@redhat.com>
> >> ---
> >>  scripts/lsvirtio | 317 +++++++++++++++++++++++++++++++++++++++++++++++
> >>  1 file changed, 317 insertions(+)
> >>  create mode 100755 scripts/lsvirtio
> > 
> > Can you add an entry for the file in MAINTAINERS?
> 
> Yes, but where?
> 
> It would go under virtio section, but I'm not sure Michael wants to maintain it.

I don't have a problem with getting patches for it.

> Perhaps "Python scripts" section?
> 
> > Otherwise:
> > Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
> > 
> 
> Thanks,
> Laurent
Peter Maydell May 11, 2021, 9:17 a.m. UTC | #5
On Thu, 6 May 2021 at 20:36, Laurent Vivier <lvivier@redhat.com> wrote:
>
> Add "lsvirtio" that lists all virtio devices in a system
> the same way lspci does for the PCI cards.

This is cool, but it's not really QEMU specific -- it should
work on any Linux guest running on some hypervisor or hardware
that exposes virtio devices, right? So I'm not sure it really
belongs in QEMU's source tree...

If you're a distro packager you'd probably want to have this be in its
own package or at least not in the same package as the QEMU binaries,
for instance, because this lives in the guest, not the host.

thanks
-- PMM
Laurent Vivier May 12, 2021, 7:44 a.m. UTC | #6
On 11/05/2021 11:17, Peter Maydell wrote:
> On Thu, 6 May 2021 at 20:36, Laurent Vivier <lvivier@redhat.com> wrote:
>>
>> Add "lsvirtio" that lists all virtio devices in a system
>> the same way lspci does for the PCI cards.
> 
> This is cool, but it's not really QEMU specific -- it should
> work on any Linux guest running on some hypervisor or hardware
> that exposes virtio devices, right? So I'm not sure it really
> belongs in QEMU's source tree...
> 
> If you're a distro packager you'd probably want to have this be in its
> own package or at least not in the same package as the QEMU binaries,
> for instance, because this lives in the guest, not the host.
> 

Yes, I agree with that, but if it is in its own package I think it will never reach user
because no one will find it. I can try to push this into util-linux where we can find
tools like lscpu, lsblk ... but the competencies to review the code are in qemu-devel ML
not in util-linux ML.

Thanks,
Laurent
diff mbox series

Patch

diff --git a/scripts/lsvirtio b/scripts/lsvirtio
new file mode 100755
index 000000000000..f457d5b7344d
--- /dev/null
+++ b/scripts/lsvirtio
@@ -0,0 +1,317 @@ 
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 Red Hat, Inc.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+# Virtual I/O Device (VIRTIO) Version 1.1
+
+# 2.1 Device Status Field
+status_name = {
+    ( 1, 'ACKNOWLEDGE' ),
+    ( 2, 'DRIVER') ,
+    ( 4, 'DRIVER_OK' ),
+    ( 8, 'FEATURES_OK' ),
+    ( 64, 'DEVICE_NEEDS_RESET' ),
+    ( 128, 'FAILED' )
+}
+
+# 5 Device Types
+device_name = {
+    1:'Network Card',
+    2:'Block Device',
+    3:'Console',
+    4:'Entropy Source',
+    5:'Memory Ballooning (traditional)',
+    6:'ioMemory',
+    7:'rpmsg',
+    8:'SCSI host',
+    9:'9P transport',
+    10:'MAC80211 WLAN',
+    11:'rproc serial',
+    12:'CAIF',
+    13:'Memory Balloon',
+    16:'GPU Device',
+    17:'Timer/Clock Device',
+    18:'Input Device',
+    19:'Socket Device',
+    20:'Crypto Device',
+    21:'Signal Distribution Module',
+    22:'pstore Device',
+    23:'IOMMU Device',
+    24:'Memory Device',
+# From linux headers
+    26:'Filesystem',
+    27:'pmem',
+    29:'mac80211-hwsim',
+}
+
+# 5.1 Network Device
+# 5.1.3 Feature bits
+net_feature_name = {
+    0:'CSUM',
+    1:'GUEST_CSUM',
+    2:'CTRL_GUEST_OFFLOADS',
+    3:'MTU',
+    5:'MAC',
+    6:'GSO',
+    7:'GUEST_TSO4',
+    8:'GUEST_TSO6',
+    9:'GUEST_ECN',
+    10:'GUEST_UFO',
+    11:'HOST_TSO4',
+    12:'HOST_TSO6',
+    13:'HOST_ECN',
+    14:'HOST_UFO',
+    15:'MRG_RXBUF',
+    16:'STATUS',
+    17:'CTRL_VQ',
+    18:'CTRL_RX',
+    19:'CTRL_VLAN',
+    21:'GUEST_ANNOUNCE',
+    22:'MQ',
+    23:'CTRL_MAC_ADDR',
+    41:'GUEST_RSC4',
+    42:'GUEST_RSC6',
+    61:'RSC_EXT',
+    62:'STANDBY',
+}
+
+def get_feature_net(feature):
+    return net_feature_name[feature]
+
+# 5.2 Block Device
+# 5.2.3 Feature bits
+block_feature_name = {
+    0:'BARRIER',
+    1:'SIZE_MAX',
+    2:'SEG_MAX',
+    4:'GEOMETRY',
+    5:'RO',
+    6:'BLK_SIZE',
+    7:'SCSI',
+    9:'FLUSH',
+    10:'TOPOLOGY',
+    11:'CONFIG_WCE',
+    13:'DISCARD',
+    14:'WRITE_ZEROES',
+}
+
+def get_feature_block(feature):
+    return block_feature_name[feature]
+
+# 5.3 Console Device
+# 5.3.3 Feature bits
+console_feature_name = {
+    0:'SIZE',
+    1:'MULTIPORT',
+    2:'EMERG_WRITE',
+}
+
+def get_feature_console(feature):
+    return console_feature_name[feature]
+
+# 5.4 Entropy Device
+# 5.4.3 Feature bits
+# No feature bits
+
+# 5.5 Traditional Memory Balloon Device
+# 5.5.3 Feature bits
+balloon_traditional_feature_name = {
+    0:'MUST_TELL_HOST',
+    1:'STATS_VQ',
+    2:'DEFLATE_ON_OOM',
+# from linux headers
+    3:'FREE_PAGE_HINT',
+    4:'PAGE_POISON',
+    5:'REPORTING',
+}
+
+def get_feature_balloon_traditional(feature):
+    return balloon_traditional_feature_name[feature]
+
+# 5.6 SCSI Host Device
+# 5.6.3 Feature bits
+scsi_feature_name = {
+    0:'INOUT',
+    1:'HOTPLUG',
+    2:'CHANGE',
+    3:'T10_PI',
+}
+
+def get_feature_scsi_host(feature):
+    return scsi_feature_name[feature]
+
+# 5.7 GPU Device
+# 5.7.3 Feature bits
+gpu_feature_name = {
+    0:'VIRGL',
+    1:'EDID',
+}
+
+def get_feature_gpu(feature):
+    return gpu_feature_name[feature]
+
+# 5.8 Input Device
+# 5.8.3 Feature bits
+# No feature bits
+
+# 5.9 Crypto Device
+# 5.9.3 Feature bits
+crypto_feature_name = {
+    0:'REVISION_1',
+    1:'CIPHER_STATELESS_MODE',
+    2:'HASH_STATELESS_MODE',
+    3:'MAC_STATELESS_MODE',
+    4:'AEAD_STATELESS_MODE',
+}
+
+def get_feature_crypto(feature):
+    return crypto_feature_name[feature]
+
+# 5.10 Socket Device
+# 5.10.3 Feature bits
+# No feature bits
+
+# following feature bits from linux headers
+# 9P
+ninep_feature_name = {
+    0:'MOUNT_TAG',
+}
+
+def get_feature_9p(feature):
+    return ninep_feature_name[feature]
+
+# IOMMU
+iommu_feature_name = {
+    0:'INPUT_RANGE',
+    1:'DOMAIN_RANGE',
+    2:'MAP_UNMAP',
+    3:'BYPASS',
+    4:'PROBE',
+    5:'MMIO',
+}
+
+def get_feature_iommu(feature):
+    return iommu_feature_name[feature]
+
+# MEM
+
+mem_feature_name = {
+    0:'ACPI_PXM',
+}
+
+def get_feature_memory(feature):
+    return mem_feature_name[feature]
+
+get_feature = {
+    1:get_feature_net,
+    2:get_feature_block,
+    3:get_feature_console,
+    5:get_feature_balloon_traditional,
+    8:get_feature_scsi_host,
+    9:get_feature_9p,
+    16:get_feature_gpu,
+    20:get_feature_crypto,
+    23:get_feature_iommu,
+    24:get_feature_memory,
+}
+
+# 6 Reserved Feature Bits
+reserved_feature_name = {
+    24:'NOTIFY_ON_EMPTY',
+    27:'ANY_LAYOUT',
+    28:'RING_INDIRECT_DESC',
+    29:'RING_EVENT_IDX',
+    30:'BAD_FEATURE',
+    32:'VERSION_1',
+    33:'ACCESS_PLATFORM',
+    34:'RING_PACKED',
+    35:'IN_ORDER',
+    36:'ORDER_PLATFORM',
+    37:'SR_IOV',
+    38:'NOTIFICATION_DATA'
+}
+
+vendor_name = {
+    0x554D4551:'Virt (MMIO)',
+    0x1AF4:'Red Hat, Inc. (PCI)',
+}
+
+def get_status_name(status):
+    result = ''
+    for name in status_name:
+        if name[0] & status:
+            result = result + name[1] + ' '
+    return result
+
+def list_interfaces(path):
+    interfaces = ''
+    for interface in sorted(os.listdir(path)):
+        interfaces = interfaces + interface + ' '
+    return interfaces
+
+def get_net_interfaces(path):
+    return list_interfaces(path + '/net')
+
+def get_block_interfaces(path):
+    return list_interfaces(path + '/block')
+
+def get_console_interfaces(path):
+    return list_interfaces(path + '/block')
+
+def get_9p_interfaces(path):
+    return open(path + '/mount_tag').read().rstrip()
+
+def get_gpu_interfaces(path):
+    return list_interfaces(path + '/graphics')
+
+def get_input_interaces(path):
+    return list_interfaces(path + '/input')
+
+get_interfaces = {
+    1:get_net_interfaces,
+    2:get_block_interfaces,
+    3:get_console_interfaces,
+    9:get_9p_interfaces,
+    16:get_gpu_interfaces,
+    18:get_input_interaces,
+}
+
+busses = '/sys/bus/virtio'
+devices = busses + '/devices'
+
+for device in sorted(os.listdir(devices)):
+    bus = os.path.basename(os.path.dirname(os.readlink(devices + '/' + device)))
+    path = devices + '/' + device
+    subsystem = os.path.basename(os.readlink(path + '/subsystem'))
+    device_id = int(open(path + '/device').read(), base = 0)
+    vendor = int(open(path + '/vendor').read(), base = 0)
+    driver = os.path.basename(os.readlink(path + '/driver'))
+    modalias = open(path + '/modalias').read().rstrip()
+    features = open(path + '/features').read().rstrip()
+    status = open(path + '/status').read().rstrip()
+
+    print(bus + ' ' + device + ' ' + vendor_name[vendor] + ' Virtio ' + device_name[device_id])
+    print('\tSubsystem: ' + subsystem)
+    print('\tModalias: ' + modalias)
+    print('\tStatus: ' + get_status_name(int(status, base=0)))
+    bit=0
+    for feature in features:
+        if feature == '1':
+            try:
+                if bit >= 24:
+                    print('\tFeature: ' + reserved_feature_name[bit])
+                else:
+                    print('\tFeature: ' + get_feature[device_id](bit))
+            except:
+                print('\tFeature: ' + str(bit))
+        bit += 1
+    print('\tKernel driver in use: ' + driver)
+    try:
+        print('\tInterfaces: ' + get_interfaces[device_id](path))
+    except:
+        print('\tNo interface')
+    print('')