Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/Documentation/ABI/testing/   (LibreOffice Version 25.8.3.2©)  Datei vom 24.10.2025 mit Größe 542 B image not shown  

Quelle  fault_inject.c   Sprache: unbekannt

 
// SPDX-License-Identifier: GPL-2.0

/*
 * Fault injection ublk target. Hack this up however you like for
 * testing specific behaviors of ublk_drv. Currently is a null target
 * with a configurable delay before completing each I/O. This delay can
 * be used to test ublk_drv's handling of I/O outstanding to the ublk
 * server when it dies.
 */


#include "kublk.h"

static int ublk_fault_inject_tgt_init(const struct dev_ctx *ctx,
          struct ublk_dev *dev)
{
 const struct ublksrv_ctrl_dev_info *info = &dev->dev_info;
 unsigned long dev_size = 250UL << 30;

 if (ctx->auto_zc_fallback) {
  ublk_err("%s: not support auto_zc_fallback\n", __func__);
  return -EINVAL;
 }

 dev->tgt.dev_size = dev_size;
 dev->tgt.params = (struct ublk_params) {
  .types = UBLK_PARAM_TYPE_BASIC,
  .basic = {
   .logical_bs_shift = 9,
   .physical_bs_shift = 12,
   .io_opt_shift  = 12,
   .io_min_shift  = 9,
   .max_sectors  = info->max_io_buf_bytes >> 9,
   .dev_sectors  = dev_size >> 9,
  },
 };

 dev->private_data = (void *)(unsigned long)(ctx->fault_inject.delay_us * 1000);
 return 0;
}

static int ublk_fault_inject_queue_io(struct ublk_thread *t,
          struct ublk_queue *q, int tag)
{
 const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);
 struct io_uring_sqe *sqe;
 struct __kernel_timespec ts = {
  .tv_nsec = (long long)q->dev->private_data,
 };

 ublk_io_alloc_sqes(t, &sqe, 1);
 io_uring_prep_timeout(sqe, &ts, 10);
 sqe->user_data = build_user_data(tag, ublksrv_get_op(iod), 0, q->q_id, 1);

 ublk_queued_tgt_io(t, q, tag, 1);

 return 0;
}

static void ublk_fault_inject_tgt_io_done(struct ublk_thread *t,
       struct ublk_queue *q,
       const struct io_uring_cqe *cqe)
{
 unsigned tag = user_data_to_tag(cqe->user_data);
 const struct ublksrv_io_desc *iod = ublk_get_iod(q, tag);

 if (cqe->res != -ETIME)
  ublk_err("%s: unexpected cqe res %d\n", __func__, cqe->res);

 if (ublk_completed_tgt_io(t, q, tag))
  ublk_complete_io(t, q, tag, iod->nr_sectors << 9);
 else
  ublk_err("%s: io not complete after 1 cqe\n", __func__);
}

static void ublk_fault_inject_cmd_line(struct dev_ctx *ctx, int argc, char *argv[])
{
 static const struct option longopts[] = {
  { "delay_us",  1, NULL,  0  },
  { 0000 }
 };
 int option_idx, opt;

 ctx->fault_inject.delay_us = 0;
 while ((opt = getopt_long(argc, argv, "",
      longopts, &option_idx)) != -1) {
  switch (opt) {
  case 0:
   if (!strcmp(longopts[option_idx].name, "delay_us"))
    ctx->fault_inject.delay_us = strtoll(optarg, NULL, 10);
  }
 }
}

static void ublk_fault_inject_usage(const struct ublk_tgt_ops *ops)
{
 printf("\tfault_inject: [--delay_us us (default 0)]\n");
}

const struct ublk_tgt_ops fault_inject_tgt_ops = {
 .name = "fault_inject",
 .init_tgt = ublk_fault_inject_tgt_init,
 .queue_io = ublk_fault_inject_queue_io,
 .tgt_io_done = ublk_fault_inject_tgt_io_done,
 .parse_cmd_line = ublk_fault_inject_cmd_line,
 .usage = ublk_fault_inject_usage,
};

Messung V0.5 in Prozent
C=96 H=88 G=91

[Dauer der Verarbeitung: 0.2 Sekunden, vorverarbeitet 2026-06-07]