From nobody Fri May 3 15:29:35 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1544817859533680.4799116147257; Fri, 14 Dec 2018 12:04:19 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5278E40250; Fri, 14 Dec 2018 20:04:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 9EC6D60BF6; Fri, 14 Dec 2018 20:04:15 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 209EF12E30; Fri, 14 Dec 2018 20:04:13 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id wBEK4Bvq003357 for ; Fri, 14 Dec 2018 15:04:11 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9525D600C1; Fri, 14 Dec 2018 20:04:11 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-48.brq.redhat.com [10.40.204.48]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0595C600C0 for ; Fri, 14 Dec 2018 20:04:05 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Fri, 14 Dec 2018 21:04:03 +0100 Message-Id: <898457cb1fd00d358975b0844fe20fd6ec2639c3.1544817788.git.mprivozn@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH v2] Drop UML driver X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Fri, 14 Dec 2018 20:04:18 +0000 (UTC) Content-Type: text/plain; charset="utf-8" The driver is unmaintained, untested and severely broken for quite some time now. Since nobody even reported any issue with it let us drop it. Signed-off-by: Michal Privoznik --- diff to v2: - don't drop UML from RNG schema nor config parser as suggested by Dan configure.ac | 4 - docs/aclpolkit.html.in | 4 - docs/drivers.html.in | 1 - docs/drvuml.html.in | 93 - docs/formatcaps.html.in | 3 - docs/formatdomain.html.in | 6 +- docs/formatdomaincaps.html.in | 1 - docs/formatnwfilter.html.in | 2 +- docs/news.xml | 14 + docs/schemas/capability.rng | 4 +- docs/schemas/domaincommon.rng | 6 +- include/libvirt/virterror.h | 2 +- libvirt.spec.in | 65 +- m4/virt-driver-uml.m4 | 54 - mingw-libvirt.spec.in | 1 - po/POTFILES | 2 - src/Makefile.am | 1 - src/README | 3 +- src/locking/lock_driver.h | 2 +- src/remote/Makefile.inc.am | 1 - src/remote/libvirtd.uml.logrotate.in | 8 - src/remote/remote_daemon.c | 4 - src/uml/Makefile.inc.am | 48 - src/uml/uml_conf.c | 481 ----- src/uml/uml_conf.h | 82 - src/uml/uml_driver.c | 2835 -------------------------- src/uml/uml_driver.h | 29 - tests/domaincapsschemadata/basic.xml | 25 - tests/domaincapstest.c | 2 - tests/objectlocking.ml | 3 - tests/virdrivermoduletest.c | 3 - tools/virsh.c | 3 - 32 files changed, 28 insertions(+), 3764 deletions(-) delete mode 100644 docs/drvuml.html.in delete mode 100644 m4/virt-driver-uml.m4 delete mode 100644 src/remote/libvirtd.uml.logrotate.in delete mode 100644 src/uml/Makefile.inc.am delete mode 100644 src/uml/uml_conf.c delete mode 100644 src/uml/uml_conf.h delete mode 100644 src/uml/uml_driver.c delete mode 100644 src/uml/uml_driver.h delete mode 100644 tests/domaincapsschemadata/basic.xml diff --git a/configure.ac b/configure.ac index 8c89ff365b..ac52189dff 100644 --- a/configure.ac +++ b/configure.ac @@ -225,7 +225,6 @@ if test "$with_libvirtd" =3D "no" ; then with_qemu=3Dno with_lxc=3Dno with_libxl=3Dno - with_uml=3Dno with_vbox=3Dno fi =20 @@ -445,7 +444,6 @@ LIBVIRT_DRIVER_ARG_VBOX LIBVIRT_DRIVER_ARG_LXC LIBVIRT_DRIVER_ARG_VZ LIBVIRT_DRIVER_ARG_BHYVE -LIBVIRT_DRIVER_ARG_UML LIBVIRT_DRIVER_ARG_ESX LIBVIRT_DRIVER_ARG_HYPERV LIBVIRT_DRIVER_ARG_TEST @@ -464,7 +462,6 @@ LIBVIRT_DRIVER_CHECK_VBOX LIBVIRT_DRIVER_CHECK_LXC LIBVIRT_DRIVER_CHECK_VZ LIBVIRT_DRIVER_CHECK_BHYVE -LIBVIRT_DRIVER_CHECK_UML LIBVIRT_DRIVER_CHECK_ESX LIBVIRT_DRIVER_CHECK_HYPERV LIBVIRT_DRIVER_CHECK_TEST @@ -947,7 +944,6 @@ AC_MSG_NOTICE([]) AC_MSG_NOTICE([Drivers]) AC_MSG_NOTICE([]) LIBVIRT_DRIVER_RESULT_QEMU -LIBVIRT_DRIVER_RESULT_UML LIBVIRT_DRIVER_RESULT_OPENVZ LIBVIRT_DRIVER_RESULT_VMWARE LIBVIRT_DRIVER_RESULT_VBOX diff --git a/docs/aclpolkit.html.in b/docs/aclpolkit.html.in index ac54f125da..2cf1f9b5a5 100644 --- a/docs/aclpolkit.html.in +++ b/docs/aclpolkit.html.in @@ -381,10 +381,6 @@ storage storage - - uml - UML - vbox VBOX diff --git a/docs/drivers.html.in b/docs/drivers.html.in index c94144aa41..a66651df2f 100644 --- a/docs/drivers.html.in +++ b/docs/drivers.html.in @@ -29,7 +29,6 @@
  • OpenVZ
  • QEMU
  • Test - Used for te= sting
  • -
  • UML - User Mode Lin= ux
  • VirtualBox
  • VMware ESX
  • VMware Workstation/Player=
  • diff --git a/docs/drvuml.html.in b/docs/drvuml.html.in deleted file mode 100644 index 0860db7dcf..0000000000 --- a/docs/drvuml.html.in +++ /dev/null @@ -1,93 +0,0 @@ - - - - -

    User Mode Linux driver

    - -

    - The UML driver for libvirt allows use and management of paravirtualized - guests built for User Mode Linux. UML requires no special support in - the host kernel, so can be used by any user of any linux system, provi= ded - they have enough free RAM for their guest's needs, though there are - certain restrictions on network connectivity unless the administrator - has pre-created TAP devices. -

    - -

    Project Links

    - - - -

    Connections to UML driver

    - -

    - The libvirt UML driver follows the QEMU driver in providing two - types of connection. There is one privileged instance per host, - which runs as root. This is called the "system" instance, and allows - full use of all host resources. Then, there is a per-user unprivileged - "session", instance. This has more restricted capabilities, and may - require the host administrator to setup certain resources ahead of - time to allow full integration with the network. Example connection - URIs are -

    - -
    -uml:///session                       (local access to per-user instance)
    -uml+unix:///session                  (local access to per-user instance)
    -
    -uml:///system                        (local access to system instance)
    -uml+unix:///system                   (local access to system instance)
    -uml://example.com/system             (remote access, TLS/x509)
    -uml+tcp://example.com/system         (remote access, SASl/Kerberos)
    -uml+ssh://root@example.com/system    (remote access, SSH tunnelled)
    -
    - -

    Example XML configuration

    - -

    - User mode Linux driver only supports directly kernel boot at - this time. A future driver enhancement may allow a paravirt - bootloader in a similar style to Xen's pygrub. For now though, - the UML kernel must be stored on the host and referenced - explicitly in the "os" element. Since UML is a paravirtualized - technology, the kernel "type" is set to "uml" -

    - -

    - There is not yet support for networking in the driver, but - disks can be specified in the usual libvirt manner. The main - variation is the target device naming scheme "ubd0", and - bus type of "uml". -

    - -

    - Once booted the primary console is connected to a PTY, and - thus accessible with "virsh console" or equivalent tools -

    - -
    -<domain type=3D'uml'>
    -  <name>demo</name>
    -  <uuid>b4433fc2-a22e-ffb3-0a3d-9c173b395800</uuid>
    -  <memory>500000</memory>
    -  <currentMemory>500000</currentMemory>
    -  <vcpu>1</vcpu>
    -  <os>
    -    <type arch=3D'x86_64'>uml</type>
    -    <kernel>/home/berrange/linux-uml-2.6.26-x86_64</kernel>
    -  </os>
    -  <devices>
    -    <disk type=3D'file' device=3D'disk'>
    -      <source file=3D'/home/berrange/FedoraCore6-AMD64-root_fs'/>
    -      <target dev=3D'ubd0' bus=3D'uml'/>
    -    </disk>
    -    <console type=3D'pty'/>
    -  </devices>
    -</domain>
    -
    - - diff --git a/docs/formatcaps.html.in b/docs/formatcaps.html.in index 86534b2ed2..2a0aa963bb 100644 --- a/docs/formatcaps.html.in +++ b/docs/formatcaps.html.in @@ -87,9 +87,6 @@ =20
    exe
    Container based virtualization
    - -
    uml
    -
    User Mode Linux
    =20 diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 428b0e8bb5..2463261372 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -7161,9 +7161,9 @@ qemu-kvm -net nic,model=3D? /dev/null Valid values for the type attribute are: serial (described below); virtio (usable whenever VirtIO support is available); - xen, lxc, uml and - openvz (available when the corresponding hypervisor is = in - use). sclp and sclplm (usable for s390 and + xen, lxc and openvz + (available when the corresponding hypervisor is in use). + sclp and sclplm (usable for s390 and s390x QEMU guests) are supported for compatibility reasons but should not be used for new guests: use the sclpconsole and sclplmconsole target models, respectively, with the diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in index 9920de4dac..cafd9abbdf 100644 --- a/docs/formatdomaincaps.html.in +++ b/docs/formatdomaincaps.html.in @@ -278,7 +278,6 @@ <value>virtio</value> <value>xen</value> <value>usb</value> - <value>uml</value> <value>sata</value> <value>sd</value> </enum> diff --git a/docs/formatnwfilter.html.in b/docs/formatnwfilter.html.in index b2282b7dee..796c16549d 100644 --- a/docs/formatnwfilter.html.in +++ b/docs/formatnwfilter.html.in @@ -2265,7 +2265,7 @@ echo 3 > /proc/sys/net/netfilter/nf_conntrack_icmp_ti= meout to the incoming and outgoing direction. All this is related to the ftp data traffic originating from TCP port 20 of the VM. This then leads = to the following solution - (since 0.8.5 (QEMU, KVM, UML)): + (since 0.8.5 (QEMU, KVM)):

     <filter name=3D'test-eth0'>
    diff --git a/docs/news.xml b/docs/news.xml
    index 5bdbd34a14..e9b6bb7c65 100644
    --- a/docs/news.xml
    +++ b/docs/news.xml
    @@ -59,6 +59,20 @@
             
           
         
    +    
    + + + Drop UML driver + + + The UML driver was unmaintained and not tested for + quite some time now. Worse, there is a bug that causes + it to deadlock on some very basic operations (e.g. + dumping domain XML). These facts make us believe no one + uses it. + + +
    diff --git a/docs/schemas/capability.rng b/docs/schemas/capability.rng index fe90a2e4c6..8f3266b9f1 100644 --- a/docs/schemas/capability.rng +++ b/docs/schemas/capability.rng @@ -412,7 +412,7 @@ but is also used by phyp driver --> hvm exe - uml + uml @@ -484,7 +484,7 @@ kqemu kvm xen - uml + uml lxc openvz test diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 5a6c48f1aa..76b49aacc2 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -204,7 +204,7 @@ kvm xen lxc - uml + uml openvz test vmware @@ -1907,7 +1907,7 @@ virtio xen usb - uml + uml sata sd @@ -3725,7 +3725,7 @@ xen serial - uml + uml virtio lxc openvz diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index f41afcd0a7..fbbe2d5624 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -74,7 +74,7 @@ typedef enum { VIR_FROM_NETWORK =3D 19, /* Error from network config */ =20 VIR_FROM_DOMAIN =3D 20, /* Error from domain config */ - VIR_FROM_UML =3D 21, /* Error at the UML driver */ + VIR_FROM_UML =3D 21, /* Error at the UML driver; unused since= 5.0.0 */ VIR_FROM_NODEDEV =3D 22, /* Error from node device monitor */ VIR_FROM_XEN_INOTIFY =3D 23, /* Error from xen inotify layer */ VIR_FROM_SECURITY =3D 24, /* Error from security framework */ diff --git a/libvirt.spec.in b/libvirt.spec.in index 71cd45c603..09472dcadc 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -20,7 +20,6 @@ # The hypervisor drivers that run in libvirtd %define with_qemu 0%{!?_without_qemu:1} %define with_lxc 0%{!?_without_lxc:1} -%define with_uml 0%{!?_without_uml:1} %define with_libxl 0%{!?_without_libxl:1} %define with_vbox 0%{!?_without_vbox:1} =20 @@ -111,13 +110,12 @@ %endif =20 =20 -# RHEL doesn't ship OpenVZ, VBox, UML, PowerHypervisor, +# RHEL doesn't ship OpenVZ, VBox, PowerHypervisor, # VMware, libxenserver (xenapi), libxenlight (Xen 4.1 and newer), # or HyperV. %if 0%{?rhel} %define with_openvz 0 %define with_vbox 0 - %define with_uml 0 %define with_phyp 0 %define with_vmware 0 %define with_xenapi 0 @@ -178,7 +176,7 @@ %endif =20 =20 -%if %{with_qemu} || %{with_lxc} || %{with_uml} +%if %{with_qemu} || %{with_lxc} # numad is used to manage the CPU and memory placement dynamically, # it's not available on many non-x86 architectures. %ifnarch s390 s390x %{arm} riscv64 @@ -231,9 +229,6 @@ Requires: libvirt-daemon-driver-lxc =3D %{version}-%{re= lease} %if %{with_qemu} Requires: libvirt-daemon-driver-qemu =3D %{version}-%{release} %endif -%if %{with_uml} -Requires: libvirt-daemon-driver-uml =3D %{version}-%{release} -%endif %if %{with_vbox} Requires: libvirt-daemon-driver-vbox =3D %{version}-%{release} %endif @@ -743,19 +738,6 @@ the Linux kernel %endif =20 =20 -%if %{with_uml} -%package daemon-driver-uml -Summary: Uml driver plugin for the libvirtd daemon -Requires: libvirt-daemon =3D %{version}-%{release} -Requires: libvirt-libs =3D %{version}-%{release} - -%description daemon-driver-uml -The UML driver plugin for the libvirtd daemon, providing -an implementation of the hypervisor driver APIs using -User Mode Linux -%endif - - %if %{with_vbox} %package daemon-driver-vbox Summary: VirtualBox driver plugin for the libvirtd daemon @@ -843,26 +825,6 @@ capabilities of LXC %endif =20 =20 -%if %{with_uml} -%package daemon-uml -Summary: Server side daemon & driver required to run UML guests - -Requires: libvirt-daemon =3D %{version}-%{release} -Requires: libvirt-daemon-driver-uml =3D %{version}-%{release} -Requires: libvirt-daemon-driver-interface =3D %{version}-%{release} -Requires: libvirt-daemon-driver-network =3D %{version}-%{release} -Requires: libvirt-daemon-driver-nodedev =3D %{version}-%{release} -Requires: libvirt-daemon-driver-nwfilter =3D %{version}-%{release} -Requires: libvirt-daemon-driver-secret =3D %{version}-%{release} -Requires: libvirt-daemon-driver-storage =3D %{version}-%{release} -# There are no UML kernel RPMs in Fedora/RHEL to depend on. - -%description daemon-uml -Server side daemon and driver required to manage the virtualization -capabilities of UML -%endif - - %if %{with_libxl} %package daemon-xen Summary: Server side daemon & driver required to run XEN guests @@ -1068,12 +1030,6 @@ exit 1 %define arg_vmware --without-vmware %endif =20 -%if %{with_uml} - %define arg_uml --with-uml -%else - %define arg_uml --without-uml -%endif - %if %{with_storage_rbd} %define arg_storage_rbd --with-storage-rbd %else @@ -1187,7 +1143,6 @@ rm -f po/stamp-po --with-avahi \ --with-polkit \ --with-libvirtd \ - %{?arg_uml} \ %{?arg_phyp} \ %{?arg_esx} \ %{?arg_hyperv} \ @@ -1316,9 +1271,6 @@ rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libv= irtd.libxl rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/libvirtd_libxl.aug rm -f $RPM_BUILD_ROOT%{_datadir}/augeas/lenses/tests/test_libvirtd_libxl.a= ug %endif -%if ! %{with_uml} -rm -rf $RPM_BUILD_ROOT%{_sysconfdir}/logrotate.d/libvirtd.uml -%endif =20 # Copied into libvirt-docs subpackage eventually mv $RPM_BUILD_ROOT%{_datadir}/doc/libvirt-%{version} libvirt-docs @@ -1725,15 +1677,6 @@ exit 0 %{_libdir}/%{name}/connection-driver/libvirt_driver_lxc.so %endif =20 -%if %{with_uml} -%files daemon-driver-uml -%dir %attr(0700, root, root) %{_localstatedir}/log/libvirt/uml/ -%config(noreplace) %{_sysconfdir}/logrotate.d/libvirtd.uml -%ghost %dir %{_localstatedir}/run/libvirt/uml/ -%dir %attr(0700, root, root) %{_localstatedir}/lib/libvirt/uml/ -%{_libdir}/%{name}/connection-driver/libvirt_driver_uml.so -%endif - %if %{with_libxl} %files daemon-driver-libxl %config(noreplace) %{_sysconfdir}/libvirt/libxl.conf @@ -1764,10 +1707,6 @@ exit 0 %files daemon-lxc %endif =20 -%if %{with_uml} -%files daemon-uml -%endif - %if %{with_libxl} %files daemon-xen %endif diff --git a/m4/virt-driver-uml.m4 b/m4/virt-driver-uml.m4 deleted file mode 100644 index 9b406a5b6b..0000000000 --- a/m4/virt-driver-uml.m4 +++ /dev/null @@ -1,54 +0,0 @@ -dnl The UML driver -dnl -dnl Copyright (C) 2005-2015 Red Hat, Inc. -dnl -dnl This library is free software; you can redistribute it and/or -dnl modify it under the terms of the GNU Lesser General Public -dnl License as published by the Free Software Foundation; either -dnl version 2.1 of the License, or (at your option) any later version. -dnl -dnl This library is distributed in the hope that it will be useful, -dnl but WITHOUT ANY WARRANTY; without even the implied warranty of -dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -dnl Lesser General Public License for more details. -dnl -dnl You should have received a copy of the GNU Lesser General Public -dnl License along with this library. If not, see -dnl . -dnl - -AC_DEFUN([LIBVIRT_DRIVER_ARG_UML],[ - LIBVIRT_ARG_WITH_FEATURE([UML], [UML], [check]) -]) - -AC_DEFUN([LIBVIRT_DRIVER_CHECK_UML],[ - if test "$with_libvirtd" =3D "no" || test "$with_linux" =3D "no"; then - if test "$with_uml" =3D "yes"; then - AC_MSG_ERROR([The UML driver cannot be enabled]) - elif test "$with_uml" =3D "check"; then - with_uml=3D"no" - fi - fi - - if test "$with_uml" =3D "yes" || test "$with_uml" =3D "check"; then - AC_CHECK_HEADER([sys/inotify.h], [ - with_uml=3Dyes - ], [ - if test "$with_uml" =3D "check"; then - with_uml=3Dno - AC_MSG_NOTICE([ is required for the UML drive= r, disabling it]) - else - AC_MSG_ERROR([The is required for the UML dr= iver. Upgrade your libc6.]) - fi - ]) - fi - - if test "$with_uml" =3D "yes" ; then - AC_DEFINE_UNQUOTED([WITH_UML], 1, [whether UML driver is enabled]) - fi - AM_CONDITIONAL([WITH_UML], [test "$with_uml" =3D "yes"]) -]) - -AC_DEFUN([LIBVIRT_DRIVER_RESULT_UML],[ - LIBVIRT_RESULT([UML], [$with_uml]) -]) diff --git a/mingw-libvirt.spec.in b/mingw-libvirt.spec.in index b28e40f7f7..7c7ab4146d 100644 --- a/mingw-libvirt.spec.in +++ b/mingw-libvirt.spec.in @@ -177,7 +177,6 @@ autoreconf -if --without-avahi \ --without-polkit \ --without-libvirtd \ - --without-uml \ %{?_without_phyp} \ %{?_without_esx} \ %{?_without_hyperv} \ diff --git a/po/POTFILES b/po/POTFILES index be2874487c..9dd4ee7d99 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -190,8 +190,6 @@ src/storage/storage_backend_zfs.c src/storage/storage_driver.c src/storage/storage_util.c src/test/test_driver.c -src/uml/uml_conf.c -src/uml/uml_driver.c src/util/iohelper.c src/util/viralloc.c src/util/virarptable.c diff --git a/src/Makefile.am b/src/Makefile.am index 33ff280d78..e2b89e27e8 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -107,7 +107,6 @@ include logging/Makefile.inc.am include locking/Makefile.inc.am include admin/Makefile.inc.am include rpc/Makefile.inc.am -include uml/Makefile.inc.am include phyp/Makefile.inc.am include test/Makefile.inc.am include esx/Makefile.inc.am diff --git a/src/README b/src/README index bb3cddfc6e..846bf2b664 100644 --- a/src/README +++ b/src/README @@ -34,7 +34,6 @@ Then there are the hypervisor implementations: * qemu/ - QEMU / KVM using qemu CLI/monitor * remote/ - Generic libvirt native RPC client * test/ - A "mock" driver for testing - * uml/ - User Mode Linux * vbox/ - Virtual Box using native API * vmware/ - VMware Workstation and Player using the vmrun tool * xen/ - Xen using hypercalls, XenD SEXPR & XenStore @@ -42,7 +41,7 @@ Then there are the hypervisor implementations: =20 =20 Finally some secondary drivers that are shared for several HVs. -Currently these are used by LXC, OpenVZ, QEMU, UML and Xen drivers. +Currently these are used by LXC, OpenVZ, QEMU and Xen drivers. The ESX, Hyper-V, Power Hypervisor, Remote, Test & VirtualBox drivers all implement the secondary drivers directly =20 diff --git a/src/locking/lock_driver.h b/src/locking/lock_driver.h index f2d5266517..50c73a70d4 100644 --- a/src/locking/lock_driver.h +++ b/src/locking/lock_driver.h @@ -124,7 +124,7 @@ struct _virLockManagerParam { * too old to support key features. * * NB: A plugin may be loaded multiple times, for different - * libvirt drivers (eg QEMU, LXC, UML) + * libvirt drivers (eg QEMU, LXC) * * Returns -1 if the requested version/flags were inadequate */ diff --git a/src/remote/Makefile.inc.am b/src/remote/Makefile.inc.am index eb8d6feb31..d188c4e348 100644 --- a/src/remote/Makefile.inc.am +++ b/src/remote/Makefile.inc.am @@ -39,7 +39,6 @@ LOGROTATE_FILES_IN +=3D \ remote/libvirtd.qemu.logrotate.in \ remote/libvirtd.lxc.logrotate.in \ remote/libvirtd.libxl.logrotate.in \ - remote/libvirtd.uml.logrotate.in \ remote/libvirtd.logrotate.in \ $(NULL) =20 diff --git a/src/remote/libvirtd.uml.logrotate.in b/src/remote/libvirtd.uml= .logrotate.in deleted file mode 100644 index 66a848e37e..0000000000 --- a/src/remote/libvirtd.uml.logrotate.in +++ /dev/null @@ -1,8 +0,0 @@ -@localstatedir@/log/libvirt/uml/*.log { - weekly - missingok - rotate 4 - compress - delaycompress - copytruncate -} diff --git a/src/remote/remote_daemon.c b/src/remote/remote_daemon.c index f0dd7597e6..3be3ad02fc 100644 --- a/src/remote/remote_daemon.c +++ b/src/remote/remote_daemon.c @@ -339,10 +339,6 @@ static int daemonInitialize(void) if (virDriverLoadModule("lxc", "lxcRegister", false) < 0) return -1; #endif -#ifdef WITH_UML - if (virDriverLoadModule("uml", "umlRegister", false) < 0) - return -1; -#endif #ifdef WITH_VBOX if (virDriverLoadModule("vbox", "vboxRegister", false) < 0) return -1; diff --git a/src/uml/Makefile.inc.am b/src/uml/Makefile.inc.am deleted file mode 100644 index 975398b928..0000000000 --- a/src/uml/Makefile.inc.am +++ /dev/null @@ -1,48 +0,0 @@ -UML_DRIVER_SOURCES =3D \ - uml/uml_conf.c \ - uml/uml_conf.h \ - uml/uml_driver.c \ - uml/uml_driver.h \ - $(NULL) - -DRIVER_SOURCE_FILES +=3D $(UML_DRIVER_SOURCES) -STATEFUL_DRIVER_SOURCE_FILES +=3D $(UML_DRIVER_SOURCES) -EXTRA_DIST +=3D $(UML_DRIVER_SOURCES) - -if WITH_UML -noinst_LTLIBRARIES +=3D libvirt_driver_uml_impl.la -libvirt_driver_uml_la_SOURCES =3D -libvirt_driver_uml_la_LIBADD =3D \ - libvirt_driver_uml_impl.la \ - libvirt.la \ - ../gnulib/lib/libgnu.la \ - $(NULL) -mod_LTLIBRARIES +=3D libvirt_driver_uml.la -libvirt_driver_uml_la_LDFLAGS =3D $(AM_LDFLAGS_MOD_NOUNDEF) - -libvirt_driver_uml_impl_la_CFLAGS =3D \ - -I$(srcdir)/access \ - -I$(srcdir)/conf \ - $(AM_CFLAGS) \ - $(NULL) -libvirt_driver_uml_impl_la_LDFLAGS =3D $(AM_LDFLAGS) -libvirt_driver_uml_impl_la_SOURCES =3D $(UML_DRIVER_SOURCES) - -INSTALL_DATA_DIRS +=3D uml - -install-data-uml: - $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/uml" - $(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/uml" - $(MKDIR_P) "$(DESTDIR)$(localstatedir)/log/libvirt/uml" - -uninstall-data-uml: - rmdir "$(DESTDIR)$(localstatedir)/lib/libvirt/uml" ||: - rmdir "$(DESTDIR)$(localstatedir)/run/libvirt/uml" ||: - rmdir "$(DESTDIR)$(localstatedir)/log/libvirt/uml" ||: - -endif WITH_UML - -.PHONY: \ - install-data-uml \ - uninstall-data-uml \ - $(NULL) diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c deleted file mode 100644 index 067600afba..0000000000 --- a/src/uml/uml_conf.c +++ /dev/null @@ -1,481 +0,0 @@ -/* - * uml_conf.c: UML driver configuration - * - * Copyright (C) 2006-2014, 2016 Red Hat, Inc. - * Copyright (C) 2006 Daniel P. Berrange - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#include - -#include -#include -#include -#include -#include -#include - -#include "uml_conf.h" -#include "viruuid.h" -#include "virbuffer.h" -#include "virconf.h" -#include "viralloc.h" -#include "virlog.h" -#include "domain_nwfilter.h" -#include "virfile.h" -#include "vircommand.h" -#include "virnetdevtap.h" -#include "virnodesuspend.h" -#include "virstring.h" - -#define VIR_FROM_THIS VIR_FROM_UML - -VIR_LOG_INIT("uml.uml_conf"); - -virCapsPtr umlCapsInit(void) -{ - virCapsPtr caps; - virCapsGuestPtr guest; - - if ((caps =3D virCapabilitiesNew(virArchFromHost(), - false, false)) =3D=3D NULL) - goto error; - - /* Some machines have problematic NUMA topology causing - * unexpected failures. We don't want to break the QEMU - * driver in this scenario, so log errors & carry on - */ - if (virCapabilitiesInitNUMA(caps) < 0) { - virCapabilitiesFreeNUMAInfo(caps); - VIR_WARN("Failed to query host NUMA topology, disabling NUMA capab= ilities"); - } - - if (virCapabilitiesInitCaches(caps) < 0) - VIR_WARN("Failed to get host CPU cache info"); - - if (virNodeSuspendGetTargetMask(&caps->host.powerMgmt) < 0) - VIR_WARN("Failed to get host power management capabilities"); - - if (virGetHostUUID(caps->host.host_uuid)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("cannot get the host uuid")); - goto error; - } - - if ((guest =3D virCapabilitiesAddGuest(caps, - VIR_DOMAIN_OSTYPE_UML, - caps->host.arch, - NULL, - NULL, - 0, - NULL)) =3D=3D NULL) - goto error; - - if (virCapabilitiesAddGuestDomain(guest, - VIR_DOMAIN_VIRT_UML, - NULL, - NULL, - 0, - NULL) =3D=3D NULL) - goto error; - - return caps; - - error: - virObjectUnref(caps); - return NULL; -} - - -static int -umlConnectTapDevice(virDomainDefPtr vm, - virDomainNetDefPtr net, - const char *bridge) -{ - bool template_ifname =3D false; - int tapfd =3D -1; - - if (!net->ifname || - STRPREFIX(net->ifname, VIR_NET_GENERATED_TAP_PREFIX) || - strchr(net->ifname, '%')) { - VIR_FREE(net->ifname); - if (VIR_STRDUP(net->ifname, VIR_NET_GENERATED_TAP_PREFIX "%d") < 0) - goto error; - /* avoid exposing vnet%d in getXMLDesc or error outputs */ - template_ifname =3D true; - } - - if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, &net->mac, - vm->uuid, net->backend.tap, &tapfd,= 1, - virDomainNetGetActualVirtPortProfil= e(net), - virDomainNetGetActualVlan(net), - NULL, 0, NULL, - VIR_NETDEV_TAP_CREATE_IFUP | - VIR_NETDEV_TAP_CREATE_PERSIST) < 0)= { - if (template_ifname) - VIR_FREE(net->ifname); - goto error; - } - - if (net->filter) { - if (virDomainConfNWFilterInstantiate(vm->name, vm->uuid, net, fals= e) < 0) { - if (template_ifname) - VIR_FREE(net->ifname); - goto error; - } - } - - VIR_FORCE_CLOSE(tapfd); - return 0; - - error: - VIR_FORCE_CLOSE(tapfd); - return -1; -} - -static char * -umlBuildCommandLineNet(virConnectPtr conn, - virDomainDefPtr vm, - virDomainNetDefPtr def, - int idx) -{ - virBuffer buf =3D VIR_BUFFER_INITIALIZER; - char macaddr[VIR_MAC_STRING_BUFLEN]; - - /* General format: ethNN=3Dtype,options */ - - virBufferAsprintf(&buf, "eth%d=3D", idx); - - switch (def->type) { - case VIR_DOMAIN_NET_TYPE_USER: - /* ethNNN=3Dslirp,macaddr */ - virBufferAddLit(&buf, "slirp"); - break; - - case VIR_DOMAIN_NET_TYPE_ETHERNET: - /* ethNNN=3Dtuntap,tapname,macaddr,gateway */ - virBufferAddLit(&buf, "tuntap,"); - if (def->ifname) - virBufferAdd(&buf, def->ifname, -1); - if (def->guestIP.nips > 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("IP address not supported for ethernet interf= ace")); - goto error; - } - break; - - case VIR_DOMAIN_NET_TYPE_VHOSTUSER: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("vhostuser networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_SERVER: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("TCP server networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_CLIENT: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("TCP client networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_UDP: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("UDP networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_MCAST: - /* ethNNN=3Dtuntap,macaddr,ipaddr,port */ - virBufferAddLit(&buf, "mcast"); - break; - - case VIR_DOMAIN_NET_TYPE_NETWORK: - { - char *bridge; - virNetworkPtr network =3D virNetworkLookupByName(conn, - def->data.network.n= ame); - if (!network) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Network '%s' not found"), - def->data.network.name); - goto error; - } - bridge =3D virNetworkGetBridgeName(network); - virObjectUnref(network); - if (bridge =3D=3D NULL) - goto error; - - if (umlConnectTapDevice(vm, def, bridge) < 0) { - VIR_FREE(bridge); - goto error; - } - - /* ethNNN=3Dtuntap,tapname,macaddr,gateway */ - virBufferAsprintf(&buf, "tuntap,%s", def->ifname); - break; - } - - case VIR_DOMAIN_NET_TYPE_BRIDGE: - if (umlConnectTapDevice(vm, def, - def->data.bridge.brname) < 0) - goto error; - - /* ethNNN=3Dtuntap,tapname,macaddr,gateway */ - virBufferAsprintf(&buf, "tuntap,%s", def->ifname); - break; - - case VIR_DOMAIN_NET_TYPE_INTERNAL: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("internal networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_DIRECT: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("direct networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_HOSTDEV: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("hostdev networking type not supported")); - goto error; - - case VIR_DOMAIN_NET_TYPE_LAST: - break; - } - - if (def->script) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("interface script execution not supported by this= driver")); - goto error; - } - - virBufferAsprintf(&buf, ",%s", virMacAddrFormat(&def->mac, macaddr)); - - if (def->type =3D=3D VIR_DOMAIN_NET_TYPE_MCAST) { - virBufferAsprintf(&buf, ",%s,%d", - def->data.socket.address, - def->data.socket.port); - } - - if (virBufferCheckError(&buf) < 0) - return NULL; - - return virBufferContentAndReset(&buf); - - error: - virBufferFreeAndReset(&buf); - return NULL; -} - -static char * -umlBuildCommandLineChr(virDomainChrDefPtr def, - const char *dev, - virCommandPtr cmd) -{ - char *ret =3D NULL; - - switch (def->source->type) { - case VIR_DOMAIN_CHR_TYPE_NULL: - if (virAsprintf(&ret, "%s%d=3Dnull", dev, def->target.port) < 0) - return NULL; - break; - - case VIR_DOMAIN_CHR_TYPE_PTY: - if (virAsprintf(&ret, "%s%d=3Dpts", dev, def->target.port) < 0) - return NULL; - break; - - case VIR_DOMAIN_CHR_TYPE_DEV: - if (virAsprintf(&ret, "%s%d=3Dtty:%s", dev, def->target.port, - def->source->data.file.path) < 0) - return NULL; - break; - - case VIR_DOMAIN_CHR_TYPE_STDIO: - if (virAsprintf(&ret, "%s%d=3Dfd:0,fd:1", dev, def->target.port) <= 0) - return NULL; - break; - - case VIR_DOMAIN_CHR_TYPE_TCP: - if (def->source->data.tcp.listen !=3D 1) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("only TCP listen is supported for chr device"= )); - return NULL; - } - - if (virAsprintf(&ret, "%s%d=3Dport:%s", dev, def->target.port, - def->source->data.tcp.service) < 0) - return NULL; - break; - - case VIR_DOMAIN_CHR_TYPE_FILE: - { - int fd_out; - - if ((fd_out =3D open(def->source->data.file.path, - O_WRONLY | O_APPEND | O_CREAT, 0660)) < 0) { - virReportSystemError(errno, - _("failed to open chardev file: %s"), - def->source->data.file.path); - return NULL; - } - if (virAsprintf(&ret, "%s%d=3Dnull,fd:%d", dev, def->target.po= rt, fd_out) < 0) { - VIR_FORCE_CLOSE(fd_out); - return NULL; - } - virCommandPassFD(cmd, fd_out, - VIR_COMMAND_PASS_FD_CLOSE_PARENT); - } - break; - case VIR_DOMAIN_CHR_TYPE_PIPE: - /* XXX could open the pipe & just pass the FDs. Be wary of - * the effects of blocking I/O, though. */ - - case VIR_DOMAIN_CHR_TYPE_VC: - case VIR_DOMAIN_CHR_TYPE_UDP: - case VIR_DOMAIN_CHR_TYPE_UNIX: - default: - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unsupported chr device type %d"), def->source->t= ype); - break; - } - - return ret; -} - -/* - * Null-terminate the current argument and return a pointer to the next. - * This should follow the same rules as the Linux kernel: arguments are - * separated by spaces; arguments can be quoted with double quotes; double - * quotes can't be escaped. - */ -static char *umlNextArg(char *args) -{ - int in_quote =3D 0; - - for (; *args; args++) { - if (*args =3D=3D ' ' && !in_quote) { - *args++ =3D '\0'; - break; - } - if (*args =3D=3D '"') - in_quote =3D !in_quote; - } - - while (*args =3D=3D ' ') - args++; - - return args; -} - -/* - * Constructs a argv suitable for launching uml with config defined - * for a given virtual machine. - */ -virCommandPtr umlBuildCommandLine(virConnectPtr conn, - struct uml_driver *driver, - virDomainObjPtr vm) -{ - size_t i, j; - virCommandPtr cmd; - - cmd =3D virCommandNew(vm->def->os.kernel); - - virCommandAddEnvPassCommon(cmd); - - /* virCommandAddArgPair(cmd, "con0", "fd:0,fd:1"); */ - virCommandAddArgFormat(cmd, "mem=3D%lluK", vm->def->mem.cur_balloon); - virCommandAddArgPair(cmd, "umid", vm->def->name); - virCommandAddArgPair(cmd, "uml_dir", driver->monitorDir); - - if (vm->def->os.root) - virCommandAddArgPair(cmd, "root", vm->def->os.root); - - for (i =3D 0; i < vm->def->ndisks; i++) { - virDomainDiskDefPtr disk =3D vm->def->disks[i]; - - if (!STRPREFIX(disk->dst, "ubd")) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unsupported disk type '%s'"), disk->dst); - goto error; - } - - virCommandAddArgPair(cmd, disk->dst, virDomainDiskGetSource(disk)); - } - - for (i =3D 0; i < vm->def->nnets; i++) { - char *ret =3D umlBuildCommandLineNet(conn, vm->def, vm->def->nets[= i], i); - if (!ret) - goto error; - virCommandAddArg(cmd, ret); - VIR_FREE(ret); - } - - for (i =3D 0; i < UML_MAX_CHAR_DEVICE; i++) { - virDomainChrDefPtr chr =3D NULL; - char *ret =3D NULL; - for (j =3D 0; j < vm->def->nconsoles; j++) - if (vm->def->consoles[j]->target.port =3D=3D i) - chr =3D vm->def->consoles[j]; - if (chr) - ret =3D umlBuildCommandLineChr(chr, "con", cmd); - if (!ret) - if (virAsprintf(&ret, "con%zu=3Dnone", i) < 0) - goto error; - virCommandAddArg(cmd, ret); - VIR_FREE(ret); - } - - for (i =3D 0; i < UML_MAX_CHAR_DEVICE; i++) { - virDomainChrDefPtr chr =3D NULL; - char *ret =3D NULL; - for (j =3D 0; j < vm->def->nserials; j++) - if (vm->def->serials[j]->target.port =3D=3D i) - chr =3D vm->def->serials[j]; - if (chr) - ret =3D umlBuildCommandLineChr(chr, "ssl", cmd); - if (!ret) - if (virAsprintf(&ret, "ssl%zu=3Dnone", i) < 0) - goto error; - - virCommandAddArg(cmd, ret); - VIR_FREE(ret); - } - - if (vm->def->os.cmdline) { - char *args, *next_arg; - char *cmdline; - if (VIR_STRDUP(cmdline, vm->def->os.cmdline) < 0) - goto error; - - args =3D cmdline; - while (*args =3D=3D ' ') - args++; - - while (*args) { - next_arg =3D umlNextArg(args); - virCommandAddArg(cmd, args); - args =3D next_arg; - } - VIR_FREE(cmdline); - } - - return cmd; - - error: - virCommandFree(cmd); - return NULL; -} diff --git a/src/uml/uml_conf.h b/src/uml/uml_conf.h deleted file mode 100644 index a9520a6d3e..0000000000 --- a/src/uml/uml_conf.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * uml_conf.h: VM configuration management - * - * Copyright (C) 2006, 2007, 2010 Red Hat, Inc. - * Copyright (C) 2006 Daniel P. Berrange - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#ifndef LIBVIRT_UML_CONF_H -# define LIBVIRT_UML_CONF_H - -# include "internal.h" -# include "libvirt_internal.h" -# include "capabilities.h" -# include "network_conf.h" -# include "virdomainobjlist.h" -# include "domain_event.h" -# include "virerror.h" -# include "virthread.h" -# include "vircommand.h" -# include "virhash.h" - -# define umlDebug(fmt, ...) do {} while (0) - -# define UML_CPUMASK_LEN CPU_SETSIZE - -# define UML_MAX_CHAR_DEVICE 16 - -/* Main driver state */ -struct uml_driver { - virMutex lock; - - bool privileged; - virStateInhibitCallback inhibitCallback; - void *inhibitOpaque; - - unsigned long umlVersion; - int nextvmid; - - virDomainObjListPtr domains; - size_t nactive; - - char *configDir; - char *autostartDir; - char *logDir; - char *monitorDir; - - int inotifyFD; - int inotifyWatch; - - virCapsPtr caps; - virDomainXMLOptionPtr xmlopt; - - /* Event handling */ - virObjectEventStatePtr domainEventState; - - /* Mapping of 'char *uuidstr' -> virConnectPtr - * of guests which will be automatically killed - * when the virConnectPtr is closed*/ - virHashTablePtr autodestroy; -}; - -virCapsPtr umlCapsInit (void); - -virCommandPtr umlBuildCommandLine(virConnectPtr conn, - struct uml_driver *driver, - virDomainObjPtr dom); - -#endif /* LIBVIRT_UML_CONF_H */ diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c deleted file mode 100644 index e790273717..0000000000 --- a/src/uml/uml_driver.c +++ /dev/null @@ -1,2835 +0,0 @@ -/* - * uml_driver.c: core driver methods for managing UML guests - * - * Copyright (C) 2006-2015 Red Hat, Inc. - * Copyright (C) 2006-2008 Daniel P. Berrange - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "uml_driver.h" -#include "uml_conf.h" -#include "virbuffer.h" -#include "virhostcpu.h" -#include "virhostmem.h" -#include "capabilities.h" -#include "viralloc.h" -#include "viruuid.h" -#include "domain_conf.h" -#include "domain_audit.h" -#include "datatypes.h" -#include "virlog.h" -#include "domain_nwfilter.h" -#include "virfile.h" -#include "virfdstream.h" -#include "configmake.h" -#include "virnetdevtap.h" -#include "virnodesuspend.h" -#include "virprocess.h" -#include "viruri.h" -#include "virstring.h" -#include "viraccessapicheck.h" - -#define VIR_FROM_THIS VIR_FROM_UML - -VIR_LOG_INIT("uml.uml_driver"); - -typedef struct _umlDomainObjPrivate umlDomainObjPrivate; -typedef umlDomainObjPrivate *umlDomainObjPrivatePtr; -struct _umlDomainObjPrivate { - int monitor; - int monitorWatch; -}; - -static int umlProcessAutoDestroyInit(struct uml_driver *driver); -static void umlProcessAutoDestroyRun(struct uml_driver *driver, - virConnectPtr conn); -static void umlProcessAutoDestroyShutdown(struct uml_driver *driver); -static int umlProcessAutoDestroyAdd(struct uml_driver *driver, - virDomainObjPtr vm, - virConnectPtr conn); -static int umlProcessAutoDestroyRemove(struct uml_driver *driver, - virDomainObjPtr vm); - - -static int umlStateCleanup(void); - -static void *umlDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED) -{ - umlDomainObjPrivatePtr priv; - - if (VIR_ALLOC(priv) < 0) - return NULL; - - priv->monitor =3D -1; - priv->monitorWatch =3D -1; - - return priv; -} - -static void umlDomainObjPrivateFree(void *data) -{ - umlDomainObjPrivatePtr priv =3D data; - - VIR_FREE(priv); -} - - -static void umlDriverLock(struct uml_driver *driver) -{ - virMutexLock(&driver->lock); -} -static void umlDriverUnlock(struct uml_driver *driver) -{ - virMutexUnlock(&driver->lock); -} - - -static int umlOpenMonitor(struct uml_driver *driver, - virDomainObjPtr vm); -static int umlReadPidFile(struct uml_driver *driver, - virDomainObjPtr vm); - -static int umlStartVMDaemon(virConnectPtr conn, - struct uml_driver *driver, - virDomainObjPtr vm, - bool autoDestroy); - -static void umlShutdownVMDaemon(struct uml_driver *driver, - virDomainObjPtr vm, - virDomainShutoffReason reason); - - -static int umlMonitorCommand(const struct uml_driver *driver, - const virDomainObj *vm, - const char *cmd, - char **reply); - -static struct uml_driver *uml_driver; - -static virDomainObjPtr -umlDomObjFromDomainLocked(struct uml_driver *driver, - const unsigned char *uuid) -{ - virDomainObjPtr vm; - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - if (!(vm =3D virDomainObjListFindByUUID(driver->domains, uuid))) { - virUUIDFormat(uuid, uuidstr); - - virReportError(VIR_ERR_NO_DOMAIN, - _("no domain with matching uuid '%s'"), uuidstr); - return NULL; - } - - return vm; -} - - -static virDomainObjPtr -umlDomObjFromDomain(struct uml_driver *driver, - const unsigned char *uuid) -{ - virDomainObjPtr vm; - - umlDriverLock(driver); - vm =3D umlDomObjFromDomainLocked(driver, uuid); - umlDriverUnlock(driver); - return vm; -} - - -struct umlAutostartData { - struct uml_driver *driver; - virConnectPtr conn; -}; - -static int -umlAutostartDomain(virDomainObjPtr vm, - void *opaque) -{ - const struct umlAutostartData *data =3D opaque; - int ret =3D 0; - virObjectLock(vm); - if (vm->autostart && - !virDomainObjIsActive(vm)) { - virResetLastError(); - ret =3D umlStartVMDaemon(data->conn, data->driver, vm, false); - virDomainAuditStart(vm, "booted", ret >=3D 0); - if (ret < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, _("Failed to autostart = VM '%s': %s"), - vm->def->name, virGetLastErrorMessage()); - } else { - virObjectEventPtr event =3D - virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_STARTED, - VIR_DOMAIN_EVENT_STARTED_BOOTED); - virObjectEventStateQueue(data->driver->domainEventState, event= ); - } - } - virObjectUnlock(vm); - return ret; -} - -static void -umlAutostartConfigs(struct uml_driver *driver) -{ - /* XXX: Figure out a better way todo this. The domain - * startup code needs a connection handle in order - * to lookup the bridge associated with a virtual - * network - */ - virConnectPtr conn =3D virConnectOpen(driver->privileged ? - "uml:///system" : - "uml:///session"); - /* Ignoring NULL conn which is mostly harmless here */ - - struct umlAutostartData data =3D { driver, conn }; - - umlDriverLock(driver); - virDomainObjListForEach(driver->domains, umlAutostartDomain, &data); - umlDriverUnlock(driver); - - virObjectUnref(conn); -} - - -static int -umlIdentifyOneChrPTY(struct uml_driver *driver, - virDomainObjPtr dom, - virDomainChrDefPtr def, - const char *dev) -{ - char *cmd; - char *res =3D NULL; - int retries =3D 0; - if (virAsprintf(&cmd, "config %s%d", dev, def->target.port) < 0) - return -1; - requery: - if (umlMonitorCommand(driver, dom, cmd, &res) < 0) - return -1; - - if (res && STRPREFIX(res, "pts:")) { - VIR_FREE(def->source->data.file.path); - if (VIR_STRDUP(def->source->data.file.path, res + 4) < 0) { - VIR_FREE(res); - VIR_FREE(cmd); - return -1; - } - } else if (!res || STRPREFIX(res, "pts")) { - /* It can take a while to startup, so retry for - up to 5 seconds */ - /* XXX should do this in a better non-blocking - way somehow ...perhaps register a timer */ - if (retries++ < 50) { - VIR_FREE(res); - usleep(1000*10); - goto requery; - } - } - - VIR_FREE(cmd); - VIR_FREE(res); - return 0; -} - -static int -umlIdentifyChrPTY(struct uml_driver *driver, - virDomainObjPtr dom) -{ - size_t i; - - for (i =3D 0; i < dom->def->nconsoles; i++) - if (dom->def->consoles[i]->source->type =3D=3D VIR_DOMAIN_CHR_TYPE= _PTY) - if (umlIdentifyOneChrPTY(driver, dom, - dom->def->consoles[i], "con") < 0) - return -1; - - for (i =3D 0; i < dom->def->nserials; i++) - if (dom->def->serials[i]->source->type =3D=3D VIR_DOMAIN_CHR_TYPE_= PTY && - umlIdentifyOneChrPTY(driver, dom, - dom->def->serials[i], "ssl") < 0) - return -1; - - return 0; -} - -static void -umlInotifyEvent(int watch, - int fd, - int events ATTRIBUTE_UNUSED, - void *data) -{ - char buf[1024]; - struct inotify_event e; - int got; - char *tmp, *name; - struct uml_driver *driver =3D data; - virDomainObjPtr dom; - virObjectEventPtr event =3D NULL; - - umlDriverLock(driver); - if (watch !=3D driver->inotifyWatch) - goto cleanup; - - reread: - got =3D read(fd, buf, sizeof(buf)); - if (got =3D=3D -1) { - if (errno =3D=3D EINTR) - goto reread; - goto cleanup; - } - - tmp =3D buf; - while (got) { - if (got < sizeof(e)) - goto cleanup; /* bad */ - - memcpy(&e, tmp, sizeof(e)); - tmp +=3D sizeof(e); - got -=3D sizeof(e); - - if (got < e.len) - goto cleanup; - - tmp +=3D e.len; - got -=3D e.len; - - name =3D (char *)&(e.name); - - dom =3D virDomainObjListFindByName(driver->domains, name); - - if (!dom) - continue; - - if (e.mask & IN_DELETE) { - VIR_DEBUG("Got inotify domain shutdown '%s'", name); - if (!virDomainObjIsActive(dom)) { - virDomainObjEndAPI(&dom); - continue; - } - - umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); - virDomainAuditStop(dom, "shutdown"); - event =3D virDomainEventLifecycleNewFromObj(dom, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_SHUT= DOWN); - if (!dom->persistent) - virDomainObjListRemove(driver->domains, dom); - } else if (e.mask & (IN_CREATE | IN_MODIFY)) { - VIR_DEBUG("Got inotify domain startup '%s'", name); - if (virDomainObjIsActive(dom)) { - virDomainObjEndAPI(&dom); - continue; - } - - if (umlReadPidFile(driver, dom) < 0) { - virDomainObjEndAPI(&dom); - continue; - } - - dom->def->id =3D driver->nextvmid++; - - if (!driver->nactive && driver->inhibitCallback) - driver->inhibitCallback(true, driver->inhibitOpaque); - driver->nactive++; - - virDomainObjSetState(dom, VIR_DOMAIN_RUNNING, - VIR_DOMAIN_RUNNING_BOOTED); - - if (umlOpenMonitor(driver, dom) < 0) { - VIR_WARN("Could not open monitor for new domain"); - umlShutdownVMDaemon(driver, dom, - VIR_DOMAIN_SHUTOFF_FAILED); - virDomainAuditStop(dom, "failed"); - event =3D virDomainEventLifecycleNewFromObj(dom, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_= FAILED); - if (!dom->persistent) - virDomainObjListRemove(driver->domains, dom); - } else if (umlIdentifyChrPTY(driver, dom) < 0) { - VIR_WARN("Could not identify character devices for new dom= ain"); - umlShutdownVMDaemon(driver, dom, - VIR_DOMAIN_SHUTOFF_FAILED); - virDomainAuditStop(dom, "failed"); - event =3D virDomainEventLifecycleNewFromObj(dom, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_= FAILED); - if (!dom->persistent) - virDomainObjListRemove(driver->domains, dom); - } - } - virDomainObjEndAPI(&dom); - virObjectEventStateQueue(driver->domainEventState, event); - event =3D NULL; - } - - cleanup: - umlDriverUnlock(driver); -} - - -static int -umlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev, - const virDomainDef *def ATTRIBUTE_UNUSED, - virCapsPtr caps ATTRIBUTE_UNUSED, - unsigned int parseFlags ATTRIBUTE_UNUSED, - void *opaque ATTRIBUTE_UNUSED, - void *parseOpaque ATTRIBUTE_UNUSED) -{ - if (dev->type =3D=3D VIR_DOMAIN_DEVICE_CHR && - dev->data.chr->deviceType =3D=3D VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOL= E && - dev->data.chr->targetType =3D=3D VIR_DOMAIN_CHR_CONSOLE_TARGET_TYP= E_NONE) - dev->data.chr->targetType =3D VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_U= ML; - - /* forbid capabilities mode hostdev in this kind of hypervisor */ - if (dev->type =3D=3D VIR_DOMAIN_DEVICE_HOSTDEV && - dev->data.hostdev->mode =3D=3D VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIE= S) { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("hostdev mode 'capabilities' is not " - "supported in %s"), - virDomainVirtTypeToString(def->virtType)); - return -1; - } - - return 0; -} - - -static int -umlDomainDefPostParse(virDomainDefPtr def ATTRIBUTE_UNUSED, - virCapsPtr caps ATTRIBUTE_UNUSED, - unsigned int parseFlags ATTRIBUTE_UNUSED, - void *opaque ATTRIBUTE_UNUSED, - void *parseOpaque ATTRIBUTE_UNUSED) -{ - return 0; -} - - -virDomainDefParserConfig umlDriverDomainDefParserConfig =3D { - .devicesPostParseCallback =3D umlDomainDeviceDefPostParse, - .domainPostParseCallback =3D umlDomainDefPostParse, -}; - - -/** - * umlStartup: - * - * Initialization function for the Uml daemon - */ -static int -umlStateInitialize(bool privileged, - virStateInhibitCallback callback, - void *opaque) -{ - char *base =3D NULL; - char *userdir =3D NULL; - - virDomainXMLPrivateDataCallbacks privcb =3D { - .alloc =3D umlDomainObjPrivateAlloc, - .free =3D umlDomainObjPrivateFree, - }; - - if (VIR_ALLOC(uml_driver) < 0) - return -1; - - uml_driver->privileged =3D privileged; - uml_driver->inhibitCallback =3D callback; - uml_driver->inhibitOpaque =3D opaque; - - if (virMutexInit(¨_driver->lock) < 0) { - VIR_FREE(uml_driver); - return -1; - } - umlDriverLock(uml_driver); - - /* Don't have a dom0 so start from 1 */ - uml_driver->nextvmid =3D 1; - uml_driver->inotifyWatch =3D -1; - - if (!(uml_driver->domains =3D virDomainObjListNew())) - goto error; - - uml_driver->domainEventState =3D virObjectEventStateNew(); - if (!uml_driver->domainEventState) - goto error; - - userdir =3D virGetUserDirectory(); - if (!userdir) - goto error; - - if (privileged) { - if (virAsprintf(¨_driver->logDir, - "%s/log/libvirt/uml", LOCALSTATEDIR) =3D=3D -1) - goto out_of_memory; - - if (VIR_STRDUP(base, SYSCONFDIR "/libvirt") < 0) - goto error; - - if (virAsprintf(¨_driver->monitorDir, - "%s/run/libvirt/uml-guest", LOCALSTATEDIR) =3D=3D = -1) - goto out_of_memory; - } else { - base =3D virGetUserConfigDirectory(); - if (!base) - goto error; - - if (virAsprintf(¨_driver->logDir, - "%s/uml/log", base) =3D=3D -1) - goto out_of_memory; - - if (virAsprintf(¨_driver->monitorDir, - "%s/.uml", userdir) =3D=3D -1) - goto out_of_memory; - } - - /* Configuration paths are either $XDG_CONFIG_HOME/libvirt/uml/... (se= ssion) or - * /etc/libvirt/uml/... (system). - */ - if (virAsprintf(¨_driver->configDir, "%s/uml", base) =3D=3D -1) - goto out_of_memory; - - if (virAsprintf(¨_driver->autostartDir, "%s/uml/autostart", base) = =3D=3D -1) - goto out_of_memory; - - VIR_FREE(base); - - if ((uml_driver->caps =3D umlCapsInit()) =3D=3D NULL) - goto out_of_memory; - - if (!(uml_driver->xmlopt =3D virDomainXMLOptionNew(¨DriverDomainDef= ParserConfig, - &privcb, NULL, NULL, = NULL))) - goto error; - - if ((uml_driver->inotifyFD =3D inotify_init()) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("cannot initialize = inotify")); - goto error; - } - - if (virFileMakePath(uml_driver->monitorDir) < 0) { - virReportSystemError(errno, _("Failed to create monitor directory = %s"), - uml_driver->monitorDir); - goto error; - } - - VIR_INFO("Adding inotify watch on %s", uml_driver->monitorDir); - if (inotify_add_watch(uml_driver->inotifyFD, - uml_driver->monitorDir, - IN_CREATE | IN_MODIFY | IN_DELETE) < 0) { - virReportSystemError(errno, _("Failed to create inotify watch on %= s"), - uml_driver->monitorDir); - goto error; - } - - if ((uml_driver->inotifyWatch =3D - virEventAddHandle(uml_driver->inotifyFD, POLLIN, - umlInotifyEvent, uml_driver, NULL)) < 0) - goto error; - - if (umlProcessAutoDestroyInit(uml_driver) < 0) - goto error; - - if (virDomainObjListLoadAllConfigs(uml_driver->domains, - uml_driver->configDir, - uml_driver->autostartDir, false, - uml_driver->caps, - uml_driver->xmlopt, - NULL, NULL) < 0) - goto error; - - umlDriverUnlock(uml_driver); - - VIR_FREE(userdir); - - return 0; - - out_of_memory: - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("umlStartup: out of mem= ory")); - - error: - VIR_FREE(userdir); - VIR_FREE(base); - umlDriverUnlock(uml_driver); - umlStateCleanup(); - return -1; -} - -/** - * umlStateAutoStart: - * - * Function to autostart the Uml daemons - */ -static void -umlStateAutoStart(void) -{ - if (!uml_driver) - return; - - umlAutostartConfigs(uml_driver); -} - -static void umlNotifyLoadDomain(virDomainObjPtr vm, int newVM, void *opaqu= e) -{ - struct uml_driver *driver =3D opaque; - - if (newVM) { - virObjectEventPtr event =3D - virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_DEFINED, - VIR_DOMAIN_EVENT_DEFINED_ADDED); - virObjectEventStateQueue(driver->domainEventState, event); - } -} - - -/** - * umlStateReload: - * - * Function to restart the Uml daemon, it will recheck the configuration - * files and update its state and the networking - */ -static int -umlStateReload(void) -{ - if (!uml_driver) - return 0; - - umlDriverLock(uml_driver); - virDomainObjListLoadAllConfigs(uml_driver->domains, - uml_driver->configDir, - uml_driver->autostartDir, false, - uml_driver->caps, - uml_driver->xmlopt, - umlNotifyLoadDomain, uml_driver); - umlDriverUnlock(uml_driver); - - return 0; -} - - -static int -umlShutdownOneVM(virDomainObjPtr dom, void *opaque) -{ - struct uml_driver *driver =3D opaque; - - virObjectLock(dom); - if (virDomainObjIsActive(dom)) { - umlShutdownVMDaemon(driver, dom, VIR_DOMAIN_SHUTOFF_SHUTDOWN); - virDomainAuditStop(dom, "shutdown"); - } - virObjectUnlock(dom); - return 0; -} - -/** - * umlStateCleanup: - * - * Shutdown the Uml daemon, it will stop all active domains and networks - */ -static int -umlStateCleanup(void) -{ - if (!uml_driver) - return -1; - - umlDriverLock(uml_driver); - if (uml_driver->inotifyWatch !=3D -1) - virEventRemoveHandle(uml_driver->inotifyWatch); - VIR_FORCE_CLOSE(uml_driver->inotifyFD); - virObjectUnref(uml_driver->caps); - virObjectUnref(uml_driver->xmlopt); - - /* shutdown active VMs - * XXX allow them to stay around & reconnect */ - virDomainObjListForEach(uml_driver->domains, umlShutdownOneVM, uml_dri= ver); - - virObjectUnref(uml_driver->domains); - - virObjectUnref(uml_driver->domainEventState); - - VIR_FREE(uml_driver->logDir); - VIR_FREE(uml_driver->configDir); - VIR_FREE(uml_driver->autostartDir); - VIR_FREE(uml_driver->monitorDir); - - umlProcessAutoDestroyShutdown(uml_driver); - - umlDriverUnlock(uml_driver); - virMutexDestroy(¨_driver->lock); - VIR_FREE(uml_driver); - - return 0; -} - - -static int umlProcessAutoDestroyInit(struct uml_driver *driver) -{ - if (!(driver->autodestroy =3D virHashCreate(5, NULL))) - return -1; - - return 0; -} - -struct umlProcessAutoDestroyData { - struct uml_driver *driver; - virConnectPtr conn; -}; - -static int umlProcessAutoDestroyDom(void *payload, - const void *name, - void *opaque) -{ - struct umlProcessAutoDestroyData *data =3D opaque; - virConnectPtr conn =3D payload; - const char *uuidstr =3D name; - unsigned char uuid[VIR_UUID_BUFLEN]; - virDomainObjPtr dom; - virObjectEventPtr event =3D NULL; - - VIR_DEBUG("conn=3D%p uuidstr=3D%s thisconn=3D%p", conn, uuidstr, data-= >conn); - - if (data->conn !=3D conn) - return 0; - - if (virUUIDParse(uuidstr, uuid) < 0) { - VIR_WARN("Failed to parse %s", uuidstr); - return 0; - } - - if (!(dom =3D virDomainObjListFindByUUID(data->driver->domains, uuid))= ) { - VIR_DEBUG("No domain object to kill"); - return 0; - } - - VIR_DEBUG("Killing domain"); - umlShutdownVMDaemon(data->driver, dom, VIR_DOMAIN_SHUTOFF_DESTROYED); - virDomainAuditStop(dom, "destroyed"); - event =3D virDomainEventLifecycleNewFromObj(dom, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - - if (!dom->persistent) - virDomainObjListRemove(data->driver->domains, dom); - - virDomainObjEndAPI(&dom); - virObjectEventStateQueue(data->driver->domainEventState, event); - virHashRemoveEntry(data->driver->autodestroy, uuidstr); - return 0; -} - -/* - * Precondition: driver is locked - */ -static void umlProcessAutoDestroyRun(struct uml_driver *driver, virConnect= Ptr conn) -{ - struct umlProcessAutoDestroyData data =3D { - driver, conn - }; - VIR_DEBUG("conn=3D%p", conn); - virHashForEach(driver->autodestroy, umlProcessAutoDestroyDom, &data); -} - -static void umlProcessAutoDestroyShutdown(struct uml_driver *driver) -{ - virHashFree(driver->autodestroy); -} - -static int umlProcessAutoDestroyAdd(struct uml_driver *driver, - virDomainObjPtr vm, - virConnectPtr conn) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - VIR_DEBUG("vm=3D%s uuid=3D%s conn=3D%p", vm->def->name, uuidstr, conn); - if (virHashAddEntry(driver->autodestroy, uuidstr, conn) < 0) - return -1; - return 0; -} - -static int umlProcessAutoDestroyRemove(struct uml_driver *driver, - virDomainObjPtr vm) -{ - char uuidstr[VIR_UUID_STRING_BUFLEN]; - virUUIDFormat(vm->def->uuid, uuidstr); - VIR_DEBUG("vm=3D%s uuid=3D%s", vm->def->name, uuidstr); - if (virHashRemoveEntry(driver->autodestroy, uuidstr) < 0) - return -1; - return 0; -} - - -static int umlReadPidFile(struct uml_driver *driver, - virDomainObjPtr vm) -{ - int rc =3D -1; - FILE *file; - char *pidfile =3D NULL; - int retries =3D 0; - - vm->pid =3D -1; - if (virAsprintf(&pidfile, "%s/%s/pid", - driver->monitorDir, vm->def->name) < 0) - return -1; - - reopen: - if (!(file =3D fopen(pidfile, "r"))) { - if (errno =3D=3D ENOENT && - retries++ < 50) { - usleep(1000 * 100); - goto reopen; - } - goto cleanup; - } - - if (fscanf(file, "%d", &vm->pid) !=3D 1) { - errno =3D EINVAL; - VIR_FORCE_FCLOSE(file); - goto cleanup; - } - - if (VIR_FCLOSE(file) < 0) - goto cleanup; - - rc =3D 0; - - cleanup: - if (rc !=3D 0) - virReportSystemError(errno, - _("failed to read pid: %s"), - pidfile); - VIR_FREE(pidfile); - return rc; -} - -static int umlMonitorAddress(const struct uml_driver *driver, - const virDomainObj *vm, - struct sockaddr_un *addr) -{ - char *sockname; - int retval =3D 0; - - if (virAsprintf(&sockname, "%s/%s/mconsole", - driver->monitorDir, vm->def->name) < 0) - return -1; - - memset(addr, 0, sizeof(*addr)); - addr->sun_family =3D AF_UNIX; - if (virStrcpyStatic(addr->sun_path, sockname) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Unix path %s too long for destination"), socknam= e); - retval =3D -1; - } - VIR_FREE(sockname); - return retval; -} - -static int umlOpenMonitor(struct uml_driver *driver, - virDomainObjPtr vm) -{ - struct sockaddr_un addr; - struct stat sb; - int retries =3D 0; - umlDomainObjPrivatePtr priv =3D vm->privateData; - - if (umlMonitorAddress(driver, vm, &addr) < 0) - return -1; - - VIR_DEBUG("Dest address for monitor is '%s'", addr.sun_path); - restat: - if (stat(addr.sun_path, &sb) < 0) { - if (errno =3D=3D ENOENT && - retries++ < 50) { - usleep(1000 * 100); - goto restat; - } - return -1; - } - - if ((priv->monitor =3D socket(PF_UNIX, SOCK_DGRAM, 0)) < 0) { - virReportSystemError(errno, - "%s", _("cannot open socket")); - return -1; - } - - memset(addr.sun_path, 0, sizeof(addr.sun_path)); - snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1, - "libvirt-uml-%u", vm->pid); - VIR_DEBUG("Reply address for monitor is '%s'", addr.sun_path+1); - if (bind(priv->monitor, (struct sockaddr *)&addr, sizeof(addr)) < 0) { - virReportSystemError(errno, - "%s", _("cannot bind socket")); - VIR_FORCE_CLOSE(priv->monitor); - return -1; - } - - return 0; -} - - -#define MONITOR_MAGIC 0xcafebabe -#define MONITOR_BUFLEN 512 -#define MONITOR_VERSION 2 - -struct monitor_request { - uint32_t magic; - uint32_t version; - uint32_t length; - char data[MONITOR_BUFLEN]; -}; - -struct monitor_response { - uint32_t error; - uint32_t extra; - uint32_t length; - char data[MONITOR_BUFLEN]; -}; - - -static int umlMonitorCommand(const struct uml_driver *driver, - const virDomainObj *vm, - const char *cmd, - char **reply) -{ - struct monitor_request req; - struct monitor_response res; - char *retdata =3D NULL; - int retlen =3D 0, ret =3D 0; - struct sockaddr_un addr; - unsigned int addrlen; - umlDomainObjPrivatePtr priv =3D vm->privateData; - - VIR_DEBUG("Run command '%s'", cmd); - - *reply =3D NULL; - - if (umlMonitorAddress(driver, vm, &addr) < 0) - return -1; - - memset(&req, 0, sizeof(req)); - req.magic =3D MONITOR_MAGIC; - req.version =3D MONITOR_VERSION; - req.length =3D strlen(cmd); - if (req.length > (MONITOR_BUFLEN-1)) { - virReportSystemError(EINVAL, - _("cannot send too long command %s (%d bytes)= "), - cmd, req.length); - return -1; - } - if (virStrcpyStatic(req.data, cmd) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("Command %s too long for destination"), cmd); - return -1; - } - - if (sendto(priv->monitor, &req, sizeof(req), 0, - (struct sockaddr *)&addr, sizeof(addr)) !=3D sizeof(req)) { - virReportSystemError(errno, - _("cannot send command %s"), - cmd); - return -1; - } - - do { - ssize_t nbytes; - addrlen =3D sizeof(addr); - nbytes =3D recvfrom(priv->monitor, &res, sizeof(res), 0, - (struct sockaddr *)&addr, &addrlen); - if (nbytes < 0) { - if (errno =3D=3D EAGAIN || errno =3D=3D EINTR) - continue; - virReportSystemError(errno, _("cannot read reply %s"), cmd); - goto error; - } - /* Ensure res.length is safe to read before validating its value. = */ - if (nbytes < offsetof(struct monitor_request, data) || - nbytes < offsetof(struct monitor_request, data) + res.length) { - virReportSystemError(0, _("incomplete reply %s"), cmd); - goto error; - } - - if (VIR_REALLOC_N(retdata, retlen + res.length) < 0) - goto error; - memcpy(retdata + retlen, res.data, res.length); - retlen +=3D res.length - 1; - retdata[retlen] =3D '\0'; - - if (res.error) - ret =3D -1; - - } while (res.extra); - - VIR_DEBUG("Command reply is '%s'", NULLSTR(retdata)); - - if (ret < 0) - VIR_FREE(retdata); - else - *reply =3D retdata; - - return ret; - - error: - VIR_FREE(retdata); - return -1; -} - - -static void umlCleanupTapDevices(virDomainObjPtr vm) -{ - size_t i; - - for (i =3D 0; i < vm->def->nnets; i++) { - virDomainNetDefPtr def =3D vm->def->nets[i]; - - if (def->type !=3D VIR_DOMAIN_NET_TYPE_BRIDGE && - def->type !=3D VIR_DOMAIN_NET_TYPE_NETWORK) - continue; - - ignore_value(virNetDevTapDelete(def->ifname, - def->backend.tap)); - } -} - -static int umlStartVMDaemon(virConnectPtr conn, - struct uml_driver *driver, - virDomainObjPtr vm, - bool autoDestroy) -{ - int ret =3D -1; - char *logfile; - int logfd =3D -1; - umlDomainObjPrivatePtr priv =3D vm->privateData; - virCommandPtr cmd =3D NULL; - size_t i; - - if (virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("VM is already active")); - return -1; - } - - if (!vm->def->os.kernel) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("no kernel specified")); - return -1; - } - /* Make sure the binary we are about to try exec'ing exists. - * Technically we could catch the exec() failure, but that's - * in a sub-process so its hard to feed back a useful error - */ - if (!virFileIsExecutable(vm->def->os.kernel)) { - virReportSystemError(errno, - _("Cannot find UML kernel %s"), - vm->def->os.kernel); - return -1; - } - - if (virFileMakePath(driver->logDir) < 0) { - virReportSystemError(errno, - _("cannot create log directory %s"), - driver->logDir); - return -1; - } - - if (virAsprintf(&logfile, "%s/%s.log", - driver->logDir, vm->def->name) < 0) - return -1; - - if ((logfd =3D open(logfile, O_CREAT | O_TRUNC | O_WRONLY, - S_IRUSR | S_IWUSR)) < 0) { - virReportSystemError(errno, - _("failed to create logfile %s"), - logfile); - VIR_FREE(logfile); - return -1; - } - VIR_FREE(logfile); - - if (virSetCloseExec(logfd) < 0) { - virReportSystemError(errno, "%s", - _("Unable to set VM logfile close-on-exec fla= g")); - VIR_FORCE_CLOSE(logfd); - return -1; - } - - /* Do this upfront, so any part of the startup process can add - * runtime state to vm->def that won't be persisted. This let's us - * report implicit runtime defaults in the XML, like vnc listen/socket - */ - VIR_DEBUG("Setting current domain def as transient"); - if (virDomainObjSetDefTransient(driver->caps, driver->xmlopt, vm) < 0)= { - VIR_FORCE_CLOSE(logfd); - return -1; - } - - if (!(cmd =3D umlBuildCommandLine(conn, driver, vm))) - goto cleanup; - - for (i =3D 0; i < vm->def->nconsoles; i++) { - VIR_FREE(vm->def->consoles[i]->info.alias); - if (virAsprintf(&vm->def->consoles[i]->info.alias, "console%zu", i= ) < 0) - goto cleanup; - } - - virCommandWriteArgLog(cmd, logfd); - - priv->monitor =3D -1; - - virCommandClearCaps(cmd); - virCommandSetOutputFD(cmd, &logfd); - virCommandSetErrorFD(cmd, &logfd); - virCommandDaemonize(cmd); - - if (virCommandRun(cmd, NULL) < 0) - goto cleanup; - - if (autoDestroy && - umlProcessAutoDestroyAdd(driver, vm, conn) < 0) - goto cleanup; - - ret =3D 0; - cleanup: - VIR_FORCE_CLOSE(logfd); - virCommandFree(cmd); - - if (ret < 0) { - virDomainConfVMNWFilterTeardown(vm); - umlCleanupTapDevices(vm); - virDomainObjRemoveTransientDef(vm); - } - - /* NB we don't mark it running here - we do that async - with inotify */ - /* XXX what if someone else tries to start it again - before we get the inotification ? Sounds like - trouble.... */ - /* XXX this is bad for events too. must fix this better */ - - return ret; -} - -static void umlShutdownVMDaemon(struct uml_driver *driver, - virDomainObjPtr vm, - virDomainShutoffReason reason) -{ - int ret; - umlDomainObjPrivatePtr priv =3D vm->privateData; - - if (!virDomainObjIsActive(vm)) - return; - - virProcessKill(vm->pid, SIGTERM); - - VIR_FORCE_CLOSE(priv->monitor); - - if ((ret =3D waitpid(vm->pid, NULL, 0)) !=3D vm->pid) { - VIR_WARN("Got unexpected pid %d !=3D %d", - ret, vm->pid); - } - - vm->pid =3D -1; - vm->def->id =3D -1; - virDomainObjSetState(vm, VIR_DOMAIN_SHUTOFF, reason); - - virDomainConfVMNWFilterTeardown(vm); - umlCleanupTapDevices(vm); - - /* Stop autodestroy in case guest is restarted */ - umlProcessAutoDestroyRemove(driver, vm); - - virDomainObjRemoveTransientDef(vm); - - driver->nactive--; - if (!driver->nactive && driver->inhibitCallback) - driver->inhibitCallback(false, driver->inhibitOpaque); -} - - -static int umlConnectURIProbe(char **uri) -{ - if (uml_driver =3D=3D NULL) - return 0; - - return VIR_STRDUP(*uri, uml_driver->privileged ? - "uml:///system" : - "uml:///session"); -} - - -static virDrvOpenStatus umlConnectOpen(virConnectPtr conn, - virConnectAuthPtr auth ATTRIBUTE_UN= USED, - virConfPtr conf ATTRIBUTE_UNUSED, - unsigned int flags) -{ - virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR); - - /* URI was good, but driver isn't active */ - if (uml_driver =3D=3D NULL) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("uml state driver is not active")); - return VIR_DRV_OPEN_ERROR; - } - - /* Check path and tell them correct path if they made a mistake */ - if (uml_driver->privileged) { - if (STRNEQ(conn->uri->path, "/system") && - STRNEQ(conn->uri->path, "/session")) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected UML URI path '%s', try uml:///sys= tem"), - conn->uri->path); - return VIR_DRV_OPEN_ERROR; - } - } else { - if (STRNEQ(conn->uri->path, "/session")) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected UML URI path '%s', try uml:///ses= sion"), - conn->uri->path); - return VIR_DRV_OPEN_ERROR; - } - } - - if (virConnectOpenEnsureACL(conn) < 0) - return VIR_DRV_OPEN_ERROR; - - conn->privateData =3D uml_driver; - - return VIR_DRV_OPEN_SUCCESS; -} - -static int umlConnectClose(virConnectPtr conn) -{ - struct uml_driver *driver =3D conn->privateData; - - umlDriverLock(driver); - umlProcessAutoDestroyRun(driver, conn); - umlDriverUnlock(driver); - - conn->privateData =3D NULL; - - return 0; -} - -static const char *umlConnectGetType(virConnectPtr conn) { - if (virConnectGetTypeEnsureACL(conn) < 0) - return NULL; - - return "UML"; -} - - -static int umlConnectIsSecure(virConnectPtr conn ATTRIBUTE_UNUSED) -{ - /* Trivially secure, since always inside the daemon */ - return 1; -} - - -static int umlConnectIsEncrypted(virConnectPtr conn ATTRIBUTE_UNUSED) -{ - /* Not encrypted, but remote driver takes care of that */ - return 0; -} - - -static int umlConnectIsAlive(virConnectPtr conn ATTRIBUTE_UNUSED) -{ - return 1; -} - - -static char *umlConnectGetCapabilities(virConnectPtr conn) { - struct uml_driver *driver =3D (struct uml_driver *)conn->privateData; - char *xml; - - if (virConnectGetCapabilitiesEnsureACL(conn) < 0) - return NULL; - - umlDriverLock(driver); - xml =3D virCapabilitiesFormatXML(driver->caps); - umlDriverUnlock(driver); - - return xml; -} - - - -static int umlGetProcessInfo(unsigned long long *cpuTime, pid_t pid) -{ - char *proc; - FILE *pidinfo; - unsigned long long usertime, systime; - - if (virAsprintf(&proc, "/proc/%lld/stat", (long long)pid) < 0) - return -1; - - if (!(pidinfo =3D fopen(proc, "r"))) { - /* VM probably shut down, so fake 0 */ - *cpuTime =3D 0; - VIR_FREE(proc); - return 0; - } - - VIR_FREE(proc); - - if (fscanf(pidinfo, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %= *u %llu %llu", &usertime, &systime) !=3D 2) { - umlDebug("not enough arg"); - VIR_FORCE_FCLOSE(pidinfo); - return -1; - } - - /* We got jiffies - * We want nanoseconds - * _SC_CLK_TCK is jiffies per second - * So calculate thus.... - */ - *cpuTime =3D 1000ull * 1000ull * 1000ull * (usertime + systime) / (uns= igned long long)sysconf(_SC_CLK_TCK); - - umlDebug("Got %llu %llu %llu", usertime, systime, *cpuTime); - - VIR_FORCE_FCLOSE(pidinfo); - - return 0; -} - - -static virDomainPtr umlDomainLookupByID(virConnectPtr conn, - int id) -{ - struct uml_driver *driver =3D (struct uml_driver *)conn->privateData; - virDomainObjPtr vm; - virDomainPtr dom =3D NULL; - - umlDriverLock(driver); - vm =3D virDomainObjListFindByID(driver->domains, id); - umlDriverUnlock(driver); - - if (!vm) { - virReportError(VIR_ERR_NO_DOMAIN, - _("no domain with matching id '%d'"), id); - goto cleanup; - } - - if (virDomainLookupByIDEnsureACL(conn, vm->def) < 0) - goto cleanup; - - dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); - - cleanup: - virDomainObjEndAPI(&vm); - return dom; -} - -static virDomainPtr umlDomainLookupByUUID(virConnectPtr conn, - const unsigned char *uuid) -{ - struct uml_driver *driver =3D (struct uml_driver *)conn->privateData; - virDomainObjPtr vm; - virDomainPtr dom =3D NULL; - - if (!(vm =3D umlDomObjFromDomain(driver, uuid))) - return NULL; - - if (virDomainLookupByUUIDEnsureACL(conn, vm->def) < 0) - goto cleanup; - - dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); - - cleanup: - virDomainObjEndAPI(&vm); - return dom; -} - -static virDomainPtr umlDomainLookupByName(virConnectPtr conn, - const char *name) -{ - struct uml_driver *driver =3D (struct uml_driver *)conn->privateData; - virDomainObjPtr vm; - virDomainPtr dom =3D NULL; - - umlDriverLock(driver); - vm =3D virDomainObjListFindByName(driver->domains, name); - umlDriverUnlock(driver); - - if (!vm) { - virReportError(VIR_ERR_NO_DOMAIN, - _("no domain with matching name '%s'"), name); - goto cleanup; - } - - if (virDomainLookupByNameEnsureACL(conn, vm->def) < 0) - goto cleanup; - - dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); - - cleanup: - virDomainObjEndAPI(&vm); - return dom; -} - - -static int umlDomainIsActive(virDomainPtr dom) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr obj; - int ret =3D -1; - - if (!(obj =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainIsActiveEnsureACL(dom->conn, obj->def) < 0) - goto cleanup; - - ret =3D virDomainObjIsActive(obj); - - cleanup: - virDomainObjEndAPI(&obj); - return ret; -} - - -static int umlDomainIsPersistent(virDomainPtr dom) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr obj; - int ret =3D -1; - - if (!(obj =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainIsPersistentEnsureACL(dom->conn, obj->def) < 0) - goto cleanup; - - ret =3D obj->persistent; - - cleanup: - virDomainObjEndAPI(&obj); - return ret; -} - -static int umlDomainIsUpdated(virDomainPtr dom) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr obj; - int ret =3D -1; - - if (!(obj =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainIsUpdatedEnsureACL(dom->conn, obj->def) < 0) - goto cleanup; - - ret =3D obj->updated; - - cleanup: - virDomainObjEndAPI(&obj); - return ret; -} - -static int umlConnectGetVersion(virConnectPtr conn, unsigned long *version) -{ - struct uml_driver *driver =3D conn->privateData; - struct utsname ut; - int ret =3D -1; - - if (virConnectGetVersionEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - - if (driver->umlVersion =3D=3D 0) { - uname(&ut); - - if (virParseVersionString(ut.release, &driver->umlVersion, true) <= 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot parse version %s"), ut.release); - goto cleanup; - } - } - - *version =3D driver->umlVersion; - ret =3D 0; - - cleanup: - umlDriverUnlock(driver); - return ret; -} - - -static char *umlConnectGetHostname(virConnectPtr conn) -{ - if (virConnectGetHostnameEnsureACL(conn) < 0) - return NULL; - - return virGetHostname(); -} - - -static int umlConnectListDomains(virConnectPtr conn, int *ids, int nids) -{ - struct uml_driver *driver =3D conn->privateData; - int n; - - if (virConnectListDomainsEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - n =3D virDomainObjListGetActiveIDs(driver->domains, ids, nids, - virConnectListDomainsCheckACL, conn); - umlDriverUnlock(driver); - - return n; -} -static int umlConnectNumOfDomains(virConnectPtr conn) -{ - struct uml_driver *driver =3D conn->privateData; - int n; - - if (virConnectNumOfDomainsEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - n =3D virDomainObjListNumOfDomains(driver->domains, true, - virConnectNumOfDomainsCheckACL, conn); - umlDriverUnlock(driver); - - return n; -} -static virDomainPtr umlDomainCreateXML(virConnectPtr conn, const char *xml, - unsigned int flags) -{ - struct uml_driver *driver =3D conn->privateData; - virDomainDefPtr def; - virDomainObjPtr vm =3D NULL; - virDomainPtr dom =3D NULL; - virObjectEventPtr event =3D NULL; - unsigned int parse_flags =3D VIR_DOMAIN_DEF_PARSE_INACTIVE; - - virCheckFlags(VIR_DOMAIN_START_AUTODESTROY | - VIR_DOMAIN_START_VALIDATE, NULL); - - if (flags & VIR_DOMAIN_START_VALIDATE) - parse_flags |=3D VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA; - - virNWFilterReadLockFilterUpdates(); - umlDriverLock(driver); - if (!(def =3D virDomainDefParseString(xml, driver->caps, driver->xmlop= t, - NULL, parse_flags))) - goto cleanup; - - if (virDomainCreateXMLEnsureACL(conn, def) < 0) - goto cleanup; - - if (!(vm =3D virDomainObjListAdd(driver->domains, def, - driver->xmlopt, - VIR_DOMAIN_OBJ_LIST_ADD_LIVE | - VIR_DOMAIN_OBJ_LIST_ADD_CHECK_LIVE, - NULL))) - goto cleanup; - def =3D NULL; - - if (umlStartVMDaemon(conn, driver, vm, - (flags & VIR_DOMAIN_START_AUTODESTROY)) < 0) { - virDomainAuditStart(vm, "booted", false); - if (!vm->persistent) - virDomainObjListRemove(driver->domains, vm); - goto cleanup; - } - virDomainAuditStart(vm, "booted", true); - event =3D virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_STARTED, - VIR_DOMAIN_EVENT_STARTED_BOOTED); - - dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); - - cleanup: - virDomainDefFree(def); - virDomainObjEndAPI(&vm); - virObjectEventStateQueue(driver->domainEventState, event); - umlDriverUnlock(driver); - virNWFilterUnlockFilterUpdates(); - return dom; -} - - -static int umlDomainShutdownFlags(virDomainPtr dom, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - char *info =3D NULL; - int ret =3D -1; - - virCheckFlags(0, -1); - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainShutdownFlagsEnsureACL(dom->conn, vm->def, flags) < 0) - goto cleanup; - -#if 0 - if (umlMonitorCommand(driver, vm, "system_powerdown", &info) < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("shutdown operation failed")); - goto cleanup; - } - ret =3D 0; -#endif - - cleanup: - VIR_FREE(info); - virDomainObjEndAPI(&vm); - return ret; -} - -static int -umlDomainShutdown(virDomainPtr dom) -{ - return umlDomainShutdownFlags(dom, 0); -} - -static int -umlDomainDestroyFlags(virDomainPtr dom, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - virObjectEventPtr event =3D NULL; - int ret =3D -1; - - virCheckFlags(0, -1); - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - return -1; - - if (virDomainDestroyFlagsEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - umlShutdownVMDaemon(driver, vm, VIR_DOMAIN_SHUTOFF_DESTROYED); - virDomainAuditStop(vm, "destroyed"); - event =3D virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_STOPPED, - VIR_DOMAIN_EVENT_STOPPED_DESTROYED); - if (!vm->persistent) - virDomainObjListRemove(driver->domains, vm); - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - virObjectEventStateQueue(driver->domainEventState, event); - umlDriverUnlock(driver); - return ret; -} - - -static int umlDomainDestroy(virDomainPtr dom) -{ - return umlDomainDestroyFlags(dom, 0); -} - - -static char *umlDomainGetOSType(virDomainPtr dom) { - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - char *type =3D NULL; - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return NULL; - - if (virDomainGetOSTypeEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (VIR_STRDUP(type, virDomainOSTypeToString(vm->def->os.type)) < 0) - goto cleanup; - - cleanup: - virDomainObjEndAPI(&vm); - return type; -} - -/* Returns max memory in kb, 0 if error */ -static unsigned long long -umlDomainGetMaxMemory(virDomainPtr dom) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - unsigned long long ret =3D 0; - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainGetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - ret =3D virDomainDefGetMemoryTotal(vm->def); - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - -static int umlDomainSetMaxMemory(virDomainPtr dom, unsigned long newmax) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainSetMaxMemoryEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (newmax < vm->def->mem.cur_balloon) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("cannot set max memory lower than current memory"= )); - goto cleanup; - } - - virDomainDefSetMemoryTotal(vm->def, newmax); - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - -static int umlDomainSetMemory(virDomainPtr dom, unsigned long newmem) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainSetMemoryEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("cannot set memory of an active domain")); - goto cleanup; - } - - if (newmem > virDomainDefGetMemoryTotal(vm->def)) { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("cannot set memory higher than max memory")); - goto cleanup; - } - - vm->def->mem.cur_balloon =3D newmem; - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - -static int umlDomainGetInfo(virDomainPtr dom, - virDomainInfoPtr info) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainGetInfoEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - info->state =3D virDomainObjGetState(vm, NULL); - - if (!virDomainObjIsActive(vm)) { - info->cpuTime =3D 0; - } else { - if (umlGetProcessInfo(&(info->cpuTime), vm->pid) < 0) { - virReportError(VIR_ERR_OPERATION_FAILED, "%s", - _("cannot read cputime for domain")); - goto cleanup; - } - } - - info->maxMem =3D virDomainDefGetMemoryTotal(vm->def); - info->memory =3D vm->def->mem.cur_balloon; - info->nrVirtCpu =3D virDomainDefGetVcpus(vm->def); - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - - -static int -umlDomainGetState(virDomainPtr dom, - int *state, - int *reason, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - virCheckFlags(0, -1); - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainGetStateEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - *state =3D virDomainObjGetState(vm, reason); - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - - -static char *umlDomainGetXMLDesc(virDomainPtr dom, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - char *ret =3D NULL; - - /* Flags checked by virDomainDefFormat */ - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainGetXMLDescEnsureACL(dom->conn, vm->def, flags) < 0) - goto cleanup; - - ret =3D virDomainDefFormat((flags & VIR_DOMAIN_XML_INACTIVE) && vm->ne= wDef ? - vm->newDef : vm->def, driver->caps, - virDomainDefFormatConvertXMLFlags(flags)); - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - - -static int umlConnectListDefinedDomains(virConnectPtr conn, - char **const names, int nnames) { - struct uml_driver *driver =3D conn->privateData; - int n; - - if (virConnectListDefinedDomainsEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - n =3D virDomainObjListGetInactiveNames(driver->domains, names, nnames, - virConnectListDefinedDomainsCheck= ACL, conn); - umlDriverUnlock(driver); - - return n; -} - -static int umlConnectNumOfDefinedDomains(virConnectPtr conn) -{ - struct uml_driver *driver =3D conn->privateData; - int n; - - if (virConnectNumOfDefinedDomainsEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - n =3D virDomainObjListNumOfDomains(driver->domains, false, - virConnectNumOfDefinedDomainsCheckACL= , conn); - umlDriverUnlock(driver); - - return n; -} - - -static int umlDomainCreateWithFlags(virDomainPtr dom, unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - virObjectEventPtr event =3D NULL; - int ret =3D -1; - - virCheckFlags(VIR_DOMAIN_START_AUTODESTROY, -1); - - virNWFilterReadLockFilterUpdates(); - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainCreateWithFlagsEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - ret =3D umlStartVMDaemon(dom->conn, driver, vm, - (flags & VIR_DOMAIN_START_AUTODESTROY)); - virDomainAuditStart(vm, "booted", ret >=3D 0); - if (ret =3D=3D 0) - event =3D virDomainEventLifecycleNewFromObj(vm, - VIR_DOMAIN_EVENT_STARTED, - VIR_DOMAIN_EVENT_STARTED_BOOTED); - - cleanup: - virDomainObjEndAPI(&vm); - virObjectEventStateQueue(driver->domainEventState, event); - umlDriverUnlock(driver); - virNWFilterUnlockFilterUpdates(); - return ret; -} - -static int umlDomainCreate(virDomainPtr dom) -{ - return umlDomainCreateWithFlags(dom, 0); -} - -static virDomainPtr -umlDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int = flags) -{ - struct uml_driver *driver =3D conn->privateData; - virDomainDefPtr def; - virDomainObjPtr vm =3D NULL; - virDomainPtr dom =3D NULL; - unsigned int parse_flags =3D VIR_DOMAIN_DEF_PARSE_INACTIVE; - - virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL); - - if (flags & VIR_DOMAIN_DEFINE_VALIDATE) - parse_flags |=3D VIR_DOMAIN_DEF_PARSE_VALIDATE_SCHEMA; - - umlDriverLock(driver); - if (!(def =3D virDomainDefParseString(xml, driver->caps, driver->xmlop= t, - NULL, parse_flags))) - goto cleanup; - - if (virXMLCheckIllegalChars("name", def->name, "\n") < 0) - goto cleanup; - - if (virDomainDefineXMLFlagsEnsureACL(conn, def) < 0) - goto cleanup; - - if (!(vm =3D virDomainObjListAdd(driver->domains, def, - driver->xmlopt, - 0, NULL))) - goto cleanup; - def =3D NULL; - vm->persistent =3D 1; - - if (virDomainSaveConfig(driver->configDir, driver->caps, - vm->newDef ? vm->newDef : vm->def) < 0) { - virDomainObjListRemove(driver->domains, vm); - goto cleanup; - } - - dom =3D virGetDomain(conn, vm->def->name, vm->def->uuid, vm->def->id); - - cleanup: - virDomainDefFree(def); - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return dom; -} - -static virDomainPtr -umlDomainDefineXML(virConnectPtr conn, const char *xml) -{ - return umlDomainDefineXMLFlags(conn, xml, 0); -} - -static int umlDomainUndefineFlags(virDomainPtr dom, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - virCheckFlags(0, -1); - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainUndefineFlagsEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (!vm->persistent) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("cannot undefine transient domain")); - goto cleanup; - } - - if (virDomainDeleteConfig(driver->configDir, driver->autostartDir, vm)= < 0) - goto cleanup; - - if (virDomainObjIsActive(vm)) - vm->persistent =3D 0; - else - virDomainObjListRemove(driver->domains, vm); - - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - - -static int umlDomainUndefine(virDomainPtr dom) -{ - return umlDomainUndefineFlags(dom, 0); -} - -static int umlDomainAttachUmlDisk(struct uml_driver *driver, - virDomainObjPtr vm, - virDomainDiskDefPtr disk) -{ - size_t i; - char *cmd =3D NULL; - char *reply =3D NULL; - - for (i =3D 0; i < vm->def->ndisks; i++) { - if (STREQ(vm->def->disks[i]->dst, disk->dst)) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("target %s already exists"), disk->dst); - return -1; - } - } - - if (!virDomainDiskGetSource(disk)) { - virReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("disk source path is missing")); - goto error; - } - - if (virAsprintf(&cmd, "config %s=3D%s", disk->dst, - virDomainDiskGetSource(disk)) < 0) - return -1; - - if (umlMonitorCommand(driver, vm, cmd, &reply) < 0) - goto error; - - if (VIR_REALLOC_N(vm->def->disks, vm->def->ndisks+1) < 0) - goto error; - - virDomainDiskInsertPreAlloced(vm->def, disk); - - VIR_FREE(reply); - VIR_FREE(cmd); - - return 0; - - error: - - VIR_FREE(reply); - VIR_FREE(cmd); - - return -1; -} - - -static int umlDomainAttachDevice(virDomainPtr dom, const char *xml) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - virDomainDeviceDefPtr dev =3D NULL; - int ret =3D -1; - - umlDriverLock(driver); - - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainAttachDeviceEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (!virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cannot attach device on inactive domain")); - goto cleanup; - } - - dev =3D virDomainDeviceDefParse(xml, vm->def, driver->caps, driver->xm= lopt, - VIR_DOMAIN_DEF_PARSE_INACTIVE); - - if (dev =3D=3D NULL) - goto cleanup; - - if (dev->type =3D=3D VIR_DOMAIN_DEVICE_DISK) { - if (dev->data.disk->bus =3D=3D VIR_DOMAIN_DISK_BUS_UML) { - ret =3D umlDomainAttachUmlDisk(driver, vm, dev->data.disk); - if (ret =3D=3D 0) - dev->data.disk =3D NULL; - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("disk bus '%s' cannot be hotplugged."), - virDomainDiskBusTypeToString(dev->data.disk->bu= s)); - } - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("device type '%s' cannot be attached"), - virDomainDeviceTypeToString(dev->type)); - goto cleanup; - } - - cleanup: - - virDomainDeviceDefFree(dev); - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - - -static int -umlDomainAttachDeviceFlags(virDomainPtr dom, - const char *xml, - unsigned int flags) -{ - virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); - - if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cannot modify the persistent configuration= of a domain")); - return -1; - } - - return umlDomainAttachDevice(dom, xml); -} - - -static int umlDomainDetachUmlDisk(struct uml_driver *driver, - virDomainObjPtr vm, - virDomainDeviceDefPtr dev) -{ - size_t i; - int ret =3D -1; - virDomainDiskDefPtr detach =3D NULL; - char *cmd; - char *reply; - - for (i =3D 0; i < vm->def->ndisks; i++) { - if (STREQ(vm->def->disks[i]->dst, dev->data.disk->dst)) - break; - } - - if (i =3D=3D vm->def->ndisks) { - virReportError(VIR_ERR_OPERATION_FAILED, - _("disk %s not found"), dev->data.disk->dst); - return -1; - } - - detach =3D vm->def->disks[i]; - - if (virAsprintf(&cmd, "remove %s", detach->dst) < 0) - return -1; - - if (umlMonitorCommand(driver, vm, cmd, &reply) < 0) - goto cleanup; - - virDomainDiskRemove(vm->def, i); - - virDomainDiskDefFree(detach); - - ret =3D 0; - - VIR_FREE(reply); - - cleanup: - VIR_FREE(cmd); - - return ret; -} - - -static int umlDomainDetachDevice(virDomainPtr dom, const char *xml) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - virDomainDeviceDefPtr dev =3D NULL; - int ret =3D -1; - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainDetachDeviceEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (!virDomainObjIsActive(vm)) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cannot detach device on inactive domain")); - goto cleanup; - } - - dev =3D virDomainDeviceDefParse(xml, vm->def, driver->caps, driver->xm= lopt, - VIR_DOMAIN_DEF_PARSE_INACTIVE | - VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE); - if (dev =3D=3D NULL) - goto cleanup; - - if (dev->type =3D=3D VIR_DOMAIN_DEVICE_DISK && - dev->data.disk->device =3D=3D VIR_DOMAIN_DISK_DEVICE_DISK) { - if (dev->data.disk->bus =3D=3D VIR_DOMAIN_DISK_BUS_UML) - ret =3D umlDomainDetachUmlDisk(driver, vm, dev); - else - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", - _("This type of disk cannot be hot unplugged")); - } else { - virReportError(VIR_ERR_CONFIG_UNSUPPORTED, - "%s", _("This type of device cannot be hot unplugge= d")); - } - - cleanup: - virDomainDeviceDefFree(dev); - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - - -static int -umlDomainDetachDeviceFlags(virDomainPtr dom, - const char *xml, - unsigned int flags) -{ - virCheckFlags(VIR_DOMAIN_AFFECT_LIVE | VIR_DOMAIN_AFFECT_CONFIG, -1); - - if (flags & VIR_DOMAIN_AFFECT_CONFIG) { - virReportError(VIR_ERR_OPERATION_INVALID, - "%s", _("cannot modify the persistent configuration= of a domain")); - return -1; - } - - return umlDomainDetachDevice(dom, xml); -} - - -static int umlDomainGetAutostart(virDomainPtr dom, - int *autostart) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int ret =3D -1; - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainGetAutostartEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - *autostart =3D vm->autostart; - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - -static int umlDomainSetAutostart(virDomainPtr dom, - int autostart) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - char *configFile =3D NULL, *autostartLink =3D NULL; - int ret =3D -1; - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainSetAutostartEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (!vm->persistent) { - virReportError(VIR_ERR_OPERATION_INVALID, "%s", - _("cannot set autostart for transient domain")); - goto cleanup; - } - - autostart =3D (autostart !=3D 0); - - if (vm->autostart !=3D autostart) { - if ((configFile =3D virDomainConfigFile(driver->configDir, vm->def= ->name)) =3D=3D NULL) - goto cleanup; - if ((autostartLink =3D virDomainConfigFile(driver->autostartDir, v= m->def->name)) =3D=3D NULL) - goto cleanup; - - if (autostart) { - if (virFileMakePath(driver->autostartDir) < 0) { - virReportSystemError(errno, - _("cannot create autostart directory = %s"), - driver->autostartDir); - goto cleanup; - } - - if (symlink(configFile, autostartLink) < 0) { - virReportSystemError(errno, - _("Failed to create symlink '%s to '%= s'"), - autostartLink, configFile); - goto cleanup; - } - } else { - if (unlink(autostartLink) < 0 && errno !=3D ENOENT && errno != =3D ENOTDIR) { - virReportSystemError(errno, - _("Failed to delete symlink '%s'"), - autostartLink); - goto cleanup; - } - } - - vm->autostart =3D autostart; - } - ret =3D 0; - - cleanup: - VIR_FREE(configFile); - VIR_FREE(autostartLink); - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - - -static int -umlDomainBlockPeek(virDomainPtr dom, - const char *path, - unsigned long long offset, size_t size, - void *buffer, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm; - int fd =3D -1, ret =3D -1; - const char *actual; - - virCheckFlags(0, -1); - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainBlockPeekEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (!path || path[0] =3D=3D '\0') { - virReportError(VIR_ERR_INVALID_ARG, "%s", - _("NULL or empty path")); - goto cleanup; - } - - /* Check the path belongs to this domain. */ - if (!(actual =3D virDomainDiskPathByName(vm->def, path))) { - virReportError(VIR_ERR_INVALID_ARG, - _("invalid path '%s'"), path); - goto cleanup; - } - path =3D actual; - - /* The path is correct, now try to open it and get its size. */ - fd =3D open(path, O_RDONLY); - if (fd =3D=3D -1) { - virReportSystemError(errno, - _("cannot open %s"), path); - goto cleanup; - } - - /* Seek and read. */ - /* NB. Because we configure with AC_SYS_LARGEFILE, off_t should - * be 64 bits on all platforms. - */ - if (lseek(fd, offset, SEEK_SET) =3D=3D (off_t)-1 || - saferead(fd, buffer, size) =3D=3D (ssize_t)-1) { - virReportSystemError(errno, - _("cannot read %s"), path); - goto cleanup; - } - - ret =3D 0; - - cleanup: - VIR_FORCE_CLOSE(fd); - virDomainObjEndAPI(&vm); - return ret; -} - - -static int -umlDomainOpenConsole(virDomainPtr dom, - const char *dev_name, - virStreamPtr st, - unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - virDomainObjPtr vm =3D NULL; - int ret =3D -1; - virDomainChrDefPtr chr =3D NULL; - size_t i; - - virCheckFlags(0, -1); - - umlDriverLock(driver); - if (!(vm =3D umlDomObjFromDomainLocked(driver, dom->uuid))) - goto cleanup; - - if (virDomainOpenConsoleEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - if (virDomainObjCheckActive(vm) < 0) - goto cleanup; - - if (dev_name) { - for (i =3D 0; i < vm->def->nconsoles; i++) { - if (vm->def->consoles[i]->info.alias && - STREQ(vm->def->consoles[i]->info.alias, dev_name)) { - chr =3D vm->def->consoles[i]; - break; - } - } - } else { - if (vm->def->nconsoles) - chr =3D vm->def->consoles[0]; - else if (vm->def->nserials) - chr =3D vm->def->serials[0]; - } - - if (!chr) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("cannot find console device '%s'"), - dev_name ? dev_name : _("default")); - goto cleanup; - } - - if (chr->source->type !=3D VIR_DOMAIN_CHR_TYPE_PTY) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("character device %s is not using a PTY"), - dev_name ? dev_name : NULLSTR(chr->info.alias)); - goto cleanup; - } - - if (virFDStreamOpenFile(st, chr->source->data.file.path, - 0, 0, O_RDWR) < 0) - goto cleanup; - - ret =3D 0; - cleanup: - virDomainObjEndAPI(&vm); - umlDriverUnlock(driver); - return ret; -} - - -static int -umlConnectDomainEventRegister(virConnectPtr conn, - virConnectDomainEventCallback callback, - void *opaque, - virFreeCallback freecb) -{ - struct uml_driver *driver =3D conn->privateData; - int ret =3D 0; - - if (virConnectDomainEventRegisterEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - if (virDomainEventStateRegister(conn, - driver->domainEventState, - callback, opaque, freecb) < 0) - ret =3D -1; - umlDriverUnlock(driver); - - return ret; -} - -static int -umlConnectDomainEventDeregister(virConnectPtr conn, - virConnectDomainEventCallback callback) -{ - struct uml_driver *driver =3D conn->privateData; - int ret =3D 0; - - if (virConnectDomainEventDeregisterEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - if (virDomainEventStateDeregister(conn, - driver->domainEventState, - callback) < 0) - ret =3D -1; - umlDriverUnlock(driver); - - return ret; -} - -static int -umlConnectDomainEventRegisterAny(virConnectPtr conn, - virDomainPtr dom, - int eventID, - virConnectDomainEventGenericCallback call= back, - void *opaque, - virFreeCallback freecb) -{ - struct uml_driver *driver =3D conn->privateData; - int ret; - - if (virConnectDomainEventRegisterAnyEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - if (virDomainEventStateRegisterID(conn, - driver->domainEventState, - dom, eventID, - callback, opaque, freecb, &ret) < 0) - ret =3D -1; - umlDriverUnlock(driver); - - return ret; -} - - -static int -umlConnectDomainEventDeregisterAny(virConnectPtr conn, - int callbackID) -{ - struct uml_driver *driver =3D conn->privateData; - int ret =3D 0; - - if (virConnectDomainEventDeregisterAnyEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - if (virObjectEventStateDeregisterID(conn, - driver->domainEventState, - callbackID, true) < 0) - ret =3D -1; - umlDriverUnlock(driver); - - return ret; -} - - -static int umlConnectListAllDomains(virConnectPtr conn, - virDomainPtr **domains, - unsigned int flags) -{ - struct uml_driver *driver =3D conn->privateData; - int ret =3D -1; - - virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ALL, -1); - - if (virConnectListAllDomainsEnsureACL(conn) < 0) - return -1; - - umlDriverLock(driver); - ret =3D virDomainObjListExport(driver->domains, conn, domains, - virConnectListAllDomainsCheckACL, flags); - umlDriverUnlock(driver); - - return ret; -} - - -static int -umlNodeGetInfo(virConnectPtr conn, - virNodeInfoPtr nodeinfo) -{ - if (virNodeGetInfoEnsureACL(conn) < 0) - return -1; - - return virCapabilitiesGetNodeInfo(nodeinfo); -} - - -static int -umlNodeGetCPUStats(virConnectPtr conn, - int cpuNum, - virNodeCPUStatsPtr params, - int *nparams, - unsigned int flags) -{ - if (virNodeGetCPUStatsEnsureACL(conn) < 0) - return -1; - - return virHostCPUGetStats(cpuNum, params, nparams, flags); -} - - -static int -umlNodeGetMemoryStats(virConnectPtr conn, - int cellNum, - virNodeMemoryStatsPtr params, - int *nparams, - unsigned int flags) -{ - if (virNodeGetMemoryStatsEnsureACL(conn) < 0) - return -1; - - return virHostMemGetStats(cellNum, params, nparams, flags); -} - - -static int -umlNodeGetCellsFreeMemory(virConnectPtr conn, - unsigned long long *freeMems, - int startCell, - int maxCells) -{ - if (virNodeGetCellsFreeMemoryEnsureACL(conn) < 0) - return -1; - - return virHostMemGetCellsFree(freeMems, startCell, maxCells); -} - - -static unsigned long long -umlNodeGetFreeMemory(virConnectPtr conn) -{ - unsigned long long freeMem; - - if (virNodeGetFreeMemoryEnsureACL(conn) < 0) - return 0; - - if (virHostMemGetInfo(NULL, &freeMem) < 0) - return 0; - - return freeMem; -} - - -static int -umlNodeGetMemoryParameters(virConnectPtr conn, - virTypedParameterPtr params, - int *nparams, - unsigned int flags) -{ - if (virNodeGetMemoryParametersEnsureACL(conn) < 0) - return -1; - - return virHostMemGetParameters(params, nparams, flags); -} - - -static int -umlNodeSetMemoryParameters(virConnectPtr conn, - virTypedParameterPtr params, - int nparams, - unsigned int flags) -{ - if (virNodeSetMemoryParametersEnsureACL(conn) < 0) - return -1; - - return virHostMemSetParameters(params, nparams, flags); -} - - -static int -umlNodeGetCPUMap(virConnectPtr conn, - unsigned char **cpumap, - unsigned int *online, - unsigned int flags) -{ - if (virNodeGetCPUMapEnsureACL(conn) < 0) - return -1; - - return virHostCPUGetMap(cpumap, online, flags); -} - - -static int -umlNodeSuspendForDuration(virConnectPtr conn, - unsigned int target, - unsigned long long duration, - unsigned int flags) -{ - if (virNodeSuspendForDurationEnsureACL(conn) < 0) - return -1; - - return virNodeSuspend(target, duration, flags); -} - - -static int -umlNodeGetFreePages(virConnectPtr conn, - unsigned int npages, - unsigned int *pages, - int startCell, - unsigned int cellCount, - unsigned long long *counts, - unsigned int flags) -{ - virCheckFlags(0, -1); - - if (virNodeGetFreePagesEnsureACL(conn) < 0) - return -1; - - return virHostMemGetFreePages(npages, pages, startCell, cellCount, cou= nts); -} - - -static int -umlNodeAllocPages(virConnectPtr conn, - unsigned int npages, - unsigned int *pageSizes, - unsigned long long *pageCounts, - int startCell, - unsigned int cellCount, - unsigned int flags) -{ - bool add =3D !(flags & VIR_NODE_ALLOC_PAGES_SET); - - virCheckFlags(VIR_NODE_ALLOC_PAGES_SET, -1); - - if (virNodeAllocPagesEnsureACL(conn) < 0) - return -1; - - return virHostMemAllocPages(npages, pageSizes, pageCounts, - startCell, cellCount, add); -} - - -static int -umlDomainHasManagedSaveImage(virDomainPtr dom, unsigned int flags) -{ - struct uml_driver *driver =3D dom->conn->privateData; - int ret =3D -1; - virDomainObjPtr vm; - - virCheckFlags(0, -1); - - if (!(vm =3D umlDomObjFromDomain(driver, dom->uuid))) - return -1; - - if (virDomainHasManagedSaveImageEnsureACL(dom->conn, vm->def) < 0) - goto cleanup; - - ret =3D 0; - - cleanup: - virDomainObjEndAPI(&vm); - return ret; -} - - -static virHypervisorDriver umlHypervisorDriver =3D { - .name =3D "UML", - .connectURIProbe =3D umlConnectURIProbe, - .connectOpen =3D umlConnectOpen, /* 0.5.0 */ - .connectClose =3D umlConnectClose, /* 0.5.0 */ - .connectGetType =3D umlConnectGetType, /* 0.5.0 */ - .connectGetVersion =3D umlConnectGetVersion, /* 0.5.0 */ - .connectGetHostname =3D umlConnectGetHostname, /* 0.5.0 */ - .nodeGetInfo =3D umlNodeGetInfo, /* 0.5.0 */ - .connectGetCapabilities =3D umlConnectGetCapabilities, /* 0.5.0 */ - .connectListDomains =3D umlConnectListDomains, /* 0.5.0 */ - .connectNumOfDomains =3D umlConnectNumOfDomains, /* 0.5.0 */ - .connectListAllDomains =3D umlConnectListAllDomains, /* 0.9.13 */ - .domainCreateXML =3D umlDomainCreateXML, /* 0.5.0 */ - .domainLookupByID =3D umlDomainLookupByID, /* 0.5.0 */ - .domainLookupByUUID =3D umlDomainLookupByUUID, /* 0.5.0 */ - .domainLookupByName =3D umlDomainLookupByName, /* 0.5.0 */ - .domainShutdown =3D umlDomainShutdown, /* 0.5.0 */ - .domainShutdownFlags =3D umlDomainShutdownFlags, /* 0.9.10 */ - .domainDestroy =3D umlDomainDestroy, /* 0.5.0 */ - .domainDestroyFlags =3D umlDomainDestroyFlags, /* 0.9.4 */ - .domainGetOSType =3D umlDomainGetOSType, /* 0.5.0 */ - .domainGetMaxMemory =3D umlDomainGetMaxMemory, /* 0.5.0 */ - .domainSetMaxMemory =3D umlDomainSetMaxMemory, /* 0.5.0 */ - .domainSetMemory =3D umlDomainSetMemory, /* 0.5.0 */ - .domainGetInfo =3D umlDomainGetInfo, /* 0.5.0 */ - .domainGetState =3D umlDomainGetState, /* 0.9.2 */ - .domainGetXMLDesc =3D umlDomainGetXMLDesc, /* 0.5.0 */ - .connectListDefinedDomains =3D umlConnectListDefinedDomains, /* 0.5.0 = */ - .connectNumOfDefinedDomains =3D umlConnectNumOfDefinedDomains, /* 0.5.= 0 */ - .domainCreate =3D umlDomainCreate, /* 0.5.0 */ - .domainCreateWithFlags =3D umlDomainCreateWithFlags, /* 0.8.2 */ - .domainDefineXML =3D umlDomainDefineXML, /* 0.5.0 */ - .domainDefineXMLFlags =3D umlDomainDefineXMLFlags, /* 1.2.12 */ - .domainUndefine =3D umlDomainUndefine, /* 0.5.0 */ - .domainUndefineFlags =3D umlDomainUndefineFlags, /* 0.9.4 */ - .domainAttachDevice =3D umlDomainAttachDevice, /* 0.8.4 */ - .domainAttachDeviceFlags =3D umlDomainAttachDeviceFlags, /* 0.8.4 */ - .domainDetachDevice =3D umlDomainDetachDevice, /* 0.8.4 */ - .domainDetachDeviceFlags =3D umlDomainDetachDeviceFlags, /* 0.8.4 */ - .domainGetAutostart =3D umlDomainGetAutostart, /* 0.5.0 */ - .domainSetAutostart =3D umlDomainSetAutostart, /* 0.5.0 */ - .domainBlockPeek =3D umlDomainBlockPeek, /* 0.5.0 */ - .nodeGetCPUStats =3D umlNodeGetCPUStats, /* 0.9.3 */ - .nodeGetMemoryStats =3D umlNodeGetMemoryStats, /* 0.9.3 */ - .nodeGetCellsFreeMemory =3D umlNodeGetCellsFreeMemory, /* 0.5.0 */ - .nodeGetFreeMemory =3D umlNodeGetFreeMemory, /* 0.5.0 */ - .nodeGetCPUMap =3D umlNodeGetCPUMap, /* 1.0.0 */ - .connectDomainEventRegister =3D umlConnectDomainEventRegister, /* 0.9.= 4 */ - .connectDomainEventDeregister =3D umlConnectDomainEventDeregister, /* = 0.9.4 */ - .connectIsEncrypted =3D umlConnectIsEncrypted, /* 0.7.3 */ - .connectIsSecure =3D umlConnectIsSecure, /* 0.7.3 */ - .domainIsActive =3D umlDomainIsActive, /* 0.7.3 */ - .domainIsPersistent =3D umlDomainIsPersistent, /* 0.7.3 */ - .domainIsUpdated =3D umlDomainIsUpdated, /* 0.8.6 */ - .connectDomainEventRegisterAny =3D umlConnectDomainEventRegisterAny, /= * 0.9.4 */ - .connectDomainEventDeregisterAny =3D umlConnectDomainEventDeregisterAn= y, /* 0.9.4 */ - .domainOpenConsole =3D umlDomainOpenConsole, /* 0.8.6 */ - .connectIsAlive =3D umlConnectIsAlive, /* 0.9.8 */ - .nodeSuspendForDuration =3D umlNodeSuspendForDuration, /* 0.9.8 */ - .nodeGetMemoryParameters =3D umlNodeGetMemoryParameters, /* 0.10.2 */ - .nodeSetMemoryParameters =3D umlNodeSetMemoryParameters, /* 0.10.2 */ - .nodeGetFreePages =3D umlNodeGetFreePages, /* 1.2.6 */ - .nodeAllocPages =3D umlNodeAllocPages, /* 1.2.9 */ - .domainHasManagedSaveImage =3D umlDomainHasManagedSaveImage, /* 1.2.13= */ -}; - -static virConnectDriver umlConnectDriver =3D { - .localOnly =3D true, - .uriSchemes =3D (const char *[]){ "uml", NULL }, - .hypervisorDriver =3D ¨HypervisorDriver, -}; - -static virStateDriver umlStateDriver =3D { - .name =3D "UML", - .stateInitialize =3D umlStateInitialize, - .stateAutoStart =3D umlStateAutoStart, - .stateCleanup =3D umlStateCleanup, - .stateReload =3D umlStateReload, -}; - -int umlRegister(void) -{ - if (virRegisterConnectDriver(¨ConnectDriver, - true) < 0) - return -1; - if (virRegisterStateDriver(¨StateDriver) < 0) - return -1; - return 0; -} diff --git a/src/uml/uml_driver.h b/src/uml/uml_driver.h deleted file mode 100644 index 3a258f6658..0000000000 --- a/src/uml/uml_driver.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * uml_driver.h: user mode Linux driver - * - * Copyright (C) 2006, 2007 Red Hat, Inc. - * Copyright (C) 2006-2008 Daniel P. Berrange - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library. If not, see - * . - */ - -#ifndef LIBVIRT_UML_DRIVER_H -# define LIBVIRT_UML_DRIVER_H - -# include "internal.h" - -int umlRegister(void); - -#endif /* LIBVIRT_UML_DRIVER_H */ diff --git a/tests/domaincapsschemadata/basic.xml b/tests/domaincapsschemad= ata/basic.xml deleted file mode 100644 index 7bf4e56ae0..0000000000 --- a/tests/domaincapsschemadata/basic.xml +++ /dev/null @@ -1,25 +0,0 @@ - - /bin/emulatorbin - uml - my-machine-type - x86_64 - - - - - - - - - - - - - - - - - - diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c index ea4e57d118..7f52058bad 100644 --- a/tests/domaincapstest.c +++ b/tests/domaincapstest.c @@ -409,8 +409,6 @@ mymain(void) ret =3D -1; \ } while (0) =20 - DO_TEST("basic", "/bin/emulatorbin", "my-machine-type", - "x86_64", VIR_DOMAIN_VIRT_UML, CAPS_NONE); DO_TEST("full", "/bin/emulatorbin", "my-machine-type", "x86_64", VIR_DOMAIN_VIRT_KVM, CAPS_ALL); =20 diff --git a/tests/objectlocking.ml b/tests/objectlocking.ml index 778e67cffd..6726d29e73 100644 --- a/tests/objectlocking.ml +++ b/tests/objectlocking.ml @@ -121,7 +121,6 @@ let driverLockMethods =3D [ "openvzDriverLock"; "testDriverLock"; "lxcDriverLock"; - "umlDriverLock"; "nodedevDriverLock"; "networkDriverLock"; "storageDriverLock"; @@ -136,7 +135,6 @@ let driverUnlockMethods =3D [ "openvzDriverUnlock"; "testDriverUnlock"; "lxcDriverUnlock"; - "umlDriverUnlock"; "nodedevDriverUnlock"; "networkDriverUnlock"; "storageDriverUnlock"; @@ -153,7 +151,6 @@ let lockableDrivers =3D [ "openvz_driver"; "testConnPtr"; "lxc_driver_t"; - "uml_driver"; "virStorageDriverStatePtr"; "network_driver"; "virNodeDeviceState"; diff --git a/tests/virdrivermoduletest.c b/tests/virdrivermoduletest.c index 7e9dced87e..0d753cd0ee 100644 --- a/tests/virdrivermoduletest.c +++ b/tests/virdrivermoduletest.c @@ -89,9 +89,6 @@ mymain(void) #ifdef WITH_LXC TEST("lxc"); #endif -#ifdef WITH_UML - TEST("uml"); -#endif #ifdef WITH_VBOX TEST("vbox"); #endif diff --git a/tools/virsh.c b/tools/virsh.c index 09fa0f8a67..8428e539f6 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -518,9 +518,6 @@ virshShowVersion(vshControl *ctl ATTRIBUTE_UNUSED) #ifdef WITH_LXC vshPrint(ctl, " LXC"); #endif -#ifdef WITH_UML - vshPrint(ctl, " UML"); -#endif #ifdef WITH_LIBXL vshPrint(ctl, " LibXL"); #endif --=20 2.19.2 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list