* Renamed UserlandFSServer to userlandfs_server. It is expected to live in
/system/servers, now. * Got rid of the dispatcher application. It was the entity the kernel module talked to when mounting a yet unknown FS. It started the client FS server applications. Now the kernel module starts them directly. They use respectively named ports, so the kernel module can find them when already running. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29377 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -3,15 +3,27 @@
|
|||||||
#ifndef USERLAND_FS_DISPATCHER_DEFS_H
|
#ifndef USERLAND_FS_DISPATCHER_DEFS_H
|
||||||
#define USERLAND_FS_DISPATCHER_DEFS_H
|
#define USERLAND_FS_DISPATCHER_DEFS_H
|
||||||
|
|
||||||
|
#include "FSCapabilities.h"
|
||||||
|
#include "Port.h"
|
||||||
|
|
||||||
|
|
||||||
namespace UserlandFSUtil {
|
namespace UserlandFSUtil {
|
||||||
|
|
||||||
extern const char* kUserlandFSDispatcherPortName;
|
extern const char* kUserlandFSDispatcherPortName;
|
||||||
extern const char* kUserlandFSDispatcherReplyPortName;
|
extern const char* kUserlandFSDispatcherReplyPortName;
|
||||||
|
|
||||||
|
struct fs_init_info {
|
||||||
|
FSCapabilities capabilities;
|
||||||
|
client_fs_type clientFSType;
|
||||||
|
int32 portInfoCount;
|
||||||
|
Port::Info portInfos[0];
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace UserlandFSUtil
|
} // namespace UserlandFSUtil
|
||||||
|
|
||||||
using UserlandFSUtil::kUserlandFSDispatcherPortName;
|
using UserlandFSUtil::kUserlandFSDispatcherPortName;
|
||||||
using UserlandFSUtil::kUserlandFSDispatcherReplyPortName;
|
using UserlandFSUtil::kUserlandFSDispatcherReplyPortName;
|
||||||
|
using UserlandFSUtil::fs_init_info;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
UFS_DISPATCHER_CONNECT = 'cnct',
|
UFS_DISPATCHER_CONNECT = 'cnct',
|
||||||
|
|||||||
+104
-44
@@ -1,76 +1,136 @@
|
|||||||
// FileSystemInitializer.cpp
|
/*
|
||||||
|
* Copyright 2001-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "FileSystemInitializer.h"
|
#include "FileSystemInitializer.h"
|
||||||
|
|
||||||
#include <new>
|
#include <new>
|
||||||
|
|
||||||
|
#include <image.h>
|
||||||
|
#include <OS.h>
|
||||||
|
|
||||||
|
#include <port.h>
|
||||||
|
#include <team.h>
|
||||||
|
|
||||||
|
#include "AutoDeleter.h"
|
||||||
|
|
||||||
|
#include "DispatcherDefs.h"
|
||||||
#include "FileSystem.h"
|
#include "FileSystem.h"
|
||||||
#include "RequestAllocator.h"
|
#include "RequestAllocator.h"
|
||||||
#include "RequestPort.h"
|
#include "RequestPort.h"
|
||||||
#include "Requests.h"
|
#include "Requests.h"
|
||||||
#include "SingleReplyRequestHandler.h"
|
#include "SingleReplyRequestHandler.h"
|
||||||
|
|
||||||
using std::nothrow;
|
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
FileSystemInitializer::FileSystemInitializer(const char* name,
|
FileSystemInitializer::FileSystemInitializer(const char* name)
|
||||||
RequestPort* initPort)
|
:
|
||||||
: fName(name),
|
fName(name),
|
||||||
fInitPort(initPort),
|
fFileSystem(NULL)
|
||||||
fFileSystem(NULL)
|
|
||||||
{
|
{
|
||||||
// Note: We don't copy the name. It's only needed in FirstTimeInit() and
|
// Note: We don't copy the name. It's only needed in FirstTimeInit() and
|
||||||
// the UserlandFS makes sure it is valid until then.
|
// the UserlandFS makes sure it is valid until then.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
FileSystemInitializer::~FileSystemInitializer()
|
FileSystemInitializer::~FileSystemInitializer()
|
||||||
{
|
{
|
||||||
delete fFileSystem;
|
delete fFileSystem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// FirstTimeInit
|
// FirstTimeInit
|
||||||
status_t
|
status_t
|
||||||
FileSystemInitializer::FirstTimeInit()
|
FileSystemInitializer::FirstTimeInit()
|
||||||
{
|
{
|
||||||
// prepare the request
|
// First check whether a server for this FS is already loaded. Look for a
|
||||||
RequestAllocator allocator(fInitPort->GetPort());
|
// port with the respective name.
|
||||||
FSConnectRequest* request;
|
char portName[B_OS_NAME_LENGTH];
|
||||||
status_t error = AllocateRequest(allocator, &request);
|
snprintf(portName, sizeof(portName), "_userlandfs_%s", fName);
|
||||||
if (error != B_OK)
|
|
||||||
|
port_id port = find_port(portName);
|
||||||
|
if (port >= 0)
|
||||||
|
return _Init(port);
|
||||||
|
|
||||||
|
// We have to start the server ourselves. First create the port we're going
|
||||||
|
// to use.
|
||||||
|
port = create_port(1, portName);
|
||||||
|
if (port < 0)
|
||||||
|
RETURN_ERROR(port);
|
||||||
|
|
||||||
|
// prepare the command line arguments
|
||||||
|
char portID[16];
|
||||||
|
snprintf(portID, sizeof(portID), "%ld", port);
|
||||||
|
|
||||||
|
const char* args[4] = {
|
||||||
|
"/system/servers/userlandfs_server",
|
||||||
|
fName,
|
||||||
|
portID,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
// start the server
|
||||||
|
thread_id thread = load_image_etc(3, args, NULL, B_NORMAL_PRIORITY,
|
||||||
|
B_SYSTEM_TEAM, 0);
|
||||||
|
if (thread < 0) {
|
||||||
|
delete_port(port);
|
||||||
|
RETURN_ERROR(thread);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let it own the port and start the team
|
||||||
|
status_t error = set_port_owner(port, thread);
|
||||||
|
if (error == B_OK)
|
||||||
|
resume_thread(thread);
|
||||||
|
|
||||||
|
// and do the initialization
|
||||||
|
if (error == B_OK)
|
||||||
|
error = _Init(port);
|
||||||
|
|
||||||
|
if (error != B_OK) {
|
||||||
|
kill_team(thread);
|
||||||
|
delete_port(port);
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
FileSystemInitializer::_Init(port_id port)
|
||||||
|
{
|
||||||
|
// allocate a buffer for the FS info
|
||||||
|
const size_t bufferSize = 1024;
|
||||||
|
fs_init_info* info = (fs_init_info*)malloc(bufferSize);
|
||||||
|
MemoryDeleter _(info);
|
||||||
|
|
||||||
|
// Read the info -- we peek only, so it won't go away and we can do the
|
||||||
|
// initialization again, in case we get completely unloaded are reloaded
|
||||||
|
// later.
|
||||||
|
ssize_t bytesRead = read_port_etc(port, NULL, info, bufferSize,
|
||||||
|
B_PEEK_PORT_MESSAGE | B_CAN_INTERRUPT, 0);
|
||||||
|
if (bytesRead < 0)
|
||||||
|
RETURN_ERROR(bytesRead);
|
||||||
|
|
||||||
|
// sanity check
|
||||||
|
if ((size_t)bytesRead < sizeof(fs_init_info)
|
||||||
|
|| info->portInfoCount < 2
|
||||||
|
|| (size_t)bytesRead < sizeof(fs_init_info)
|
||||||
|
+ info->portInfoCount * sizeof(Port::Info)) {
|
||||||
|
RETURN_ERROR(B_BAD_DATA);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create and init the FileSystem
|
||||||
|
fFileSystem = new(std::nothrow) FileSystem;
|
||||||
|
if (!fFileSystem)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t error = fFileSystem->Init(fName, info->portInfos,
|
||||||
|
info->portInfoCount, info->capabilities);
|
||||||
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
error = allocator.AllocateString(request->fsName, fName);
|
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
// send the request
|
|
||||||
SingleReplyRequestHandler handler(FS_CONNECT_REPLY);
|
|
||||||
FSConnectReply* reply;
|
|
||||||
error = fInitPort->SendRequest(&allocator, &handler, (Request**)&reply);
|
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
RequestReleaser requestReleaser(fInitPort, reply);
|
|
||||||
|
|
||||||
// process the reply
|
|
||||||
if (reply->error != B_OK)
|
|
||||||
RETURN_ERROR(reply->error);
|
|
||||||
|
|
||||||
// get the port infos
|
|
||||||
int32 count = reply->portInfoCount;
|
|
||||||
if (count < 2)
|
|
||||||
RETURN_ERROR(B_BAD_DATA);
|
|
||||||
if (reply->portInfos.GetSize() != count * (int32)sizeof(Port::Info))
|
|
||||||
RETURN_ERROR(B_BAD_DATA);
|
|
||||||
Port::Info* infos = (Port::Info*)reply->portInfos.GetData();
|
|
||||||
|
|
||||||
// create and init the FileSystem
|
|
||||||
fFileSystem = new(nothrow) FileSystem();
|
|
||||||
if (!fFileSystem)
|
|
||||||
return B_NO_MEMORY;
|
|
||||||
|
|
||||||
error = fFileSystem->Init(fName, infos, count, reply->capabilities);
|
|
||||||
if (error != B_OK)
|
|
||||||
return B_ERROR;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// FileSystemInitializer.h
|
/*
|
||||||
|
* Copyright 2001-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef USERLAND_FS_FILE_SYSTEM_INITIALIZER_H
|
#ifndef USERLAND_FS_FILE_SYSTEM_INITIALIZER_H
|
||||||
#define USERLAND_FS_FILE_SYSTEM_INITIALIZER_H
|
#define USERLAND_FS_FILE_SYSTEM_INITIALIZER_H
|
||||||
|
|
||||||
@@ -19,8 +21,7 @@ class FileSystem;
|
|||||||
|
|
||||||
class FileSystemInitializer : public LazyInitializable, public Referencable {
|
class FileSystemInitializer : public LazyInitializable, public Referencable {
|
||||||
public:
|
public:
|
||||||
FileSystemInitializer(const char* name,
|
FileSystemInitializer(const char* name);
|
||||||
RequestPort* initPort);
|
|
||||||
~FileSystemInitializer();
|
~FileSystemInitializer();
|
||||||
|
|
||||||
inline FileSystem* GetFileSystem() { return fFileSystem; }
|
inline FileSystem* GetFileSystem() { return fFileSystem; }
|
||||||
@@ -28,9 +29,11 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
virtual status_t FirstTimeInit();
|
virtual status_t FirstTimeInit();
|
||||||
|
|
||||||
|
private:
|
||||||
|
status_t _Init(port_id port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char* fName; // valid only until FirstTimeInit()
|
const char* fName; // valid only until FirstTimeInit()
|
||||||
RequestPort* fInitPort;
|
|
||||||
FileSystem* fFileSystem;
|
FileSystem* fFileSystem;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ local userlandFSTop = [ FDirName $(HAIKU_TOP) src add-ons kernel file_systems
|
|||||||
userlandfs ] ;
|
userlandfs ] ;
|
||||||
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
|
local userlandFSIncludes = [ PrivateHeaders userlandfs ] ;
|
||||||
|
|
||||||
|
UsePrivateKernelHeaders ;
|
||||||
SubDirHdrs [ FDirName $(userlandFSIncludes) private ] ;
|
SubDirHdrs [ FDirName $(userlandFSIncludes) private ] ;
|
||||||
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
|
SubDirHdrs [ FDirName $(userlandFSIncludes) shared ] ;
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
// UserlandFS.cpp
|
/*
|
||||||
|
* Copyright 2001-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "UserlandFS.h"
|
#include "UserlandFS.h"
|
||||||
|
|
||||||
@@ -18,9 +21,9 @@ UserlandFS* UserlandFS::sUserlandFS = NULL;
|
|||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
UserlandFS::UserlandFS()
|
UserlandFS::UserlandFS()
|
||||||
: fPort(NULL),
|
:
|
||||||
fFileSystems(NULL),
|
fFileSystems(NULL),
|
||||||
fDebuggerCommandsAdded(false)
|
fDebuggerCommandsAdded(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,19 +31,6 @@ UserlandFS::UserlandFS()
|
|||||||
UserlandFS::~UserlandFS()
|
UserlandFS::~UserlandFS()
|
||||||
{
|
{
|
||||||
PRINT(("UserlandFS::~UserlandFS()\n"))
|
PRINT(("UserlandFS::~UserlandFS()\n"))
|
||||||
if (fPort) {
|
|
||||||
// send a disconnect request
|
|
||||||
RequestAllocator allocator(fPort->GetPort());
|
|
||||||
UFSDisconnectRequest* request;
|
|
||||||
if (AllocateRequest(allocator, &request) == B_OK) {
|
|
||||||
if (fPort->SendRequest(&allocator) != B_OK)
|
|
||||||
PRINT((" failed to send disconnect request\n"));
|
|
||||||
} else
|
|
||||||
PRINT((" failed to allocate disconnect request\n"));
|
|
||||||
delete fPort;
|
|
||||||
} else
|
|
||||||
PRINT((" no port\n"));
|
|
||||||
|
|
||||||
delete fFileSystems;
|
delete fFileSystems;
|
||||||
if (fDebuggerCommandsAdded)
|
if (fDebuggerCommandsAdded)
|
||||||
KernelDebug::RemoveDebuggerCommands();
|
KernelDebug::RemoveDebuggerCommands();
|
||||||
@@ -99,8 +89,8 @@ UserlandFS::RegisterFileSystem(const char* name, FileSystem** _fileSystem)
|
|||||||
if (fileSystemInitializer) {
|
if (fileSystemInitializer) {
|
||||||
fileSystemInitializer->AddReference();
|
fileSystemInitializer->AddReference();
|
||||||
} else {
|
} else {
|
||||||
fileSystemInitializer = new(nothrow) FileSystemInitializer(name,
|
fileSystemInitializer = new(nothrow) FileSystemInitializer(name/*,
|
||||||
fPort);
|
fPort*/);
|
||||||
if (!fileSystemInitializer)
|
if (!fileSystemInitializer)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -156,40 +146,7 @@ UserlandFS::_Init()
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
// find the dispatcher ports
|
return B_OK;
|
||||||
port_id port = find_port(kUserlandFSDispatcherPortName);
|
|
||||||
if (port < 0)
|
|
||||||
RETURN_ERROR(B_ERROR);
|
|
||||||
port_id replyPort = find_port(kUserlandFSDispatcherReplyPortName);
|
|
||||||
if (replyPort < 0)
|
|
||||||
RETURN_ERROR(B_ERROR);
|
|
||||||
|
|
||||||
// create a reply port
|
|
||||||
// send a connection request
|
|
||||||
error = write_port(port, UFS_DISPATCHER_CONNECT, NULL, 0);
|
|
||||||
if (error != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
// receive the reply
|
|
||||||
int32 replyCode;
|
|
||||||
Port::Info portInfo;
|
|
||||||
ssize_t bytesRead = read_port(replyPort, &replyCode, &portInfo,
|
|
||||||
sizeof(Port::Info));
|
|
||||||
if (bytesRead < 0)
|
|
||||||
RETURN_ERROR(bytesRead);
|
|
||||||
if (replyCode != UFS_DISPATCHER_CONNECT_ACK)
|
|
||||||
RETURN_ERROR(B_BAD_DATA);
|
|
||||||
if (bytesRead != sizeof(Port::Info))
|
|
||||||
RETURN_ERROR(B_BAD_DATA);
|
|
||||||
|
|
||||||
// create a request port
|
|
||||||
fPort = new(nothrow) RequestPort(&portInfo);
|
|
||||||
if (!fPort)
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
if ((error = fPort->InitCheck()) != B_OK)
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
|
|
||||||
RETURN_ERROR(error);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// _UnregisterFileSystem
|
// _UnregisterFileSystem
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// UserlandFS.h
|
/*
|
||||||
|
* Copyright 2001-2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
#ifndef USERLAND_FS_H
|
#ifndef USERLAND_FS_H
|
||||||
#define USERLAND_FS_H
|
#define USERLAND_FS_H
|
||||||
|
|
||||||
@@ -49,7 +51,6 @@ private:
|
|||||||
private:
|
private:
|
||||||
static UserlandFS* sUserlandFS;
|
static UserlandFS* sUserlandFS;
|
||||||
|
|
||||||
RequestPort* fPort;
|
|
||||||
FileSystemMap* fFileSystems;
|
FileSystemMap* fFileSystems;
|
||||||
bool fDebuggerCommandsAdded;
|
bool fDebuggerCommandsAdded;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ SEARCH_SOURCE += [ FDirName $(userlandFSTop) private ] ;
|
|||||||
SEARCH_SOURCE += [ FDirName $(userlandFSTop) shared ] ;
|
SEARCH_SOURCE += [ FDirName $(userlandFSTop) shared ] ;
|
||||||
|
|
||||||
DEFINES += USER=1 ;
|
DEFINES += USER=1 ;
|
||||||
DEFINES += DEBUG_APP="\\\"UserlandFSServer\\\"" ;
|
DEFINES += DEBUG_APP="\\\"userlandfs_server\\\"" ;
|
||||||
DEFINES += BUILDING_USERLAND_FS_SERVER=1 ;
|
DEFINES += BUILDING_USERLAND_FS_SERVER=1 ;
|
||||||
|
|
||||||
Application UserlandFSServer
|
Application userlandfs_server
|
||||||
:
|
:
|
||||||
AreaSupport.cpp
|
AreaSupport.cpp
|
||||||
Debug.cpp
|
Debug.cpp
|
||||||
@@ -41,7 +41,7 @@ Application UserlandFSServer
|
|||||||
main.cpp
|
main.cpp
|
||||||
RequestThread.cpp
|
RequestThread.cpp
|
||||||
ServerDefs.cpp
|
ServerDefs.cpp
|
||||||
UserlandFSDispatcher.cpp
|
# UserlandFSDispatcher.cpp
|
||||||
UserlandFSServer.cpp
|
UserlandFSServer.cpp
|
||||||
UserlandRequestHandler.cpp
|
UserlandRequestHandler.cpp
|
||||||
Volume.cpp
|
Volume.cpp
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ UserlandFSServer::UserlandFSServer(const char* signature)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
UserlandFSServer::~UserlandFSServer()
|
UserlandFSServer::~UserlandFSServer()
|
||||||
{
|
{
|
||||||
@@ -55,9 +56,10 @@ UserlandFSServer::~UserlandFSServer()
|
|||||||
unload_add_on(fAddOnImage);
|
unload_add_on(fAddOnImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Init
|
// Init
|
||||||
status_t
|
status_t
|
||||||
UserlandFSServer::Init(const char* fileSystem)
|
UserlandFSServer::Init(const char* fileSystem, port_id port)
|
||||||
{
|
{
|
||||||
// get the add-on path
|
// get the add-on path
|
||||||
BPath addOnPath;
|
BPath addOnPath;
|
||||||
@@ -118,11 +120,12 @@ UserlandFSServer::Init(const char* fileSystem)
|
|||||||
if (gServerSettings.ShallEnterDebugger())
|
if (gServerSettings.ShallEnterDebugger())
|
||||||
debugger("File system ready to use.");
|
debugger("File system ready to use.");
|
||||||
|
|
||||||
// finally register with the dispatcher
|
// finally announce our existence
|
||||||
error = _RegisterWithDispatcher(fileSystem);
|
error = _Announce(fileSystem, port);
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetNotificationRequestPort
|
// GetNotificationRequestPort
|
||||||
RequestPort*
|
RequestPort*
|
||||||
UserlandFSServer::GetNotificationRequestPort()
|
UserlandFSServer::GetNotificationRequestPort()
|
||||||
@@ -132,6 +135,7 @@ UserlandFSServer::GetNotificationRequestPort()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// GetFileSystem
|
// GetFileSystem
|
||||||
FileSystem*
|
FileSystem*
|
||||||
UserlandFSServer::GetFileSystem()
|
UserlandFSServer::GetFileSystem()
|
||||||
@@ -141,62 +145,37 @@ UserlandFSServer::GetFileSystem()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// _RegisterWithDispatcher
|
|
||||||
|
// _Announce
|
||||||
status_t
|
status_t
|
||||||
UserlandFSServer::_RegisterWithDispatcher(const char* fsName)
|
UserlandFSServer::_Announce(const char* fsName, port_id port)
|
||||||
{
|
{
|
||||||
// get the dispatcher messenger from the clipboard
|
// if not given, create a port
|
||||||
BMessenger messenger;
|
if (port < 0) {
|
||||||
BClipboard clipboard(kUserlandFSDispatcherClipboardName);
|
char portName[B_OS_NAME_LENGTH];
|
||||||
if (AutoLocker<BClipboard> locker = clipboard) {
|
snprintf(portName, sizeof(portName), "_userlandfs_%s", fsName);
|
||||||
status_t error = B_OK;
|
|
||||||
if (BMessage* data = clipboard.Data()) {
|
port = create_port(1, portName);
|
||||||
error = data->FindMessenger("messenger", &messenger);
|
if (port < 0)
|
||||||
if (error != B_OK) {
|
RETURN_ERROR(port);
|
||||||
ERROR(("No dispatcher messenger in clipboard.\n"));
|
|
||||||
return error;
|
|
||||||
}
|
|
||||||
if (!messenger.IsValid()) {
|
|
||||||
ERROR(("Found dispatcher messenger not valid.\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ERROR(("Failed to get clipboard data container\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ERROR(("Failed to lock the clipboard.\n"));
|
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocate stack space for the FS initialization info
|
||||||
|
const size_t bufferSize = sizeof(fs_init_info)
|
||||||
|
+ sizeof(Port::Info) * (kRequestThreadCount + 1);
|
||||||
|
char buffer[bufferSize];
|
||||||
|
fs_init_info* info = (fs_init_info*)buffer;
|
||||||
|
|
||||||
// get the port infos
|
// get the port infos
|
||||||
Port::Info infos[kRequestThreadCount + 1];
|
info->portInfoCount = kRequestThreadCount + 1;
|
||||||
infos[0] = *fNotificationRequestPort->GetPortInfo();
|
info->portInfos[0] = *fNotificationRequestPort->GetPortInfo();
|
||||||
for (int32 i = 0; i < kRequestThreadCount; i++)
|
for (int32 i = 0; i < kRequestThreadCount; i++)
|
||||||
infos[i + 1] = *fRequestThreads[i].GetPortInfo();
|
info->portInfos[i + 1] = *fRequestThreads[i].GetPortInfo();
|
||||||
|
|
||||||
// FS capabilities
|
// FS capabilities
|
||||||
FSCapabilities capabilities;
|
fFileSystem->GetCapabilities(info->capabilities);
|
||||||
fFileSystem->GetCapabilities(capabilities);
|
info->clientFSType = fFileSystem->GetClientFSType();
|
||||||
|
|
||||||
// init an FS info
|
// send the info to our port
|
||||||
FSInfo info;
|
RETURN_ERROR(write_port(port, 0, buffer, bufferSize));
|
||||||
status_t error = info.SetTo(fsName, infos, kRequestThreadCount + 1,
|
|
||||||
capabilities, fFileSystem->GetClientFSType());
|
|
||||||
|
|
||||||
// prepare the message
|
|
||||||
BMessage message(UFS_REGISTER_FS);
|
|
||||||
if (error == B_OK)
|
|
||||||
error = message.AddInt32("team", Team());
|
|
||||||
if (error == B_OK)
|
|
||||||
error = info.Archive(&message);
|
|
||||||
|
|
||||||
// send the message
|
|
||||||
BMessage reply;
|
|
||||||
error = messenger.SendMessage(&message, &reply);
|
|
||||||
if (error == B_OK && reply.what != UFS_REGISTER_FS_ACK) {
|
|
||||||
ERROR(("FS registration failed.\n"));
|
|
||||||
error = B_ERROR;
|
|
||||||
}
|
|
||||||
return error;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,13 +21,13 @@ public:
|
|||||||
UserlandFSServer(const char* signature);
|
UserlandFSServer(const char* signature);
|
||||||
virtual ~UserlandFSServer();
|
virtual ~UserlandFSServer();
|
||||||
|
|
||||||
status_t Init(const char* fileSystem);
|
status_t Init(const char* fileSystem, port_id port);
|
||||||
|
|
||||||
static RequestPort* GetNotificationRequestPort();
|
static RequestPort* GetNotificationRequestPort();
|
||||||
static FileSystem* GetFileSystem();
|
static FileSystem* GetFileSystem();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _RegisterWithDispatcher(const char* fsName);
|
status_t _Announce(const char* fsName, port_id port);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
image_id fAddOnImage;
|
image_id fAddOnImage;
|
||||||
|
|||||||
@@ -26,5 +26,5 @@ SharedLibrary libuserlandfs_beos_kernel.so
|
|||||||
BeOSKernelVolume.cpp
|
BeOSKernelVolume.cpp
|
||||||
|
|
||||||
:
|
:
|
||||||
<nogrist>UserlandFSServer
|
<nogrist>userlandfs_server
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -34,5 +34,5 @@ SharedLibrary libuserlandfs_haiku_kernel.so
|
|||||||
HaikuKernelVolume.cpp
|
HaikuKernelVolume.cpp
|
||||||
|
|
||||||
:
|
:
|
||||||
<nogrist>UserlandFSServer
|
<nogrist>userlandfs_server
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
// main.cpp
|
// main.cpp
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "ServerDefs.h"
|
#include "ServerDefs.h"
|
||||||
#include "UserlandFSDispatcher.h"
|
|
||||||
#include "UserlandFSServer.h"
|
#include "UserlandFSServer.h"
|
||||||
|
|
||||||
// server signature
|
// server signature
|
||||||
@@ -14,19 +16,19 @@ static const char* kServerSignature
|
|||||||
|
|
||||||
// usage
|
// usage
|
||||||
static const char* kUsage =
|
static const char* kUsage =
|
||||||
"Usage: %s <options>\n"
|
"Usage: %s <options> <file system> [ <port> ]\n"
|
||||||
" %s <options> <file system>\n"
|
|
||||||
"\n"
|
"\n"
|
||||||
"The first version runs the server as the dispatcher, i.e. as the singleton\n"
|
"Runs the userlandfs server for a given file system. Typically this is done\n"
|
||||||
"app the kernel add-on contacts when it is looking for a file system.\n"
|
"automatically by the kernel module when a volume is requested to be mounted,\n"
|
||||||
"The dispatcher uses the second version to start a server for a specific file\n"
|
"but running the server manually can be useful for debugging purposes. The\n"
|
||||||
"system.\n"
|
"<file system> argument specifies the name of the file system to be loaded.\n"
|
||||||
|
"<port> should not be given when starting the server manually; it is used by\n"
|
||||||
|
"the kernel module only.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
" --debug - the file system server enters the debugger after the\n"
|
" --debug - the file system server enters the debugger after the\n"
|
||||||
" userland file system add-on has been loaded and is\n"
|
" userland file system add-on has been loaded and is\n"
|
||||||
" ready to be used. If specified for the dispatcher, it\n"
|
" ready to be used.\n"
|
||||||
" passes the flag to all file system servers it starts.\n"
|
|
||||||
" -h, --help - print this text\n"
|
" -h, --help - print this text\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -80,37 +82,36 @@ main(int argc, char** argv)
|
|||||||
fileSystem = argv[argi++];
|
fileSystem = argv[argi++];
|
||||||
dispatcher = false;
|
dispatcher = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get the port, if any
|
||||||
|
int32 port = -1;
|
||||||
|
if (argi < argc) {
|
||||||
|
port = atol(argv[argi++]);
|
||||||
|
if (port <= 0) {
|
||||||
|
print_usage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (argi < argc) {
|
if (argi < argc) {
|
||||||
print_usage();
|
print_usage();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create and init the application
|
// create and init the application
|
||||||
BApplication* app = NULL;
|
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
if (dispatcher) {
|
UserlandFSServer* server
|
||||||
UserlandFSDispatcher* dispatcher
|
= new(std::nothrow) UserlandFSServer(kServerSignature);
|
||||||
= new(nothrow) UserlandFSDispatcher(kServerSignature);
|
if (!server) {
|
||||||
if (!dispatcher) {
|
fprintf(stderr, "Failed to create server.\n");
|
||||||
fprintf(stderr, "Failed to create dispatcher.\n");
|
return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
error = dispatcher->Init();
|
|
||||||
app = dispatcher;
|
|
||||||
} else {
|
|
||||||
UserlandFSServer* server
|
|
||||||
= new(nothrow) UserlandFSServer(kServerSignature);
|
|
||||||
if (!server) {
|
|
||||||
fprintf(stderr, "Failed to create server.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
error = server->Init(fileSystem);
|
|
||||||
app = server;
|
|
||||||
}
|
}
|
||||||
|
error = server->Init(fileSystem, port);
|
||||||
|
|
||||||
// run it, if everything went fine
|
// run it, if everything went fine
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
app->Run();
|
server->Run();
|
||||||
delete app;
|
|
||||||
|
delete server;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user