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