On 08/07/2014 01:35 AM, Andy Grover wrote:
I don't believe any kernel code needs to be changed, it's just a matter
of developing and announcing a convention that other accessors would be
expected to follow. One that I prototyped a while back was lockf() on
/var/run/target.lock for everything, but we could define finer
granularity locking too. A given library used by multiple clients could
have each client try to acquire the global lock, or acquire it once and
then handle concurrency its own way.
Regards -- Andy
p.s. I'm cribbing this technique from git://linux-nfs.org/nfs-utils
utils/exportfs/exportfs.c, seems like the same issue as what they're
solving in a similar manner.
Sounds good to me.
Regarding granularity of locks, I am tempted to go for top-level objects
locks: targets and backstores, the latter being almost equivalent to
locking storage objects as we only use 1:1 mapping these days.
However that poses a couple of semantics problems.
What happens when a target gets deleted? We have to release that lock,
so we must somehow enforce a sane behavior for the code acquiring a lock
for a defunct object. And I am afraid this is easy to do in the context
of rtslib, but difficult to push it as a mere convention, at least in
another ballpark as just agreeing on a lock convention. Maybe this is
not a problem for real use cases, but we must be careful there.
Also, there is the question of target --LUN-> storage object
dependencies. Acquiring a lock on a backstore effectively means that you
can impact the behavior of dependent targets. And in the worst case,
backstore deletion, that would mean deleting LUNs as a side effect.
Which probably means either finer semantics or enforcing bundled locks
(to acquire a lock on a backstore, you need to acquire first a lock on
all targets having LUNs using that backstore). Again, this gets complicated.
Still, I would like to explore the possibility before resorting to a
global lock convention + higher-level (i.e the rtslib.config API or
something like targetd) implementation of a second layer of
finer-grained locking.
To explain the reason for this, imagine the following scenario. You have
something like a remote API daemon running on the machine, that
arbitrates his clients and grants them individual access to separate
configuration parts. So far, so good.
Now, you have a choice to make:
A) That remote API daemon hang onto the global lock for its entire
runtime. In effect, the locking strategy prevents using local tools to
alter the configuration, negating the initial intent which is to allow
concurrent usage of different tools.
B) You only grab the global lock when at least a client requests a
finer-grained lock, and release it when no active client transactions
exist. Then, some admin could sneak in, run targetcli and hold the lock.
If that guy leaves his screen session detached with a running targetcli,
then your nice remote API is effectively dead...
So, of course could go for A and claim that if you want to manage your
targets through a persistent daemon, the price to pay is loosing the
ability to use any other means of safe target configuration while it is
running. And the simpler case of concurrent targetcli/other admin tools
usage would still be solved anyway.
But I feel that even though the scenario above might be not so
problematic, maybe even contrived, there might be other cases we haven't
though about yet leading to the same class of problem.
And BTW, I do realize that targetcli could request the global lock only
when performing an actual configfs write, instead of holding it for the
lifetime of a session. But given the very imperative nature of 2.x
targetcli, this means that an admin could start a series of changes that
only make sense if they are run to completion, and then fail to acquire
the lock again because meanwhile some script acquired the lock and
decided to hold it forever. And in some cases, 10 minutes might feel
like forever. Imagine a session where the admin needs to set login +
password + ACL. Depending on the order he does it and when he gets cut
out, this might become a problem.
However, I want to point out that this is not a problem at all for the
new lio shell - basically anything using the rtslib.config API semantics
- as in that case our admin would make a series of changes to a
candidate configuration and then only need to acquire the lock once for
the whole batch of changes before committing them.
Best,
--
Jerome
--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html