Class: UBLK::Native::Control

Inherits:
Object
  • Object
show all
Defined in:
ext/ublk/control.c

Instance Method Summary collapse

Constructor Details

#initializeObject



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'ext/ublk/control.c', line 43

static VALUE control_initialize(VALUE self)
{
  ublk_control *control;
  struct io_uring_params params;
  int result;

  TypedData_Get_Struct(self, ublk_control, &control_type, control);
  control->fd = open("/dev/ublk-control", O_RDWR | O_CLOEXEC);
  if (control->fd < 0) rb_sys_fail("open(/dev/ublk-control)");

  memset(&params, 0, sizeof(params));
  params.flags = IORING_SETUP_SQE128;
  result = io_uring_queue_init_params(8, &control->ring, &params);
  if (result < 0) {
    close(control->fd);
    control->fd = -1;
    rb_syserr_fail(-result, "io_uring_queue_init_params");
  }

  control->ring_ready = 1;
  control->pid = getpid();
  return self;
}

Instance Method Details

#add_dev(id, queues, depth, max_io_bytes, recovery) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'ext/ublk/control.c', line 170

static VALUE control_add_dev(VALUE self, VALUE id, VALUE queues, VALUE depth,
                             VALUE max_io_bytes, VALUE recovery)
{
  ublk_control *control = get_control(self);
  struct ublk_rb_dev_info info;
  int result;

  memset(&info, 0, sizeof(info));
  info.dev_id = NIL_P(id) ? UINT32_MAX : NUM2UINT(id);
  info.nr_hw_queues = NUM2UINT(queues);
  info.queue_depth = NUM2UINT(depth);
  info.max_io_buf_bytes = NUM2UINT(max_io_bytes);
  info.flags = UBLK_F_USER_COPY | UBLK_F_CMD_IOCTL_ENCODE;
  if (RTEST(recovery)) info.flags |= UBLK_F_USER_RECOVERY;

  result = control_submit(control, UBLK_RB_U_RDWR_CMD(UBLK_CMD_ADD_DEV), info.dev_id,
                          &info, sizeof(info), 0);
  ublk_raise_result(result, "UBLK_U_CMD_ADD_DEV");
  return info_to_array(&info);
}

#closeObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'ext/ublk/control.c', line 146

static VALUE control_close(VALUE self)
{
  ublk_control *control;
  TypedData_Get_Struct(self, ublk_control, &control_type, control);
  ublk_check_pid(control->pid);
  if (control->ring_ready) {
    io_uring_queue_exit(&control->ring);
    control->ring_ready = 0;
  }
  if (control->fd >= 0) {
    close(control->fd);
    control->fd = -1;
  }
  return Qnil;
}

#del_dev(id) ⇒ Object



249
250
251
252
# File 'ext/ublk/control.c', line 249

static VALUE control_del_dev(VALUE self, VALUE id)
{
  return control_simple(self, id, UBLK_CMD_DEL_DEV, "UBLK_U_CMD_DEL_DEV", 0);
}

#end_user_recovery(id, pid) ⇒ Object



259
260
261
262
# File 'ext/ublk/control.c', line 259

static VALUE control_end_recovery(VALUE self, VALUE id, VALUE pid)
{
  return control_simple(self, id, UBLK_CMD_END_USER_RECOVERY, "UBLK_U_CMD_END_USER_RECOVERY", NUM2UINT(pid));
}

#get_dev_info(id) ⇒ Object



264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'ext/ublk/control.c', line 264

static VALUE control_get_info(VALUE self, VALUE id)
{
  ublk_control *control = get_control(self);
  struct ublk_rb_dev_info info;
  int result;

  memset(&info, 0, sizeof(info));
  info.dev_id = NUM2UINT(id);
  result = control_submit(control, UBLK_RB_U_READ_CMD(UBLK_CMD_GET_DEV_INFO), info.dev_id,
                          &info, sizeof(info), 0);
  ublk_raise_result(result, "UBLK_U_CMD_GET_DEV_INFO");
  return info_to_array(&info);
}

#set_params(id, size, logical, physical, max_io, read_only, rotational, discard) ⇒ Object



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'ext/ublk/control.c', line 199

static VALUE control_set_params(VALUE self, VALUE id, VALUE size,
                                VALUE logical, VALUE physical, VALUE max_io,
                                VALUE read_only, VALUE rotational, VALUE discard)
{
  ublk_control *control = get_control(self);
  struct ublk_rb_params params;
  int result;

  memset(&params, 0, sizeof(params));
  params.len = sizeof(params);
  params.types = UBLK_PARAM_TYPE_BASIC;
  params.basic.logical_bs_shift = block_shift(logical);
  params.basic.physical_bs_shift = block_shift(physical);
  params.basic.io_min_shift = params.basic.logical_bs_shift;
  params.basic.max_sectors = NUM2ULL(max_io) >> 9;
  params.basic.dev_sectors = NUM2ULL(size) >> 9;
  params.basic.attrs = UBLK_ATTR_VOLATILE_CACHE;
  if (RTEST(read_only)) params.basic.attrs |= UBLK_ATTR_READ_ONLY;
  if (RTEST(rotational)) params.basic.attrs |= UBLK_ATTR_ROTATIONAL;
  if (RTEST(discard)) {
    params.types |= UBLK_PARAM_TYPE_DISCARD;
    params.discard.discard_granularity = NUM2UINT(logical);
    params.discard.max_discard_sectors = params.basic.max_sectors;
    params.discard.max_write_zeroes_sectors = params.basic.max_sectors;
    params.discard.max_discard_segments = 1;
  }

  result = control_submit(control, UBLK_RB_U_RDWR_CMD(UBLK_CMD_SET_PARAMS), NUM2UINT(id),
                          &params, sizeof(params), 0);
  ublk_raise_result(result, "UBLK_U_CMD_SET_PARAMS");
  return Qtrue;
}

#start_dev(id, pid) ⇒ Object



239
240
241
242
# File 'ext/ublk/control.c', line 239

static VALUE control_start_dev(VALUE self, VALUE id, VALUE pid)
{
  return control_simple(self, id, UBLK_CMD_START_DEV, "UBLK_U_CMD_START_DEV", NUM2UINT(pid));
}

#start_user_recovery(id) ⇒ Object



254
255
256
257
# File 'ext/ublk/control.c', line 254

static VALUE control_start_recovery(VALUE self, VALUE id)
{
  return control_simple(self, id, UBLK_CMD_START_USER_RECOVERY, "UBLK_U_CMD_START_USER_RECOVERY", 0);
}

#stop_dev(id) ⇒ Object



244
245
246
247
# File 'ext/ublk/control.c', line 244

static VALUE control_stop_dev(VALUE self, VALUE id)
{
  return control_simple(self, id, UBLK_CMD_STOP_DEV, "UBLK_U_CMD_STOP_DEV", 0);
}