6524928 domU console shouldn't drop when the domain reboots
6664507 virsh console command on Xen DomU system does not enforce console write exclusivity
6718462 need HVM serial support in virt-install
6718906 xVM console should be more verbose
1 --- libvirt-0.4.0/qemud/remote.c 2007-12-12 05:30:49.000000000 -0800
2 +++ libvirt-new/qemud/remote.c 2008-04-10 12:52:18.059618661 -0700
3 @@ -434,6 +434,15 @@ remoteDispatchOpen (struct qemud_server
4 flags = args->flags;
5 if (client->readonly) flags |= VIR_CONNECT_RO;
6
7 +#ifdef __sun
8 + /*
9 + * On Solaris, all clients are forced to go via virtd. As a result,
10 + * virtd must indicate it really does want to connect to the
11 + * hypervisor.
12 + */
13 + name = "xen:///";
14 +#endif
15 +
16 client->conn =
17 flags & VIR_CONNECT_RO
18 ? virConnectOpenReadOnly (name)
19 --- libvirt-0.4.0/src/libvirt.c 2007-12-17 13:51:09.000000000 -0800
20 +++ libvirt-new/src/libvirt.c 2008-04-16 08:46:28.767087199 -0700
21 @@ -34,6 +34,7 @@
22
23 #include "uuid.h"
24 #include "test.h"
25 +#include "xen_internal.h"
26 #include "xen_unified.h"
27 #include "remote_internal.h"
28 #include "qemu_driver.h"
29 @@ -202,8 +203,16 @@ virInitialize(void)
30 if (qemudRegister() == -1) return -1;
31 #endif
32 #ifdef WITH_XEN
33 + /*
34 + * On Solaris, only initialize Xen if we're libvirtd.
35 + */
36 +#ifdef __sun
37 + if (geteuid() != 0 && xenHavePrivilege() &&
38 + xenUnifiedRegister () == -1) return -1;
39 +#else
40 if (xenUnifiedRegister () == -1) return -1;
41 #endif
42 +#endif
43 #ifdef WITH_OPENVZ
44 if (openvzRegister() == -1) return -1;
45 #endif
46 @@ -525,6 +534,16 @@ do_open (const char *name,
47 if (STREQ (name, "xen://"))
48 name = "xen:///";
49
50 +#ifdef __sun
51 + /*
52 + * If we're not libvirtd, force us to go via the daemon.
53 + */
54 + if (geteuid() == 0 || !xenHavePrivilege())
55 + name = "remote+unix:///";
56 + else if (STREQ (name, "xen:///") && xenUnifiedRegister () == -1)
57 + return NULL;
58 +#endif
59 +
60 if (!initialized)
61 if (virInitialize() < 0)
62 return NULL;
63 --- libvirt-0.4.0/qemud/qemud.c 2007-12-12 05:30:49.000000000 -0800
64 +++ libvirt-new/qemud/qemud.c 2008-04-17 17:16:47.075258251 -0700
65 @@ -60,6 +60,25 @@
66 #include "mdns.h"
67 #endif
68
69 +#ifdef __sun
70 +#include <ucred.h>
71 +#include <priv.h>
72 +
73 +#ifndef PRIV_VIRT_MANAGE
74 +#define PRIV_VIRT_MANAGE ((const char *)"virt_manage")
75 +#endif
76 +
77 +#ifndef PRIV_XVM_CONTROL
78 +#define PRIV_XVM_CONTROL ((const char *)"xvm_control")
79 +#endif
80 +
81 +#define PU_RESETGROUPS 0x0001 /* Remove supplemental groups */
82 +#define PU_CLEARLIMITSET 0x0008 /* L=0 */
83 +
84 +extern int __init_daemon_priv(int, uid_t, gid_t, ...);
85 +
86 +#endif
87 +
88 static int godaemon = 0; /* -d: Be a daemon */
89 static int verbose = 0; /* -v: Verbose mode */
90 static int timeout = -1; /* -t: Shutdown timeout */
91 @@ -668,11 +687,13 @@ static int qemudInitPaths(struct qemud_s
92
93 unlink(sockname);
94
95 +#ifndef __sun
96 if (snprintf (roSockname, maxlen, "%s/run/libvirt/libvirt-sock-ro",
97 LOCAL_STATE_DIR) >= maxlen)
98 goto snprintf_error;
99
100 unlink(roSockname);
101 +#endif
102
103 if (snprintf(server->logDir, PATH_MAX, "%s/log/libvirt/", LOCAL_STATE_DIR) >= PATH_MAX)
104 goto snprintf_error;
105 @@ -1033,6 +1054,29 @@ static int qemudDispatchServer(struct qe
106 return -1;
107 }
108
109 +#ifdef __sun
110 + {
111 + ucred_t *ucred = NULL;
112 + const priv_set_t *privs;
113 +
114 + if (getpeerucred (fd, &ucred) == -1 ||
115 + (privs = ucred_getprivset (ucred, PRIV_EFFECTIVE)) == NULL) {
116 + if (ucred != NULL)
117 + ucred_free (ucred);
118 + close (fd);
119 + return -1;
120 + }
121 +
122 + if (!priv_ismember (privs, PRIV_VIRT_MANAGE)) {
123 + ucred_free (ucred);
124 + close (fd);
125 + return -1;
126 + }
127 +
128 + ucred_free (ucred);
129 + }
130 +#endif /* __sun */
131 +
132 /* Disable Nagle. Unix sockets will ignore this. */
133 setsockopt (fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_slow_start,
134 sizeof no_slow_start);
135 @@ -1864,6 +1908,10 @@ remoteReadConfigFile (struct qemud_serve
136 if (auth_unix_rw == REMOTE_AUTH_POLKIT)
137 unix_sock_rw_mask = 0777;
138 #endif
139 +#ifdef __sun
140 + unix_sock_rw_mask = 0666;
141 +#endif
142 +
143 if (remoteConfigGetAuth(conf, "auth_unix_ro", &auth_unix_ro, filename) < 0)
144 return -1;
145 if (remoteConfigGetAuth(conf, "auth_tcp", &auth_tcp, filename) < 0)
146 @@ -1955,6 +2003,32 @@ remoteReadConfigFile (struct qemud_serve
147 return -1;
148 }
149
150 +#ifdef __sun
151 +static void
152 +qemudSetupPrivs (struct qemud_server *server)
153 +{
154 + chown ("/var/run/libvirt", 60, 60);
155 + chmod ("/var/run/libvirt", 0755);
156 + chown ("/var/run/libvirt/libvirt-sock", 60, 60);
157 + chmod ("/var/run/libvirt/libvirt-sock", 0666);
158 + chown (server->logDir, 60, 60);
159 +
160 + if (__init_daemon_priv (PU_RESETGROUPS | PU_CLEARLIMITSET,
161 + 60, 60, PRIV_XVM_CONTROL, NULL)) {
162 + fprintf (stderr, "additional privileges are required\n");
163 + exit (1);
164 + }
165 +
166 + if (priv_set (PRIV_OFF, PRIV_ALLSETS, PRIV_FILE_LINK_ANY, PRIV_PROC_INFO,
167 + PRIV_PROC_SESSION, PRIV_PROC_EXEC, PRIV_PROC_FORK, NULL)) {
168 + fprintf (stderr, "failed to set reduced privileges\n");
169 + exit (1);
170 + }
171 +}
172 +#else
173 +#define qemudSetupPrivs
174 +#endif
175 +
176 /* Print command-line usage. */
177 static void
178 usage (const char *argv0)
179 @@ -2139,6 +2213,8 @@ int main(int argc, char **argv) {
180 goto error2;
181 }
182
183 + qemudSetupPrivs(server);
184 +
185 qemudRunLoop(server);
186
187 qemudCleanup(server);
188 --- libvirt-0.4.0/src/xs_internal.c 2007-12-14 07:33:11.000000000 -0800
189 +++ libvirt-new/src/xs_internal.c 2008-04-10 09:54:38.676077954 -0700
190 @@ -31,7 +31,7 @@
191 #include "driver.h"
192 #include "xen_unified.h"
193 #include "xs_internal.h"
194 -#include "xen_internal.h" /* for xenHypervisorCheckID */
195 +#include "xen_internal.h"
196
197 #ifdef __linux__
198 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
199 @@ -344,11 +344,11 @@ xenStoreOpen(virConnectPtr conn,
200
201 if (priv->xshandle == NULL) {
202 /*
203 - * not being able to connect via the socket as a normal user
204 - * is rather normal, this should fallback to the proxy (or
205 - * remote) mechanism.
206 + * not being able to connect via the socket as an unprivileged
207 + * user is rather normal, this should fallback to the proxy (or
208 + * remote) mechanism.
209 */
210 - if (getuid() == 0) {
211 + if (!xenHavePrivilege()) {
212 virXenStoreError(NULL, VIR_ERR_NO_XEN,
213 _("failed to connect to Xen Store"));
214 }
215 --- libvirt-0.4.0/src/xen_internal.c 2007-12-12 05:30:49.000000000 -0800
216 +++ libvirt-new/src/xen_internal.c 2008-04-10 10:28:41.363704244 -0700
217 @@ -28,6 +28,15 @@
218 #include <errno.h>
219 #include <sys/utsname.h>
220
221 +#ifdef __sun
222 +#include <priv.h>
223 +
224 +#ifndef PRIV_XVM_CONTROL
225 +#define PRIV_XVM_CONTROL ((const char *)"xvm_control")
226 +#endif
227 +
228 +#endif
229 +
230 #include "xs_internal.h"
231 #include "stats_linux.h"
232 #include "xend_internal.h"
233 @@ -3259,6 +3268,21 @@ xenHypervisorGetVcpuMax(virDomainPtr dom
234 return maxcpu;
235 }
236
237 +/**
238 + * xenHavePrivilege()
239 + *
240 + * Return true if the current process should be able to connect to Xen.
241 + */
242 +int
243 +xenHavePrivilege()
244 +{
245 +#ifdef __sun
246 + return priv_ineffect (PRIV_XVM_CONTROL);
247 +#else
248 + return getuid () == 0;
249 +#endif
250 +}
251 +
252 #endif /* WITH_XEN */
253 /*
254 * vim: set tabstop=4:
255 --- libvirt-0.4.0/src/xen_internal.h 2007-12-05 12:33:02.000000000 -0800
256 +++ libvirt-new/src/xen_internal.h 2008-04-10 09:34:16.379186656 -0700
257 @@ -98,6 +98,9 @@ int xenHypervisorNodeGetCellsFreeMemory(
258 unsigned long long *freeMems,
259 int startCell,
260 int maxCells);
261 +
262 +int xenHavePrivilege(void);
263 +
264 #ifdef __cplusplus
265 }
266 #endif
267 --- libvirt-0.4.0/src/xen_unified.c 2007-12-12 05:30:49.000000000 -0800
268 +++ libvirt-new/src/xen_unified.c 2008-04-10 15:10:53.653298774 -0700
269 @@ -266,8 +266,8 @@ xenUnifiedOpen (virConnectPtr conn, xmlU
270 priv->xendConfigVersion > 2)
271 continue;
272
273 - /* Ignore proxy for root */
274 - if (i == XEN_UNIFIED_PROXY_OFFSET && getuid() == 0)
275 + /* Ignore proxy if we have privilege */
276 + if (i == XEN_UNIFIED_PROXY_OFFSET && xenHavePrivilege())
277 continue;
278
279 if (drivers[i]->open) {
280 @@ -282,10 +282,10 @@ xenUnifiedOpen (virConnectPtr conn, xmlU
281 #endif
282 }
283
284 - /* If as root, then all drivers must succeed.
285 - If non-root, then only proxy must succeed */
286 + /* If privileged, then all drivers must succeed.
287 + If unprivileged, then only proxy must succeed */
288 if (!priv->opened[i] &&
289 - (getuid() == 0 || i == XEN_UNIFIED_PROXY_OFFSET)) {
290 + (xenHavePrivilege() || i == XEN_UNIFIED_PROXY_OFFSET)) {
291 for (j = 0; j < i; ++j)
292 if (priv->opened[j]) drivers[j]->close (conn);
293 free (priv);
294 @@ -1266,6 +1266,12 @@ static virDriver xenUnifiedDriver = {
295 int
296 xenUnifiedRegister (void)
297 {
298 + static int driver_priority = 0;
299 + static int xen_initialized = 0;
300 +
301 + if (xen_initialized)
302 + return driver_priority;
303 +
304 /* Ignore failures here. */
305 (void) xenHypervisorInit ();
306 (void) xenProxyInit ();
307 @@ -1273,7 +1279,9 @@ xenUnifiedRegister (void)
308 (void) xenStoreInit ();
309 (void) xenXMInit ();
310
311 - return virRegisterDriver (&xenUnifiedDriver);
312 + driver_priority = virRegisterDriver (&xenUnifiedDriver);
313 + xen_initialized = 1;
314 + return driver_priority;
315 }
316
317 #endif /* WITH_XEN */
318 --- libvirt-0.4.0/src/xend_internal.c 2007-12-17 15:05:27.000000000 -0800
319 +++ libvirt-new/src/xend_internal.c 2008-04-10 09:45:10.262989682 -0700
320 @@ -42,7 +42,7 @@
321 #include "uuid.h"
322 #include "xen_unified.h"
323 #include "xend_internal.h"
324 -#include "xen_internal.h" /* for DOM0_INTERFACE_VERSION */
325 +#include "xen_internal.h"
326 #include "xs_internal.h" /* To extract VNC port & Serial console TTY */
327
328 /* required for cpumap_t */
329 @@ -235,7 +235,7 @@ do_connect(virConnectPtr xend)
330 * is rather normal, this should fallback to the proxy (or
331 * remote) mechanism.
332 */
333 - if ((getuid() == 0) || (xend->flags & VIR_CONNECT_RO)) {
334 + if (xenHavePrivilege() || (xend->flags & VIR_CONNECT_RO)) {
335 virXendError(xend, VIR_ERR_INTERNAL_ERROR,
336 "failed to connect to xend");
337 }
338 --- libvirt-0.4.0/src/virsh.c 2007-12-07 07:00:48.000000000 -0800
339 +++ libvirt-new/src/virsh.c 2008-04-16 08:44:35.668718168 -0700
340 @@ -36,6 +36,7 @@
341 #include <sys/stat.h>
342 #include <inttypes.h>
343 #include <test.h>
344 +#include <signal.h>
345
346 #include <libxml/parser.h>
347 #include <libxml/tree.h>
348 @@ -50,6 +51,7 @@
349 #include "console.h"
350
351 static char *progname;
352 +static int sigpipe;
353
354 #ifndef TRUE
355 #define TRUE 1
356 @@ -202,9 +204,6 @@ typedef struct __vshControl {
357 virConnectPtr conn; /* connection to hypervisor (MAY BE NULL) */
358 vshCmd *cmd; /* the current command */
359 char *cmdstr; /* string with command */
360 -#ifndef __MINGW32__
361 - uid_t uid; /* process owner */
362 -#endif /* __MINGW32__ */
363 int imode; /* interactive mode? */
364 int quiet; /* quiet mode */
365 int debug; /* print debug messages? */
366 @@ -4523,22 +4497,11 @@ vshInit(vshControl * ctl)
367 if (ctl->conn)
368 return FALSE;
369
370 -#ifndef __MINGW32__
371 - ctl->uid = getuid();
372 -#endif
373 -
374 vshOpenLogFile(ctl);
375
376 /* set up the library error handler */
377 virSetErrorFunc(NULL, virshErrorHandler);
378
379 -#ifndef __MINGW32__
380 - /* Force a non-root, Xen connection to readonly */
381 - if ((ctl->name == NULL ||
382 - !strcasecmp(ctl->name, "xen")) && ctl->uid != 0)
383 - ctl->readonly = 1;
384 -#endif
385 -
386 ctl->conn = virConnectOpenAuth(ctl->name,
387 virConnectAuthPtrDefault,
388 ctl->readonly ? VIR_CONNECT_RO : 0);
389 @@ -5021,12 +4984,21 @@ vshParseArgv(vshControl * ctl, int argc,
390 return TRUE;
391 }
392
393 -int
394 +static void sigpipe_handler(int sig)
395 +{
396 + sigpipe = 1;
397 + /*
398 + * Force readline() to exit.
399 + */
400 + close(STDIN_FILENO);
401 +}
402 +
403 main(int argc, char **argv)
404 {
405 vshControl _ctl, *ctl = &_ctl;
406 char *defaultConn;
407 int ret = TRUE;
408 + struct sigaction sig_action;
409
410 if (!setlocale(LC_ALL, "")) {
411 perror("setlocale");
412 @@ -5059,6 +5031,12 @@ main(int argc, char **argv)
413 exit(EXIT_FAILURE);
414 }
415
416 + sig_action.sa_handler = sigpipe_handler;
417 + sig_action.sa_flags = 0;
418 + sigemptyset(&sig_action.sa_mask);
419 +
420 + sigaction(SIGPIPE, &sig_action, NULL);
421 +
422 if (!vshInit(ctl)) {
423 vshDeinit(ctl);
424 exit(EXIT_FAILURE);
425 @@ -5098,6 +5076,13 @@ main(int argc, char **argv)
426 fputc('\n', stdout); /* line break after alone prompt */
427 }
428
429 + /*
430 + * If the connection over a socket failed abruptly, it's probably
431 + * due to not having the right privileges.
432 + */
433 + if (sigpipe)
434 + vshError(ctl, TRUE, _("failed to connect (insufficient privileges?)"));
435 +
436 vshDeinit(ctl);
437 exit(ret ? EXIT_SUCCESS : EXIT_FAILURE);
438 }
--- EOF ---