diff --git a/scst/README b/scst/README index 022b537b9..836e195ae 100644 --- a/scst/README +++ b/scst/README @@ -483,6 +483,9 @@ following files and directories under /proc/scsi_tgt: - "del NAME" to /proc/scsi_tgt/groups/GROUP_NAME/names deletes name "NAME" from group "GROUP_NAME" + - "move NAME NEW_GROUP_NAME" to /proc/scsi_tgt/groups/OLD_GROUP_NAME/names + moves name "NAME" from group "OLD_GROUP_NAME" to group "NEW_GROUP_NAME". + - "clear" to /proc/scsi_tgt/groups/GROUP_NAME/names clears the list of names for group "GROUP_NAME" diff --git a/scst/README_in-tree b/scst/README_in-tree index 388c59617..f0abba00b 100644 --- a/scst/README_in-tree +++ b/scst/README_in-tree @@ -401,6 +401,9 @@ following files and directories under /proc/scsi_tgt: - "del NAME" to /proc/scsi_tgt/groups/GROUP_NAME/names deletes name "NAME" from group "GROUP_NAME" + - "move NAME NEW_GROUP_NAME" to /proc/scsi_tgt/groups/OLD_GROUP_NAME/names + moves name "NAME" from group "OLD_GROUP_NAME" to group "NEW_GROUP_NAME". + - "clear" to /proc/scsi_tgt/groups/GROUP_NAME/names clears the list of names for group "GROUP_NAME" diff --git a/scst/include/scst_debug.h b/scst/include/scst_debug.h index cf009efe3..c20c926b1 100644 --- a/scst/include/scst_debug.h +++ b/scst/include/scst_debug.h @@ -258,26 +258,26 @@ do { \ #define PRINT_WARNING(format, args...) \ do { \ if (strcmp(INFO_FLAG, LOG_FLAG)) { \ - PRINT_LOG_FLAG(LOG_FLAG, "***WARNING*** " format, args); \ + PRINT_LOG_FLAG(LOG_FLAG, "***WARNING***: " format, args); \ } \ - PRINT_LOG_FLAG(INFO_FLAG, "***WARNING*** " format, args); \ + PRINT_LOG_FLAG(INFO_FLAG, "***WARNING***: " format, args); \ } while (0) #define PRINT_ERROR(format, args...) \ do { \ if (strcmp(ERROR_FLAG, LOG_FLAG)) { \ - PRINT_LOG_FLAG(LOG_FLAG, "***ERROR*** " format, args); \ + PRINT_LOG_FLAG(LOG_FLAG, "***ERROR***: " format, args); \ } \ - PRINT_LOG_FLAG(ERROR_FLAG, "***ERROR*** " format, args); \ + PRINT_LOG_FLAG(ERROR_FLAG, "***ERROR***: " format, args); \ } while (0) #define PRINT_CRIT_ERROR(format, args...) \ do { \ /* if (strcmp(CRIT_FLAG, LOG_FLAG)) \ { \ - PRINT_LOG_FLAG(LOG_FLAG, "***CRITICAL ERROR*** " format, args); \ + PRINT_LOG_FLAG(LOG_FLAG, "***CRITICAL ERROR***: " format, args); \ }*/ \ - PRINT_LOG_FLAG(CRIT_FLAG, "***CRITICAL ERROR*** " format, args); \ + PRINT_LOG_FLAG(CRIT_FLAG, "***CRITICAL ERROR***: " format, args); \ } while (0) #define PRINT_INFO(format, args...) \ @@ -366,19 +366,19 @@ do { \ #define PRINT_WARNING(format, args...) \ do { \ - PRINT(INFO_FLAG, "%s: ***WARNING*** " \ + PRINT(INFO_FLAG, "%s: ***WARNING***: " \ format, LOG_PREFIX, args); \ } while (0) #define PRINT_ERROR(format, args...) \ do { \ - PRINT(ERROR_FLAG, "%s: ***ERROR*** " \ + PRINT(ERROR_FLAG, "%s: ***ERROR***: " \ format, LOG_PREFIX, args); \ } while (0) #define PRINT_CRIT_ERROR(format, args...) \ do { \ - PRINT(CRIT_FLAG, "%s: ***CRITICAL ERROR*** " \ + PRINT(CRIT_FLAG, "%s: ***CRITICAL ERROR***: " \ format, LOG_PREFIX, args); \ } while (0) @@ -391,19 +391,19 @@ do { \ #define PRINT_WARNING(format, args...) \ do { \ - PRINT(INFO_FLAG, "***WARNING*** " \ + PRINT(INFO_FLAG, "***WARNING***: " \ format, args); \ } while (0) #define PRINT_ERROR(format, args...) \ do { \ - PRINT(ERROR_FLAG, "***ERROR*** " \ + PRINT(ERROR_FLAG, "***ERROR***: " \ format, args); \ } while (0) #define PRINT_CRIT_ERROR(format, args...) \ do { \ - PRINT(CRIT_FLAG, "***CRITICAL ERROR*** " \ + PRINT(CRIT_FLAG, "***CRITICAL ERROR***: " \ format, args); \ } while (0) diff --git a/scst/src/scst_lib.c b/scst/src/scst_lib.c index 09da5ce75..cb139cadc 100644 --- a/scst/src/scst_lib.c +++ b/scst/src/scst_lib.c @@ -1836,7 +1836,7 @@ void __scst_acg_remove_acn(struct scst_acn *n) } /* The activity supposed to be suspended and scst_mutex held */ -int scst_acg_remove_name(struct scst_acg *acg, const char *name) +int scst_acg_remove_name(struct scst_acg *acg, const char *name, bool reassign) { int res = -EINVAL; struct scst_acn *n; @@ -1854,7 +1854,8 @@ int scst_acg_remove_name(struct scst_acg *acg, const char *name) if (res == 0) { PRINT_INFO("Removed name %s from group %s", name, acg->acg_name); - scst_check_reassign_sessions(); + if (reassign) + scst_check_reassign_sessions(); } else PRINT_ERROR("Unable to find name %s in group %s", name, acg->acg_name); diff --git a/scst/src/scst_main.c b/scst/src/scst_main.c index c47d59cd0..33708c306 100644 --- a/scst/src/scst_main.c +++ b/scst/src/scst_main.c @@ -678,15 +678,13 @@ out_resume: out_err: if (res == 0) { - PRINT_INFO("Attached SCSI target mid-level at " - "scsi%d, channel %d, id %d, lun %d, type %d", - scsidp->host->host_no, scsidp->channel, scsidp->id, - scsidp->lun, scsidp->type); + PRINT_INFO("Attached to scsi%d, channel %d, id %d, lun %d, " + "type %d", scsidp->host->host_no, scsidp->channel, + scsidp->id, scsidp->lun, scsidp->type); } else { - PRINT_ERROR("Failed to attach SCSI target mid-level " - "at scsi%d, channel %d, id %d, lun %d, type %d", - scsidp->host->host_no, scsidp->channel, scsidp->id, - scsidp->lun, scsidp->type); + PRINT_ERROR("Failed to to scsi%d, channel %d, id %d, lun %d, " + "type %d", scsidp->host->host_no, scsidp->channel, + scsidp->id, scsidp->lun, scsidp->type); } TRACE_EXIT_RES(res); @@ -736,9 +734,9 @@ static void scst_unregister_device(struct scsi_device *scsidp) put_disk(dev->rq_disk); scst_free_device(dev); - PRINT_INFO("Detached SCSI target mid-level from scsi%d, channel %d, " - "id %d, lun %d, type %d", scsidp->host->host_no, - scsidp->channel, scsidp->id, scsidp->lun, scsidp->type); + PRINT_INFO("Detached from scsi%d, channel %d, id %d, lun %d, type %d", + scsidp->host->host_no, scsidp->channel, scsidp->id, + scsidp->lun, scsidp->type); out_unblock: mutex_unlock(&scst_mutex); @@ -835,13 +833,11 @@ out_resume: scst_resume_activity(); out: - if (res > 0) { - PRINT_INFO("Attached SCSI target mid-level to virtual " - "device %s (id %d)", dev_name, dev->virt_id); - } else { - PRINT_INFO("Failed to attach SCSI target mid-level to " - "virtual device %s", dev_name); - } + if (res > 0) + PRINT_INFO("Attached to virtual device %s (id %d)", + dev_name, dev->virt_id); + else + PRINT_INFO("Failed to attach to virtual device %s", dev_name); TRACE_EXIT_RES(res); return res; @@ -885,8 +881,8 @@ void scst_unregister_virtual_device(int id) scst_assign_dev_handler(dev, &scst_null_devtype); - PRINT_INFO("Detached SCSI target mid-level from virtual device %s " - "(id %d)", dev->virt_name, dev->virt_id); + PRINT_INFO("Detached from virtual device %s (id %d)", + dev->virt_name, dev->virt_id); scst_free_device(dev); diff --git a/scst/src/scst_priv.h b/scst/src/scst_priv.h index 080a76071..7ae0562aa 100644 --- a/scst/src/scst_priv.h +++ b/scst/src/scst_priv.h @@ -305,7 +305,7 @@ int scst_acg_add_dev(struct scst_acg *acg, struct scst_device *dev, int scst_acg_remove_dev(struct scst_acg *acg, struct scst_device *dev); int scst_acg_add_name(struct scst_acg *acg, const char *name); -int scst_acg_remove_name(struct scst_acg *acg, const char *name); +int scst_acg_remove_name(struct scst_acg *acg, const char *name, bool reassign); void __scst_acg_remove_acn(struct scst_acn *n); int scst_prepare_request_sense(struct scst_cmd *orig_cmd); diff --git a/scst/src/scst_proc.c b/scst/src/scst_proc.c index 90aceb942..734d30404 100644 --- a/scst/src/scst_proc.c +++ b/scst/src/scst_proc.c @@ -78,12 +78,13 @@ static struct scst_proc_data scst_dev_handler_proc_data; #define SCST_PROC_ACTION_SET 4 #define SCST_PROC_ACTION_ADD 5 #define SCST_PROC_ACTION_CLEAR 6 -#define SCST_PROC_ACTION_DEL 7 -#define SCST_PROC_ACTION_VALUE 8 -#define SCST_PROC_ACTION_ASSIGN 9 -#define SCST_PROC_ACTION_ADD_GROUP 10 -#define SCST_PROC_ACTION_DEL_GROUP 11 -#define SCST_PROC_ACTION_RENAME_GROUP 12 +#define SCST_PROC_ACTION_MOVE 7 +#define SCST_PROC_ACTION_DEL 8 +#define SCST_PROC_ACTION_VALUE 9 +#define SCST_PROC_ACTION_ASSIGN 10 +#define SCST_PROC_ACTION_ADD_GROUP 11 +#define SCST_PROC_ACTION_DEL_GROUP 12 +#define SCST_PROC_ACTION_RENAME_GROUP 13 static struct proc_dir_entry *scst_proc_scsi_tgt; static struct proc_dir_entry *scst_proc_groups_root; @@ -137,6 +138,7 @@ static char *scst_proc_help_string = " echo \"clear\" >/proc/scsi_tgt/groups/GROUP_NAME/devices\n" "\n" " echo \"add|del NAME\" >/proc/scsi_tgt/groups/GROUP_NAME/names\n" +" echo \"move NAME NEW_GROUP_NAME\" >/proc/scsi_tgt/groups/OLD_GROUP_NAME/names\n" " echo \"clear\" >/proc/scsi_tgt/groups/GROUP_NAME/names\n" "\n" " echo \"DEC|0xHEX|0OCT\" >/proc/scsi_tgt/threads\n" @@ -1374,6 +1376,26 @@ static ssize_t scst_proc_scsi_tgt_gen_write(struct file *file, case SCST_PROC_ACTION_ADD_GROUP: case SCST_PROC_ACTION_DEL_GROUP: case SCST_PROC_ACTION_RENAME_GROUP: + pp = p; + while (!isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + *pp = '\0'; + pp++; + while (isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + switch (action) { + case SCST_PROC_ACTION_ADD_GROUP: + case SCST_PROC_ACTION_DEL_GROUP: + PRINT_ERROR("%s", "Too many " + "arguments"); + res = -EINVAL; + goto out_up_free; + } + } + } + if (strcmp(p, SCST_DEFAULT_ACG_NAME) == 0) { PRINT_ERROR("Attempt to add/delete/rename predefined " "group \"%s\"", p); @@ -1381,25 +1403,6 @@ static ssize_t scst_proc_scsi_tgt_gen_write(struct file *file, goto out_up_free; } - pp = p; - while (!isspace(*pp) && *pp != '\0') - pp++; - if (*pp != '\0') { - switch (action) { - case SCST_PROC_ACTION_ADD_GROUP: - case SCST_PROC_ACTION_DEL_GROUP: - PRINT_ERROR("Wrong acg name %s", p); - res = -EINVAL; - goto out_up_free; - default: - *pp = '\0'; - pp++; - while (isspace(*pp) && *pp != '\0') - pp++; - break; - } - } - list_for_each_entry(a, &scst_acg_list, scst_acg_list_entry) { if (strcmp(a->acg_name, p) == 0) { TRACE_DBG("group (acg) %p %s found", @@ -1432,13 +1435,20 @@ static ssize_t scst_proc_scsi_tgt_gen_write(struct file *file, res = -EINVAL; goto out_up_free; } + p = pp; while (!isspace(*pp) && *pp != '\0') pp++; if (*pp != '\0') { - PRINT_ERROR("Wrong acg name %s", p); - res = -EINVAL; - goto out_up_free; + *pp = '\0'; + pp++; + while (isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + PRINT_ERROR("%s", "Too many arguments"); + res = -EINVAL; + goto out_up_free; + } } rc = scst_proc_rename_acg(acg, p); break; @@ -1771,7 +1781,7 @@ static ssize_t scst_proc_groups_names_write(struct file *file, size_t length, loff_t *off) { int res = length, rc = 0, action; - char *buffer, *p, *e; + char *buffer, *p, *pp = NULL; struct scst_acg *acg = (struct scst_acg *)PDE(file->f_dentry->d_inode)->data; struct scst_acn *n, *nn; @@ -1804,6 +1814,7 @@ static ssize_t scst_proc_groups_names_write(struct file *file, /* * Usage: echo "add|del NAME" >/proc/scsi_tgt/groups/GROUP_NAME/names + * or echo "move NAME NEW_GROUP_NAME" >/proc/scsi_tgt/groups/OLD_GROUP_NAME/names" * or echo "clear" >/proc/scsi_tgt/groups/GROUP_NAME/names */ p = buffer; @@ -1817,6 +1828,9 @@ static ssize_t scst_proc_groups_names_write(struct file *file, } else if (!strncasecmp("del ", p, 4)) { p += 4; action = SCST_PROC_ACTION_DEL; + } else if (!strncasecmp("move ", p, 5)) { + p += 5; + action = SCST_PROC_ACTION_MOVE; } else { PRINT_ERROR("Unknown action \"%s\"", p); res = -EINVAL; @@ -1826,12 +1840,28 @@ static ssize_t scst_proc_groups_names_write(struct file *file, switch (action) { case SCST_PROC_ACTION_ADD: case SCST_PROC_ACTION_DEL: + case SCST_PROC_ACTION_MOVE: while (isspace(*p) && *p != '\0') p++; - e = p; - while (!isspace(*e) && *e != '\0') - e++; - *e = 0; + pp = p; + while (!isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + *pp = '\0'; + pp++; + while (isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + switch (action) { + case SCST_PROC_ACTION_ADD: + case SCST_PROC_ACTION_DEL: + PRINT_ERROR("%s", "Too many " + "arguments"); + res = -EINVAL; + goto out_free; + } + } + } break; } @@ -1849,8 +1879,45 @@ static ssize_t scst_proc_groups_names_write(struct file *file, rc = scst_acg_add_name(acg, p); break; case SCST_PROC_ACTION_DEL: - rc = scst_acg_remove_name(acg, p); + rc = scst_acg_remove_name(acg, p, true); break; + case SCST_PROC_ACTION_MOVE: + { + struct scst_acg *a, *new_acg = NULL; + char *name = p; + p = pp; + while (!isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + *pp = '\0'; + pp++; + while (isspace(*pp) && *pp != '\0') + pp++; + if (*pp != '\0') { + PRINT_ERROR("%s", "Too many arguments"); + res = -EINVAL; + goto out_free_unlock; + } + } + list_for_each_entry(a, &scst_acg_list, scst_acg_list_entry) { + if (strcmp(a->acg_name, p) == 0) { + TRACE_DBG("group (acg) %p %s found", + a, a->acg_name); + new_acg = a; + break; + } + } + if (new_acg == NULL) { + PRINT_ERROR("Group %s not found", p); + res = -EINVAL; + goto out_free_unlock; + } + rc = scst_acg_remove_name(acg, name, false); + if (rc != 0) + goto out_free_unlock; + rc = scst_acg_add_name(new_acg, name); + break; + } case SCST_PROC_ACTION_CLEAR: list_for_each_entry_safe(n, nn, &acg->acn_list, acn_list_entry) { @@ -1860,6 +1927,7 @@ static ssize_t scst_proc_groups_names_write(struct file *file, break; } +out_free_unlock: mutex_unlock(&scst_mutex); out_free_resume: