diff options
| -rw-r--r-- | .cirrus.yml | 121 | ||||
| -rw-r--r-- | .mailmap | 2 | ||||
| -rw-r--r-- | block/nbd.c | 71 | ||||
| -rwxr-xr-x | configure | 1 | ||||
| -rw-r--r-- | contrib/gitdm/domain-map | 10 | ||||
| -rw-r--r-- | contrib/gitdm/group-map-academics | 4 | ||||
| -rw-r--r-- | contrib/gitdm/group-map-individuals | 7 | ||||
| -rw-r--r-- | contrib/gitdm/group-map-redhat | 1 | ||||
| -rw-r--r-- | contrib/plugins/hotblocks.c | 2 | ||||
| -rw-r--r-- | hw/ide/core.c | 4 | ||||
| -rw-r--r-- | hw/misc/mips_cpc.c | 1 | ||||
| -rw-r--r-- | nbd/server.c | 217 | ||||
| -rw-r--r-- | plugins/loader.c | 1 | ||||
| -rw-r--r-- | qemu-nbd.c | 15 | ||||
| -rw-r--r-- | tests/acceptance/machine_rx_gdbsim.py | 1 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/centos8.docker | 1 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/debian-amd64.docker | 1 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/fedora.docker | 1 | ||||
| -rw-r--r-- | tests/docker/dockerfiles/ubuntu2004.docker | 1 | ||||
| -rw-r--r-- | tests/plugin/bb.c | 4 |
20 files changed, 262 insertions, 204 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index d58782ce67..99d118239c 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -15,7 +15,7 @@ freebsd_12_task: - cd build - ../configure --enable-werror || { cat config.log; exit 1; } - gmake -j$(sysctl -n hw.ncpu) - - gmake -j$(sysctl -n hw.ncpu) check + - gmake -j$(sysctl -n hw.ncpu) check V=1 macos_task: osx_instance: @@ -29,7 +29,7 @@ macos_task: --extra-cflags='-Wno-error=deprecated-declarations' || { cat config.log; exit 1; } - gmake -j$(sysctl -n hw.ncpu) - - gmake check + - gmake check V=1 macos_xcode_task: osx_instance: @@ -43,67 +43,88 @@ macos_xcode_task: - ../configure --extra-cflags='-Wno-error=deprecated-declarations' --enable-werror --cc=clang || { cat config.log; exit 1; } - gmake -j$(sysctl -n hw.ncpu) - - gmake check + - gmake check V=1 windows_msys2_task: + timeout_in: 90m windows_container: - image: cirrusci/windowsservercore:cmake + image: cirrusci/windowsservercore:2019 os_version: 2019 cpu: 8 memory: 8G env: + CIRRUS_SHELL: powershell MSYS: winsymlinks:nativestrict MSYSTEM: MINGW64 CHERE_INVOKING: 1 - printenv_script: - - C:\tools\msys64\usr\bin\bash.exe -lc 'printenv' + setup_script: + - choco install -y --no-progress 7zip + - Write-Output $env:PATH + msys2_cache: + folder: C:\tools\archive + reupload_on_changes: false + fingerprint_script: cat .cirrus.yml + populate_script: + - | + md C:\tools + md C:\tools\archive + $start_time = Get-Date + cd C:\tools + bitsadmin /transfer msys_download /dynamic /download /priority FOREGROUND https://github.com/msys2/msys2-installer/releases/download/2020-09-03/msys2-base-x86_64-20200903.sfx.exe C:\tools\base.exe + Write-Output "Download time taken: $((Get-Date).Subtract($start_time).Seconds) second(s)" + C:\tools\base.exe -y + ((Get-Content -path C:\tools\msys64\etc\\post-install\\07-pacman-key.post -Raw) -replace '--refresh-keys', '--version') | Set-Content -Path C:\tools\msys64\etc\\post-install\\07-pacman-key.post + C:\tools\msys64\usr\bin\bash.exe -lc "sed -i 's/^CheckSpace/#CheckSpace/g' /etc/pacman.conf" + C:\tools\msys64\usr\bin\bash.exe -lc "export" + C:\tools\msys64\usr\bin\bash.exe -lc "grep -rl 'repo.msys2.org/' /etc/pacman.d/mirrorlist.* | xargs sed -i 's/repo.msys2.org\//mirrors.tuna.tsinghua.edu.cn\/msys2\//g'" + C:\tools\msys64\usr\bin\pacman.exe --noconfirm -Sy + echo Y | C:\tools\msys64\usr\bin\pacman.exe --noconfirm -Suu --overwrite=* + taskkill /F /FI "MODULES eq msys-2.0.dll" + tasklist + C:\tools\msys64\usr\bin\bash.exe -lc "mv -f /etc/pacman.conf.pacnew /etc/pacman.conf || true" + C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Suu --overwrite=*" + C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed \ + diffutils git grep make pkg-config sed \ + mingw-w64-x86_64-python \ + mingw-w64-x86_64-python-setuptools \ + mingw-w64-x86_64-toolchain \ + mingw-w64-x86_64-SDL2 \ + mingw-w64-x86_64-SDL2_image \ + mingw-w64-x86_64-gtk3 \ + mingw-w64-x86_64-glib2 \ + mingw-w64-x86_64-ninja \ + mingw-w64-x86_64-jemalloc \ + mingw-w64-x86_64-lzo2 \ + mingw-w64-x86_64-zstd \ + mingw-w64-x86_64-libjpeg-turbo \ + mingw-w64-x86_64-pixman \ + mingw-w64-x86_64-libgcrypt \ + mingw-w64-x86_64-libpng \ + mingw-w64-x86_64-libssh \ + mingw-w64-x86_64-libxml2 \ + mingw-w64-x86_64-snappy \ + mingw-w64-x86_64-libusb \ + mingw-w64-x86_64-usbredir \ + mingw-w64-x86_64-libtasn1 \ + mingw-w64-x86_64-nettle \ + mingw-w64-x86_64-cyrus-sasl \ + mingw-w64-x86_64-curl \ + mingw-w64-x86_64-gnutls \ + " + C:\tools\msys64\usr\bin\bash.exe -lc "rm -rf /var/cache/pacman/pkg/*" + cd C:\tools\msys64 + echo "Start archive" + cmd /C "7z a -ttar . -so | 7z a -txz -simsys2-x86_64.tar C:\tools\archive\msys2-x86_64.tar.xz" install_script: - - C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && - curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - - C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && - curl -O http://repo.msys2.org/msys/x86_64/msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz.sig" - - C:\tools\msys64\usr\bin\bash.exe -lc "cd /c/tools && - pacman -U --noconfirm msys2-keyring-r21.b39fb11-1-any.pkg.tar.xz" - - C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Sy" - - C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed - bash pacman pacman-mirrors msys2-runtime" - - taskkill /F /IM gpg-agent.exe - - C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -Su" - - C:\tools\msys64\usr\bin\bash.exe -lc "pacman --noconfirm -S --needed - base-devel - git - mingw-w64-x86_64-python - mingw-w64-x86_64-python-setuptools - mingw-w64-x86_64-toolchain - mingw-w64-x86_64-capstone - mingw-w64-x86_64-SDL2 - mingw-w64-x86_64-SDL2_image - mingw-w64-x86_64-gtk3 - mingw-w64-x86_64-glib2 - mingw-w64-x86_64-ninja - mingw-w64-x86_64-make - mingw-w64-x86_64-lzo2 - mingw-w64-x86_64-zstd - mingw-w64-x86_64-libjpeg-turbo - mingw-w64-x86_64-pixman - mingw-w64-x86_64-libgcrypt - mingw-w64-x86_64-libpng - mingw-w64-x86_64-libssh - mingw-w64-x86_64-libxml2 - mingw-w64-x86_64-snappy - mingw-w64-x86_64-libusb - mingw-w64-x86_64-usbredir - mingw-w64-x86_64-libtasn1 - mingw-w64-x86_64-nettle - mingw-w64-x86_64-cyrus-sasl - mingw-w64-x86_64-curl - mingw-w64-x86_64-gnutls - mingw-w64-x86_64-zstd" + - | + cd C:\tools + cmd /C "7z x C:\tools\archive\msys2-x86_64.tar.xz -so | 7z x -aoa -simsys2-x86_64.tar -ttar -omsys64" + C:\tools\msys64\usr\bin\bash.exe -lc "export" + script: - C:\tools\msys64\usr\bin\bash.exe -lc "mkdir build" - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && ../configure - --python=python3 --ninja=ninja - --target-list-exclude=i386-softmmu,arm-softmmu,ppc-softmmu,mips-softmmu" - - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make -j$NUMBER_OF_PROCESSORS" + --python=python3 --ninja=ninja" + - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make -j8" test_script: - C:\tools\msys64\usr\bin\bash.exe -lc "cd build && make V=1 check" diff --git a/.mailmap b/.mailmap index b914c9e290..663819fb01 100644 --- a/.mailmap +++ b/.mailmap @@ -85,6 +85,7 @@ Christophe Lyon <christophe.lyon@st.com> Collin L. Walling <walling@linux.ibm.com> Daniel P. Berrangé <berrange@redhat.com> Eduardo Otubo <otubo@redhat.com> +Erik Smit <erik.lucas.smit@gmail.com> Fabrice Desclaux <fabrice.desclaux@cea.fr> Fernando Luis Vázquez Cao <fernando_b1@lab.ntt.co.jp> Fernando Luis Vázquez Cao <fernando@oss.ntt.co.jp> @@ -142,6 +143,7 @@ Roger Pau Monné <roger.pau@citrix.com> Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp> Shin'ichiro Kawasaki <shinichiro.kawasaki@wdc.com> Sochin Jiang <sochin.jiang@huawei.com> +Stefan Berger <stefanb@linux.vnet.ibm.com> <stefanb@linux.ibm.com> Takashi Yoshii <takasi-y@ops.dti.ne.jp> Thomas Huth <thuth@redhat.com> Thomas Knych <thomaswk@google.com> diff --git a/block/nbd.c b/block/nbd.c index 9daf003bea..4548046cd7 100644 --- a/block/nbd.c +++ b/block/nbd.c @@ -122,6 +122,8 @@ typedef struct BDRVNBDState { Error *connect_err; bool wait_in_flight; + QEMUTimer *reconnect_delay_timer; + NBDClientRequest requests[MAX_NBD_REQUESTS]; NBDReply reply; BlockDriverState *bs; @@ -188,10 +190,49 @@ static void nbd_recv_coroutines_wake_all(BDRVNBDState *s) } } +static void reconnect_delay_timer_del(BDRVNBDState *s) +{ + if (s->reconnect_delay_timer) { + timer_del(s->reconnect_delay_timer); + timer_free(s->reconnect_delay_timer); + s->reconnect_delay_timer = NULL; + } +} + +static void reconnect_delay_timer_cb(void *opaque) +{ + BDRVNBDState *s = opaque; + + if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + s->state = NBD_CLIENT_CONNECTING_NOWAIT; + while (qemu_co_enter_next(&s->free_sema, NULL)) { + /* Resume all queued requests */ + } + } + + reconnect_delay_timer_del(s); +} + +static void reconnect_delay_timer_init(BDRVNBDState *s, uint64_t expire_time_ns) +{ + if (s->state != NBD_CLIENT_CONNECTING_WAIT) { + return; + } + + assert(!s->reconnect_delay_timer); + s->reconnect_delay_timer = aio_timer_new(bdrv_get_aio_context(s->bs), + QEMU_CLOCK_REALTIME, + SCALE_NS, + reconnect_delay_timer_cb, s); + timer_mod(s->reconnect_delay_timer, expire_time_ns); +} + static void nbd_client_detach_aio_context(BlockDriverState *bs) { BDRVNBDState *s = (BDRVNBDState *)bs->opaque; + /* Timer is deleted in nbd_client_co_drain_begin() */ + assert(!s->reconnect_delay_timer); qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); } @@ -242,6 +283,13 @@ static void coroutine_fn nbd_client_co_drain_begin(BlockDriverState *bs) } nbd_co_establish_connection_cancel(bs, false); + + reconnect_delay_timer_del(s); + + if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + s->state = NBD_CLIENT_CONNECTING_NOWAIT; + qemu_co_queue_restart_all(&s->free_sema); + } } static void coroutine_fn nbd_client_co_drain_end(BlockDriverState *bs) @@ -544,7 +592,7 @@ static coroutine_fn void nbd_reconnect_attempt(BDRVNBDState *s) /* Finalize previous connection if any */ if (s->ioc) { - nbd_client_detach_aio_context(s->bs); + qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); @@ -588,21 +636,17 @@ out: static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s) { - uint64_t start_time_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); - uint64_t delay_ns = s->reconnect_delay * NANOSECONDS_PER_SECOND; uint64_t timeout = 1 * NANOSECONDS_PER_SECOND; uint64_t max_timeout = 16 * NANOSECONDS_PER_SECOND; + if (s->state == NBD_CLIENT_CONNECTING_WAIT) { + reconnect_delay_timer_init(s, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + + s->reconnect_delay * NANOSECONDS_PER_SECOND); + } + nbd_reconnect_attempt(s); while (nbd_client_connecting(s)) { - if (s->state == NBD_CLIENT_CONNECTING_WAIT && - qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - start_time_ns > delay_ns) - { - s->state = NBD_CLIENT_CONNECTING_NOWAIT; - qemu_co_queue_restart_all(&s->free_sema); - } - if (s->drained) { bdrv_dec_in_flight(s->bs); s->wait_drained_end = true; @@ -617,6 +661,9 @@ static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s) } else { qemu_co_sleep_ns_wakeable(QEMU_CLOCK_REALTIME, timeout, &s->connection_co_sleep_ns_state); + if (s->drained) { + continue; + } if (timeout < max_timeout) { timeout *= 2; } @@ -624,6 +671,8 @@ static coroutine_fn void nbd_co_reconnect_loop(BDRVNBDState *s) nbd_reconnect_attempt(s); } + + reconnect_delay_timer_del(s); } static coroutine_fn void nbd_connection_entry(void *opaque) @@ -702,7 +751,7 @@ static coroutine_fn void nbd_connection_entry(void *opaque) s->connection_co = NULL; if (s->ioc) { - nbd_client_detach_aio_context(s->bs); + qio_channel_detach_aio_context(QIO_CHANNEL(s->ioc)); object_unref(OBJECT(s->sioc)); s->sioc = NULL; object_unref(OBJECT(s->ioc)); diff --git a/configure b/configure index 28df227db5..b553288c5e 100755 --- a/configure +++ b/configure @@ -7209,6 +7209,7 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \ -Dwerror=$(if test "$werror" = yes; then echo true; else echo false; fi) \ -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \ -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \ + -Db_staticpic=$(if test "$pie" = yes; then echo true; else echo false; fi) \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \ -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \ diff --git a/contrib/gitdm/domain-map b/contrib/gitdm/domain-map index dd79147c76..0074da618f 100644 --- a/contrib/gitdm/domain-map +++ b/contrib/gitdm/domain-map @@ -5,10 +5,13 @@ # amd.com AMD +baidu.com Baidu +bytedance.com ByteDance cmss.chinamobile.com China Mobile citrix.com Citrix -greensocs.com GreenSocs fujitsu.com Fujitsu +google.com Google +greensocs.com GreenSocs huawei.com Huawei ibm.com IBM igalia.com Igalia @@ -16,13 +19,18 @@ intel.com Intel linaro.org Linaro microsoft.com Microsoft nokia.com Nokia +nuviainc.com NUVIA oracle.com Oracle proxmox.com Proxmox +quicinc.com Qualcomm Innovation Center redhat.com Red Hat rt-rk.com RT-RK siemens.com Siemens sifive.com SiFive +suse.com SUSE suse.de SUSE virtuozzo.com Virtuozzo wdc.com Western Digital xilinx.com Xilinx +yadro.com YADRO +yandex-team.ru Yandex diff --git a/contrib/gitdm/group-map-academics b/contrib/gitdm/group-map-academics index 08f9d81d13..bf3c894821 100644 --- a/contrib/gitdm/group-map-academics +++ b/contrib/gitdm/group-map-academics @@ -12,3 +12,7 @@ ispras.ru # Columbia University cs.columbia.edu cota@braap.org + +uni-paderborn.de +edu +edu.cn diff --git a/contrib/gitdm/group-map-individuals b/contrib/gitdm/group-map-individuals index cf8a2ce367..641169fa63 100644 --- a/contrib/gitdm/group-map-individuals +++ b/contrib/gitdm/group-map-individuals @@ -16,3 +16,10 @@ aurelien@aurel32.net balaton@eik.bme.hu e.emanuelegiuseppe@gmail.com andrew.smirnov@gmail.com +sw@weilnetz.de +deller@gmx.de +fthain@telegraphics.com.au +vr_qemu@t-online.de +nieklinnenbank@gmail.com +devnexen@gmail.com +pauldzim@gmail.com diff --git a/contrib/gitdm/group-map-redhat b/contrib/gitdm/group-map-redhat index d15db2d35e..02507b7b53 100644 --- a/contrib/gitdm/group-map-redhat +++ b/contrib/gitdm/group-map-redhat @@ -6,3 +6,4 @@ david@gibson.dropbear.id.au laurent@vivier.eu pjp@fedoraproject.org armbru@pond.sub.org +nirsof@gmail.com diff --git a/contrib/plugins/hotblocks.c b/contrib/plugins/hotblocks.c index 3942a2ca54..37435a3fc7 100644 --- a/contrib/plugins/hotblocks.c +++ b/contrib/plugins/hotblocks.c @@ -102,7 +102,7 @@ static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { ExecCount *cnt; uint64_t pc = qemu_plugin_tb_vaddr(tb); - unsigned long insns = qemu_plugin_tb_n_insns(tb); + size_t insns = qemu_plugin_tb_n_insns(tb); uint64_t hash = pc ^ insns; g_mutex_lock(&lock); diff --git a/hw/ide/core.c b/hw/ide/core.c index 0e32abd779..693b352d5e 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -2289,8 +2289,8 @@ void ide_ctrl_write(void *opaque, uint32_t addr, uint32_t val) s = &bus->ifs[i]; s->status |= BUSY_STAT; } - aio_bh_schedule_oneshot(qemu_get_aio_context(), - ide_bus_perform_srst, bus); + replay_bh_schedule_oneshot_event(qemu_get_aio_context(), + ide_bus_perform_srst, bus); } bus->cmd = val; diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c index 2f7b2c9592..7c11fb3d44 100644 --- a/hw/misc/mips_cpc.c +++ b/hw/misc/mips_cpc.c @@ -38,6 +38,7 @@ static void mips_cpu_reset_async_work(CPUState *cs, run_on_cpu_data data) MIPSCPCState *cpc = (MIPSCPCState *) data.host_ptr; cpu_reset(cs); + cs->halted = 0; cpc->vp_running |= 1ULL << cs->cpu_index; } diff --git a/nbd/server.c b/nbd/server.c index f74766add7..e75c825879 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2018 Red Hat, Inc. + * Copyright (C) 2016-2020 Red Hat, Inc. * Copyright (C) 2005 Anthony Liguori <anthony@codemonkey.ws> * * Network Block Device Server Side @@ -301,10 +301,11 @@ nbd_opt_invalid(NBDClient *client, Error **errp, const char *fmt, ...) } /* Read size bytes from the unparsed payload of the current option. + * If @check_nul, require that no NUL bytes appear in buffer. * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, - Error **errp) + bool check_nul, Error **errp) { if (size > client->optlen) { return nbd_opt_invalid(client, errp, @@ -312,7 +313,16 @@ static int nbd_opt_read(NBDClient *client, void *buffer, size_t size, nbd_opt_lookup(client->opt)); } client->optlen -= size; - return qio_channel_read_all(client->ioc, buffer, size, errp) < 0 ? -EIO : 1; + if (qio_channel_read_all(client->ioc, buffer, size, errp) < 0) { + return -EIO; + } + + if (check_nul && strnlen(buffer, size) != size) { + return nbd_opt_invalid(client, errp, + "Unexpected embedded NUL in option %s", + nbd_opt_lookup(client->opt)); + } + return 1; } /* Drop size bytes from the unparsed payload of the current option. @@ -349,7 +359,7 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, g_autofree char *local_name = NULL; *name = NULL; - ret = nbd_opt_read(client, &len, sizeof(len), errp); + ret = nbd_opt_read(client, &len, sizeof(len), false, errp); if (ret <= 0) { return ret; } @@ -361,7 +371,7 @@ static int nbd_opt_read_name(NBDClient *client, char **name, uint32_t *length, } local_name = g_malloc(len + 1); - ret = nbd_opt_read(client, local_name, len, errp); + ret = nbd_opt_read(client, local_name, len, true, errp); if (ret <= 0) { return ret; } @@ -556,7 +566,7 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) NBDExport *exp; uint16_t requests; uint16_t request; - uint32_t namelen; + uint32_t namelen = 0; bool sendname = false; bool blocksize = false; uint32_t sizes[3]; @@ -576,14 +586,14 @@ static int nbd_negotiate_handle_info(NBDClient *client, Error **errp) } trace_nbd_negotiate_handle_export_name_request(name); - rc = nbd_opt_read(client, &requests, sizeof(requests), errp); + rc = nbd_opt_read(client, &requests, sizeof(requests), false, errp); if (rc <= 0) { return rc; } requests = be16_to_cpu(requests); trace_nbd_negotiate_handle_info_requests(requests); while (requests--) { - rc = nbd_opt_read(client, &request, sizeof(request), errp); + rc = nbd_opt_read(client, &request, sizeof(request), false, errp); if (rc <= 0) { return rc; } @@ -787,135 +797,95 @@ static int nbd_negotiate_send_meta_context(NBDClient *client, return qio_channel_writev_all(client->ioc, iov, 2, errp) < 0 ? -EIO : 0; } -/* Read strlen(@pattern) bytes, and set @match to true if they match @pattern. - * @match is never set to false. - * - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. - * - * Note: return code = 1 doesn't mean that we've read exactly @pattern. - * It only means that there are no errors. +/* + * Return true if @query matches @pattern, or if @query is empty when + * the @client is performing _LIST_. */ -static int nbd_meta_pattern(NBDClient *client, const char *pattern, bool *match, - Error **errp) +static bool nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, + const char *query) { - int ret; - char *query; - size_t len = strlen(pattern); - - assert(len); - - query = g_malloc(len); - ret = nbd_opt_read(client, query, len, errp); - if (ret <= 0) { - g_free(query); - return ret; + if (!*query) { + trace_nbd_negotiate_meta_query_parse("empty"); + return client->opt == NBD_OPT_LIST_META_CONTEXT; } - - if (strncmp(query, pattern, len) == 0) { + if (strcmp(query, pattern) == 0) { trace_nbd_negotiate_meta_query_parse(pattern); - *match = true; - } else { - trace_nbd_negotiate_meta_query_skip("pattern not matched"); + return true; } - g_free(query); - - return 1; + trace_nbd_negotiate_meta_query_skip("pattern not matched"); + return false; } /* - * Read @len bytes, and set @match to true if they match @pattern, or if @len - * is 0 and the client is performing _LIST_. @match is never set to false. - * - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. - * - * Note: return code = 1 doesn't mean that we've read exactly @pattern. - * It only means that there are no errors. + * Return true and adjust @str in place if it begins with @prefix. */ -static int nbd_meta_empty_or_pattern(NBDClient *client, const char *pattern, - uint32_t len, bool *match, Error **errp) +static bool nbd_strshift(const char **str, const char *prefix) { - if (len == 0) { - if (client->opt == NBD_OPT_LIST_META_CONTEXT) { - *match = true; - } - trace_nbd_negotiate_meta_query_parse("empty"); - return 1; - } + size_t len = strlen(prefix); - if (len != strlen(pattern)) { - trace_nbd_negotiate_meta_query_skip("different lengths"); - return nbd_opt_skip(client, len, errp); + if (strncmp(*str, prefix, len) == 0) { + *str += len; + return true; } - - return nbd_meta_pattern(client, pattern, match, errp); + return false; } /* nbd_meta_base_query * * Handle queries to 'base' namespace. For now, only the base:allocation - * context is available. 'len' is the amount of text remaining to be read from - * the current name, after the 'base:' portion has been stripped. - * - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. + * context is available. Return true if @query has been handled. */ -static int nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *meta, - uint32_t len, Error **errp) +static bool nbd_meta_base_query(NBDClient *client, NBDExportMetaContexts *meta, + const char *query) { - return nbd_meta_empty_or_pattern(client, "allocation", len, - &meta->base_allocation, errp); + if (!nbd_strshift(&query, "base:")) { + return false; + } + trace_nbd_negotiate_meta_query_parse("base:"); + + if (nbd_meta_empty_or_pattern(client, "allocation", query)) { + meta->base_allocation = true; + } + return true; } -/* nbd_meta_bitmap_query +/* nbd_meta_qemu_query * - * Handle query to 'qemu:' namespace. - * @len is the amount of text remaining to be read from the current name, after - * the 'qemu:' portion has been stripped. - * - * Return -errno on I/O error, 0 if option was completely handled by - * sending a reply about inconsistent lengths, or 1 on success. */ -static int nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta, - uint32_t len, Error **errp) + * Handle queries to 'qemu' namespace. For now, only the qemu:dirty-bitmap: + * context is available. Return true if @query has been handled. + */ +static bool nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta, + const char *query) { - bool dirty_bitmap = false; - size_t dirty_bitmap_len = strlen("dirty-bitmap:"); - int ret; - - if (!meta->exp->export_bitmap) { - trace_nbd_negotiate_meta_query_skip("no dirty-bitmap exported"); - return nbd_opt_skip(client, len, errp); + if (!nbd_strshift(&query, "qemu:")) { + return false; } + trace_nbd_negotiate_meta_query_parse("qemu:"); - if (len == 0) { + if (!*query) { if (client->opt == NBD_OPT_LIST_META_CONTEXT) { - meta->bitmap = true; + meta->bitmap = !!meta->exp->export_bitmap; } trace_nbd_negotiate_meta_query_parse("empty"); - return 1; - } - - if (len < dirty_bitmap_len) { - trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:"); - return nbd_opt_skip(client, len, errp); + return true; } - len -= dirty_bitmap_len; - ret = nbd_meta_pattern(client, "dirty-bitmap:", &dirty_bitmap, errp); - if (ret <= 0) { - return ret; - } - if (!dirty_bitmap) { - trace_nbd_negotiate_meta_query_skip("not dirty-bitmap:"); - return nbd_opt_skip(client, len, errp); + if (nbd_strshift(&query, "dirty-bitmap:")) { + trace_nbd_negotiate_meta_query_parse("dirty-bitmap:"); + if (!meta->exp->export_bitmap) { + trace_nbd_negotiate_meta_query_skip("no dirty-bitmap exported"); + return true; + } + if (nbd_meta_empty_or_pattern(client, + meta->exp->export_bitmap_context + + strlen("qemu:dirty-bitmap:"), query)) { + meta->bitmap = true; + } + return true; } - trace_nbd_negotiate_meta_query_parse("dirty-bitmap:"); - - return nbd_meta_empty_or_pattern( - client, meta->exp->export_bitmap_context + - strlen("qemu:dirty_bitmap:"), len, &meta->bitmap, errp); + trace_nbd_negotiate_meta_query_skip("not dirty-bitmap"); + return true; } /* nbd_negotiate_meta_query @@ -925,25 +895,16 @@ static int nbd_meta_qemu_query(NBDClient *client, NBDExportMetaContexts *meta, * * The only supported namespaces are 'base' and 'qemu'. * - * The function aims not wasting time and memory to read long unknown namespace - * names. - * * Return -errno on I/O error, 0 if option was completely handled by * sending a reply about inconsistent lengths, or 1 on success. */ static int nbd_negotiate_meta_query(NBDClient *client, NBDExportMetaContexts *meta, Error **errp) { - /* - * Both 'qemu' and 'base' namespaces have length = 5 including a - * colon. If another length namespace is later introduced, this - * should certainly be refactored. - */ int ret; - size_t ns_len = 5; - char ns[5]; + g_autofree char *query = NULL; uint32_t len; - ret = nbd_opt_read(client, &len, sizeof(len), errp); + ret = nbd_opt_read(client, &len, sizeof(len), false, errp); if (ret <= 0) { return ret; } @@ -953,27 +914,23 @@ static int nbd_negotiate_meta_query(NBDClient *client, trace_nbd_negotiate_meta_query_skip("length too long"); return nbd_opt_skip(client, len, errp); } - if (len < ns_len) { - trace_nbd_negotiate_meta_query_skip("length too short"); - return nbd_opt_skip(client, len, errp); - } - len -= ns_len; - ret = nbd_opt_read(client, ns, ns_len, errp); + query = g_malloc(len + 1); + ret = nbd_opt_read(client, query, len, true, errp); if (ret <= 0) { return ret; } + query[len] = '\0'; - if (!strncmp(ns, "base:", ns_len)) { - trace_nbd_negotiate_meta_query_parse("base:"); - return nbd_meta_base_query(client, meta, len, errp); - } else if (!strncmp(ns, "qemu:", ns_len)) { - trace_nbd_negotiate_meta_query_parse("qemu:"); - return nbd_meta_qemu_query(client, meta, len, errp); + if (nbd_meta_base_query(client, meta, query)) { + return 1; + } + if (nbd_meta_qemu_query(client, meta, query)) { + return 1; } trace_nbd_negotiate_meta_query_skip("unknown namespace"); - return nbd_opt_skip(client, len, errp); + return 1; } /* nbd_negotiate_meta_queries @@ -1016,7 +973,7 @@ static int nbd_negotiate_meta_queries(NBDClient *client, "export '%s' not present", sane_name); } - ret = nbd_opt_read(client, &nb_queries, sizeof(nb_queries), errp); + ret = nbd_opt_read(client, &nb_queries, sizeof(nb_queries), false, errp); if (ret <= 0) { return ret; } diff --git a/plugins/loader.c b/plugins/loader.c index 685d334e1a..8ac5dbc20f 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -235,6 +235,7 @@ static int plugin_load(struct qemu_plugin_desc *desc, const qemu_info_t *info) return rc; err_symbol: + g_module_close(ctx->handle); err_dlopen: qemu_vfree(ctx); return 1; diff --git a/qemu-nbd.c b/qemu-nbd.c index bacb69b089..bc644a0670 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -154,13 +154,13 @@ QEMU_COPYRIGHT "\n" , name); } -#if HAVE_NBD_DEVICE +#ifdef CONFIG_POSIX static void termsig_handler(int signum) { qatomic_cmpxchg(&state, RUNNING, TERMINATE); qemu_notify_event(); } -#endif /* HAVE_NBD_DEVICE */ +#endif /* CONFIG_POSIX */ static int qemu_nbd_client_list(SocketAddress *saddr, QCryptoTLSCreds *tls, const char *hostname) @@ -581,17 +581,18 @@ int main(int argc, char **argv) const char *pid_file_name = NULL; BlockExportOptions *export_opts; -#if HAVE_NBD_DEVICE - /* The client thread uses SIGTERM to interrupt the server. A signal - * handler ensures that "qemu-nbd -v -c" exits with a nice status code. +#ifdef CONFIG_POSIX + /* + * Exit gracefully on various signals, which includes SIGTERM used + * by 'qemu-nbd -v -c'. */ struct sigaction sa_sigterm; memset(&sa_sigterm, 0, sizeof(sa_sigterm)); sa_sigterm.sa_handler = termsig_handler; sigaction(SIGTERM, &sa_sigterm, NULL); -#endif /* HAVE_NBD_DEVICE */ + sigaction(SIGINT, &sa_sigterm, NULL); + sigaction(SIGHUP, &sa_sigterm, NULL); -#ifdef CONFIG_POSIX signal(SIGPIPE, SIG_IGN); #endif diff --git a/tests/acceptance/machine_rx_gdbsim.py b/tests/acceptance/machine_rx_gdbsim.py index 0c72506028..32b737b6d8 100644 --- a/tests/acceptance/machine_rx_gdbsim.py +++ b/tests/acceptance/machine_rx_gdbsim.py @@ -22,6 +22,7 @@ class RxGdbSimMachine(Test): timeout = 30 KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' + @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab') def test_uboot(self): """ U-Boot and checks that the console is operational. diff --git a/tests/docker/dockerfiles/centos8.docker b/tests/docker/dockerfiles/centos8.docker index f435616d6a..0fc2697491 100644 --- a/tests/docker/dockerfiles/centos8.docker +++ b/tests/docker/dockerfiles/centos8.docker @@ -8,6 +8,7 @@ ENV PACKAGES \ dbus-daemon \ gcc \ gcc-c++ \ + genisoimage \ gettext \ git \ glib2-devel \ diff --git a/tests/docker/dockerfiles/debian-amd64.docker b/tests/docker/dockerfiles/debian-amd64.docker index d2500dcff1..314c6bae83 100644 --- a/tests/docker/dockerfiles/debian-amd64.docker +++ b/tests/docker/dockerfiles/debian-amd64.docker @@ -14,6 +14,7 @@ RUN apt update && \ RUN apt update && \ DEBIAN_FRONTEND=noninteractive eatmydata \ apt install -y --no-install-recommends \ + genisoimage \ libbz2-dev \ liblzo2-dev \ libgcrypt20-dev \ diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index ec783418c8..85c975543d 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -15,6 +15,7 @@ ENV PACKAGES \ findutils \ gcc \ gcc-c++ \ + genisoimage \ gettext \ git \ glib2-devel \ diff --git a/tests/docker/dockerfiles/ubuntu2004.docker b/tests/docker/dockerfiles/ubuntu2004.docker index cafe8443fb..f4b9556b9e 100644 --- a/tests/docker/dockerfiles/ubuntu2004.docker +++ b/tests/docker/dockerfiles/ubuntu2004.docker @@ -3,6 +3,7 @@ ENV PACKAGES flex bison \ ccache \ clang-10\ gcc \ + genisoimage \ gettext \ git \ glusterfs-common \ diff --git a/tests/plugin/bb.c b/tests/plugin/bb.c index e4cc7fdd6e..de09bdde4e 100644 --- a/tests/plugin/bb.c +++ b/tests/plugin/bb.c @@ -72,7 +72,7 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata) CPUCount *count = max_cpus ? g_ptr_array_index(counts, cpu_index) : &inline_count; - unsigned long n_insns = (unsigned long)udata; + uintptr_t n_insns = (uintptr_t)udata; g_mutex_lock(&count->lock); count->insn_count += n_insns; count->bb_count++; @@ -81,7 +81,7 @@ static void vcpu_tb_exec(unsigned int cpu_index, void *udata) static void vcpu_tb_trans(qemu_plugin_id_t id, struct qemu_plugin_tb *tb) { - unsigned long n_insns = qemu_plugin_tb_n_insns(tb); + size_t n_insns = qemu_plugin_tb_n_insns(tb); if (do_inline) { qemu_plugin_register_vcpu_tb_exec_inline(tb, QEMU_PLUGIN_INLINE_ADD_U64, |