launch_daemon: Now blocks the CD tray on read-only /boot.
This commit is contained in:
@@ -13,9 +13,7 @@
|
|||||||
#include <Message.h>
|
#include <Message.h>
|
||||||
#include <StringList.h>
|
#include <StringList.h>
|
||||||
|
|
||||||
#include <DiskDevice.h>
|
#include "Utility.h"
|
||||||
#include <DiskDeviceRoster.h>
|
|
||||||
#include <Volume.h>
|
|
||||||
|
|
||||||
|
|
||||||
class ConditionContainer : public Condition {
|
class ConditionContainer : public Condition {
|
||||||
@@ -86,7 +84,9 @@ public:
|
|||||||
virtual BString ToString() const;
|
virtual BString ToString() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
dev_t fDevice;
|
BString fPath;
|
||||||
|
mutable bool fIsReadOnly;
|
||||||
|
mutable bool fTestPerformed;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -365,33 +365,28 @@ SafeModeCondition::ToString() const
|
|||||||
|
|
||||||
|
|
||||||
ReadOnlyCondition::ReadOnlyCondition(const BMessage& args)
|
ReadOnlyCondition::ReadOnlyCondition(const BMessage& args)
|
||||||
|
:
|
||||||
|
fPath(args.GetString("args")),
|
||||||
|
fIsReadOnly(false),
|
||||||
|
fTestPerformed(false)
|
||||||
{
|
{
|
||||||
fDevice = dev_for_path(args.GetString("args", "/boot"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
ReadOnlyCondition::Test(ConditionContext& context) const
|
ReadOnlyCondition::Test(ConditionContext& context) const
|
||||||
{
|
{
|
||||||
BVolume volume;
|
if (fTestPerformed)
|
||||||
status_t status = volume.SetTo(fDevice);
|
return fIsReadOnly;
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, "Failed to get BVolume for device %" B_PRIdDEV
|
|
||||||
": %s\n", fDevice, strerror(status));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
BDiskDeviceRoster roster;
|
if (fPath.IsEmpty() || fPath == "/boot")
|
||||||
BDiskDevice diskDevice;
|
fIsReadOnly = context.BootVolumeIsReadOnly();
|
||||||
BPartition* partition;
|
else
|
||||||
status = roster.FindPartitionByVolume(volume, &diskDevice, &partition);
|
fIsReadOnly = Utility::IsReadOnlyVolume(fPath);
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, "Failed to get partition for device %" B_PRIdDEV
|
|
||||||
": %s\n", fDevice, strerror(status));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return partition->IsReadOnly();
|
fTestPerformed = true;
|
||||||
|
|
||||||
|
return fIsReadOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -406,7 +401,7 @@ BString
|
|||||||
ReadOnlyCondition::ToString() const
|
ReadOnlyCondition::ToString() const
|
||||||
{
|
{
|
||||||
BString string = "readonly ";
|
BString string = "readonly ";
|
||||||
string << fDevice;
|
string << fPath;
|
||||||
return string;
|
return string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class BMessage;
|
|||||||
class ConditionContext {
|
class ConditionContext {
|
||||||
public:
|
public:
|
||||||
virtual bool IsSafeMode() const = 0;
|
virtual bool IsSafeMode() const = 0;
|
||||||
|
virtual bool BootVolumeIsReadOnly() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ Server launch_daemon
|
|||||||
Job.cpp
|
Job.cpp
|
||||||
SettingsParser.cpp
|
SettingsParser.cpp
|
||||||
Target.cpp
|
Target.cpp
|
||||||
|
Utility.cpp
|
||||||
Worker.cpp
|
Worker.cpp
|
||||||
|
|
||||||
# init jobs
|
# init jobs
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
#include "SettingsParser.h"
|
#include "SettingsParser.h"
|
||||||
#include "Target.h"
|
#include "Target.h"
|
||||||
|
#include "Utility.h"
|
||||||
#include "Worker.h"
|
#include "Worker.h"
|
||||||
|
|
||||||
|
|
||||||
@@ -78,6 +79,7 @@ public:
|
|||||||
Session* FindSession(uid_t user) const;
|
Session* FindSession(uid_t user) const;
|
||||||
|
|
||||||
virtual bool IsSafeMode() const;
|
virtual bool IsSafeMode() const;
|
||||||
|
virtual bool BootVolumeIsReadOnly() const;
|
||||||
|
|
||||||
virtual void ReadyToRun();
|
virtual void ReadyToRun();
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
@@ -123,6 +125,7 @@ private:
|
|||||||
MainWorker* fMainWorker;
|
MainWorker* fMainWorker;
|
||||||
Target* fInitTarget;
|
Target* fInitTarget;
|
||||||
bool fSafeMode;
|
bool fSafeMode;
|
||||||
|
bool fReadOnlyBootVolume;
|
||||||
bool fUserMode;
|
bool fUserMode;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -221,11 +224,23 @@ LaunchDaemon::IsSafeMode() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
LaunchDaemon::BootVolumeIsReadOnly() const
|
||||||
|
{
|
||||||
|
return fReadOnlyBootVolume;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
LaunchDaemon::ReadyToRun()
|
LaunchDaemon::ReadyToRun()
|
||||||
{
|
{
|
||||||
_RetrieveKernelOptions();
|
_RetrieveKernelOptions();
|
||||||
_SetupEnvironment();
|
_SetupEnvironment();
|
||||||
|
|
||||||
|
fReadOnlyBootVolume = Utility::IsReadOnlyVolume("/boot");
|
||||||
|
if (fReadOnlyBootVolume)
|
||||||
|
Utility::BlockMedia("/boot", true);
|
||||||
|
|
||||||
if (fUserMode) {
|
if (fUserMode) {
|
||||||
BLaunchRoster roster;
|
BLaunchRoster roster;
|
||||||
BLaunchRoster::Private(roster).RegisterSessionDaemon(this);
|
BLaunchRoster::Private(roster).RegisterSessionDaemon(this);
|
||||||
|
|||||||
@@ -0,0 +1,80 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "Utility.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <device/scsi.h>
|
||||||
|
#include <DiskDevice.h>
|
||||||
|
#include <DiskDeviceRoster.h>
|
||||||
|
#include <fs_info.h>
|
||||||
|
#include <Volume.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Utility {
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsReadOnlyVolume(dev_t device)
|
||||||
|
{
|
||||||
|
BVolume volume;
|
||||||
|
status_t status = volume.SetTo(device);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to get BVolume for device %" B_PRIdDEV
|
||||||
|
": %s\n", device, strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
BDiskDeviceRoster roster;
|
||||||
|
BDiskDevice diskDevice;
|
||||||
|
BPartition* partition;
|
||||||
|
status = roster.FindPartitionByVolume(volume, &diskDevice, &partition);
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "Failed to get partition for device %" B_PRIdDEV
|
||||||
|
": %s\n", device, strerror(status));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return partition->IsReadOnly();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsReadOnlyVolume(const char* path)
|
||||||
|
{
|
||||||
|
return IsReadOnlyVolume(dev_for_path(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BlockMedia(const char* path, bool block)
|
||||||
|
{
|
||||||
|
fs_info info;
|
||||||
|
if (fs_stat_dev(dev_for_path(path), &info) == B_OK) {
|
||||||
|
if (strcmp(info.fsh_name, "devfs") != 0)
|
||||||
|
path = info.device_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
int device = open(path, O_RDONLY);
|
||||||
|
if (device < 0)
|
||||||
|
return device;
|
||||||
|
|
||||||
|
status_t status = B_OK;
|
||||||
|
|
||||||
|
if (ioctl(device, B_SCSI_PREVENT_ALLOW, &block, sizeof(block)) != 0) {
|
||||||
|
fprintf(stderr, "Failed to block media on %s: %s\n", path,
|
||||||
|
strerror(errno));
|
||||||
|
status = errno;
|
||||||
|
}
|
||||||
|
close(device);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace Utility
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015, Axel Dörfler, [email protected].
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*/
|
||||||
|
#ifndef UTILITY_H
|
||||||
|
#define UTILITY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace Utility {
|
||||||
|
bool IsReadOnlyVolume(dev_t device);
|
||||||
|
bool IsReadOnlyVolume(const char* path);
|
||||||
|
|
||||||
|
status_t BlockMedia(const char* path, bool block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // UTILITY_H
|
||||||
Reference in New Issue
Block a user