From nobody Tue Feb 10 04:16:41 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 1649887349503121.97982770010208; Wed, 13 Apr 2022 15:02:29 -0700 (PDT) Received: from localhost ([::1]:58616 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nel4G-0003Kh-AU for importer@patchew.org; Wed, 13 Apr 2022 18:02:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48740) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nel2a-0001Df-37 for qemu-devel@nongnu.org; Wed, 13 Apr 2022 18:00:44 -0400 Received: from smtp126.ord1d.emailsrvr.com ([184.106.54.126]:50776) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nel2X-0004Ll-Aa for qemu-devel@nongnu.org; Wed, 13 Apr 2022 18:00:43 -0400 Received: by smtp8.relay.ord1d.emailsrvr.com (Authenticated sender: adeason-AT-sinenomine.net) with ESMTPSA id 4FD5BC019F; Wed, 13 Apr 2022 18:00:16 -0400 (EDT) X-Auth-ID: adeason@sinenomine.net From: Andrew Deason To: qemu-devel@nongnu.org Subject: [PATCH v2 1/5] qga/commands-posix: Use getifaddrs when available Date: Wed, 13 Apr 2022 17:00:03 -0500 Message-Id: <20220413220007.14467-2-adeason@sinenomine.net> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20220413220007.14467-1-adeason@sinenomine.net> References: <20220413220007.14467-1-adeason@sinenomine.net> X-Classification-ID: 5647c629-c4e4-4626-ae9f-55e4ffbba697-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=184.106.54.126; envelope-from=adeason@sinenomine.net; helo=smtp126.ord1d.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, 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 , Michal Privoznik Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZM-MESSAGEID: 1649887351909100001 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 861de93c4f..1c033bcc58 100644 --- a/meson.build +++ b/meson.build @@ -1633,20 +1633,21 @@ config_host_data.set('CONFIG_MEMALIGN', cc.has_func= tion('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_SEM_TIMEDWAIT', cc.has_function('sem_timedwai= t', dependencies: threads)) 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 75dbaab68e..e0feb5ffb5 100644 --- a/qga/commands-posix.c +++ b/qga/commands-posix.c @@ -37,38 +37,45 @@ #include #define environ (*_NSGetEnviron()) #else extern char **environ; #endif #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 @@ -2147,237 +2154,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: @@ -2933,26 +2723,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; @@ -2980,20 +2764,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) { @@ -3042,33 +3054,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