[libvirt] [PATCH V3] add console support in libxl
by Bamvor Jian Zhang
this patch introduce the console api in libxl driver for both pv and
hvm guest. and import and update the libxlMakeChrdevStr function
which was deleted in commit dfa1e1dd.
Signed-off-by: Bamvor Jian Zhang <bjzhang(a)suse.com>
---
Changes since V2:
1), forbid parallel configure because libxl do not support it
2), only support one serial on libxl driver.
3), also remove console code in libxl driver, AFAICS serial is enough for connecting to libxl console.
changes since V1:
1), add virDomainOpenConsoleEnsureACL
3), remove virReportOOMErrorFull when virAsprintf fail.
4), change size_t for non-nagetive number in libxlDomainOpenConsole
size_t i;
size_t num = 0;
5), fix for make check
(1), replace virAsprintf with VIR_STRDUP in two places
(2), delete space.
src/libxl/libxl_conf.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++
src/libxl/libxl_conf.h | 3 ++
src/libxl/libxl_driver.c | 87 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 190 insertions(+)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 4a0fba9..539d537 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -331,6 +331,90 @@ error:
}
static int
+libxlMakeChrdevStr(virDomainChrDefPtr def, char **buf)
+{
+ const char *type = virDomainChrTypeToString(def->source.type);
+ int ret;
+
+ if (!type) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("unexpected chr device type"));
+ return -1;
+ }
+
+ switch (def->source.type) {
+ case VIR_DOMAIN_CHR_TYPE_NULL:
+ case VIR_DOMAIN_CHR_TYPE_STDIO:
+ case VIR_DOMAIN_CHR_TYPE_VC:
+ case VIR_DOMAIN_CHR_TYPE_PTY:
+ if (VIR_STRDUP(*buf, type) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_FILE:
+ case VIR_DOMAIN_CHR_TYPE_PIPE:
+ if (virAsprintf(buf, "%s:%s", type,
+ def->source.data.file.path) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_DEV:
+ if (VIR_STRDUP(*buf, def->source.data.file.path) < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UDP: {
+ const char *connectHost = def->source.data.udp.connectHost;
+ const char *bindHost = def->source.data.udp.bindHost;
+ const char *bindService = def->source.data.udp.bindService;
+
+ if (connectHost == NULL)
+ connectHost = "";
+ if (bindHost == NULL)
+ bindHost = "";
+ if (bindService == NULL)
+ bindService = "0";
+
+ ret = virAsprintf(buf, "udp:%s:%s@%s:%s",
+ connectHost,
+ def->source.data.udp.connectService,
+ bindHost,
+ bindService);
+ if (ret < 0)
+ return -1;
+ break;
+
+ }
+ case VIR_DOMAIN_CHR_TYPE_TCP:
+ if (def->source.data.tcp.protocol == VIR_DOMAIN_CHR_TCP_PROTOCOL_TELNET)
+ ret = virAsprintf(buf, "telnet:%s:%s%s",
+ def->source.data.tcp.host,
+ def->source.data.tcp.service,
+ def->source.data.tcp.listen ? ",server,nowait" : "");
+ else
+ ret = virAsprintf(buf, "tcp:%s:%s%s",
+ def->source.data.tcp.host,
+ def->source.data.tcp.service,
+ def->source.data.tcp.listen ? ",server,nowait" : "");
+
+ if (ret < 0)
+ return -1;
+ break;
+
+ case VIR_DOMAIN_CHR_TYPE_UNIX:
+ ret = virAsprintf(buf, "unix:%s%s",
+ def->source.data.nix.path,
+ def->source.data.nix.listen ? ",server,nowait" : "");
+ if (ret < 0)
+ return -1;
+ break;
+
+ }
+
+ return 0;
+}
+
+static int
libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
{
libxl_domain_build_info *b_info = &d_config->b_info;
@@ -403,6 +487,22 @@ libxlMakeDomBuildInfo(virDomainDefPtr def, libxl_domain_config *d_config)
if (VIR_STRDUP(b_info->u.hvm.boot, bootorder) < 0)
goto error;
+ if (def->nserials) {
+ if (def->nserials > 1) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Only one serial is supported by libxl"));
+ goto error;
+ }
+ if (libxlMakeChrdevStr(def->serials[0], &b_info->u.hvm.serial) < 0)
+ goto error;
+ }
+
+ if (def->nparallels) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("Parallel is not supported"));
+ goto error;
+ }
+
/*
* The following comment and calculation were taken directly from
* libxenlight's internal function libxl_get_required_shadow_memory():
diff --git a/src/libxl/libxl_conf.h b/src/libxl/libxl_conf.h
index 2b4a281..861d689 100644
--- a/src/libxl/libxl_conf.h
+++ b/src/libxl/libxl_conf.h
@@ -34,6 +34,7 @@
# include "configmake.h"
# include "virportallocator.h"
# include "virobject.h"
+# include "virchrdev.h"
# define LIBXL_VNC_PORT_MIN 5900
@@ -94,6 +95,8 @@ struct _libxlDomainObjPrivate {
/* per domain libxl ctx */
libxl_ctx *ctx;
+ /* console */
+ virChrdevsPtr devs;
libxl_evgen_domain_death *deathW;
/* list of libxl timeout registrations */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 358d387..b3a8d50 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -417,6 +417,9 @@ libxlDomainObjPrivateAlloc(void)
libxl_osevent_register_hooks(priv->ctx, &libxl_event_callbacks, priv);
+ if (!(priv->devs = virChrdevAlloc()))
+ return NULL;
+
return priv;
}
@@ -429,6 +432,7 @@ libxlDomainObjPrivateDispose(void *obj)
libxl_evdisable_domain_death(priv->ctx, priv->deathW);
libxl_ctx_free(priv->ctx);
+ virChrdevFree(priv->devs);
}
static void
@@ -4493,6 +4497,88 @@ cleanup:
return ret;
}
+
+static int
+libxlDomainOpenConsole(virDomainPtr dom,
+ const char *dev_name,
+ virStreamPtr st,
+ unsigned int flags)
+{
+ libxlDriverPrivatePtr driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ virDomainChrDefPtr chr = NULL;
+ libxlDomainObjPrivatePtr priv;
+ char *console = NULL;
+
+ virCheckFlags(VIR_DOMAIN_CONSOLE_SAFE |
+ VIR_DOMAIN_CONSOLE_FORCE, -1);
+
+ libxlDriverLock(driver);
+ vm = virDomainObjListFindByUUID(driver->domains, dom->uuid);
+ libxlDriverUnlock(driver);
+ if (!vm) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(dom->uuid, uuidstr);
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("No domain with matching uuid '%s'"), uuidstr);
+ goto cleanup;
+ }
+
+ if (virDomainOpenConsoleEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ priv = vm->privateData;
+
+ if (vm->def->nserials)
+ chr = vm->def->serials[0];
+
+ if (!chr) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot find character device %s"),
+ NULLSTR(dev_name));
+ goto cleanup;
+ }
+
+ if (chr->source.type != VIR_DOMAIN_CHR_TYPE_PTY) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("character device %s is not using a PTY"),
+ NULLSTR(dev_name));
+ goto cleanup;
+ }
+
+ ret = libxl_primary_console_get_tty(priv->ctx, vm->def->id, &console);
+ if (ret)
+ goto cleanup;
+
+ if (VIR_STRDUP(chr->source.data.file.path, console) < 0)
+ goto cleanup;
+
+ /* handle mutually exclusive access to console devices */
+ ret = virChrdevOpen(priv->devs,
+ &chr->source,
+ st,
+ (flags & VIR_DOMAIN_CONSOLE_FORCE) != 0);
+
+ if (ret == 1) {
+ virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+ _("Active console session exists for this domain"));
+ ret = -1;
+ }
+
+cleanup:
+ VIR_FREE(console);
+ if (vm)
+ virObjectUnlock(vm);
+ return ret;
+}
+
static int
libxlDomainSetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr params,
int nparams)
@@ -4875,6 +4961,7 @@ static virDriver libxlDriver = {
.domainManagedSave = libxlDomainManagedSave, /* 0.9.2 */
.domainHasManagedSaveImage = libxlDomainHasManagedSaveImage, /* 0.9.2 */
.domainManagedSaveRemove = libxlDomainManagedSaveRemove, /* 0.9.2 */
+ .domainOpenConsole = libxlDomainOpenConsole, /* 1.1.1 */
.domainIsActive = libxlDomainIsActive, /* 0.9.0 */
.domainIsPersistent = libxlDomainIsPersistent, /* 0.9.0 */
.domainIsUpdated = libxlDomainIsUpdated, /* 0.9.0 */
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] Add logic for handling systemd-machined non-existance
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
If systemd machine does not exist, return -2 instead of -1,
so that applications don't need to repeat the tedious error
checking code
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/virsystemd.c | 13 ++++++++++-
tests/virsystemdmock.c | 14 +++++++----
tests/virsystemdtest.c | 63 +++++++++++++++++++++++++++++++++++---------------
3 files changed, 66 insertions(+), 24 deletions(-)
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index 8477cd3..11d1153 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -26,6 +26,7 @@
#include "virstring.h"
#include "viralloc.h"
#include "virutil.h"
+#include "virlog.h"
#define VIR_FROM_THIS VIR_FROM_SYSTEMD
@@ -38,6 +39,8 @@
* @rootdir: root directory of machine filesystem
* @pidleader: PID of the leader process
* @slice: name of the slice to place the machine in
+ *
+ * Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available
*/
int virSystemdCreateMachine(const char *name,
const char *drivername,
@@ -117,6 +120,7 @@ int virSystemdCreateMachine(const char *name,
* allow further API calls to be made against the object.
*/
+ VIR_DEBUG("Attempting to create machine via systemd");
if (virDBusCallMethod(conn,
NULL,
"org.freedesktop.machine1",
@@ -135,8 +139,15 @@ int virSystemdCreateMachine(const char *name,
(unsigned int)pidleader,
rootdir ? rootdir : "",
1, "Slice", "s",
- slicename) < 0)
+ slicename) < 0) {
+ virErrorPtr err = virGetLastError();
+ if (err->code == VIR_ERR_DBUS_SERVICE &&
+ STREQ(err->str2, "org.freedesktop.DBus.Error.ServiceUnknown")) {
+ virResetLastError();
+ ret = -2;
+ }
goto cleanup;
+ }
ret = 0;
diff --git a/tests/virsystemdmock.c b/tests/virsystemdmock.c
index 5f9cce6..1f4413c 100644
--- a/tests/virsystemdmock.c
+++ b/tests/virsystemdmock.c
@@ -60,16 +60,20 @@ dbus_bool_t dbus_connection_set_watch_functions(DBusConnection *connection ATTRI
DBusMessage *dbus_connection_send_with_reply_and_block(DBusConnection *connection ATTRIBUTE_UNUSED,
DBusMessage *message,
int timeout_milliseconds ATTRIBUTE_UNUSED,
- DBusError *error ATTRIBUTE_UNUSED)
+ DBusError *error)
{
- DBusMessage *reply;
+ DBusMessage *reply = NULL;
dbus_message_set_serial(message, 7);
- if (getenv("FAIL_NO_SERVICE"))
+ if (getenv("FAIL_BAD_SERVICE"))
reply = dbus_message_new_error(message,
- "org.freedesktop.DBus.Error.ServiceUnknown",
- "The name org.freedesktop.machine1 was not provided by any .service files");
+ "org.freedesktop.systemd.badthing",
+ "Something went wrong creating the machine");
+ else if (getenv("FAIL_NO_SERVICE"))
+ dbus_set_error(error,
+ "org.freedesktop.DBus.Error.ServiceUnknown",
+ "%s", "The name org.freedesktop.machine1 was not provided by any .service files");
else
reply = dbus_message_new_method_return(message);
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index 3992722..bcf3ad3 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -82,35 +82,60 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
3, 3, 3, 3,
4, 4, 4, 4
};
+ int rv;
setenv("FAIL_NO_SERVICE", "1", 1);
- if (virSystemdCreateMachine("demo",
- "qemu",
- true,
- uuid,
- NULL,
- 123,
- false,
- NULL) == 0) {
+ if ((rv = virSystemdCreateMachine("demo",
+ "qemu",
+ true,
+ uuid,
+ NULL,
+ 123,
+ false,
+ NULL)) == 0) {
fprintf(stderr, "%s", "Unexpected create machine success\n");
return -1;
}
- virErrorPtr err = virGetLastError();
+ if (rv != -2) {
+ fprintf(stderr, "%s", "Unexpected create machine error\n");
+ return -1;
+ }
+
+ return 0;
+}
- if (!err) {
- fprintf(stderr, "No error raised");
+static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN] = {
+ 1, 1, 1, 1,
+ 2, 2, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4
+ };
+ int rv;
+
+ setenv("FAIL_BAD_SERVICE", "1", 1);
+
+ if ((rv = virSystemdCreateMachine("demo",
+ "qemu",
+ true,
+ uuid,
+ NULL,
+ 123,
+ false,
+ NULL)) == 0) {
+ fprintf(stderr, "%s", "Unexpected create machine success\n");
return -1;
}
- if (err->code == VIR_ERR_DBUS_SERVICE &&
- STREQ(err->str2, "org.freedesktop.DBus.Error.ServiceUnknown"))
- return 0;
+ if (rv != -1) {
+ fprintf(stderr, "%s", "Unexpected create machine error\n");
+ return -1;
+ }
- fprintf(stderr, "Unexpected error code %d / message %s\n",
- err->code, err->str2);
- return -1;
+ return 0;
}
static int
@@ -122,7 +147,9 @@ mymain(void)
ret = -1;
if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
ret = -1;
- if (virtTestRun("Test create nosystemd ", 1, testCreateNoSystemd, NULL) < 0)
+ if (virtTestRun("Test create no systemd ", 1, testCreateNoSystemd, NULL) < 0)
+ ret = -1;
+ if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)
ret = -1;
return ret==0 ? EXIT_SUCCESS : EXIT_FAILURE;
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] Fix handling of DBus errors emitted by the bus itself
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Current code for handling dbus errors only works for errors
received from the remote application itself. We must also
handle errors emitted by the bus itself, for example, when
it fails to spawn the target service.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/virdbus.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index ee99f7f..e3d172e 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -1129,9 +1129,8 @@ int virDBusCallMethod(DBusConnection *conn,
call,
VIR_DBUS_METHOD_CALL_TIMEOUT_MILLIS,
&error))) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("Cannot send to %s.%s on path %s with interface %s: %s"),
- destination, member, path, interface, NULLSTR(error.message));
+ virReportDBusServiceError(error.message ? error.message : "unknown error",
+ error.name);
goto cleanup;
}
--
1.8.1.4
11 years, 5 months
[libvirt] KVM Forum 2013 Call for Participation - Extended to August 4th
by Anthony Liguori
We have received numerous requests to extend the CFP deadline and so
we are happy to announce that the CFP deadline has been moved by two
weeks to August 4th.
=================================================================
KVM Forum 2013: Call For Participation
October 21-23, 2013 - Edinburgh International Conference Centre - Edinburgh, UK
(All submissions must be received before midnight July 21, 2013)
=================================================================
KVM is an industry leading open source hypervisor that provides an ideal
platform for datacenter virtualization, virtual desktop infrastructure,
and cloud computing. Once again, it's time to bring together the
community of developers and users that define the KVM ecosystem for
our annual technical conference. We will discuss the current state of
affairs and plan for the future of KVM, its surrounding infrastructure,
and management tools. The oVirt Workshop will run in parallel with the
KVM Forum again, bringing in a community focused on enterprise datacenter
virtualization management built on KVM. For topics which overlap we will
have shared sessions. So mark your calendar and join us in advancing KVM.
http://events.linuxfoundation.org/events/kvm-forum/
Once again we are colocated with The Linux Foundation's LinuxCon Europe.
KVM Forum attendees will be able to attend oVirt Workshop sessions and
are eligible to attend LinuxCon Europe for a discounted rate.
http://events.linuxfoundation.org/events/kvm-forum/register
We invite you to lead part of the discussion by submitting a speaking
proposal for KVM Forum 2013.
http://events.linuxfoundation.org/cfp
Suggested topics:
KVM/Kernel
- Scaling and performance
- Nested virtualization
- I/O improvements
- VFIO, device assignment, SR-IOV
- Driver domains
- Time keeping
- Resource management (cpu, memory, i/o)
- Memory management (page sharing, swapping, huge pages, etc)
- Network virtualization
- Security
- Architecture ports
QEMU
- Device model improvements
- New devices and chipsets
- Scaling and performance
- Desktop virtualization
- Spice
- Increasing robustness and hardening
- Security model
- Management interfaces
- QMP protocol and implementation
- Image formats
- Firmware (SeaBIOS, OVMF, UEFI, etc)
- Live migration
- Live snapshots and merging
- Fault tolerance, high availability, continuous backup
- Real-time guest support
Virtio
- Speeding up existing devices
- Alternatives
- Virtio on non-Linux or non-virtualized
Management infrastructure
- oVirt (shared track w/ oVirt Workshop)
- Libvirt
- KVM autotest
- OpenStack
- Network virtualization management
- Enterprise storage management
Cloud computing
- Scalable storage
- Virtual networking
- Security
- Provisioning
SUBMISSION REQUIREMENTS
Abstracts due: July 21, 2013
Notification: August 1, 2013
Please submit a short abstract (~150 words) describing your presentation
proposal. In your submission please note how long your talk will take.
Slots vary in length up to 45 minutes. Also include in your proposal
the proposal type -- one of:
- technical talk
- end-user talk
- birds of a feather (BOF) session
Submit your proposal here:
http://events.linuxfoundation.org/cfp
You will receive a notification whether or not your presentation proposal
was accepted by Aug 1st.
END-USER COLLABORATION
One of the big challenges as developers is to know what, where and how
people actually use our software. We will reserve a few slots for end
users talking about their deployment challenges and achievements.
If you are using KVM in production you are encouraged submit a speaking
proposal. Simply mark it as an end-user collaboration proposal. As an
end user, this is a unique opportunity to get your input to developers.
BOF SESSION
We will reserve some slots in the evening after the main conference
tracks, for birds of a feather (BOF) sessions. These sessions will be
less formal than presentation tracks and targetted for people who would
like to discuss specific issues with other developers and/or users.
If you are interested in getting developers and/or uses together to
discuss a specific problem, please submit a BOF proposal.
HOTEL / TRAVEL
The KVM Forum 2013 will be held in Edinburgh, UK at the Edinburgh
International Conference Centre.
http://events.linuxfoundation.org/events/kvm-forum/hotel
Thank you for your interest in KVM. We're looking forward to your
submissions and seeing you at the KVM Forum 2013 in October!
Thanks,
-your KVM Forum 2013 Program Committee
Please contact us with any questions or comments.
KVM-Forum-2013-PC(a)redhat.com
11 years, 5 months
[libvirt] [PATCH] qemu: Take error path if acquiring of job fails in qemuDomainSaveInternal
by Peter Krempa
Due to a goto statement missed when refactoring in 2771f8b74c1bf50d1fa
when acquiring of a domain job failed the error path was not taken. This
resulted into a crash afterwards as a extra reference was removed from a
domain object leading to it being freed. An attempt to list the domains
afterwards leaded to a crash of the daemon afterwards.
https://bugzilla.redhat.com/show_bug.cgi?id=928672
---
Sorry for breaking that in the first place :/
src/qemu/qemu_driver.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0af76a5..96f87cd 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2987,8 +2987,8 @@ qemuDomainSaveInternal(virQEMUDriverPtr driver, virDomainPtr dom,
if (!qemuMigrationIsAllowed(driver, vm, vm->def, false, false))
goto cleanup;
- if (qemuDomainObjBeginAsyncJob(driver, vm,
- QEMU_ASYNC_JOB_SAVE) < 0)
+ if (qemuDomainObjBeginAsyncJob(driver, vm, QEMU_ASYNC_JOB_SAVE) < 0)
+ goto cleanup;
memset(&priv->job.info, 0, sizeof(priv->job.info));
priv->job.info.type = VIR_DOMAIN_JOB_UNBOUNDED;
--
1.8.3.2
11 years, 5 months
[libvirt] [PATCH] build: fix make rpm failure
by Laine Stump
util/virdbuspriv.h needed to be added to UTIL_SOURCES in the makefile.
---
Pushed under build breaker rule.
src/Makefile.am | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 0eb3cb5..84372cb 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -86,7 +86,7 @@ UTIL_SOURCES = \
util/virclosecallbacks.c util/virclosecallbacks.h \
util/vircommand.c util/vircommand.h \
util/virconf.c util/virconf.h \
- util/virdbus.c util/virdbus.h \
+ util/virdbus.c util/virdbus.h util/virdbuspriv.h \
util/virdnsmasq.c util/virdnsmasq.h \
util/virebtables.c util/virebtables.h \
util/virendian.h \
--
1.7.11.7
11 years, 5 months
[libvirt] [PATCH] bridge driver: use more general function names
by Roman Bogorodskiy
Continue preparation for extracting platform-specific
parts from bridge_driver: s/Iptables/Firewall/ for
firewall related function names.
---
src/network/bridge_driver.c | 70 ++++++++++++++++++++++-----------------------
1 file changed, 35 insertions(+), 35 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 8b50659..0bb57ea 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -116,7 +116,7 @@ static int networkStartNetworkExternal(virNetworkDriverStatePtr driver,
static int networkShutdownNetworkExternal(virNetworkDriverStatePtr driver,
virNetworkObjPtr network);
-static void networkReloadIptablesRules(virNetworkDriverStatePtr driver);
+static void networkReloadFirewallRules(virNetworkDriverStatePtr driver);
static void networkRefreshDaemons(virNetworkDriverStatePtr driver);
static int networkPlugBandwidth(virNetworkObjPtr net,
@@ -337,7 +337,7 @@ firewalld_dbus_filter_bridge(DBusConnection *connection ATTRIBUTE_UNUSED,
"Reloaded"))
{
VIR_DEBUG("Reload in bridge_driver because of firewalld.");
- networkReloadIptablesRules(_driverState);
+ networkReloadFirewallRules(_driverState);
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
@@ -428,7 +428,7 @@ networkStateInitialize(bool privileged,
goto error;
networkFindActiveConfigs(driverState);
- networkReloadIptablesRules(driverState);
+ networkReloadFirewallRules(driverState);
networkRefreshDaemons(driverState);
networkAutostartConfigs(driverState);
@@ -490,7 +490,7 @@ networkStateReload(void) {
virNetworkLoadAllConfigs(&driverState->networks,
driverState->networkConfigDir,
driverState->networkAutostartDir);
- networkReloadIptablesRules(driverState);
+ networkReloadFirewallRules(driverState);
networkRefreshDaemons(driverState);
networkAutostartConfigs(driverState);
networkDriverUnlock(driverState);
@@ -1508,7 +1508,7 @@ networkRefreshDaemons(virNetworkDriverStatePtr driver)
}
static int
-networkAddMasqueradingIptablesRules(virNetworkObjPtr network,
+networkAddMasqueradingFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
@@ -1650,7 +1650,7 @@ networkAddMasqueradingIptablesRules(virNetworkObjPtr network,
}
static void
-networkRemoveMasqueradingIptablesRules(virNetworkObjPtr network,
+networkRemoveMasqueradingFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
@@ -1688,7 +1688,7 @@ networkRemoveMasqueradingIptablesRules(virNetworkObjPtr network,
}
static int
-networkAddRoutingIptablesRules(virNetworkObjPtr network,
+networkAddRoutingFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
@@ -1735,7 +1735,7 @@ routeerr1:
}
static void
-networkRemoveRoutingIptablesRules(virNetworkObjPtr network,
+networkRemoveRoutingFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
int prefix = virNetworkIpDefPrefix(ipdef);
@@ -1857,7 +1857,7 @@ networkRemoveGeneralIp6tablesRules(virNetworkObjPtr network)
}
static int
-networkAddGeneralIptablesRules(virNetworkObjPtr network)
+networkAddGeneralFirewallRules(virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipv4def;
@@ -1979,7 +1979,7 @@ err1:
}
static void
-networkRemoveGeneralIptablesRules(virNetworkObjPtr network)
+networkRemoveGeneralFirewallRules(virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipv4def;
@@ -2009,7 +2009,7 @@ networkRemoveGeneralIptablesRules(virNetworkObjPtr network)
}
static int
-networkAddIpSpecificIptablesRules(virNetworkObjPtr network,
+networkAddIpSpecificFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
/* NB: in the case of IPv6, routing rules are added when the
@@ -2018,46 +2018,46 @@ networkAddIpSpecificIptablesRules(virNetworkObjPtr network,
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
- return networkAddMasqueradingIptablesRules(network, ipdef);
+ return networkAddMasqueradingFirewallRules(network, ipdef);
else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
- return networkAddRoutingIptablesRules(network, ipdef);
+ return networkAddRoutingFirewallRules(network, ipdef);
} else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
- return networkAddRoutingIptablesRules(network, ipdef);
+ return networkAddRoutingFirewallRules(network, ipdef);
}
return 0;
}
static void
-networkRemoveIpSpecificIptablesRules(virNetworkObjPtr network,
+networkRemoveIpSpecificFirewallRules(virNetworkObjPtr network,
virNetworkIpDefPtr ipdef)
{
if (network->def->forward.type == VIR_NETWORK_FORWARD_NAT) {
if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET))
- networkRemoveMasqueradingIptablesRules(network, ipdef);
+ networkRemoveMasqueradingFirewallRules(network, ipdef);
else if (VIR_SOCKET_ADDR_IS_FAMILY(&ipdef->address, AF_INET6))
- networkRemoveRoutingIptablesRules(network, ipdef);
+ networkRemoveRoutingFirewallRules(network, ipdef);
} else if (network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE) {
- networkRemoveRoutingIptablesRules(network, ipdef);
+ networkRemoveRoutingFirewallRules(network, ipdef);
}
}
/* Add all rules for all ip addresses (and general rules) on a network */
static int
-networkAddIptablesRules(virNetworkObjPtr network)
+networkAddFirewallRules(virNetworkObjPtr network)
{
size_t i, j;
virNetworkIpDefPtr ipdef;
virErrorPtr orig_error;
/* Add "once per network" rules */
- if (networkAddGeneralIptablesRules(network) < 0)
+ if (networkAddGeneralFirewallRules(network) < 0)
return -1;
for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) {
/* Add address-specific iptables rules */
- if (networkAddIpSpecificIptablesRules(network, ipdef) < 0) {
+ if (networkAddIpSpecificFirewallRules(network, ipdef) < 0) {
goto err;
}
}
@@ -2067,15 +2067,15 @@ err:
/* store the previous error message before attempting removal of rules */
orig_error = virSaveLastError();
- /* The final failed call to networkAddIpSpecificIptablesRules will
+ /* The final failed call to networkAddIpSpecificFirewallRules will
* have removed any rules it created, but we need to remove those
* added for previous IP addresses.
*/
for (j = 0; j < i; j++) {
if ((ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, j)))
- networkRemoveIpSpecificIptablesRules(network, ipdef);
+ networkRemoveIpSpecificFirewallRules(network, ipdef);
}
- networkRemoveGeneralIptablesRules(network);
+ networkRemoveGeneralFirewallRules(network);
/* return the original error */
virSetError(orig_error);
@@ -2085,7 +2085,7 @@ err:
/* Remove all rules for all ip addresses (and general rules) on a network */
static void
-networkRemoveIptablesRules(virNetworkObjPtr network)
+networkRemoveFirewallRules(virNetworkObjPtr network)
{
size_t i;
virNetworkIpDefPtr ipdef;
@@ -2093,13 +2093,13 @@ networkRemoveIptablesRules(virNetworkObjPtr network)
for (i = 0;
(ipdef = virNetworkDefGetIpByIndex(network->def, AF_UNSPEC, i));
i++) {
- networkRemoveIpSpecificIptablesRules(network, ipdef);
+ networkRemoveIpSpecificFirewallRules(network, ipdef);
}
- networkRemoveGeneralIptablesRules(network);
+ networkRemoveGeneralFirewallRules(network);
}
static void
-networkReloadIptablesRules(virNetworkDriverStatePtr driver)
+networkReloadFirewallRules(virNetworkDriverStatePtr driver)
{
size_t i;
@@ -2116,8 +2116,8 @@ networkReloadIptablesRules(virNetworkDriverStatePtr driver)
/* Only the three L3 network types that are configured by libvirt
* need to have iptables rules reloaded.
*/
- networkRemoveIptablesRules(network);
- if (networkAddIptablesRules(network) < 0) {
+ networkRemoveFirewallRules(network);
+ if (networkAddFirewallRules(network) < 0) {
/* failed to add but already logged */
}
}
@@ -2436,7 +2436,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
goto err1;
/* Add "once per network" rules */
- if (networkAddIptablesRules(network) < 0)
+ if (networkAddFirewallRules(network) < 0)
goto err1;
for (i = 0;
@@ -2529,7 +2529,7 @@ networkStartNetworkVirtual(virNetworkDriverStatePtr driver,
err2:
if (!save_err)
save_err = virSaveLastError();
- networkRemoveIptablesRules(network);
+ networkRemoveFirewallRules(network);
err1:
if (!save_err)
@@ -2583,7 +2583,7 @@ static int networkShutdownNetworkVirtual(virNetworkDriverStatePtr driver ATTRIBU
ignore_value(virNetDevSetOnline(network->def->bridge, 0));
- networkRemoveIptablesRules(network);
+ networkRemoveFirewallRules(network);
ignore_value(virNetDevBridgeDelete(network->def->bridge));
@@ -3411,8 +3411,8 @@ networkUpdate(virNetworkPtr net,
network->def->forward.type == VIR_NETWORK_FORWARD_NAT ||
network->def->forward.type == VIR_NETWORK_FORWARD_ROUTE)) {
/* these could affect the iptables rules */
- networkRemoveIptablesRules(network);
- if (networkAddIptablesRules(network) < 0)
+ networkRemoveFirewallRules(network);
+ if (networkAddFirewallRules(network) < 0)
goto cleanup;
}
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] Add virDBusMessage(Encode,Decode) stubs
by Roman Bogorodskiy
Commit 834c9c94 introduced virDBusMessageEncode and
virDBusMessageDecode functions, however corresponding stubs
were not added to !WITH_DBUS section, therefore 'make check'
started to fail when compiled w/out dbus support like that:
Expected symbol virDBusMessageDecode is not in ELF library
---
src/util/virdbus.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/util/virdbus.c b/src/util/virdbus.c
index ee99f7f..6221bdc 100644
--- a/src/util/virdbus.c
+++ b/src/util/virdbus.c
@@ -1222,4 +1222,22 @@ int virDBusMessageRead(DBusMessage *msg ATTRIBUTE_UNUSED,
return -1;
}
+int virDBusMessageEncode(DBusMessage* msg ATTRIBUTE_UNUSED,
+ const char *types ATTRIBUTE_UNUSED,
+ ...)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("DBus support not compiled into this binary"));
+ return -1;
+}
+
+int virDBusMessageDecode(DBusMessage* msg ATTRIBUTE_UNUSED,
+ const char *types ATTRIBUTE_UNUSED,
+ ...)
+{
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("DBus support not compiled into this binary"));
+ return -1;
+}
+
#endif /* ! WITH_DBUS */
--
1.8.1.4
11 years, 5 months
[libvirt] [PATCH] Make locking more debuggable from logs
by Martin Kletzander
With this patch, there is new ./configure option '--enable-lock-debug'
which controls whether we want to turn on debugging locks. This
feature is exposed as a ./configure option due to its huge overhead in
speed/log size and is only meant to be used with this in mind. It is
designed in a way that even log from deadlocked daemon should provide
enough info to find the deadlock itself. Every matching Lock() call
can be matched with its Unlock() call and with every Lock() called it
is visible whether it failed or not. Unlock() call follows the same
output, even though unnecessary (the call cannot block).
Lock logging is disabled while logging because that would either
recurse or deadlock.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
configure.ac | 19 +++++++++++++++
src/Makefile.am | 3 ++-
src/libvirt_private.syms | 1 +
src/util/virlog.c | 8 +++++++
src/util/virthread.h | 4 ++++
src/util/virthreadpthread.c | 58 ++++++++++++++++++++++++++++++++++++++++++++-
src/util/virutil.c | 40 +++++++++++++++++++++++++++++++
src/util/virutil.h | 2 ++
8 files changed, 133 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index b5af0d3..c63ffe7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -478,6 +478,24 @@ if test x"$enable_debug" = x"yes"; then
AC_DEFINE([ENABLE_DEBUG], [], [whether debugging is enabled])
fi
+dnl --enable-lock-debug=(yes|no)
+AC_ARG_ENABLE([lock-debug],
+ [AC_HELP_STRING([--enable-lock-debug=@<:@no|yes@:>@],
+ [enable lock debugging (beware of huge overhead) @<:@default=no@:>@])],
+ [],[enable_lock_debug=no])
+AM_CONDITIONAL([ENABLE_LOCK_DEBUG], test x"$enable_lock_debug" = x"yes")
+if test x"$enable_lock_debug" = x"yes"; then
+ if test "$ac_cv_header_pthread_h" != "yes" ; then
+ AC_MSG_ERROR([POSIX threads are needed to properly debug locking])
+ fi
+ if test x"$enable_debug" != x"yes" ; then
+ AC_MSG_ERROR([Cannot debug locking without enabling debugging itself])
+ fi
+
+ AC_DEFINE([ENABLE_LOCK_DEBUG], [], [whether lock debugging is enabled])
+ LOCK_DEBUG_LDFLAGS="-rdynamic"
+fi
+AC_SUBST([LOCK_DEBUG_LDFLAGS])
dnl
@@ -2601,6 +2619,7 @@ AC_MSG_NOTICE([])
AC_MSG_NOTICE([Miscellaneous])
AC_MSG_NOTICE([])
AC_MSG_NOTICE([ Debug: $enable_debug])
+AC_MSG_NOTICE([ Lock debug: $enable_lock_debug])
AC_MSG_NOTICE([ Use -Werror: $set_werror])
AC_MSG_NOTICE([ Warning Flags: $WARN_CFLAGS])
AC_MSG_NOTICE([ Readline: $lv_use_readline])
diff --git a/src/Makefile.am b/src/Makefile.am
index 8fa8680..ef6aaa3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,7 +33,8 @@ AM_CFLAGS = $(LIBXML_CFLAGS) \
$(WIN32_EXTRA_CFLAGS) \
$(COVERAGE_CFLAGS)
AM_LDFLAGS = $(DRIVER_MODULE_LDFLAGS) \
- $(COVERAGE_LDFLAGS)
+ $(COVERAGE_LDFLAGS) \
+ $(LOCK_DEBUG_LDFLAGS)
EXTRA_DIST = $(conf_DATA) util/keymaps.csv
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 7790ede..44b4a60 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2022,6 +2022,7 @@ virGetGroupID;
virGetGroupList;
virGetGroupName;
virGetHostname;
+virGetLockFunc;
virGetUnprivSGIOSysfsPath;
virGetUserCacheDirectory;
virGetUserConfigDirectory;
diff --git a/src/util/virlog.c b/src/util/virlog.c
index d1fb0b3..8d1e943 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -150,14 +150,22 @@ virMutex virLogMutex;
void
virLogLock(void)
{
+#ifdef ENABLE_LOCK_DEBUG
+ virMutexLockNoLog(&virLogMutex);
+#else
virMutexLock(&virLogMutex);
+#endif
}
void
virLogUnlock(void)
{
+#ifdef ENABLE_LOCK_DEBUG
+ virMutexUnlockNoLog(&virLogMutex);
+#else
virMutexUnlock(&virLogMutex);
+#endif
}
diff --git a/src/util/virthread.h b/src/util/virthread.h
index 84d3bdc..6d86227 100644
--- a/src/util/virthread.h
+++ b/src/util/virthread.h
@@ -88,6 +88,10 @@ void virMutexDestroy(virMutexPtr m);
void virMutexLock(virMutexPtr m);
void virMutexUnlock(virMutexPtr m);
+# ifdef ENABLE_LOCK_DEBUG
+void virMutexLockNoLog(virMutexPtr m);
+void virMutexUnlockNoLog(virMutexPtr m);
+# endif
int virCondInit(virCondPtr c) ATTRIBUTE_RETURN_CHECK;
diff --git a/src/util/virthreadpthread.c b/src/util/virthreadpthread.c
index ca841e4..95e20b5 100644
--- a/src/util/virthreadpthread.c
+++ b/src/util/virthreadpthread.c
@@ -29,6 +29,11 @@
#include "viralloc.h"
+#ifdef ENABLE_LOCK_DEBUG
+# include "virutil.h"
+# include "virlog.h"
+#endif
+
/* Nothing special required for pthreads */
int virThreadInitialize(void)
@@ -81,7 +86,57 @@ void virMutexDestroy(virMutexPtr m)
pthread_mutex_destroy(&m->lock);
}
-void virMutexLock(virMutexPtr m){
+#ifdef ENABLE_LOCK_DEBUG
+
+# define PRE_LOCK_PROC(mutex) \
+ char *frame = virGetLockFrame(); \
+ do { \
+ if (frame) \
+ VIR_DEBUG("lock=%p, frame=%s, state=request", \
+ &mutex->lock, NULLSTR(frame)); \
+ else \
+ VIR_DEBUG("lock=%p, state=request", &mutex->lock); \
+ } while (0)
+
+# define POST_LOCK_PROC(mutex) \
+ do { \
+ if (frame) { \
+ VIR_DEBUG("lock=%p, frame=%s, state=done", \
+ &mutex->lock, NULLSTR(frame)); \
+ VIR_FREE(frame); \
+ } else { \
+ VIR_DEBUG("lock=%p, state=done", &mutex->lock); \
+ } \
+ } while (0)
+
+void virMutexLock(virMutexPtr m)
+{
+ PRE_LOCK_PROC(m);
+ virMutexLockNoLog(m);
+ POST_LOCK_PROC(m);
+}
+
+void virMutexUnlock(virMutexPtr m)
+{
+ PRE_LOCK_PROC(m);
+ virMutexUnlockNoLog(m);
+ POST_LOCK_PROC(m);
+}
+
+void virMutexLockNoLog(virMutexPtr m)
+{
+ pthread_mutex_lock(&m->lock);
+}
+
+void virMutexUnlockNoLog(virMutexPtr m)
+{
+ pthread_mutex_unlock(&m->lock);
+}
+
+#else /* ENABLE_LOCK_DEBUG */
+
+void virMutexLock(virMutexPtr m)
+{
pthread_mutex_lock(&m->lock);
}
@@ -90,6 +145,7 @@ void virMutexUnlock(virMutexPtr m)
pthread_mutex_unlock(&m->lock);
}
+#endif /* ENABLE_LOCK_DEBUG */
int virCondInit(virCondPtr c)
{
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 0b54ef7..88b7984 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -40,6 +40,7 @@
#include <string.h>
#include <termios.h>
#include <locale.h>
+#include <execinfo.h>
#if HAVE_LIBDEVMAPPER_H
# include <libdevmapper.h>
@@ -2017,3 +2018,42 @@ virCompareLimitUlong(unsigned long long a, unsigned long b)
return -1;
}
+
+
+/**
+ * virGetLockFrame:
+ *
+ * This function returns possibly the most relevant frame information
+ * from where a lock function was called. This info is obtained from
+ * a backtrace while going through the functions and filtering those
+ * which end with 'Lock'.
+ *
+ * We don't want to log anything from this method, not even an OOM
+ * Error, in case of any problems, just cleanup and return NULL.
+ */
+char *
+virGetLockFrame(void)
+{
+ char **fnames = NULL;
+ char *out = NULL;
+ int i = 0;
+ int nframes = 0;
+ void *frames[100] = {0};
+
+ if (!(nframes = backtrace(frames, ARRAY_CARDINALITY(frames))) ||
+ !(fnames = backtrace_symbols(frames, nframes)))
+ goto cleanup;
+
+ for (i = 0; i < nframes; i++) {
+ if (!strstr(fnames[i], "Lock") &&
+ !strstr(fnames[i], "Unlock") &&
+ !strstr(fnames[i], "(+")) {
+ ignore_value(VIR_STRDUP_QUIET(out, fnames[i]));
+ break;
+ }
+ }
+
+ cleanup:
+ VIR_FREE(fnames);
+ return out;
+}
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 0083c88..e385ae6 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -169,4 +169,6 @@ char *virFindFCHostCapableVport(const char *sysfs_prefix);
int virCompareLimitUlong(unsigned long long a, unsigned long b);
+char *virGetLockFrame(void);
+
#endif /* __VIR_UTIL_H__ */
--
1.8.3.2
11 years, 5 months