qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH] scripts: add a script to list virtio devices in a system


From: Michael S. Tsirkin
Subject: Re: [PATCH] scripts: add a script to list virtio devices in a system
Date: Tue, 11 May 2021 04:32:39 -0400

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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]