qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

qemu-pr-helper.c (30737B)


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