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:
Axel Dörfler
2015-07-22 20:41:14 +02:00
parent ef462ab57f
commit c16361c49c
12 changed files with 305 additions and 51 deletions
+1 -2
View File
@@ -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
-1
View File
@@ -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;
}
+26
View File
@@ -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
+7 -1
View File
@@ -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++ ]
:
+52 -13
View File
@@ -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);