rev |
line source |
cl349@5357
|
1 /*
|
cl349@5357
|
2 Fake libxc which doesn't require hypervisor but talks to xs_test.
|
cl349@5357
|
3 Copyright (C) 2005 Rusty Russell IBM Corporation
|
cl349@5357
|
4
|
cl349@5357
|
5 This program is free software; you can redistribute it and/or modify
|
cl349@5357
|
6 it under the terms of the GNU General Public License as published by
|
cl349@5357
|
7 the Free Software Foundation; either version 2 of the License, or
|
cl349@5357
|
8 (at your option) any later version.
|
cl349@5357
|
9
|
cl349@5357
|
10 This program is distributed in the hope that it will be useful,
|
cl349@5357
|
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
|
cl349@5357
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
cl349@5357
|
13 GNU General Public License for more details.
|
cl349@5357
|
14
|
cl349@5357
|
15 You should have received a copy of the GNU General Public License
|
cl349@5357
|
16 along with this program; if not, write to the Free Software
|
cl349@5357
|
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
cl349@5357
|
18 */
|
cl349@5357
|
19
|
cl349@5357
|
20 #include <stdio.h>
|
cl349@5357
|
21 #include <stdlib.h>
|
cl349@5357
|
22 #include <sys/types.h>
|
cl349@5357
|
23 #include <sys/stat.h>
|
cl349@5357
|
24 #include <fcntl.h>
|
cl349@5357
|
25 #include <sys/mman.h>
|
cl349@5357
|
26 #include <unistd.h>
|
cl349@5357
|
27 #include <assert.h>
|
cl349@5357
|
28 #include <signal.h>
|
cl349@5357
|
29 #include "utils.h"
|
cl349@5357
|
30 #include "xenstored_core.h"
|
cl349@5357
|
31 #include "xenstored_domain.h"
|
cl349@5357
|
32 #include "xenstored_test.h"
|
cl349@5357
|
33
|
cl349@5357
|
34 static int sigfd;
|
cl349@5357
|
35 static int xs_test_pid;
|
cl349@5357
|
36 static u16 port;
|
cl349@5357
|
37
|
cl349@5357
|
38 /* The event channel maps to a signal, shared page to an mmapped file. */
|
cl349@5357
|
39 int xc_evtchn_send(int xc_handle __attribute__((unused)), int local_port)
|
cl349@5357
|
40 {
|
cl349@5357
|
41 assert(local_port == port);
|
cl349@5357
|
42 if (kill(xs_test_pid, SIGUSR2) != 0)
|
cl349@5357
|
43 barf_perror("fake event channel failed");
|
cl349@5357
|
44 return 0;
|
cl349@5357
|
45 }
|
cl349@5357
|
46
|
cl349@5357
|
47 void *xc_map_foreign_range(int xc_handle, u32 dom __attribute__((unused)),
|
cl349@5357
|
48 int size, int prot,
|
cl349@5357
|
49 unsigned long mfn __attribute__((unused)))
|
cl349@5357
|
50 {
|
cl349@5357
|
51 void *ret;
|
cl349@5357
|
52
|
cl349@5357
|
53 ret = mmap(NULL, size, prot, MAP_SHARED, xc_handle, 0);
|
cl349@5357
|
54 if (ret == MAP_FAILED)
|
cl349@5357
|
55 return NULL;
|
cl349@5357
|
56
|
cl349@5357
|
57 /* xs_test tells us pid and port by putting it in buffer, we reply. */
|
cl349@5357
|
58 xs_test_pid = *(int *)(ret + 32);
|
cl349@5357
|
59 port = *(int *)(ret + 36);
|
cl349@5357
|
60 *(int *)(ret + 32) = getpid();
|
cl349@5357
|
61 return ret;
|
cl349@5357
|
62 }
|
cl349@5357
|
63
|
cl349@5357
|
64 int xc_interface_open(void)
|
cl349@5357
|
65 {
|
cl349@5357
|
66 int fd;
|
cl349@5357
|
67 char page[getpagesize()];
|
cl349@5357
|
68
|
cl349@5357
|
69 fd = open("/tmp/xcmap", O_RDWR|O_CREAT|O_TRUNC, 0600);
|
cl349@5357
|
70 if (fd < 0)
|
cl349@5357
|
71 return fd;
|
cl349@5357
|
72
|
cl349@5357
|
73 memset(page, 0, sizeof(page));
|
kaf24@5423
|
74 if (!xs_write_all(fd, page, sizeof(page)))
|
cl349@5357
|
75 barf_perror("Failed to write /tmp/xcmap page");
|
cl349@5357
|
76
|
cl349@5357
|
77 return fd;
|
cl349@5357
|
78 }
|
cl349@5357
|
79
|
cl349@5357
|
80 int xc_interface_close(int xc_handle)
|
cl349@5357
|
81 {
|
cl349@5357
|
82 close(xc_handle);
|
cl349@5357
|
83 return 0;
|
cl349@5357
|
84 }
|
cl349@5357
|
85
|
cl349@6752
|
86 int xc_domain_getinfo(int xc_handle __attribute__((unused)),
|
cl349@6752
|
87 u32 first_domid, unsigned int max_doms,
|
cl349@6752
|
88 xc_dominfo_t *info)
|
cl349@6752
|
89 {
|
cl349@6752
|
90 assert(max_doms == 1);
|
cl349@6752
|
91 info->domid = first_domid;
|
cl349@6752
|
92
|
cl349@6752
|
93 info->dying = 0;
|
cl349@6752
|
94 info->shutdown = 0;
|
cl349@6752
|
95 info->paused = 0;
|
cl349@6752
|
96 info->blocked = 0;
|
cl349@6752
|
97 info->running = 1;
|
cl349@6752
|
98
|
cl349@6752
|
99 info->shutdown_reason = 0;
|
cl349@6752
|
100
|
cl349@6752
|
101 if ( info->shutdown && (info->shutdown_reason == SHUTDOWN_crash) )
|
cl349@6752
|
102 {
|
cl349@6752
|
103 info->shutdown = 0;
|
cl349@6752
|
104 info->crashed = 1;
|
cl349@6752
|
105 }
|
cl349@6752
|
106
|
cl349@6752
|
107 return 1;
|
cl349@6752
|
108 }
|
cl349@6752
|
109
|
cl349@6752
|
110 int xc_evtchn_bind_virq(int xc_handle __attribute__((unused)),
|
cl349@6752
|
111 int virq __attribute__((unused)),
|
cl349@6752
|
112 int *port)
|
cl349@6752
|
113 {
|
cl349@6752
|
114 if (port)
|
cl349@6752
|
115 *port = 0;
|
cl349@6752
|
116 return 0;
|
cl349@6752
|
117 }
|
cl349@6752
|
118
|
cl349@5357
|
119 static void send_to_fd(int signo __attribute__((unused)))
|
cl349@5357
|
120 {
|
cl349@5357
|
121 int saved_errno = errno;
|
cl349@5357
|
122 write(sigfd, &port, sizeof(port));
|
cl349@5357
|
123 errno = saved_errno;
|
cl349@5357
|
124 }
|
cl349@5357
|
125
|
cl349@5357
|
126 void fake_block_events(void)
|
cl349@5357
|
127 {
|
cl349@5357
|
128 signal(SIGUSR2, SIG_IGN);
|
cl349@5357
|
129 }
|
cl349@5357
|
130
|
cl349@5357
|
131 void fake_ack_event(void)
|
cl349@5357
|
132 {
|
cl349@5357
|
133 signal(SIGUSR2, send_to_fd);
|
cl349@5357
|
134 }
|
cl349@5357
|
135
|
cl349@5357
|
136 int fake_open_eventchn(void)
|
cl349@5357
|
137 {
|
cl349@5357
|
138 int fds[2];
|
cl349@5357
|
139
|
cl349@5357
|
140 if (pipe(fds) != 0)
|
cl349@5357
|
141 return -1;
|
cl349@5357
|
142
|
cl349@5357
|
143 if (signal(SIGUSR2, send_to_fd) == SIG_ERR) {
|
cl349@5357
|
144 int saved_errno = errno;
|
cl349@5357
|
145 close(fds[0]);
|
cl349@5357
|
146 close(fds[1]);
|
cl349@5357
|
147 errno = saved_errno;
|
cl349@5357
|
148 return -1;
|
cl349@5357
|
149 }
|
cl349@5357
|
150 sigfd = fds[1];
|
cl349@5357
|
151 return fds[0];
|
cl349@5357
|
152 }
|