On 2003-03-25 at 14:50:51 [-0800], Ingo Weinhold wrote: > > On Sun, 23 Mar 2003, Tyler Dauwalder wrote: > > > Here's my proposed header changes for the Disk Device API > > incorporating a more general partitioning scheme: > > > > http://www.dauwalder.net/DiskDeviceAPI_v2.0.zip > > > > BPartition now provides the base functionality used for any > > contiguous chunk of data. Each BPartition has a char* Type() that > > identifies the system it's formatted with (be it a partitioning > > system or a file system). > > > > BDiskDevice is a subclass of BPartition that provides the device > > specific functionality. Each device also has an associated char* > > DeviceType() that identifies what sort of device it is. > > In principle I like the idea of a base class for managing the > `contiguous > disk space' aspects, though I'm not yet sure, if it would perhaps be > better to introduce a third class, from which both BPartition and > BDiskDevice are derived from. A couple of BPartition methods are > simply > not applicable -- Index(), Doesn't do any harm though. Device.Index() == 0 makes at least a marginal amount of sense, similar to a single primary partition in an intel map. > Parent(), Device.Parent() == NULL lets you know when you've gotten to the bottom of the tree, though, similar to BDirectory("/").GetParent(...) == B_ENTRY_NOT_FOUND. I think that's actually useful. > {Minimum,Maximum}Size() (well, > they > could be computed, but make little sense), > MoveTo(), ResizeTo(). I guess I looked at it as being no different than a partition that didn't support resizing or moving. > On the other hand that would probably introduce more need for casting > and > make the API less convenient to use. That's my main complaint. > [...] > > Aside from stripping out all the BSession related stuff, I also made > > the partition management code a little more specific. It seemed to > > me > > that the method we were using for partitioning was pretty general, > > i.e. for every partitioning system we support, we'd have to write a > > new set of parameter editors to support the entire partitioning > > process (correct me if I'm wrong here). > > That's right. But in fact, the two partitioning systems supported by > BeOS > were different enough to justify separate editors, in my opinion. Hmmm, I see. This is where we differ, then. :-) My reaction to the two partitioning editors has been "why are there two of them with such notably different interfaces, when they aren't really that different?". :-) However, after reading your comments and considering it more, I'm starting to think it's perhaps not going to be worth the effort when we have only 2 partitioning systems to support. Incidentally, I meant to mention that I'm not insisting upon using this new partitioning process interface by any means; I thought it was worth looking into, and that ditching it for the old interface would be easy enough to do if desired. > > Since the whole system is now > > more general, it seemed to me it would be reasonable to support the > > general set of partition management functions (move, resize, create, > > delete, edit parameters) in the API itself. > > That may be more difficult than it looks. I write a bit more on that > below. Yes, I'm beginning to see what you mean. :-) > > I'd like to see our > > DriveSetup replacement offer a nice, unified UI for partition > > management a la PartitionMagic, > > Actually I've never seen PartitionMagic. Which partitioning systems > does > it support, and how does it manage to unify the GUI for them? Just intel partitions, actually. :-) But their interface seems general enough to me that it could be used for apple partitions (I'll send you some screenshots). > > and I think supporting partitioning > > in the API itself will make it easier for new partition systems to > > be > > supported transparently. > > In theory that is certainly right. In practice, however, I suspect, > that > the only application using the provided write support will be > DriveSetup. > And currently it does so in a very specific manner -- it doesn't > manipulate single partitions, but the partition layout of a whole > disk. See, room for improvement. ;-) > > The idea is that the functions will first do some checking to make > > sure the operating can be performed. If so, they'll spawn a new > > thread to perform the task, and return a unique id for the job. The > > job then can send progress update messages containing the job id to > > the specified BMessenger, where they can then be passed on to the > > user somehow so they know what's going on. > > Mmh, I would rather see the asynchronous operation to be optional. > Synchronous processing should be possible at least. Instead of the > job ID, > I would vote for the ID of the partition under modification to be sent > with the notifications, plus an optional template message to be > passed to > the method. I don't know, but for some reason, I suspect, that there > will > be very few applications allowing for more than one partitioning > process > at a time, anyway. ;-) I was just planning on one: Drive Setup. :-) Seriously, if you had a way to lock portions of the drive being modified at any given time, I see no reason why you couldn't work on other parts of the drive too. And certainly one could repartition a second drive while the first was busy resizing a 20GB bfs partition to 10GB. :-) > Now to the headers: > > DiskDeviceTypes.h: > ----------------- > > * Instead of macros, I would vote for string constants (`const char > *const'). Fine by me. > * There is a way to discriminate between a CD and a DVD? Not that I know of. :-) I had "Optical Storage Device" in there at some point, but I'm really not sure what happened to it... > Partition.h > ----------- > > * Path(): The comment confuses me a bit. What does it actually > return? For > the device, I suspect, the path to the `raw' device. For partitions > the > `virtual' devices, i.e. `/dev/disk/.../x_y'? If we support arbitrarily > nested partitions, will the names then be `x[_y[_z[...]]]'? Yes, that was my intent. > The return value is not const, so the returned string is owned by the > caller? I completely forgot to check for appropriate use of const and non-const, sorry. I intended that one to be const. > I would prefer a BString* parameter instead (and perhaps also > a char* parameter version). That'd be fine with me, though I think a const version of what's there already would also be reasonable. > Finally, usually it is better not to declare virtuals const. Though, > in this case we know all derived classes. Well, in that case perhaps the BString* version would be better. > * Flags() doesn't harm, even, if we had convenience methods for each > flag. Okay. > * `const BPartition* Parent()' -> `BPartition* Parent() const'? Yes. > * PartitionWithID() const? Yes. > * CountDescendents() may be rather heavy weight This I don't really see. Wouldn't it just be a recursive set of CountChildren() calls, all of which just check the size of fChildren? > (as is PartitionWithID*(), BTW). This is a leftover from the first draft, and actually I'm not sure I see the point of it when there's BDiskDeviceRoster::GetPartitionWithID(). > * Traverse() could now also return a BPartition*. Another name for the > method would be great (yes, I proposed it, but I never claimed it to > be a > good one ;-). Maybe VisitEachDescendent(), VisitPartitionTree(),...? Well, if we keep CountDescendents(), VisitEachDescendent() would be consistent at least. I don't have any better ideas atm :-). > And hey, you left out the header of the BDiskDeviceVisitor class! :-P Ooops. :-) > It actually would only need one Visit() method now (with BPartition* > parameter). True. > * I miss something like `bool IsNode()' or `bool IsLeaf()' or > something like that (a better name!), so that one can ask whether the > partition is just a partition tree node or a real data partition. IsPartitionable() == IsNode() !IsPartitionable() == IsLeaf() IsMountable() is there 1) to signal a partition with a supported filesystem and 2) to allow for signalling of a partitioning system that can also be mounted. I don't know if the latter case is even worth supporting. Do you think it would just be better to instead have IsContainer() == !IsData(), or something to that degree? > There're > IsMountable() and CountChildren(), but I think neither returns the > exact > info. A partition may simply be not mountable because of the missing > FS > add-on, which doesn't make it a tree node. In that case it would be !IsMountable() && !IsPartitionable() > And having no children > holds > true also for a tree node with all children removed. IsPartitionable() && CountChildren() == 0 > * {Minimum,Maximum}Size(): Depending on how the values are obtained, a > single GetSizeLimits(off_t*, off_t*) may be better. Yes, I like that better. > BTW, why not const? Same story, no good reason. > * MoveTo(), Resize(): > - For performance reasons a MoveAndResize() could be added, too. Perhaps, though I think the BPartitionJob concept is better. > - Who does the parameter checking? Most partitioning systems support > block aligned partitions only, some may require even greater > alignments (e.g. cylinder boundaries). Wouldn't that information > be > missing in a generic GUI? > E.g. I imagine the user setting a new size for a partition, > pressing > `OK' and getting an error message like `Failed to resize > partition: > Invalid parameters.' You're right, there are a lot of assumptions built in there. I invisioned it as this: 1) Block alignment I kind of figured was a given, i.e. the GUI would ensure block alignment. 2) Size limits would be known from the GetSizeLimits() function. 3) Movement and creation limits could be inferred from the known partition layout. This I'm not so sure about now, though. Are there requirements wrt having a certain amount of space between partitions? Thus the GUI would keep the user from making poor choices most of the time (i.e. unaligned, invalid size). The kernel code would do the final, complete error checking, but theoretically the GUI would have filtered out the majority of bad inputs. As to alignment on cylinder boundaries or what have you...isn't that a bit unlikely in this day and age? I thought you couldn't even believe the physical geometry claimed by hard disks anymore, as they oftentimes take the liberty of remapping blocks at the hardware level when they feel like it. > - Complex operations are a must. The user must be able to specify a > complete set of partitions layout changes, that are carried out > together. I imagine something like a BPartitioningJob class with > {Create,Resize,Move,...}Partition() methods and, of course, a > Do()/Perform()/Execute()... (That makes MoveAndResize() > superfluous, > BTW.) This is more complicated, if one intends to allow creating > hierarchies (e.g. creating a child of a not yet created > partition). Well, if all the necessary parameters for partitioning could be retrieved from the appropriate add-ons (i.e. size limits, spacing between partitions, etc.), it could be done. The hard part is thoroughly gathering all the necessary information (which clearly the current design does not account for). Things like "only one extended partition is allowed" would have to be conveyed, also, and that could get difficult to do in a general manner, I think. > * Regarding the parameter editors. It occurs to me, that you want them > for editing only partitioning system specific properties, but not > position and size. Yes. > While that is a good idea in principle, it has > problems with specific restrictions applying to position and size > (as > mentioned above). Yes. > Furthermore, you return BDiskScannerParameterEditors. They are not > exactly convenient to use. That's one reason why they didn't appear > in > the old API. The other is, that the class could be kept private, so > that it could be changed without affecting the DiskDevice API. Okay. It seemed to me the old API was pretty much a "here, get all the necessary info and return when you're done" sort of thing, whereas I just wanted to get a BView that could be placed wherever needed. > * Initialize() misses a volume name and a flags parameter. I figured that would be incorporated into the parameters string, since initialize is also used for partitioning systems, which do not by necessity require a volume name. Shall I put them back, then? > DiskDevice.h > ------------ > > * Unset(): It was possible (and necessary) to create an uninitialized > BDiskDevice object that BDiskDeviceRoster method could fill with life. > Unset() simply resets the object to the uninitialized state, > similarly to > almost all of the SK classes. Whether it will be needed depends on > the way > we'll communicate with our kernel component. Okay. > DiskDeviceRoster.h/DiskDeviceList.h > ----------------------------------- > > * They look mostly unmodified, save regarding the disappearance of > BSession. > > BTW, have I ever mentioned BDiskDeviceList? I introduced it at some > point, > starting as kind of a prototype study, but I can't remember mailing > anything to the list about it. I don't know that you did. I remember being a bit surprised by it, but figured I must have just forgotten about it. :-) I take it that it's meant to be a repository of BDiskDevices that can subscribe for updates and thus remain up to date? > I'm not completely happy with it > anyway, > but that's another story... Oh do tell. :-) I'm actually not seeing what it is you wouldn't like just by looking at it, if that's any consolation. So, in summary, clearly the API is lacking in the area of acquiring all the necessary information to allow it to be used as a basis for a general partitioning tool. As I mentioned, I thought it was worth looking into, and having done so, I'm starting to feel more like the previous system will be more cost-effective for us at this point, i.e. I still like the general concept, but it looks like it'll be a good deal more work than I had hoped, and for little gain over the old system. What do you think? -Tyler