From 5e17d2d743272a72125b31b5ca055941b8b50721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 16 Jul 2015 22:36:02 +0200 Subject: [PATCH] mount_server: Ported to a launch_daemon world. * Now inherits from BServer, and gets its message port from the launch_daemon. * It registers an event "initial_volumes_mounted" that allows other services to be started afterwards. * This is now used in the boot launch files, and makes the scripting based previous solution superfluous which has been removed with this commit, too. * This implements the last needed feature in order to reproduce the complete former boot process using the launch_daemon. --- data/launch/system | 1 - data/launch/user | 6 + src/servers/mount/AutoMounter.cpp | 277 ++++++++++-------------------- src/servers/mount/AutoMounter.h | 21 ++- src/servers/mount/Jamfile | 6 +- 5 files changed, 107 insertions(+), 204 deletions(-) diff --git a/data/launch/system b/data/launch/system index 53e8ae0b49..1b737fdd95 100644 --- a/data/launch/system +++ b/data/launch/system @@ -26,7 +26,6 @@ service x-vnd.Haiku-SystemLogger { service x-vnd.Haiku-mount_server { launch /system/servers/mount_server - legacy } service x-vnd.Haiku-media_server { diff --git a/data/launch/user b/data/launch/user index 20950ac895..7792beb659 100644 --- a/data/launch/user +++ b/data/launch/user @@ -4,11 +4,17 @@ target desktop { service x-vnd.Be-TRAK { launch /system/Tracker legacy + on { + initial_volumes_mounted + } } service x-vnd.Be-TSKB { launch /system/Deskbar legacy + on { + initial_volumes_mounted + } } job create-installer-link { diff --git a/src/servers/mount/AutoMounter.cpp b/src/servers/mount/AutoMounter.cpp index 74545f15b6..dca79297d1 100644 --- a/src/servers/mount/AutoMounter.cpp +++ b/src/servers/mount/AutoMounter.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +38,6 @@ #include #include -//#include "AutoMounterSettings.h" #include "MountServer.h" @@ -46,11 +46,12 @@ static const char* kMountServerSettings = "mount_server"; -static const uint32 kMsgInitialScan = 'insc'; static const char* kMountFlagsKeyExtension = " mount flags"; +static const char* kInitialMountEvent = "initial_volumes_mounted"; -bool + +static bool BootedInSafeMode() { const char *safeMode = getenv("SAFEMODE"); @@ -63,7 +64,7 @@ BootedInSafeMode() AutoMounter::AutoMounter() : - BApplication(kMountServerSignature), + BServer(kMountServerSignature, true, NULL), fNormalMode(kRestorePreviousVolumes), fRemovableMode(kAllVolumes), fEjectWhenUnmounting(true) @@ -80,38 +81,30 @@ AutoMounter::AutoMounter() BDiskDeviceRoster().StartWatching(this, B_DEVICE_REQUEST_DEVICE | B_DEVICE_REQUEST_DEVICE_LIST); + BLaunchRoster().RegisterEvent(this, kInitialMountEvent); } AutoMounter::~AutoMounter() { + BLaunchRoster().UnregisterEvent(this, kInitialMountEvent); BDiskDeviceRoster().StopWatching(this); } +void +AutoMounter::ReadyToRun() +{ + // Do initial scan + _MountVolumes(fNormalMode, fRemovableMode, true); + BLaunchRoster().NotifyEvent(this, kInitialMountEvent); +} + + void AutoMounter::MessageReceived(BMessage* message) { switch (message->what) { - case B_EXECUTE_PROPERTY: - { - int32 index; - BMessage specifier; - int32 what; - const char* property = NULL; - if (message->GetCurrentSpecifier(&index, &specifier, &what, - &property) < B_OK - || !_ScriptReceived(message, index, &specifier, what, - property)) { - BApplication::MessageReceived(message); - } - break; - } - - case kMsgInitialScan: - _MountVolumes(fNormalMode, fRemovableMode, true); - break; - case kMountVolume: _MountVolume(message); break; @@ -270,169 +263,7 @@ AutoMounter::QuitRequested() } -// #pragma mark - scripting - - -const uint32 kApplication = 0; - -static property_info sPropertyInfo[] = { - { - "InitialScan", - {B_EXECUTE_PROPERTY}, - {B_DIRECT_SPECIFIER}, - NULL, kApplication, - {B_STRING_TYPE}, - {}, - {} - }, - {} -}; - - -BHandler* -AutoMounter::ResolveSpecifier(BMessage* message, int32 index, - BMessage* specifier, int32 what, const char* property) -{ - BPropertyInfo propInfo(sPropertyInfo); - - uint32 data; - if (propInfo.FindMatch(message, 0, specifier, what, property, &data) >= 0) { - if (data == kApplication) - return this; - - BMessage reply(B_MESSAGE_NOT_UNDERSTOOD); - reply.AddInt32("error", B_ERROR); - reply.AddString("message", "Unkown specifier."); - message->SendReply(&reply); - return NULL; - } - - return BApplication::ResolveSpecifier(message, index, specifier, what, - property); -} - - -status_t -AutoMounter::GetSupportedSuites(BMessage* data) -{ - if (data == NULL) - return B_BAD_VALUE; - - status_t status = data->AddString("suites", - "suite/vnd.Haiku-mount_server"); - if (status != B_OK) - return status; - - BPropertyInfo propertyInfo(sPropertyInfo); - status = data->AddFlat("messages", &propertyInfo); - if (status != B_OK) - return status; - - return BApplication::GetSupportedSuites(data); -} - - -bool -AutoMounter::_ScriptReceived(BMessage *message, int32 index, - BMessage *specifier, int32 what, const char *property) -{ - BMessage reply(B_REPLY); - status_t err = B_BAD_SCRIPT_SYNTAX; - - switch (message->what) { - case B_EXECUTE_PROPERTY: - if (strcmp("InitialScan", property) == 0) { - _MountVolumes(fNormalMode, fRemovableMode, true); - err = reply.AddString("result", - B_TRANSLATE("Previous volumes mounted.")); - } - break; - } - - if (err == B_BAD_SCRIPT_SYNTAX) - return false; - - if (err != B_OK) { - reply.what = B_MESSAGE_NOT_UNDERSTOOD; - reply.AddString("message", strerror(err)); - } - reply.AddInt32("error", err); - message->SendReply(&reply); - return true; -} - - -// #pragma mark - - - -static bool -suggest_mount_flags(const BPartition* partition, uint32* _flags) -{ - uint32 mountFlags = 0; - - bool askReadOnly = true; - bool isBFS = false; - - if (partition->ContentType() != NULL - && strcmp(partition->ContentType(), kPartitionTypeBFS) == 0) { -#if 0 - askReadOnly = false; -#endif - isBFS = true; - } - - BDiskSystem diskSystem; - status_t status = partition->GetDiskSystem(&diskSystem); - if (status == B_OK && !diskSystem.SupportsWriting()) - askReadOnly = false; - - if (partition->IsReadOnly()) - askReadOnly = false; - - if (askReadOnly) { - // Suggest to the user to mount read-only until Haiku is more mature. - BString string; - if (partition->ContentName() != NULL) { - char buffer[512]; - snprintf(buffer, sizeof(buffer), - B_TRANSLATE("Mounting volume '%s'\n\n"), - partition->ContentName()); - string << buffer; - } else - string << B_TRANSLATE("Mounting volume \n\n"); - - // TODO: Use distro name instead of "Haiku"... - if (!isBFS) { - string << B_TRANSLATE("The file system on this volume is not the " - "Haiku file system. It is strongly suggested to mount it in " - "read-only mode. This will prevent unintentional data loss " - "because of errors in Haiku."); - } else { - string << B_TRANSLATE("It is suggested to mount all additional " - "Haiku volumes in read-only mode. This will prevent " - "unintentional data loss because of errors in Haiku."); - } - - BAlert* alert = new BAlert(B_TRANSLATE("Mount warning"), - string.String(), B_TRANSLATE("Mount read/write"), - B_TRANSLATE("Cancel"), B_TRANSLATE("Mount read-only"), - B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); - alert->SetShortcut(1, B_ESCAPE); - int32 choice = alert->Go(); - switch (choice) { - case 0: - break; - case 1: - return false; - case 2: - mountFlags |= B_MOUNT_READ_ONLY; - break; - } - } - - *_flags = mountFlags; - return true; -} +// #pragma mark - private methods void @@ -515,7 +346,7 @@ AutoMounter::_MountVolumes(mount_mode normal, mount_mode removable, if (!fInitialRescan) { // Ask the user about mount flags if this is not the // initial scan. - if (!suggest_mount_flags(partition, &mountFlags)) + if (!_SuggestMountFlags(partition, &mountFlags)) return false; } else { BString mountFlagsKey(path.Path()); @@ -561,7 +392,7 @@ AutoMounter::_MountVolume(const BMessage* message) return; uint32 mountFlags; - if (!suggest_mount_flags(partition, &mountFlags)) + if (!_SuggestMountFlags(partition, &mountFlags)) return; status_t status = partition->Mount(NULL, mountFlags); @@ -929,6 +760,76 @@ AutoMounter::_GetSettings(BMessage *message) } +/*static*/ bool +AutoMounter::_SuggestMountFlags(const BPartition* partition, uint32* _flags) +{ + uint32 mountFlags = 0; + + bool askReadOnly = true; + bool isBFS = false; + + if (partition->ContentType() != NULL + && strcmp(partition->ContentType(), kPartitionTypeBFS) == 0) { +#if 0 + askReadOnly = false; +#endif + isBFS = true; + } + + BDiskSystem diskSystem; + status_t status = partition->GetDiskSystem(&diskSystem); + if (status == B_OK && !diskSystem.SupportsWriting()) + askReadOnly = false; + + if (partition->IsReadOnly()) + askReadOnly = false; + + if (askReadOnly) { + // Suggest to the user to mount read-only until Haiku is more mature. + BString string; + if (partition->ContentName() != NULL) { + char buffer[512]; + snprintf(buffer, sizeof(buffer), + B_TRANSLATE("Mounting volume '%s'\n\n"), + partition->ContentName()); + string << buffer; + } else + string << B_TRANSLATE("Mounting volume \n\n"); + + // TODO: Use distro name instead of "Haiku"... + if (!isBFS) { + string << B_TRANSLATE("The file system on this volume is not the " + "Haiku file system. It is strongly suggested to mount it in " + "read-only mode. This will prevent unintentional data loss " + "because of errors in Haiku."); + } else { + string << B_TRANSLATE("It is suggested to mount all additional " + "Haiku volumes in read-only mode. This will prevent " + "unintentional data loss because of errors in Haiku."); + } + + BAlert* alert = new BAlert(B_TRANSLATE("Mount warning"), + string.String(), B_TRANSLATE("Mount read/write"), + B_TRANSLATE("Cancel"), B_TRANSLATE("Mount read-only"), + B_WIDTH_FROM_WIDEST, B_WARNING_ALERT); + alert->SetShortcut(1, B_ESCAPE); + int32 choice = alert->Go(); + switch (choice) { + case 0: + break; + case 1: + return false; + case 2: + mountFlags |= B_MOUNT_READ_ONLY; + break; + } + } + + *_flags = mountFlags; + return true; +} + + // #pragma mark - diff --git a/src/servers/mount/AutoMounter.h b/src/servers/mount/AutoMounter.h index edc90aeb9f..1539910567 100644 --- a/src/servers/mount/AutoMounter.h +++ b/src/servers/mount/AutoMounter.h @@ -1,32 +1,30 @@ /* - * Copyright 2007-2009, Haiku, Inc. All rights reserved. + * Copyright 2007-2015, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. */ #ifndef AUTO_MOUNTER_H #define AUTO_MOUNTER_H -#include + #include #include #include +#include + class BPartition; class BPath; -class AutoMounter : public BApplication { +class AutoMounter : public BServer { public: AutoMounter(); virtual ~AutoMounter(); + virtual void ReadyToRun(); virtual void MessageReceived(BMessage* message); virtual bool QuitRequested(); - virtual BHandler* ResolveSpecifier(BMessage* message, - int32 index, BMessage* specifier, - int32 what, const char* property); - virtual status_t GetSupportedSuites(BMessage* data); - private: enum mount_mode { kNoVolumes, @@ -36,9 +34,6 @@ private: }; void _GetSettings(BMessage* message); - bool _ScriptReceived(BMessage* msg, int32 index, - BMessage* specifier, int32 form, - const char* property); void _MountVolumes(mount_mode normal, mount_mode removable, @@ -62,6 +57,9 @@ private: void _ReadSettings(); void _WriteSettings(); + static bool _SuggestMountFlags(const BPartition* partition, + uint32* _flags); + private: mount_mode fNormalMode; mount_mode fRemovableMode; @@ -71,4 +69,5 @@ private: BMessage fSettings; }; + #endif // AUTO_MOUNTER_H diff --git a/src/servers/mount/Jamfile b/src/servers/mount/Jamfile index 469feef6c7..b9b4f50794 100644 --- a/src/servers/mount/Jamfile +++ b/src/servers/mount/Jamfile @@ -1,14 +1,12 @@ SubDir HAIKU_TOP src servers mount ; -UsePrivateHeaders mount shared storage ; +UsePrivateHeaders app mount shared storage ; Server mount_server : AutoMounter.cpp -# AutoMounterSettings.cpp : - libbe.so localestub - [ TargetLibstdc++ ] + libbe.so localestub [ TargetLibstdc++ ] : mount_server.rdef ;