1 /*\
2 * Copyright (C) International Business Machines Corp., 2005
3 * Author(s): Anthony Liguori <aliguori@us.ibm.com>
4 *
5 * Xen Console Daemon
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; under version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; If not, see <http://www.gnu.org/licenses/>.
18 \*/
19
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <sys/wait.h>
23 #include <unistd.h>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <err.h>
27 #include <errno.h>
28 #include <stdio.h>
29 #include <getopt.h>
30 #include <stdbool.h>
31 #include <sys/socket.h>
32 #include <sys/un.h>
33 #include <string.h>
34 #include <signal.h>
35
36 #include "utils.h"
37
38 struct xs_handle *xs;
39 xc_interface *xc;
40
child_exit(int sig)41 static void child_exit(int sig)
42 {
43 while (waitpid(-1, NULL, WNOHANG) > 0);
44 }
45
daemonize(const char * pidfile)46 void daemonize(const char *pidfile)
47 {
48 pid_t pid;
49 int fd;
50 int len;
51 int i;
52 char buf[100];
53
54 if ((pid = fork()) > 0) {
55 exit(0);
56 } else if (pid == -1) {
57 err(errno, "fork() failed");
58 }
59
60 setsid();
61
62 if ((pid = fork()) > 0) {
63 exit(0);
64 } else if (pid == -1) {
65 err(errno, "fork() failed");
66 }
67
68 /* redirect fd 0,1,2 to /dev/null */
69 if ((fd = open("/dev/null",O_RDWR)) == -1) {
70 exit(1);
71 }
72
73 for (i = 0; i <= 2; i++) {
74 close(i);
75 dup2(fd, i);
76 }
77
78 close(fd);
79
80 umask(027);
81 if (chdir("/") < 0)
82 exit (1);
83
84 fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR|S_IWUSR);
85 if (fd == -1) {
86 exit(1);
87 }
88
89 if (lockf(fd, F_TLOCK, 0) == -1) {
90 exit(1);
91 }
92
93 len = snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
94 if (write(fd, buf, len) < 0)
95 exit(1);
96
97 signal(SIGCHLD, child_exit);
98 signal(SIGTSTP, SIG_IGN);
99 signal(SIGTTOU, SIG_IGN);
100 signal(SIGTTIN, SIG_IGN);
101 close(fd);
102 }
103
xen_setup(void)104 bool xen_setup(void)
105 {
106
107 xs = xs_daemon_open();
108 if (xs == NULL) {
109 dolog(LOG_ERR,
110 "Failed to contact xenstore (%m). Is it running?");
111 goto out;
112 }
113
114 xc = xc_interface_open(0,0,0);
115 if (!xc) {
116 dolog(LOG_ERR, "Failed to contact hypervisor (%m)");
117 goto out;
118 }
119
120 if (!xs_watch(xs, "@introduceDomain", "domlist")) {
121 dolog(LOG_ERR, "xenstore watch on @introduceDomain fails.");
122 goto out;
123 }
124
125 if (!xs_watch(xs, "@releaseDomain", "domlist")) {
126 dolog(LOG_ERR, "xenstore watch on @releaseDomain fails.");
127 goto out;
128 }
129
130 return true;
131
132 out:
133 if (xs)
134 xs_daemon_close(xs);
135 if (xc)
136 xc_interface_close(xc);
137 return false;
138 }
139
140