qemu/scsi/qemu-pr-helper.c
<<
>>
Prefs
   1/*
   2 * Privileged helper to handle persistent reservation commands for QEMU
   3 *
   4 * Copyright (C) 2017 Red Hat, Inc. <pbonzini@redhat.com>
   5 *
   6 * Author: Paolo Bonzini <pbonzini@redhat.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation; under version 2 of the License.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, see <http://www.gnu.org/licenses/>.
  19 */
  20
  21#include "qemu/osdep.h"
  22#include <getopt.h>
  23#include <sys/ioctl.h>
  24#include <linux/dm-ioctl.h>
  25#include <scsi/sg.h>
  26
  27#ifdef CONFIG_LIBCAP
  28#include <cap-ng.h>
  29#endif
  30#include <pwd.h>
  31#include <grp.h>
  32
  33#ifdef CONFIG_MPATH
  34#include <libudev.h>
  35#include <mpath_cmd.h>
  36#include <mpath_persist.h>
  37#endif
  38
  39#include "qapi/error.h"
  40#include "qemu-common.h"
  41#include "qemu/cutils.h"
  42#include "qemu/main-loop.h"
  43#include "qemu/error-report.h"
  44#include "qemu/config-file.h"
  45#include "qemu/bswap.h"
  46#include "qemu/log.h"
  47#include "qemu/systemd.h"
  48#include "qapi/util.h"
  49#include "qapi/qmp/qstring.h"
  50#include "io/channel-socket.h"
  51#include "trace/control.h"
  52#include "qemu-version.h"
  53
  54#include "block/aio.h"
  55#include "block/thread-pool.h"
  56
  57#include "scsi/constants.h"
  58#include "scsi/utils.h"
  59#include "pr-helper.h"
  60
  61#define PR_OUT_FIXED_PARAM_SIZE 24
  62
  63static char *socket_path;
  64static char *pidfile;
  65static enum { RUNNING, TERMINATE, TERMINATING } state;
  66static QIOChannelSocket *server_ioc;
  67static int server_watch;
  68static int num_active_sockets = 1;
  69static int noisy;
  70static int verbose;
  71
  72#ifdef CONFIG_LIBCAP
  73static int uid = -1;
  74static int gid = -1;
  75#endif
  76
  77static void compute_default_paths(void)
  78{
  79    socket_path = qemu_get_local_state_pathname("run/qemu-pr-helper.sock");
  80    pidfile = qemu_get_local_state_pathname("run/qemu-pr-helper.pid");
  81}
  82
  83static void usage(const char *name)
  84{
  85    (printf) (
  86"Usage: %s [OPTIONS] FILE\n"
  87"Persistent Reservation helper program for QEMU\n"
  88"\n"
  89"  -h, --help                display this help and exit\n"
  90"  -V, --version             output version information and exit\n"
  91"\n"
  92"  -d, --daemon              run in the background\n"
  93"  -f, --pidfile=PATH        PID file when running as a daemon\n"
  94"                            (default '%s')\n"
  95"  -k, --socket=PATH         path to the unix socket\n"
  96"                            (default '%s')\n"
  97"  -T, --trace [[enable=]<pattern>][,events=<file>][,file=<file>]\n"
  98"                            specify tracing options\n"
  99#ifdef CONFIG_LIBCAP
 100"  -u, --user=USER           user to drop privileges to\n"
 101"  -g, --group=GROUP         group to drop privileges to\n"
 102#endif
 103"\n"
 104QEMU_HELP_BOTTOM "\n"
 105    , name, pidfile, socket_path);
 106}
 107
 108static void version(const char *name)
 109{
 110    printf(
 111"%s " QEMU_FULL_VERSION "\n"
 112"Written by Paolo Bonzini.\n"
 113"\n"
 114QEMU_COPYRIGHT "\n"
 115"This is free software; see the source for copying conditions.  There is NO\n"
 116"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
 117    , name);
 118}
 119
 120static void write_pidfile(void)
 121{
 122    int pidfd;
 123    char pidstr[32];
 124
 125    pidfd = qemu_open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
 126    if (pidfd == -1) {
 127        error_report("Cannot open pid file, %s", strerror(errno));
 128        exit(EXIT_FAILURE);
 129    }
 130
 131    if (lockf(pidfd, F_TLOCK, 0)) {
 132        error_report("Cannot lock pid file, %s", strerror(errno));
 133        goto fail;
 134    }
 135    if (ftruncate(pidfd, 0)) {
 136        error_report("Failed to truncate pid file");
 137        goto fail;
 138    }
 139
 140    snprintf(pidstr, sizeof(pidstr), "%d\n", getpid());
 141    if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) {
 142        error_report("Failed to write pid file");
 143        goto fail;
 144    }
 145    return;
 146
 147fail:
 148    unlink(pidfile);
 149    close(pidfd);
 150    exit(EXIT_FAILURE);
 151}
 152
 153/* SG_IO support */
 154
 155typedef struct PRHelperSGIOData {
 156    int fd;
 157    const uint8_t *cdb;
 158    uint8_t *sense;
 159    uint8_t *buf;
 160    int sz;              /* input/output */
 161    int dir;
 162} PRHelperSGIOData;
 163
 164static int do_sgio_worker(void *opaque)
 165{
 166    PRHelperSGIOData *data = opaque;
 167    struct sg_io_hdr io_hdr;
 168    int ret;
 169    int status;
 170    SCSISense sense_code;
 171
 172    memset(data->sense, 0, PR_HELPER_SENSE_SIZE);
 173    memset(&io_hdr, 0, sizeof(io_hdr));
 174    io_hdr.interface_id = 'S';
 175    io_hdr.cmd_len = PR_HELPER_CDB_SIZE;
 176    io_hdr.cmdp = (uint8_t *)data->cdb;
 177    io_hdr.sbp = data->sense;
 178    io_hdr.mx_sb_len = PR_HELPER_SENSE_SIZE;
 179    io_hdr.timeout = 1;
 180    io_hdr.dxfer_direction = data->dir;
 181    io_hdr.dxferp = (char *)data->buf;
 182    io_hdr.dxfer_len = data->sz;
 183    ret = ioctl(data->fd, SG_IO, &io_hdr);
 184    status = sg_io_sense_from_errno(ret < 0 ? errno : 0, &io_hdr,
 185                                    &sense_code);
 186    if (status == GOOD) {
 187        data->sz -= io_hdr.resid;
 188    } else {
 189        data->sz = 0;
 190    }
 191
 192    if (status == CHECK_CONDITION &&
 193        !(io_hdr.driver_status & SG_ERR_DRIVER_SENSE)) {
 194        scsi_build_sense(data->sense, sense_code);
 195    }
 196
 197    return status;
 198}
 199
 200static int do_sgio(int fd, const uint8_t *cdb, uint8_t *sense,
 201                    uint8_t *buf, int *sz, int dir)
 202{
 203    ThreadPool *pool = aio_get_thread_pool(qemu_get_aio_context());
 204    int r;
 205
 206    PRHelperSGIOData data = {
 207        .fd = fd,
 208        .cdb = cdb,
 209        .sense = sense,
 210        .buf = buf,
 211        .sz = *sz,
 212        .dir = dir,
 213    };
 214
 215    r = thread_pool_submit_co(pool, do_sgio_worker, &data);
 216    *sz = data.sz;
 217    return r;
 218}
 219
 220/* Device mapper interface */
 221
 222#ifdef CONFIG_MPATH
 223#define CONTROL_PATH "/dev/mapper/control"
 224
 225typedef struct DMData {
 226    struct dm_ioctl dm;
 227    uint8_t data[1024];
 228} DMData;
 229
 230static int control_fd;
 231
 232static void *dm_ioctl(int ioc, struct dm_ioctl *dm)
 233{
 234    static DMData d;
 235    memcpy(&d.dm, dm, sizeof(d.dm));
 236    QEMU_BUILD_BUG_ON(sizeof(d.data) < sizeof(struct dm_target_spec));
 237
 238    d.dm.version[0] = DM_VERSION_MAJOR;
 239    d.dm.version[1] = 0;
 240    d.dm.version[2] = 0;
 241    d.dm.data_size = 1024;
 242    d.dm.data_start = offsetof(DMData, data);
 243    if (ioctl(control_fd, ioc, &d) < 0) {
 244        return NULL;
 245    }
 246    memcpy(dm, &d.dm, sizeof(d.dm));
 247    return &d.data;
 248}
 249
 250static void *dm_dev_ioctl(int fd, int ioc, struct dm_ioctl *dm)
 251{
 252    struct stat st;
 253    int r;
 254
 255    r = fstat(fd, &st);
 256    if (r < 0) {
 257        perror("fstat");
 258        exit(1);
 259    }
 260
 261    dm->dev = st.st_rdev;
 262    return dm_ioctl(ioc, dm);
 263}
 264
 265static void dm_init(void)
 266{
 267    control_fd = open(CONTROL_PATH, O_RDWR);
 268    if (control_fd < 0) {
 269        perror("Cannot open " CONTROL_PATH);
 270        exit(1);
 271    }
 272    struct dm_ioctl dm = { 0 };
 273    if (!dm_ioctl(DM_VERSION, &dm)) {
 274        perror("ioctl");
 275        exit(1);
 276    }
 277    if (dm.version[0] != DM_VERSION_MAJOR) {
 278        fprintf(stderr, "Unsupported device mapper interface");
 279        exit(1);
 280    }
 281}
 282
 283/* Variables required by libmultipath and libmpathpersist.  */
 284QEMU_BUILD_BUG_ON(PR_HELPER_DATA_SIZE > MPATH_MAX_PARAM_LEN);
 285static struct config *multipath_conf;
 286unsigned mpath_mx_alloc_len = PR_HELPER_DATA_SIZE;
 287int logsink;
 288struct udev *udev;
 289
 290extern struct config *get_multipath_config(void);
 291struct config *get_multipath_config(void)
 292{
 293    return multipath_conf;
 294}
 295
 296extern void put_multipath_config(struct config *conf);
 297void put_multipath_config(struct config *conf)
 298{
 299}
 300
 301static void multipath_pr_init(void)
 302{
 303    udev = udev_new();
 304    multipath_conf = mpath_lib_init();
 305}
 306
 307static int is_mpath(int fd)
 308{
 309    struct dm_ioctl dm = { .flags = DM_NOFLUSH_FLAG };
 310    struct dm_target_spec *tgt;
 311
 312    tgt = dm_dev_ioctl(fd, DM_TABLE_STATUS, &dm);
 313    if (!tgt) {
 314        if (errno == ENXIO) {
 315            return 0;
 316        }
 317        perror("ioctl");
 318        exit(EXIT_FAILURE);
 319    }
 320    return !strncmp(tgt->target_type, "multipath", DM_MAX_TYPE_NAME);
 321}
 322
 323static SCSISense mpath_generic_sense(int r)
 324{
 325    switch (r) {
 326    case MPATH_PR_SENSE_NOT_READY:
 327         return SENSE_CODE(NOT_READY);
 328    case MPATH_PR_SENSE_MEDIUM_ERROR:
 329         return SENSE_CODE(READ_ERROR);
 330    case MPATH_PR_SENSE_HARDWARE_ERROR:
 331         return SENSE_CODE(TARGET_FAILURE);
 332    case MPATH_PR_SENSE_ABORTED_COMMAND:
 333         return SENSE_CODE(IO_ERROR);
 334    default:
 335         abort();
 336    }
 337}
 338
 339static int mpath_reconstruct_sense(int fd, int r, uint8_t *sense)
 340{
 341    switch (r) {
 342    case MPATH_PR_SUCCESS:
 343        return GOOD;
 344    case MPATH_PR_SENSE_NOT_READY:
 345    case MPATH_PR_SENSE_MEDIUM_ERROR:
 346    case MPATH_PR_SENSE_HARDWARE_ERROR:
 347    case MPATH_PR_SENSE_ABORTED_COMMAND:
 348        {
 349            /* libmpathpersist ate the exact sense.  Try to find it by
 350             * issuing TEST UNIT READY.
 351             */
 352            uint8_t cdb[6] = { TEST_UNIT_READY };
 353            int sz = 0;
 354            int r = do_sgio(fd, cdb, sense, NULL, &sz, SG_DXFER_NONE);
 355
 356            if (r != GOOD) {
 357                return r;
 358            }
 359            scsi_build_sense(sense, mpath_generic_sense(r));
 360            return CHECK_CONDITION;
 361        }
 362
 363    case MPATH_PR_SENSE_UNIT_ATTENTION:
 364        /* Congratulations libmpathpersist, you ruined the Unit Attention...
 365         * Return a heavyweight one.
 366         */
 367        scsi_build_sense(sense, SENSE_CODE(SCSI_BUS_RESET));
 368        return CHECK_CONDITION;
 369    case MPATH_PR_SENSE_INVALID_OP:
 370        /* Only one valid sense.  */
 371        scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
 372        return CHECK_CONDITION;
 373    case MPATH_PR_ILLEGAL_REQ:
 374        /* Guess.  */
 375        scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
 376        return CHECK_CONDITION;
 377    case MPATH_PR_NO_SENSE:
 378        scsi_build_sense(sense, SENSE_CODE(NO_SENSE));
 379        return CHECK_CONDITION;
 380
 381    case MPATH_PR_RESERV_CONFLICT:
 382        return RESERVATION_CONFLICT;
 383
 384    case MPATH_PR_OTHER:
 385    default:
 386        scsi_build_sense(sense, SENSE_CODE(LUN_COMM_FAILURE));
 387        return CHECK_CONDITION;
 388    }
 389}
 390
 391static int multipath_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
 392                           uint8_t *data, int sz)
 393{
 394    int rq_servact = cdb[1];
 395    struct prin_resp resp;
 396    size_t written;
 397    int r;
 398
 399    switch (rq_servact) {
 400    case MPATH_PRIN_RKEY_SA:
 401    case MPATH_PRIN_RRES_SA:
 402    case MPATH_PRIN_RCAP_SA:
 403        break;
 404    case MPATH_PRIN_RFSTAT_SA:
 405        /* Nobody implements it anyway, so bail out. */
 406    default:
 407        /* Cannot parse any other output.  */
 408        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
 409        return CHECK_CONDITION;
 410    }
 411
 412    r = mpath_persistent_reserve_in(fd, rq_servact, &resp, noisy, verbose);
 413    if (r == MPATH_PR_SUCCESS) {
 414        switch (rq_servact) {
 415        case MPATH_PRIN_RKEY_SA:
 416        case MPATH_PRIN_RRES_SA: {
 417            struct prin_readdescr *out = &resp.prin_descriptor.prin_readkeys;
 418            assert(sz >= 8);
 419            written = MIN(out->additional_length + 8, sz);
 420            stl_be_p(&data[0], out->prgeneration);
 421            stl_be_p(&data[4], out->additional_length);
 422            memcpy(&data[8], out->key_list, written - 8);
 423            break;
 424        }
 425        case MPATH_PRIN_RCAP_SA: {
 426            struct prin_capdescr *out = &resp.prin_descriptor.prin_readcap;
 427            assert(sz >= 6);
 428            written = 6;
 429            stw_be_p(&data[0], out->length);
 430            data[2] = out->flags[0];
 431            data[3] = out->flags[1];
 432            stw_be_p(&data[4], out->pr_type_mask);
 433            break;
 434        }
 435        default:
 436            scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
 437            return CHECK_CONDITION;
 438        }
 439        assert(written <= sz);
 440        memset(data + written, 0, sz - written);
 441    }
 442
 443    return mpath_reconstruct_sense(fd, r, sense);
 444}
 445
 446static int multipath_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
 447                            const uint8_t *param, int sz)
 448{
 449    int rq_servact = cdb[1];
 450    int rq_scope = cdb[2] >> 4;
 451    int rq_type = cdb[2] & 0xf;
 452    struct prout_param_descriptor paramp;
 453    char transportids[PR_HELPER_DATA_SIZE];
 454    int r;
 455
 456    if (sz < PR_OUT_FIXED_PARAM_SIZE) {
 457        /* Illegal request, Parameter list length error.  This isn't fatal;
 458         * we have read the data, send an error without closing the socket.
 459         */
 460        scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM_LEN));
 461        return CHECK_CONDITION;
 462    }
 463
 464    switch (rq_servact) {
 465    case MPATH_PROUT_REG_SA:
 466    case MPATH_PROUT_RES_SA:
 467    case MPATH_PROUT_REL_SA:
 468    case MPATH_PROUT_CLEAR_SA:
 469    case MPATH_PROUT_PREE_SA:
 470    case MPATH_PROUT_PREE_AB_SA:
 471    case MPATH_PROUT_REG_IGN_SA:
 472        break;
 473    case MPATH_PROUT_REG_MOV_SA:
 474        /* Not supported by struct prout_param_descriptor.  */
 475    default:
 476        /* Cannot parse any other input.  */
 477        scsi_build_sense(sense, SENSE_CODE(INVALID_FIELD));
 478        return CHECK_CONDITION;
 479    }
 480
 481    /* Convert input data, especially transport IDs, to the structs
 482     * used by libmpathpersist (which, of course, will immediately
 483     * do the opposite).
 484     */
 485    memset(&paramp, 0, sizeof(paramp));
 486    memcpy(&paramp.key, &param[0], 8);
 487    memcpy(&paramp.sa_key, &param[8], 8);
 488    paramp.sa_flags = param[20];
 489    if (sz > PR_OUT_FIXED_PARAM_SIZE) {
 490        size_t transportid_len;
 491        int i, j;
 492        if (sz < PR_OUT_FIXED_PARAM_SIZE + 4) {
 493            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM_LEN));
 494            return CHECK_CONDITION;
 495        }
 496        transportid_len = ldl_be_p(&param[24]) + PR_OUT_FIXED_PARAM_SIZE + 4;
 497        if (transportid_len > sz) {
 498            scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
 499            return CHECK_CONDITION;
 500        }
 501        for (i = PR_OUT_FIXED_PARAM_SIZE + 4, j = 0; i < transportid_len; ) {
 502            struct transportid *id = (struct transportid *) &transportids[j];
 503            int len;
 504
 505            id->format_code = param[i] & 0xc0;
 506            id->protocol_id = param[i] & 0x0f;
 507            switch (param[i] & 0xcf) {
 508            case 0:
 509                /* FC transport.  */
 510                if (i + 24 > transportid_len) {
 511                    goto illegal_req;
 512                }
 513                memcpy(id->n_port_name, &param[i + 8], 8);
 514                j += offsetof(struct transportid, n_port_name[8]);
 515                i += 24;
 516                break;
 517            case 5:
 518            case 0x45:
 519                /* iSCSI transport.  */
 520                len = lduw_be_p(&param[i + 2]);
 521                if (len > 252 || (len & 3) || i + len + 4 > transportid_len) {
 522                    /* For format code 00, the standard says the maximum is 223
 523                     * plus the NUL terminator.  For format code 01 there is no
 524                     * maximum length, but libmpathpersist ignores the first
 525                     * byte of id->iscsi_name so our maximum is 252.
 526                     */
 527                    goto illegal_req;
 528                }
 529                if (memchr(&param[i + 4], 0, len) == NULL) {
 530                    goto illegal_req;
 531                }
 532                memcpy(id->iscsi_name, &param[i + 2], len + 2);
 533                j += offsetof(struct transportid, iscsi_name[len + 2]);
 534                i += len + 4;
 535                break;
 536            case 6:
 537                /* SAS transport.  */
 538                if (i + 24 > transportid_len) {
 539                    goto illegal_req;
 540                }
 541                memcpy(id->sas_address, &param[i + 4], 8);
 542                j += offsetof(struct transportid, sas_address[8]);
 543                i += 24;
 544                break;
 545            default:
 546            illegal_req:
 547                scsi_build_sense(sense, SENSE_CODE(INVALID_PARAM));
 548                return CHECK_CONDITION;
 549            }
 550
 551            paramp.trnptid_list[paramp.num_transportid++] = id;
 552        }
 553    }
 554
 555    r = mpath_persistent_reserve_out(fd, rq_servact, rq_scope, rq_type,
 556                                     &paramp, noisy, verbose);
 557    return mpath_reconstruct_sense(fd, r, sense);
 558}
 559#endif
 560
 561static int do_pr_in(int fd, const uint8_t *cdb, uint8_t *sense,
 562                    uint8_t *data, int *resp_sz)
 563{
 564#ifdef CONFIG_MPATH
 565    if (is_mpath(fd)) {
 566        /* multipath_pr_in fills the whole input buffer.  */
 567        int r = multipath_pr_in(fd, cdb, sense, data, *resp_sz);
 568        if (r != GOOD) {
 569            *resp_sz = 0;
 570        }
 571        return r;
 572    }
 573#endif
 574
 575    return do_sgio(fd, cdb, sense, data, resp_sz,
 576                   SG_DXFER_FROM_DEV);
 577}
 578
 579static int do_pr_out(int fd, const uint8_t *cdb, uint8_t *sense,
 580                     const uint8_t *param, int sz)
 581{
 582    int resp_sz;
 583
 584    if ((fcntl(fd, F_GETFL) & O_ACCMODE) == O_RDONLY) {
 585        scsi_build_sense(sense, SENSE_CODE(INVALID_OPCODE));
 586        return CHECK_CONDITION;
 587    }
 588
 589#ifdef CONFIG_MPATH
 590    if (is_mpath(fd)) {
 591        return multipath_pr_out(fd, cdb, sense, param, sz);
 592    }
 593#endif
 594
 595    resp_sz = sz;
 596    return do_sgio(fd, cdb, sense, (uint8_t *)param, &resp_sz,
 597                   SG_DXFER_TO_DEV);
 598}
 599
 600/* Client */
 601
 602typedef struct PRHelperClient {
 603    QIOChannelSocket *ioc;
 604    Coroutine *co;
 605    int fd;
 606    uint8_t data[PR_HELPER_DATA_SIZE];
 607} PRHelperClient;
 608
 609typedef struct PRHelperRequest {
 610    int fd;
 611    size_t sz;
 612    uint8_t cdb[PR_HELPER_CDB_SIZE];
 613} PRHelperRequest;
 614
 615static int coroutine_fn prh_read(PRHelperClient *client, void *buf, int sz,
 616                                 Error **errp)
 617{
 618    int ret = 0;
 619
 620    while (sz > 0) {
 621        int *fds = NULL;
 622        size_t nfds = 0;
 623        int i;
 624        struct iovec iov;
 625        ssize_t n_read;
 626
 627        iov.iov_base = buf;
 628        iov.iov_len = sz;
 629        n_read = qio_channel_readv_full(QIO_CHANNEL(client->ioc), &iov, 1,
 630                                        &fds, &nfds, errp);
 631
 632        if (n_read == QIO_CHANNEL_ERR_BLOCK) {
 633            qio_channel_yield(QIO_CHANNEL(client->ioc), G_IO_IN);
 634            continue;
 635        }
 636        if (n_read <= 0) {
 637            ret = n_read ? n_read : -1;
 638            goto err;
 639        }
 640
 641        /* Stash one file descriptor per request.  */
 642        if (nfds) {
 643            bool too_many = false;
 644            for (i = 0; i < nfds; i++) {
 645                if (client->fd == -1) {
 646                    client->fd = fds[i];
 647                } else {
 648                    close(fds[i]);
 649                    too_many = true;
 650                }
 651            }
 652            g_free(fds);
 653            if (too_many) {
 654                ret = -1;
 655                goto err;
 656            }
 657        }
 658
 659        buf += n_read;
 660        sz -= n_read;
 661    }
 662
 663    return 0;
 664
 665err:
 666    if (client->fd != -1) {
 667        close(client->fd);
 668        client->fd = -1;
 669    }
 670    return ret;
 671}
 672
 673static int coroutine_fn prh_read_request(PRHelperClient *client,
 674                                         PRHelperRequest *req,
 675                                         PRHelperResponse *resp, Error **errp)
 676{
 677    uint32_t sz;
 678
 679    if (prh_read(client, req->cdb, sizeof(req->cdb), NULL) < 0) {
 680        return -1;
 681    }
 682
 683    if (client->fd == -1) {
 684        error_setg(errp, "No file descriptor in request.");
 685        return -1;
 686    }
 687
 688    if (req->cdb[0] != PERSISTENT_RESERVE_OUT &&
 689        req->cdb[0] != PERSISTENT_RESERVE_IN) {
 690        error_setg(errp, "Invalid CDB, closing socket.");
 691        goto out_close;
 692    }
 693
 694    sz = scsi_cdb_xfer(req->cdb);
 695    if (sz > sizeof(client->data)) {
 696        goto out_close;
 697    }
 698
 699    if (req->cdb[0] == PERSISTENT_RESERVE_OUT) {
 700        if (qio_channel_read_all(QIO_CHANNEL(client->ioc),
 701                                 (char *)client->data, sz,
 702                                 errp) < 0) {
 703            goto out_close;
 704        }
 705    }
 706
 707    req->fd = client->fd;
 708    req->sz = sz;
 709    client->fd = -1;
 710    return sz;
 711
 712out_close:
 713    close(client->fd);
 714    client->fd = -1;
 715    return -1;
 716}
 717
 718static int coroutine_fn prh_write_response(PRHelperClient *client,
 719                                           PRHelperRequest *req,
 720                                           PRHelperResponse *resp, Error **errp)
 721{
 722    ssize_t r;
 723    size_t sz;
 724
 725    if (req->cdb[0] == PERSISTENT_RESERVE_IN && resp->result == GOOD) {
 726        assert(resp->sz <= req->sz && resp->sz <= sizeof(client->data));
 727    } else {
 728        assert(resp->sz == 0);
 729    }
 730
 731    sz = resp->sz;
 732
 733    resp->result = cpu_to_be32(resp->result);
 734    resp->sz = cpu_to_be32(resp->sz);
 735    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
 736                              (char *) resp, sizeof(*resp), errp);
 737    if (r < 0) {
 738        return r;
 739    }
 740
 741    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
 742                              (char *) client->data,
 743                              sz, errp);
 744    return r < 0 ? r : 0;
 745}
 746
 747static void coroutine_fn prh_co_entry(void *opaque)
 748{
 749    PRHelperClient *client = opaque;
 750    Error *local_err = NULL;
 751    uint32_t flags;
 752    int r;
 753
 754    qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
 755                             false, NULL);
 756    qio_channel_attach_aio_context(QIO_CHANNEL(client->ioc),
 757                                   qemu_get_aio_context());
 758
 759    /* A very simple negotiation for future extensibility.  No features
 760     * are defined so write 0.
 761     */
 762    flags = cpu_to_be32(0);
 763    r = qio_channel_write_all(QIO_CHANNEL(client->ioc),
 764                             (char *) &flags, sizeof(flags), NULL);
 765    if (r < 0) {
 766        goto out;
 767    }
 768
 769    r = qio_channel_read_all(QIO_CHANNEL(client->ioc),
 770                             (char *) &flags, sizeof(flags), NULL);
 771    if (be32_to_cpu(flags) != 0 || r < 0) {
 772        goto out;
 773    }
 774
 775    while (atomic_read(&state) == RUNNING) {
 776        PRHelperRequest req;
 777        PRHelperResponse resp;
 778        int sz;
 779
 780        sz = prh_read_request(client, &req, &resp, &local_err);
 781        if (sz < 0) {
 782            break;
 783        }
 784
 785        num_active_sockets++;
 786        if (req.cdb[0] == PERSISTENT_RESERVE_OUT) {
 787            r = do_pr_out(req.fd, req.cdb, resp.sense,
 788                          client->data, sz);
 789            resp.sz = 0;
 790        } else {
 791            resp.sz = sizeof(client->data);
 792            r = do_pr_in(req.fd, req.cdb, resp.sense,
 793                         client->data, &resp.sz);
 794            resp.sz = MIN(resp.sz, sz);
 795        }
 796        num_active_sockets--;
 797        close(req.fd);
 798        if (r == -1) {
 799            break;
 800        }
 801        resp.result = r;
 802
 803        if (prh_write_response(client, &req, &resp, &local_err) < 0) {
 804            break;
 805        }
 806    }
 807
 808    if (local_err) {
 809        if (verbose == 0) {
 810            error_free(local_err);
 811        } else {
 812            error_report_err(local_err);
 813        }
 814    }
 815
 816out:
 817    qio_channel_detach_aio_context(QIO_CHANNEL(client->ioc));
 818    object_unref(OBJECT(client->ioc));
 819    g_free(client);
 820}
 821
 822static gboolean accept_client(QIOChannel *ioc, GIOCondition cond, gpointer opaque)
 823{
 824    QIOChannelSocket *cioc;
 825    PRHelperClient *prh;
 826
 827    cioc = qio_channel_socket_accept(QIO_CHANNEL_SOCKET(ioc),
 828                                     NULL);
 829    if (!cioc) {
 830        return TRUE;
 831    }
 832
 833    prh = g_new(PRHelperClient, 1);
 834    prh->ioc = cioc;
 835    prh->fd = -1;
 836    prh->co = qemu_coroutine_create(prh_co_entry, prh);
 837    qemu_coroutine_enter(prh->co);
 838
 839    return TRUE;
 840}
 841
 842static void termsig_handler(int signum)
 843{
 844    atomic_cmpxchg(&state, RUNNING, TERMINATE);
 845    qemu_notify_event();
 846}
 847
 848static void close_server_socket(void)
 849{
 850    assert(server_ioc);
 851
 852    g_source_remove(server_watch);
 853    server_watch = -1;
 854    object_unref(OBJECT(server_ioc));
 855    num_active_sockets--;
 856}
 857
 858#ifdef CONFIG_LIBCAP
 859static int drop_privileges(void)
 860{
 861    /* clear all capabilities */
 862    capng_clear(CAPNG_SELECT_BOTH);
 863
 864    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
 865                     CAP_SYS_RAWIO) < 0) {
 866        return -1;
 867    }
 868
 869#ifdef CONFIG_MPATH
 870    /* For /dev/mapper/control ioctls */
 871    if (capng_update(CAPNG_ADD, CAPNG_EFFECTIVE | CAPNG_PERMITTED,
 872                     CAP_SYS_ADMIN) < 0) {
 873        return -1;
 874    }
 875#endif
 876
 877    /* Change user/group id, retaining the capabilities.  Because file descriptors
 878     * are passed via SCM_RIGHTS, we don't need supplementary groups (and in
 879     * fact the helper can run as "nobody").
 880     */
 881    if (capng_change_id(uid != -1 ? uid : getuid(),
 882                        gid != -1 ? gid : getgid(),
 883                        CAPNG_DROP_SUPP_GRP | CAPNG_CLEAR_BOUNDING)) {
 884        return -1;
 885    }
 886
 887    return 0;
 888}
 889#endif
 890
 891int main(int argc, char **argv)
 892{
 893    const char *sopt = "hVk:f:dT:u:g:vq";
 894    struct option lopt[] = {
 895        { "help", no_argument, NULL, 'h' },
 896        { "version", no_argument, NULL, 'V' },
 897        { "socket", required_argument, NULL, 'k' },
 898        { "pidfile", required_argument, NULL, 'f' },
 899        { "daemon", no_argument, NULL, 'd' },
 900        { "trace", required_argument, NULL, 'T' },
 901        { "user", required_argument, NULL, 'u' },
 902        { "group", required_argument, NULL, 'g' },
 903        { "verbose", no_argument, NULL, 'v' },
 904        { "quiet", no_argument, NULL, 'q' },
 905        { NULL, 0, NULL, 0 }
 906    };
 907    int opt_ind = 0;
 908    int loglevel = 1;
 909    int quiet = 0;
 910    int ch;
 911    Error *local_err = NULL;
 912    char *trace_file = NULL;
 913    bool daemonize = false;
 914    bool pidfile_specified = false;
 915    bool socket_path_specified = false;
 916    unsigned socket_activation;
 917
 918    struct sigaction sa_sigterm;
 919    memset(&sa_sigterm, 0, sizeof(sa_sigterm));
 920    sa_sigterm.sa_handler = termsig_handler;
 921    sigaction(SIGTERM, &sa_sigterm, NULL);
 922    sigaction(SIGINT, &sa_sigterm, NULL);
 923    sigaction(SIGHUP, &sa_sigterm, NULL);
 924
 925    signal(SIGPIPE, SIG_IGN);
 926
 927    module_call_init(MODULE_INIT_TRACE);
 928    module_call_init(MODULE_INIT_QOM);
 929    qemu_add_opts(&qemu_trace_opts);
 930    qemu_init_exec_dir(argv[0]);
 931
 932    compute_default_paths();
 933
 934    while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
 935        switch (ch) {
 936        case 'k':
 937            g_free(socket_path);
 938            socket_path = g_strdup(optarg);
 939            socket_path_specified = true;
 940            if (socket_path[0] != '/') {
 941                error_report("socket path must be absolute");
 942                exit(EXIT_FAILURE);
 943            }
 944            break;
 945        case 'f':
 946            g_free(pidfile);
 947            pidfile = g_strdup(optarg);
 948            pidfile_specified = true;
 949            break;
 950#ifdef CONFIG_LIBCAP
 951        case 'u': {
 952            unsigned long res;
 953            struct passwd *userinfo = getpwnam(optarg);
 954            if (userinfo) {
 955                uid = userinfo->pw_uid;
 956            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
 957                       (uid_t)res == res) {
 958                uid = res;
 959            } else {
 960                error_report("invalid user '%s'", optarg);
 961                exit(EXIT_FAILURE);
 962            }
 963            break;
 964        }
 965        case 'g': {
 966            unsigned long res;
 967            struct group *groupinfo = getgrnam(optarg);
 968            if (groupinfo) {
 969                gid = groupinfo->gr_gid;
 970            } else if (qemu_strtoul(optarg, NULL, 10, &res) == 0 &&
 971                       (gid_t)res == res) {
 972                gid = res;
 973            } else {
 974                error_report("invalid group '%s'", optarg);
 975                exit(EXIT_FAILURE);
 976            }
 977            break;
 978        }
 979#else
 980        case 'u':
 981        case 'g':
 982            error_report("-%c not supported by this %s", ch, argv[0]);
 983            exit(1);
 984#endif
 985        case 'd':
 986            daemonize = true;
 987            break;
 988        case 'q':
 989            quiet = 1;
 990            break;
 991        case 'v':
 992            ++loglevel;
 993            break;
 994        case 'T':
 995            g_free(trace_file);
 996            trace_file = trace_opt_parse(optarg);
 997            break;
 998        case 'V':
 999            version(argv[0]);
1000            exit(EXIT_SUCCESS);
1001            break;
1002        case 'h':
1003            usage(argv[0]);
1004            exit(EXIT_SUCCESS);
1005            break;
1006        case '?':
1007            error_report("Try `%s --help' for more information.", argv[0]);
1008            exit(EXIT_FAILURE);
1009        }
1010    }
1011
1012    /* set verbosity */
1013    noisy = !quiet && (loglevel >= 3);
1014    verbose = quiet ? 0 : MIN(loglevel, 3);
1015
1016    if (!trace_init_backends()) {
1017        exit(EXIT_FAILURE);
1018    }
1019    trace_init_file(trace_file);
1020    qemu_set_log(LOG_TRACE);
1021
1022#ifdef CONFIG_MPATH
1023    dm_init();
1024    multipath_pr_init();
1025#endif
1026
1027    socket_activation = check_socket_activation();
1028    if (socket_activation == 0) {
1029        SocketAddress saddr;
1030        saddr = (SocketAddress){
1031            .type = SOCKET_ADDRESS_TYPE_UNIX,
1032            .u.q_unix.path = socket_path,
1033        };
1034        server_ioc = qio_channel_socket_new();
1035        if (qio_channel_socket_listen_sync(server_ioc, &saddr, &local_err) < 0) {
1036            object_unref(OBJECT(server_ioc));
1037            error_report_err(local_err);
1038            return 1;
1039        }
1040    } else {
1041        /* Using socket activation - check user didn't use -p etc. */
1042        if (socket_path_specified) {
1043            error_report("Unix socket can't be set when using socket activation");
1044            exit(EXIT_FAILURE);
1045        }
1046
1047        /* Can only listen on a single socket.  */
1048        if (socket_activation > 1) {
1049            error_report("%s does not support socket activation with LISTEN_FDS > 1",
1050                         argv[0]);
1051            exit(EXIT_FAILURE);
1052        }
1053        server_ioc = qio_channel_socket_new_fd(FIRST_SOCKET_ACTIVATION_FD,
1054                                               &local_err);
1055        if (server_ioc == NULL) {
1056            error_report("Failed to use socket activation: %s",
1057                         error_get_pretty(local_err));
1058            exit(EXIT_FAILURE);
1059        }
1060    }
1061
1062    if (qemu_init_main_loop(&local_err)) {
1063        error_report_err(local_err);
1064        exit(EXIT_FAILURE);
1065    }
1066
1067    server_watch = qio_channel_add_watch(QIO_CHANNEL(server_ioc),
1068                                         G_IO_IN,
1069                                         accept_client,
1070                                         NULL, NULL);
1071
1072    if (daemonize) {
1073        if (daemon(0, 0) < 0) {
1074            error_report("Failed to daemonize: %s", strerror(errno));
1075            exit(EXIT_FAILURE);
1076        }
1077    }
1078
1079    if (daemonize || pidfile_specified)
1080        write_pidfile();
1081
1082#ifdef CONFIG_LIBCAP
1083    if (drop_privileges() < 0) {
1084        error_report("Failed to drop privileges: %s", strerror(errno));
1085        exit(EXIT_FAILURE);
1086    }
1087#endif
1088
1089    state = RUNNING;
1090    do {
1091        main_loop_wait(false);
1092        if (state == TERMINATE) {
1093            state = TERMINATING;
1094            close_server_socket();
1095        }
1096    } while (num_active_sockets > 0);
1097
1098    exit(EXIT_SUCCESS);
1099}
1100