Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add media change support v2 #435

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions configfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,23 @@ int tcmu_get_attribute(struct tcmu_device *dev, const char *name)
return tcmu_get_cfgfs_int(path);
}

int tcmu_set_control(struct tcmu_device *dev, const char *key, unsigned long val)
{
char path[PATH_MAX];
char buf[CFGFS_BUF_SIZE];

snprintf(path, sizeof(path), CFGFS_CORE"/%s/%s/control",
dev->tcm_hba_name, dev->tcm_dev_name);
snprintf(buf, sizeof(buf), "%s=%lu", key, val);

return tcmu_set_cfgfs_str(path, buf, strlen(buf) + 1);
#define tcmu_set_cfgfs_ctrl(type_name, type, type_frmt) \
int tcmu_set_cfgfs_ctrl_##type_name(struct tcmu_device *dev, \
const char *key, type val) \
{ \
char path[PATH_MAX]; \
char buf[CFGFS_BUF_SIZE]; \
\
snprintf(path, sizeof(path), CFGFS_CORE"/%s/%s/control", \
dev->tcm_hba_name, dev->tcm_dev_name); \
snprintf(buf, sizeof(buf), "%s="type_frmt, key, val); \
\
return tcmu_set_cfgfs_str(path, buf, strlen(buf) + 1); \
}

tcmu_set_cfgfs_ctrl(ull, unsigned long long, "%llu");
tcmu_set_cfgfs_ctrl(str, const char *, "%s");

static bool tcmu_cfgfs_mod_param_is_supported(const char *name)
{
char path[PATH_MAX];
Expand Down Expand Up @@ -211,7 +216,7 @@ int tcmu_set_dev_size(struct tcmu_device *dev)

dev_size = tcmu_get_dev_num_lbas(dev) * tcmu_get_dev_block_size(dev);

return tcmu_set_control(dev, "dev_size", dev_size);
return tcmu_set_cfgfs_ctrl_ull(dev, "dev_size", dev_size);
}

long long tcmu_get_dev_size(struct tcmu_device *dev)
Expand Down
1 change: 1 addition & 0 deletions file_optical.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,7 @@ static struct tcmur_handler fbo_handler = {
.subtype = "fbo",
.handle_cmd = fbo_handle_cmd,
.nr_threads = 1,
.medium_change_supp = 1,
};

/* Entry point must be named "handler_init". */
Expand Down
34 changes: 26 additions & 8 deletions libtcmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,22 @@ lookup_dev_by_name(struct tcmulib_context *ctx, char *dev_name, int *index)
return NULL;
}

struct tcmu_device *
tcmulib_lookup_dev_by_tcmu_name(struct tcmulib_context *ctx, char *tcmu_name)
{
struct tcmu_device **dev_ptr;
struct tcmu_device *dev;

darray_foreach(dev_ptr, ctx->devices) {
dev = *dev_ptr;

if (!strcmp(dev->tcm_dev_name, tcmu_name))
return dev;
}

return NULL;
}

static int reconfig_device(struct tcmulib_context *ctx, char *dev_name,
struct genl_info *info)
{
Expand Down Expand Up @@ -1008,11 +1024,15 @@ struct tcmulib_cmd *tcmulib_get_next_command(struct tcmu_device *dev)
return NULL;
}

static int tcmu_sts_to_scsi(int tcmu_sts, uint8_t *sense)
static int tcmu_sts_to_scsi(struct tcmu_device *dev, int tcmu_sts,
uint8_t *sense, uint8_t *cdb)
{
switch (tcmu_sts) {
case TCMU_STS_OK:
if (tcmu_sts == TCMU_STS_OK)
return SAM_STAT_GOOD;

tcmu_dev_dbg(dev, "Completing 0x%x with status %d\n", cdb[0], tcmu_sts);

switch (tcmu_sts) {
case TCMU_STS_NO_RESOURCE:
return SAM_STAT_TASK_SET_FULL;
/*
Expand All @@ -1023,6 +1043,7 @@ static int tcmu_sts_to_scsi(int tcmu_sts, uint8_t *sense)
case TCMU_STS_BUSY:
return SAM_STAT_BUSY;
case TCMU_STS_PASSTHROUGH_ERR:
case TCMU_STS_UNIT_ATTENTION:
break;
/* Check Conditions below */
case TCMU_STS_RANGE:
Expand Down Expand Up @@ -1073,10 +1094,6 @@ static int tcmu_sts_to_scsi(int tcmu_sts, uint8_t *sense)
/* Invalid copy target device type */
tcmu_set_sense_data(sense, COPY_ABORTED, 0x0D03);
break;
case TCMU_STS_CAPACITY_CHANGED:
/* Device capacity has changed */
tcmu_set_sense_data(sense, UNIT_ATTENTION, 0x2A09);
break;
case TCMU_STS_TRANSITION:
/* ALUA state transition */
tcmu_set_sense_data(sense, NOT_READY, 0x040A);
Expand Down Expand Up @@ -1145,7 +1162,8 @@ void tcmulib_command_complete(
ent->hdr.cmd_id = cmd->cmd_id;
}

ent->rsp.scsi_status = tcmu_sts_to_scsi(result, cmd->sense_buf);
ent->rsp.scsi_status = tcmu_sts_to_scsi(dev, result, cmd->sense_buf,
cmd->cdb);
if (ent->rsp.scsi_status == SAM_STAT_CHECK_CONDITION) {
memcpy(ent->rsp.sense_buffer, cmd->sense_buf,
TCMU_SENSE_BUFFERSIZE);
Expand Down
7 changes: 7 additions & 0 deletions libtcmu.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,13 @@ void tcmulib_processing_complete(struct tcmu_device *dev);
/* Clean up loose ends when exiting */
void tcmulib_close(struct tcmulib_context *ctx);

/*
* Get a tcmu_device by its tcmu name. tcmu_name is the string found in:
* /sys/kernel/config/target/core/user_$N/$tcmu_name
*/
struct tcmu_device *tcmulib_lookup_dev_by_tcmu_name(struct tcmulib_context *ctx,
char *tcmu_name);

#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 4 additions & 2 deletions libtcmu_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ enum {
TCMU_STS_NO_RESOURCE,
/* handler has setup sense. */
TCMU_STS_PASSTHROUGH_ERR,
/* UA code has setup the sense */
TCMU_STS_UNIT_ATTENTION,
TCMU_STS_BUSY,
TCMU_STS_WR_ERR,
TCMU_STS_RD_ERR,
Expand All @@ -46,7 +48,6 @@ enum {
TCMU_STS_HW_ERR,
TCMU_STS_RANGE,
TCMU_STS_FRMT_IN_PROGRESS,
TCMU_STS_CAPACITY_CHANGED,
TCMU_STS_NOTSUPP_SAVE_PARAMS,
TCMU_STS_WR_ERR_INCOMPAT_FRMT,
TCMU_STS_TRANSITION,
Expand Down Expand Up @@ -151,13 +152,14 @@ int tcmu_set_cfgfs_str(const char *path, const char *val, int val_len);
int tcmu_get_cfgfs_int(const char *path);
int tcmu_set_cfgfs_ul(const char *path, unsigned long val);
int tcmu_get_attribute(struct tcmu_device *dev, const char *name);
int tcmu_set_cfgfs_ctrl_str(struct tcmu_device *dev, const char *key,
const char *val);
bool tcmu_cfgfs_file_is_supported(struct tcmu_device *dev, const char *name);
int tcmu_exec_cfgfs_dev_action(struct tcmu_device *dev, const char *name,
unsigned long val);
int tcmu_set_dev_size(struct tcmu_device *dev);
long long tcmu_get_dev_size(struct tcmu_device *dev);
char *tcmu_get_wwn(struct tcmu_device *dev);
int tcmu_set_control(struct tcmu_device *dev, const char *key, unsigned long val);
void tcmu_reset_netlink(void);
void tcmu_block_netlink(void);
void tcmu_unblock_netlink(void);
Expand Down
Loading