1 /*
2     Simple prototype Xen Store Daemon providing simple tree-like database.
3     Copyright (C) 2005 Rusty Russell IBM Corporation
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <stdlib.h>
24 #include <sys/mman.h>
25 
26 #include "utils.h"
27 #include "xenstored_core.h"
28 #include "xenstored_osdep.h"
29 
write_pidfile(const char * pidfile)30 void write_pidfile(const char *pidfile)
31 {
32 	char buf[100];
33 	int len;
34 	int fd;
35 
36 	fd = open(pidfile, O_RDWR | O_CREAT, 0600);
37 	if (fd == -1)
38 		barf_perror("Opening pid file %s", pidfile);
39 
40 	/* We exit silently if daemon already running. */
41 	if (lockf(fd, F_TLOCK, 0) == -1)
42 		exit(0);
43 
44 	len = snprintf(buf, sizeof(buf), "%ld\n", (long)getpid());
45 	if (write(fd, buf, len) != len)
46 		barf_perror("Writing pid file %s", pidfile);
47 
48 	close(fd);
49 }
50 
51 /* Stevens. */
daemonize(void)52 void daemonize(void)
53 {
54 	pid_t pid;
55 
56 	/* Separate from our parent via fork, so init inherits us. */
57 	if ((pid = fork()) < 0)
58 		barf_perror("Failed to fork daemon");
59 	if (pid != 0)
60 		exit(0);
61 
62 	/* Session leader so ^C doesn't whack us. */
63 	setsid();
64 
65 	/* Let session leader exit so child cannot regain CTTY */
66 	if ((pid = fork()) < 0)
67 		barf_perror("Failed to fork daemon");
68 	if (pid != 0)
69 		exit(0);
70 
71 	/* Move off any mount points we might be in. */
72 	if (chdir("/") == -1)
73 		barf_perror("Failed to chdir");
74 
75 	/* Discard our parent's old-fashioned umask prejudices. */
76 	umask(0);
77 }
78 
finish_daemonize(void)79 void finish_daemonize(void)
80 {
81 	int devnull = open("/dev/null", O_RDWR);
82 	if (devnull == -1)
83 		barf_perror("Could not open /dev/null\n");
84 	dup2(devnull, STDIN_FILENO);
85 	dup2(devnull, STDOUT_FILENO);
86 	dup2(devnull, STDERR_FILENO);
87 	close(devnull);
88 	xprintf = trace;
89 }
90 
init_pipe(int reopen_log_pipe[2])91 void init_pipe(int reopen_log_pipe[2])
92 {
93 	if (pipe(reopen_log_pipe)) {
94 		barf_perror("pipe");
95 	}
96 }
97 
unmap_xenbus(void * interface)98 void unmap_xenbus(void *interface)
99 {
100 	munmap(interface, getpagesize());
101 }
102 
103 #ifndef __sun__
xenbus_evtchn(void)104 evtchn_port_t xenbus_evtchn(void)
105 {
106 	int fd;
107 	int rc;
108 	evtchn_port_t port;
109 	char str[20];
110 
111 	fd = open(XENSTORED_PORT_DEV, O_RDONLY);
112 	if (fd == -1)
113 		return -1;
114 
115 	rc = read(fd, str, sizeof(str) - 1);
116 	if (rc == -1)
117 	{
118 		int err = errno;
119 		close(fd);
120 		errno = err;
121 		return -1;
122 	}
123 
124 	str[rc] = '\0';
125 	port = strtoul(str, NULL, 0);
126 
127 	close(fd);
128 	return port;
129 }
130 
xenbus_map(void)131 void *xenbus_map(void)
132 {
133 	int fd;
134 	void *addr;
135 
136 	fd = open(XENSTORED_KVA_DEV, O_RDWR);
137 	if (fd == -1)
138 		return NULL;
139 
140 	addr = mmap(NULL, getpagesize(), PROT_READ|PROT_WRITE,
141 		MAP_SHARED, fd, 0);
142 
143 	if (addr == MAP_FAILED)
144 		addr = NULL;
145 
146 	close(fd);
147 
148 	return addr;
149 }
150 
xenbus_notify_running(void)151 void xenbus_notify_running(void)
152 {
153 }
154 #endif /* !__sun__ */
155