xref: /openbmc/qemu/io/channel-command.c (revision 7f6c3d1a)
1 /*
2  * QEMU I/O channels external command driver
3  *
4  * Copyright (c) 2015 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library 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 GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 #include "qemu/osdep.h"
22 #include "io/channel-command.h"
23 #include "io/channel-watch.h"
24 #include "qapi/error.h"
25 #include "qemu/module.h"
26 #include "qemu/sockets.h"
27 #include "trace.h"
28 
29 
30 QIOChannelCommand *
31 qio_channel_command_new_pid(int writefd,
32                             int readfd,
33                             pid_t pid)
34 {
35     QIOChannelCommand *ioc;
36 
37     ioc = QIO_CHANNEL_COMMAND(object_new(TYPE_QIO_CHANNEL_COMMAND));
38 
39     ioc->readfd = readfd;
40     ioc->writefd = writefd;
41     ioc->pid = pid;
42 
43     trace_qio_channel_command_new_pid(ioc, writefd, readfd, pid);
44     return ioc;
45 }
46 
47 
48 #ifndef WIN32
49 QIOChannelCommand *
50 qio_channel_command_new_spawn(const char *const argv[],
51                               int flags,
52                               Error **errp)
53 {
54     pid_t pid = -1;
55     int stdinfd[2] = { -1, -1 };
56     int stdoutfd[2] = { -1, -1 };
57     int devnull = -1;
58     bool stdinnull = false, stdoutnull = false;
59     QIOChannelCommand *ioc;
60 
61     flags = flags & O_ACCMODE;
62 
63     if (flags == O_RDONLY) {
64         stdinnull = true;
65     }
66     if (flags == O_WRONLY) {
67         stdoutnull = true;
68     }
69 
70     if (stdinnull || stdoutnull) {
71         devnull = open("/dev/null", O_RDWR);
72         if (devnull < 0) {
73             error_setg_errno(errp, errno,
74                              "Unable to open /dev/null");
75             goto error;
76         }
77     }
78 
79     if ((!stdinnull && pipe(stdinfd) < 0) ||
80         (!stdoutnull && pipe(stdoutfd) < 0)) {
81         error_setg_errno(errp, errno,
82                          "Unable to open pipe");
83         goto error;
84     }
85 
86     pid = qemu_fork(errp);
87     if (pid < 0) {
88         goto error;
89     }
90 
91     if (pid == 0) { /* child */
92         dup2(stdinnull ? devnull : stdinfd[0], STDIN_FILENO);
93         dup2(stdoutnull ? devnull : stdoutfd[1], STDOUT_FILENO);
94         /* Leave stderr connected to qemu's stderr */
95 
96         if (!stdinnull) {
97             close(stdinfd[0]);
98             close(stdinfd[1]);
99         }
100         if (!stdoutnull) {
101             close(stdoutfd[0]);
102             close(stdoutfd[1]);
103         }
104         if (devnull != -1) {
105             close(devnull);
106         }
107 
108         execv(argv[0], (char * const *)argv);
109         _exit(1);
110     }
111 
112     if (!stdinnull) {
113         close(stdinfd[0]);
114     }
115     if (!stdoutnull) {
116         close(stdoutfd[1]);
117     }
118 
119     ioc = qio_channel_command_new_pid(stdinnull ? devnull : stdinfd[1],
120                                       stdoutnull ? devnull : stdoutfd[0],
121                                       pid);
122     trace_qio_channel_command_new_spawn(ioc, argv[0], flags);
123     return ioc;
124 
125  error:
126     if (devnull != -1) {
127         close(devnull);
128     }
129     if (stdinfd[0] != -1) {
130         close(stdinfd[0]);
131     }
132     if (stdinfd[1] != -1) {
133         close(stdinfd[1]);
134     }
135     if (stdoutfd[0] != -1) {
136         close(stdoutfd[0]);
137     }
138     if (stdoutfd[1] != -1) {
139         close(stdoutfd[1]);
140     }
141     return NULL;
142 }
143 
144 #else /* WIN32 */
145 QIOChannelCommand *
146 qio_channel_command_new_spawn(const char *const argv[],
147                               int flags,
148                               Error **errp)
149 {
150     error_setg_errno(errp, ENOSYS,
151                      "Command spawn not supported on this platform");
152     return NULL;
153 }
154 #endif /* WIN32 */
155 
156 #ifndef WIN32
157 static int qio_channel_command_abort(QIOChannelCommand *ioc,
158                                      Error **errp)
159 {
160     pid_t ret;
161     int status;
162     int step = 0;
163 
164     /* See if intermediate process has exited; if not, try a nice
165      * SIGTERM followed by a more severe SIGKILL.
166      */
167  rewait:
168     trace_qio_channel_command_abort(ioc, ioc->pid);
169     ret = waitpid(ioc->pid, &status, WNOHANG);
170     trace_qio_channel_command_wait(ioc, ioc->pid, ret, status);
171     if (ret == (pid_t)-1) {
172         if (errno == EINTR) {
173             goto rewait;
174         } else {
175             error_setg_errno(errp, errno,
176                              "Cannot wait on pid %llu",
177                              (unsigned long long)ioc->pid);
178             return -1;
179         }
180     } else if (ret == 0) {
181         if (step == 0) {
182             kill(ioc->pid, SIGTERM);
183         } else if (step == 1) {
184             kill(ioc->pid, SIGKILL);
185         } else {
186             error_setg(errp,
187                        "Process %llu refused to die",
188                        (unsigned long long)ioc->pid);
189             return -1;
190         }
191         step++;
192         usleep(10 * 1000);
193         goto rewait;
194     }
195 
196     return 0;
197 }
198 #endif /* ! WIN32 */
199 
200 
201 static void qio_channel_command_init(Object *obj)
202 {
203     QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj);
204     ioc->readfd = -1;
205     ioc->writefd = -1;
206     ioc->pid = -1;
207 }
208 
209 static void qio_channel_command_finalize(Object *obj)
210 {
211     QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj);
212     if (ioc->readfd != -1) {
213         close(ioc->readfd);
214     }
215     if (ioc->writefd != -1 &&
216         ioc->writefd != ioc->readfd) {
217         close(ioc->writefd);
218     }
219     ioc->writefd = ioc->readfd = -1;
220     if (ioc->pid > 0) {
221 #ifndef WIN32
222         qio_channel_command_abort(ioc, NULL);
223 #endif
224     }
225 }
226 
227 
228 static ssize_t qio_channel_command_readv(QIOChannel *ioc,
229                                          const struct iovec *iov,
230                                          size_t niov,
231                                          int **fds,
232                                          size_t *nfds,
233                                          Error **errp)
234 {
235     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
236     ssize_t ret;
237 
238  retry:
239     ret = readv(cioc->readfd, iov, niov);
240     if (ret < 0) {
241         if (errno == EAGAIN) {
242             return QIO_CHANNEL_ERR_BLOCK;
243         }
244         if (errno == EINTR) {
245             goto retry;
246         }
247 
248         error_setg_errno(errp, errno,
249                          "Unable to read from command");
250         return -1;
251     }
252 
253     return ret;
254 }
255 
256 static ssize_t qio_channel_command_writev(QIOChannel *ioc,
257                                           const struct iovec *iov,
258                                           size_t niov,
259                                           int *fds,
260                                           size_t nfds,
261                                           Error **errp)
262 {
263     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
264     ssize_t ret;
265 
266  retry:
267     ret = writev(cioc->writefd, iov, niov);
268     if (ret <= 0) {
269         if (errno == EAGAIN) {
270             return QIO_CHANNEL_ERR_BLOCK;
271         }
272         if (errno == EINTR) {
273             goto retry;
274         }
275         error_setg_errno(errp, errno, "%s",
276                          "Unable to write to command");
277         return -1;
278     }
279     return ret;
280 }
281 
282 static int qio_channel_command_set_blocking(QIOChannel *ioc,
283                                             bool enabled,
284                                             Error **errp)
285 {
286     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
287 
288     if (enabled) {
289         qemu_set_block(cioc->writefd);
290         qemu_set_block(cioc->readfd);
291     } else {
292         qemu_set_nonblock(cioc->writefd);
293         qemu_set_nonblock(cioc->readfd);
294     }
295 
296     return 0;
297 }
298 
299 
300 static int qio_channel_command_close(QIOChannel *ioc,
301                                      Error **errp)
302 {
303     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
304     int rv = 0;
305 #ifndef WIN32
306     pid_t wp;
307 #endif
308 
309     /* We close FDs before killing, because that
310      * gives a better chance of clean shutdown
311      */
312     if (cioc->readfd != -1 &&
313         close(cioc->readfd) < 0) {
314         rv = -1;
315     }
316     if (cioc->writefd != -1 &&
317         cioc->writefd != cioc->readfd &&
318         close(cioc->writefd) < 0) {
319         rv = -1;
320     }
321     cioc->writefd = cioc->readfd = -1;
322 
323 #ifndef WIN32
324     do {
325         wp = waitpid(cioc->pid, NULL, 0);
326     } while (wp == (pid_t)-1 && errno == EINTR);
327     if (wp == (pid_t)-1) {
328         error_setg_errno(errp, errno, "Failed to wait for pid %llu",
329                          (unsigned long long)cioc->pid);
330         return -1;
331     }
332 #endif
333 
334     if (rv < 0) {
335         error_setg_errno(errp, errno, "%s",
336                          "Unable to close command");
337     }
338     return rv;
339 }
340 
341 
342 static void qio_channel_command_set_aio_fd_handler(QIOChannel *ioc,
343                                                    AioContext *ctx,
344                                                    IOHandler *io_read,
345                                                    IOHandler *io_write,
346                                                    void *opaque)
347 {
348     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
349     aio_set_fd_handler(ctx, cioc->readfd, false, io_read, NULL, NULL, opaque);
350     aio_set_fd_handler(ctx, cioc->writefd, false, NULL, io_write, NULL, opaque);
351 }
352 
353 
354 static GSource *qio_channel_command_create_watch(QIOChannel *ioc,
355                                                  GIOCondition condition)
356 {
357     QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc);
358     return qio_channel_create_fd_pair_watch(ioc,
359                                             cioc->readfd,
360                                             cioc->writefd,
361                                             condition);
362 }
363 
364 
365 static void qio_channel_command_class_init(ObjectClass *klass,
366                                            void *class_data G_GNUC_UNUSED)
367 {
368     QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);
369 
370     ioc_klass->io_writev = qio_channel_command_writev;
371     ioc_klass->io_readv = qio_channel_command_readv;
372     ioc_klass->io_set_blocking = qio_channel_command_set_blocking;
373     ioc_klass->io_close = qio_channel_command_close;
374     ioc_klass->io_create_watch = qio_channel_command_create_watch;
375     ioc_klass->io_set_aio_fd_handler = qio_channel_command_set_aio_fd_handler;
376 }
377 
378 static const TypeInfo qio_channel_command_info = {
379     .parent = TYPE_QIO_CHANNEL,
380     .name = TYPE_QIO_CHANNEL_COMMAND,
381     .instance_size = sizeof(QIOChannelCommand),
382     .instance_init = qio_channel_command_init,
383     .instance_finalize = qio_channel_command_finalize,
384     .class_init = qio_channel_command_class_init,
385 };
386 
387 static void qio_channel_command_register_types(void)
388 {
389     type_register_static(&qio_channel_command_info);
390 }
391 
392 type_init(qio_channel_command_register_types);
393