From f11ebeafe43ea4a7d63642fcd28ee34d13a62ed5 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 30 Aug 2012 14:47:49 +0000 Subject: [PATCH] [PATCH] scstadmin: Handle -EAGAIN when reading from sysfs Reading from /sys/kernel/scst_tgt/devices/*/filename can (at least in theory) fail with -EAGAIN. Make sure that scstadmin retries reading from a sysfs variable if that happens. This patch has been tested by adding the following error injection code in scst_sysfs.c: --------------------------- scst/src/scst_sysfs.c ---------------------------- index 0509703..69efd80 100644 @@ -523,6 +523,22 @@ int scst_sysfs_queue_wait_work(struct scst_sysfs_work_item *work) "failed: %d", atomic_read(&uid_thread_name), (int)PTR_ERR(t)); +#if 1 + { + static int cnt; + if (!work->read_only_action || cnt++ % 4 < 3) { + /* + * Helps testing user space code that writes to or + * reads from SCST sysfs variables. + */ + timeout = 0; + rc = 0; + res = -EAGAIN; + goto out_put; + } + } +#endif + while (1) { rc = wait_for_completion_interruptible_timeout( &work->sysfs_work_done, timeout); ------------------------------------------------------------------------------ Signed-off-by: Bart Van Assche git-svn-id: http://svn.code.sf.net/p/scst/svn/trunk@4498 d57e44dd-8a1f-0410-8b47-8ef2f437770f --- .../scst-0.9.10/lib/SCST/SCST.pm | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm b/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm index 8c170b677..23457a2e8 100644 --- a/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm +++ b/scstadmin/scstadmin.sysfs/scst-0.9.10/lib/SCST/SCST.pm @@ -2614,10 +2614,10 @@ sub deviceAttributes { return undef; } - my $value = <$io>; + my ($value, $is_key) = split("\n", _sysread($io) , 2); + chomp $value; - my $is_key = <$io>; $is_key = new_sysfs_interface() && (!$is_static || defined($$dca{$attribute})) || ($is_key =~ /\[key\]/) ? TRUE : FALSE; @@ -4855,6 +4855,22 @@ sub errorString { return $string; } +# Read from the SCST sysfs file $1. Return either the data read or undef if +# reading failed. +sub _sysread { + my $io = shift; + my $deadline = time() + $TIMEOUT; + my $result; + + while (time() < $deadline) { + my $bytes = sysread($io, $result, 4096); + last if (defined($bytes) || $! != EAGAIN); + sleep 1; + } + + return $result; +} + # Write the first $3 bytes of $2 into the SCST sysfs file $1. Return either # the number of bytes written or undef if writing failed. sub _syswrite {