From nobody Wed Nov 5 18:23:04 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1536320819976830.0775071198984; Fri, 7 Sep 2018 04:46:59 -0700 (PDT) Received: from localhost ([::1]:38037 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fyFE2-0004uT-TA for importer@patchew.org; Fri, 07 Sep 2018 07:46:58 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36710) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fyF9e-0000ts-On for qemu-devel@nongnu.org; Fri, 07 Sep 2018 07:42:27 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fyF9a-0004AX-Jt for qemu-devel@nongnu.org; Fri, 07 Sep 2018 07:42:26 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:37980) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fyF9a-00049q-99 for qemu-devel@nongnu.org; Fri, 07 Sep 2018 07:42:22 -0400 Received: by mail-wm0-f44.google.com with SMTP id t25-v6so14296280wmi.3 for ; Fri, 07 Sep 2018 04:42:22 -0700 (PDT) Received: from fiorina.redhat.com (ip-94-112-73-67.net.upcbroadband.cz. [94.112.73.67]) by smtp.gmail.com with ESMTPSA id z184-v6sm25239813wmz.0.2018.09.07.04.42.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 07 Sep 2018 04:42:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Z+RgIiLmkHxRecpFDD5pjxCKiIK0Hw1NMVMZCifrFaY=; b=DM/ylk+syL5MhpqLim3/SR8GA8InavUjdpiLLvRcPza6st2Dhf/HdFRh0ul+eodOAJ Dtzq9HsJrifeI2n8dtk7RwXfSV/v/NwoKdJskoD1qw7I3IAlmGehJxWk3hiY0am112rJ tJBVL80RWZ0eoQt/T15FuuiacDMqrlrIPquPAWeb5y/ExUPJX4TWxXJtZE3NZqU9XSiP CEHvAdvmo5CDuh0mp+dm99AJA/SeiHrh/qD4sXt/kKVqqq3JT0H2XNzhJbnxDVTkfivS /Cvg/QmoRsKTQ9Qhp70Q29sBHal38cOHRvB3x8m+GH8oZeMF4kDEVQv4Up2wOu70vgoh zzgA== X-Gm-Message-State: APzg51DzIy9wLT6Hr0xvI3fSKHQE4XjpwKBvM9pJHF86eQL8gYQ0qt0P nU76ONHyJ6cyIW3kDifo70a5UNtZWdM= X-Google-Smtp-Source: ANB0VdbRcC9GnMg7tql8r4X0Z5T3WiClu0mvCiDQ1kdPK2ZmcWNDjG5xudRqzhh0A9CKE0SAYELDKQ== X-Received: by 2002:a1c:1bc2:: with SMTP id b185-v6mr5416335wmb.160.1536320540647; Fri, 07 Sep 2018 04:42:20 -0700 (PDT) From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= To: qemu-devel@nongnu.org Date: Fri, 7 Sep 2018 13:42:12 +0200 Message-Id: X-Mailer: git-send-email 2.18.0 In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 74.125.82.44 Subject: [Qemu-devel] [PATCH v3 4/5] qga: report disk serial number X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Olga Krishtal , =?UTF-8?q?Tom=C3=A1=C5=A1=20Golembiovsk=C3=BD?= , Michael Roth , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RDMRC_1 RSF_0 Z_629925259 SPT_0 The feature is implemented for Windows and Linux. Reporting of serial number on Linux depends on libudev. Example from Linux: { "name": "dm-2", "mountpoint": "/", ... "disk": [ { "serial": "SAMSUNG_MZ7LN512HCHP-000L1_S1ZKNXAG822493", ... } ], } Signed-off-by: Tom=C3=A1=C5=A1 Golembiovsk=C3=BD --- configure | 22 ++++++++++++++ qga/Makefile.objs | 1 + qga/commands-posix.c | 22 ++++++++++++++ qga/commands-win32.c | 71 ++++++++++++++++++++++++++++++++------------ qga/qapi-schema.json | 4 ++- 5 files changed, 100 insertions(+), 20 deletions(-) diff --git a/configure b/configure index 0f168607e8..ac24cb3975 100755 --- a/configure +++ b/configure @@ -477,6 +477,7 @@ libxml2=3D"" docker=3D"no" debug_mutex=3D"no" libpmem=3D"" +libudev=3D"no" =20 # cross compilers defaults, can be overridden with --cross-cc-ARCH cross_cc_aarch64=3D"aarch64-linux-gnu-gcc" @@ -873,6 +874,7 @@ Linux) vhost_vsock=3D"yes" QEMU_INCLUDES=3D"-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QE= MU_INCLUDES" supported_os=3D"yes" + libudev=3D"yes" ;; esac =20 @@ -5676,6 +5678,20 @@ if test "$libnfs" !=3D "no" ; then fi fi =20 +########################################## +# Do we have libudev +if test "$libudev" !=3D "no" ; then + if $pkg_config libudev; then + libudev=3D"yes" + libudev_libs=3D$($pkg_config --libs libudev) + else + if test "$libudev" =3D "yes" ; then + feature_not_found "libudev" "Install systemd development files" + fi + libudev=3D"no" + fi +fi + # Now we've finished running tests it's OK to add -Werror to the compiler = flags if test "$werror" =3D "yes"; then QEMU_CFLAGS=3D"-Werror $QEMU_CFLAGS" @@ -6100,6 +6116,7 @@ echo "VxHS block device $vxhs" echo "capstone $capstone" echo "docker $docker" echo "libpmem support $libpmem" +echo "libudev $libudev" =20 if test "$sdl_too_old" =3D "yes"; then echo "-> Your SDL version is too old - please upgrade to have SDL support" @@ -6944,6 +6961,11 @@ if test "$docker" !=3D "no"; then echo "HAVE_USER_DOCKER=3Dy" >> $config_host_mak fi =20 +if test "$libudev" !=3D "no"; then + echo "CONFIG_LIBUDEV=3Dy" >> $config_host_mak + echo "LIBUDEV_LIBS=3D$libudev_libs" >> $config_host_mak +fi + # use included Linux headers if test "$linux" =3D "yes" ; then mkdir -p linux-headers diff --git a/qga/Makefile.objs b/qga/Makefile.objs index ed08c5917c..80e6bb3c2e 100644 --- a/qga/Makefile.objs +++ b/qga/Makefile.objs @@ -1,3 +1,4 @@ +commands-posix.o-libs :=3D $(LIBUDEV_LIBS) qga-obj-y =3D commands.o guest-agent-command-state.o main.o qga-obj-$(CONFIG_POSIX) +=3D commands-posix.o channel-posix.o qga-obj-$(CONFIG_WIN32) +=3D commands-win32.o channel-win32.o service-win3= 2.o diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 37e8a2d791..37fedd123b 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -47,6 +47,7 @@ extern char **environ; #include #include #include +#include =20 #ifdef FIFREEZE #define CONFIG_FSFREEZE @@ -872,6 +873,10 @@ static void build_guest_fsinfo_for_real_device(char co= nst *syspath, GuestDiskAddressList *list =3D NULL; bool has_ata =3D false, has_host =3D false, has_tgt =3D false; char *p, *q, *driver =3D NULL; +#ifdef CONFIG_LIBUDEV + struct udev *udev =3D NULL; + struct udev_device *udevice =3D NULL; +#endif =20 p =3D strstr(syspath, "/devices/pci"); if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n", @@ -936,6 +941,21 @@ static void build_guest_fsinfo_for_real_device(char co= nst *syspath, list =3D g_malloc0(sizeof(*list)); list->value =3D disk; =20 +#ifdef CONFIG_LIBUDEV + udev =3D udev_new(); + udevice =3D udev_device_new_from_syspath(udev, syspath); + if (udev =3D=3D NULL || udevice =3D=3D NULL) { + g_debug("failed to query udev"); + } else { + const char *serial; + serial =3D udev_device_get_property_value(udevice, "ID_SERIAL"); + if (serial !=3D NULL && *serial !=3D 0) { + disk->serial =3D g_strdup(serial); + disk->has_serial =3D true; + } + } +#endif + if (strcmp(driver, "ata_piix") =3D=3D 0) { /* a host per ide bus, target*:0::0 */ if (!has_host || !has_tgt) { @@ -1003,6 +1023,8 @@ cleanup: qapi_free_GuestDiskAddressList(list); } g_free(driver); + udev_unref(udev); + udev_device_unref(udevice); } =20 static void build_guest_fsinfo_for_device(char const *devpath, diff --git a/qga/commands-win32.c b/qga/commands-win32.c index e16c58275e..fa186154a8 100644 --- a/qga/commands-win32.c +++ b/qga/commands-win32.c @@ -583,25 +583,53 @@ out: return pci; } =20 -static int get_disk_bus_type(HANDLE vol_h, Error **errp) +static void get_disk_properties(HANDLE vol_h, GuestDiskAddress *disk, + Error **errp) { STORAGE_PROPERTY_QUERY query; STORAGE_DEVICE_DESCRIPTOR *dev_desc, buf; DWORD received; + ULONG size =3D sizeof(buf); =20 dev_desc =3D &buf; - dev_desc->Size =3D sizeof(buf); query.PropertyId =3D StorageDeviceProperty; query.QueryType =3D PropertyStandardQuery; =20 if (!DeviceIoControl(vol_h, IOCTL_STORAGE_QUERY_PROPERTY, &query, sizeof(STORAGE_PROPERTY_QUERY), dev_desc, - dev_desc->Size, &received, NULL)) { + size, &received, NULL)) { error_setg_win32(errp, GetLastError(), "failed to get bus type"); - return -1; + return; + } + disk->bus_type =3D find_bus_type(dev_desc->BusType); + g_debug("bus type %d", disk->bus_type); + + /* Query once more. Now with long enough buffer. */ + size =3D dev_desc->Size; + dev_desc =3D g_malloc0(size); + if (!DeviceIoControl(vol_h, IOCTL_STORAGE_QUERY_PROPERTY, &query, + sizeof(STORAGE_PROPERTY_QUERY), dev_desc, + size, &received, NULL)) { + error_setg_win32(errp, GetLastError(), "failed to get serial numbe= r"); + goto out_free; + } + if (dev_desc->SerialNumberOffset > 0) { + if (dev_desc->SerialNumberOffset >=3D received) { + error_setg(errp, "offset outside the buffer"); + goto out_free; + } + const char *serial =3D (char *)dev_desc + dev_desc->SerialNumberOf= fset; + size_t len =3D received - dev_desc->SerialNumberOffset; + if (*serial !=3D 0) { + disk->serial =3D g_strndup(serial, len); + disk->has_serial =3D true; + g_debug("serial number %s", disk->serial); + } } +out_free: + g_free(dev_desc); =20 - return dev_desc->BusType; + return; } =20 /* VSS provider works with volumes, thus there is no difference if @@ -613,8 +641,8 @@ static GuestDiskAddressList *build_guest_disk_info(char= *guid, Error **errp) GuestDiskAddress *disk; SCSI_ADDRESS addr, *scsi_ad; DWORD len; - int bus; HANDLE vol_h; + Error *local_err =3D NULL; =20 scsi_ad =3D &addr; char *name =3D g_strndup(guid, strlen(guid)-1); @@ -624,22 +652,22 @@ static GuestDiskAddressList *build_guest_disk_info(ch= ar *guid, Error **errp) 0, NULL); if (vol_h =3D=3D INVALID_HANDLE_VALUE) { error_setg_win32(errp, GetLastError(), "failed to open volume"); - goto out_free; + goto err; } =20 - g_debug("getting bus type"); - bus =3D get_disk_bus_type(vol_h, errp); - if (bus < 0) { - goto out_close; + disk =3D g_malloc0(sizeof(*disk)); + get_disk_properties(vol_h, disk, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto err_close; } =20 - disk =3D g_malloc0(sizeof(*disk)); - disk->bus_type =3D find_bus_type(bus); - g_debug("bus type %d", disk->bus_type); - if (bus =3D=3D BusTypeScsi || bus =3D=3D BusTypeAta || bus =3D=3D BusT= ypeRAID + if (disk->bus_type =3D=3D GUEST_DISK_BUS_TYPE_SCSI + || disk->bus_type =3D=3D GUEST_DISK_BUS_TYPE_IDE + || disk->bus_type =3D=3D GUEST_DISK_BUS_TYPE_RAID #if (_WIN32_WINNT >=3D 0x0600) /* This bus type is not supported before Windows Server 2003 S= P1 */ - || bus =3D=3D BusTypeSas + || disk->bus_type =3D=3D GUEST_DISK_BUS_TYPE_SAS #endif ) { /* We are able to use the same ioctls for different bus types @@ -679,11 +707,16 @@ static GuestDiskAddressList *build_guest_disk_info(ch= ar *guid, Error **errp) list =3D g_malloc0(sizeof(*list)); list->value =3D disk; list->next =3D NULL; -out_close: CloseHandle(vol_h); -out_free: - g_free(name); return list; + +err_close: + g_free(disk); + CloseHandle(vol_h); +err: + g_free(name); + + return NULL; } =20 #else diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index dfbc4a5e32..3bcda6257e 100644 --- a/qga/qapi-schema.json +++ b/qga/qapi-schema.json @@ -834,13 +834,15 @@ # @bus: bus id # @target: target id # @unit: unit id +# @serial: serial number (since: 3.1) # # Since: 2.2 ## { 'struct': 'GuestDiskAddress', 'data': {'pci-controller': 'GuestPCIAddress', 'bus-type': 'GuestDiskBusType', - 'bus': 'int', 'target': 'int', 'unit': 'int'} } + 'bus': 'int', 'target': 'int', 'unit': 'int', + '*serial': 'str'} } =20 ## # @GuestFilesystemInfo: --=20 2.18.0