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 < 0) { 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 if (devnull != -1) { 102 close(devnull); 103 } 104 105 execv(argv[0], (char * const *)argv); 106 _exit(1); 107 } 108 109 if (!stdinnull) { 110 close(stdinfd[0]); 111 } 112 if (!stdoutnull) { 113 close(stdoutfd[1]); 114 } 115 116 ioc = qio_channel_command_new_pid(stdinnull ? devnull : stdinfd[1], 117 stdoutnull ? devnull : stdoutfd[0], 118 pid); 119 trace_qio_channel_command_new_spawn(ioc, argv[0], flags); 120 return ioc; 121 122 error: 123 if (devnull != -1) { 124 close(devnull); 125 } 126 if (stdinfd[0] != -1) { 127 close(stdinfd[0]); 128 } 129 if (stdinfd[1] != -1) { 130 close(stdinfd[1]); 131 } 132 if (stdoutfd[0] != -1) { 133 close(stdoutfd[0]); 134 } 135 if (stdoutfd[1] != -1) { 136 close(stdoutfd[1]); 137 } 138 return NULL; 139 } 140 141 #else /* WIN32 */ 142 QIOChannelCommand * 143 qio_channel_command_new_spawn(const char *const argv[], 144 int flags, 145 Error **errp) 146 { 147 error_setg_errno(errp, ENOSYS, 148 "Command spawn not supported on this platform"); 149 return NULL; 150 } 151 #endif /* WIN32 */ 152 153 #ifndef WIN32 154 static int qio_channel_command_abort(QIOChannelCommand *ioc, 155 Error **errp) 156 { 157 pid_t ret; 158 int status; 159 int step = 0; 160 161 /* See if intermediate process has exited; if not, try a nice 162 * SIGTERM followed by a more severe SIGKILL. 163 */ 164 rewait: 165 trace_qio_channel_command_abort(ioc, ioc->pid); 166 ret = waitpid(ioc->pid, &status, WNOHANG); 167 trace_qio_channel_command_wait(ioc, ioc->pid, ret, status); 168 if (ret == (pid_t)-1) { 169 if (errno == EINTR) { 170 goto rewait; 171 } else { 172 error_setg_errno(errp, errno, 173 "Cannot wait on pid %llu", 174 (unsigned long long)ioc->pid); 175 return -1; 176 } 177 } else if (ret == 0) { 178 if (step == 0) { 179 kill(ioc->pid, SIGTERM); 180 } else if (step == 1) { 181 kill(ioc->pid, SIGKILL); 182 } else { 183 error_setg(errp, 184 "Process %llu refused to die", 185 (unsigned long long)ioc->pid); 186 return -1; 187 } 188 step++; 189 usleep(10 * 1000); 190 goto rewait; 191 } 192 193 return 0; 194 } 195 #endif /* ! WIN32 */ 196 197 198 static void qio_channel_command_init(Object *obj) 199 { 200 QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj); 201 ioc->readfd = -1; 202 ioc->writefd = -1; 203 ioc->pid = -1; 204 } 205 206 static void qio_channel_command_finalize(Object *obj) 207 { 208 QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj); 209 if (ioc->readfd != -1) { 210 close(ioc->readfd); 211 } 212 if (ioc->writefd != -1 && 213 ioc->writefd != ioc->readfd) { 214 close(ioc->writefd); 215 } 216 ioc->writefd = ioc->readfd = -1; 217 if (ioc->pid > 0) { 218 #ifndef WIN32 219 qio_channel_command_abort(ioc, NULL); 220 #endif 221 } 222 } 223 224 225 static ssize_t qio_channel_command_readv(QIOChannel *ioc, 226 const struct iovec *iov, 227 size_t niov, 228 int **fds, 229 size_t *nfds, 230 Error **errp) 231 { 232 QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 233 ssize_t ret; 234 235 retry: 236 ret = readv(cioc->readfd, iov, niov); 237 if (ret < 0) { 238 if (errno == EAGAIN || 239 errno == EWOULDBLOCK) { 240 return QIO_CHANNEL_ERR_BLOCK; 241 } 242 if (errno == EINTR) { 243 goto retry; 244 } 245 246 error_setg_errno(errp, errno, 247 "Unable to read from command"); 248 return -1; 249 } 250 251 return ret; 252 } 253 254 static ssize_t qio_channel_command_writev(QIOChannel *ioc, 255 const struct iovec *iov, 256 size_t niov, 257 int *fds, 258 size_t nfds, 259 Error **errp) 260 { 261 QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 262 ssize_t ret; 263 264 retry: 265 ret = writev(cioc->writefd, iov, niov); 266 if (ret <= 0) { 267 if (errno == EAGAIN || 268 errno == EWOULDBLOCK) { 269 return QIO_CHANNEL_ERR_BLOCK; 270 } 271 if (errno == EINTR) { 272 goto retry; 273 } 274 error_setg_errno(errp, errno, "%s", 275 "Unable to write to command"); 276 return -1; 277 } 278 return ret; 279 } 280 281 static int qio_channel_command_set_blocking(QIOChannel *ioc, 282 bool enabled, 283 Error **errp) 284 { 285 QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 286 287 if (enabled) { 288 qemu_set_block(cioc->writefd); 289 qemu_set_block(cioc->readfd); 290 } else { 291 qemu_set_nonblock(cioc->writefd); 292 qemu_set_nonblock(cioc->readfd); 293 } 294 295 return 0; 296 } 297 298 299 static int qio_channel_command_close(QIOChannel *ioc, 300 Error **errp) 301 { 302 QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 303 int rv = 0; 304 305 /* We close FDs before killing, because that 306 * gives a better chance of clean shutdown 307 */ 308 if (cioc->readfd != -1 && 309 close(cioc->readfd) < 0) { 310 rv = -1; 311 } 312 if (cioc->writefd != -1 && 313 cioc->writefd != cioc->readfd && 314 close(cioc->writefd) < 0) { 315 rv = -1; 316 } 317 cioc->writefd = cioc->readfd = -1; 318 #ifndef WIN32 319 if (qio_channel_command_abort(cioc, errp) < 0) { 320 return -1; 321 } 322 #endif 323 if (rv < 0) { 324 error_setg_errno(errp, errno, "%s", 325 "Unable to close command"); 326 } 327 return rv; 328 } 329 330 331 static GSource *qio_channel_command_create_watch(QIOChannel *ioc, 332 GIOCondition condition) 333 { 334 QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 335 return qio_channel_create_fd_pair_watch(ioc, 336 cioc->readfd, 337 cioc->writefd, 338 condition); 339 } 340 341 342 static void qio_channel_command_class_init(ObjectClass *klass, 343 void *class_data G_GNUC_UNUSED) 344 { 345 QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); 346 347 ioc_klass->io_writev = qio_channel_command_writev; 348 ioc_klass->io_readv = qio_channel_command_readv; 349 ioc_klass->io_set_blocking = qio_channel_command_set_blocking; 350 ioc_klass->io_close = qio_channel_command_close; 351 ioc_klass->io_create_watch = qio_channel_command_create_watch; 352 } 353 354 static const TypeInfo qio_channel_command_info = { 355 .parent = TYPE_QIO_CHANNEL, 356 .name = TYPE_QIO_CHANNEL_COMMAND, 357 .instance_size = sizeof(QIOChannelCommand), 358 .instance_init = qio_channel_command_init, 359 .instance_finalize = qio_channel_command_finalize, 360 .class_init = qio_channel_command_class_init, 361 }; 362 363 static void qio_channel_command_register_types(void) 364 { 365 type_register_static(&qio_channel_command_info); 366 } 367 368 type_init(qio_channel_command_register_types); 369