Added RVolumeList, which maintains an up-to-date list of mounted volumes. Will be used as helper for RDiskDeviceList. Not complete yet.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2634 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold 2003-02-04 23:56:38 +00:00
parent 8cd6a1c0f8
commit 3e377cc75a
4 changed files with 303 additions and 1 deletions

View File

@ -10,8 +10,11 @@
// constructor
DiskDeviceManager::DiskDeviceManager()
: BLooper("disk device manager"),
fDeviceList()
fDeviceList(),
fVolumeList()
{
AddHandler(&fVolumeList);
fVolumeList.Dump();
fDeviceList.Rescan();
fDeviceList.Dump();
}
@ -19,6 +22,9 @@ DiskDeviceManager::DiskDeviceManager()
// destructor
DiskDeviceManager::~DiskDeviceManager()
{
Lock();
RemoveHandler(&fVolumeList);
Unlock();
}
// MessageReceived

View File

@ -9,6 +9,7 @@
#include <Looper.h>
#include "RDiskDeviceList.h"
#include "RVolumeList.h"
class DiskDeviceManager : public BLooper {
public:
@ -19,6 +20,7 @@ public:
private:
RDiskDeviceList fDeviceList;
RVolumeList fVolumeList;
};
#endif // DISK_DEVICE_MANAGER_H

View File

@ -0,0 +1,231 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#include <string.h>
#include <Message.h>
#include <NodeMonitor.h>
#include <Volume.h>
#include "RVolumeList.h"
#include "Debug.h"
// CompareIDPredicate
struct CompareIDPredicate : public UnaryPredicate<RVolume> {
CompareIDPredicate(dev_t id) : fID(id) {}
CompareIDPredicate(const RVolume *volume) : fID(volume->ID()) {}
virtual int operator()(const RVolume *volume) const
{
dev_t id = volume->ID();
if (fID < id)
return -1;
if (fID > id)
return 1;
return 0;
}
private:
dev_t fID;
};
// CompareDevicePathPredicate
struct CompareDevicePathPredicate : public UnaryPredicate<RVolume> {
CompareDevicePathPredicate(const char *path) : fPath(path) {}
virtual int operator()(const RVolume *volume) const
{
return strcmp(fPath, volume->DevicePath());
}
private:
const char *fPath;
};
// RVolume
// constructor
RVolume::RVolume()
: fID(-1),
fRootNode(-1)
{
}
// SetTo
status_t
RVolume::SetTo(dev_t id)
{
status_t error = B_OK;
fs_info info;
error = fs_stat_dev(id, &info);
if (error == B_OK) {
fID = id;
fRootNode = info.root;
strcpy(fDevicePath, info.device_name);
} else
Unset();
return error;
}
// Unset
void
RVolume::Unset()
{
fID = -1;
fRootNode = -1;
}
// RVolumeList
// constructor
RVolumeList::RVolumeList()
: BHandler(),
fVolumes(20, true),
fRoster()
{
}
// destructor
RVolumeList::~RVolumeList()
{
}
// MessageReceived
void
RVolumeList::MessageReceived(BMessage *message)
{
switch (message->what) {
case B_NODE_MONITOR:
{
int32 opcode = 0;
if (message->FindInt32("opcode", &opcode) == B_OK) {
switch (opcode) {
case B_DEVICE_MOUNTED:
_DeviceMounted(message);
break;
case B_DEVICE_UNMOUNTED:
_DeviceUnmounted(message);
break;
}
}
break;
}
default:
BHandler::MessageReceived(message);
break;
}
}
// SetNextHandler
void
RVolumeList::SetNextHandler(BHandler *handler)
{
// stop watching volumes, if removed from looper
if (!handler) {
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
// fRoster.StopWatching();
stop_watching(BMessenger(this));
}
BHandler::SetNextHandler(handler);
// start watching volumes and rescan list, if added to looper
if (handler) {
// TODO: Remove work-around. At this time R5 libbe's watching functions don't
// work for us. We have an own implementation in `NodeMonitoring.cpp'.
// fRoster.StartWatching(BMessenger(this));
watch_node(NULL, B_WATCH_MOUNT, BMessenger(this));
Rescan();
}
}
// Rescan
status_t
RVolumeList::Rescan()
{
fVolumes.MakeEmpty();
fRoster.Rewind();
BVolume bVolume;
while (fRoster.GetNextVolume(&bVolume) == B_OK)
_AddVolume(bVolume.Device());
return B_ERROR;
}
// VolumeForDevicePath
const RVolume *
RVolumeList::VolumeForDevicePath(const char *devicePath) const
{
// TODO: ...
return NULL;
}
// Lock
bool
RVolumeList::Lock()
{
// TODO: ...
return false;
}
// Unlock
void
RVolumeList::Unlock()
{
// TODO: ...
}
// Dump
void
RVolumeList::Dump() const
{
for (int32 i = 0; RVolume *volume = fVolumes.ItemAt(i); i++) {
printf("volume %ld:\n", volume->ID());
printf(" root node: %lld", volume->RootNode());
printf(" device: `%s'\n", volume->DevicePath());
}
}
// _AddVolume
void
RVolumeList::_AddVolume(dev_t id)
{
if (RVolume *volume = new RVolume) {
status_t error = volume->SetTo(id);
if (error == B_OK) {
fVolumes.BinaryInsert(volume,
CompareDevicePathPredicate(volume->DevicePath()));
} else {
delete volume;
PRINT(("RVolumeList::_AddVolume(): initializing RVolume failed: "
"%s\n", strerror(error)));
}
} else
PRINT(("RVolumeList::_AddVolume(): no memory!\n"));
}
// _DeviceMounted
void
RVolumeList::_DeviceMounted(BMessage *message)
{
dev_t device;
if (message->FindInt32("new device", &device) == B_OK) {
PRINT(("RVolumeList::_DeviceMounted(%ld)\n", device));
_AddVolume(device);
}
}
// _DeviceUnmounted
void
RVolumeList::_DeviceUnmounted(BMessage *message)
{
dev_t device;
if (message->FindInt32("device", &device) == B_OK) {
PRINT(("RVolumeList::_DeviceUnmounted(%ld)\n", device));
if (RVolume *volume = fVolumes.FindIf(CompareIDPredicate(volume)))
fVolumes.RemoveItem(volume);
}
}

View File

@ -0,0 +1,63 @@
//----------------------------------------------------------------------
// This software is part of the OpenBeOS distribution and is covered
// by the OpenBeOS license.
//---------------------------------------------------------------------
#ifndef VOLUME_LIST_H
#define VOLUME_LIST_H
#include <Handler.h>
#include <Node.h>
#include <ObjectList.h>
#include <VolumeRoster.h>
// RVolume
class RVolume {
public:
RVolume();
~RVolume() {}
status_t SetTo(dev_t id);
void Unset();
dev_t ID() const { return fID; }
ino_t RootNode() const { return fRootNode; }
void GetRootNodeRef(node_ref *ref) const
{ ref->device = fID; ref->node = fRootNode; }
const char *DevicePath() const { return fDevicePath; }
private:
dev_t fID;
ino_t fRootNode;
char fDevicePath[B_FILE_NAME_LENGTH];
};
// RVolumeList
class RVolumeList : public BHandler {
public:
RVolumeList();
virtual ~RVolumeList();
virtual void MessageReceived(BMessage *message);
virtual void SetNextHandler(BHandler *handler);
status_t Rescan();
const RVolume *VolumeForDevicePath(const char *devicePath) const;
bool Lock();
void Unlock();
void Dump() const;
private:
void _AddVolume(dev_t id);
void _DeviceMounted(BMessage *message);
void _DeviceUnmounted(BMessage *message);
private:
BObjectList<RVolume> fVolumes;
BVolumeRoster fRoster;
};
#endif // VOLUME_LIST_H