From nobody Mon Feb 9 05:54:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1651003050422636.2995026519959; Tue, 26 Apr 2022 12:57:30 -0700 (PDT) Received: from localhost ([::1]:57108 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njRJR-0006hS-Co for importer@patchew.org; Tue, 26 Apr 2022 15:57:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39248) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIB-0004cP-FN for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: from smtp117.iad3a.emailsrvr.com ([173.203.187.117]:33370) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRI8-0004bw-IO for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:11 -0400 Received: by smtp31.relay.iad3a.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id D2BAE239F2; Tue, 26 Apr 2022 15:55:43 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v3 1/5] qga/commands-posix: Use getifaddrs when available Date: Tue, 26 Apr 2022 14:55:22 -0500 Message-Id: <20220426195526.7699-2-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220426195526.7699-1-adeason@sinenomine.net> References: <20220426195526.7699-1-adeason@sinenomine.net> X-Classification-ID: cc5ef99f-0605-4056-825c-a202bb8c6ff8-2-1 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.203.187.117; envelope-from=adeason@sinenomine.net; helo=smtp117.iad3a.emailsrvr.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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: , Cc: Michael Roth , Andrew Deason , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1651003052169100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- meson.build | 1 + qga/commands-posix.c | 474 ++++++++++++++++++++++++++---------------------= ---- 2 files changed, 246 insertions(+), 229 deletions(-) diff --git a/meson.build b/meson.build index d083c6b7bf..860f593e9f 100644 --- a/meson.build +++ b/meson.build @@ -1631,20 +1631,21 @@ config_host_data.set('CONFIG_VALLOC', cc.has_functi= on('valloc')) config_host_data.set('CONFIG_MEMALIGN', cc.has_function('memalign')) config_host_data.set('CONFIG_PPOLL', cc.has_function('ppoll')) config_host_data.set('CONFIG_PREADV', cc.has_function('preadv', prefix: '#= include ')) config_host_data.set('CONFIG_PTHREAD_FCHDIR_NP', cc.has_function('pthread_= fchdir_np')) config_host_data.set('CONFIG_SENDFILE', cc.has_function('sendfile')) config_host_data.set('CONFIG_SETNS', cc.has_function('setns') and cc.has_f= unction('unshare')) 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_ra= nge')) +config_host_data.set('HAVE_GETIFADDRS', cc.has_function('getifaddrs')) config_host_data.set('HAVE_OPENPTY', cc.has_function('openpty', dependenci= es: util)) config_host_data.set('HAVE_STRCHRNUL', cc.has_function('strchrnul')) config_host_data.set('HAVE_SYSTEM_FUNCTION', cc.has_function('system', pre= fix: '#include ')) if rdma.found() config_host_data.set('HAVE_IBV_ADVISE_MR', cc.has_function('ibv_advise_mr', args: config_host['RDMA_LIBS'].spli= t(), prefix: '#include ')) endif =20 diff --git a/qga/commands-posix.c b/qga/commands-posix.c index 77f4672ca2..75ac19800f 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -27,38 +27,45 @@ #include "qemu/cutils.h" #include "commands-common.h" =20 #ifdef HAVE_UTMPX #include #endif =20 #if defined(__linux__) #include #include -#include -#include -#include -#include #include =20 #ifdef CONFIG_LIBUDEV #include #endif =20 #ifdef FIFREEZE #define CONFIG_FSFREEZE #endif #ifdef FITRIM #define CONFIG_FSTRIM #endif #endif =20 +#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; =20 *status =3D 0; =20 do { rpid =3D waitpid(pid, status, 0); } while (rpid =3D=3D -1 && errno =3D=3D EINTR); =20 @@ -2122,237 +2129,20 @@ void qmp_guest_suspend_disk(Error **errp) void qmp_guest_suspend_ram(Error **errp) { guest_suspend(SUSPEND_MODE_RAM, errp); } =20 void qmp_guest_suspend_hybrid(Error **errp) { guest_suspend(SUSPEND_MODE_HYBRID, errp); } =20 -static GuestNetworkInterface * -guest_find_interface(GuestNetworkInterfaceList *head, - const char *name) -{ - for (; head; head =3D head->next) { - if (strcmp(head->value->name, name) =3D=3D 0) { - return head->value; - } - } - - return NULL; -} - -static int guest_get_network_stats(const char *name, - GuestNetworkInterfaceStat *stats) -{ - int name_len; - char const *devinfo =3D "/proc/net/dev"; - FILE *fp; - char *line =3D NULL, *colon; - size_t n =3D 0; - fp =3D fopen(devinfo, "r"); - if (!fp) { - return -1; - } - name_len =3D strlen(name); - while (getline(&line, &n, fp) !=3D -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 =3D g_strchug(line); - if (trim_line[0] =3D=3D '\0') { - continue; - } - colon =3D strchr(trim_line, ':'); - if (!colon) { - continue; - } - if (colon - name_len =3D=3D trim_line && - strncmp(trim_line, name, name_len) =3D=3D 0) { - if (sscanf(colon + 1, - "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %l= ld %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) !=3D 16) { - continue; - } - stats->rx_bytes =3D rx_bytes; - stats->rx_packets =3D rx_packets; - stats->rx_errs =3D rx_errs; - stats->rx_dropped =3D rx_dropped; - stats->tx_bytes =3D tx_bytes; - stats->tx_packets =3D tx_packets; - stats->tx_errs =3D tx_errs; - stats->tx_dropped =3D 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 =3D NULL, **tail =3D &head; - struct ifaddrs *ifap, *ifa; - - if (getifaddrs(&ifap) < 0) { - error_setg_errno(errp, errno, "getifaddrs failed"); - goto error; - } - - for (ifa =3D ifap; ifa; ifa =3D ifa->ifa_next) { - GuestNetworkInterface *info; - GuestIpAddressList **address_tail; - GuestIpAddress *address_item =3D NULL; - GuestNetworkInterfaceStat *interface_stat =3D 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 =3D guest_find_interface(head, ifa->ifa_name); - - if (!info) { - info =3D g_malloc0(sizeof(*info)); - info->name =3D 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 =3D socket(PF_INET, SOCK_STREAM, 0); - if (sock =3D=3D -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) =3D=3D -1) { - error_setg_errno(errp, errno, - "failed to get MAC address of %s", - ifa->ifa_name); - close(sock); - goto error; - } - - close(sock); - mac_addr =3D (unsigned char *) &ifr.ifr_hwaddr.sa_data; - - info->hardware_address =3D - 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 =3D true; - } - - if (ifa->ifa_addr && - ifa->ifa_addr->sa_family =3D=3D AF_INET) { - /* interface with IPv4 address */ - p =3D &((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 =3D g_malloc0(sizeof(*address_item)); - address_item->ip_address =3D g_strdup(addr4); - address_item->ip_address_type =3D 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 netma= sk. */ - p =3D &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; - address_item->prefix =3D ctpop32(((uint32_t *) p)[0]); - } - } else if (ifa->ifa_addr && - ifa->ifa_addr->sa_family =3D=3D AF_INET6) { - /* interface with IPv6 address */ - p =3D &((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 =3D g_malloc0(sizeof(*address_item)); - address_item->ip_address =3D g_strdup(addr6); - address_item->ip_address_type =3D 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 netma= sk. */ - p =3D &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_add= r; - address_item->prefix =3D - 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 =3D &info->ip_addresses; - while (*address_tail) { - address_tail =3D &(*address_tail)->next; - } - QAPI_LIST_APPEND(address_tail, address_item); - - info->has_ip_addresses =3D true; - - if (!info->has_statistics) { - interface_stat =3D g_malloc0(sizeof(*interface_stat)); - if (guest_get_network_stats(info->name, interface_stat) =3D=3D= -1) { - info->has_statistics =3D false; - g_free(interface_stat); - } else { - info->statistics =3D interface_stat; - info->has_statistics =3D 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. * * In system-to-@vcpu direction, the following @vcpu fields are accessed: * - R: vcpu->logical_id * - W: vcpu->online * - W: vcpu->can_offline * * In @vcpu-to-system direction, the following @vcpu fields are accessed: @@ -2908,26 +2698,20 @@ void qmp_guest_suspend_disk(Error **errp) void qmp_guest_suspend_ram(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); } =20 void qmp_guest_suspend_hybrid(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); } =20 -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); return NULL; } =20 int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp) { error_setg(errp, QERR_UNSUPPORTED); return -1; @@ -2955,20 +2739,248 @@ qmp_guest_set_memory_blocks(GuestMemoryBlockList *= mem_blks, Error **errp) } =20 GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); return NULL; } =20 #endif =20 +#ifdef HAVE_GETIFADDRS +static GuestNetworkInterface * +guest_find_interface(GuestNetworkInterfaceList *head, + const char *name) +{ + for (; head; head =3D head->next) { + if (strcmp(head->value->name, name) =3D=3D 0) { + return head->value; + } + } + + return NULL; +} + +static int guest_get_network_stats(const char *name, + GuestNetworkInterfaceStat *stats) +{ + int name_len; + char const *devinfo =3D "/proc/net/dev"; + FILE *fp; + char *line =3D NULL, *colon; + size_t n =3D 0; + fp =3D fopen(devinfo, "r"); + if (!fp) { + return -1; + } + name_len =3D strlen(name); + while (getline(&line, &n, fp) !=3D -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 =3D g_strchug(line); + if (trim_line[0] =3D=3D '\0') { + continue; + } + colon =3D strchr(trim_line, ':'); + if (!colon) { + continue; + } + if (colon - name_len =3D=3D trim_line && + strncmp(trim_line, name, name_len) =3D=3D 0) { + if (sscanf(colon + 1, + "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %l= ld %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) !=3D 16) { + continue; + } + stats->rx_bytes =3D rx_bytes; + stats->rx_packets =3D rx_packets; + stats->rx_errs =3D rx_errs; + stats->rx_dropped =3D rx_dropped; + stats->tx_bytes =3D tx_bytes; + stats->tx_packets =3D tx_packets; + stats->tx_errs =3D tx_errs; + stats->tx_dropped =3D 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 =3D NULL, **tail =3D &head; + struct ifaddrs *ifap, *ifa; + + if (getifaddrs(&ifap) < 0) { + error_setg_errno(errp, errno, "getifaddrs failed"); + goto error; + } + + for (ifa =3D ifap; ifa; ifa =3D ifa->ifa_next) { + GuestNetworkInterface *info; + GuestIpAddressList **address_tail; + GuestIpAddress *address_item =3D NULL; + GuestNetworkInterfaceStat *interface_stat =3D 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 =3D guest_find_interface(head, ifa->ifa_name); + + if (!info) { + info =3D g_malloc0(sizeof(*info)); + info->name =3D 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 =3D socket(PF_INET, SOCK_STREAM, 0); + if (sock =3D=3D -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) =3D=3D -1) { + error_setg_errno(errp, errno, + "failed to get MAC address of %s", + ifa->ifa_name); + close(sock); + goto error; + } + + close(sock); + mac_addr =3D (unsigned char *) &ifr.ifr_hwaddr.sa_data; + + info->hardware_address =3D + 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 =3D true; + } + + if (ifa->ifa_addr && + ifa->ifa_addr->sa_family =3D=3D AF_INET) { + /* interface with IPv4 address */ + p =3D &((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 =3D g_malloc0(sizeof(*address_item)); + address_item->ip_address =3D g_strdup(addr4); + address_item->ip_address_type =3D 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 netma= sk. */ + p =3D &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr; + address_item->prefix =3D ctpop32(((uint32_t *) p)[0]); + } + } else if (ifa->ifa_addr && + ifa->ifa_addr->sa_family =3D=3D AF_INET6) { + /* interface with IPv6 address */ + p =3D &((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 =3D g_malloc0(sizeof(*address_item)); + address_item->ip_address =3D g_strdup(addr6); + address_item->ip_address_type =3D 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 netma= sk. */ + p =3D &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_add= r; + address_item->prefix =3D + 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 =3D &info->ip_addresses; + while (*address_tail) { + address_tail =3D &(*address_tail)->next; + } + QAPI_LIST_APPEND(address_tail, address_item); + + info->has_ip_addresses =3D true; + + if (!info->has_statistics) { + interface_stat =3D g_malloc0(sizeof(*interface_stat)); + if (guest_get_network_stats(info->name, interface_stat) =3D=3D= -1) { + info->has_statistics =3D false; + g_free(interface_stat); + } else { + info->statistics =3D interface_stat; + info->has_statistics =3D 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) =20 GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp) { error_setg(errp, QERR_UNSUPPORTED); return NULL; } =20 GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp) { @@ -3017,33 +3029,37 @@ qmp_guest_fstrim(bool has_minimum, int64_t minimum,= Error **errp) } #endif =20 /* add unsupported commands to the blacklist */ GList *ga_command_blacklist_init(GList *blacklist) { #if !defined(__linux__) { const char *list[] =3D { "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}; char **p =3D (char **)list; =20 while (*p) { blacklist =3D g_list_append(blacklist, g_strdup(*p++)); } } #endif =20 +#if !defined(HAVE_GETIFADDRS) + blacklist =3D g_list_append(blacklist, + g_strdup("guest-network-get-interfaces")); +#endif + #if !defined(CONFIG_FSFREEZE) { const char *list[] =3D { "guest-get-fsinfo", "guest-fsfreeze-status", "guest-fsfreeze-freeze", "guest-fsfreeze-freeze-list", "guest-fsfreeze-thaw", "guest-get-fsinfo", "guest-get-disks", NULL}; char **p =3D (char **)list; =20 while (*p) { --=20 2.11.0 From nobody Mon Feb 9 05:54:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1651003199334745.1575449462194; Tue, 26 Apr 2022 12:59:59 -0700 (PDT) Received: from localhost ([::1]:35206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njRLq-0002Wo-9J for importer@patchew.org; Tue, 26 Apr 2022 15:59:58 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39286) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIC-0004cR-Dv for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: from smtp115.iad3a.emailsrvr.com ([173.203.187.115]:39415) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRI9-0004c0-Au for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: by smtp31.relay.iad3a.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id 8787824804; Tue, 26 Apr 2022 15:55:44 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v3 2/5] qga/commands-posix: Fix iface hw address detection Date: Tue, 26 Apr 2022 14:55:23 -0500 Message-Id: <20220426195526.7699-3-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220426195526.7699-1-adeason@sinenomine.net> References: <20220426195526.7699-1-adeason@sinenomine.net> X-Classification-ID: cc5ef99f-0605-4056-825c-a202bb8c6ff8-3-1 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.203.187.115; envelope-from=adeason@sinenomine.net; helo=smtp115.iad3a.emailsrvr.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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: , Cc: Michael Roth , Andrew Deason , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1651003200975100001 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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 75ac19800f..dbfbb14152 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2850,48 +2850,57 @@ GuestNetworkInterfaceList *qmp_guest_network_get_in= terfaces(Error **errp) =20 info =3D guest_find_interface(head, ifa->ifa_name); =20 if (!info) { info =3D g_malloc0(sizeof(*info)); info->name =3D g_strdup(ifa->ifa_name); =20 QAPI_LIST_APPEND(tail, info); } =20 - if (!info->has_hardware_address && ifa->ifa_flags & SIOCGIFHWADDR)= { + if (!info->has_hardware_address) { /* we haven't obtained HW address yet */ sock =3D socket(PF_INET, SOCK_STREAM, 0); if (sock =3D=3D -1) { error_setg_errno(errp, errno, "failed to create socket"); goto error; } =20 memset(&ifr, 0, sizeof(ifr)); pstrcpy(ifr.ifr_name, IF_NAMESIZE, info->name); if (ioctl(sock, SIOCGIFHWADDR, &ifr) =3D=3D -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 =3D=3D 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)); + } =20 - close(sock); - mac_addr =3D (unsigned char *) &ifr.ifr_hwaddr.sa_data; + } else { + mac_addr =3D (unsigned char *) &ifr.ifr_hwaddr.sa_data; =20 - info->hardware_address =3D - 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 =3D + 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]); =20 - info->has_hardware_address =3D true; + info->has_hardware_address =3D true; + } + close(sock); } =20 if (ifa->ifa_addr && ifa->ifa_addr->sa_family =3D=3D AF_INET) { /* interface with IPv4 address */ p =3D &((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; } --=20 2.11.0 From nobody Mon Feb 9 05:54:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1651003049218333.76819539147914; Tue, 26 Apr 2022 12:57:29 -0700 (PDT) Received: from localhost ([::1]:57052 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njRJP-0006fM-VH for importer@patchew.org; Tue, 26 Apr 2022 15:57:27 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39230) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIA-0004bU-S2 for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:10 -0400 Received: from smtp117.iad3a.emailsrvr.com ([173.203.187.117]:40072) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRI9-0004c2-Aq for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:10 -0400 Received: by smtp31.relay.iad3a.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id 10AE2248B3; Tue, 26 Apr 2022 15:55:45 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v3 3/5] qga/commands-posix: Fix listing ifaces for Solaris Date: Tue, 26 Apr 2022 14:55:24 -0500 Message-Id: <20220426195526.7699-4-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220426195526.7699-1-adeason@sinenomine.net> References: <20220426195526.7699-1-adeason@sinenomine.net> X-Classification-ID: cc5ef99f-0605-4056-825c-a202bb8c6ff8-4-1 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.203.187.117; envelope-from=adeason@sinenomine.net; helo=smtp117.iad3a.emailsrvr.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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: , Cc: Michael Roth , Andrew Deason , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1651003049995100003 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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 --- 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 dbfbb14152..b91fdba2c1 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2756,20 +2756,21 @@ guest_find_interface(GuestNetworkInterfaceList *hea= d, return head->value; } } =20 return NULL; } =20 static int guest_get_network_stats(const char *name, GuestNetworkInterfaceStat *stats) { +#ifdef CONFIG_LINUX int name_len; char const *devinfo =3D "/proc/net/dev"; FILE *fp; char *line =3D NULL, *colon; size_t n =3D 0; fp =3D fopen(devinfo, "r"); if (!fp) { return -1; } name_len =3D strlen(name); @@ -2811,20 +2812,21 @@ static int guest_get_network_stats(const char *name, stats->tx_errs =3D tx_errs; stats->tx_dropped =3D tx_dropped; fclose(fp); g_free(line); return 0; } } fclose(fp); g_free(line); g_debug("/proc/net/dev: Interface '%s' not found", name); +#endif /* CONFIG_LINUX */ return -1; } =20 /* * Build information about guest interfaces */ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) { GuestNetworkInterfaceList *head =3D NULL, **tail =3D &head; struct ifaddrs *ifap, *ifa; @@ -2876,22 +2878,25 @@ GuestNetworkInterfaceList *qmp_guest_network_get_in= terfaces(Error **errp) if (errno =3D=3D 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)); } =20 } else { +#ifdef CONFIG_SOLARIS + mac_addr =3D (unsigned char *) &ifr.ifr_addr.sa_data; +#else mac_addr =3D (unsigned char *) &ifr.ifr_hwaddr.sa_data; - +#endif info->hardware_address =3D 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]); =20 info->has_hardware_address =3D true; } close(sock); } --=20 2.11.0 From nobody Mon Feb 9 05:54:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1651003196603142.4162261956584; Tue, 26 Apr 2022 12:59:56 -0700 (PDT) Received: from localhost ([::1]:34926 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njRLn-0002Lc-69 for importer@patchew.org; Tue, 26 Apr 2022 15:59:55 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39292) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIC-0004d5-LW for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: from smtp117.iad3a.emailsrvr.com ([173.203.187.117]:36910) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIB-0004eG-3Z for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: by smtp31.relay.iad3a.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id 8AF92248F7; Tue, 26 Apr 2022 15:55:45 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v3 4/5] qga/commands-posix: Log all net stats failures Date: Tue, 26 Apr 2022 14:55:25 -0500 Message-Id: <20220426195526.7699-5-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220426195526.7699-1-adeason@sinenomine.net> References: <20220426195526.7699-1-adeason@sinenomine.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Classification-ID: cc5ef99f-0605-4056-825c-a202bb8c6ff8-5-1 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.203.187.117; envelope-from=adeason@sinenomine.net; helo=smtp117.iad3a.emailsrvr.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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: , Cc: Michael Roth , Andrew Deason , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1651003197161100001 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=C3=A9 Lureau --- Changes since v1: - new in v2 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 b91fdba2c1..cc565e0dfd 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -2764,20 +2764,22 @@ static int guest_get_network_stats(const char *name, GuestNetworkInterfaceStat *stats) { #ifdef CONFIG_LINUX int name_len; char const *devinfo =3D "/proc/net/dev"; FILE *fp; char *line =3D NULL, *colon; size_t n =3D 0; fp =3D fopen(devinfo, "r"); if (!fp) { + g_debug("failed to open network stats %s: %s", devinfo, + g_strerror(errno)); return -1; } name_len =3D strlen(name); while (getline(&line, &n, fp) !=3D -1) { long long dummy; long long rx_bytes; long long rx_packets; long long rx_errs; long long rx_dropped; long long tx_bytes; @@ -2812,21 +2814,23 @@ static int guest_get_network_stats(const char *name, stats->tx_errs =3D tx_errs; stats->tx_dropped =3D tx_dropped; fclose(fp); g_free(line); return 0; } } 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; } =20 /* * Build information about guest interfaces */ GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp) { GuestNetworkInterfaceList *head =3D NULL, **tail =3D &head; struct ifaddrs *ifap, *ifa; --=20 2.11.0 From nobody Mon Feb 9 05:54:25 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1651003202140520.4401197233682; Tue, 26 Apr 2022 13:00:02 -0700 (PDT) Received: from localhost ([::1]:35360 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1njRLs-0002dM-U0 for importer@patchew.org; Tue, 26 Apr 2022 16:00:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:39290) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIC-0004d4-LW for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: from smtp116.iad3a.emailsrvr.com ([173.203.187.116]:40955) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1njRIA-0004cC-Sq for qemu-devel@nongnu.org; Tue, 26 Apr 2022 15:56:12 -0400 Received: by smtp31.relay.iad3a.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id 28007248BE; Tue, 26 Apr 2022 15:55:46 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v3 5/5] qga/commands-posix: 'guest-shutdown' for Solaris Date: Tue, 26 Apr 2022 14:55:26 -0500 Message-Id: <20220426195526.7699-6-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220426195526.7699-1-adeason@sinenomine.net> References: <20220426195526.7699-1-adeason@sinenomine.net> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Classification-ID: cc5ef99f-0605-4056-825c-a202bb8c6ff8-6-1 Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=173.203.187.116; envelope-from=adeason@sinenomine.net; helo=smtp116.iad3a.emailsrvr.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, 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: , Cc: Michael Roth , Andrew Deason , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1651003202948100003 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=C3=A9 Lureau --- Changes since v1: - new in v2 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 cc565e0dfd..386c1ccbc6 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -78,43 +78,58 @@ static void ga_wait_child(pid_t pid, int *status, Error= **errp) g_assert(rpid =3D=3D pid); } =20 void qmp_guest_shutdown(bool has_mode, const char *mode, Error **errp) { const char *shutdown_flag; Error *local_err =3D NULL; pid_t pid; int status; =20 +#ifdef CONFIG_SOLARIS + const char *powerdown_flag =3D "-i5"; + const char *halt_flag =3D "-i0"; + const char *reboot_flag =3D "-i6"; +#else + const char *powerdown_flag =3D "-P"; + const char *halt_flag =3D "-H"; + const char *reboot_flag =3D "-r"; +#endif + slog("guest-shutdown called, mode: %s", mode); if (!has_mode || strcmp(mode, "powerdown") =3D=3D 0) { - shutdown_flag =3D "-P"; + shutdown_flag =3D powerdown_flag; } else if (strcmp(mode, "halt") =3D=3D 0) { - shutdown_flag =3D "-H"; + shutdown_flag =3D halt_flag; } else if (strcmp(mode, "reboot") =3D=3D 0) { - shutdown_flag =3D "-r"; + shutdown_flag =3D reboot_flag; } else { error_setg(errp, "mode is invalid (valid values are: halt|powerdown|rebo= ot"); return; } =20 pid =3D fork(); if (pid =3D=3D 0) { /* child, start the shutdown */ setsid(); reopen_fd_to_null(0); reopen_fd_to_null(1); reopen_fd_to_null(2); =20 +#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"); return; } =20 ga_wait_child(pid, &status, &local_err); if (local_err) { error_propagate(errp, local_err); return; --=20 2.11.0