/*
 * Privileged helper to handle persistent reservation commands for QEMU
 *
 * Copyright (C) 2017 Red Hat, Inc. <pbonzini@redhat.com>
 *
 * Author: Paolo Bonzini <pbonzini@redhat.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; under version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include <getopt.h>
#include <sys/ioctl.h>
#include <linux/dm-ioctl.h>
#include <scsi/sg.h>

#ifdef CONFIG_LIBCAP_NG
#include <cap-ng.h>
#endif
#include <pwd.h>
#include <grp.h>

#ifdef CONFIG_MPATH
#include <libudev.h>
#include <mpath_cmd.h>
#include <mpath_persist.h>
#endif

#include "qemu-common.h"
#include "qapi/error.h"
#include "qemu/cutils.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qemu/config-file.h"
#include "qemu/bswap.h"
#include "qemu/log.h"
#include "qemu/systemd.h"
#include "qapi/util.h"
#include "qapi/qmp/qstring.h"
#include "io/channel-socket.h"
#include "trace/control.h"
#include "qemu-version.h"

#include "block/aio.h"
#include "block/thread-pool.h"

#include "scsi/constants.h"
#include "scsi/utils.h"
#include "pr-helper.h"

#define PR_OUT_FIXED_PARAM_SIZE 24

static char *socket_path;
static char *pidfile;
static enum { RUNNING, TERMINATE, TERMINATING } state;
static QIOChannelSocket *server_ioc;
static int server_watch;
static int num_active_sockets = 1;
static int noisy;
static int verbose;

#ifdef CONFIG_LIBCAP_NG
static int uid = -1;
static int gid = -1;
#endif

static void compute_default_paths(void)
{
    socket_path = qemu_get_local_state_pathname("run/qemu-pr-helper.sock");
    pidfile = qemu_get_local_state_pathname("run/qemu-pr-helper.pid");
}

static void usage(const char *name)
{
    (printf) (
"Usage: %s [OPTIONS] FILE\n"
"Persistent Reservation helper program for QEMU\n"
"\n"
"  -h, --help                display this help and exit\n"
"  -V, --version             output version information and exit\n"
"\n"
"  -d, --daemon              run in the background\n"
"  -f, --pidfile=PATH        PID file when running as a daemon\n"
"                            (default '%s')\n"
"  -k, --socket=PATH         path to the unix socket\n"
"                            (default '%s')\n"
"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
"                            specify tracing options\n"
#ifdef CONFIG_LIBCAP_NG
"  -u, --user=USER           user to drop privileges to\n"
"  -g, --group=GROUP         group to drop privileges to\n"
#endif
"\n"
QEMU_HELP_BOTTOM "\n"
    , name, pidfile, socket_path);
}

static void version(const char *name)
{
    printf(
"%s " QEMU_FULL_VERSION "\n"
"Written by Paolo Bonzini.\n"
"\n"
QEMU_COPYRIGHT "\n"
"This is free software; see the source for copying conditions.  There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
    , name);
}

/* SG_IO support */

typedef struct PRHelperSGIOData {
    int fd;
    const uint8_t *cdb;
    uint8_t *sense;
    uint8_t *buf;
    int sz;              /* input/output */
    int dir;
} PRHelperSGIOData;

static int do_sgio_worker(void *opaque)
{
    PRHelperSGIOData *data = opaque;
    struct sg_io_hdr io_hdr;
    int ret;
    int status;
    SCSISense sense_code;

    memset(data->sense, 0, PR_HELPER_SENSE_SIZE);
    memset(&io_hdr, 0, sizeof(io_hdr));
    io_hdr.interface_id = 'S';
    io_hdr.cmd_len = PR_HELPER_CDB_SIZE;
    io_hdr.cmdp = (uint8_t *)data->cdb;
    io_hdr.sbp = data->sense;
    io_hdr.mx_sb_len = PR_HELPER_SENSE_SIZE;
    io_hdr.timeout = 1;
    io_hdr.dxfer_direction = data->dir;
    io_hdr.dxferp = (char *)data->buf;
    io_hdr.dxfer_len = data->sz;
    ret = ioctl(data->fd, SG_IO, &io_hdr);
    status = sg_io_sense_from_errno(ret < 0 ? errno : 0, &io_hdr,
                                    &sense_code);
    if (status == GOOD) {
        data->sz -= io_hdr.resid;
    } else {
        data->sz = 0;
    }

    if (status == CHECK_CONDITION &&
        !(io_hdr.driver_status & SG_ERR_DRIVER_SENSE)) {
        scsi_build_sense(data->sense, sense_code);
    }

    return status;
}

static int do_sgio(int fd, const uint8_t *cdb, uint8_t *sense,
                    uint8_t *buf, int *sz, int dir)
{
    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
    int r;

    PRHelperSGIOData data = {
        .fd = fd,
        .cdb = cdb,
        .sense = sense,
        .buf = buf,
        .sz = *sz,
        .dir = dir,
    };

    r = thread_pool_submit_co(pool, do_sgio_worker, &data);
    *sz = data.sz;
    return r;
}

/* Device mapper interface */

#ifdef CONFIG_MPATH
#define CONTROL_PATH "/dev/mapper/control"

typedef struct DMData {
    struct dm_ioctl dm;
    uint8_t data[1024];
} DMData;

static int control_fd;

static void *dm_ioctl(int ioc, struct dm_ioctl *dm)
{
    static DMData d;
    memcpy(&d.dm, dm, sizeof(d.dm));
    QEMU_BUILD_BUG_ON(sizeof(d.data) < sizeof(struct dm_target_spec));

    d.dm.version[0] = DM_VERSION_MAJOR;
    d.dm.version[1] = 0;
    d.dm.version[2] = 0;
    d.dm.data_size = 1024;
    d.dm.data_start = offsetof(DMData, data);
    if (ioctl(control_fd, ioc, &d) < 0) {
        return NULL;
    }
    memcpy(dm, &d.dm, sizeof(d.dm));
    return &d.data;
}

static void *dm_dev_ioctl(int fd, int ioc, struct dm_ioctl *dm)
{
    struct stat st;
    int r;

    r = fstat(fd, &st);
    if (r < 0) {
        perror("fstat");
        exit(1);
    }

    dm->dev = st.st_rdev;
    return dm_ioctl(ioc, dm);
}

static void dm_init(void)
{
    control_fd = open(CONTROL_PATH, O_RDWR);
    if (control_fd < 0) {
        perror("Cannot open " CONTROL_PATH);
        exit(1);
    }
    struct dm_ioctl dm = { };
    if (!dm_ioctl(DM_VERSION, &dm)) {
        perror("ioctl");
        exit(1);
    }
    if (dm.version[0] != DM_VERSION_MAJOR) {
        fprintf(stderr, "Unsupported device mapper interface");
        exit(1);
    }
}

/* Variables required by libmultipath and libmpathpersist.  */
QEMU_BUILD_BUG_ON(PR_HELPER_DATA_SIZE > MPATH_MAX_PARAM_LEN);
static struct config *multipath_conf;
unsigned mpath_mx_alloc_len = PR_HELPER_DATA_SIZE;
int logsink;
struct udev *udev;

extern struct config *get_multipath_config(void);
struct config *get_multipath_config(void)
{
    return multipath_conf;
}

extern void put_multipath_config(struct config *conf);
void put_multipath_config(struct config *conf)
{
}

static void multipath_pr_init(void)
{
    udev = udev_new();
#ifdef CONFIG_MPATH_NEW_API
    multipath_conf = mpath_lib_init();
#else
    mpath_lib_init(udev);
#endif
}

static int is_mpath(int fd)
{
    struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG };
    struct dm_target_spec *tgt;

    tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm);
    if (!tgt) {
        if (errno == ENXIO) {
            return 0;
        }
        perror("ioctl");
        exit(EXIT_FAILURE);
    }
    return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
}

static SCSISense mpath_generic_sense(int r)
{
    switch (r) {
    case MPATH_PR_SENSE_NOT_READY:
         return SENSE_CODE(NOT_READY);
    case MPATH_PR_SENSE_MEDIUM_ERROR:
         return SENSE_CODE(READ_ERROR);
    case MPATH_PR_SENSE_HARDWARE_ERROR:
         return SENSE_CODE(TARGET_FAILURE);
    case MPATH_PR_SENSE_ABORTED_COMMAND:
         return SENSE_CODE(IO_ERROR);
    default:
         abort();
    }
}

static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
{
    switch (r) {
    case MPATH_PR_SUCCESS:
        return GOOD;
    case MPATH_PR_SENSE_NOT_READY:
    case MPATH_PR_SENSE_MEDIUM_ERROR:
    case MPATH_PR_SENSE_HARDWARE_ERROR:
    case MPATH_PR_SENSE_ABORTED_COMMAND:
        {
            /* libmpathpersist ate the exact sense.  Try to find it by
             * issuing TEST UNIT READY.
             */
            uint8_t cdb[6] = { TEST_UNIT_READY };
            int sz = 0;
            int ret = do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);

            if (ret != GOOD) {
                return ret;
            }
            scsi_build_sense(sense, mpath_generic_sense(r));
            return CHECK_CONDITION;
        }

    case MPATH_PR_SENSE_UNIT_ATTENTION:
        /* Congratulations libmpathpersist, you ruined the Unit Attention...
         * Return a heavyweight one.
         */
        scsi_build_sense(sense, SENSE_CODE(SCSI_BUS_RESET));
        return CHECK_CONDITION;
    case MPATH_PR_SENSE_INVALID_OP:
        /* Only one valid sense.  */
        scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
        return CHECK_CONDITION;
    case MPATH_PR_ILLEGAL_REQ:
        /* Guess.  */
        scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
        return CHECK_CONDITION;
    case MPATH_PR_NO_SENSE:
        scsi_build_sense(sense, SENSE_CODE(NO_SENSE));
        return CHECK_CONDITION;

    case MPATH_PR_RESERV_CONFLICT:
        return RESERVATION_CONFLICT;

    case MPATH_PR_OTHER:
    default:
        scsi_build_sense(sense, SENSE_CODE(LUN_COMM_FAILURE));
        return CHECK_CONDITION;
    }
}

static int multipath_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
                           uint8_t *data, int sz)
{
    int rq_servact = cdb[1];
    struct prin_resp resp;
    size_t written;
    int r;

    switch (rq_servact) {
    case MPATH_PRIN_RKEY_SA:
    case MPATH_PRIN_RRES_SA:
    case MPATH_PRIN_RCAP_SA:
        break;
    case MPATH_PRIN_RFSTAT_SA:
        /* Nobody implements it anyway, so bail out. */
    default:
        /* Cannot parse any other output.  */
        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
        return CHECK_CONDITION;
    }

    r = mpath_persistent_reserve_in(fd, rq_servact, &resp, noisy, verbose);
    if (r == MPATH_PR_SUCCESS) {
        switch (rq_servact) {
        case MPATH_PRIN_RKEY_SA:
        case MPATH_PRIN_RRES_SA: {
            struct prin_readdescr *out = &resp.prin_descriptor.prin_readkeys;
            assert(sz >= 8);
            written = MIN(out->additional_length + 8, sz);
            stl_be_p(&data[0], out->prgeneration);
            stl_be_p(&data[4], out->additional_length);
            memcpy(&data[8], out->key_list, written - 8);
            break;
        }
        case MPATH_PRIN_RCAP_SA: {
            struct prin_capdescr *out = &resp.prin_descriptor.prin_readcap;
            assert(sz >= 6);
            written = 6;
            stw_be_p(&data[0], out->length);
            data[2] = out->flags[0];
            data[3] = out->flags[1];
            stw_be_p(&data[4], out->pr_type_mask);
            break;
        }
        default:
            scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
            return CHECK_CONDITION;
        }
        assert(written <= sz);
        memset(data + written, 0, sz - written);
    }

    return mpath_reconstruct_sense(fd, r, sense);
}

static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
                            const uint8_t *param, int sz)
{
    int rq_servact = cdb[1];
    int rq_scope = cdb[2] >> 4;
    int rq_type = cdb[2] & 0xf;
    g_autofree struct prout_param_descriptor *paramp = NULL;
    char transportids[PR_HELPER_DATA_SIZE];
    int r;

    paramp = g_malloc0(sizeof(struct prout_param_descriptor)
                       + sizeof(struct transportid *) * MPATH_MX_TIDS);

    if (sz < PR_OUT_FIXED_PARAM_SIZE) {
        /* Illegal request, Parameter list length error.  This isn't fatal;
         * we have read the data, send an error without closing the socket.
         */
        scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM_LEN));
        return CHECK_CONDITION;
    }

    switch (rq_servact) {
    case MPATH_PROUT_REG_SA:
    case MPATH_PROUT_RES_SA:
    case MPATH_PROUT_REL_SA:
    case MPATH_PROUT_CLEAR_SA:
    case MPATH_PROUT_PREE_SA:
    case MPATH_PROUT_PREE_AB_SA:
    case MPATH_PROUT_REG_IGN_SA:
        break;
    case MPATH_PROUT_REG_MOV_SA:
        /* Not supported by struct prout_param_descriptor.  */
    default:
        /* Cannot parse any other input.  */
        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
        return CHECK_CONDITION;
    }

    /* Convert input data, especially transport IDs, to the structs
     * used by libmpathpersist (which, of course, will immediately
     * do the opposite).
     */
    memcpy(&paramp->key, &param[0], 8);
    memcpy(&paramp->sa_key, &param[8], 8);
    paramp->sa_flags = param[20];
    if (sz > PR_OUT_FIXED_PARAM_SIZE) {
        size_t transportid_len;
        int i, j;
        if (sz < PR_OUT_FIXED_PARAM_SIZE + 4) {
            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM_LEN));
            return CHECK_CONDITION;
        }
        transportid_len = ldl_be_p(&param[24]) + PR_OUT_FIXED_PARAM_SIZE + 4;
        if (transportid_len > sz) {
            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
            return CHECK_CONDITION;
        }
        for (i = PR_OUT_FIXED_PARAM_SIZE + 4, j = 0; i < transportid_len; ) {
            struct transportid *id = (struct transportid *) &transportids[j];
            int len;

            id->format_code = param[i] & 0xc0;
            id->protocol_id = param[i] & 0x0f;
            switch (param[i] & 0xcf) {
            case 0:
                /* FC transport.  */
                if (i + 24 > transportid_len) {
                    goto illegal_req;
                }
                memcpy(id->n_port_name, &param[i + 8], 8);
                j += offsetof(struct transportid, n_port_name[8]);
                i += 24;
                break;
            case 5:
            case 0x45:
                /* iSCSI transport.  */
                len = lduw_be_p(&param[i + 2]);
                if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {
                    /* For format code 00, the standard says the maximum is 223
                     * plus the NUL terminator.  For format code 01 there is no
                     * maximum length, but libmpathpersist ignores the first
                     * byte of id->iscsi_name so our maximum is 252.
                     */
                    goto illegal_req;
                }
                if (memchr(&param[i + 4], 0, len) == NULL) {
                    goto illegal_req;
                }
                memcpy(id->iscsi_name, &param[i + 2], len + 2);
                j += offsetof(struct transportid, iscsi_name[len + 2]);
                i += len + 4;
                break;
            case 6:
                /* SAS transport.  */
                if (i + 24 > transportid_len) {
                    goto illegal_req;
                }
                memcpy(id->sas_address, &param[i + 4], 8);
                j += offsetof(struct transportid, sas_address[8]);
                i += 24;
                break;
            default:
            illegal_req:
                scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
                return CHECK_CONDITION;
            }

            assert(paramp->num_transportid < MPATH_MX_TIDS);
            paramp->trnptid_list[paramp->num_transportid++] = id;
        }
    }

    r = mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type,
                                     paramp, noisy, verbose);
    return mpath_reconstruct_sense(fd, r, sense);
}
#endif

static int do_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
                    uint8_t *data, int *resp_sz)
{
#ifdef CONFIG_MPATH
    if (is_mpath(fd)) {
        /* multipath_pr_in fills the whole input buffer.  */
        int r = multipath_pr_in(fd, cdb, sense, data, *resp_sz);
        if (r != GOOD) {
            *resp_sz = 0;
        }
        return r;
    }
#endif

    return do_sgio(fd, cdb, sense, data, resp_sz,
                   SG_DXFER_FROM_DEV);
}

static int do_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
                     const uint8_t *param, int sz)
{
    int resp_sz;

    if ((fcntl(fd, F_GETFL) & O_ACCMODE) == O_RDONLY) {
        scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
        return CHECK_CONDITION;
    }

#ifdef CONFIG_MPATH
    if (is_mpath(fd)) {
        return multipath_pr_out(fd, cdb, sense, param, sz);
    }
#endif

    resp_sz = sz;
    return do_sgio(fd, cdb, sense, (uint8_t *)param, &resp_sz,
                   SG_DXFER_TO_DEV);
}

/* Client */

typedef struct PRHelperClient {
    QIOChannelSocket *ioc;
    Coroutine *co;
    int fd;
    uint8_t data[PR_HELPER_DATA_SIZE];
} PRHelperClient;

typedef struct PRHelperRequest {
    int fd;
    size_t sz;
    uint8_t cdb[PR_HELPER_CDB_SIZE];
} PRHelperRequest;

static int coroutine_fn prh_read(PRHelperClient *client, void *buf, int sz,
                                 Error **errp)
{
    int ret = 0;

    while (sz > 0) {
        int *fds = NULL;
        size_t nfds = 0;
        int i;
        struct iovec iov;
        ssize_t n_read;

        iov.iov_base = buf;
        iov.iov_len = sz;
        n_read = qio_channel_readv_full(QIO_CHANNEL(client->ioc), &iov, 1,
                                        &fds, &nfds, errp);

        if (n_read == QIO_CHANNEL_ERR_BLOCK) {
            qio_channel_yield(QIO_CHANNEL(client->ioc), G_IO_IN);
            continue;
        }
        if (n_read <= 0) {
            ret = n_read ? n_read : -1;
            goto err;
        }

        /* Stash one file descriptor per request.  */
        if (nfds) {
            bool too_many = false;
            for (i = 0; i < nfds; i++) {
                if (client->fd == -1) {
                    client->fd = fds[i];
                } else {
                    close(fds[i]);
                    too_many = true;
                }
            }
            g_free(fds);
            if (too_many) {
                ret = -1;
                goto err;
            }
        }

        buf += n_read;
        sz -= n_read;
    }

    return 0;

err:
    if (client->fd != -1) {
        close(client->fd);
        client->fd = -1;
    }
    return ret;
}

static int coroutine_fn prh_read_request(PRHelperClient *client,
                                         PRHelperRequest *req,
                                         PRHelperResponse *resp, Error **errp)
{
    uint32_t sz;

    if (prh_read(client, req->cdb, sizeof(req->cdb), NULL) < 0) {
        return -1;
    }

    if (client->fd == -1) {
        error_setg(errp, "No file descriptor in request.");
        return -1;
    }

    if (req->cdb[0] != PERSISTENT_RESERVE_OUT &&
        req->cdb[0] != PERSISTENT_RESERVE_IN) {
        error_setg(errp, "Invalid CDB, closing socket.");
        goto out_close;
    }

    sz = scsi_cdb_xfer(req->cdb);
    if (sz > sizeof(client->data)) {
        goto out_close;
    }

    if (req->cdb[0] == PERSISTENT_RESERVE_OUT) {
        if (qio_channel_read_all(QIO_CHANNEL(client->ioc),
                                 (char *)client->data, sz,
                                 errp) < 0) {
            goto out_close;
        }
    }

    req->fd = client->fd;
    req->sz = sz;
    client->fd = -1;
    return sz;

out_close:
    close(client->fd);
    client->fd = -1;
    return -1;
}

static int coroutine_fn prh_write_response(PRHelperClient *client,
                                           PRHelperRequest *req,
                                           PRHelperResponse *resp, Error **errp)
{
    ssize_t r;
    size_t sz;

    if (req->cdb[0] == PERSISTENT_RESERVE_IN && resp->result == GOOD) {
        assert(resp->sz <= req->sz && resp->sz <= sizeof(client->data));
    } else {
        assert(resp->sz == 0);
    }

    sz = resp->sz;

    resp->result = cpu_to_be32(resp->result);
    resp->sz = cpu_to_be32(resp->sz);
    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
                              (char *) resp, sizeof(*resp), errp);
    if (r < 0) {
        return r;
    }

    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
                              (char *) client->data,
                              sz, errp);
    return r < 0 ? r : 0;
}

static void coroutine_fn prh_co_entry(void *opaque)
{
    PRHelperClient *client = opaque;
    Error *local_err = NULL;
    uint32_t flags;
    int r;

    qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
                             false, NULL);
    qio_channel_attach_aio_context(QIO_CHANNEL(client->ioc),
                                   qemu_get_aio_context());

    /* A very simple negotiation for future extensibility.  No features
     * are defined so write 0.
     */
    flags = cpu_to_be32(0);
    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
                             (char *) &flags, sizeof(flags), NULL);
    if (r < 0) {
        goto out;
    }

    r = qio_channel_read_all(QIO_CHANNEL(client->ioc),
                             (char *) &flags, sizeof(flags), NULL);
    if (be32_to_cpu(flags) != 0 || r < 0) {
        goto out;
    }

    while (atomic_read(&state) == RUNNING) {
        PRHelperRequest req;
        PRHelperResponse resp;
        int sz;

        sz = prh_read_request(client, &req, &resp, &local_err);
        if (sz < 0) {
            break;
        }

        num_active_sockets++;
        if (req.cdb[0] == PERSISTENT_RESERVE_OUT) {
            r = do_pr_out(req.fd, req.cdb, resp.sense,
                          client->data, sz);
            resp.sz = 0;
        } else {
            resp.sz = sizeof(client->data);
            r = do_pr_in(req.fd, req.cdb, resp.sense,
                         client->data, &resp.sz);
            resp.sz = MIN(resp.sz, sz);
        }
        num_active_sockets--;
        close(req.fd);
        if (r == -1) {
            break;
        }
        resp.result = r;

        if (prh_write_response(client, &req, &resp, &local_err) < 0) {
            break;
        }
    }

    if (local_err) {
        if (verbose == 0) {
            error_free(local_err);
        } else {
            error_report_err(local_err);
        }
    }

out:
    qio_channel_detach_aio_context(QIO_CHANNEL(client->ioc));
    object_unref(OBJECT(client->ioc));
    g_free(client);
}

static gboolean accept_client(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
{
    QIOChannelSocket *cioc;
    PRHelperClient *prh;

    cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
                                     NULL);
    if (!cioc) {
        return TRUE;
    }

    prh = g_new(PRHelperClient, 1);
    prh->ioc = cioc;
    prh->fd = -1;
    prh->co = qemu_coroutine_create(prh_co_entry, prh);
    qemu_coroutine_enter(prh->co);

    return TRUE;
}

static void termsig_handler(int signum)
{
    atomic_cmpxchg(&state, RUNNING, TERMINATE);
    qemu_notify_event();
}

static void close_server_socket(void)
{
    assert(server_ioc);

    g_source_remove(server_watch);
    server_watch = -1;
    object_unref(OBJECT(server_ioc));
    num_active_sockets--;
}

#ifdef CONFIG_LIBCAP_NG
static int drop_privileges(void)
{
    /* clear all capabilities */
    capng_clear(CAPNG_SELECT_BOTH);

    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
                     CAP_SYS_RAWIO) < 0) {
        return -1;
    }

#ifdef CONFIG_MPATH
    /* For /dev/mapper/control ioctls */
    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
                     CAP_SYS_ADMIN) < 0) {
        return -1;
    }
#endif

    /* Change user/group id, retaining the capabilities.  Because file descriptors
     * are passed via SCM_RIGHTS, we don't need supplementary groups (and in
     * fact the helper can run as "nobody").
     */
    if (capng_change_id(uid != -1 ? uid : getuid(),
                        gid != -1 ? gid : getgid(),
                        CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) {
        return -1;
    }

    return 0;
}
#endif

int main(int argc, char **argv)
{
    const char *sopt = "hVk:f:dT:u:g:vq";
    struct option lopt[] = {
        { "help", no_argument, NULL, 'h' },
        { "version", no_argument, NULL, 'V' },
        { "socket", required_argument, NULL, 'k' },
        { "pidfile", required_argument, NULL, 'f' },
        { "daemon", no_argument, NULL, 'd' },
        { "trace", required_argument, NULL, 'T' },
        { "user", required_argument, NULL, 'u' },
        { "group", required_argument, NULL, 'g' },
        { "verbose", no_argument, NULL, 'v' },
        { "quiet", no_argument, NULL, 'q' },
        { NULL, 0, NULL, 0 }
    };
    int opt_ind = 0;
    int loglevel = 1;
    int quiet = 0;
    int ch;
    Error *local_err = NULL;
    char *trace_file = NULL;
    bool daemonize = false;
    bool pidfile_specified = false;
    bool socket_path_specified = false;
    unsigned socket_activation;

    struct sigaction sa_sigterm;
    memset(&sa_sigterm, 0, sizeof(sa_sigterm));
    sa_sigterm.sa_handler = termsig_handler;
    sigaction(SIGTERM, &sa_sigterm, NULL);
    sigaction(SIGINT, &sa_sigterm, NULL);
    sigaction(SIGHUP, &sa_sigterm, NULL);

    signal(SIGPIPE, SIG_IGN);

    error_init(argv[0]);
    module_call_init(MODULE_INIT_TRACE);
    module_call_init(MODULE_INIT_QOM);
    qemu_add_opts(&qemu_trace_opts);
    qemu_init_exec_dir(argv[0]);

    compute_default_paths();

    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
        switch (ch) {
        case 'k':
            g_free(socket_path);
            socket_path = g_strdup(optarg);
            socket_path_specified = true;
            if (socket_path[0] != '/') {
                error_report("socket path must be absolute");
                exit(EXIT_FAILURE);
            }
            break;
        case 'f':
            g_free(pidfile);
            pidfile = g_strdup(optarg);
            pidfile_specified = true;
            break;
#ifdef CONFIG_LIBCAP_NG
        case 'u': {
            unsigned long res;
            struct passwd *userinfo = getpwnam(optarg);
            if (userinfo) {
                uid = userinfo->pw_uid;
            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
                       (uid_t)res == res) {
                uid = res;
            } else {
                error_report("invalid user '%s'", optarg);
                exit(EXIT_FAILURE);
            }
            break;
        }
        case 'g': {
            unsigned long res;
            struct group *groupinfo = getgrnam(optarg);
            if (groupinfo) {
                gid = groupinfo->gr_gid;
            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
                       (gid_t)res == res) {
                gid = res;
            } else {
                error_report("invalid group '%s'", optarg);
                exit(EXIT_FAILURE);
            }
            break;
        }
#else
        case 'u':
        case 'g':
            error_report("-%c not supported by this %s", ch, argv[0]);
            exit(1);
#endif
        case 'd':
            daemonize = true;
            break;
        case 'q':
            quiet = 1;
            break;
        case 'v':
            ++loglevel;
            break;
        case 'T':
            g_free(trace_file);
            trace_file = trace_opt_parse(optarg);
            break;
        case 'V':
            version(argv[0]);
            exit(EXIT_SUCCESS);
            break;
        case 'h':
            usage(argv[0]);
            exit(EXIT_SUCCESS);
            break;
        case '?':
            error_report("Try `%s --help' for more information.", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    /* set verbosity */
    noisy = !quiet && (loglevel >= 3);
    verbose = quiet ? 0 : MIN(loglevel, 3);

    if (!trace_init_backends()) {
        exit(EXIT_FAILURE);
    }
    trace_init_file(trace_file);
    qemu_set_log(LOG_TRACE);

#ifdef CONFIG_MPATH
    dm_init();
    multipath_pr_init();
#endif

    socket_activation = check_socket_activation();
    if (socket_activation == 0) {
        SocketAddress saddr;
        saddr = (SocketAddress){
            .type = SOCKET_ADDRESS_TYPE_UNIX,
            .u.q_unix.path = socket_path,
        };
        server_ioc = qio_channel_socket_new();
        if (qio_channel_socket_listen_sync(server_ioc, &saddr,
                                           1, &local_err) < 0) {
            object_unref(OBJECT(server_ioc));
            error_report_err(local_err);
            return 1;
        }
    } else {
        /* Using socket activation - check user didn't use -p etc. */
        if (socket_path_specified) {
            error_report("Unix socket can't be set when using socket activation");
            exit(EXIT_FAILURE);
        }

        /* Can only listen on a single socket.  */
        if (socket_activation > 1) {
            error_report("%s does not support socket activation with LISTEN_FDS > 1",
                         argv[0]);
            exit(EXIT_FAILURE);
        }
        server_ioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD,
                                               &local_err);
        if (server_ioc == NULL) {
            error_report("Failed to use socket activation: %s",
                         error_get_pretty(local_err));
            exit(EXIT_FAILURE);
        }
    }

    if (qemu_init_main_loop(&local_err)) {
        error_report_err(local_err);
        exit(EXIT_FAILURE);
    }

    server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
                                         G_IO_IN,
                                         accept_client,
                                         NULL, NULL);

    if (daemonize) {
        if (daemon(0, 0) < 0) {
            error_report("Failed to daemonize: %s", strerror(errno));
            exit(EXIT_FAILURE);
        }
    }

    if ((daemonize || pidfile_specified) &&
        !qemu_write_pidfile(pidfile, &local_err)) {
        error_report_err(local_err);
        exit(EXIT_FAILURE);
    }

#ifdef CONFIG_LIBCAP_NG
    if (drop_privileges() < 0) {
        error_report("Failed to drop privileges: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }
#endif

    state = RUNNING;
    do {
        main_loop_wait(false);
        if (state == TERMINATE) {
            state = TERMINATING;
            close_server_socket();
        }
    } while (num_active_sockets > 0);

    exit(EXIT_SUCCESS);
}
