Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
/*
|
|
|
|
* libvirt-lxc.c: Interfaces for the libvirt library to handle lxc-specific
|
|
|
|
* APIs.
|
|
|
|
*
|
2013-12-19 22:43:46 +00:00
|
|
|
* Copyright (C) 2012-2014 Red Hat, Inc.
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* Author: Daniel P. Berrange <berrange@redhat.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <config.h>
|
|
|
|
|
|
|
|
#include "viralloc.h"
|
|
|
|
#include "virerror.h"
|
|
|
|
#include "virfile.h"
|
|
|
|
#include "virlog.h"
|
|
|
|
#include "virprocess.h"
|
2013-12-19 22:43:46 +00:00
|
|
|
#include "viruuid.h"
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
#include "datatypes.h"
|
2013-03-12 17:24:01 +00:00
|
|
|
#ifdef WITH_SELINUX
|
|
|
|
# include <selinux/selinux.h>
|
|
|
|
#endif
|
2014-03-03 10:26:45 +00:00
|
|
|
#ifdef WITH_APPARMOR
|
|
|
|
# include <sys/apparmor.h>
|
|
|
|
#endif
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
|
|
|
#define VIR_FROM_THIS VIR_FROM_NONE
|
|
|
|
|
2014-02-28 12:16:17 +00:00
|
|
|
VIR_LOG_INIT("libvirt-lxc");
|
|
|
|
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
/**
|
|
|
|
* virDomainLxcOpenNamespace:
|
|
|
|
* @domain: a domain object
|
|
|
|
* @fdlist: pointer to an array to be filled with FDs
|
|
|
|
* @flags: currently unused, pass 0
|
|
|
|
*
|
|
|
|
* This API is LXC specific, so it will only work with hypervisor
|
|
|
|
* connections to the LXC driver.
|
|
|
|
*
|
|
|
|
* Open the namespaces associated with the container @domain.
|
|
|
|
* The @fdlist array will be allocated to a suitable size,
|
|
|
|
* and filled with file descriptors for the namespaces. It
|
|
|
|
* is the caller's responsibility to close the file descriptors
|
|
|
|
*
|
|
|
|
* The returned file descriptors are intended to be used with
|
|
|
|
* the setns() system call.
|
|
|
|
*
|
|
|
|
* Returns the number of opened file descriptors, or -1 on error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virDomainLxcOpenNamespace(virDomainPtr domain,
|
|
|
|
int **fdlist,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
|
|
|
virConnectPtr conn;
|
|
|
|
|
2013-12-19 22:43:46 +00:00
|
|
|
VIR_DOMAIN_DEBUG(domain, "fdlist=%p flags=%x", fdlist, flags);
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
|
|
|
virResetLastError();
|
|
|
|
|
2014-01-07 21:38:12 +00:00
|
|
|
virCheckDomainReturn(domain, -1);
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
conn = domain->conn;
|
|
|
|
|
|
|
|
virCheckNonNullArgGoto(fdlist, error);
|
2013-12-20 14:02:49 +00:00
|
|
|
virCheckReadOnlyGoto(conn->flags, error);
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
|
|
|
if (conn->driver->domainLxcOpenNamespace) {
|
|
|
|
int ret;
|
|
|
|
ret = conn->driver->domainLxcOpenNamespace(domain,
|
|
|
|
fdlist,
|
|
|
|
flags);
|
|
|
|
if (ret < 0)
|
|
|
|
goto error;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2013-12-20 01:38:59 +00:00
|
|
|
virReportUnsupportedError();
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
error:
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
virDispatchError(conn);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virDomainLxcEnterNamespace:
|
|
|
|
* @domain: a domain object
|
|
|
|
* @nfdlist: number of FDs in @fdlist
|
|
|
|
* @fdlist: list of namespace file descriptors
|
|
|
|
* @noldfdlist: filled with number of old FDs
|
|
|
|
* @oldfdlist: pointer to hold list of old namespace file descriptors
|
|
|
|
* @flags: currently unused, pass 0
|
|
|
|
*
|
|
|
|
* This API is LXC specific, so it will only work with hypervisor
|
|
|
|
* connections to the LXC driver.
|
|
|
|
*
|
|
|
|
* Attaches the process to the namespaces associated
|
|
|
|
* with the FDs in @fdlist
|
|
|
|
*
|
|
|
|
* If @oldfdlist is non-NULL, it will be populated with file
|
|
|
|
* descriptors representing the old namespace. This allows
|
|
|
|
* the caller to switch back to its current namespace later
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virDomainLxcEnterNamespace(virDomainPtr domain,
|
|
|
|
unsigned int nfdlist,
|
|
|
|
int *fdlist,
|
|
|
|
unsigned int *noldfdlist,
|
|
|
|
int **oldfdlist,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
Convert 'int i' to 'size_t i' in src/ files
Convert the type of loop iterators named 'i', 'j', k',
'ii', 'jj', 'kk', to be 'size_t' instead of 'int' or
'unsigned int', also santizing 'ii', 'jj', 'kk' to use
the normal 'i', 'j', 'k' naming
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2013-07-08 14:09:33 +00:00
|
|
|
size_t i;
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
maint: move debug statements first in public API
Most of our public APIs emit a debug log on entry, prior to anything
else. There were a few exceptions where obvious failures were not
logged, so fix those. When moving a debug earlier, this patch also
makes sure to avoid any NULL dereference during the log (the APIs
are supposed to gracefully fail if the user passes NULL for the object).
However, do NOT use VIR_DEBUG prior to virInitialize, since setting
up the error reporting can change where VIR_DEBUG output would be
routed. Instead add documentation to virGlobalInit, virInitialize,
and virGetVersion that better explains initialization.
* src/libvirt.c (virGetVersion, virConnectRef, virDomainRef)
(virNetworkRef, virInterfaceRef, virStoragePoolRef)
(virStorageVolRef, virNodeDeviceRef, virSecretRef, virStreamRef)
(virNWFilterRef, virDomainSnapshotRef): Debug on function entry.
* src/libvirt-lxc.c (virDomainLxcEnterNamespace)
(virDomainLxcEnterSecurityLabel): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-12-27 21:16:56 +00:00
|
|
|
VIR_DOMAIN_DEBUG(domain, "nfdlist=%d, fdlist=%p, "
|
|
|
|
"noldfdlist=%p, oldfdlist=%p, flags=%x",
|
|
|
|
nfdlist, fdlist, noldfdlist, oldfdlist, flags);
|
|
|
|
|
maint: reset error on entrance to public API
We document that calling any public API wipes out all prior
libvirt errors in the same thread; but weren't obeying this
style in a few functions.
There are a couple of nested uses of virConnectRef (in lxc
and qemu reboot paths), but they should not be affected by
this change in semantics since there should not be any
previous error getting nuked (a later patch will clean up
the nested calls, along with abuse of virConnectClose on
cleanup paths which DOES nuke errors).
* src/libvirt.c (virGetVersion, virConnectRef, virDomainRef)
(virDomainGetSecurityLabel, virDomainGetSecurityLabelList)
(virDomainSetMetadata, virDomainGetMetadata)
(virNodeGetSecurityModel, virNetworkRef, virInterfaceRef)
(virStoragePoolRef, virStorageVolRef, virNodeDeviceGetName)
(virNodeDeviceRef, virSecretRef, virStreamRef, virNWFilterRef)
(virDomainSnapshotRef): Reset error on entrance.
(do_open): Drop redundant error reset.
* src/libvirt-qemu.c (virDomainQemuAgentCommand): Likewise.
* src/libvirt-lxc.c (virDomainLxcEnterNamespace)
(virDomainLxcEnterSecurityLabel): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-12-27 21:54:34 +00:00
|
|
|
virResetLastError();
|
|
|
|
|
2013-03-12 17:36:19 +00:00
|
|
|
virCheckFlagsGoto(0, error);
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
|
|
|
|
if (noldfdlist && oldfdlist) {
|
|
|
|
size_t nfds;
|
|
|
|
if (virProcessGetNamespaces(getpid(),
|
|
|
|
&nfds,
|
|
|
|
oldfdlist) < 0)
|
|
|
|
goto error;
|
|
|
|
*noldfdlist = nfds;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (virProcessSetNamespaces(nfdlist, fdlist) < 0) {
|
|
|
|
if (oldfdlist && noldfdlist) {
|
2014-11-13 14:27:11 +00:00
|
|
|
for (i = 0; i < *noldfdlist; i++)
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
VIR_FORCE_CLOSE((*oldfdlist)[i]);
|
|
|
|
VIR_FREE(*oldfdlist);
|
|
|
|
*noldfdlist = 0;
|
|
|
|
}
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
error:
|
Introduce an LXC specific public API & library
This patch introduces support for LXC specific public APIs. In
common with what was done for QEMU, this creates a libvirt_lxc.so
library and libvirt/libvirt-lxc.h header file.
The actual APIs are
int virDomainLxcOpenNamespace(virDomainPtr domain,
int **fdlist,
unsigned int flags);
int virDomainLxcEnterNamespace(virDomainPtr domain,
unsigned int nfdlist,
int *fdlist,
unsigned int *noldfdlist,
int **oldfdlist,
unsigned int flags);
which provide a way to use the setns() system call to move the
calling process into the container's namespace. It is not
practical to write in a generically applicable manner. The
nearest that we could get to such an API would be an API which
allows to pass a command + argv to be executed inside a
container. Even if we had such a generic API, this LXC specific
API is still useful, because it allows the caller to maintain
the current process context, in particular any I/O streams they
have open.
NB the virDomainLxcEnterNamespace() API is special in that it
runs client side, so does not involve the internal driver API.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2012-12-21 13:15:19 +00:00
|
|
|
virDispatchError(domain->conn);
|
|
|
|
return -1;
|
|
|
|
}
|
2013-03-12 17:24:01 +00:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* virDomainLxcEnterSecurityLabel:
|
|
|
|
* @model: the security model to set
|
|
|
|
* @label: the security label to apply
|
|
|
|
* @oldlabel: filled with old security label
|
|
|
|
* @flags: currently unused, pass 0
|
|
|
|
*
|
|
|
|
* This API is LXC specific, so it will only work with hypervisor
|
|
|
|
* connections to the LXC driver.
|
|
|
|
*
|
|
|
|
* Attaches the process to the security label specified
|
|
|
|
* by @label. @label is interpreted relative to @model
|
|
|
|
* Depending on the security driver, this may
|
|
|
|
* not take effect until the next call to exec().
|
|
|
|
*
|
|
|
|
* If @oldlabel is not NULL, it will be filled with info
|
|
|
|
* about the current security label. This may let the
|
|
|
|
* process be moved back to the previous label if no
|
|
|
|
* exec() has yet been performed.
|
|
|
|
*
|
|
|
|
* Returns 0 on success, -1 on error
|
|
|
|
*/
|
|
|
|
int
|
|
|
|
virDomainLxcEnterSecurityLabel(virSecurityModelPtr model,
|
|
|
|
virSecurityLabelPtr label,
|
|
|
|
virSecurityLabelPtr oldlabel,
|
|
|
|
unsigned int flags)
|
|
|
|
{
|
maint: move debug statements first in public API
Most of our public APIs emit a debug log on entry, prior to anything
else. There were a few exceptions where obvious failures were not
logged, so fix those. When moving a debug earlier, this patch also
makes sure to avoid any NULL dereference during the log (the APIs
are supposed to gracefully fail if the user passes NULL for the object).
However, do NOT use VIR_DEBUG prior to virInitialize, since setting
up the error reporting can change where VIR_DEBUG output would be
routed. Instead add documentation to virGlobalInit, virInitialize,
and virGetVersion that better explains initialization.
* src/libvirt.c (virGetVersion, virConnectRef, virDomainRef)
(virNetworkRef, virInterfaceRef, virStoragePoolRef)
(virStorageVolRef, virNodeDeviceRef, virSecretRef, virStreamRef)
(virNWFilterRef, virDomainSnapshotRef): Debug on function entry.
* src/libvirt-lxc.c (virDomainLxcEnterNamespace)
(virDomainLxcEnterSecurityLabel): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-12-27 21:16:56 +00:00
|
|
|
VIR_DEBUG("model=%p, label=%p, oldlabel=%p, flags=%x",
|
|
|
|
model, label, oldlabel, flags);
|
|
|
|
|
maint: reset error on entrance to public API
We document that calling any public API wipes out all prior
libvirt errors in the same thread; but weren't obeying this
style in a few functions.
There are a couple of nested uses of virConnectRef (in lxc
and qemu reboot paths), but they should not be affected by
this change in semantics since there should not be any
previous error getting nuked (a later patch will clean up
the nested calls, along with abuse of virConnectClose on
cleanup paths which DOES nuke errors).
* src/libvirt.c (virGetVersion, virConnectRef, virDomainRef)
(virDomainGetSecurityLabel, virDomainGetSecurityLabelList)
(virDomainSetMetadata, virDomainGetMetadata)
(virNodeGetSecurityModel, virNetworkRef, virInterfaceRef)
(virStoragePoolRef, virStorageVolRef, virNodeDeviceGetName)
(virNodeDeviceRef, virSecretRef, virStreamRef, virNWFilterRef)
(virDomainSnapshotRef): Reset error on entrance.
(do_open): Drop redundant error reset.
* src/libvirt-qemu.c (virDomainQemuAgentCommand): Likewise.
* src/libvirt-lxc.c (virDomainLxcEnterNamespace)
(virDomainLxcEnterSecurityLabel): Likewise.
Signed-off-by: Eric Blake <eblake@redhat.com>
2013-12-27 21:54:34 +00:00
|
|
|
virResetLastError();
|
|
|
|
|
2013-03-12 17:24:01 +00:00
|
|
|
virCheckFlagsGoto(0, error);
|
|
|
|
|
|
|
|
virCheckNonNullArgGoto(model, error);
|
|
|
|
virCheckNonNullArgGoto(label, error);
|
|
|
|
|
|
|
|
if (oldlabel)
|
|
|
|
memset(oldlabel, 0, sizeof(*oldlabel));
|
|
|
|
|
|
|
|
if (STREQ(model->model, "selinux")) {
|
|
|
|
#ifdef WITH_SELINUX
|
|
|
|
if (oldlabel) {
|
|
|
|
security_context_t ctx;
|
|
|
|
|
|
|
|
if (getcon(&ctx) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("unable to get PID %d security context"),
|
|
|
|
getpid());
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strlen((char *) ctx) >= VIR_SECURITY_LABEL_BUFLEN) {
|
|
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
|
|
_("security label exceeds "
|
|
|
|
"maximum length: %d"),
|
|
|
|
VIR_SECURITY_LABEL_BUFLEN - 1);
|
|
|
|
freecon(ctx);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(oldlabel->label, (char *) ctx);
|
|
|
|
freecon(ctx);
|
|
|
|
|
|
|
|
if ((oldlabel->enforcing = security_getenforce()) < 0) {
|
|
|
|
virReportSystemError(errno, "%s",
|
|
|
|
_("error calling security_getenforce()"));
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setexeccon(label->label) < 0) {
|
|
|
|
virReportSystemError(errno,
|
|
|
|
_("Cannot set context %s"),
|
|
|
|
label->label);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
|
|
_("Support for SELinux is not enabled"));
|
|
|
|
goto error;
|
2014-03-03 10:26:45 +00:00
|
|
|
#endif
|
|
|
|
} else if (STREQ(model->model, "apparmor")) {
|
|
|
|
#ifdef WITH_APPARMOR
|
|
|
|
if (aa_change_profile(label->label) < 0) {
|
|
|
|
virReportSystemError(errno, _("error changing profile to %s"),
|
|
|
|
label->label);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
|
|
|
|
_("Support for AppArmor is not enabled"));
|
|
|
|
goto error;
|
2013-03-12 17:24:01 +00:00
|
|
|
#endif
|
|
|
|
} else {
|
|
|
|
virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED,
|
|
|
|
_("Security model %s cannot be entered"),
|
|
|
|
model->model);
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
2014-03-25 06:57:22 +00:00
|
|
|
error:
|
2013-03-12 17:24:01 +00:00
|
|
|
virDispatchError(NULL);
|
|
|
|
return -1;
|
|
|
|
}
|