launch_daemon: Now blocks the CD tray on read-only /boot.
This commit is contained in:
parent
634aefe4fd
commit
19a4ba1015
@ -13,9 +13,7 @@
|
||||
#include <Message.h>
|
||||
#include <StringList.h>
|
||||
|
||||
#include <DiskDevice.h>
|
||||
#include <DiskDeviceRoster.h>
|
||||
#include <Volume.h>
|
||||
#include "Utility.h"
|
||||
|
||||
|
||||
class ConditionContainer : public Condition {
|
||||
@ -86,7 +84,9 @@ public:
|
||||
virtual BString ToString() const;
|
||||
|
||||
private:
|
||||
dev_t fDevice;
|
||||
BString fPath;
|
||||
mutable bool fIsReadOnly;
|
||||
mutable bool fTestPerformed;
|
||||
};
|
||||
|
||||
|
||||
@ -365,33 +365,28 @@ SafeModeCondition::ToString() const
|
||||
|
||||
|
||||
ReadOnlyCondition::ReadOnlyCondition(const BMessage& args)
|
||||
:
|
||||
fPath(args.GetString("args")),
|
||||
fIsReadOnly(false),
|
||||
fTestPerformed(false)
|
||||
{
|
||||
fDevice = dev_for_path(args.GetString("args", "/boot"));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ReadOnlyCondition::Test(ConditionContext& context) const
|
||||
{
|
||||
BVolume volume;
|
||||
status_t status = volume.SetTo(fDevice);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "Failed to get BVolume for device %" B_PRIdDEV
|
||||
": %s\n", fDevice, strerror(status));
|
||||
return false;
|
||||
}
|
||||
if (fTestPerformed)
|
||||
return fIsReadOnly;
|
||||
|
||||
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", fDevice, strerror(status));
|
||||
return false;
|
||||
}
|
||||
if (fPath.IsEmpty() || fPath == "/boot")
|
||||
fIsReadOnly = context.BootVolumeIsReadOnly();
|
||||
else
|
||||
fIsReadOnly = Utility::IsReadOnlyVolume(fPath);
|
||||
|
||||
return partition->IsReadOnly();
|
||||
fTestPerformed = true;
|
||||
|
||||
return fIsReadOnly;
|
||||
}
|
||||
|
||||
|
||||
@ -406,7 +401,7 @@ BString
|
||||
ReadOnlyCondition::ToString() const
|
||||
{
|
||||
BString string = "readonly ";
|
||||
string << fDevice;
|
||||
string << fPath;
|
||||
return string;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ class BMessage;
|
||||
class ConditionContext {
|
||||
public:
|
||||
virtual bool IsSafeMode() const = 0;
|
||||
virtual bool BootVolumeIsReadOnly() const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -14,6 +14,7 @@ Server launch_daemon
|
||||
Job.cpp
|
||||
SettingsParser.cpp
|
||||
Target.cpp
|
||||
Utility.cpp
|
||||
Worker.cpp
|
||||
|
||||
# init jobs
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "Job.h"
|
||||
#include "SettingsParser.h"
|
||||
#include "Target.h"
|
||||
#include "Utility.h"
|
||||
#include "Worker.h"
|
||||
|
||||
|
||||
@ -78,6 +79,7 @@ public:
|
||||
Session* FindSession(uid_t user) const;
|
||||
|
||||
virtual bool IsSafeMode() const;
|
||||
virtual bool BootVolumeIsReadOnly() const;
|
||||
|
||||
virtual void ReadyToRun();
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
@ -123,6 +125,7 @@ private:
|
||||
MainWorker* fMainWorker;
|
||||
Target* fInitTarget;
|
||||
bool fSafeMode;
|
||||
bool fReadOnlyBootVolume;
|
||||
bool fUserMode;
|
||||
};
|
||||
|
||||
@ -221,11 +224,23 @@ LaunchDaemon::IsSafeMode() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LaunchDaemon::BootVolumeIsReadOnly() const
|
||||
{
|
||||
return fReadOnlyBootVolume;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LaunchDaemon::ReadyToRun()
|
||||
{
|
||||
_RetrieveKernelOptions();
|
||||
_SetupEnvironment();
|
||||
|
||||
fReadOnlyBootVolume = Utility::IsReadOnlyVolume("/boot");
|
||||
if (fReadOnlyBootVolume)
|
||||
Utility::BlockMedia("/boot", true);
|
||||
|
||||
if (fUserMode) {
|
||||
BLaunchRoster roster;
|
||||
BLaunchRoster::Private(roster).RegisterSessionDaemon(this);
|
||||
|
80
src/servers/launch/Utility.cpp
Normal file
80
src/servers/launch/Utility.cpp
Normal file
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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
|
20
src/servers/launch/Utility.h
Normal file
20
src/servers/launch/Utility.h
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* 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
|
Loading…
Reference in New Issue
Block a user