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:
parent
8cd6a1c0f8
commit
3e377cc75a
@ -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
|
||||
|
@ -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
|
||||
|
231
src/servers/registrar/RVolumeList.cpp
Normal file
231
src/servers/registrar/RVolumeList.cpp
Normal 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);
|
||||
}
|
||||
}
|
||||
|
63
src/servers/registrar/RVolumeList.h
Normal file
63
src/servers/registrar/RVolumeList.h
Normal 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
|
Loading…
Reference in New Issue
Block a user