func: static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
  
                           Error **errp)
  
  {
  
      BDRVBlkdebugState *s = bs->opaque;
  
      QemuOpts *opts;
  
      Error *local_err = NULL;
  
      int ret;
  
  
  
      opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
  
      qemu_opts_absorb_qdict(opts, options, &local_err);
  
      if (local_err) {
  
          error_propagate(errp, local_err);
  
          ret = -EINVAL;
  
          goto out;
  
      }
  
  
  
      /* Read rules from config file or command line options */
  
      s->config_file = g_strdup(qemu_opt_get(opts, "config"));
  
      ret = read_config(s, s->config_file, options, errp);
  
      if (ret) {
  
          goto out;
  
      }
  
  
  
      /* Set initial state */
  
      s->state = 1;
  
  
  
      /* Open the image file */
  
      bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
  
                                 bs, &child_file, false, &local_err);
  
      if (local_err) {
  
          ret = -EINVAL;
  
          error_propagate(errp, local_err);
  
          goto out;
  
      }
  
  
  
      bs->supported_write_flags = BDRV_REQ_FUA &
  
          bs->file->bs->supported_write_flags;
  
      bs->supported_zero_flags = (BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP) &
  
          bs->file->bs->supported_zero_flags;
  
      ret = -EINVAL;
  
  
  
      /* Set request alignment */
  
      s->align = qemu_opt_get_size(opts, "align", 0);
  
      if (s->align && (s->align >= INT_MAX || !is_power_of_2(s->align))) {
  
          error_setg(errp, "Cannot meet constraints with align %" PRIu64,
  
                     s->align);
  
          goto out;
  
      }
  
  
  
      ret = 0;
  
  out:
  
      if (ret < 0) {
  
          g_free(s->config_file);
  
      }
  
      qemu_opts_del(opts);
  
      return ret;
  
  }
  