qemu/scsi/pr-manager.c
<<
>>
Prefs
   1/*
   2 * Persistent reservation manager abstract class
   3 *
   4 * Copyright (c) 2017 Red Hat, Inc.
   5 *
   6 * Author: Paolo Bonzini <pbonzini@redhat.com>
   7 *
   8 * This code is licensed under the LGPL.
   9 *
  10 */
  11
  12#include "qemu/osdep.h"
  13#include <scsi/sg.h>
  14
  15#include "qapi/error.h"
  16#include "block/aio.h"
  17#include "block/thread-pool.h"
  18#include "scsi/pr-manager.h"
  19#include "trace.h"
  20
  21typedef struct PRManagerData {
  22    PRManager *pr_mgr;
  23    struct sg_io_hdr *hdr;
  24    int fd;
  25} PRManagerData;
  26
  27static int pr_manager_worker(void *opaque)
  28{
  29    PRManagerData *data = opaque;
  30    PRManager *pr_mgr = data->pr_mgr;
  31    PRManagerClass *pr_mgr_class =
  32        PR_MANAGER_GET_CLASS(pr_mgr);
  33    struct sg_io_hdr *hdr = data->hdr;
  34    int fd = data->fd;
  35    int r;
  36
  37    g_free(data);
  38    trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
  39
  40    /* The reference was taken in pr_manager_execute.  */
  41    r = pr_mgr_class->run(pr_mgr, fd, hdr);
  42    object_unref(OBJECT(pr_mgr));
  43    return r;
  44}
  45
  46
  47BlockAIOCB *pr_manager_execute(PRManager *pr_mgr,
  48                               AioContext *ctx, int fd,
  49                               struct sg_io_hdr *hdr,
  50                               BlockCompletionFunc *complete,
  51                               void *opaque)
  52{
  53    PRManagerData *data = g_new(PRManagerData, 1);
  54    ThreadPool *pool = aio_get_thread_pool(ctx);
  55
  56    trace_pr_manager_execute(fd, hdr->cmdp[0], hdr->cmdp[1], opaque);
  57    data->pr_mgr = pr_mgr;
  58    data->fd = fd;
  59    data->hdr = hdr;
  60
  61    /* The matching object_unref is in pr_manager_worker.  */
  62    object_ref(OBJECT(pr_mgr));
  63    return thread_pool_submit_aio(pool, pr_manager_worker,
  64                                  data, complete, opaque);
  65}
  66
  67static const TypeInfo pr_manager_info = {
  68    .parent = TYPE_OBJECT,
  69    .name = TYPE_PR_MANAGER,
  70    .class_size = sizeof(PRManagerClass),
  71    .abstract = true,
  72    .interfaces = (InterfaceInfo[]) {
  73        { TYPE_USER_CREATABLE },
  74        { }
  75    }
  76};
  77
  78PRManager *pr_manager_lookup(const char *id, Error **errp)
  79{
  80    Object *obj;
  81    PRManager *pr_mgr;
  82
  83    obj = object_resolve_path_component(object_get_objects_root(), id);
  84    if (!obj) {
  85        error_setg(errp, "No persistent reservation manager with id '%s'", id);
  86        return NULL;
  87    }
  88
  89    pr_mgr = (PRManager *)
  90        object_dynamic_cast(obj,
  91                            TYPE_PR_MANAGER);
  92    if (!pr_mgr) {
  93        error_setg(errp,
  94                   "Object with id '%s' is not a persistent reservation manager",
  95                   id);
  96        return NULL;
  97    }
  98
  99    return pr_mgr;
 100}
 101
 102static void
 103pr_manager_register_types(void)
 104{
 105    type_register_static(&pr_manager_info);
 106}
 107
 108
 109type_init(pr_manager_register_types);
 110