[openbeosstorage] Re: To Unmount Or Not To Unmount

On 2003-09-27 at 07:57:21 [-0700], Ingo Weinhold wrote:
> > > [...]
> > > > > > > > Oh, there's still the general question whether the user has to
> > > > > > > > Unmount()
> > > > > > > > the concerned partition explicitely, when e.g. CanResize()
> > > > > > > > reported, that
> > > > > > > > it works only when the partition is unmounted, or whether
> > > > > > > > Resize()
> > > > > > > > would
> > > > > > > > automagically do the unmounting (or at least mark the 
> > > > > > > > partition
> > > > > > > > to
> > > > > > > > be
> > > > > > > > unmounted).
> > > > > > > Perhaps an unmount call should just be placed in from of the
> > > > > > > offending job
> > > > > > > in the job queue when it's built.
> > > > > 
> > > > > What I was thinking of, was, that when a job gets executed, it would
> > > > > itself
> > > > > first invoke the respective Validate*() hooks of the disk system 
> > > > > again
> > > > > and
> > > > > learn, if the disk system needs a currently mounted partition
> > > > > unmounted,
> > > > > or
> > > > > if something's fishy and it should rather fail on the spot.
> > > > > 
> > > > > So, if it realizes that the partition is mounted, but the disk 
> > > > > system
> > > > > can
> > > > > only operate on it when unmounted, it could either a) unmount the
> > > > > partition
> > > > > or b) fail.
> > > > 
> > > > Or c) block and request that the user either unmount the partition or
> > > > cancel. Or d) block and warn the user that when they click "unmount",
> > > > the
> > > > partition will be promptly unmounted, thus they should close anything
> > > > from
> > > > that partition that they currently have open (or risk losing data) or
> > > > else
> > > > click "cancel" to cancel the job queue.
> > > >
> > > > > The problem with a) is, that it's a bit beyond the control of
> > > > > the user. If, as Axel says, unmounting would always work not heeding
> > > > > pending vnodes, then the user might risk losing data, I suppose.
> > > > 
> > > > I agree, that's a bit mean to pull the rug out from under the user 
> > > > like
> > > > that. b) seems like a weak solution, too, though. c) and d) seem nicer
> > > > to
> > > > me. Is there any reason you can think of why either couldn't be made 
> > > > to
> > > > work?
> > > 
> > > Why, yes. The job is executed in the kernel and while it would be no
> > > problem
> > > to block it, I see some difficulties, how the user should be notified 
> > > (and
> > > how to even get feedback from them). If we had the Interface Kit 
> > > available
> > > in
> > > the kernel (not that I'm recommending that; surely not :-), we could
> > > simply
> > > pop up an alert, but with the design as is, that can't be done without
> > > some
> > > additional userland service the kernel could use.
> > 
> > No, I wasn't intending to have the kernel actually pop up the alert, just
> > somehow communicate to the corresponding userland process what's going on.
> 
> The problem is, that there isn't necessarily a userland process anymore. The
> jobs are executed asynchronously in their own thread and may take quite a
> while. So, you could already have terminated DriveSetup when jobs are still
> executing and one hits a mounted partition that it would need to unmount.

I guess I figured you'd send a message to the BMessenger passed in when the 
changes were committed, failing if there was none or if it timed out after 
some period. Though I guess we'd actually need to add a BMessenger parameter 
to Unmount().

> > > Mmh, we already discussed some time ago, how to move the (kernel)
> > > notification message delivery to the registrar. The registrar would
> > > register
> > > via a to be defined interface with the kernel as an entity providing the
> > > notification message delivery service. In the same manner some
> > > server/daemon
> > > (in doubt also the registrar) could register as kernel-user interaction
> > > service. For simple multiple choice feedback requests (alerts) that
> > > shouldn't
> > > be that hard to do.
> > 
> > I was thinking more along the lines of the user process managing the disk
> > device jobs (i.e. DriveSetup, or whoever it is using the DiskDevice API)
> > registering to be notified when such feedback requests needed to be made.
> > Tracker could register to handle such cases where a user tries to manually
> > unmount a partition with open file descriptors, DriveSetup could handle
> > cases
> > where a mounted partition is scheduled to be resized by an add-on that 
> > only
> > supports offline resizing, etc.
> 
> But that would require these applications to be running. We also should be
> careful not to add things to the Tracker that the system depends on to work
> properly.

Personally, I would find closing DriveSetup while I still had partitions 
being resized or what ever to be a little disconcerting. Honestly, are you 
planning on allowing the user to close DriveSetup while jobs are in progress? 
I'm not really sure I see the point.

Anyway, my point is not to have Tracker handle *all* such notifications, as 
the registrar would, but just notifications for the operations it requests. 
I.e., a user tries to unmount a volume with Tracker, but there are open file 
descriptors, Tracker is sent a notification to let the user know and offer 
the option of forcing an unmount. Similarly, if the user uses the `unmount' 
command from a Terminal, unmount can prompt the user what they'd like to do 
if the volume has open file handles. Thus, each application would be 
responsible for handling such notifications for any operations they invoke.

> > > > > > What would we gain because of the latter?`
> > > > > 
> > > > > Obviously that one can unmount a partition, while another app is
> > > > > preparing
> > > > > modifications for the same disk device (mind you, it doesn't even 
> > > > > need
> > > > > to
> > > > > be the same partition, nor does it play a role whether any changes
> > > > > have
> > > > > been made at all, yet).
> > > > > 
> > > > > Just to throw another alternative onto the pitch: The
> > > > > Mount()/Unmount()
> > > > > methods could have a boolean parameter indicating whether the
> > > > > operation
> > > > > shall be carried out immediately or being queued. Not sure, if that
> > > > > makes
> > > > > any sense in case of Mount(), though. Usually invoking the modifying
> > > > > methods on a BPartition object indeed immediately changes the 
> > > > > object.
> > > > > That's a bit complicated for Mount(), since one can't get a valid
> > > > > dev_t
> > > > > until the partition is really mounted.
> > > > > 
> > > > > So, maybe only a `bool immediately = true' parameter for Unmount(),
> > > > > while
> > > > > Mount() would always work immediately and fail, if the partition was
> > > > > modified?
> > > > 
> > > > That sounds okay to me. So, mounting would fail if the partition in
> > > > question
> > > > is busy.
> > > 
> > > If you mean by `busy' that the partition will be affected by scheduled 
> > > (or
> > > already executing) jobs (as I do), then it should definitely fail.
> > 
> > Yes, I'm trying to use the proper vocabulary now that I'm catching on. :-)
> > 
> > > But also,
> > > if the BPartition you're invoking Mount() on has been modified, even if
> > > the
> > > changes have not been committed yet. The reason is to avoid confusing
> > > situations like that you invoke Uninitialize() on a partition (but not 
> > > yet
> > > CommitModifications()) and the subsequent Mount() would succeed
> > > nevertheless.
> > > (Situation 2a BTW.)
> > 
> > One could also argue that by doing that, you're treating Mount() like a
> > queuable operation, even though it acts (or fails) immediately, which is
> > confusing. Especially since (unless I'm wrong here, but you didn't say
> > otherwise elsewhere) an Unmount(immediate=true) call would succeed in the
> > place of the Mount() call in the above example, while an
> > Unmount(immediate=false) call would fail (at the time of the job). In 
> > other
> > words, Mount() is always immediate, so I find the idea of basing its 
> > success
> > off the status of the shadow partitions a bit confusing. It seems to me 
> > like
> > Mount() and Unmount(immediate=true), being immediate, should have 
> > semantics
> > that are independent of modifications being prepared in the same 
> > BPartition
> > hierarchy.
> 
> Mmh, so what do you suggest? Should the Mount()/Unmount() calls in the
> following example fail or succeed?
> 
> BPartition *partition = ... some unmounted BFS partition ...;
> partition->Device()->PrepareModifications();
> partition->Uninitialize();
> partition->Mount(...);
> 
> Same with with a mounted BFS partition and Unmount(force = true, immediately
> = true).
> 
> Following you argumentation they should succeed, since they would succeed, 
> if
> PrepareModifications() and Uninitialize() hadn't been invoked. Correct?

Yep.

> As I said, I find, that this could be confusing. 

Agreed. I think both our ways are actually confusing. :-)

> Maybe it isn't such a good
> idea to allow triggering immediate mounting/unmounting on a BPartition 
> object
> belonging to a BDiskDevice for which modifications are being prepared. The
> idea would be to have Mount() always fail in such a case and Unmount() be
> non-immediate (i.e. the `immediately' flag wouldn't be needed).

This I like. :-)

> Thinking of how the API will be used, at least for Mount() I don't see any
> reason, why it shouldn't work like that. Why would your application (e.g.
> DriveSetup) want to mount a partition on a device which is about to be
> changed? And even, if such a situation occurs, one could always get a fresh
> BDiskDevice and use that for mounting.

Exactly.

> The usage pattern of Unmount() might be a bit different. E.g. if the users
> resizes a partition in DriveSetup that needs to be unmounted, the user could
> be asked, whether the partition shall be unmounted now (it doesn't seem to
> make much sense to queue the unmount request). But in this case a fresh
> BDiskDevice might be used as well, though that's less convenient.

It's not that inconvenient though, and since it's not to be queued, using a 
different object actually makes sense. Sounds okay to me.

> > > > Immediate unmounting would fail is the partition is busy
> > > 
> > > Definitely.
> > > 
> > > >, but
> > > > queued unmounting would be part of the job queue and thus succeed
> > > > always.
> > > > Correct?
> > > 
> > > If we also add a `force' parameter and `true' is supplied, then you are
> > > correct. If `false' is supplied and there are open nodes when the 
> > > attempt
> > > to
> > > unmount the partition is made, then the job (and subsequent jobs in the
> > > same
> > > queue) would fail.
> > 
> > Yes, that's precisely what I was hoping for. :-)
> > 
> > > If we add something like a kernel-user feedback feature,
> > > then we might have more options, e.g. dropping the `force' parameter and
> > > rather ask the user whether to force the unmount, or keep it and ask the
> > > user, if `false' was supplied...
> > 
> > Exactly.
> 
> OK, so it seems, we're agreeing regarding the cases 1, 2b and 2c.

Yes, though I think we might be close to agreeing on 2a as well, no? :-)

-Tyler

Other related posts: