aboutsummaryrefslogtreecommitdiffstats
path: root/tools/libxc/xc_private.c
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2010-05-28 09:30:19 +0100
committerKeir Fraser <keir.fraser@citrix.com>2010-05-28 09:30:19 +0100
commit5cc436c1d2b3b0be3f42104582f53eec3969b43a (patch)
tree1e30ade146ee7287c486d1309b5d3d2c69a2d9b9 /tools/libxc/xc_private.c
parent7f9a888af4b65cb8c22cea3c8295d30d0fedd623 (diff)
downloadxen-5cc436c1d2b3b0be3f42104582f53eec3969b43a.tar.gz
xen-5cc436c1d2b3b0be3f42104582f53eec3969b43a.tar.bz2
xen-5cc436c1d2b3b0be3f42104582f53eec3969b43a.zip
libxc: eliminate static variables, use xentoollog; API change
This patch eliminate the global variables in libxenctrl (used for logging and error reporting). Instead the information which was in the global variables is now in a new xc_interface* opaque structure, which xc_interface open returns instead of the raw file descriptor; furthermore, logging is done via xentoollog. There are three new parameters to xc_interface_open to control the logging, but existing callers can just pass "0" for all three to get the old behaviour. All libxc callers have been adjusted accordingly. Also update QEMU_TAG for corresponding qemu change. Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Diffstat (limited to 'tools/libxc/xc_private.c')
-rw-r--r--tools/libxc/xc_private.c241
1 files changed, 142 insertions, 99 deletions
diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c
index aaa1a39d87..9bcf1754e5 100644
--- a/tools/libxc/xc_private.c
+++ b/tools/libxc/xc_private.c
@@ -7,70 +7,83 @@
#include <inttypes.h>
#include "xc_private.h"
#include "xg_private.h"
+#include "xc_dom.h"
#include <stdarg.h>
#include <stdlib.h>
#include <malloc.h>
#include <unistd.h>
#include <pthread.h>
+#include <assert.h>
+
+xc_interface *xc_interface_open(xentoollog_logger *logger,
+ xentoollog_logger *dombuild_logger,
+ unsigned open_flags) {
+ xc_interface xch_buf, *xch = &xch_buf;
+
+ xch->fd = -1;
+ xch->dombuild_logger_file = 0;
+ xc_clear_last_error(xch);
+
+ xch->error_handler = logger; xch->error_handler_tofree = 0;
+ xch->dombuild_logger = dombuild_logger; xch->dombuild_logger_tofree = 0;
+
+ if (!xch->error_handler) {
+ xch->error_handler = xch->error_handler_tofree =
+ (xentoollog_logger*)
+ xtl_createlogger_stdiostream(stderr, XTL_PROGRESS, 0);
+ if (!xch->error_handler)
+ goto err;
+ }
-static pthread_key_t last_error_pkey;
-static pthread_once_t last_error_pkey_once = PTHREAD_ONCE_INIT;
-
-static pthread_key_t errbuf_pkey;
-static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT;
-
-#if DEBUG
-static xc_error_handler error_handler = xc_default_error_handler;
-#else
-static xc_error_handler error_handler = NULL;
-#endif
+ xch = malloc(sizeof(*xch));
+ if (!xch) {
+ xch = &xch_buf;
+ PERROR("Could not allocate new xc_interface struct");
+ goto err;
+ }
+ *xch = xch_buf;
-void xc_default_error_handler(const xc_error *err)
-{
- const char *desc = xc_error_code_to_desc(err->code);
- fprintf(stderr, "ERROR %s: %s\n", desc, err->message);
-}
+ if (!(open_flags & XC_OPENFLAG_DUMMY)) {
+ xch->fd = xc_interface_open_core(xch);
+ if (xch->fd < 0)
+ goto err;
+ }
-static void
-_xc_clean_last_error(void *m)
-{
- free(m);
- pthread_setspecific(last_error_pkey, NULL);
-}
+ return xch;
-static void
-_xc_init_last_error(void)
-{
- pthread_key_create(&last_error_pkey, _xc_clean_last_error);
+ err:
+ if (xch) xtl_logger_destroy(xch->error_handler);
+ if (xch != &xch_buf) free(xch);
+ return 0;
}
-static xc_error *
-_xc_get_last_error(void)
+int xc_interface_close(xc_interface *xch)
{
- xc_error *last_error;
+ int rc = 0;
- pthread_once(&last_error_pkey_once, _xc_init_last_error);
+ xtl_logger_destroy(xch->dombuild_logger_tofree);
+ xtl_logger_destroy(xch->error_handler_tofree);
- last_error = pthread_getspecific(last_error_pkey);
- if (last_error == NULL) {
- last_error = malloc(sizeof(xc_error));
- pthread_setspecific(last_error_pkey, last_error);
- xc_clear_last_error();
+ if (xch->fd >= 0) {
+ rc = xc_interface_close_core(xch, xch->fd);
+ if (rc) PERROR("Could not close hypervisor interface");
}
-
- return last_error;
+ free(xch);
+ return rc;
}
-const xc_error *xc_get_last_error(void)
+static pthread_key_t errbuf_pkey;
+static pthread_once_t errbuf_pkey_once = PTHREAD_ONCE_INIT;
+
+const xc_error *xc_get_last_error(xc_interface *xch)
{
- return _xc_get_last_error();
+ return &xch->last_error;
}
-void xc_clear_last_error(void)
+void xc_clear_last_error(xc_interface *xch)
{
- xc_error *last_error = _xc_get_last_error();
- last_error->code = XC_ERROR_NONE;
- last_error->message[0] = '\0';
+ xch->last_error.code = XC_ERROR_NONE;
+ xch->last_error.message[0] = '\0';
}
const char *xc_error_code_to_desc(int code)
@@ -93,40 +106,70 @@ const char *xc_error_code_to_desc(int code)
return "Unknown error code";
}
-xc_error_handler xc_set_error_handler(xc_error_handler handler)
-{
- xc_error_handler old = error_handler;
- error_handler = handler;
- return old;
+void xc_reportv(xc_interface *xch, xentoollog_logger *lg,
+ xentoollog_level level, int code,
+ const char *fmt, va_list args) {
+ int saved_errno = errno;
+ char msgbuf[XC_MAX_ERROR_MSG_LEN];
+ char *msg;
+
+ /* Strip newlines from messages.
+ * XXX really the messages themselves should have the newlines removed.
+ */
+ char fmt_nonewline[512];
+ int fmt_l;
+
+ fmt_l = strlen(fmt);
+ if (fmt_l && fmt[fmt_l-1]=='\n' && fmt_l < sizeof(fmt_nonewline)) {
+ memcpy(fmt_nonewline, fmt, fmt_l-1);
+ fmt_nonewline[fmt_l-1] = 0;
+ fmt = fmt_nonewline;
+ }
+
+ if ( level >= XTL_ERROR ) {
+ msg = xch->last_error.message;
+ xch->last_error.code = code;
+ } else {
+ msg = msgbuf;
+ }
+ vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
+ msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+
+ xtl_log(lg, level, -1, "xc",
+ "%s" "%s%s", msg,
+ code?": ":"", code ? xc_error_code_to_desc(code) : "");
+
+ errno = saved_errno;
}
-static void _xc_set_error(int code, const char *msg)
-{
- xc_error *last_error = _xc_get_last_error();
- last_error->code = code;
- strncpy(last_error->message, msg, XC_MAX_ERROR_MSG_LEN - 1);
- last_error->message[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+void xc_report(xc_interface *xch, xentoollog_logger *lg,
+ xentoollog_level level, int code, const char *fmt, ...) {
+ va_list args;
+ va_start(args,fmt);
+ xc_reportv(xch,lg,level,code,fmt,args);
+ va_end(args);
}
-void xc_set_error(int code, const char *fmt, ...)
+void xc_report_error(xc_interface *xch, int code, const char *fmt, ...)
{
- int saved_errno = errno;
- char msg[XC_MAX_ERROR_MSG_LEN];
va_list args;
-
va_start(args, fmt);
- vsnprintf(msg, XC_MAX_ERROR_MSG_LEN-1, fmt, args);
- msg[XC_MAX_ERROR_MSG_LEN-1] = '\0';
+ xc_reportv(xch, xch->error_handler, XTL_ERROR, code, fmt, args);
va_end(args);
+}
- _xc_set_error(code, msg);
-
- errno = saved_errno;
+void xc_report_progress_start(xc_interface *xch, const char *doing,
+ unsigned long total) {
+ xch->currently_progress_reporting = doing;
+ xtl_progress(xch->error_handler, "xc", xch->currently_progress_reporting,
+ 0, total);
+}
- if ( error_handler != NULL ) {
- xc_error *last_error = _xc_get_last_error();
- error_handler(last_error);
- }
+void xc_report_progress_step(xc_interface *xch,
+ unsigned long done, unsigned long total) {
+ assert(xch->currently_progress_reporting);
+ xtl_progress(xch->error_handler, "xc", xch->currently_progress_reporting,
+ done, total);
}
#ifdef __sun__
@@ -244,7 +287,7 @@ void hcall_buf_release(void **addr, size_t len)
#endif
/* NB: arr must be locked */
-int xc_get_pfn_type_batch(int xc_handle, uint32_t dom,
+int xc_get_pfn_type_batch(xc_interface *xch, uint32_t dom,
unsigned int num, xen_pfn_t *arr)
{
DECLARE_DOMCTL;
@@ -252,11 +295,11 @@ int xc_get_pfn_type_batch(int xc_handle, uint32_t dom,
domctl.domain = (domid_t)dom;
domctl.u.getpageframeinfo3.num = num;
set_xen_guest_handle(domctl.u.getpageframeinfo3.array, arr);
- return do_domctl(xc_handle, &domctl);
+ return do_domctl(xch, &domctl);
}
int xc_mmuext_op(
- int xc_handle,
+ xc_interface *xch,
struct mmuext_op *op,
unsigned int nr_ops,
domid_t dom)
@@ -276,7 +319,7 @@ int xc_mmuext_op(
hypercall.arg[2] = (unsigned long)0;
hypercall.arg[3] = (unsigned long)dom;
- ret = do_xen_hypercall(xc_handle, &hypercall);
+ ret = do_xen_hypercall(xch, &hypercall);
hcall_buf_release((void **)&op, nr_ops*sizeof(*op));
@@ -284,7 +327,7 @@ int xc_mmuext_op(
return ret;
}
-static int flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
+static int flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
{
int err = 0;
DECLARE_HYPERCALL;
@@ -305,7 +348,7 @@ static int flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
goto out;
}
- if ( do_xen_hypercall(xc_handle, &hypercall) < 0 )
+ if ( do_xen_hypercall(xch, &hypercall) < 0 )
{
ERROR("Failure when submitting mmu updates");
err = 1;
@@ -319,7 +362,7 @@ static int flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
return err;
}
-struct xc_mmu *xc_alloc_mmu_updates(int xc_handle, domid_t dom)
+struct xc_mmu *xc_alloc_mmu_updates(xc_interface *xch, domid_t dom)
{
struct xc_mmu *mmu = malloc(sizeof(*mmu));
if ( mmu == NULL )
@@ -329,24 +372,24 @@ struct xc_mmu *xc_alloc_mmu_updates(int xc_handle, domid_t dom)
return mmu;
}
-int xc_add_mmu_update(int xc_handle, struct xc_mmu *mmu,
+int xc_add_mmu_update(xc_interface *xch, struct xc_mmu *mmu,
unsigned long long ptr, unsigned long long val)
{
mmu->updates[mmu->idx].ptr = ptr;
mmu->updates[mmu->idx].val = val;
if ( ++mmu->idx == MAX_MMU_UPDATES )
- return flush_mmu_updates(xc_handle, mmu);
+ return flush_mmu_updates(xch, mmu);
return 0;
}
-int xc_flush_mmu_updates(int xc_handle, struct xc_mmu *mmu)
+int xc_flush_mmu_updates(xc_interface *xch, struct xc_mmu *mmu)
{
- return flush_mmu_updates(xc_handle, mmu);
+ return flush_mmu_updates(xch, mmu);
}
-int xc_memory_op(int xc_handle,
+int xc_memory_op(xc_interface *xch,
int cmd,
void *arg)
{
@@ -421,7 +464,7 @@ int xc_memory_op(int xc_handle,
break;
}
- ret = do_xen_hypercall(xc_handle, &hypercall);
+ ret = do_xen_hypercall(xch, &hypercall);
switch ( cmd )
{
@@ -459,14 +502,14 @@ int xc_memory_op(int xc_handle,
}
-long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
+long long xc_domain_get_cpu_usage( xc_interface *xch, domid_t domid, int vcpu )
{
DECLARE_DOMCTL;
domctl.cmd = XEN_DOMCTL_getvcpuinfo;
domctl.domain = (domid_t)domid;
domctl.u.getvcpuinfo.vcpu = (uint16_t)vcpu;
- if ( (do_domctl(xc_handle, &domctl) < 0) )
+ if ( (do_domctl(xch, &domctl) < 0) )
{
PERROR("Could not get info on domain");
return -1;
@@ -476,7 +519,7 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu )
#ifndef __ia64__
-int xc_get_pfn_list(int xc_handle,
+int xc_get_pfn_list(xc_interface *xch,
uint32_t domid,
uint64_t *pfn_buf,
unsigned long max_pfns)
@@ -498,7 +541,7 @@ int xc_get_pfn_list(int xc_handle,
return -1;
}
- ret = do_domctl(xc_handle, &domctl);
+ ret = do_domctl(xch, &domctl);
unlock_pages(pfn_buf, max_pfns * sizeof(*pfn_buf));
@@ -506,22 +549,22 @@ int xc_get_pfn_list(int xc_handle,
}
#endif
-long xc_get_tot_pages(int xc_handle, uint32_t domid)
+long xc_get_tot_pages(xc_interface *xch, uint32_t domid)
{
DECLARE_DOMCTL;
domctl.cmd = XEN_DOMCTL_getdomaininfo;
domctl.domain = (domid_t)domid;
- return (do_domctl(xc_handle, &domctl) < 0) ?
+ return (do_domctl(xch, &domctl) < 0) ?
-1 : domctl.u.getdomaininfo.tot_pages;
}
-int xc_copy_to_domain_page(int xc_handle,
+int xc_copy_to_domain_page(xc_interface *xch,
uint32_t domid,
unsigned long dst_pfn,
const char *src_page)
{
void *vaddr = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
+ xch, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
if ( vaddr == NULL )
return -1;
memcpy(vaddr, src_page, PAGE_SIZE);
@@ -529,12 +572,12 @@ int xc_copy_to_domain_page(int xc_handle,
return 0;
}
-int xc_clear_domain_page(int xc_handle,
+int xc_clear_domain_page(xc_interface *xch,
uint32_t domid,
unsigned long dst_pfn)
{
void *vaddr = xc_map_foreign_range(
- xc_handle, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
+ xch, domid, PAGE_SIZE, PROT_WRITE, dst_pfn);
if ( vaddr == NULL )
return -1;
memset(vaddr, 0, PAGE_SIZE);
@@ -542,17 +585,17 @@ int xc_clear_domain_page(int xc_handle,
return 0;
}
-int xc_domctl(int xc_handle, struct xen_domctl *domctl)
+int xc_domctl(xc_interface *xch, struct xen_domctl *domctl)
{
- return do_domctl(xc_handle, domctl);
+ return do_domctl(xch, domctl);
}
-int xc_sysctl(int xc_handle, struct xen_sysctl *sysctl)
+int xc_sysctl(xc_interface *xch, struct xen_sysctl *sysctl)
{
- return do_sysctl(xc_handle, sysctl);
+ return do_sysctl(xch, sysctl);
}
-int xc_version(int xc_handle, int cmd, void *arg)
+int xc_version(xc_interface *xch, int cmd, void *arg)
{
int rc, argsize = 0;
@@ -586,7 +629,7 @@ int xc_version(int xc_handle, int cmd, void *arg)
memset(arg, 0, argsize);
#endif
- rc = do_xen_version(xc_handle, cmd, arg);
+ rc = do_xen_version(xch, cmd, arg);
if ( argsize != 0 )
unlock_pages(arg, argsize);
@@ -595,20 +638,20 @@ int xc_version(int xc_handle, int cmd, void *arg)
}
unsigned long xc_make_page_below_4G(
- int xc_handle, uint32_t domid, unsigned long mfn)
+ xc_interface *xch, uint32_t domid, unsigned long mfn)
{
xen_pfn_t old_mfn = mfn;
xen_pfn_t new_mfn;
if ( xc_domain_memory_decrease_reservation(
- xc_handle, domid, 1, 0, &old_mfn) != 0 )
+ xch, domid, 1, 0, &old_mfn) != 0 )
{
DPRINTF("xc_make_page_below_4G decrease failed. mfn=%lx\n",mfn);
return 0;
}
if ( xc_domain_memory_increase_reservation(
- xc_handle, domid, 1, 0, XENMEMF_address_bits(32), &new_mfn) != 0 )
+ xch, domid, 1, 0, XENMEMF_address_bits(32), &new_mfn) != 0 )
{
DPRINTF("xc_make_page_below_4G increase failed. mfn=%lx\n",mfn);
return 0;