[openbeosstorage] Device API
- From: "Ingo Weinhold" <bonefish@xxxxxxxxxxxxxxx>
- To: "Storage Kit" <openbeosstorage@xxxxxxxxxxxxx>
- Date: Sun, 24 Nov 2002 00:27:43 CET (+0100)
Hi,
I started to have a closer look at the device API, and here's a little
brain storming. There are a lot of questions, mostly unanswered, of
course. ;-)
These are basically the classes we have to deal with:
DeviceList:
A list of Devices, contains all the available devices in the system
after scanning. The list is passive, i.e. one has to rescan to keep it
up to date. Provides some functionality to traverse devices and
partitions.
Device:
Represents a device -- a disk-like device to be precise. Features
methods to access the device's properties and its list of Sessions.
Session:
A session on a device. Makes sense preferably for CDs and the like
(hard disks for instance seem to have exactly one session containing
all partitions). Access to some properties and the Partitions.
Partition:
Represents a partition. Access to the partition properties.
Now the methods:
Partition
=========
Partition(Session *, const char *name, const char *type,
const char *fsShortName, const char *fsLongName,
const char *volumeName, const char *mountedAt,
uint32 logicalBlockSize, uint64 offset, uint64 blocks,
bool hidden = false);
Partition(Session *, uint32 logicalBlockSize, uint64 offset,
uint64 blocks, bool hidden = false);
Partition(Session *, const partition_data &);
Not much to say about. Create the object and set the supplied data.
-----------------------------------------------------------------------
void SetName(const char *);
const char *Name() const;
void SetType(const char *);
const char *Type() const;
void SetFileSystemShortName(const char *);
const char *FileSystemShortName() const;
void SetFileSystemLongName(const char *);
const char *FileSystemLongName() const;
void SetVolumeName(const char *);
const char *VolumeName() const;
void SetMountedAt(const char *);
const char *MountedAt() const;
status_t GetMountPointNodeRef(node_ref*) const;
void SetMountPointNodeRef(const node_ref*);
MountState Mounted() const;
void SetMountState(MountState state);
uint32 LogicalBlockSize() const;
uint64 Offset() const;
uint64 Blocks() const;
bool Hidden() const;
partition_data *Data();
bool IsBFSDisk() const;
bool IsHFSDisk() const;
bool IsOFSDisk() const;
int32 Index() const;
Session *GetSession() const;
Device *GetDevice() const;
Accessors for the object's members.
-----------------------------------------------------------------------
bool BuildFileSystemInfo(void *params);
bool RebuildFileSystemInfo();
The comment says: `set up the files system short and long names for
this partition'. No idea, what `params' is good for though -- maybe
just for the EachPartitionMemberFunction signature.
The former one invokes the mysterious function `EachAddOnCommon(char
const *, bool (*)(long, BEntry *, void *), void *)'.
RebuildFileSystemInfo() uses BuildFileSystemInfo().
-----------------------------------------------------------------------
bool SetOneUnknownMountState(void *);
bool ClearOneMountState(void *);
According to the comment: `utility calls for updating mounting info'. I
guess they manipulate the member `MountState mounted'. The first method
is very short, probably only a `mounted = kUnknown; return false;'. The
second one seems to call `SetMountedAt()'. Both have the
EachPartitionMemberFunction signature.
-----------------------------------------------------------------------
status_t Mount(int32 mountflags = 0, void *params = NULL,
int32 len = 0);
status_t Unmount();
Mount/unmount the partition. The Mount() parameters are passed to the
FS's mount function.
Mount() seems to rebuild the FS info, check whether there exist that
many partitions, check whether the mount point exists and is an empty
directory and publish a device in `/dev/...'.
Unmount() uses BVolume to get the mount point.
I don't see, how the actual mounting/unmounting is done, but I would
use the POSIX API functions mount() and unmount() (unistd.h).
(BTW, how do I make objdump list calls to undefined symbols, like those
from other libs?)
-----------------------------------------------------------------------
status_t Initialize(InitializeControlBlock *params,
const char *fileSystem = "bfs");
The comment:
`the drive setup addon call protocol requires a lot of extra stuff:
you have to pass a window onto which the drive setup addon will
center itself. Upon completion it will send it a message with
<completionMessage> signature; the MessageReceived in the window
needs to release <completionSemaphore> to unblock the call'
An interesting question comes to my mind: Is the DriveSetup add-on
interface documented or is there at least a header or something one can
see how it looks like?
-----------------------------------------------------------------------
int32 UniqueID() const;
`returns a number uinque to the volume in a given device list
used to identify unmounted volumes'
Returns `int32 partitionUniqueID', which is set at construction time
using `static int32 lastUniqueID'.
-----------------------------------------------------------------------
dev_t VolumeDeviceID() const;
void SetVolumeDeviceID(dev_t);
Returns `dev_t volumeDeviceID', which should be set at construction or
mount time.
-----------------------------------------------------------------------
status_t AddVirtualDevice();
`publishes a device in /dev...' that can be used to access the
partition.
-----------------------------------------------------------------------
void Dump(const char *includeThisText = "");
Prints some info to stdout. includeThisText is prepended.
------------------------------private----------------------------------
status_t AddVirtualDevice(char *device);
`fills out <device> with the path to the device driver in /dev...'
-----------------------------------------------------------------------
void InitialMountPointName(char *);
Copies the name of the initial mount point into the supplied buffer.
-----------------------------------------------------------------------
Session
=======
Session(Device *device, const char *, uint64 offset, uint64 blocks,
bool data);
Constructs the object initializing it with the supplied data.
-----------------------------------------------------------------------
uint64 Blocks() const;
void SetName(const char *);
const char *Name() const;
void SetType(int32 type);
uint64 Offset() const;
Device *GetDevice() const;
int32 Index() const;
bool IsDataSession() const;
static status_t GetSessionData(int32 dev, int32 index, int32 blockSize,
session_data *session);
Accessors for the object's members.
-----------------------------------------------------------------------
void AddPartition(Partition *);
int32 CountPartitions() const;
Partition *PartitionAt(int32 index) const;
Partition list accessors.
-----------------------------------------------------------------------
bool VirtualPartitionOnly() const;
Returns `bool virtualPartitionOnly'. Probably for devices like
floppies, that don't support partitions, but have a Partition object,
however, to fit into this framework.
-----------------------------------------------------------------------
void SetAddOnEntry(const BEntry *entry);
`the addon that knows how to handle this session'
Now that is interesting. Does that mean a DriveSetup add-on?
-----------------------------------------------------------------------
bool BuildPartitionMap(int32 dev, uchar *block, bool singlePartition);
`adds one or more partitions to the list
returns true if multiple partitions found
pass false in <singlePartition> if device cannot support
multiple partitions (floppy)'
This comment actually doesn't help me very much.
The method uses:
Device::BlockSize(void)
EachAddOnCommon(char const *, bool (*)(long, BEntry *, void *),
void *)
node_ref::node_ref(void)
Session::AddPartition(Partition *)
Again EachAddOnCommon()...
Wild guessing: To me partition map sounds a bit like an on-disk
structure that specifies which partitions exist and where they are
located. The parameter `block' could be raw data from disk, or raw data
to be filled in and written to disk. No idea what `dev' is, though.
-----------------------------------------------------------------------
bool BuildFileSystemInfo(int32 dev);
Mmh, `dev' again. I would guess this method simply calls
Partition::BuildFileSystemInfo() on all partitions. The occurence of
`Session::EachPartition()' seems to support that suspicion.
-----------------------------------------------------------------------
bool EachPartition(EachPartitionMemberFunction, void *);
`return true if terminated early'
..
-----------------------------------------------------------------------
BEntry add_on; // we probably don't need this
Well, an add-on. A DriveSetup add-on perhaps.
-----------------------------------------------------------------------
Device
======
Device(const char *path, int devfd = -1);
~Device();
The constructor initializes the object (Device::InitNewDeviceState()).
-----------------------------------------------------------------------
int32 CountSessions() const;
Session *SessionAt(int32 index) const;
int32 CountPartitions() const;
Session list accessors.
-----------------------------------------------------------------------
int32 BlockSize() const;
void SetPartitioningFlags(drive_setup_partition_flags newFlags);
const char *Name() const;
const char *DisplayName(bool includeBusID = true,
bool includeLUN = false) const;
bool ReadOnly() const
bool Removable() const
bool NoMedia() const;
bool IsFloppy() const;
Accessors for the object's members.
-----------------------------------------------------------------------
Session *NewSession(int32 dev, int32 index);
Looks like it would create a Session object for the `index'th session.
Again the `dev' parameter...
-----------------------------------------------------------------------
bool FindMountedVolumes(void *);
Looks like this methods iterates through all partitions of all sessions
and checks whether the mount point node_ref identifies a valid
directory and sets the mount point path (Partition::SetMountedAt())
accordingly.
-----------------------------------------------------------------------
void UpdateDeviceState();
Rebuilds the session list (MakeEmpty(), InitNewDeviceState()).
-----------------------------------------------------------------------
status_t Eject();
No idea, what that method might do. ;-)
-----------------------------------------------------------------------
void Dump(const char *);
bool Dump(void *);
..
-----------------------------------------------------------------------
bool DeviceStateChanged(void *params);
Has the EachDeviceMemberFunction signature.
Calls:
Device::CountSessions(void)
Device::DisplayName(bool, bool)
Device::Name(void)
And is called by:
::OneHandleIfDisappeared(Partition *, void *)
Not sure, what it does.
------------------------------private----------------------------------
void InitNewDeviceState();
Seems to initialize the (some?) Device member vars (BBitmap methods are
invoked, so the icons are certainly initialized), build the session
list and initialize the sessions and their partitions.
-----------------------------------------------------------------------
void KillOldDeviceState();
MakeEmpty(). Probably does more. But what?
-----------------------------------------------------------------------
bool OneIfDeviceStateChangedAdaptor(void *params);
Obviously an adaptor for Device::DeviceStateChanged(void *). Not sure
what it does though. Signature is the same -- both are of type
EachDeviceMemberFunction.
-----------------------------------------------------------------------
void BuildDisplayName(bool includeBusID, bool includeLUN);
Initializes `shortName', a more human readable version of `name'.
-----------------------------------------------------------------------
DeviceList
==========
DeviceList();
~DeviceList();
Constructs empty device list/destroys list.
-----------------------------------------------------------------------
status_t RescanDevices(bool runRescanDriver = true);
Empties and rebuilds the device list. runRescanDriver? -- sounds like
whether or not the kernel shall scan for new devices. Invokes
ScanDirectory() which does the actual scanning.
-----------------------------------------------------------------------
bool UpdateMountingInfo();
Checks all partitions for a change in their mount state. Comment:
`returns true if there was a change'
-----------------------------------------------------------------------
bool EachDevice(EachDeviceMemberFunction, void *);
Device *EachDevice(EachDeviceFunction, void *);
Partition *EachPartition(EachPartitionFunction func, void *params);
bool EachPartition(EachPartitionMemberFunction func, void *params);
Partition *EachMountedPartition(EachPartitionFunction, void *);
Partition *EachMountablePartition(EachPartitionFunction, void *);
Partition *EachInitializablePartition(EachPartitionFunction, void *);
..
-----------------------------------------------------------------------
Partition *PartitionWithID(int32);
..
-----------------------------------------------------------------------
bool CheckDevicesChanged(DeviceScanParams *);
Checks whether some device has changed with respect to the device scan
parameters. At least that's what I guess -- the dump shows only
TypedList<Device *>::CountItems()/ItemAt(long), but no call to
EachChangedDevice() as I would expect.
-----------------------------------------------------------------------
void UpdateChangedDevices(DeviceScanParams *);
Updates all devices that have changed wrt. the scan params. Finally
Device::UpdateDeviceState() is called on the concerned devices,
supposedly.
-----------------------------------------------------------------------
bool UnmountDisappearedPartitions();
Unmounts all disappeared partitions (OneHandleIfDisappeared() on each
partition). I wonder, what `disappeared' means. Perhaps unmounted by
someone else?
------------------------------private----------------------------------
bool EachChangedDevice(EachDeviceFunction, DeviceScanParams *, void *);
`iterate through every device that is out of sync with current state
used to sync when media changes, etc.'
-----------------------------------------------------------------------
status_t ScanDirectory(const char *path);
Given a directory path, checks recursively (?) which entries represent
devices and initializes respective Device objects
(InitNewDeviceState()) and adds them to the list.
-----------------------------------------------------------------------
Congratulations, you've reached the end. ;-)
Any comments are very welcome, especially those shedding more light on
the vague parts. :-P
CU, Ingo
Other related posts:
- » [openbeosstorage] Device API