direct-io.hg

view tools/libxc/xc_ptrace.h @ 12765:2dd4569e0640

[LIBXC] Add an error reporting API to the libxc library.

- An 'xc_error' struct is used to pass around error
details. Currently contains two members 'code' an enumeration of
error types, and 'message' a free text description of the specific
problem.

- The xc_get_last_error() method returns a const pointer to the
internal instance of this struct manged by libxc. By returning a
const pointer we can add extra members to the end of the struct at
any time without worrying about ABI of callers. This will let us
provide more fine-grained info if needed in the future.

- The xc_error instance is statically defined inside libxc and marked
__thread. This ensures that errors are recorded per-thread, and
that when dealing with errors we never need to call malloc - all
storage needed is statically allocated.

- The xc_clear_last_error() method resets any currently recorded
error details

- The xc_error_code_to_desc() method converts the integer error code
into a generic user facing messsage. eg "Invalid kernel". Together
with the 'message' field from xc_error, this provides the user
visible feedback. eg "Invalid kernel: Non PAE-kernel on PAE host."

- A callback can be registered with xc_set_error_handler to receive
notification whenever an error is recorded, rather than querying
for error details after the fact with xc_get_last_error

- If built with -DDEBUG set, a default error handler will be
registered which calls fprintf(stderr), thus maintaining current
behaviour of logging errors to stderr during developer builds.

- The python binding for libxc is updated to use xc_get_last_error
to pull out error details whenever appropriate, instead of
returning info based on 'errno'

- The xc_set_error method is private to libxc internals, and is used
for setting error details

- The ERROR and PERROR macros have been updated to call xc_set_error
automatically specifying XC_INTERNAL_ERROR as the error code. This
gives a generic error report for all current failure points

- Some uses of the ERROR macro have been replaced with explicit
calls to xc_set_error to enable finer grained error reporting. In
particular the code dealing with invalid kernel types uses this
to report about PAE/architecture/wordsize mismatches

The patch has been tested by calling xm create against a varietry of
config files defining invalid kernels of various kinds. It has also
been tested with libvirt talking to xend. In both cases the error
messages were propagated all the way back up the stack.

There is only one place where I need to do further work. The suspend
& restore APIs in Xend invoke external helper programs rather than
calling libxc directly. This means that error details are essentially
lost. Since there is already code in XenD which scans STDERR from
these programs I will investigate adapting this to extract actual
error messages from these helpers.

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
author kfraser@localhost.localdomain
date Thu Dec 07 11:36:26 2006 +0000 (2006-12-07)
parents 5d2ce349f9f4
children
line source
1 #ifndef XC_PTRACE_
2 #define XC_PTRACE_
4 #define X86_CR0_PE 0x00000001 /* Enable Protected Mode (RW) */
5 #define X86_CR0_PG 0x80000000 /* Paging (RW) */
6 #define BSD_PAGE_MASK (PAGE_SIZE-1)
7 #define PSL_T 0x00000100 /* trace enable bit */
9 #ifdef __x86_64__
10 struct gdb_regs
11 {
12 unsigned long r15;
13 unsigned long r14;
14 unsigned long r13;
15 unsigned long r12;
16 unsigned long rbp;
17 unsigned long rbx;
18 unsigned long r11;
19 unsigned long r10;
20 unsigned long r9;
21 unsigned long r8;
22 unsigned long rax;
23 unsigned long rcx;
24 unsigned long rdx;
25 unsigned long rsi;
26 unsigned long rdi;
27 unsigned long orig_rax;
28 unsigned long rip;
29 unsigned long xcs;
30 unsigned long rflags;
31 unsigned long rsp;
32 unsigned long xss;
33 unsigned long fs_base;
34 unsigned long gs_base;
35 unsigned long xds;
36 unsigned long xes;
37 unsigned long xfs;
38 unsigned long xgs;
39 };
41 #define SET_PT_REGS(pt, xc) \
42 { \
43 pt.r8 = xc.r8; \
44 pt.r9 = xc.r9; \
45 pt.r10 = xc.r10; \
46 pt.r11 = xc.r11; \
47 pt.r12 = xc.r12; \
48 pt.r13 = xc.r13; \
49 pt.r14 = xc.r14; \
50 pt.r15 = xc.r15; \
51 pt.rbx = xc.rbx; \
52 pt.rcx = xc.rcx; \
53 pt.rdx = xc.rdx; \
54 pt.rsi = xc.rsi; \
55 pt.rdi = xc.rdi; \
56 pt.rbp = xc.rbp; \
57 pt.rax = xc.rax; \
58 pt.rip = xc.rip; \
59 pt.xcs = xc.cs; \
60 pt.rflags = xc.rflags; \
61 pt.rsp = xc.rsp; \
62 pt.xss = xc.ss; \
63 pt.xes = xc.es; \
64 pt.xds = xc.ds; \
65 pt.xfs = xc.fs; \
66 pt.xgs = xc.gs; \
67 }
69 #define SET_XC_REGS(pt, xc) \
70 { \
71 xc.r8 = pt->r8; \
72 xc.r9 = pt->r9; \
73 xc.r10 = pt->r10; \
74 xc.r11 = pt->r11; \
75 xc.r12 = pt->r12; \
76 xc.r13 = pt->r13; \
77 xc.r14 = pt->r14; \
78 xc.r15 = pt->r15; \
79 xc.rbx = pt->rbx; \
80 xc.rcx = pt->rcx; \
81 xc.rdx = pt->rdx; \
82 xc.rsi = pt->rsi; \
83 xc.rdi = pt->rdi; \
84 xc.rbp = pt->rbp; \
85 xc.rax = pt->rax; \
86 xc.rip = pt->rip; \
87 xc.cs = pt->xcs; \
88 xc.rflags = pt->rflags & 0xffffffff; \
89 xc.rsp = pt->rsp; \
90 xc.ss = pt->xss; \
91 xc.es = pt->xes; \
92 xc.ds = pt->xds; \
93 xc.fs = pt->xfs; \
94 xc.gs = pt->xgs; \
95 }
97 #elif __i386__
99 struct gdb_regs {
100 long ebx; /* 0 */
101 long ecx; /* 4 */
102 long edx; /* 8 */
103 long esi; /* 12 */
104 long edi; /* 16 */
105 long ebp; /* 20 */
106 long eax; /* 24 */
107 int xds; /* 28 */
108 int xes; /* 32 */
109 int xfs; /* 36 */
110 int xgs; /* 40 */
111 long orig_eax; /* 44 */
112 long eip; /* 48 */
113 int xcs; /* 52 */
114 long eflags; /* 56 */
115 long esp; /* 60 */
116 int xss; /* 64 */
117 };
119 #define SET_PT_REGS(pt, xc) \
120 { \
121 pt.ebx = xc.ebx; \
122 pt.ecx = xc.ecx; \
123 pt.edx = xc.edx; \
124 pt.esi = xc.esi; \
125 pt.edi = xc.edi; \
126 pt.ebp = xc.ebp; \
127 pt.eax = xc.eax; \
128 pt.eip = xc.eip; \
129 pt.xcs = xc.cs; \
130 pt.eflags = xc.eflags; \
131 pt.esp = xc.esp; \
132 pt.xss = xc.ss; \
133 pt.xes = xc.es; \
134 pt.xds = xc.ds; \
135 pt.xfs = xc.fs; \
136 pt.xgs = xc.gs; \
137 }
139 #define SET_XC_REGS(pt, xc) \
140 { \
141 xc.ebx = pt->ebx; \
142 xc.ecx = pt->ecx; \
143 xc.edx = pt->edx; \
144 xc.esi = pt->esi; \
145 xc.edi = pt->edi; \
146 xc.ebp = pt->ebp; \
147 xc.eax = pt->eax; \
148 xc.eip = pt->eip; \
149 xc.cs = pt->xcs; \
150 xc.eflags = pt->eflags; \
151 xc.esp = pt->esp; \
152 xc.ss = pt->xss; \
153 xc.es = pt->xes; \
154 xc.ds = pt->xds; \
155 xc.fs = pt->xfs; \
156 xc.gs = pt->xgs; \
157 }
158 #endif
160 #endif /* XC_PTRACE */