[libvirt] [PATCH][libvirt-glib] Don't misuse GMainLoop for libvirt event loop
by Michal Privoznik
Since we are calling APIs within timers, those might block as
any libvirt API may block. This, however, might get so critical,
that server will shut us down due to timeout on keepalive.
Simply, if an API called within a timer block, entire event loop
is blocked and no keepalive response can be sent.
Therefore, delegate separate thread for such purpose.
---
For some reason LibvirtGObject-1.0.gir generation fails with this from time to time.
examples/event-test.c | 4 +-
libvirt-glib/libvirt-glib-event.c | 474 +++++++-------------------------
libvirt-glib/libvirt-glib-event.h | 3 +-
libvirt-glib/libvirt-glib.sym | 5 +
libvirt-gobject/libvirt-gobject-main.c | 3 +-
python/libvirt-glib.c | 23 ++-
6 files changed, 129 insertions(+), 383 deletions(-)
diff --git a/examples/event-test.c b/examples/event-test.c
index 7c9f4ec..ccb8f9e 100644
--- a/examples/event-test.c
+++ b/examples/event-test.c
@@ -166,7 +166,8 @@ int main(int argc, char **argv)
}
loop = g_main_loop_new(g_main_context_default(), 1);
- gvir_event_register();
+ if (gvir_event_register() != TRUE)
+ return -1;
virConnectPtr dconn = NULL;
dconn = virConnectOpen (argv[1] ? argv[1] : NULL);
@@ -185,6 +186,7 @@ int main(int argc, char **argv)
if (virConnectClose(dconn) < 0)
printf("error closing\n");
+ gvir_event_deregister();
printf("done\n");
return 0;
diff --git a/libvirt-glib/libvirt-glib-event.c b/libvirt-glib/libvirt-glib-event.c
index 94f4de8..d3cf7c3 100644
--- a/libvirt-glib/libvirt-glib-event.c
+++ b/libvirt-glib/libvirt-glib-event.c
@@ -33,7 +33,7 @@
/**
* SECTION:libvirt-glib-event
- * @short_description: Integrate libvirt with the GMain event framework
+ * @short_description: Implement libvirt event loop
* @title: Event loop
* @stability: Stable
* @include: libvirt-glib/libvirt-glib.h
@@ -41,22 +41,23 @@
* The libvirt API has the ability to provide applications with asynchronous
* notifications of interesting events. To enable this functionality though,
* applications must provide libvirt with an event loop implementation. The
- * libvirt-glib API provides such an implementation, which naturally integrates
- * with the GMain event loop framework.
+ * libvirt-glib API provides such an implementation.
*
- * To enable use of the GMain event loop glue, the <code>gvir_event_register()</code>
- * should be invoked. Once this is done, it is mandatory to have the default
- * GMain event loop run by a thread in the application, usually the primary
- * thread, eg by using <code>gtk_main()</code> or <code>g_application_run()</code>
+ * To enable this one must call <code>gvir_event_register()</code>. This will create
+ * a separate thread which will run the libvirt event loop. Once the event loop is
+ * no longer needed, it should be joined by invoking
+ * <code>gvir_event_deregister()</code>.
*
* <example>
* <title>Registering for events with a GTK application</title>
* <programlisting><![CDATA[
* int main(int argc, char **argv) {
* ...setup...
- * gvir_event_register();
+ * if (gvir_event_register() != TRUE)
+ * return -1;
* ...more setup...
* gtk_main();
+ * gvir_event_deregister();
* return 0;
* }
* ]]></programlisting>
@@ -68,9 +69,11 @@
* int main(int argc, char **argv) {
* ...setup...
* GApplication *app = ...create some impl of GApplication...
- * gvir_event_register();
+ * if (gvir_event_register() != TRUE)
+ * return -1;
* ...more setup...
* g_application_run(app);
+ * gvir_event_deregister();
* return 0;
* }
* ]]></programlisting>
@@ -80,408 +83,123 @@
#if GLIB_CHECK_VERSION(2, 31, 0)
#define g_mutex_new() g_new0(GMutex, 1)
+#define g_mutex_free(m) g_free(m)
#endif
-struct gvir_event_handle
+GThread *event_thread = NULL;
+GMutex *event_lock = NULL;
+gboolean quit = FALSE;
+
+static gpointer
+event_loop(gpointer dummy G_GNUC_UNUSED)
+{
+ while (1) {
+ gboolean do_quit;
+
+ g_mutex_lock(event_lock);
+ do_quit = quit;
+ g_mutex_unlock(event_lock);
+
+ if (do_quit)
+ break;
+
+ if (virEventRunDefaultImpl() < 0)
+ g_warn_if_reached();
+ }
+ return NULL;
+}
+
+static void
+deinit_timer(int timer G_GNUC_UNUSED, void *dummy G_GNUC_UNUSED)
{
- int watch;
- int fd;
- int events;
- int enabled;
- GIOChannel *channel;
- guint source;
- virEventHandleCallback cb;
- void *opaque;
- virFreeCallback ff;
-};
-
-struct gvir_event_timeout
+ /* nothing to be done here */
+}
+
+static gpointer
+event_deregister_once(gpointer data G_GNUC_UNUSED)
{
int timer;
- int interval;
- guint source;
- virEventTimeoutCallback cb;
- void *opaque;
- virFreeCallback ff;
-};
-GMutex *eventlock = NULL;
-
-static int nextwatch = 1;
-static GPtrArray *handles;
-
-static int nexttimer = 1;
-static GPtrArray *timeouts;
-
-static gboolean
-gvir_event_handle_dispatch(GIOChannel *source G_GNUC_UNUSED,
- GIOCondition condition,
- gpointer opaque)
-{
- struct gvir_event_handle *data = opaque;
- int events = 0;
-
- if (condition & G_IO_IN)
- events |= VIR_EVENT_HANDLE_READABLE;
- if (condition & G_IO_OUT)
- events |= VIR_EVENT_HANDLE_WRITABLE;
- if (condition & G_IO_HUP)
- events |= VIR_EVENT_HANDLE_HANGUP;
- if (condition & G_IO_ERR)
- events |= VIR_EVENT_HANDLE_ERROR;
-
- g_debug("Dispatch handler %d %d %p\n", data->fd, events, data->opaque);
-
- (data->cb)(data->watch, data->fd, events, data->opaque);
-
- return TRUE;
-}
-
-
-static int
-gvir_event_handle_add(int fd,
- int events,
- virEventHandleCallback cb,
- void *opaque,
- virFreeCallback ff)
-{
- struct gvir_event_handle *data;
- GIOCondition cond = 0;
- int ret;
-
- g_mutex_lock(eventlock);
-
- data = g_new0(struct gvir_event_handle, 1);
-
- if (events & VIR_EVENT_HANDLE_READABLE)
- cond |= G_IO_IN;
- if (events & VIR_EVENT_HANDLE_WRITABLE)
- cond |= G_IO_OUT;
-
- data->watch = nextwatch++;
- data->fd = fd;
- data->events = events;
- data->cb = cb;
- data->opaque = opaque;
- data->channel = g_io_channel_unix_new(fd);
- data->ff = ff;
-
- g_debug("Add handle %d %d %p\n", data->fd, events, data->opaque);
-
- data->source = g_io_add_watch(data->channel,
- cond,
- gvir_event_handle_dispatch,
- data);
-
- g_ptr_array_add(handles, data);
-
- ret = data->watch;
-
- g_mutex_unlock(eventlock);
-
- return ret;
-}
-
-static struct gvir_event_handle *
-gvir_event_handle_find(int watch, guint *idx)
-{
- guint i;
-
- for (i = 0 ; i < handles->len ; i++) {
- struct gvir_event_handle *h = g_ptr_array_index(handles, i);
-
- if (h == NULL) {
- g_warn_if_reached ();
- continue;
- }
-
- if (h->watch == watch) {
- if (idx != NULL)
- *idx = i;
- return h;
- }
- }
-
- return NULL;
-}
-
-static void
-gvir_event_handle_update(int watch,
- int events)
-{
- struct gvir_event_handle *data;
-
- g_mutex_lock(eventlock);
-
- data = gvir_event_handle_find(watch, NULL);
- if (!data) {
- g_debug("Update for missing handle watch %d", watch);
- goto cleanup;
+ if (!event_thread) {
+ g_warn_if_reached();
+ return NULL;
}
- if (events) {
- GIOCondition cond = 0;
- if (events == data->events)
- goto cleanup;
-
- if (data->source)
- g_source_remove(data->source);
-
- cond |= G_IO_HUP;
- if (events & VIR_EVENT_HANDLE_READABLE)
- cond |= G_IO_IN;
- if (events & VIR_EVENT_HANDLE_WRITABLE)
- cond |= G_IO_OUT;
- data->source = g_io_add_watch(data->channel,
- cond,
- gvir_event_handle_dispatch,
- data);
- data->events = events;
- } else {
- if (!data->source)
- goto cleanup;
-
- g_source_remove(data->source);
- data->source = 0;
- data->events = 0;
- }
-
-cleanup:
- g_mutex_unlock(eventlock);
-}
+ g_mutex_lock(event_lock);
+ quit = TRUE;
+ /* Add dummy timeout to break event loop */
+ timer = virEventAddTimeout(0, deinit_timer, NULL, NULL);
+ g_mutex_unlock(event_lock);
-static gboolean
-_event_handle_remove(gpointer data)
-{
- struct gvir_event_handle *h = data;
-
- if (h->ff)
- (h->ff)(h->opaque);
-
- g_ptr_array_remove_fast(handles, h);
-
- return FALSE;
-}
-
-static int
-gvir_event_handle_remove(int watch)
-{
- struct gvir_event_handle *data;
- int ret = -1;
- guint idx;
-
- g_mutex_lock(eventlock);
-
- data = gvir_event_handle_find(watch, &idx);
- if (!data) {
- g_debug("Remove of missing watch %d", watch);
- goto cleanup;
- }
-
- g_debug("Remove handle %d %d\n", watch, data->fd);
-
- if (!data->source)
- goto cleanup;
+ g_thread_join(event_thread);
+ g_mutex_free(event_lock);
+ event_lock = NULL;
+ event_thread = NULL;
+ quit = FALSE;
- g_source_remove(data->source);
- data->source = 0;
- data->events = 0;
- g_idle_add(_event_handle_remove, data);
-
- ret = 0;
-
-cleanup:
- g_mutex_unlock(eventlock);
- return ret;
-}
-
-
-static gboolean
-gvir_event_timeout_dispatch(void *opaque)
-{
- struct gvir_event_timeout *data = opaque;
- g_debug("Dispatch timeout %p %p %d %p\n", data, data->cb, data->timer, data->opaque);
- (data->cb)(data->timer, data->opaque);
-
- return TRUE;
-}
-
-static int
-gvir_event_timeout_add(int interval,
- virEventTimeoutCallback cb,
- void *opaque,
- virFreeCallback ff)
-{
- struct gvir_event_timeout *data;
- int ret;
-
- g_mutex_lock(eventlock);
-
- data = g_new0(struct gvir_event_timeout, 1);
- data->timer = nexttimer++;
- data->interval = interval;
- data->cb = cb;
- data->opaque = opaque;
- data->ff = ff;
- if (interval >= 0)
- data->source = g_timeout_add(interval,
- gvir_event_timeout_dispatch,
- data);
-
- g_ptr_array_add(timeouts, data);
-
- g_debug("Add timeout %p %d %p %p %d\n", data, interval, cb, opaque, data->timer);
-
- ret = data->timer;
-
- g_mutex_unlock(eventlock);
-
- return ret;
-}
-
-
-static struct gvir_event_timeout *
-gvir_event_timeout_find(int timer, guint *idx)
-{
- guint i;
-
- g_return_val_if_fail(timeouts != NULL, NULL);
-
- for (i = 0 ; i < timeouts->len ; i++) {
- struct gvir_event_timeout *t = g_ptr_array_index(timeouts, i);
-
- if (t == NULL) {
- g_warn_if_reached ();
- continue;
- }
-
- if (t->timer == timer) {
- if (idx != NULL)
- *idx = i;
- return t;
- }
- }
+ if (timer != -1)
+ virEventRemoveTimeout(timer);
return NULL;
}
-
-static void
-gvir_event_timeout_update(int timer,
- int interval)
+/*
+ * gvir_event_deregister:
+ *
+ * De-register libvirt event loop and free allocated memory.
+ * If invoked more than once, this method will be no-op.
+ *
+ */
+void
+gvir_event_deregister(void)
{
- struct gvir_event_timeout *data;
-
- g_mutex_lock(eventlock);
+ static GOnce once = G_ONCE_INIT;
- data = gvir_event_timeout_find(timer, NULL);
- if (!data) {
- g_debug("Update of missing timer %d", timer);
- goto cleanup;
- }
-
- g_debug("Update timeout %p %d %d\n", data, timer, interval);
-
- if (interval >= 0) {
- if (data->source)
- goto cleanup;
-
- data->interval = interval;
- data->source = g_timeout_add(data->interval,
- gvir_event_timeout_dispatch,
- data);
- } else {
- if (!data->source)
- goto cleanup;
-
- g_source_remove(data->source);
- data->source = 0;
- }
-
-cleanup:
- g_mutex_unlock(eventlock);
-}
-
-static gboolean
-_event_timeout_remove(gpointer data)
-{
- struct gvir_event_timeout *t = data;
-
- if (t->ff)
- (t->ff)(t->opaque);
-
- g_ptr_array_remove_fast(timeouts, t);
-
- return FALSE;
+ g_once(&once, event_deregister_once, NULL);
}
-static int
-gvir_event_timeout_remove(int timer)
+static gpointer
+event_register_once(gpointer data G_GNUC_UNUSED)
{
- struct gvir_event_timeout *data;
- guint idx;
- int ret = -1;
-
- g_mutex_lock(eventlock);
+ GError *err;
- data = gvir_event_timeout_find(timer, &idx);
- if (!data) {
- g_debug("Remove of missing timer %d", timer);
+ if (virEventRegisterDefaultImpl() < 0)
goto cleanup;
- }
-
- g_debug("Remove timeout %p %d\n", data, timer);
-
- if (!data->source)
- goto cleanup;
-
- g_source_remove(data->source);
- data->source = 0;
- g_idle_add(_event_timeout_remove, data);
- ret = 0;
+ event_lock = g_mutex_new();
+
+ event_thread = g_thread_create(event_loop, NULL, TRUE, &err);
+ if (!event_thread) {
+ g_warning("Libvirt event loop thread could not be created: %s",
+ err->message);
+ g_error_free(err);
+ g_mutex_free(event_lock);
+ }
cleanup:
- g_mutex_unlock(eventlock);
- return ret;
+ return event_thread;
}
-
-static gpointer event_register_once(gpointer data G_GNUC_UNUSED)
-{
- eventlock = g_mutex_new();
- timeouts = g_ptr_array_new_with_free_func(g_free);
- handles = g_ptr_array_new_with_free_func(g_free);
- virEventRegisterImpl(gvir_event_handle_add,
- gvir_event_handle_update,
- gvir_event_handle_remove,
- gvir_event_timeout_add,
- gvir_event_timeout_update,
- gvir_event_timeout_remove);
- return NULL;
-}
-
-
/**
* gvir_event_register:
*
- * Registers a libvirt event loop implementation that is backed
- * by the default <code>GMain</code> context. If invoked more
- * than once this method will be a no-op. Applications should,
- * however, take care not to register any another non-GLib
- * event loop with libvirt.
+ * Registers a libvirt event loop implementation. If invoked
+ * more than once this method will be a no-op. If event loop
+ * is no longer needed, it should be free'd by invoking
+ * <code>gvir_event_deregister()</code>.
+ * Failure to run the event loop will mean no libvirt events
+ * get dispatched, and the libvirt keepalive timer will kill
+ * off libvirt connections frequently.
*
- * After invoking this method, it is mandatory to run the
- * default GMain event loop. Typically this can be satisfied
- * by invoking <code>gtk_main</code> or <code>g_application_run</code>
- * in the application's main thread. Failure to run the event
- * loop will mean no libvirt events get dispatched, and the
- * libvirt keepalive timer will kill off libvirt connections
- * frequently.
+ * Returns: (transfer full): #TRUE on successful init,
+ * #FALSE otherwise.
*/
-void gvir_event_register(void)
+gboolean
+gvir_event_register(void)
{
static GOnce once = G_ONCE_INIT;
g_once(&once, event_register_once, NULL);
+
+ return once.retval ? TRUE : FALSE;
}
diff --git a/libvirt-glib/libvirt-glib-event.h b/libvirt-glib/libvirt-glib-event.h
index 57cadab..e163674 100644
--- a/libvirt-glib/libvirt-glib-event.h
+++ b/libvirt-glib/libvirt-glib-event.h
@@ -28,7 +28,8 @@
G_BEGIN_DECLS
-void gvir_event_register(void);
+gboolean gvir_event_register(void);
+void gvir_event_deregister(void);
G_END_DECLS
diff --git a/libvirt-glib/libvirt-glib.sym b/libvirt-glib/libvirt-glib.sym
index 53b8907..8f6f15f 100644
--- a/libvirt-glib/libvirt-glib.sym
+++ b/libvirt-glib/libvirt-glib.sym
@@ -15,4 +15,9 @@ LIBVIRT_GLIB_0.0.7 {
*;
};
+LIBVIRT_GLIB_0.0.9 {
+ global:
+ gvir_event_deregister;
+} LIBVIRT_GLIB_0.0.7;
+
# .... define new API here using predicted next version number ....
diff --git a/libvirt-gobject/libvirt-gobject-main.c b/libvirt-gobject/libvirt-gobject-main.c
index 9dd6e3c..c7980ff 100644
--- a/libvirt-gobject/libvirt-gobject-main.c
+++ b/libvirt-gobject/libvirt-gobject-main.c
@@ -66,7 +66,8 @@ gboolean gvir_init_object_check(int *argc,
{
g_type_init();
- gvir_event_register();
+ if (gvir_event_register() != TRUE)
+ return FALSE;
if (!gvir_init_check(argc, argv, err))
return FALSE;
diff --git a/python/libvirt-glib.c b/python/libvirt-glib.c
index 1daca36..6b8c78c 100644
--- a/python/libvirt-glib.c
+++ b/python/libvirt-glib.c
@@ -24,17 +24,36 @@ extern void initcygvirtglibmod(void);
#endif
#define VIR_PY_NONE (Py_INCREF (Py_None), Py_None)
+#define VIR_PY_INT_FAIL (libvirt_intWrap(-1))
+#define VIR_PY_INT_SUCCESS (libvirt_intWrap(0))
+
+PyObject *
+libvirt_intWrap(int val)
+{
+ PyObject *ret;
+ ret = PyInt_FromLong((long) val);
+ return ret;
+}
static PyObject *
libvirt_gvir_event_register(PyObject *self G_GNUC_UNUSED, PyObject *args G_GNUC_UNUSED) {
- gvir_event_register();
+ if ( gvir_event_register() != TRUE)
+ return VIR_PY_INT_FAIL;
+
+ return VIR_PY_INT_SUCCESS;
+}
+
+
+static PyObject *
+libvirt_gvir_event_deregister(PyObject *self G_GNUC_UNUSED, PyObject 8args G_GNUC_UNUSED) {
+ gvir_event_deregister();
return VIR_PY_NONE;
}
-
static PyMethodDef libvirtGLibMethods[] = {
{(char *) "event_register", libvirt_gvir_event_register, METH_VARARGS, NULL},
+ {(char *) "event_deregister", libvirt_gvir_event_deregister, METH_VARARGS, NULL},
{NULL, NULL, 0, NULL}
};
--
1.7.8.5
12 years, 6 months
[libvirt] [PATCH] security: Switch to C99-style struct initialization
by Michal Privoznik
---
src/security/security_apparmor.c | 50 ++++++++++++++++++------------------
src/security/security_dac.c | 53 ++++++++++++++++++-------------------
src/security/security_nop.c | 52 ++++++++++++++++++------------------
src/security/security_selinux.c | 52 ++++++++++++++++++------------------
src/security/security_stack.c | 52 ++++++++++++++++++------------------
5 files changed, 129 insertions(+), 130 deletions(-)
diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 2d05fd0..62af3c6 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -809,39 +809,39 @@ AppArmorSetImageFDLabel(virSecurityManagerPtr mgr,
}
virSecurityDriver virAppArmorSecurityDriver = {
- 0,
- SECURITY_APPARMOR_NAME,
- AppArmorSecurityManagerProbe,
- AppArmorSecurityManagerOpen,
- AppArmorSecurityManagerClose,
+ .privateDataLen = 0,
+ .name = SECURITY_APPARMOR_NAME,
+ .probe = AppArmorSecurityManagerProbe,
+ .open = AppArmorSecurityManagerOpen,
+ .close = AppArmorSecurityManagerClose,
- AppArmorSecurityManagerGetModel,
- AppArmorSecurityManagerGetDOI,
+ .getModel = AppArmorSecurityManagerGetModel,
+ .getDOI = AppArmorSecurityManagerGetDOI,
- AppArmorSecurityVerify,
+ .domainSecurityVerify = AppArmorSecurityVerify,
- AppArmorSetSecurityImageLabel,
- AppArmorRestoreSecurityImageLabel,
+ .domainSetSecurityImageLabel = AppArmorSetSecurityImageLabel,
+ .domainRestoreSecurityImageLabel = AppArmorRestoreSecurityImageLabel,
- AppArmorSetSecurityDaemonSocketLabel,
- AppArmorSetSecuritySocketLabel,
- AppArmorClearSecuritySocketLabel,
+ .domainSetSecurityDaemonSocketLabel = AppArmorSetSecurityDaemonSocketLabel,
+ .domainSetSecuritySocketLabel = AppArmorSetSecuritySocketLabel,
+ .domainClearSecuritySocketLabel = AppArmorClearSecuritySocketLabel,
- AppArmorGenSecurityLabel,
- AppArmorReserveSecurityLabel,
- AppArmorReleaseSecurityLabel,
+ .domainGenSecurityLabel = AppArmorGenSecurityLabel,
+ .domainReserveSecurityLabel = AppArmorReserveSecurityLabel,
+ .domainReleaseSecurityLabel = AppArmorReleaseSecurityLabel,
- AppArmorGetSecurityProcessLabel,
- AppArmorSetSecurityProcessLabel,
+ .domainGetSecurityProcessLabel = AppArmorGetSecurityProcessLabel,
+ .domainSetSecurityProcessLabel = AppArmorSetSecurityProcessLabel,
- AppArmorSetSecurityAllLabel,
- AppArmorRestoreSecurityAllLabel,
+ .domainSetSecurityAllLabel = AppArmorSetSecurityAllLabel,
+ .domainRestoreSecurityAllLabel = AppArmorRestoreSecurityAllLabel,
- AppArmorSetSecurityHostdevLabel,
- AppArmorRestoreSecurityHostdevLabel,
+ .domainSetSecurityHostdevLabel = AppArmorSetSecurityHostdevLabel,
+ .domainRestoreSecurityHostdevLabel = AppArmorRestoreSecurityHostdevLabel,
- AppArmorSetSavedStateLabel,
- AppArmorRestoreSavedStateLabel,
+ .domainSetSavedStateLabel = AppArmorSetSavedStateLabel,
+ .domainRestoreSavedStateLabel = AppArmorRestoreSavedStateLabel,
- AppArmorSetImageFDLabel,
+ .domainSetSecurityImageFDLabel = AppArmorSetImageFDLabel,
};
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 470861d..9182b39 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -723,42 +723,41 @@ static char *virSecurityDACGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE_U
}
virSecurityDriver virSecurityDriverDAC = {
- sizeof(virSecurityDACData),
- "virDAC",
+ .privateDataLen = sizeof(virSecurityDACData),
+ .name = "virDAC",
+ .probe = virSecurityDACProbe,
+ .open = virSecurityDACOpen,
+ .close = virSecurityDACClose,
- virSecurityDACProbe,
- virSecurityDACOpen,
- virSecurityDACClose,
+ .getModel = virSecurityDACGetModel,
+ .getDOI = virSecurityDACGetDOI,
- virSecurityDACGetModel,
- virSecurityDACGetDOI,
+ .domainSecurityVerify = virSecurityDACVerify,
- virSecurityDACVerify,
+ .domainSetSecurityImageLabel = virSecurityDACSetSecurityImageLabel,
+ .domainRestoreSecurityImageLabel = virSecurityDACRestoreSecurityImageLabel,
- virSecurityDACSetSecurityImageLabel,
- virSecurityDACRestoreSecurityImageLabel,
+ .domainSetSecurityDaemonSocketLabel = virSecurityDACSetDaemonSocketLabel,
+ .domainSetSecuritySocketLabel = virSecurityDACSetSocketLabel,
+ .domainClearSecuritySocketLabel = virSecurityDACClearSocketLabel,
- virSecurityDACSetDaemonSocketLabel,
- virSecurityDACSetSocketLabel,
- virSecurityDACClearSocketLabel,
+ .domainGenSecurityLabel = virSecurityDACGenLabel,
+ .domainReserveSecurityLabel = virSecurityDACReserveLabel,
+ .domainReleaseSecurityLabel = virSecurityDACReleaseLabel,
- virSecurityDACGenLabel,
- virSecurityDACReserveLabel,
- virSecurityDACReleaseLabel,
+ .domainGetSecurityProcessLabel = virSecurityDACGetProcessLabel,
+ .domainSetSecurityProcessLabel = virSecurityDACSetProcessLabel,
- virSecurityDACGetProcessLabel,
- virSecurityDACSetProcessLabel,
+ .domainSetSecurityAllLabel = virSecurityDACSetSecurityAllLabel,
+ .domainRestoreSecurityAllLabel = virSecurityDACRestoreSecurityAllLabel,
- virSecurityDACSetSecurityAllLabel,
- virSecurityDACRestoreSecurityAllLabel,
+ .domainSetSecurityHostdevLabel = virSecurityDACSetSecurityHostdevLabel,
+ .domainRestoreSecurityHostdevLabel = virSecurityDACRestoreSecurityHostdevLabel,
- virSecurityDACSetSecurityHostdevLabel,
- virSecurityDACRestoreSecurityHostdevLabel,
+ .domainSetSavedStateLabel = virSecurityDACSetSavedStateLabel,
+ .domainRestoreSavedStateLabel = virSecurityDACRestoreSavedStateLabel,
- virSecurityDACSetSavedStateLabel,
- virSecurityDACRestoreSavedStateLabel,
+ .domainSetSecurityImageFDLabel = virSecurityDACSetImageFDLabel,
- virSecurityDACSetImageFDLabel,
-
- virSecurityDACGetMountOptions,
+ .domainGetSecurityMountOptions = virSecurityDACGetMountOptions,
};
diff --git a/src/security/security_nop.c b/src/security/security_nop.c
index b62daf5..5f90df3 100644
--- a/src/security/security_nop.c
+++ b/src/security/security_nop.c
@@ -170,41 +170,41 @@ static char *virSecurityDomainGetMountOptionsNop(virSecurityManagerPtr mgr ATTRI
}
virSecurityDriver virSecurityDriverNop = {
- 0,
- "none",
- virSecurityDriverProbeNop,
- virSecurityDriverOpenNop,
- virSecurityDriverCloseNop,
+ .privateDataLen = 0,
+ .name = "none",
+ .probe = virSecurityDriverProbeNop,
+ .open = virSecurityDriverOpenNop,
+ .close = virSecurityDriverCloseNop,
- virSecurityDriverGetModelNop,
- virSecurityDriverGetDOINop,
+ .getModel = virSecurityDriverGetModelNop,
+ .getDOI = virSecurityDriverGetDOINop,
- virSecurityDomainVerifyNop,
+ .domainSecurityVerify = virSecurityDomainVerifyNop,
- virSecurityDomainSetImageLabelNop,
- virSecurityDomainRestoreImageLabelNop,
+ .domainSetSecurityImageLabel = virSecurityDomainSetImageLabelNop,
+ .domainRestoreSecurityImageLabel = virSecurityDomainRestoreImageLabelNop,
- virSecurityDomainSetDaemonSocketLabelNop,
- virSecurityDomainSetSocketLabelNop,
- virSecurityDomainClearSocketLabelNop,
+ .domainSetSecurityDaemonSocketLabel = virSecurityDomainSetDaemonSocketLabelNop,
+ .domainSetSecuritySocketLabel = virSecurityDomainSetSocketLabelNop,
+ .domainClearSecuritySocketLabel = virSecurityDomainClearSocketLabelNop,
- virSecurityDomainGenLabelNop,
- virSecurityDomainReserveLabelNop,
- virSecurityDomainReleaseLabelNop,
+ .domainGenSecurityLabel = virSecurityDomainGenLabelNop,
+ .domainReserveSecurityLabel = virSecurityDomainReserveLabelNop,
+ .domainReleaseSecurityLabel = virSecurityDomainReleaseLabelNop,
- virSecurityDomainGetProcessLabelNop,
- virSecurityDomainSetProcessLabelNop,
+ .domainGetSecurityProcessLabel = virSecurityDomainGetProcessLabelNop,
+ .domainSetSecurityProcessLabel = virSecurityDomainSetProcessLabelNop,
- virSecurityDomainSetAllLabelNop,
- virSecurityDomainRestoreAllLabelNop,
+ .domainSetSecurityAllLabel = virSecurityDomainSetAllLabelNop,
+ .domainRestoreSecurityAllLabel = virSecurityDomainRestoreAllLabelNop,
- virSecurityDomainSetHostdevLabelNop,
- virSecurityDomainRestoreHostdevLabelNop,
+ .domainSetSecurityHostdevLabel = virSecurityDomainSetHostdevLabelNop,
+ .domainRestoreSecurityHostdevLabel = virSecurityDomainRestoreHostdevLabelNop,
- virSecurityDomainSetSavedStateLabelNop,
- virSecurityDomainRestoreSavedStateLabelNop,
+ .domainSetSavedStateLabel = virSecurityDomainSetSavedStateLabelNop,
+ .domainRestoreSavedStateLabel = virSecurityDomainRestoreSavedStateLabelNop,
- virSecurityDomainSetFDLabelNop,
+ .domainSetSecurityImageFDLabel = virSecurityDomainSetFDLabelNop,
- virSecurityDomainGetMountOptionsNop,
+ .domainGetSecurityMountOptions = virSecurityDomainGetMountOptionsNop,
};
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 2b8ff19..ffa65fb 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1591,41 +1591,41 @@ static char *SELinuxGetSecurityMountOptions(virSecurityManagerPtr mgr,
}
virSecurityDriver virSecurityDriverSELinux = {
- sizeof(virSecuritySELinuxData),
- SECURITY_SELINUX_NAME,
- SELinuxSecurityDriverProbe,
- SELinuxSecurityDriverOpen,
- SELinuxSecurityDriverClose,
+ .privateDataLen = sizeof(virSecuritySELinuxData),
+ .name = SECURITY_SELINUX_NAME,
+ .probe = SELinuxSecurityDriverProbe,
+ .open = SELinuxSecurityDriverOpen,
+ .close = SELinuxSecurityDriverClose,
- SELinuxSecurityGetModel,
- SELinuxSecurityGetDOI,
+ .getModel = SELinuxSecurityGetModel,
+ .getDOI = SELinuxSecurityGetDOI,
- SELinuxSecurityVerify,
+ .domainSecurityVerify = SELinuxSecurityVerify,
- SELinuxSetSecurityImageLabel,
- SELinuxRestoreSecurityImageLabel,
+ .domainSetSecurityImageLabel = SELinuxSetSecurityImageLabel,
+ .domainRestoreSecurityImageLabel = SELinuxRestoreSecurityImageLabel,
- SELinuxSetSecurityDaemonSocketLabel,
- SELinuxSetSecuritySocketLabel,
- SELinuxClearSecuritySocketLabel,
+ .domainSetSecurityDaemonSocketLabel = SELinuxSetSecurityDaemonSocketLabel,
+ .domainSetSecuritySocketLabel = SELinuxSetSecuritySocketLabel,
+ .domainClearSecuritySocketLabel = SELinuxClearSecuritySocketLabel,
- SELinuxGenSecurityLabel,
- SELinuxReserveSecurityLabel,
- SELinuxReleaseSecurityLabel,
+ .domainGenSecurityLabel = SELinuxGenSecurityLabel,
+ .domainReserveSecurityLabel = SELinuxReserveSecurityLabel,
+ .domainReleaseSecurityLabel = SELinuxReleaseSecurityLabel,
- SELinuxGetSecurityProcessLabel,
- SELinuxSetSecurityProcessLabel,
+ .domainGetSecurityProcessLabel = SELinuxGetSecurityProcessLabel,
+ .domainSetSecurityProcessLabel = SELinuxSetSecurityProcessLabel,
- SELinuxSetSecurityAllLabel,
- SELinuxRestoreSecurityAllLabel,
+ .domainSetSecurityAllLabel = SELinuxSetSecurityAllLabel,
+ .domainRestoreSecurityAllLabel = SELinuxRestoreSecurityAllLabel,
- SELinuxSetSecurityHostdevLabel,
- SELinuxRestoreSecurityHostdevLabel,
+ .domainSetSecurityHostdevLabel = SELinuxSetSecurityHostdevLabel,
+ .domainRestoreSecurityHostdevLabel = SELinuxRestoreSecurityHostdevLabel,
- SELinuxSetSavedStateLabel,
- SELinuxRestoreSavedStateLabel,
+ .domainSetSavedStateLabel = SELinuxSetSavedStateLabel,
+ .domainRestoreSavedStateLabel = SELinuxRestoreSavedStateLabel,
- SELinuxSetImageFDLabel,
+ .domainSetSecurityImageFDLabel = SELinuxSetImageFDLabel,
- SELinuxGetSecurityMountOptions,
+ .domainGetSecurityMountOptions = SELinuxGetSecurityMountOptions,
};
diff --git a/src/security/security_stack.c b/src/security/security_stack.c
index 6ecd099..65d30d6 100644
--- a/src/security/security_stack.c
+++ b/src/security/security_stack.c
@@ -409,41 +409,41 @@ static char *virSecurityStackGetMountOptions(virSecurityManagerPtr mgr ATTRIBUTE
}
virSecurityDriver virSecurityDriverStack = {
- sizeof(virSecurityStackData),
- "stack",
- virSecurityStackProbe,
- virSecurityStackOpen,
- virSecurityStackClose,
+ .privateDataLen = sizeof(virSecurityStackData),
+ .name = "stack",
+ .probe = virSecurityStackProbe,
+ .open = virSecurityStackOpen,
+ .close = virSecurityStackClose,
- virSecurityStackGetModel,
- virSecurityStackGetDOI,
+ .getModel = virSecurityStackGetModel,
+ .getDOI = virSecurityStackGetDOI,
- virSecurityStackVerify,
+ .domainSecurityVerify = virSecurityStackVerify,
- virSecurityStackSetSecurityImageLabel,
- virSecurityStackRestoreSecurityImageLabel,
+ .domainSetSecurityImageLabel = virSecurityStackSetSecurityImageLabel,
+ .domainRestoreSecurityImageLabel = virSecurityStackRestoreSecurityImageLabel,
- virSecurityStackSetDaemonSocketLabel,
- virSecurityStackSetSocketLabel,
- virSecurityStackClearSocketLabel,
+ .domainSetSecurityDaemonSocketLabel = virSecurityStackSetDaemonSocketLabel,
+ .domainSetSecuritySocketLabel = virSecurityStackSetSocketLabel,
+ .domainClearSecuritySocketLabel = virSecurityStackClearSocketLabel,
- virSecurityStackGenLabel,
- virSecurityStackReserveLabel,
- virSecurityStackReleaseLabel,
+ .domainGenSecurityLabel = virSecurityStackGenLabel,
+ .domainReserveSecurityLabel = virSecurityStackReserveLabel,
+ .domainReleaseSecurityLabel = virSecurityStackReleaseLabel,
- virSecurityStackGetProcessLabel,
- virSecurityStackSetProcessLabel,
+ .domainGetSecurityProcessLabel = virSecurityStackGetProcessLabel,
+ .domainSetSecurityProcessLabel = virSecurityStackSetProcessLabel,
- virSecurityStackSetSecurityAllLabel,
- virSecurityStackRestoreSecurityAllLabel,
+ .domainSetSecurityAllLabel = virSecurityStackSetSecurityAllLabel,
+ .domainRestoreSecurityAllLabel = virSecurityStackRestoreSecurityAllLabel,
- virSecurityStackSetSecurityHostdevLabel,
- virSecurityStackRestoreSecurityHostdevLabel,
+ .domainSetSecurityHostdevLabel = virSecurityStackSetSecurityHostdevLabel,
+ .domainRestoreSecurityHostdevLabel = virSecurityStackRestoreSecurityHostdevLabel,
- virSecurityStackSetSavedStateLabel,
- virSecurityStackRestoreSavedStateLabel,
+ .domainSetSavedStateLabel = virSecurityStackSetSavedStateLabel,
+ .domainRestoreSavedStateLabel = virSecurityStackRestoreSavedStateLabel,
- virSecurityStackSetImageFDLabel,
+ .domainSetSecurityImageFDLabel = virSecurityStackSetImageFDLabel,
- virSecurityStackGetMountOptions,
+ .domainGetSecurityMountOptions = virSecurityStackGetMountOptions,
};
--
1.7.8.5
12 years, 6 months
[libvirt] [PATCH 0/5] Atomic api to list all domains
by Peter Krempa
This patchset adds a atomic way to list guests. A more detailed description is in patch 1.
Peter Krempa (5):
lib: Add public api to enable atomic listing of guest
python: add API exports for virConnectListAllDomains()
remote: implement remote protocol for virConnectListAllDomains()
qemu: implement virConnectListAllDomains() for qemu driver
virsh: add support for virConnectListAllDomains and clean up cmdList
daemon/remote.c | 50 ++++
include/libvirt/libvirt.h.in | 8 +-
python/generator.py | 1 +
python/libvirt-override-api.xml | 12 +-
python/libvirt-override-virConnect.py | 12 +
python/libvirt-override.c | 49 ++++-
src/driver.h | 12 +-
src/libvirt.c | 46 ++++
src/libvirt_public.syms | 5 +
src/qemu/qemu_driver.c | 97 ++++++++
src/remote/remote_driver.c | 66 +++++
src/remote/remote_protocol.x | 14 +-
src/remote_protocol-structs | 12 +
tools/virsh.c | 423 +++++++++++++++++++++------------
14 files changed, 647 insertions(+), 160 deletions(-)
--
1.7.3.4
12 years, 6 months
[libvirt] [PATCH] fix building error on non fedora system
by Wen Congyang
We forget to define with_storage_rbd if the system is not fedora,
or the version is less than 16.
---
libvirt.spec.in | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 8c4a2fd..0b83969 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -75,6 +75,8 @@
%define with_storage_mpath 0%{!?_without_storage_mpath:%{server_drivers}}
%if 0%{?fedora} >= 16
%define with_storage_rbd 0%{!?_without_storage_rbd:%{server_drivers}}
+%else
+%define with_storage_rbd 0
%endif
%define with_numactl 0%{!?_without_numactl:%{server_drivers}}
%define with_selinux 0%{!?_without_selinux:%{server_drivers}}
--
1.7.1
12 years, 6 months
[libvirt] [PATCH] Add stub impl of virNetlinkEventServiceLocalPid for Win32
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
Pushed the following under build-breaker fix rule (Win32)
The libvirt_private.syms file exports virNetlinkEventServiceLocalPid
so there needs to be a no-op stub for Win32 to avoid linker errors
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/util/virnetlink.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/src/util/virnetlink.c b/src/util/virnetlink.c
index e316137..9539694 100644
--- a/src/util/virnetlink.c
+++ b/src/util/virnetlink.c
@@ -669,6 +669,12 @@ bool virNetlinkEventServiceIsRunning(void)
return 0;
}
+int virNetlinkEventServiceLocalPid(void)
+{
+ netlinkError(VIR_ERR_INTERNAL_ERROR, "%s", _(unsupported));
+ return -1;
+}
+
/**
* virNetlinkEventAddClient: register a callback for handling of
* netlink messages
--
1.7.7.6
12 years, 6 months
[libvirt] [PATCHv3 4/4] openvz: add quota argument when creating container
by Guido Günther
---
src/openvz/openvz_driver.c | 58 +++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c
index c6d25d7..fb72cde 100644
--- a/src/openvz/openvz_driver.c
+++ b/src/openvz/openvz_driver.c
@@ -189,6 +189,48 @@ cleanup:
}
+static int
+openvzSetDiskQuota(virDomainDefPtr vmdef,
+ virDomainFSDefPtr fss)
+{
+ int ret = -1;
+ unsigned long long sl, hl;
+ virCommandPtr cmd = virCommandNewArgList(VZCTL,
+ "--quiet",
+ "set",
+ vmdef->name,
+ "--save",
+ NULL);
+
+ if (fss->type == VIR_DOMAIN_FS_TYPE_TEMPLATE) {
+ if (fss->space_hard_limit) {
+ hl = VIR_DIV_UP(fss->space_hard_limit, 1024);
+ virCommandAddArg(cmd, "--diskspace");
+
+ if (fss->space_soft_limit) {
+ sl = VIR_DIV_UP(fss->space_soft_limit, 1024);
+ virCommandAddArgFormat(cmd, "%lld:%lld", sl, hl);
+ } else {
+ virCommandAddArgFormat(cmd, "%lld", hl);
+ }
+ } else if (fss->space_soft_limit) {
+ openvzError(VIR_ERR_INVALID_ARG, "%s",
+ _("Can't set soft limit without hard limit"));
+ goto cleanup;
+ }
+
+ if (virCommandRun(cmd, NULL) < 0)
+ goto cleanup;
+ }
+
+ ret = 0;
+cleanup:
+ virCommandFree(cmd);
+
+ return ret;
+}
+
+
static virDomainPtr openvzDomainLookupByID(virConnectPtr conn,
int id) {
struct openvz_driver *driver = conn->privateData;
@@ -895,7 +937,13 @@ openvzDomainDefineXML(virConnectPtr conn, const char *xml)
goto cleanup;
}
- /* TODO: set quota */
+ if (vm->def->nfss == 1) {
+ if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not set disk quota"));
+ goto cleanup;
+ }
+ }
if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -977,6 +1025,14 @@ openvzDomainCreateXML(virConnectPtr conn, const char *xml,
goto cleanup;
}
+ if (vm->def->nfss == 1) {
+ if (openvzSetDiskQuota(vm->def, vm->def->fss[0]) < 0) {
+ openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Could not set disk quota"));
+ goto cleanup;
+ }
+ }
+
if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not set UUID"));
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv3 2/4] Introduce filesystem limits to virDomainFSDef
by Guido Günther
---
docs/formatdomain.html.in | 14 ++++++++++++++
docs/schemas/domaincommon.rng | 12 ++++++++++++
src/conf/domain_conf.c | 30 +++++++++++++++++++++++++++---
src/conf/domain_conf.h | 2 ++
4 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3875167..c56a793 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1686,6 +1686,20 @@
default read-write access is given (currently only works for
QEMU/KVM driver).
</dd>
+
+ <dt><code>space_hard_limit</code></dt>
+ <dd>
+ Maximum space available to this guest's filesystem.
+ <span class="since">Since 0.9.13</span>
+ </dd>
+
+ <dt><code>space_soft_limit</code></dt>
+ <dd>
+ Maximum space available to this guest's filesystem. The container is
+ permitted to exceed its soft limits for a grace period of time. Afterwards the
+ hard limit is enforced.
+ <span class="since">Since 0.9.13</span>
+ </dd>
</dl>
<h4><a name="elementsAddress">Device Addresses</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 34f63c3..62c28c8 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1316,6 +1316,18 @@
<ref name="address"/>
</optional>
</interleave>
+ <interleave>
+ <optional>
+ <element name="space_hard_limit">
+ <ref name='scaledInteger'/>
+ </element>
+ </optional>
+ <optional>
+ <element name="space_soft_limit">
+ <ref name='scaledInteger'/>
+ </element>
+ </optional>
+ </interleave>
</element>
</define>
<!--
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5ac911e..a75e7e8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4200,9 +4200,10 @@ cleanup:
*/
static virDomainFSDefPtr
virDomainFSDefParseXML(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
unsigned int flags) {
virDomainFSDefPtr def;
- xmlNodePtr cur;
+ xmlNodePtr cur, save_node = ctxt->node;
char *type = NULL;
char *fsdriver = NULL;
char *source = NULL;
@@ -4210,6 +4211,8 @@ virDomainFSDefParseXML(xmlNodePtr node,
char *accessmode = NULL;
char *wrpolicy = NULL;
+ ctxt->node = node;
+
if (VIR_ALLOC(def) < 0) {
virReportOOMError();
return NULL;
@@ -4237,6 +4240,18 @@ virDomainFSDefParseXML(xmlNodePtr node,
def->accessmode = VIR_DOMAIN_FS_ACCESSMODE_PASSTHROUGH;
}
+ if (virDomainParseScaledValue("./space_hard_limit[1]", ctxt,
+ &def->space_hard_limit, 1,
+ ULONG_LONG_MAX,
+ false) < 0)
+ goto error;
+
+ if (virDomainParseScaledValue("./space_soft_limit[1]", ctxt,
+ &def->space_soft_limit, 1,
+ ULONG_LONG_MAX,
+ false) < 0)
+ goto error;
+
cur = node->children;
while (cur != NULL) {
if (cur->type == XML_ELEMENT_NODE) {
@@ -4303,6 +4318,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
goto error;
cleanup:
+ ctxt->node = save_node;
VIR_FREE(type);
VIR_FREE(fsdriver);
VIR_FREE(target);
@@ -7076,7 +7092,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "filesystem")) {
dev->type = VIR_DOMAIN_DEVICE_FS;
- if (!(dev->data.fs = virDomainFSDefParseXML(node, flags)))
+ if (!(dev->data.fs = virDomainFSDefParseXML(node, ctxt, flags)))
goto error;
} else if (xmlStrEqual(node->name, BAD_CAST "interface")) {
dev->type = VIR_DOMAIN_DEVICE_NET;
@@ -8621,7 +8637,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
if (n && VIR_ALLOC_N(def->fss, n) < 0)
goto no_memory;
for (i = 0 ; i < n ; i++) {
- virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i],
+ virDomainFSDefPtr fs = virDomainFSDefParseXML(nodes[i], ctxt,
flags);
if (!fs)
goto error;
@@ -11319,6 +11335,14 @@ virDomainFSDefFormat(virBufferPtr buf,
if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
return -1;
+
+ if (def->space_hard_limit)
+ virBufferAsprintf(buf, " <space_hard_limit unit='B'>"
+ "%llu</space_hard_limit>\n", def->space_hard_limit);
+ if (def->space_soft_limit) {
+ virBufferAsprintf(buf, " <space_soft_limit unit='B'>"
+ "%llu</space_soft_limit>\n", def->space_soft_limit);
+ }
virBufferAddLit(buf, " </filesystem>\n");
return 0;
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 4c56902..8d5b35a 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -699,6 +699,8 @@ struct _virDomainFSDef {
char *dst;
unsigned int readonly : 1;
virDomainDeviceInfo info;
+ unsigned long long space_hard_limit; /* in bytes */
+ unsigned long long space_soft_limit; /* in bytes */
};
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv3 3/4] openvz: support file system quota reporting
by Guido Günther
---
src/conf/domain_conf.c | 4 ++--
src/openvz/openvz_conf.c | 24 +++++++++++++++++++++++
tests/domainschemadata/domain-openvz-simple.xml | 2 ++
3 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a75e7e8..357929b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11337,10 +11337,10 @@ virDomainFSDefFormat(virBufferPtr buf,
if (def->space_hard_limit)
- virBufferAsprintf(buf, " <space_hard_limit unit='B'>"
+ virBufferAsprintf(buf, " <space_hard_limit unit='bytes'>"
"%llu</space_hard_limit>\n", def->space_hard_limit);
if (def->space_soft_limit) {
- virBufferAsprintf(buf, " <space_soft_limit unit='B'>"
+ virBufferAsprintf(buf, " <space_soft_limit unit='bytes'>"
"%llu</space_soft_limit>\n", def->space_soft_limit);
}
virBufferAddLit(buf, " </filesystem>\n");
diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c
index 5f107ed..363cd1e 100644
--- a/src/openvz/openvz_conf.c
+++ b/src/openvz/openvz_conf.c
@@ -407,6 +407,8 @@ openvzReadFSConf(virDomainDefPtr def,
virDomainFSDefPtr fs = NULL;
char *veid_str = NULL;
char *temp = NULL;
+ const char *param;
+ unsigned long long barrier, limit;
ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp);
if (ret < 0) {
@@ -444,6 +446,28 @@ openvzReadFSConf(virDomainDefPtr def,
fs->dst = strdup("/");
+ param = "DISKSPACE";
+ ret = openvzReadVPSConfigParam(veid, param, &temp);
+ if (ret > 0) {
+ if (openvzParseBarrierLimit(temp, &barrier, &limit)) {
+ openvzError(VIR_ERR_INTERNAL_ERROR,
+ _("Could not read '%s' from config for container %d"),
+ param, veid);
+ goto error;
+ } else {
+ /* Ensure that we can multiply by 1024 without overflowing. */
+ if (barrier > ULONG_LONG_MAX / 1024 ||
+ limit > ULONG_LONG_MAX / 1024 ) {
+ virReportSystemError(EINVAL,
+ _("%s"),
+ "Unable to parse quota");
+ goto error;
+ }
+ fs->space_soft_limit = barrier * 1024; /* unit is bytes */
+ fs->space_hard_limit = limit * 1024; /* unit is bytes */
+ }
+ }
+
if (fs->src == NULL || fs->dst == NULL)
goto no_memory;
diff --git a/tests/domainschemadata/domain-openvz-simple.xml b/tests/domainschemadata/domain-openvz-simple.xml
index a121d39..949e96d 100644
--- a/tests/domainschemadata/domain-openvz-simple.xml
+++ b/tests/domainschemadata/domain-openvz-simple.xml
@@ -21,6 +21,8 @@
<filesystem type='template' accessmode='passthrough'>
<source name='debian'/>
<target dir='/'/>
+ <space_hard_limit>1153024</space_hard_limit>
+ <space_soft_limit>1048576</space_soft_limit>
</filesystem>
</devices>
</domain>
--
1.7.10
12 years, 6 months
[libvirt] [PATCHv3 1/4] Introduce virDomainParseScaledValue
by Guido Günther
and use it for virDomainParseMemory. This allows to parse arbitrary
scaled value, not only memory related values as needed for the
filesystem limits code following later in this series.
---
src/conf/domain_conf.c | 94 +++++++++++++++++++++++++++++++-----------------
1 file changed, 61 insertions(+), 33 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 9def71d..5ac911e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4138,6 +4138,63 @@ cleanup:
goto cleanup;
}
+
+/* Parse a value located at XPATH within CTXT, and store the
+ * result into val. If REQUIRED, then the value must exist;
+ * otherwise, the value is optional. The value is in bytes.
+ * Return 0 on success, -1 on failure after issuing error. */
+static int
+virDomainParseScaledValue(const char *xpath,
+ xmlXPathContextPtr ctxt,
+ unsigned long long *val,
+ unsigned long long scale,
+ unsigned long long max,
+ bool required)
+{
+ char *xpath_full = NULL;
+ char *unit = NULL;
+ int ret = -1;
+ unsigned long long bytes;
+
+ *val = 0;
+ if (virAsprintf(&xpath_full, "string(%s)", xpath) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ ret = virXPathULongLong(xpath_full, ctxt, &bytes);
+ if (ret < 0) {
+ if (ret == -2)
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("could not parse memory element %s"),
+ xpath);
+ else if (required)
+ virDomainReportError(VIR_ERR_XML_ERROR,
+ _("missing element %s"),
+ xpath);
+ else
+ ret = 0;
+ goto cleanup;
+ }
+ VIR_FREE(xpath_full);
+
+ if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
+ unit = virXPathString(xpath_full, ctxt);
+
+ if (virScaleInteger(&bytes, unit, scale, max) < 0)
+ goto cleanup;
+
+ *val = bytes;
+ ret = 0;
+cleanup:
+ VIR_FREE(xpath_full);
+ VIR_FREE(unit);
+ return ret;
+}
+
+
/* Parse the XML definition for a disk
* @param node XML nodeset to parse for disk definition
*/
@@ -7768,53 +7825,24 @@ static int
virDomainParseMemory(const char *xpath, xmlXPathContextPtr ctxt,
unsigned long long *mem, bool required)
{
- char *xpath_full = NULL;
- char *unit = NULL;
int ret = -1;
- unsigned long long bytes;
- unsigned long long max;
+ unsigned long long bytes, max;
- *mem = 0;
- if (virAsprintf(&xpath_full, "string(%s)", xpath) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- ret = virXPathULongLong(xpath_full, ctxt, &bytes);
- if (ret < 0) {
- if (ret == -2)
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("could not parse memory element %s"),
- xpath);
- else if (required)
- virDomainReportError(VIR_ERR_XML_ERROR,
- _("missing memory element %s"),
- xpath);
- else
- ret = 0;
- goto cleanup;
- }
- VIR_FREE(xpath_full);
-
- if (virAsprintf(&xpath_full, "string(%s/@unit)", xpath) < 0) {
- virReportOOMError();
- goto cleanup;
- }
- unit = virXPathString(xpath_full, ctxt);
/* On 32-bit machines, our bound is 0xffffffff * KiB. On 64-bit
* machines, our bound is off_t (2^63). */
if (sizeof(unsigned long) < sizeof(long long))
max = 1024ull * ULONG_MAX;
else
max = LLONG_MAX;
- if (virScaleInteger(&bytes, unit, 1024, max) < 0)
+
+ ret = virDomainParseScaledValue(xpath, ctxt, &bytes, 1024, max, required);
+ if (ret < 0)
goto cleanup;
/* Yes, we really do use kibibytes for our internal sizing. */
*mem = VIR_DIV_UP(bytes, 1024);
ret = 0;
cleanup:
- VIR_FREE(xpath_full);
- VIR_FREE(unit);
return ret;
}
--
1.7.10
12 years, 6 months