ia64/xen-unstable

view tools/console/daemon/utils.c @ 6538:84ee014ebd41

Merge xen-vtx-unstable.hg
author adsharma@los-vmm.sc.intel.com
date Wed Aug 17 12:34:38 2005 -0800 (2005-08-17)
parents 23979fb12c49 d74e320900fd
children 99914b54f7bf
line source
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 \*/
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/wait.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <fcntl.h>
27 #include <err.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <getopt.h>
31 #include <stdbool.h>
32 #include <sys/socket.h>
33 #include <sys/un.h>
34 #include <string.h>
36 #include "xc.h"
37 #include "xen/io/domain_controller.h"
38 #include "xcs_proto.h"
40 #include "utils.h"
42 struct xs_handle *xs;
43 int xc;
45 int xcs_ctrl_fd = -1;
46 int xcs_data_fd = -1;
48 bool _read_write_sync(int fd, void *data, size_t size, bool do_read)
49 {
50 size_t offset = 0;
51 ssize_t len;
53 while (offset < size) {
54 if (do_read) {
55 len = read(fd, data + offset, size - offset);
56 } else {
57 len = write(fd, data + offset, size - offset);
58 }
60 if (len < 1) {
61 if (len == -1 && (errno == EAGAIN || errno == EINTR)) {
62 continue;
63 } else {
64 return false;
65 }
66 } else {
67 offset += len;
68 }
69 }
71 return true;
72 }
74 static int open_domain_socket(const char *path)
75 {
76 struct sockaddr_un addr;
77 int sock;
78 size_t addr_len;
80 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
81 goto out;
82 }
84 addr.sun_family = AF_UNIX;
85 strcpy(addr.sun_path, path);
86 addr_len = sizeof(addr.sun_family) + strlen(XCS_SUN_PATH) + 1;
88 if (connect(sock, (struct sockaddr *)&addr, addr_len) == -1) {
89 goto out_close_sock;
90 }
92 return sock;
94 out_close_sock:
95 close(sock);
96 out:
97 return -1;
98 }
100 static void child_exit(int sig)
101 {
102 while (waitpid(-1, NULL, WNOHANG) > 0);
103 }
105 void daemonize(const char *pidfile)
106 {
107 pid_t pid;
108 int fd;
109 int len;
110 int i;
111 char buf[100];
113 if (getppid() == 1) {
114 return;
115 }
117 if ((pid = fork()) > 0) {
118 exit(0);
119 } else if (pid == -1) {
120 err(errno, "fork() failed");
121 }
123 setsid();
125 /* redirect fd 0,1,2 to /dev/null */
126 if ((fd = open("/dev/null",O_RDWR)) == -1) {
127 exit(1);
128 }
130 for (i = 0; i <= 2; i++) {
131 close(i);
132 dup2(fd, i);
133 }
135 close(fd);
137 umask(027);
138 chdir("/");
140 fd = open(pidfile, O_RDWR | O_CREAT);
141 if (fd == -1) {
142 exit(1);
143 }
145 if (lockf(fd, F_TLOCK, 0) == -1) {
146 exit(1);
147 }
149 len = sprintf(buf, "%d\n", getpid());
150 write(fd, buf, len);
152 signal(SIGCHLD, child_exit);
153 signal(SIGTSTP, SIG_IGN);
154 signal(SIGTTOU, SIG_IGN);
155 signal(SIGTTIN, SIG_IGN);
156 }
158 /* synchronized send/recv strictly for setting up xcs */
159 /* always use asychronize callbacks any other time */
160 static bool xcs_send_recv(int fd, xcs_msg_t *msg)
161 {
162 bool ret = false;
164 if (!write_sync(fd, msg, sizeof(*msg))) {
165 dolog(LOG_ERR, "Write failed at %s:%s():L%d? Possible bug.",
166 __FILE__, __FUNCTION__, __LINE__);
167 goto out;
168 }
170 if (!read_sync(fd, msg, sizeof(*msg))) {
171 dolog(LOG_ERR, "Read failed at %s:%s():L%d? Possible bug.",
172 __FILE__, __FUNCTION__, __LINE__);
173 goto out;
174 }
176 ret = true;
178 out:
179 return ret;
180 }
182 bool xen_setup(void)
183 {
184 int sock;
185 xcs_msg_t msg;
187 xs = xs_daemon_open();
188 if (xs == NULL) {
189 dolog(LOG_ERR,
190 "Failed to contact xenstore (%m). Is it running?");
191 goto out;
192 }
194 xc = xc_interface_open();
195 if (xc == -1) {
196 dolog(LOG_ERR, "Failed to contact hypervisor (%m)");
197 goto out;
198 }
200 sock = open_domain_socket(XCS_SUN_PATH);
201 if (sock == -1) {
202 dolog(LOG_ERR, "Failed to contact xcs (%m). Is it running?");
203 goto out_close_store;
204 }
206 xcs_ctrl_fd = sock;
208 sock = open_domain_socket(XCS_SUN_PATH);
209 if (sock == -1) {
210 dolog(LOG_ERR, "Failed to contact xcs (%m). Is it running?");
211 goto out_close_ctrl;
212 }
214 xcs_data_fd = sock;
216 memset(&msg, 0, sizeof(msg));
217 msg.type = XCS_CONNECT_CTRL;
218 if (!xcs_send_recv(xcs_ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) {
219 dolog(LOG_ERR, "xcs control connect failed. Possible bug.");
220 goto out_close_data;
221 }
223 msg.type = XCS_CONNECT_DATA;
224 if (!xcs_send_recv(xcs_data_fd, &msg) || msg.result != XCS_RSLT_OK) {
225 dolog(LOG_ERR, "xcs data connect failed. Possible bug.");
226 goto out_close_data;
227 }
229 /* Since the vast majority of control messages are console messages
230 it's just easier to ignore other messages that try to bind to
231 a specific type. */
232 msg.type = XCS_MSG_BIND;
233 msg.u.bind.port = PORT_WILDCARD;
234 msg.u.bind.type = TYPE_WILDCARD;
235 if (!xcs_send_recv(xcs_ctrl_fd, &msg) || msg.result != XCS_RSLT_OK) {
236 dolog(LOG_ERR, "xcs vind failed. Possible bug.");
237 goto out_close_data;
238 }
240 return true;
242 out_close_data:
243 close(xcs_ctrl_fd);
244 xcs_data_fd = -1;
245 out_close_ctrl:
246 close(xcs_ctrl_fd);
247 xcs_ctrl_fd = -1;
248 out_close_store:
249 xs_daemon_close(xs);
250 out:
251 return false;
252 }