1195e14d0SDaniel P. Berrange /* 2195e14d0SDaniel P. Berrange * QEMU I/O channels external command driver 3195e14d0SDaniel P. Berrange * 4195e14d0SDaniel P. Berrange * Copyright (c) 2015 Red Hat, Inc. 5195e14d0SDaniel P. Berrange * 6195e14d0SDaniel P. Berrange * This library is free software; you can redistribute it and/or 7195e14d0SDaniel P. Berrange * modify it under the terms of the GNU Lesser General Public 8195e14d0SDaniel P. Berrange * License as published by the Free Software Foundation; either 9c8198bd5SChetan Pant * version 2.1 of the License, or (at your option) any later version. 10195e14d0SDaniel P. Berrange * 11195e14d0SDaniel P. Berrange * This library is distributed in the hope that it will be useful, 12195e14d0SDaniel P. Berrange * but WITHOUT ANY WARRANTY; without even the implied warranty of 13195e14d0SDaniel P. Berrange * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14195e14d0SDaniel P. Berrange * Lesser General Public License for more details. 15195e14d0SDaniel P. Berrange * 16195e14d0SDaniel P. Berrange * You should have received a copy of the GNU Lesser General Public 17195e14d0SDaniel P. Berrange * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18195e14d0SDaniel P. Berrange * 19195e14d0SDaniel P. Berrange */ 20195e14d0SDaniel P. Berrange 21cae9fc56SPeter Maydell #include "qemu/osdep.h" 22195e14d0SDaniel P. Berrange #include "io/channel-command.h" 23195e14d0SDaniel P. Berrange #include "io/channel-watch.h" 24da34e65cSMarkus Armbruster #include "qapi/error.h" 250b8fa32fSMarkus Armbruster #include "qemu/module.h" 26195e14d0SDaniel P. Berrange #include "qemu/sockets.h" 27195e14d0SDaniel P. Berrange #include "trace.h" 28195e14d0SDaniel P. Berrange 2905e50e8fSMarc-André Lureau #ifndef WIN32 3005e50e8fSMarc-André Lureau /** 3105e50e8fSMarc-André Lureau * qio_channel_command_new_pid: 3205e50e8fSMarc-André Lureau * @writefd: the FD connected to the command's stdin 3305e50e8fSMarc-André Lureau * @readfd: the FD connected to the command's stdout 34*a95570e3SMarc-André Lureau * @pid: the PID/HANDLE of the running child command 3505e50e8fSMarc-André Lureau * @errp: pointer to a NULL-initialized error object 3605e50e8fSMarc-André Lureau * 3705e50e8fSMarc-André Lureau * Create a channel for performing I/O with the 3805e50e8fSMarc-André Lureau * previously spawned command identified by @pid. 3905e50e8fSMarc-André Lureau * The two file descriptors provide the connection 4005e50e8fSMarc-André Lureau * to command's stdio streams, either one or which 4105e50e8fSMarc-André Lureau * may be -1 to indicate that stream is not open. 4205e50e8fSMarc-André Lureau * 4305e50e8fSMarc-André Lureau * The channel will take ownership of the process 4405e50e8fSMarc-André Lureau * @pid and will kill it when closing the channel. 4505e50e8fSMarc-André Lureau * Similarly it will take responsibility for 4605e50e8fSMarc-André Lureau * closing the file descriptors @writefd and @readfd. 4705e50e8fSMarc-André Lureau * 4805e50e8fSMarc-André Lureau * Returns: the command channel object, or NULL on error 4905e50e8fSMarc-André Lureau */ 5005e50e8fSMarc-André Lureau static QIOChannelCommand * 51195e14d0SDaniel P. Berrange qio_channel_command_new_pid(int writefd, 52195e14d0SDaniel P. Berrange int readfd, 53*a95570e3SMarc-André Lureau GPid pid) 54195e14d0SDaniel P. Berrange { 55195e14d0SDaniel P. Berrange QIOChannelCommand *ioc; 56195e14d0SDaniel P. Berrange 57195e14d0SDaniel P. Berrange ioc = QIO_CHANNEL_COMMAND(object_new(TYPE_QIO_CHANNEL_COMMAND)); 58195e14d0SDaniel P. Berrange 59195e14d0SDaniel P. Berrange ioc->readfd = readfd; 60195e14d0SDaniel P. Berrange ioc->writefd = writefd; 61195e14d0SDaniel P. Berrange ioc->pid = pid; 62195e14d0SDaniel P. Berrange 63195e14d0SDaniel P. Berrange trace_qio_channel_command_new_pid(ioc, writefd, readfd, pid); 64195e14d0SDaniel P. Berrange return ioc; 65195e14d0SDaniel P. Berrange } 66195e14d0SDaniel P. Berrange 67195e14d0SDaniel P. Berrange QIOChannelCommand * 68195e14d0SDaniel P. Berrange qio_channel_command_new_spawn(const char *const argv[], 69195e14d0SDaniel P. Berrange int flags, 70195e14d0SDaniel P. Berrange Error **errp) 71195e14d0SDaniel P. Berrange { 72*a95570e3SMarc-André Lureau g_autoptr(GError) err = NULL; 73*a95570e3SMarc-André Lureau GPid pid = 0; 74*a95570e3SMarc-André Lureau GSpawnFlags gflags = G_SPAWN_CLOEXEC_PIPES | G_SPAWN_DO_NOT_REAP_CHILD; 75*a95570e3SMarc-André Lureau int stdinfd = -1, stdoutfd = -1; 76195e14d0SDaniel P. Berrange 77195e14d0SDaniel P. Berrange flags = flags & O_ACCMODE; 78*a95570e3SMarc-André Lureau gflags |= flags == O_WRONLY ? G_SPAWN_STDOUT_TO_DEV_NULL : 0; 79195e14d0SDaniel P. Berrange 80*a95570e3SMarc-André Lureau if (!g_spawn_async_with_pipes(NULL, (char **)argv, NULL, gflags, NULL, NULL, 81*a95570e3SMarc-André Lureau &pid, 82*a95570e3SMarc-André Lureau flags == O_RDONLY ? NULL : &stdinfd, 83*a95570e3SMarc-André Lureau flags == O_WRONLY ? NULL : &stdoutfd, 84*a95570e3SMarc-André Lureau NULL, &err)) { 85*a95570e3SMarc-André Lureau error_setg(errp, "%s", err->message); 86195e14d0SDaniel P. Berrange return NULL; 87195e14d0SDaniel P. Berrange } 88195e14d0SDaniel P. Berrange 89*a95570e3SMarc-André Lureau return qio_channel_command_new_pid(stdinfd, stdoutfd, pid); 90*a95570e3SMarc-André Lureau } 91*a95570e3SMarc-André Lureau 92195e14d0SDaniel P. Berrange #else /* WIN32 */ 93195e14d0SDaniel P. Berrange QIOChannelCommand * 94195e14d0SDaniel P. Berrange qio_channel_command_new_spawn(const char *const argv[], 95195e14d0SDaniel P. Berrange int flags, 96195e14d0SDaniel P. Berrange Error **errp) 97195e14d0SDaniel P. Berrange { 98195e14d0SDaniel P. Berrange error_setg_errno(errp, ENOSYS, 99195e14d0SDaniel P. Berrange "Command spawn not supported on this platform"); 100195e14d0SDaniel P. Berrange return NULL; 101195e14d0SDaniel P. Berrange } 102195e14d0SDaniel P. Berrange #endif /* WIN32 */ 103195e14d0SDaniel P. Berrange 104195e14d0SDaniel P. Berrange #ifndef WIN32 105195e14d0SDaniel P. Berrange static int qio_channel_command_abort(QIOChannelCommand *ioc, 106195e14d0SDaniel P. Berrange Error **errp) 107195e14d0SDaniel P. Berrange { 108195e14d0SDaniel P. Berrange pid_t ret; 109195e14d0SDaniel P. Berrange int status; 110195e14d0SDaniel P. Berrange int step = 0; 111195e14d0SDaniel P. Berrange 112195e14d0SDaniel P. Berrange /* See if intermediate process has exited; if not, try a nice 113195e14d0SDaniel P. Berrange * SIGTERM followed by a more severe SIGKILL. 114195e14d0SDaniel P. Berrange */ 115195e14d0SDaniel P. Berrange rewait: 116195e14d0SDaniel P. Berrange trace_qio_channel_command_abort(ioc, ioc->pid); 117195e14d0SDaniel P. Berrange ret = waitpid(ioc->pid, &status, WNOHANG); 118195e14d0SDaniel P. Berrange trace_qio_channel_command_wait(ioc, ioc->pid, ret, status); 119195e14d0SDaniel P. Berrange if (ret == (pid_t)-1) { 120195e14d0SDaniel P. Berrange if (errno == EINTR) { 121195e14d0SDaniel P. Berrange goto rewait; 122195e14d0SDaniel P. Berrange } else { 123195e14d0SDaniel P. Berrange error_setg_errno(errp, errno, 124195e14d0SDaniel P. Berrange "Cannot wait on pid %llu", 125195e14d0SDaniel P. Berrange (unsigned long long)ioc->pid); 126195e14d0SDaniel P. Berrange return -1; 127195e14d0SDaniel P. Berrange } 128195e14d0SDaniel P. Berrange } else if (ret == 0) { 129195e14d0SDaniel P. Berrange if (step == 0) { 130195e14d0SDaniel P. Berrange kill(ioc->pid, SIGTERM); 131195e14d0SDaniel P. Berrange } else if (step == 1) { 132195e14d0SDaniel P. Berrange kill(ioc->pid, SIGKILL); 133195e14d0SDaniel P. Berrange } else { 134195e14d0SDaniel P. Berrange error_setg(errp, 135195e14d0SDaniel P. Berrange "Process %llu refused to die", 136195e14d0SDaniel P. Berrange (unsigned long long)ioc->pid); 137195e14d0SDaniel P. Berrange return -1; 138195e14d0SDaniel P. Berrange } 1390c0a55b2SDaniel P. Berrange step++; 140195e14d0SDaniel P. Berrange usleep(10 * 1000); 141195e14d0SDaniel P. Berrange goto rewait; 142195e14d0SDaniel P. Berrange } 143195e14d0SDaniel P. Berrange 144195e14d0SDaniel P. Berrange return 0; 145195e14d0SDaniel P. Berrange } 146195e14d0SDaniel P. Berrange #endif /* ! WIN32 */ 147195e14d0SDaniel P. Berrange 148195e14d0SDaniel P. Berrange 149195e14d0SDaniel P. Berrange static void qio_channel_command_init(Object *obj) 150195e14d0SDaniel P. Berrange { 151195e14d0SDaniel P. Berrange QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj); 152195e14d0SDaniel P. Berrange ioc->readfd = -1; 153195e14d0SDaniel P. Berrange ioc->writefd = -1; 154*a95570e3SMarc-André Lureau ioc->pid = 0; 155195e14d0SDaniel P. Berrange } 156195e14d0SDaniel P. Berrange 157195e14d0SDaniel P. Berrange static void qio_channel_command_finalize(Object *obj) 158195e14d0SDaniel P. Berrange { 159195e14d0SDaniel P. Berrange QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj); 160195e14d0SDaniel P. Berrange if (ioc->readfd != -1) { 161195e14d0SDaniel P. Berrange close(ioc->readfd); 162195e14d0SDaniel P. Berrange } 163e155494cSDaniel P. Berrange if (ioc->writefd != -1 && 164e155494cSDaniel P. Berrange ioc->writefd != ioc->readfd) { 165195e14d0SDaniel P. Berrange close(ioc->writefd); 166195e14d0SDaniel P. Berrange } 167e155494cSDaniel P. Berrange ioc->writefd = ioc->readfd = -1; 168195e14d0SDaniel P. Berrange if (ioc->pid > 0) { 169195e14d0SDaniel P. Berrange #ifndef WIN32 170195e14d0SDaniel P. Berrange qio_channel_command_abort(ioc, NULL); 171195e14d0SDaniel P. Berrange #endif 172*a95570e3SMarc-André Lureau g_spawn_close_pid(ioc->pid); 173195e14d0SDaniel P. Berrange } 174195e14d0SDaniel P. Berrange } 175195e14d0SDaniel P. Berrange 176195e14d0SDaniel P. Berrange 177195e14d0SDaniel P. Berrange static ssize_t qio_channel_command_readv(QIOChannel *ioc, 178195e14d0SDaniel P. Berrange const struct iovec *iov, 179195e14d0SDaniel P. Berrange size_t niov, 180195e14d0SDaniel P. Berrange int **fds, 181195e14d0SDaniel P. Berrange size_t *nfds, 182195e14d0SDaniel P. Berrange Error **errp) 183195e14d0SDaniel P. Berrange { 184195e14d0SDaniel P. Berrange QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 185195e14d0SDaniel P. Berrange ssize_t ret; 186195e14d0SDaniel P. Berrange 187195e14d0SDaniel P. Berrange retry: 188195e14d0SDaniel P. Berrange ret = readv(cioc->readfd, iov, niov); 189195e14d0SDaniel P. Berrange if (ret < 0) { 19030fd3e27SDaniel P. Berrange if (errno == EAGAIN) { 191195e14d0SDaniel P. Berrange return QIO_CHANNEL_ERR_BLOCK; 192195e14d0SDaniel P. Berrange } 193195e14d0SDaniel P. Berrange if (errno == EINTR) { 194195e14d0SDaniel P. Berrange goto retry; 195195e14d0SDaniel P. Berrange } 196195e14d0SDaniel P. Berrange 197195e14d0SDaniel P. Berrange error_setg_errno(errp, errno, 198195e14d0SDaniel P. Berrange "Unable to read from command"); 199195e14d0SDaniel P. Berrange return -1; 200195e14d0SDaniel P. Berrange } 201195e14d0SDaniel P. Berrange 202195e14d0SDaniel P. Berrange return ret; 203195e14d0SDaniel P. Berrange } 204195e14d0SDaniel P. Berrange 205195e14d0SDaniel P. Berrange static ssize_t qio_channel_command_writev(QIOChannel *ioc, 206195e14d0SDaniel P. Berrange const struct iovec *iov, 207195e14d0SDaniel P. Berrange size_t niov, 208195e14d0SDaniel P. Berrange int *fds, 209195e14d0SDaniel P. Berrange size_t nfds, 210b88651cbSLeonardo Bras int flags, 211195e14d0SDaniel P. Berrange Error **errp) 212195e14d0SDaniel P. Berrange { 213195e14d0SDaniel P. Berrange QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 214195e14d0SDaniel P. Berrange ssize_t ret; 215195e14d0SDaniel P. Berrange 216195e14d0SDaniel P. Berrange retry: 217195e14d0SDaniel P. Berrange ret = writev(cioc->writefd, iov, niov); 218195e14d0SDaniel P. Berrange if (ret <= 0) { 21930fd3e27SDaniel P. Berrange if (errno == EAGAIN) { 220195e14d0SDaniel P. Berrange return QIO_CHANNEL_ERR_BLOCK; 221195e14d0SDaniel P. Berrange } 222195e14d0SDaniel P. Berrange if (errno == EINTR) { 223195e14d0SDaniel P. Berrange goto retry; 224195e14d0SDaniel P. Berrange } 225195e14d0SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 226195e14d0SDaniel P. Berrange "Unable to write to command"); 227195e14d0SDaniel P. Berrange return -1; 228195e14d0SDaniel P. Berrange } 229195e14d0SDaniel P. Berrange return ret; 230195e14d0SDaniel P. Berrange } 231195e14d0SDaniel P. Berrange 232195e14d0SDaniel P. Berrange static int qio_channel_command_set_blocking(QIOChannel *ioc, 233195e14d0SDaniel P. Berrange bool enabled, 234195e14d0SDaniel P. Berrange Error **errp) 235195e14d0SDaniel P. Berrange { 23617fc1245SMarc-André Lureau #ifdef WIN32 23717fc1245SMarc-André Lureau /* command spawn is not supported on win32 */ 23817fc1245SMarc-André Lureau g_assert_not_reached(); 23917fc1245SMarc-André Lureau #else 240195e14d0SDaniel P. Berrange QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 241195e14d0SDaniel P. Berrange 24217fc1245SMarc-André Lureau if (!g_unix_set_fd_nonblocking(cioc->writefd, !enabled, NULL) || 24317fc1245SMarc-André Lureau !g_unix_set_fd_nonblocking(cioc->readfd, !enabled, NULL)) { 24417fc1245SMarc-André Lureau error_setg_errno(errp, errno, "Failed to set FD nonblocking"); 24517fc1245SMarc-André Lureau return -1; 246195e14d0SDaniel P. Berrange } 24717fc1245SMarc-André Lureau #endif 248195e14d0SDaniel P. Berrange return 0; 249195e14d0SDaniel P. Berrange } 250195e14d0SDaniel P. Berrange 251195e14d0SDaniel P. Berrange 252195e14d0SDaniel P. Berrange static int qio_channel_command_close(QIOChannel *ioc, 253195e14d0SDaniel P. Berrange Error **errp) 254195e14d0SDaniel P. Berrange { 255195e14d0SDaniel P. Berrange QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 256195e14d0SDaniel P. Berrange int rv = 0; 257fe823b6fSThomas Huth #ifndef WIN32 258fe823b6fSThomas Huth pid_t wp; 259fe823b6fSThomas Huth #endif 260195e14d0SDaniel P. Berrange 261195e14d0SDaniel P. Berrange /* We close FDs before killing, because that 262195e14d0SDaniel P. Berrange * gives a better chance of clean shutdown 263195e14d0SDaniel P. Berrange */ 264e155494cSDaniel P. Berrange if (cioc->readfd != -1 && 265e155494cSDaniel P. Berrange close(cioc->readfd) < 0) { 266195e14d0SDaniel P. Berrange rv = -1; 267195e14d0SDaniel P. Berrange } 268e155494cSDaniel P. Berrange if (cioc->writefd != -1 && 269e155494cSDaniel P. Berrange cioc->writefd != cioc->readfd && 270e155494cSDaniel P. Berrange close(cioc->writefd) < 0) { 271195e14d0SDaniel P. Berrange rv = -1; 272195e14d0SDaniel P. Berrange } 273e155494cSDaniel P. Berrange cioc->writefd = cioc->readfd = -1; 274fe823b6fSThomas Huth 275195e14d0SDaniel P. Berrange #ifndef WIN32 276fe823b6fSThomas Huth do { 277fe823b6fSThomas Huth wp = waitpid(cioc->pid, NULL, 0); 278fe823b6fSThomas Huth } while (wp == (pid_t)-1 && errno == EINTR); 279fe823b6fSThomas Huth if (wp == (pid_t)-1) { 280fe823b6fSThomas Huth error_setg_errno(errp, errno, "Failed to wait for pid %llu", 281fe823b6fSThomas Huth (unsigned long long)cioc->pid); 282195e14d0SDaniel P. Berrange return -1; 283195e14d0SDaniel P. Berrange } 284195e14d0SDaniel P. Berrange #endif 285fe823b6fSThomas Huth 286195e14d0SDaniel P. Berrange if (rv < 0) { 287195e14d0SDaniel P. Berrange error_setg_errno(errp, errno, "%s", 288195e14d0SDaniel P. Berrange "Unable to close command"); 289195e14d0SDaniel P. Berrange } 290195e14d0SDaniel P. Berrange return rv; 291195e14d0SDaniel P. Berrange } 292195e14d0SDaniel P. Berrange 293195e14d0SDaniel P. Berrange 294bf88c124SPaolo Bonzini static void qio_channel_command_set_aio_fd_handler(QIOChannel *ioc, 295bf88c124SPaolo Bonzini AioContext *ctx, 296bf88c124SPaolo Bonzini IOHandler *io_read, 297bf88c124SPaolo Bonzini IOHandler *io_write, 298bf88c124SPaolo Bonzini void *opaque) 299bf88c124SPaolo Bonzini { 300bf88c124SPaolo Bonzini QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 301826cc324SStefan Hajnoczi aio_set_fd_handler(ctx, cioc->readfd, false, 302826cc324SStefan Hajnoczi io_read, NULL, NULL, NULL, opaque); 303826cc324SStefan Hajnoczi aio_set_fd_handler(ctx, cioc->writefd, false, 304826cc324SStefan Hajnoczi NULL, io_write, NULL, NULL, opaque); 305bf88c124SPaolo Bonzini } 306bf88c124SPaolo Bonzini 307bf88c124SPaolo Bonzini 308195e14d0SDaniel P. Berrange static GSource *qio_channel_command_create_watch(QIOChannel *ioc, 309195e14d0SDaniel P. Berrange GIOCondition condition) 310195e14d0SDaniel P. Berrange { 311195e14d0SDaniel P. Berrange QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); 312195e14d0SDaniel P. Berrange return qio_channel_create_fd_pair_watch(ioc, 313195e14d0SDaniel P. Berrange cioc->readfd, 314195e14d0SDaniel P. Berrange cioc->writefd, 315195e14d0SDaniel P. Berrange condition); 316195e14d0SDaniel P. Berrange } 317195e14d0SDaniel P. Berrange 318195e14d0SDaniel P. Berrange 319195e14d0SDaniel P. Berrange static void qio_channel_command_class_init(ObjectClass *klass, 320195e14d0SDaniel P. Berrange void *class_data G_GNUC_UNUSED) 321195e14d0SDaniel P. Berrange { 322195e14d0SDaniel P. Berrange QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass); 323195e14d0SDaniel P. Berrange 324195e14d0SDaniel P. Berrange ioc_klass->io_writev = qio_channel_command_writev; 325195e14d0SDaniel P. Berrange ioc_klass->io_readv = qio_channel_command_readv; 326195e14d0SDaniel P. Berrange ioc_klass->io_set_blocking = qio_channel_command_set_blocking; 327195e14d0SDaniel P. Berrange ioc_klass->io_close = qio_channel_command_close; 328195e14d0SDaniel P. Berrange ioc_klass->io_create_watch = qio_channel_command_create_watch; 329bf88c124SPaolo Bonzini ioc_klass->io_set_aio_fd_handler = qio_channel_command_set_aio_fd_handler; 330195e14d0SDaniel P. Berrange } 331195e14d0SDaniel P. Berrange 332195e14d0SDaniel P. Berrange static const TypeInfo qio_channel_command_info = { 333195e14d0SDaniel P. Berrange .parent = TYPE_QIO_CHANNEL, 334195e14d0SDaniel P. Berrange .name = TYPE_QIO_CHANNEL_COMMAND, 335195e14d0SDaniel P. Berrange .instance_size = sizeof(QIOChannelCommand), 336195e14d0SDaniel P. Berrange .instance_init = qio_channel_command_init, 337195e14d0SDaniel P. Berrange .instance_finalize = qio_channel_command_finalize, 338195e14d0SDaniel P. Berrange .class_init = qio_channel_command_class_init, 339195e14d0SDaniel P. Berrange }; 340195e14d0SDaniel P. Berrange 341195e14d0SDaniel P. Berrange static void qio_channel_command_register_types(void) 342195e14d0SDaniel P. Berrange { 343195e14d0SDaniel P. Berrange type_register_static(&qio_channel_command_info); 344195e14d0SDaniel P. Berrange } 345195e14d0SDaniel P. Berrange 346195e14d0SDaniel P. Berrange type_init(qio_channel_command_register_types); 347