1. 20 1月, 2014 6 次提交
  2. 17 1月, 2014 8 次提交
    • M
      virSecuritySELinuxSetFileconHelper: Don't fail on read-only NFS · d1fdecb6
      Michal Privoznik 提交于
      https://bugzilla.redhat.com/show_bug.cgi?id=996543
      
      When starting up a domain, the SELinux labeling is done depending on
      current configuration. If the labeling fails we check for possible
      causes, as not all labeling failures are fatal. For example, if the
      labeled file is on NFS which lacks SELinux support, the file can still
      be readable to qemu process. These cases are distinguished by the errno
      code: NFS without SELinux support returns EOPNOTSUPP. However, we were
      missing one scenario. In case there's a read-only disk on a read-only
      NFS (and possibly any FS) and the labeling is just optional (not
      explicitly requested in the XML) there's no need to make the labeling
      error fatal. In other words, read-only file on read-only NFS can fail to
      be labeled, but be readable at the same time.
      Signed-off-by: NMichal Privoznik <mprivozn@redhat.com>
      d1fdecb6
    • E
      maint: replace remaining virLib*Error with better names · 42358e3a
      Eric Blake 提交于
      Finish the cleanup of libvirt.c; all uses of virLib*Error have
      now been converted to more canonical conventions.
      
      * src/libvirt.c: Use virReportError in remaining errors.
      (virLibConnError, virLibDomainError): Delete unused macros.
      * cfg.mk (msg_gen_function): Drop unused names.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      42358e3a
    • E
      maint: simplify driver registration at startup · 323c2cc4
      Eric Blake 提交于
      We had a lot of repetition of errors that would occur if we
      ever register too many drivers; this is unlikely to occur
      unless we start adding a lot of new hypervisor modules, but
      if it does occur, it's better to have uniform handling of the
      situation, so that a one-line change is all that would be
      needed if we decide that an internal error is not the best.
      
      * src/libvirt.c (virDriverCheckTabMaxReturn): New define.
      (virRegister*Driver): Use it for less code duplication.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      323c2cc4
    • E
      maint: clean up error reporting in migration · 27553573
      Eric Blake 提交于
      The choice of error message and category was not consistent
      in the migration code; furthermore, the use of virLibConnError
      is no longer necessary now that we have a generic virReportError.
      
      * src/qemu/qemu_migration.c (virDomainMigrate*): Prefer
      virReportError over virLibConnError.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      27553573
    • E
      maint: don't lose error on canceled migration · c8ed177a
      Eric Blake 提交于
      While auditing the error reporting, I noticed that migration
      had some issues.  Some of the static helper functions tried
      to call virDispatchError(), even though their caller will also
      report the error.  Also, if a migration is cancelled early
      because a uri was not set, we did not guarantee that the finish
      stage would not overwrite the first error message.
      
      * src/qemu/qemu_migration.c (doPeer2PeerMigrate2)
      (doPeer2PeerMigrate3): Preserve first error when cancelling.
      * src/libvirt.c (virDomainMigrateVersion3Full): Likewise.
      (virDomainMigrateVersion1, virDomainMigrateVersion2)
      (virDomainMigrateDirect): Avoid redundant error dispatch.
      (virDomainMigrateFinish2, virDomainMigrateFinish3)
      (virDomainMigrateFinish3Params): Don't report error on cleanup
      path.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      c8ed177a
    • E
      maint: avoid nested use of virConnect{Ref,Close} · 25221a1b
      Eric Blake 提交于
      The public virConnectRef and virConnectClose API are just thin
      wrappers around virObjectRef/virObjectRef, with added object
      validation and an error reset.  Within our backend drivers, use
      of the object validation is just an inefficiency since we always
      pass valid objects.  More important to think about is what
      happens with the error reset; our uses of virConnectRef happened
      to be safe (since we hadn't encountered any earlier errors), but
      in several cases the use of virConnectClose could lose a real
      error.
      
      Ideally, we should also avoid calling virConnectOpen() from
      within backend drivers - but that is a known situation that
      needs much more design work.
      
      * src/qemu/qemu_process.c (qemuProcessReconnectHelper)
      (qemuProcessReconnect): Avoid nested public API call.
      * src/qemu/qemu_driver.c (qemuAutostartDomains)
      (qemuStateInitialize, qemuStateStop): Likewise.
      * src/qemu/qemu_migration.c (doPeer2PeerMigrate): Likewise.
      * src/storage/storage_driver.c (storageDriverAutostart):
      Likewise.
      * src/uml/uml_driver.c (umlAutostartConfigs): Likewise.
      * src/lxc/lxc_process.c (virLXCProcessAutostartAll): Likewise.
      (virLXCProcessReboot): Likewise, and avoid leaking conn on error.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      25221a1b
    • E
      maint: don't leave garbage on early API exit · c05aebfd
      Eric Blake 提交于
      Several APIs clear out a user input buffer before attempting to
      populate it; but in a few cases we missed this memset if we
      detect a reason for an early exit.  Note that these APIs
      check for non-NULL arguments, and exit early with an error
      message when NULL is passed in; which means that we must be
      careful to avoid a NULL deref in order to get to that error
      message.  Also, we were inconsistent on the use of
      sizeof(virType) vs. sizeof(expression); the latter is more
      robust if we ever change the type of the expression (although
      such action is unlikely since these types are part of our
      public API).
      
      * src/libvirt.c (virDomainGetInfo, virDomainGetBlockInfo)
      (virStoragePoolGetInfo, virStorageVolGetInfo)
      (virDomainGetJobInfo, virDomainGetBlockJobInfo): Move memset
      before any returns.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      c05aebfd
    • M
      qemu: Change the default unix monitor timeout · fe89b687
      Martin Kletzander 提交于
      There is a number of reported issues when we fail starting a domain.
      Turns out that, in some scenarios like high load, 3 second timeout is
      not enough for qemu to start up to the phase where the socket is
      created.  Since there is no downside of waiting longer, raise the
      timeout right to 30 seconds.
      Signed-off-by: NMartin Kletzander <mkletzan@redhat.com>
      fe89b687
  3. 16 1月, 2014 11 次提交
    • P
      storage: Introduce internal pool support · 362da820
      Peter Krempa 提交于
      To allow using the storage driver APIs to do operation on generic domain
      disks we will need to introduce internal storage pools that will give is
      a base to support this stuff even on files that weren't originally
      defined as a part of the pool.
      
      This patch introduces the 'internal' flag for a storage pool that will
      prevent it from being listed along with the user defined storage pools.
      362da820
    • P
      storage: Sheepdog: Separate creating of the volume from building · b3c1a25d
      Peter Krempa 提交于
      Separate the steps to create libvirt's volume metadata from the actual
      volume building process.
      b3c1a25d
    • P
      storage: RBD: Separate creating of the volume from building · e103acba
      Peter Krempa 提交于
      Separate the steps to create libvirt's volume metadata from the actual
      volume building process.
      e103acba
    • P
      storage: disk: Separate creating of the volume from building · 67ccf91b
      Peter Krempa 提交于
      Separate the steps to create libvirt's volume metadata from the actual
      volume building process.
      67ccf91b
    • P
      storage: lvm: Separate creating of the volume from building · af1fb38f
      Peter Krempa 提交于
      Separate the steps to create libvirt's volume metadata from the actual
      volume building process. This is already done for regular file based
      pools to allow job support for storage APIs.
      af1fb38f
    • P
      storage: Support deletion of volumes on gluster pools · 7de04882
      Peter Krempa 提交于
      Implement the "deleteVol" storage backend function for gluster volumes.
      7de04882
    • C
      conf: Always use VIR_ERR_CONFIG_UNSUPPORTED on enumFromString() failures · 9b73290f
      Christophe Fergeau 提交于
      Currently, during XML parsing, when a call to a FromString() function to
      get an enum value fails, the error which is reported is either
      VIR_ERR_CONFIG_UNSUPPORTED, VIR_ERR_INTERNAL_ERROR or VIR_ERR_XML_ERROR.
      
      This commit makes such conversion failures consistently return
      VIR_ERR_CONFIG_UNSUPPORTED.
      9b73290f
    • E
      event: filter global events by domain:getattr ACL [CVE-2014-0028] · f9f56340
      Eric Blake 提交于
      Ever since ACL filtering was added in commit 76397360 (v1.1.1), a
      user could still use event registration to obtain access to a
      domain that they could not normally access via virDomainLookup*
      or virConnectListAllDomains and friends.  We already have the
      framework in the RPC generator for creating the filter, and
      previous cleanup patches got us to the point that we can now
      wire the filter through the entire object event stack.
      
      Furthermore, whether or not domain:getattr is honored, use of
      global events is a form of obtaining a list of networks, which
      is covered by connect:search_domains added in a93cd08f (v1.1.0).
      Ideally, we'd have a way to enforce connect:search_domains when
      doing global registrations while omitting that check on a
      per-domain registration.  But this patch just unconditionally
      requires connect:search_domains, even when no list could be
      obtained, based on the following observations:
      1. Administrators are unlikely to grant domain:getattr for one
      or all domains while still denying connect:search_domains - a
      user that is able to manage domains will want to be able to
      manage them efficiently, but efficient management includes being
      able to list the domains they can access.  The idea of denying
      connect:search_domains while still granting access to individual
      domains is therefore not adding any real security, but just
      serves as a layer of obscurity to annoy the end user.
      2. In the current implementation, domain events are filtered
      on the client; the server has no idea if a domain filter was
      requested, and must therefore assume that all domain event
      requests are global.  Even if we fix the RPC protocol to
      allow for server-side filtering for newer client/server combos,
      making the connect:serach_domains ACL check conditional on
      whether the domain argument was NULL won't benefit older clients.
      Therefore, we choose to document that connect:search_domains
      is a pre-requisite to any domain event management.
      
      Network events need the same treatment, with the obvious
      change of using connect:search_networks and network:getattr.
      
      * src/access/viraccessperm.h
      (VIR_ACCESS_PERM_CONNECT_SEARCH_DOMAINS)
      (VIR_ACCESS_PERM_CONNECT_SEARCH_NETWORKS): Document additional
      effect of the permission.
      * src/conf/domain_event.h (virDomainEventStateRegister)
      (virDomainEventStateRegisterID): Add new parameter.
      * src/conf/network_event.h (virNetworkEventStateRegisterID):
      Likewise.
      * src/conf/object_event_private.h (virObjectEventStateRegisterID):
      Likewise.
      * src/conf/object_event.c (_virObjectEventCallback): Track a filter.
      (virObjectEventDispatchMatchCallback): Use filter.
      (virObjectEventCallbackListAddID): Register filter.
      * src/conf/domain_event.c (virDomainEventFilter): New function.
      (virDomainEventStateRegister, virDomainEventStateRegisterID):
      Adjust callers.
      * src/conf/network_event.c (virNetworkEventFilter): New function.
      (virNetworkEventStateRegisterID): Adjust caller.
      * src/remote/remote_protocol.x
      (REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER)
      (REMOTE_PROC_CONNECT_DOMAIN_EVENT_REGISTER_ANY)
      (REMOTE_PROC_CONNECT_NETWORK_EVENT_REGISTER_ANY): Generate a
      filter, and require connect:search_domains instead of weaker
      connect:read.
      * src/test/test_driver.c (testConnectDomainEventRegister)
      (testConnectDomainEventRegisterAny)
      (testConnectNetworkEventRegisterAny): Update callers.
      * src/remote/remote_driver.c (remoteConnectDomainEventRegister)
      (remoteConnectDomainEventRegisterAny): Likewise.
      * src/xen/xen_driver.c (xenUnifiedConnectDomainEventRegister)
      (xenUnifiedConnectDomainEventRegisterAny): Likewise.
      * src/vbox/vbox_tmpl.c (vboxDomainGetXMLDesc): Likewise.
      * src/libxl/libxl_driver.c (libxlConnectDomainEventRegister)
      (libxlConnectDomainEventRegisterAny): Likewise.
      * src/qemu/qemu_driver.c (qemuConnectDomainEventRegister)
      (qemuConnectDomainEventRegisterAny): Likewise.
      * src/uml/uml_driver.c (umlConnectDomainEventRegister)
      (umlConnectDomainEventRegisterAny): Likewise.
      * src/network/bridge_driver.c
      (networkConnectNetworkEventRegisterAny): Likewise.
      * src/lxc/lxc_driver.c (lxcConnectDomainEventRegister)
      (lxcConnectDomainEventRegisterAny): Likewise.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      f9f56340
    • E
      event: wire up RPC for server-side network event filtering · 8d9d098b
      Eric Blake 提交于
      We haven't had a release with network events yet, so we are free
      to fix the RPC so that it actually does what we want.  Doing
      client-side filtering of per-network events is inefficient if a
      connection is only interested in events on a single network out
      of hundreds available on the server.  But to do server-side
      per-network filtering, the server needs to know which network
      to filter on - so we need to pass an optional network over on
      registration.  Furthermore, it is possible to have a client with
      both a global and per-network filter; in the existing code, the
      server sends only one event and the client replicates to both
      callbacks.  But with server-side filtering, the server will send
      the event twice, so we need a way for the client to know which
      callbackID is sending an event, to ensure that the client can
      filter out events from a registration that does not match the
      callbackID from the server.  Likewise, the existing style of
      deregistering by eventID alone is fine; but in the new style,
      we have to remember which callbackID to delete.
      
      This patch fixes the RPC wire definition to contain all the
      needed pieces of information, and hooks into the server and
      client side improvements of the previous patches, in order to
      switch over to full server-side filtering of network events.
      Also, since we fixed this in time, all released versions of
      libvirtd that support network events also support per-network
      filtering, so we can hard-code that assumption into
      network_event.c.
      
      Converting domain events to server-side filtering will require
      the introduction of new RPC numbers, as well as a server
      feature bit that the client can use to tell whether to use
      old-style (server only supports global events) or new-style
      (server supports filtered events), so that is deferred to a
      later set of patches.
      
      * src/conf/network_event.c (virNetworkEventStateRegisterClient):
      Assume server-side filtering.
      * src/remote/remote_protocol.x
      (remote_connect_network_event_register_any_args): Add network
      argument.
      (remote_connect_network_event_register_any_ret): Return callbackID
      instead of count.
      (remote_connect_network_event_deregister_any_args): Pass
      callbackID instead of eventID.
      (remote_connect_network_event_deregister_any_ret): Drop unused
      type.
      (remote_network_event_lifecycle_msg): Add callbackID.
      * daemon/remote.c
      (remoteDispatchConnectNetworkEventDeregisterAny): Drop unused arg,
      and deal with callbackID from client.
      (remoteRelayNetworkEventLifecycle): Pass callbackID.
      (remoteDispatchConnectNetworkEventRegisterAny): Likewise, and
      recognize non-NULL network.
      * src/remote/remote_driver.c
      (remoteConnectNetworkEventRegisterAny): Pass network, and track
      server side id.
      (remoteConnectNetworkEventDeregisterAny): Deregister by callback id.
      (remoteNetworkBuildEventLifecycle): Pass remote id to event queue.
      * src/remote_protocol-structs: Regenerate.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      8d9d098b
    • E
      event: add notion of remoteID for filtering client network events · a59097e5
      Eric Blake 提交于
      In order to mirror a server with per-object filtering, the client
      needs to track which server callbackID is servicing the client
      callback.  This patch introduces the notion of a serverID, as
      well as the plumbing to use it for network events, although the
      actual complexity of using per-object filtering in the remote
      driver is deferred to a later patch.
      
      * src/conf/object_event.h (virObjectEventStateEventID): Add parameter.
      (virObjectEventStateQueueRemote, virObjectEventStateSetRemote):
      New prototypes.
      (virObjectEventStateRegisterID): Move...
      * src/conf/object_event_private.h: ...here, and add parameter.
      (_virObjectEvent): Add field.
      * src/conf/network_event.h (virNetworkEventStateRegisterClient): New
      prototype.
      * src/conf/object_event.c (_virObjectEventCallback): Add field.
      (virObjectEventStateSetRemote): New function.
      (virObjectEventStateQueue): Make wrapper around...
      (virObjectEventStateQueueRemote): New function.
      (virObjectEventCallbackListCount): Tweak return count when remote
      id matching is used.
      (virObjectEventCallbackLookup, virObjectEventStateRegisterID):
      Tweak registration when remote id matching will be used.
      (virObjectEventNew): Default to no remote id.
      (virObjectEventCallbackListAddID): Likewise, but set remote id
      when one is available.
      (virObjectEventCallbackListRemoveID)
      (virObjectEventCallbackListMarkDeleteID): Adjust return value when
      remote id was set.
      (virObjectEventStateEventID): Query existing id.
      (virObjectEventDispatchMatchCallback): Require matching event id.
      (virObjectEventStateCallbackID): Adjust caller.
      * src/conf/network_event.c (virNetworkEventStateRegisterClient): New
      function.
      (virNetworkEventStateRegisterID): Update caller.
      * src/conf/domain_event.c (virDomainEventStateRegister)
      (virDomainEventStateRegisterID): Update callers.
      * src/remote/remote_driver.c
      (remoteConnectNetworkEventRegisterAny)
      (remoteConnectNetworkEventDeregisterAny)
      (remoteConnectDomainEventDeregisterAny): Likewise.
      (remoteEventQueue): Hoist earlier to avoid forward declaration,
      and add parameter.  Adjust all callers.
      * src/libvirt_private.syms (conf/object_event.h): Drop function.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      a59097e5
    • P
      qemu: Avoid operations on NULL monitor if VM fails early · b952cbbc
      Peter Krempa 提交于
      https://bugzilla.redhat.com/show_bug.cgi?id=1047659
      
      If a VM dies very early during an attempted connect to the guest agent
      while the locks are down the domain monitor object will be freed. The
      object is then accessed later as any failure during guest agent startup
      isn't considered fatal.
      
      In the current upstream version this doesn't lead to a crash as
      virObjectLock called when entering the monitor in
      qemuProcessDetectVcpuPIDs checks the pointer before attempting to
      dereference (lock) it. The NULL pointer is then caught in the monitor
      helper code.
      
      Before the introduction of virObjectLockable - observed on 0.10.2 - the
      pointer is locked directly via virMutexLock leading to a crash.
      
      To avoid this problem we need to differentiate between the guest agent
      not being present and the VM quitting when the locks were down. The fix
      reorganizes the code in qemuConnectAgent to add the check and then adds
      special handling to the callers.
      b952cbbc
  4. 15 1月, 2014 3 次提交
  5. 14 1月, 2014 3 次提交
    • J
      Really don't crash if a connection closes early · 066c8ef6
      Jiri Denemark 提交于
      https://bugzilla.redhat.com/show_bug.cgi?id=1047577
      
      When writing commit 173c2914, I missed the fact virNetServerClientClose
      unlocks the client object before actually clearing client->sock and thus
      it is possible to hit a window when client->keepalive is NULL while
      client->sock is not NULL. I was thinking client->sock == NULL was a
      better check for a closed connection but apparently we have to go with
      client->keepalive == NULL to actually fix the crash.
      Signed-off-by: NJiri Denemark <jdenemar@redhat.com>
      066c8ef6
    • P
      storage: FS: Tweak some comments and fix typos · fbe472d5
      Peter Krempa 提交于
      fbe472d5
    • E
      build: fix build on mingw with winpthreads · c91d13bd
      Eric Blake 提交于
      On my Fedora 20 box with mingw cross-compiler, the build failed with:
      
      ../../src/rpc/virnetclient.c: In function 'virNetClientSetTLSSession':
      ../../src/rpc/virnetclient.c:745:14: error: unused variable 'oldmask' [-Werror=unused-variable]
           sigset_t oldmask, blockedsigs;
                    ^
      
      I traced it to the fact that mingw64-winpthreads installs a header
      that does #define pthread_sigmask(...) 0, which means any argument
      only ever passed to pthread_sigmask is reported as unused.  This
      patch works around the compilation failure, with behavior no worse
      than what mingw already gives us regarding the function being a
      no-op.
      
      * configure.ac (pthread_sigmask): Probe for broken mingw macro.
      * src/util/virutil.h (pthread_sigmask): Rewrite to something that
      avoids unused variables.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      c91d13bd
  6. 13 1月, 2014 2 次提交
    • P
    • J
      Don't crash if a connection closes early · 173c2914
      Jiri Denemark 提交于
      https://bugzilla.redhat.com/show_bug.cgi?id=1047577
      
      When a client closes its connection to libvirtd early during
      virConnectOpen, more specifically just after making
      REMOTE_PROC_CONNECT_SUPPORTS_FEATURE call to check if
      VIR_DRV_FEATURE_PROGRAM_KEEPALIVE is supported without even waiting for
      the result, libvirtd may crash due to a race in keep-alive
      initialization. Once receiving the REMOTE_PROC_CONNECT_SUPPORTS_FEATURE
      call, the daemon's event loop delegates it to a worker thread. In case
      the event loop detects EOF on the connection and calls
      virNetServerClientClose before the worker thread starts to handle
      REMOTE_PROC_CONNECT_SUPPORTS_FEATURE call, client->keepalive will be
      disposed by the time virNetServerClientStartKeepAlive gets called from
      remoteDispatchConnectSupportsFeature. Because the flow is common for
      both authenticated and read-only connections, even unprivileged clients
      may cause the daemon to crash.
      
      To avoid the crash, virNetServerClientStartKeepAlive needs to check if
      the connection is still open before starting keep-alive protocol.
      
      Every libvirt release since 0.9.8 is affected by this bug.
      173c2914
  7. 11 1月, 2014 1 次提交
  8. 10 1月, 2014 6 次提交
    • P
      storage: Improve error message when a storage backend is missing · 558ffad5
      Peter Krempa 提交于
      Include the name of the storage backend in the error message instead of
      just the number.
      558ffad5
    • P
      storage: lvm: Avoid forward decl of virStorageBackendLogicalDeleteVol · af38f830
      Peter Krempa 提交于
      Change code ordering to avoid the need for a forward declaration.
      af38f830
    • P
      storage: fs: Fix comment for virStorageBackendFileSystemDelete · 1c0e2b60
      Peter Krempa 提交于
      The comment was talking about creating the pool while the function is
      deleting it. Fix the mismatch.
      1c0e2b60
    • C
      c4dadf23
    • E
      event: don't queue NULL event on OOM · f86e4630
      Eric Blake 提交于
      Ever since commit 61ac8ce0, Coverity complained about
      remoteNetworkBuildEventLifecycle not checking for NULL failure
      to build an event, compared to other calls in the code base.
      But the problem is latent from copy and paste; all 17 of our
      remote*BuildEvent* functions in remote_driver.c have the same
      issue - if an OOM causes an event to not be built, we happily
      pass NULL to remoteEventQueue(), but that function has marked
      event as a nonnull parameter.  We were getting lucky (the
      event queue's first use of the event happened to be a call to
      virIsObjectClass(), which acts gracefully on NULL, so there
      was no way to crash); but this is a latent bug waiting to bite
      us due to the disregard for the nonnull attribute, as well as
      a waste of resources in the event queue.  Better is to just
      refuse to queue NULL.  The discard is silent, since the problem
      only happens on OOM, and since events are already best effort -
      if we fail to get an event, it's not like we have any memory
      left to report the issue, nor any idea of who would benefit
      from knowing we couldn't create or queue the event.
      
      * src/remote/remote_driver.c (remoteEventQueue): Ignore NULL event.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      f86e4630
    • E
      virt-login-shell: fix regressions in behavior · 3d007cb5
      Eric Blake 提交于
      Our fixes for CVE-2013-4400 were so effective at "fixing" bugs
      in virt-login-shell that we ended up fixing it into a useless
      do-nothing program.
      
      Commit 3e2f27e1 picked the name LIBVIRT_SETUID_RPC_CLIENT for
      the witness macro when we are doing secure compilation.  But
      commit 9cd6a57d checked whether the name IN_VIRT_LOGIN_SHELL,
      from an earlier version of the patch series, was defined; with
      the net result that virt-login-shell invariably detected that
      it was setuid and failed virInitialize.
      
      Commit b7fcc799 closed all fds larger than stderr, but in the
      wrong place.  Looking at the larger context, we mistakenly did
      the close in between obtaining the set of namespace fds, then
      actually using those fds to switch namespace, which means that
      virt-login-shell will ALWAYS fail.
      
      This is the minimal patch to fix the regressions, although
      further patches are also worth having to clean up poor
      semantics of the resulting program (for example, it is rude to
      not pass on the exit status of the wrapped program back to the
      invoking shell).
      
      * tools/virt-login-shell.c (main): Don't close fds until after
      namespace swap.
      * src/libvirt.c (virGlobalInit): Use correct macro.
      Signed-off-by: NEric Blake <eblake@redhat.com>
      3d007cb5