launch_daemon: Initialize /tmp & /var/shared_memory, clock.
* Added initializing /tmp & /var/shared_memory to the launch_daemon. * Moved clockconfig.cpp code into the launch_daemon. * This follows systemd design; since those jobs are fixed, it doesn't matter where you maintain them. * The init jobs are BJobs, but the JobQueue is only used for that one use for now. At a later time, I intend to put the job launching in there, as well. BJob allows to represent the dependencies already.
This commit is contained in:
@@ -3,8 +3,7 @@
|
||||
SYSTEM_BIN = [ FFilterByBuildFeatures
|
||||
addattr alert arp
|
||||
bc beep bfsinfo
|
||||
catattr checkfs checkitout chop clear
|
||||
clockconfig cmp collectcatkeys compress copyattr
|
||||
catattr checkfs checkitout chop clear cmp collectcatkeys compress copyattr
|
||||
dc desklink df diff diff3 diskimage draggers
|
||||
driveinfo dstcheck dumpcatalog
|
||||
eject error
|
||||
|
||||
@@ -81,7 +81,6 @@ StdBinCommands
|
||||
catattr.cpp
|
||||
checkfs.cpp
|
||||
clipboard.cpp
|
||||
clockconfig.cpp
|
||||
df.cpp
|
||||
diskimage.cpp
|
||||
dpms.cpp
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "AbstractEmptyDirectoryJob.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Directory.h>
|
||||
#include <Entry.h>
|
||||
|
||||
|
||||
AbstractEmptyDirectoryJob::AbstractEmptyDirectoryJob(const BString& name)
|
||||
:
|
||||
BJob(name)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractEmptyDirectoryJob::CreateAndEmpty(const char* path) const
|
||||
{
|
||||
BEntry entry(path);
|
||||
if (entry.InitCheck() != B_OK) {
|
||||
create_directory(path, 0777);
|
||||
|
||||
status_t status = entry.SetTo(path);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "Cannot create directory \"%s\": %s\n", path,
|
||||
strerror(status));
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
return _EmptyDirectory(entry, false);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
AbstractEmptyDirectoryJob::_EmptyDirectory(BEntry& directoryEntry,
|
||||
bool remove) const
|
||||
{
|
||||
BDirectory directory(&directoryEntry);
|
||||
BEntry entry;
|
||||
while (directory.GetNextEntry(&entry) == B_OK) {
|
||||
if (entry.IsDirectory())
|
||||
_EmptyDirectory(entry, true);
|
||||
else
|
||||
entry.Remove();
|
||||
}
|
||||
|
||||
return remove ? directoryEntry.Remove() : B_OK;
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef ABSTRACT_EMPTY_DIRECTORY_JOB_H
|
||||
#define ABSTRACT_EMPTY_DIRECTORY_JOB_H
|
||||
|
||||
|
||||
#include <Job.h>
|
||||
|
||||
|
||||
class BEntry;
|
||||
|
||||
|
||||
class AbstractEmptyDirectoryJob : public BSupportKit::BJob {
|
||||
public:
|
||||
AbstractEmptyDirectoryJob(const BString& name);
|
||||
|
||||
protected:
|
||||
status_t CreateAndEmpty(const char* path) const;
|
||||
|
||||
private:
|
||||
status_t _EmptyDirectory(BEntry& directoryEntry,
|
||||
bool remove) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // ABSTRACT_EMPTY_DIRECTORY_JOB_H
|
||||
@@ -1,43 +1,64 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Copyright 2004, Jérôme Duval, jerome.duval@free.fr.
|
||||
* Copyright 2010, 2012, Oliver Tappe <zooey@hirschkaefer.de>
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
//! Initialize real time clock, and time zone offset
|
||||
|
||||
|
||||
#include "InitRealTimeClockJob.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <File.h>
|
||||
#include <FindDirectory.h>
|
||||
#include <Message.h>
|
||||
#include <OS.h>
|
||||
#include <Path.h>
|
||||
#include <String.h>
|
||||
#include <TimeZone.h>
|
||||
|
||||
#include <syscalls.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
using BSupportKit::BJob;
|
||||
|
||||
|
||||
static char* program;
|
||||
InitRealTimeClockJob::InitRealTimeClockJob()
|
||||
:
|
||||
BJob("init real time clock")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
InitRealTimeClockJob::Execute()
|
||||
{
|
||||
BPath path;
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (status == B_OK) {
|
||||
_SetRealTimeClockIsGMT(path);
|
||||
_SetTimeZoneOffset(path);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setRealTimeClockIsGMT(BPath path)
|
||||
InitRealTimeClockJob::_SetRealTimeClockIsGMT(BPath path) const
|
||||
{
|
||||
path.Append("RTC_time_settings");
|
||||
BFile file;
|
||||
status_t status = file.SetTo(path.Path(), B_READ_ONLY);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: can't open RTC settings file\n", program);
|
||||
fprintf(stderr, "Can't open RTC settings file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[10];
|
||||
ssize_t bytesRead = file.Read(buffer, sizeof(buffer));
|
||||
if (bytesRead < 0) {
|
||||
fprintf(stderr, "%s: unable to read RTC settings file\n", program);
|
||||
fprintf(stderr, "Unable to read RTC settings file\n");
|
||||
return;
|
||||
}
|
||||
bool isGMT = strncmp(buffer, "local", 5) != 0;
|
||||
@@ -48,25 +69,25 @@ setRealTimeClockIsGMT(BPath path)
|
||||
|
||||
|
||||
void
|
||||
setTimeZoneOffset(BPath path)
|
||||
InitRealTimeClockJob::_SetTimeZoneOffset(BPath path) const
|
||||
{
|
||||
path.Append("Time settings");
|
||||
BFile file;
|
||||
status_t status = file.SetTo(path.Path(), B_READ_ONLY);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: can't open Time settings file\n", program);
|
||||
fprintf(stderr, "Can't open Time settings file\n");
|
||||
return;
|
||||
}
|
||||
|
||||
BMessage settings;
|
||||
status = settings.Unflatten(&file);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: unable to parse Time settings file\n", program);
|
||||
fprintf(stderr, "Unable to parse Time settings file\n");
|
||||
return;
|
||||
}
|
||||
BString timeZoneID;
|
||||
if (settings.FindString("timezone", &timeZoneID) != B_OK) {
|
||||
fprintf(stderr, "%s: no timezone found\n", program);
|
||||
fprintf(stderr, "No timezone found\n");
|
||||
return;
|
||||
}
|
||||
int32 timeZoneOffset = BTimeZone(timeZoneID.String()).OffsetFromGMT();
|
||||
@@ -76,22 +97,3 @@ setTimeZoneOffset(BPath path)
|
||||
printf("timezone is %s, offset is %" B_PRId32 " seconds from GMT.\n",
|
||||
timeZoneID.String(), timeZoneOffset);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
program = argv[0];
|
||||
|
||||
BPath path;
|
||||
status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path);
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: can't find settings directory\n", program);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
setRealTimeClockIsGMT(path);
|
||||
setTimeZoneOffset(path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INIT_REAL_TIME_CLOCK_JOB_H
|
||||
#define INIT_REAL_TIME_CLOCK_JOB_H
|
||||
|
||||
|
||||
#include <Job.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
class InitRealTimeClockJob : public BSupportKit::BJob {
|
||||
public:
|
||||
InitRealTimeClockJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
|
||||
private:
|
||||
void _SetRealTimeClockIsGMT(BPath path) const;
|
||||
void _SetTimeZoneOffset(BPath path) const;
|
||||
};
|
||||
|
||||
|
||||
#endif // INIT_REAL_TIME_CLOCK_JOB_H
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
//! Empty main temporary directory
|
||||
|
||||
|
||||
#include "InitSharedMemoryDirectoryJob.h"
|
||||
|
||||
|
||||
InitSharedMemoryDirectoryJob::InitSharedMemoryDirectoryJob()
|
||||
:
|
||||
AbstractEmptyDirectoryJob("init /var/shared_memory")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
InitSharedMemoryDirectoryJob::Execute()
|
||||
{
|
||||
return CreateAndEmpty("/var/shared_memory");
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INIT_SHARED_MEMORY_DIRECTORY_JOB_H
|
||||
#define INIT_SHARED_MEMORY_DIRECTORY_JOB_H
|
||||
|
||||
|
||||
#include "AbstractEmptyDirectoryJob.h"
|
||||
|
||||
|
||||
class InitSharedMemoryDirectoryJob : public AbstractEmptyDirectoryJob {
|
||||
public:
|
||||
InitSharedMemoryDirectoryJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
};
|
||||
|
||||
|
||||
#endif // INIT_SHARED_MEMORY_DIRECTORY_JOB_H
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
//! Empty main temporary directory
|
||||
|
||||
|
||||
#include "InitTemporaryDirectoryJob.h"
|
||||
|
||||
#include <FindDirectory.h>
|
||||
#include <Path.h>
|
||||
|
||||
|
||||
InitTemporaryDirectoryJob::InitTemporaryDirectoryJob()
|
||||
:
|
||||
AbstractEmptyDirectoryJob("init /tmp")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
InitTemporaryDirectoryJob::Execute()
|
||||
{
|
||||
// TODO: the /tmp entries could be scanned synchronously, and deleted
|
||||
// later
|
||||
BPath path;
|
||||
status_t status = find_directory(B_SYSTEM_TEMP_DIRECTORY, &path, true);
|
||||
if (status == B_OK)
|
||||
return CreateAndEmpty(path.Path());
|
||||
|
||||
return status;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2015, Axel Dörfler, [email protected].
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INIT_TEMPORARY_DIRECTORY_JOB_H
|
||||
#define INIT_TEMPORARY_DIRECTORY_JOB_H
|
||||
|
||||
|
||||
#include "AbstractEmptyDirectoryJob.h"
|
||||
|
||||
|
||||
class InitTemporaryDirectoryJob : public AbstractEmptyDirectoryJob {
|
||||
public:
|
||||
InitTemporaryDirectoryJob();
|
||||
|
||||
protected:
|
||||
virtual status_t Execute();
|
||||
};
|
||||
|
||||
|
||||
#endif // INIT_TEMPORARY_DIRECTORY_JOB_H
|
||||
@@ -1,11 +1,17 @@
|
||||
SubDir HAIKU_TOP src servers launch ;
|
||||
|
||||
UsePrivateHeaders app shared ;
|
||||
UsePrivateHeaders app package shared storage support ;
|
||||
UsePrivateSystemHeaders ;
|
||||
|
||||
Server launch_daemon
|
||||
:
|
||||
LaunchDaemon.cpp
|
||||
|
||||
# init jobs
|
||||
AbstractEmptyDirectoryJob.cpp
|
||||
InitRealTimeClockJob.cpp
|
||||
InitSharedMemoryDirectoryJob.cpp
|
||||
InitTemporaryDirectoryJob.cpp
|
||||
:
|
||||
be libshared.a [ TargetLibstdc++ ]
|
||||
:
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <Directory.h>
|
||||
#include <driver_settings.h>
|
||||
#include <Entry.h>
|
||||
#include <File.h>
|
||||
#include <ObjectList.h>
|
||||
#include <Path.h>
|
||||
#include <PathFinder.h>
|
||||
@@ -20,11 +21,18 @@
|
||||
|
||||
#include <AppMisc.h>
|
||||
#include <DriverSettingsMessageAdapter.h>
|
||||
#include <JobQueue.h>
|
||||
#include <LaunchDaemonDefs.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
#include "InitRealTimeClockJob.h"
|
||||
#include "InitSharedMemoryDirectoryJob.h"
|
||||
#include "InitTemporaryDirectoryJob.h"
|
||||
|
||||
|
||||
using namespace BPrivate;
|
||||
using namespace BSupportKit;
|
||||
using BSupportKit::BPrivate::JobQueue;
|
||||
|
||||
|
||||
static const char* kLaunchDirectory = "launch";
|
||||
@@ -127,11 +135,16 @@ private:
|
||||
void _InitJobs();
|
||||
void _LaunchJobs();
|
||||
|
||||
void _RetrieveKernelOptions();
|
||||
void _SetupEnvironment();
|
||||
void _InitSystem();
|
||||
|
||||
bool _IsSafeMode() const;
|
||||
|
||||
private:
|
||||
JobMap fJobs;
|
||||
JobQueue fJobQueue;
|
||||
bool fSafeMode;
|
||||
};
|
||||
|
||||
|
||||
@@ -410,7 +423,9 @@ LaunchDaemon::~LaunchDaemon()
|
||||
void
|
||||
LaunchDaemon::ReadyToRun()
|
||||
{
|
||||
_RetrieveKernelOptions();
|
||||
_SetupEnvironment();
|
||||
_InitSystem();
|
||||
|
||||
BStringList paths;
|
||||
BPathFinder::FindPaths(B_FIND_PATH_DATA_DIRECTORY, kLaunchDirectory,
|
||||
@@ -609,29 +624,52 @@ LaunchDaemon::_LaunchJobs()
|
||||
|
||||
|
||||
void
|
||||
LaunchDaemon::_SetupEnvironment()
|
||||
{
|
||||
// Determine safemode kernel option
|
||||
BString safemode = "SAFEMODE=";
|
||||
safemode << _IsSafeMode() ? "yes" : "no";
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LaunchDaemon::_IsSafeMode() const
|
||||
LaunchDaemon::_RetrieveKernelOptions()
|
||||
{
|
||||
char buffer[32];
|
||||
size_t size = sizeof(buffer);
|
||||
status_t status = _kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, buffer,
|
||||
&size);
|
||||
if (status == B_OK) {
|
||||
return !strncasecmp(buffer, "true", size)
|
||||
fSafeMode = !strncasecmp(buffer, "true", size)
|
||||
|| !strncasecmp(buffer, "yes", size)
|
||||
|| !strncasecmp(buffer, "on", size)
|
||||
|| !strncasecmp(buffer, "enabled", size);
|
||||
}
|
||||
} else
|
||||
fSafeMode = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
void
|
||||
LaunchDaemon::_SetupEnvironment()
|
||||
{
|
||||
// Determine safemode kernel option
|
||||
BString safemode = "SAFEMODE=";
|
||||
safemode << _IsSafeMode() ? "yes" : "no";
|
||||
|
||||
putenv(safemode.String());
|
||||
}
|
||||
|
||||
|
||||
/*! Basic system initialization that must happen before any jobs are launched.
|
||||
*/
|
||||
void
|
||||
LaunchDaemon::_InitSystem()
|
||||
{
|
||||
fJobQueue.AddJob(new InitRealTimeClockJob());
|
||||
fJobQueue.AddJob(new InitSharedMemoryDirectoryJob());
|
||||
fJobQueue.AddJob(new InitTemporaryDirectoryJob());
|
||||
|
||||
// TODO: these should be done in parallel
|
||||
while (BJob* job = fJobQueue.Pop())
|
||||
job->Run();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LaunchDaemon::_IsSafeMode() const
|
||||
{
|
||||
return fSafeMode;
|
||||
}
|
||||
|
||||
|
||||
@@ -647,6 +685,7 @@ main()
|
||||
if (fd != STDOUT_FILENO)
|
||||
dup2(fd, STDOUT_FILENO);
|
||||
puts("launch_daemon is alive and kicking.");
|
||||
fflush(stdout);
|
||||
|
||||
status_t status;
|
||||
LaunchDaemon* daemon = new LaunchDaemon(status);
|
||||
|
||||
Reference in New Issue
Block a user