All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] qga: Support NVMe disk type and SMART
@ 2022-04-20  2:26 zhenwei pi
  2022-04-20  2:26 ` [PATCH v2 1/2] qga: Introduce NVMe disk bus type zhenwei pi
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: zhenwei pi @ 2022-04-20  2:26 UTC (permalink / raw)
  To: michael.roth, armbru; +Cc: marcandre.lureau, qemu-devel, zhenwei pi, f4bug

v1 -> v2:
 - Update version from 7.0 to 7.1.

v1:
 - Introduce NVMe type for command 'guest-get-disks'.
 - Introduce SMART, and implement NVMe SMART for command 'guest-get-disks'.

Zhenwei Pi (2):
  qga: Introduce NVMe disk bus type
  qga: Introduce disk smart

 qga/commands-posix.c | 78 +++++++++++++++++++++++++++++++++++++++++++-
 qga/qapi-schema.json | 56 +++++++++++++++++++++++++++++--
 2 files changed, 131 insertions(+), 3 deletions(-)

-- 
2.20.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] qga: Introduce NVMe disk bus type
  2022-04-20  2:26 [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
@ 2022-04-20  2:26 ` zhenwei pi
  2022-04-20  2:26 ` [PATCH v2 2/2] qga: Introduce disk smart zhenwei pi
  2022-04-27  1:51 ` PING: [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
  2 siblings, 0 replies; 4+ messages in thread
From: zhenwei pi @ 2022-04-20  2:26 UTC (permalink / raw)
  To: michael.roth, armbru; +Cc: marcandre.lureau, qemu-devel, zhenwei pi, f4bug

Assigning a NVMe disk by VFIO or emulating a NVMe controller by QEMU,
a NVMe disk get exposed in guest side. Support NVMe disk bus type and
implement posix version.

Test PCI passthrough case:
~#virsh qemu-agent-command buster '{"execute":"guest-get-disks"}' | jq
  ...
    {
      "name": "/dev/nvme0n1",
      "dependencies": [],
      "partition": false,
      "address": {
        "serial": "SAMSUNG MZQL23T8HCLS-00A07_S64HNE0N500076",
        "bus-type": "nvme",
        "bus": 0,
        "unit": 0,
        "pci-controller": {
          "bus": 0,
          "slot": 22,
          "domain": 0,
          "function": 0
        },
        "dev": "/dev/nvme0n1",
        "target": 0
      }
  ...

Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 qga/commands-posix.c | 5 ++++-
 qga/qapi-schema.json | 3 ++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 75dbaab68e..4ec83bbfbc 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -889,7 +889,8 @@ static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
         if (driver && (g_str_equal(driver, "ata_piix") ||
                        g_str_equal(driver, "sym53c8xx") ||
                        g_str_equal(driver, "virtio-pci") ||
-                       g_str_equal(driver, "ahci"))) {
+                       g_str_equal(driver, "ahci") ||
+                       g_str_equal(driver, "nvme"))) {
             break;
         }
 
@@ -984,6 +985,8 @@ static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
             g_debug("no host for '%s' (driver '%s')", syspath, driver);
             goto cleanup;
         }
+    } else if (strcmp(driver, "nvme") == 0) {
+        disk->bus_type = GUEST_DISK_BUS_TYPE_NVME;
     } else {
         g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath);
         goto cleanup;
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 94e4aacdcc..5ea76cfd1d 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -827,13 +827,14 @@
 # @mmc: Win multimedia card (MMC) bus type
 # @virtual: Win virtual bus type
 # @file-backed-virtual: Win file-backed bus type
+# @nvme: NVMe disks (since 7.1)
 #
 # Since: 2.2; 'Unknown' and all entries below since 2.4
 ##
 { 'enum': 'GuestDiskBusType',
   'data': [ 'ide', 'fdc', 'scsi', 'virtio', 'xen', 'usb', 'uml', 'sata',
             'sd', 'unknown', 'ieee1394', 'ssa', 'fibre', 'raid', 'iscsi',
-            'sas', 'mmc', 'virtual', 'file-backed-virtual' ] }
+            'sas', 'mmc', 'virtual', 'file-backed-virtual', 'nvme' ] }
 
 
 ##
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] qga: Introduce disk smart
  2022-04-20  2:26 [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
  2022-04-20  2:26 ` [PATCH v2 1/2] qga: Introduce NVMe disk bus type zhenwei pi
@ 2022-04-20  2:26 ` zhenwei pi
  2022-04-27  1:51 ` PING: [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
  2 siblings, 0 replies; 4+ messages in thread
From: zhenwei pi @ 2022-04-20  2:26 UTC (permalink / raw)
  To: michael.roth, armbru
  Cc: Keith Busch, marcandre.lureau, qemu-devel, zhenwei pi, f4bug

After assigning a NVMe/SCSI controller to guest by VFIO, we lose
everything on the host side. A guest uses these devices exclusively,
we usually don't care the actions on these devices. But there is a
low probability that hitting physical hardware warning, we need a
chance to get the basic smart log info.

Introduce disk smart, and implement NVMe smart on linux.

Thanks to Keith and Marc-André.

CC: Keith Busch <kbusch@kernel.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
 qga/commands-posix.c | 73 ++++++++++++++++++++++++++++++++++++++++++++
 qga/qapi-schema.json | 53 +++++++++++++++++++++++++++++++-
 2 files changed, 125 insertions(+), 1 deletion(-)

diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index 4ec83bbfbc..383bbebe42 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -27,6 +27,7 @@
 #include "qemu/base64.h"
 #include "qemu/cutils.h"
 #include "commands-common.h"
+#include "block/nvme.h"
 
 #ifdef HAVE_UTMPX
 #include <utmpx.h>
@@ -49,6 +50,7 @@ extern char **environ;
 #include <sys/socket.h>
 #include <net/if.h>
 #include <sys/statvfs.h>
+#include <linux/nvme_ioctl.h>
 
 #ifdef CONFIG_LIBUDEV
 #include <libudev.h>
@@ -1390,6 +1392,76 @@ static GuestDiskInfoList *get_disk_partitions(
     return ret;
 }
 
+static void get_nvme_smart(GuestDiskInfo *disk)
+{
+    int fd;
+    GuestNVMeSmart *smart;
+    NvmeSmartLog log = {0};
+    struct nvme_admin_cmd cmd = {
+        .opcode = NVME_ADM_CMD_GET_LOG_PAGE,
+        .nsid = NVME_NSID_BROADCAST,
+        .addr = (uint64_t)&log,
+        .data_len = sizeof(log),
+        .cdw10 = NVME_LOG_SMART_INFO | (1 << 15) /* RAE bit */
+                 | (((sizeof(log) >> 2) - 1) << 16)
+    };
+
+    fd = qemu_open_old(disk->name, O_RDONLY);
+    if (fd == -1) {
+        g_debug("Failed to open device: %s: %s", disk->name, g_strerror(errno));
+        return;
+    }
+
+    if (ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd)) {
+        g_debug("Failed to get smart: %s: %s", disk->name, g_strerror(errno));
+        close(fd);
+        return;
+    }
+
+    disk->has_smart = true;
+    disk->smart = g_new0(GuestDiskSmart, 1);
+    disk->smart->type = GUEST_DISK_BUS_TYPE_NVME;
+
+    smart = &disk->smart->u.nvme;
+    smart->critical_warning = log.critical_warning;
+    smart->temperature = lduw_le_p(&log.temperature); /* unaligned field */
+    smart->available_spare = log.available_spare;
+    smart->available_spare_threshold = log.available_spare_threshold;
+    smart->percentage_used = log.percentage_used;
+    smart->data_units_read_lo = le64_to_cpu(log.data_units_read[0]);
+    smart->data_units_read_hi = le64_to_cpu(log.data_units_read[1]);
+    smart->data_units_written_lo = le64_to_cpu(log.data_units_written[0]);
+    smart->data_units_written_hi = le64_to_cpu(log.data_units_written[1]);
+    smart->host_read_commands_lo = le64_to_cpu(log.host_read_commands[0]);
+    smart->host_read_commands_hi = le64_to_cpu(log.host_read_commands[1]);
+    smart->host_write_commands_lo = le64_to_cpu(log.host_write_commands[0]);
+    smart->host_write_commands_hi = le64_to_cpu(log.host_write_commands[1]);
+    smart->controller_busy_time_lo = le64_to_cpu(log.controller_busy_time[0]);
+    smart->controller_busy_time_hi = le64_to_cpu(log.controller_busy_time[1]);
+    smart->power_cycles_lo = le64_to_cpu(log.power_cycles[0]);
+    smart->power_cycles_hi = le64_to_cpu(log.power_cycles[1]);
+    smart->power_on_hours_lo = le64_to_cpu(log.power_on_hours[0]);
+    smart->power_on_hours_hi = le64_to_cpu(log.power_on_hours[1]);
+    smart->unsafe_shutdowns_lo = le64_to_cpu(log.unsafe_shutdowns[0]);
+    smart->unsafe_shutdowns_hi = le64_to_cpu(log.unsafe_shutdowns[1]);
+    smart->media_errors_lo = le64_to_cpu(log.media_errors[0]);
+    smart->media_errors_hi = le64_to_cpu(log.media_errors[1]);
+    smart->number_of_error_log_entries_lo =
+        le64_to_cpu(log.number_of_error_log_entries[0]);
+    smart->number_of_error_log_entries_hi =
+        le64_to_cpu(log.number_of_error_log_entries[1]);
+
+    close(fd);
+}
+
+static void get_disk_smart(GuestDiskInfo *disk)
+{
+    if (disk->has_address
+        && (disk->address->bus_type == GUEST_DISK_BUS_TYPE_NVME)) {
+        get_nvme_smart(disk);
+    }
+}
+
 GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
 {
     GuestDiskInfoList *ret = NULL;
@@ -1463,6 +1535,7 @@ GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
         }
 
         get_disk_deps(disk_dir, disk);
+        get_disk_smart(disk);
         ret = get_disk_partitions(ret, de->d_name, disk_dir, dev_name);
     }
 
diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json
index 5ea76cfd1d..4d8e506c9e 100644
--- a/qga/qapi-schema.json
+++ b/qga/qapi-schema.json
@@ -888,6 +888,55 @@
            '*serial': 'str', '*dev': 'str',
            '*ccw-address': 'GuestCCWAddress'} }
 
+##
+# @GuestNVMeSmart:
+#
+# NVMe smart informations, based on NVMe specification,
+# section <SMART / Health Information (Log Identifier 02h)>
+#
+# Since: 7.1
+##
+{ 'struct': 'GuestNVMeSmart',
+  'data': {'critical-warning': 'int',
+           'temperature': 'int',
+           'available-spare': 'int',
+           'available-spare-threshold': 'int',
+           'percentage-used': 'int',
+           'data-units-read-lo': 'uint64',
+           'data-units-read-hi': 'uint64',
+           'data-units-written-lo': 'uint64',
+           'data-units-written-hi': 'uint64',
+           'host-read-commands-lo': 'uint64',
+           'host-read-commands-hi': 'uint64',
+           'host-write-commands-lo': 'uint64',
+           'host-write-commands-hi': 'uint64',
+           'controller-busy-time-lo': 'uint64',
+           'controller-busy-time-hi': 'uint64',
+           'power-cycles-lo': 'uint64',
+           'power-cycles-hi': 'uint64',
+           'power-on-hours-lo': 'uint64',
+           'power-on-hours-hi': 'uint64',
+           'unsafe-shutdowns-lo': 'uint64',
+           'unsafe-shutdowns-hi': 'uint64',
+           'media-errors-lo': 'uint64',
+           'media-errors-hi': 'uint64',
+           'number-of-error-log-entries-lo': 'uint64',
+           'number-of-error-log-entries-hi': 'uint64' } }
+
+##
+# @GuestDiskSmart:
+#
+# Disk type related smart information.
+#
+# - @nvme: NVMe disk smart
+#
+# Since: 7.1
+##
+{ 'union': 'GuestDiskSmart',
+  'base': { 'type': 'GuestDiskBusType' },
+  'discriminator': 'type',
+  'data': { 'nvme': 'GuestNVMeSmart' } }
+
 ##
 # @GuestDiskInfo:
 #
@@ -899,12 +948,14 @@
 # @address: disk address information (only for non-virtual devices)
 # @alias: optional alias assigned to the disk, on Linux this is a name assigned
 #         by device mapper
+# @smart: disk smart information (Since 7.1)
 #
 # Since 5.2
 ##
 { 'struct': 'GuestDiskInfo',
   'data': {'name': 'str', 'partition': 'bool', '*dependencies': ['str'],
-           '*address': 'GuestDiskAddress', '*alias': 'str'} }
+           '*address': 'GuestDiskAddress', '*alias': 'str',
+           '*smart': 'GuestDiskSmart'} }
 
 ##
 # @guest-get-disks:
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 4+ messages in thread

* PING: [PATCH v2 0/2] qga: Support NVMe disk type and SMART
  2022-04-20  2:26 [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
  2022-04-20  2:26 ` [PATCH v2 1/2] qga: Introduce NVMe disk bus type zhenwei pi
  2022-04-20  2:26 ` [PATCH v2 2/2] qga: Introduce disk smart zhenwei pi
@ 2022-04-27  1:51 ` zhenwei pi
  2 siblings, 0 replies; 4+ messages in thread
From: zhenwei pi @ 2022-04-27  1:51 UTC (permalink / raw)
  To: michael.roth, armbru; +Cc: Keith Busch, marcandre.lureau, qemu-devel, f4bug

Hi, Markus & Michael

Could you please give any hint about this patch?

On 4/20/22 10:26, zhenwei pi wrote:
> v1 -> v2:
>   - Update version from 7.0 to 7.1.
> 
> v1:
>   - Introduce NVMe type for command 'guest-get-disks'.
>   - Introduce SMART, and implement NVMe SMART for command 'guest-get-disks'.
> 
> Zhenwei Pi (2):
>    qga: Introduce NVMe disk bus type
>    qga: Introduce disk smart
> 
>   qga/commands-posix.c | 78 +++++++++++++++++++++++++++++++++++++++++++-
>   qga/qapi-schema.json | 56 +++++++++++++++++++++++++++++--
>   2 files changed, 131 insertions(+), 3 deletions(-)
> 

-- 
zhenwei pi


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-04-27  1:56 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-20  2:26 [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi
2022-04-20  2:26 ` [PATCH v2 1/2] qga: Introduce NVMe disk bus type zhenwei pi
2022-04-20  2:26 ` [PATCH v2 2/2] qga: Introduce disk smart zhenwei pi
2022-04-27  1:51 ` PING: [PATCH v2 0/2] qga: Support NVMe disk type and SMART zhenwei pi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.