From patchwork Wed May 4 10:00:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=DbwgjXwD; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZ814d5Cz9sFx for ; Wed, 4 May 2022 21:18:25 +1000 (AEST) Received: from localhost ([::1]:42964 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmD1S-0004En-Uk for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:18:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59608) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBor-0008SL-PM for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:17 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:34935) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBoo-00069M-4A for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:16 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658473; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mfeQWKnPNSlvXdYR2weUhOBzSNS2naEy4+zw5GwrTeY=; b=DbwgjXwDUYUTW3yhFu5X6JKUP7DoqUvsZozAuRQjP1QEbNCIesoMmLJK1c1Ghbt1t+tO6q OTCazs73VORuc+j7v0g1YGCRh+wDOOtLtu89/kmvHZw4BgrJlPoKekkdqlXaDV91f0W23n BNWaCdqjHwyzpHjKGpGx7kH2QRQ6hhw= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-644-AuTmb8LXOUGQTxbt_sDq8Q-1; Wed, 04 May 2022 06:01:10 -0400 X-MC-Unique: AuTmb8LXOUGQTxbt_sDq8Q-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 648313C02B62; Wed, 4 May 2022 10:01:10 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A37E44A19A; Wed, 4 May 2022 10:01:08 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , Andrew Deason Subject: [PULL 1/7] qga/commands-posix: Use getifaddrs when available Date: Wed, 4 May 2022 14:00:55 +0400 Message-Id: <20220504100101.564747-2-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Andrew Deason Currently, commands-posix.c assumes that getifaddrs() is only available on Linux, and so the related guest agent command guest-network-get-interfaces is only implemented for #ifdef __linux__. This function does exist on other platforms, though, such as Solaris. So, add a meson check for getifaddrs(), and move the code for guest-network-get-interfaces to be built whenever getifaddrs() is available. The implementation for guest-network-get-interfaces still has some Linux-specific code, which is not fixed in this commit. This commit moves the relevant big chunks of code around without changing them, so a future commit can change the code in place. Signed-off-by: Andrew Deason Reviewed-by: Michal Privoznik Message-Id: <20220426195526.7699-2-adeason@sinenomine.net> --- meson.build | 1 + qga/commands-posix.c | 474 ++++++++++++++++++++++--------------------- 2 files changed, 246 insertions(+), 229 deletions(-) diff --git a/meson.build b/meson.build index 1fe7d257ff89..c26aa442d40e 100644 --- a/meson.build +++ b/meson.build @@ -1687,6 +1687,7 @@ config_host_data.set('CONFIG_SYNCFS', cc.has_function('syncfs')) config_host_data.set('CONFIG_SYNC_FILE_RANGE', cc.has_function('sync_file_range')) config_host_data.set('CONFIG_TIMERFD', cc.has_function('timerfd_create')) config_host_data.set('HAVE_COPY_FILE_RANGE', cc.has_function('copy_file_range')) +config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependencies: util)) config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', prefix: '#include ')) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 78f2f210015d..8fc56f7d71ac 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -34,10 +34,6 @@ #if defined(__linux__) #include #include -#include -#include -#include -#include #include #ifdef CONFIG_LIBUDEV @@ -52,6 +48,17 @@ #endif #endif +#ifdef HAVE_GETIFADDRS +#include +#include +#include +#include +#include +#ifdef CONFIG_SOLARIS +#include +#endif +#endif + static void ga_wait_child(pid_t pid, int *status, Error **errp) { pid_t rpid; @@ -2133,223 +2140,6 @@ void qmp_guest_suspend_hybrid(Error **errp) guest_suspend(SUSPEND_MODE_HYBRID, errp); } -static GuestNetworkInterface * -guest_find_interface(GuestNetworkInterfaceList *head, - const char *name) -{ - for (; head; head = head->next) { - if (strcmp(head->value->name, name) == 0) { - return head->value; - } - } - - return NULL; -} - -static int guest_get_network_stats(const char *name, - GuestNetworkInterfaceStat *stats) -{ - int name_len; - char const *devinfo = "/proc/net/dev"; - FILE *fp; - char *line = NULL, *colon; - size_t n = 0; - fp = fopen(devinfo, "r"); - if (!fp) { - return -1; - } - name_len = strlen(name); - while (getline(&line, &n, fp) != -1) { - long long dummy; - long long rx_bytes; - long long rx_packets; - long long rx_errs; - long long rx_dropped; - long long tx_bytes; - long long tx_packets; - long long tx_errs; - long long tx_dropped; - char *trim_line; - trim_line = g_strchug(line); - if (trim_line[0] == '\0') { - continue; - } - colon = strchr(trim_line, ':'); - if (!colon) { - continue; - } - if (colon - name_len == trim_line && - strncmp(trim_line, name, name_len) == 0) { - if (sscanf(colon + 1, - "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", - &rx_bytes, &rx_packets, &rx_errs, &rx_dropped, - &dummy, &dummy, &dummy, &dummy, - &tx_bytes, &tx_packets, &tx_errs, &tx_dropped, - &dummy, &dummy, &dummy, &dummy) != 16) { - continue; - } - stats->rx_bytes = rx_bytes; - stats->rx_packets = rx_packets; - stats->rx_errs = rx_errs; - stats->rx_dropped = rx_dropped; - stats->tx_bytes = tx_bytes; - stats->tx_packets = tx_packets; - stats->tx_errs = tx_errs; - stats->tx_dropped = tx_dropped; - fclose(fp); - g_free(line); - return 0; - } - } - fclose(fp); - g_free(line); - g_debug("/proc/net/dev: Interface '%s' not found", name); - return -1; -} - -/* - * Build information about guest interfaces - */ -GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) -{ - GuestNetworkInterfaceList *head = NULL, **tail = &head; - struct ifaddrs *ifap, *ifa; - - if (getifaddrs(&ifap) < 0) { - error_setg_errno(errp, errno, "getifaddrs failed"); - goto error; - } - - for (ifa = ifap; ifa; ifa = ifa->ifa_next) { - GuestNetworkInterface *info; - GuestIpAddressList **address_tail; - GuestIpAddress *address_item = NULL; - GuestNetworkInterfaceStat *interface_stat = NULL; - char addr4[INET_ADDRSTRLEN]; - char addr6[INET6_ADDRSTRLEN]; - int sock; - struct ifreq ifr; - unsigned char *mac_addr; - void *p; - - g_debug("Processing %s interface", ifa->ifa_name); - - info = guest_find_interface(head, ifa->ifa_name); - - if (!info) { - info = g_malloc0(sizeof(*info)); - info->name = g_strdup(ifa->ifa_name); - - QAPI_LIST_APPEND(tail, info); - } - - if (!info->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR) { - /* we haven't obtained HW address yet */ - sock = socket(PF_INET, SOCK_STREAM, 0); - if (sock == -1) { - error_setg_errno(errp, errno, "failed to create socket"); - goto error; - } - - memset(&ifr, 0, sizeof(ifr)); - pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name); - if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { - error_setg_errno(errp, errno, - "failed to get MAC address of %s", - ifa->ifa_name); - close(sock); - goto error; - } - - close(sock); - mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; - - info->hardware_address = - g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", - (int) mac_addr[0], (int) mac_addr[1], - (int) mac_addr[2], (int) mac_addr[3], - (int) mac_addr[4], (int) mac_addr[5]); - - info->has_hardware_address = true; - } - - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_INET) { - /* interface with IPv4 address */ - p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; - if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { - error_setg_errno(errp, errno, "inet_ntop failed"); - goto error; - } - - address_item = g_malloc0(sizeof(*address_item)); - address_item->ip_address = g_strdup(addr4); - address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; - - if (ifa->ifa_netmask) { - /* Count the number of set bits in netmask. - * This is safe as '1' and '0' cannot be shuffled in netmask. */ - p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; - address_item->prefix = ctpop32(((uint32_t *) p)[0]); - } - } else if (ifa->ifa_addr && - ifa->ifa_addr->sa_family == AF_INET6) { - /* interface with IPv6 address */ - p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; - if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { - error_setg_errno(errp, errno, "inet_ntop failed"); - goto error; - } - - address_item = g_malloc0(sizeof(*address_item)); - address_item->ip_address = g_strdup(addr6); - address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; - - if (ifa->ifa_netmask) { - /* Count the number of set bits in netmask. - * This is safe as '1' and '0' cannot be shuffled in netmask. */ - p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; - address_item->prefix = - ctpop32(((uint32_t *) p)[0]) + - ctpop32(((uint32_t *) p)[1]) + - ctpop32(((uint32_t *) p)[2]) + - ctpop32(((uint32_t *) p)[3]); - } - } - - if (!address_item) { - continue; - } - - address_tail = &info->ip_addresses; - while (*address_tail) { - address_tail = &(*address_tail)->next; - } - QAPI_LIST_APPEND(address_tail, address_item); - - info->has_ip_addresses = true; - - if (!info->has_statistics) { - interface_stat = g_malloc0(sizeof(*interface_stat)); - if (guest_get_network_stats(info->name, interface_stat) == -1) { - info->has_statistics = false; - g_free(interface_stat); - } else { - info->statistics = interface_stat; - info->has_statistics = true; - } - } - } - - freeifaddrs(ifap); - return head; - -error: - freeifaddrs(ifap); - qapi_free_GuestNetworkInterfaceList(head); - return NULL; -} - /* Transfer online/offline status between @vcpu and the guest system. * * On input either @errp or *@errp must be NULL. @@ -2919,12 +2709,6 @@ void qmp_guest_suspend_hybrid(Error **errp) error_setg(errp, QERR_UNSUPPORTED); } -GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) -{ - error_setg(errp, QERR_UNSUPPORTED); - return NULL; -} - GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); @@ -2966,6 +2750,234 @@ GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) #endif +#ifdef HAVE_GETIFADDRS +static GuestNetworkInterface * +guest_find_interface(GuestNetworkInterfaceList *head, + const char *name) +{ + for (; head; head = head->next) { + if (strcmp(head->value->name, name) == 0) { + return head->value; + } + } + + return NULL; +} + +static int guest_get_network_stats(const char *name, + GuestNetworkInterfaceStat *stats) +{ + int name_len; + char const *devinfo = "/proc/net/dev"; + FILE *fp; + char *line = NULL, *colon; + size_t n = 0; + fp = fopen(devinfo, "r"); + if (!fp) { + return -1; + } + name_len = strlen(name); + while (getline(&line, &n, fp) != -1) { + long long dummy; + long long rx_bytes; + long long rx_packets; + long long rx_errs; + long long rx_dropped; + long long tx_bytes; + long long tx_packets; + long long tx_errs; + long long tx_dropped; + char *trim_line; + trim_line = g_strchug(line); + if (trim_line[0] == '\0') { + continue; + } + colon = strchr(trim_line, ':'); + if (!colon) { + continue; + } + if (colon - name_len == trim_line && + strncmp(trim_line, name, name_len) == 0) { + if (sscanf(colon + 1, + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld", + &rx_bytes, &rx_packets, &rx_errs, &rx_dropped, + &dummy, &dummy, &dummy, &dummy, + &tx_bytes, &tx_packets, &tx_errs, &tx_dropped, + &dummy, &dummy, &dummy, &dummy) != 16) { + continue; + } + stats->rx_bytes = rx_bytes; + stats->rx_packets = rx_packets; + stats->rx_errs = rx_errs; + stats->rx_dropped = rx_dropped; + stats->tx_bytes = tx_bytes; + stats->tx_packets = tx_packets; + stats->tx_errs = tx_errs; + stats->tx_dropped = tx_dropped; + fclose(fp); + g_free(line); + return 0; + } + } + fclose(fp); + g_free(line); + g_debug("/proc/net/dev: Interface '%s' not found", name); + return -1; +} + +/* + * Build information about guest interfaces + */ +GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) +{ + GuestNetworkInterfaceList *head = NULL, **tail = &head; + struct ifaddrs *ifap, *ifa; + + if (getifaddrs(&ifap) < 0) { + error_setg_errno(errp, errno, "getifaddrs failed"); + goto error; + } + + for (ifa = ifap; ifa; ifa = ifa->ifa_next) { + GuestNetworkInterface *info; + GuestIpAddressList **address_tail; + GuestIpAddress *address_item = NULL; + GuestNetworkInterfaceStat *interface_stat = NULL; + char addr4[INET_ADDRSTRLEN]; + char addr6[INET6_ADDRSTRLEN]; + int sock; + struct ifreq ifr; + unsigned char *mac_addr; + void *p; + + g_debug("Processing %s interface", ifa->ifa_name); + + info = guest_find_interface(head, ifa->ifa_name); + + if (!info) { + info = g_malloc0(sizeof(*info)); + info->name = g_strdup(ifa->ifa_name); + + QAPI_LIST_APPEND(tail, info); + } + + if (!info->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR) { + /* we haven't obtained HW address yet */ + sock = socket(PF_INET, SOCK_STREAM, 0); + if (sock == -1) { + error_setg_errno(errp, errno, "failed to create socket"); + goto error; + } + + memset(&ifr, 0, sizeof(ifr)); + pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name); + if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { + error_setg_errno(errp, errno, + "failed to get MAC address of %s", + ifa->ifa_name); + close(sock); + goto error; + } + + close(sock); + mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; + + info->hardware_address = + g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", + (int) mac_addr[0], (int) mac_addr[1], + (int) mac_addr[2], (int) mac_addr[3], + (int) mac_addr[4], (int) mac_addr[5]); + + info->has_hardware_address = true; + } + + if (ifa->ifa_addr && + ifa->ifa_addr->sa_family == AF_INET) { + /* interface with IPv4 address */ + p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; + if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) { + error_setg_errno(errp, errno, "inet_ntop failed"); + goto error; + } + + address_item = g_malloc0(sizeof(*address_item)); + address_item->ip_address = g_strdup(addr4); + address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4; + + if (ifa->ifa_netmask) { + /* Count the number of set bits in netmask. + * This is safe as '1' and '0' cannot be shuffled in netmask. */ + p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; + address_item->prefix = ctpop32(((uint32_t *) p)[0]); + } + } else if (ifa->ifa_addr && + ifa->ifa_addr->sa_family == AF_INET6) { + /* interface with IPv6 address */ + p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr; + if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) { + error_setg_errno(errp, errno, "inet_ntop failed"); + goto error; + } + + address_item = g_malloc0(sizeof(*address_item)); + address_item->ip_address = g_strdup(addr6); + address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6; + + if (ifa->ifa_netmask) { + /* Count the number of set bits in netmask. + * This is safe as '1' and '0' cannot be shuffled in netmask. */ + p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr; + address_item->prefix = + ctpop32(((uint32_t *) p)[0]) + + ctpop32(((uint32_t *) p)[1]) + + ctpop32(((uint32_t *) p)[2]) + + ctpop32(((uint32_t *) p)[3]); + } + } + + if (!address_item) { + continue; + } + + address_tail = &info->ip_addresses; + while (*address_tail) { + address_tail = &(*address_tail)->next; + } + QAPI_LIST_APPEND(address_tail, address_item); + + info->has_ip_addresses = true; + + if (!info->has_statistics) { + interface_stat = g_malloc0(sizeof(*interface_stat)); + if (guest_get_network_stats(info->name, interface_stat) == -1) { + info->has_statistics = false; + g_free(interface_stat); + } else { + info->statistics = interface_stat; + info->has_statistics = true; + } + } + } + + freeifaddrs(ifap); + return head; + +error: + freeifaddrs(ifap); + qapi_free_GuestNetworkInterfaceList(head); + return NULL; +} + +#else + +GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) +{ + error_setg(errp, QERR_UNSUPPORTED); + return NULL; +} + +#endif /* HAVE_GETIFADDRS */ + #if !defined(CONFIG_FSFREEZE) GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) @@ -3028,8 +3040,7 @@ GList *ga_command_blacklist_init(GList *blacklist) { const char *list[] = { "guest-suspend-disk", "guest-suspend-ram", - "guest-suspend-hybrid", "guest-network-get-interfaces", - "guest-get-vcpus", "guest-set-vcpus", + "guest-suspend-hybrid", "guest-get-vcpus", "guest-set-vcpus", "guest-get-memory-blocks", "guest-set-memory-blocks", "guest-get-memory-block-size", "guest-get-memory-block-info", NULL}; @@ -3041,6 +3052,11 @@ GList *ga_command_blacklist_init(GList *blacklist) } #endif +#if !defined(HAVE_GETIFADDRS) + blacklist = g_list_append(blacklist, + g_strdup("guest-network-get-interfaces")); +#endif + #if !defined(CONFIG_FSFREEZE) { const char *list[] = { From patchwork Wed May 4 10:00:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626275 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=VnRzghxQ; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtYmz3SN5z9sFx for ; Wed, 4 May 2022 21:01:54 +1000 (AEST) Received: from localhost ([::1]:53740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmClN-0006ay-CO for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:01:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59630) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBox-00008Y-J5 for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:23 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:22040) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBov-0006Bu-GA for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658480; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/oYHCi98DqoX1i4GOw9C0kndEV6O3aVPdwJYp5PtqAc=; b=VnRzghxQyX9RpBkAQs6mKMLEjoMgDMcQKzOaADnYf5ZZP1VKde8xRjMvJocabshzMiXzx1 fWkv+TXXrD8IunW0+rqi/7WE8gjU3Hy5l8YKQ113XnBNFyyWYMimRZdTo7ym2dtsRehFtd BRUa9CS7r7NyUwdLLvM0XLMng/LklBs= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-584-zQK_vU9CN1abkbNW-g93cw-1; Wed, 04 May 2022 06:01:15 -0400 X-MC-Unique: zQK_vU9CN1abkbNW-g93cw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 725C8800B21; Wed, 4 May 2022 10:01:15 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 66939155CAD1; Wed, 4 May 2022 10:01:14 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , Andrew Deason Subject: [PULL 2/7] qga/commands-posix: Fix iface hw address detection Date: Wed, 4 May 2022 14:00:56 +0400 Message-Id: <20220504100101.564747-3-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Andrew Deason Since its introduction in commit 3424fc9f16a1 ("qemu-ga: add guest-network-get-interfaces command"), guest-network-get-interfaces seems to check if a given interface has a hardware address by checking 'ifa->ifa_flags & SIOCGIFHWADDR'. But ifa_flags is a field for IFF_* flags (IFF_UP, IFF_LOOPBACK, etc), and comparing it to an ioctl like SIOCGIFHWADDR doesn't make sense. On Linux, this isn't a big deal, since SIOCGIFHWADDR has so many bits set (0x8927), 'ifa->ifa_flags & SIOCGIFHWADDR' will usually have a nonzero result for any 'normal'-looking interfaces: anything with IFF_UP (0x1) or IFF_BROADCAST (0x2) set, as well as several less-common flags. This means we'll try to get the hardware address for most/all interfaces, even those that don't really have one (like the loopback device). For those interfaces, Linux just returns a hardware address of all zeroes. On Solaris, however, trying to get the hardware address for a loopback device returns an EADDRNOTAVAIL error. This causes us to return an error and the entire guest-network-get-interfaces call fails. Change this logic to always try to get the hardware address for each interface, and don't return an error if we fail to get it. Instead, just don't include the 'hardware-address' field in the result if we can't get the hardware address. Signed-off-by: Andrew Deason Reviewed-by: Michal Privoznik Message-Id: <20220426195526.7699-3-adeason@sinenomine.net> --- qga/commands-posix.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 8fc56f7d71ac..febb2ef0ffd6 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2861,7 +2861,7 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) QAPI_LIST_APPEND(tail, info); } - if (!info->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR) { + if (!info->has_hardware_address) { /* we haven't obtained HW address yet */ sock = socket(PF_INET, SOCK_STREAM, 0); if (sock == -1) { @@ -2872,23 +2872,32 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) memset(&ifr, 0, sizeof(ifr)); pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name); if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) { - error_setg_errno(errp, errno, - "failed to get MAC address of %s", - ifa->ifa_name); - close(sock); - goto error; - } + /* + * We can't get the hw addr of this interface, but that's not a + * fatal error. Don't set info->hardware_address, but keep + * going. + */ + if (errno == EADDRNOTAVAIL) { + /* The interface doesn't have a hw addr (e.g. loopback). */ + g_debug("failed to get MAC address of %s: %s", + ifa->ifa_name, strerror(errno)); + } else{ + g_warning("failed to get MAC address of %s: %s", + ifa->ifa_name, strerror(errno)); + } - close(sock); - mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; + } else { + mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; - info->hardware_address = - g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", - (int) mac_addr[0], (int) mac_addr[1], - (int) mac_addr[2], (int) mac_addr[3], - (int) mac_addr[4], (int) mac_addr[5]); + info->hardware_address = + g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", + (int) mac_addr[0], (int) mac_addr[1], + (int) mac_addr[2], (int) mac_addr[3], + (int) mac_addr[4], (int) mac_addr[5]); - info->has_hardware_address = true; + info->has_hardware_address = true; + } + close(sock); } if (ifa->ifa_addr && From patchwork Wed May 4 10:00:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626289 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=B+SObmLy; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZFH5kKkz9sFx for ; Wed, 4 May 2022 21:22:59 +1000 (AEST) Received: from localhost ([::1]:51846 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmD5s-0002S1-UE for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:22:57 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59700) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBp8-0000Nm-DM for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:54567) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBp3-0006Ex-3k for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=N8JNzGiaNDNHWs6xvMxyw01tzjQZKmtGczraMqhx/hI=; b=B+SObmLyRD7Str301o4xVmnMMx1hAND7tMXsF+S95tvir1NOkHq44eOtAZprwLJKpXRwmo r/ap/LCPsjHNXGOXoXRNTHoA7fNKusnpu3xPdId5ba0YyOu0Pp8/BMPepck3z7/Vihy7u+ rBRKKzxF5Q2O/F4Cn6lASkrbcUkunEg= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-608-z93h8aoKPyK3xkL3y294lA-1; Wed, 04 May 2022 06:01:19 -0400 X-MC-Unique: z93h8aoKPyK3xkL3y294lA-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6D92A1D3236C; Wed, 4 May 2022 10:01:19 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D5FE403D18D; Wed, 4 May 2022 10:01:18 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , Andrew Deason Subject: [PULL 3/7] qga/commands-posix: Fix listing ifaces for Solaris Date: Wed, 4 May 2022 14:00:57 +0400 Message-Id: <20220504100101.564747-4-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Andrew Deason The code for guest-network-get-interfaces needs a couple of small adjustments for Solaris: - The results from SIOCGIFHWADDR are documented as being in ifr_addr, not ifr_hwaddr (ifr_hwaddr doesn't exist on Solaris). - The implementation of guest_get_network_stats is Linux-specific, so hide it under #ifdef CONFIG_LINUX. On non-Linux, we just won't provide network interface stats. Signed-off-by: Andrew Deason Reviewed-by: Michal Privoznik Message-Id: <20220426195526.7699-4-adeason@sinenomine.net> --- qga/commands-posix.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index febb2ef0ffd6..c1e994f3e6ab 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2767,6 +2767,7 @@ guest_find_interface(GuestNetworkInterfaceList *head, static int guest_get_network_stats(const char *name, GuestNetworkInterfaceStat *stats) { +#ifdef CONFIG_LINUX int name_len; char const *devinfo = "/proc/net/dev"; FILE *fp; @@ -2822,6 +2823,7 @@ static int guest_get_network_stats(const char *name, fclose(fp); g_free(line); g_debug("/proc/net/dev: Interface '%s' not found", name); +#endif /* CONFIG_LINUX */ return -1; } @@ -2887,8 +2889,11 @@ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) } } else { +#ifdef CONFIG_SOLARIS + mac_addr = (unsigned char *) &ifr.ifr_addr.sa_data; +#else mac_addr = (unsigned char *) &ifr.ifr_hwaddr.sa_data; - +#endif info->hardware_address = g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x", (int) mac_addr[0], (int) mac_addr[1], From patchwork Wed May 4 10:00:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626280 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=QSBCE5d1; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZ2z3009z9sFx for ; Wed, 4 May 2022 21:14:03 +1000 (AEST) Received: from localhost ([::1]:33434 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmCxF-0005fr-7K for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:14:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59690) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBp4-0000J4-GR for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:30 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:44329) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBp2-0006Ee-Sh for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658488; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=utl+uFbDvNs/TJQRyDTZGAG/tI3wsSKl/nWyOYU7QBQ=; b=QSBCE5d1TAt2+CjrkAXmL2LpffXD2c4gM0SJBtHQqIw1UAOsVt+j53BUM0ZBuaZ6Wtq22M ZwC2JAb6y4tbZQWewLoNhEyerC3iiNHw+mMhXnd4b5mgD1mC8ysvD1heDhuP5LUcw7MrNl QPZbumaCXNWKxq0pdLDUN1B+4ViMPGI= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-670-o3Rc0XI8MNOvN7imSFyaag-1; Wed, 04 May 2022 06:01:24 -0400 X-MC-Unique: o3Rc0XI8MNOvN7imSFyaag-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 3EA07811E81; Wed, 4 May 2022 10:01:24 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 41F1B155CAD1; Wed, 4 May 2022 10:01:22 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , Andrew Deason Subject: [PULL 4/7] qga/commands-posix: Log all net stats failures Date: Wed, 4 May 2022 14:00:58 +0400 Message-Id: <20220504100101.564747-5-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.7 Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Andrew Deason guest_get_network_stats can silently fail in a couple of ways. Add debug messages to these cases, so we're never completely silent on failure. Signed-off-by: Andrew Deason Reviewed-by: Marc-André Lureau Message-Id: <20220426195526.7699-5-adeason@sinenomine.net> --- qga/commands-posix.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index c1e994f3e6ab..ee997a58f21c 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2775,6 +2775,8 @@ static int guest_get_network_stats(const char *name, size_t n = 0; fp = fopen(devinfo, "r"); if (!fp) { + g_debug("failed to open network stats %s: %s", devinfo, + g_strerror(errno)); return -1; } name_len = strlen(name); @@ -2823,7 +2825,9 @@ static int guest_get_network_stats(const char *name, fclose(fp); g_free(line); g_debug("/proc/net/dev: Interface '%s' not found", name); -#endif /* CONFIG_LINUX */ +#else /* !CONFIG_LINUX */ + g_debug("Network stats reporting available only for Linux"); +#endif /* !CONFIG_LINUX */ return -1; } From patchwork Wed May 4 10:00:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626284 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=RsiW8ya/; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZ7q4JqKz9sFx for ; Wed, 4 May 2022 21:18:14 +1000 (AEST) Received: from localhost ([::1]:42180 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmD1H-0003fj-00 for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:18:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59716) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBpA-0000QH-Fj for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:37199) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBp8-0006HC-RR for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:36 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658494; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QlQECKQuhJDdLwwEy/HTaRQ2au5LWxZ7ON+0Bk3rmJE=; b=RsiW8ya/9zJpVRXG3nJwb8X80HUtq8Vy3wnD0apZUTbb2ok3K1xkfWnoOj5zSHvM5gKGpj pOYh/f2ep/Nhs+h7B5nk7+zxwGz2jwySardxQPCvm+dhRVPeecAZVXK9kfFwO32yaM5Jdg BXJD2r3m7q0RHGru8kBMmqaBY1E1PSQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-661-4Q1AwTQ8M_6FtD5DhdNaEw-1; Wed, 04 May 2022 06:01:29 -0400 X-MC-Unique: 4Q1AwTQ8M_6FtD5DhdNaEw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id EFAAE85A5BE; Wed, 4 May 2022 10:01:28 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0CB6144A19D; Wed, 4 May 2022 10:01:27 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , Andrew Deason Subject: [PULL 5/7] qga/commands-posix: 'guest-shutdown' for Solaris Date: Wed, 4 May 2022 14:00:59 +0400 Message-Id: <20220504100101.564747-6-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.85 on 10.11.54.9 Received-SPF: pass client-ip=170.10.129.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: Andrew Deason On Solaris, instead of the -P, -H, and -r flags, we need to provide the target init state to the 'shutdown' command: state 5 is poweroff, 0 is halt, and 6 is reboot. We also need to pass -g0 to avoid the default 60-second delay, and -y to avoid a confirmation prompt. Implement this logic under an #ifdef CONFIG_SOLARIS, so the 'guest-shutdown' command works properly on Solaris. Signed-off-by: Andrew Deason Reviewed-by: Marc-André Lureau Message-Id: <20220426195526.7699-6-adeason@sinenomine.net> --- qga/commands-posix.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/qga/commands-posix.c b/qga/commands-posix.c index ee997a58f21c..7ab8d5eb3c69 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -85,13 +85,23 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) pid_t pid; int status; +#ifdef CONFIG_SOLARIS + const char *powerdown_flag = "-i5"; + const char *halt_flag = "-i0"; + const char *reboot_flag = "-i6"; +#else + const char *powerdown_flag = "-P"; + const char *halt_flag = "-H"; + const char *reboot_flag = "-r"; +#endif + slog("guest-shutdown called, mode: %s", mode); if (!has_mode || strcmp(mode, "powerdown") == 0) { - shutdown_flag = "-P"; + shutdown_flag = powerdown_flag; } else if (strcmp(mode, "halt") == 0) { - shutdown_flag = "-H"; + shutdown_flag = halt_flag; } else if (strcmp(mode, "reboot") == 0) { - shutdown_flag = "-r"; + shutdown_flag = reboot_flag; } else { error_setg(errp, "mode is invalid (valid values are: halt|powerdown|reboot"); @@ -106,8 +116,13 @@ void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) reopen_fd_to_null(1); reopen_fd_to_null(2); +#ifdef CONFIG_SOLARIS + execl("/sbin/shutdown", "shutdown", shutdown_flag, "-g0", "-y", + "hypervisor initiated shutdown", (char *)NULL); +#else execl("/sbin/shutdown", "shutdown", "-h", shutdown_flag, "+0", "hypervisor initiated shutdown", (char *)NULL); +#endif _exit(EXIT_FAILURE); } else if (pid < 0) { error_setg_errno(errp, errno, "failed to create child process"); From patchwork Wed May 4 10:01:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626290 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=BEeBMhTU; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZJD4J0yz9sFx for ; Wed, 4 May 2022 21:25:32 +1000 (AEST) Received: from localhost ([::1]:60564 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmD8L-0008Fs-Pa for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:25:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59734) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBpD-0000Ql-6h for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:40214) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBpA-0006HN-IO for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658495; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FBGmOd+ztf6Fw/4X0tGkERuaGl13ZSRfvCTVQ/ZlYFA=; b=BEeBMhTUX/qiYZfLCYh+2fBM11byf2MhcVRqfT1r3rcSUfBFWCQxDsUFiJY/DfPirMkGKE ge5J9LO4t/2d97uuuBpHqAUqWuhiMvEvXvkUwrf9xADYxbvmjLJn6EuqxchcriZiopLBwH 3MMNXGvw8qyzN0Tn2u4pkGTGvgWclj4= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-227-hfw1pr6tP8OGeSdDOoN40A-1; Wed, 04 May 2022 06:01:34 -0400 X-MC-Unique: hfw1pr6tP8OGeSdDOoN40A-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 31081811E78; Wed, 4 May 2022 10:01:34 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0CD3840CFD32; Wed, 4 May 2022 10:01:32 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , zhenwei pi Subject: [PULL 6/7] qga: Introduce NVMe disk bus type Date: Wed, 4 May 2022 14:01:00 +0400 Message-Id: <20220504100101.564747-7-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.11.54.1 Received-SPF: pass client-ip=170.10.129.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: zhenwei pi 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é Signed-off-by: zhenwei pi Message-Id: <20220420022610.418052-2-pizhenwei@bytedance.com> --- qga/qapi-schema.json | 3 ++- qga/commands-posix.c | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 94e4aacdcc65..5ea76cfd1d73 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' ] } ## diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 7ab8d5eb3c69..a5fbae00e90c 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -890,7 +890,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; } @@ -985,6 +986,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; From patchwork Wed May 4 10:01:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Marc-Andr=C3=A9_Lureau?= X-Patchwork-Id: 1626281 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=OKDQ+0nQ; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by bilbo.ozlabs.org (Postfix) with ESMTPS id 4KtZ306XMTz9sFx for ; Wed, 4 May 2022 21:14:04 +1000 (AEST) Received: from localhost ([::1]:33630 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nmCxG-0005nm-Ne for incoming@patchwork.ozlabs.org; Wed, 04 May 2022 07:14:02 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:59828) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBpL-0000jb-3b for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:37517) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nmBpI-0006Il-WA for qemu-devel@nongnu.org; Wed, 04 May 2022 06:01:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1651658504; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fGFLqz4GcWCyjhk8yzSNs5Qx91J3YajMXB6rSUu1Clk=; b=OKDQ+0nQQY3//JrKUv4h4G1URZUwWYmo4Qgdc28rY0z60a3dNCnO230sE0jjHOHByKmpZ0 XMjZlwLBiZDcTxgQHmnYhPyt1KAex5OO7WfVlksTBS2mb8oUZ/7v9+NikWTEIES6RJcPOZ tlc+nAxpVb/6JODAg1TuT3cEM/KlTto= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-362-_Sn8_Cm4PuiOK8T_eeNkFA-1; Wed, 04 May 2022 06:01:39 -0400 X-MC-Unique: _Sn8_Cm4PuiOK8T_eeNkFA-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C6D7E3C01D90; Wed, 4 May 2022 10:01:38 +0000 (UTC) Received: from localhost (unknown [10.39.208.46]) by smtp.corp.redhat.com (Postfix) with ESMTP id 84E199E84; Wed, 4 May 2022 10:01:37 +0000 (UTC) From: marcandre.lureau@redhat.com To: qemu-devel@nongnu.org Cc: Richard Henderson , Michael Roth , Peter Maydell , zhenwei pi , Keith Busch Subject: [PULL 7/7] qga: Introduce disk smart Date: Wed, 4 May 2022 14:01:01 +0400 Message-Id: <20220504100101.564747-8-marcandre.lureau@redhat.com> In-Reply-To: <20220504100101.564747-1-marcandre.lureau@redhat.com> References: <20220504100101.564747-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 Received-SPF: pass client-ip=170.10.133.124; envelope-from=marcandre.lureau@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -28 X-Spam_score: -2.9 X-Spam_bar: -- X-Spam_report: (-2.9 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.082, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" From: zhenwei pi 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 Reviewed-by: Marc-André Lureau Signed-off-by: zhenwei pi Message-Id: <20220420022610.418052-3-pizhenwei@bytedance.com> --- qga/qapi-schema.json | 53 +++++++++++++++++++++++++++++++- qga/commands-posix.c | 73 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+), 1 deletion(-) diff --git a/qga/qapi-schema.json b/qga/qapi-schema.json index 5ea76cfd1d73..4d8e506c9e86 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 +# +# 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: diff --git a/qga/commands-posix.c b/qga/commands-posix.c index a5fbae00e90c..69f209af87e6 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -26,6 +26,7 @@ #include "qemu/base64.h" #include "qemu/cutils.h" #include "commands-common.h" +#include "block/nvme.h" #ifdef HAVE_UTMPX #include @@ -35,6 +36,7 @@ #include #include #include +#include #ifdef CONFIG_LIBUDEV #include @@ -1391,6 +1393,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 = (uintptr_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; @@ -1464,6 +1536,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); }