From e2c57de2d5c10425cc35f76170928946bbef727c Mon Sep 17 00:00:00 2001 From: Brian M Date: Thu, 14 May 2026 10:11:39 -0700 Subject: [PATCH] scst_vdisk: enable bind_alua_state for fileio devices Wire the on_alua_state_change_{start,finish} callbacks into vdisk_file_devtype and expose bind_alua_state as a sysfs attribute and create-time parameter for fileio. The callback bodies were already backing-agnostic; rename them from blockio_* to vdev_* to match. Default bind_alua_state=0 for fileio (vs. 1 for blockio) to preserve existing behavior on upgrade. Adjust the sysfs show function to compare against the per-backing default so scstadmin persists explicit settings correctly. --- scst/README | 59 +++++++++++-------- scst/src/dev_handlers/scst_vdisk.c | 29 ++++++--- .../scst-1.0.0/t/07-scstadmin-args.t | 1 + 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/scst/README b/scst/README index 841338908..f4e51cb43 100644 --- a/scst/README +++ b/scst/README @@ -1273,24 +1273,29 @@ blocksize, nv_cache, read_only, removable, rotational, thin_provisioned, tst, dif_mode, dif_type, dif_static_app_tag, dif_filename. See vdisk_fileio above for description of those parameters. -vdisk_blockio devices have the following two additional attributes: +vdisk_fileio and vdisk_blockio devices have the following two additional +attributes: -- active - if this flag is set (the default), the backing block device +- active - if this flag is set (the default), the backing device or file will be opened when the SCST device is added/opened. If a SCST device - is opened with active=0 then the backing block device will not be + is opened with active=0 then the backing device or file will not be opened, allowing for an active/passive SCST configuration. In addition, this attribute is writable via sysfs allowing the user to open/close the - backing block device on the fly, or via a script. + backing device or file on the fly, or via a script. -- bind_alua_state - if this flag is set (the default), when the device is - associated with an ALUA device group, and a target group ALUA state - changes to the active/nonoptimized state, the active attribute will be - set to 1 which attempts to open the backing block device. If the target - group ALUA state changes to a value other than active/nonoptimized, the - backing device will be closed (active=0). If bind_alua_state=0 for a +- bind_alua_state - if this flag is set, when the device is associated + with an ALUA device group, and a target group ALUA state changes to + the active/optimized or active/nonoptimized state, the active attribute + will be set to 1 which attempts to open the backing device or file. If + the target group ALUA state changes to any other value, the backing + device or file will be closed (active=0). If bind_alua_state=0 for a device the ALUA state changes have NO effect on the active attribute, it is left up to the user to use a script, or manually set the active - attribute to open/close the backing block device. + attribute to open/close the backing device or file. + + The default differs by backing type: vdisk_blockio defaults to + bind_alua_state=1, vdisk_fileio defaults to bind_alua_state=0 + (preserves the historical fileio behavior on upgrade). Handler vdisk_nullio provides NULLIO mode to create virtual devices. In this mode no real I/O is done, but success returned to initiators. @@ -1768,14 +1773,14 @@ DEVICE_GROUP dgroup2 { } } -Note, if you are using "active" BLOCKIO device attribute to prevent open -of the backend block device on the passive node, it is not recommended -to set both active ("active", "nonoptimized") and passive ("standby", -etc.) ALUA states for the same device if "bind_alua_state=1" is used, as -shown above to keep internal "active" state of the BLOCKIO device consistent. +Note, if you are using the "active" device attribute to prevent open of +the backend device or file on the passive node, it is not recommended to +set both active ("active", "nonoptimized") and passive ("standby", etc.) +ALUA states for the same device if "bind_alua_state=1" is used, as shown +above to keep the internal "active" state of the device consistent. -If using the "active" BLOCKIO device attribute and multiple target groups -exist per device on a SCST instance then "bind_alua_state=0" should be used +If using the "active" device attribute and multiple target groups exist +per device on a SCST instance then "bind_alua_state=0" should be used and it is left up to the user to modify the "active" attribute value. Explicit ALUA @@ -1795,20 +1800,22 @@ DRBD as well as other replication/failover SW does not allow to open its device on the secondary as well as does not allow to perform primary to secondary transition, if this device is open. -SCST BLOCKIO handler has necessary support for such behavior: +SCST BLOCKIO and FILEIO handlers have necessary support for such behavior: -1. If you need to prevent an SCST BLOCKIO device from opening its block -device, you need to create it with parameter "active=0". In case of DRBD +1. If you need to prevent an SCST device from opening its backing device +or file, you need to create it with parameter "active=0". In case of DRBD it would be done automatically, you don't have to use the "active" attribute. -2. By default, if you write new ALUA state in the "state" attribute and -"bind_alua_state=1" for the device, SCST BLOCKIO handler before transition +2. If you write new ALUA state in the "state" attribute and +"bind_alua_state=1" for the device, the SCST handler before transition closes open handles on all affected SCST devices and after transition reopens them, if the new state is active or nonoptimized. Alternatively, -set "bind_alua_state=0" for SCST BLOCKIO devices and ALUA state changes -will not open/close the backing block device, the user will need to handle -this manually or via a cluster RA in an HA setup. +set "bind_alua_state=0" for SCST devices and ALUA state changes will not +open/close the backing device or file; the user will need to handle this +manually or via a cluster RA in an HA setup. Note that BLOCKIO defaults +to "bind_alua_state=1" while FILEIO defaults to "bind_alua_state=0"; +enable it explicitly on FILEIO devices that should participate. Thus, the recommended implicit ALUA state change procedure for primary to secondary transition is: diff --git a/scst/src/dev_handlers/scst_vdisk.c b/scst/src/dev_handlers/scst_vdisk.c index 9a979da0b..77784c619 100644 --- a/scst/src/dev_handlers/scst_vdisk.c +++ b/scst/src/dev_handlers/scst_vdisk.c @@ -6217,9 +6217,9 @@ static enum compl_status_e nullio_exec_verify(struct vdisk_cmd_params *p) return CMD_SUCCEEDED; } -static void blockio_on_alua_state_change_start(struct scst_device *dev, - enum scst_tg_state old_state, - enum scst_tg_state new_state) +static void vdev_on_alua_state_change_start(struct scst_device *dev, + enum scst_tg_state old_state, + enum scst_tg_state new_state) { struct scst_vdisk_dev *virt_dev = dev->dh_priv; const bool close = virt_dev->dev_active && @@ -6246,9 +6246,9 @@ static void blockio_on_alua_state_change_start(struct scst_device *dev, TRACE_EXIT(); } -static void blockio_on_alua_state_change_finish(struct scst_device *dev, - enum scst_tg_state old_state, - enum scst_tg_state new_state) +static void vdev_on_alua_state_change_finish(struct scst_device *dev, + enum scst_tg_state old_state, + enum scst_tg_state new_state) { struct scst_vdisk_dev *virt_dev = dev->dh_priv; const bool open = !virt_dev->dev_active && @@ -7052,6 +7052,8 @@ static int vdev_fileio_add_device(const char *device_name, char *params) virt_dev->wt_flag = DEF_WRITE_THROUGH; virt_dev->nv_cache = DEF_NV_CACHE; virt_dev->o_direct_flag = DEF_O_DIRECT; + /* Opt-in for fileio; preserves pre-existing behavior on upgrade. */ + virt_dev->bind_alua_state = 0; res = vdev_parse_add_dev_params(virt_dev, params, NULL); if (res != 0) @@ -9263,7 +9265,12 @@ static ssize_t vdev_sysfs_bind_alua_state_show(struct kobject *kobj, ret = sysfs_emit(buf, "%d\n", bind_alua_state); - if (bind_alua_state != DEF_BIND_ALUA_STATE) + /* + * Per-backing default: blockio defaults to 1 (close/reopen FD on ALUA + * state change), fileio defaults to 0 (opt-in). Mark non-default so + * scstadmin knows to persist explicit settings. + */ + if (bind_alua_state != (virt_dev->blockio ? 1 : 0)) ret += sysfs_emit_at(buf, ret, "%s\n", SCST_SYSFS_KEY_MARK); TRACE_EXIT_RES(ret); @@ -9502,6 +9509,7 @@ static struct scst_trace_log vdisk_local_trace_tbl[] = { static const struct attribute *vdisk_fileio_attrs[] = { &vdev_active_attr.attr, + &vdev_bind_alua_state_attr.attr, &vdev_size_ro_attr.attr, &vdev_size_mb_ro_attr.attr, &vdisk_blocksize_attr.attr, @@ -9537,6 +9545,7 @@ static const struct attribute *vdisk_fileio_attrs[] = { static const char *const fileio_add_dev_params[] = { "active", "async", + "bind_alua_state", "blocksize", "cluster_mode", "dif_filename", @@ -9576,6 +9585,8 @@ static struct scst_dev_type vdisk_file_devtype = { .parse = fileio_parse, .exec = fileio_exec, .on_free_cmd = fileio_on_free_cmd, + .on_alua_state_change_start = vdev_on_alua_state_change_start, + .on_alua_state_change_finish = vdev_on_alua_state_change_finish, .task_mgmt_fn_done = vdisk_task_mgmt_fn_done, #ifdef CONFIG_DEBUG_EXT_COPY_REMAP .ext_copy_remap = vdev_ext_copy_remap, @@ -9662,8 +9673,8 @@ static struct scst_dev_type vdisk_blk_devtype = { .detach_tgt = vdisk_detach_tgt, .parse = non_fileio_parse, .exec = blockio_exec, - .on_alua_state_change_start = blockio_on_alua_state_change_start, - .on_alua_state_change_finish = blockio_on_alua_state_change_finish, + .on_alua_state_change_start = vdev_on_alua_state_change_start, + .on_alua_state_change_finish = vdev_on_alua_state_change_finish, .task_mgmt_fn_done = vdisk_task_mgmt_fn_done, .get_supported_opcodes = vdisk_get_supported_opcodes, .devt_priv = (void *)blockio_ops, diff --git a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t index cc2dd631a..c44ef338a 100644 --- a/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t +++ b/scstadmin/scstadmin.sysfs/scst-1.0.0/t/07-scstadmin-args.t @@ -393,6 +393,7 @@ Collecting current configuration: done. Device CREATE attributes available ---------------------------------- async + bind_alua_state blocksize cluster_mode dif_filename