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 SYSTEM_BIN = [ FFilterByBuildFeatures
addattr alert arp addattr alert arp
bc beep bfsinfo bc beep bfsinfo
catattr checkfs checkitout chop clear catattr checkfs checkitout chop clear cmp collectcatkeys compress copyattr
clockconfig cmp collectcatkeys compress copyattr
dc desklink df diff diff3 diskimage draggers dc desklink df diff diff3 diskimage draggers
driveinfo dstcheck dumpcatalog driveinfo dstcheck dumpcatalog
eject error eject error
-1
View File
@@ -81,7 +81,6 @@ StdBinCommands
catattr.cpp catattr.cpp
checkfs.cpp checkfs.cpp
clipboard.cpp clipboard.cpp
clockconfig.cpp
df.cpp df.cpp
diskimage.cpp diskimage.cpp
dpms.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 2004, Jérôme Duval, jerome.duval@free.fr.
* Copyright 2010, 2012, Oliver Tappe <zooey@hirschkaefer.de> * 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 <File.h>
#include <FindDirectory.h> #include <FindDirectory.h>
#include <Message.h> #include <Message.h>
#include <OS.h>
#include <Path.h>
#include <String.h>
#include <TimeZone.h> #include <TimeZone.h>
#include <syscalls.h> #include <syscalls.h>
#include <stdio.h>
#include <stdlib.h> using BSupportKit::BJob;
#include <string.h>
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 void
setRealTimeClockIsGMT(BPath path) InitRealTimeClockJob::_SetRealTimeClockIsGMT(BPath path) const
{ {
path.Append("RTC_time_settings"); path.Append("RTC_time_settings");
BFile file; BFile file;
status_t status = file.SetTo(path.Path(), B_READ_ONLY); status_t status = file.SetTo(path.Path(), B_READ_ONLY);
if (status != B_OK) { 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; return;
} }
char buffer[10]; char buffer[10];
ssize_t bytesRead = file.Read(buffer, sizeof(buffer)); ssize_t bytesRead = file.Read(buffer, sizeof(buffer));
if (bytesRead < 0) { if (bytesRead < 0) {
fprintf(stderr, "%s: unable to read RTC settings file\n", program); fprintf(stderr, "Unable to read RTC settings file\n");
return; return;
} }
bool isGMT = strncmp(buffer, "local", 5) != 0; bool isGMT = strncmp(buffer, "local", 5) != 0;
@@ -48,25 +69,25 @@ setRealTimeClockIsGMT(BPath path)
void void
setTimeZoneOffset(BPath path) InitRealTimeClockJob::_SetTimeZoneOffset(BPath path) const
{ {
path.Append("Time settings"); path.Append("Time settings");
BFile file; BFile file;
status_t status = file.SetTo(path.Path(), B_READ_ONLY); status_t status = file.SetTo(path.Path(), B_READ_ONLY);
if (status != B_OK) { 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; return;
} }
BMessage settings; BMessage settings;
status = settings.Unflatten(&file); status = settings.Unflatten(&file);
if (status != B_OK) { 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; return;
} }
BString timeZoneID; BString timeZoneID;
if (settings.FindString("timezone", &timeZoneID) != B_OK) { if (settings.FindString("timezone", &timeZoneID) != B_OK) {
fprintf(stderr, "%s: no timezone found\n", program); fprintf(stderr, "No timezone found\n");
return; return;
} }
int32 timeZoneOffset = BTimeZone(timeZoneID.String()).OffsetFromGMT(); 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", printf("timezone is %s, offset is %" B_PRId32 " seconds from GMT.\n",
timeZoneID.String(), timeZoneOffset); 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 ; SubDir HAIKU_TOP src servers launch ;
UsePrivateHeaders app shared ; UsePrivateHeaders app package shared storage support ;
UsePrivateSystemHeaders ; UsePrivateSystemHeaders ;
Server launch_daemon Server launch_daemon
: :
LaunchDaemon.cpp LaunchDaemon.cpp
# init jobs
AbstractEmptyDirectoryJob.cpp
InitRealTimeClockJob.cpp
InitSharedMemoryDirectoryJob.cpp
InitTemporaryDirectoryJob.cpp
: :
be libshared.a [ TargetLibstdc++ ] be libshared.a [ TargetLibstdc++ ]
: :
+51 -12
View File
@@ -13,6 +13,7 @@
#include <Directory.h> #include <Directory.h>
#include <driver_settings.h> #include <driver_settings.h>
#include <Entry.h> #include <Entry.h>
#include <File.h>
#include <ObjectList.h> #include <ObjectList.h>
#include <Path.h> #include <Path.h>
#include <PathFinder.h> #include <PathFinder.h>
@@ -20,11 +21,18 @@
#include <AppMisc.h> #include <AppMisc.h>
#include <DriverSettingsMessageAdapter.h> #include <DriverSettingsMessageAdapter.h>
#include <JobQueue.h>
#include <LaunchDaemonDefs.h> #include <LaunchDaemonDefs.h>
#include <syscalls.h> #include <syscalls.h>
#include "InitRealTimeClockJob.h"
#include "InitSharedMemoryDirectoryJob.h"
#include "InitTemporaryDirectoryJob.h"
using namespace BPrivate; using namespace BPrivate;
using namespace BSupportKit;
using BSupportKit::BPrivate::JobQueue;
static const char* kLaunchDirectory = "launch"; static const char* kLaunchDirectory = "launch";
@@ -127,11 +135,16 @@ private:
void _InitJobs(); void _InitJobs();
void _LaunchJobs(); void _LaunchJobs();
void _RetrieveKernelOptions();
void _SetupEnvironment(); void _SetupEnvironment();
void _InitSystem();
bool _IsSafeMode() const; bool _IsSafeMode() const;
private: private:
JobMap fJobs; JobMap fJobs;
JobQueue fJobQueue;
bool fSafeMode;
}; };
@@ -410,7 +423,9 @@ LaunchDaemon::~LaunchDaemon()
void void
LaunchDaemon::ReadyToRun() LaunchDaemon::ReadyToRun()
{ {
_RetrieveKernelOptions();
_SetupEnvironment(); _SetupEnvironment();
_InitSystem();
BStringList paths; BStringList paths;
BPathFinder::FindPaths(B_FIND_PATH_DATA_DIRECTORY, kLaunchDirectory, BPathFinder::FindPaths(B_FIND_PATH_DATA_DIRECTORY, kLaunchDirectory,
@@ -609,29 +624,52 @@ LaunchDaemon::_LaunchJobs()
void void
LaunchDaemon::_SetupEnvironment() LaunchDaemon::_RetrieveKernelOptions()
{
// Determine safemode kernel option
BString safemode = "SAFEMODE=";
safemode << _IsSafeMode() ? "yes" : "no";
}
bool
LaunchDaemon::_IsSafeMode() const
{ {
char buffer[32]; char buffer[32];
size_t size = sizeof(buffer); size_t size = sizeof(buffer);
status_t status = _kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, buffer, status_t status = _kern_get_safemode_option(B_SAFEMODE_SAFE_MODE, buffer,
&size); &size);
if (status == B_OK) { if (status == B_OK) {
return !strncasecmp(buffer, "true", size) fSafeMode = !strncasecmp(buffer, "true", size)
|| !strncasecmp(buffer, "yes", size) || !strncasecmp(buffer, "yes", size)
|| !strncasecmp(buffer, "on", size) || !strncasecmp(buffer, "on", size)
|| !strncasecmp(buffer, "enabled", 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) if (fd != STDOUT_FILENO)
dup2(fd, STDOUT_FILENO); dup2(fd, STDOUT_FILENO);
puts("launch_daemon is alive and kicking."); puts("launch_daemon is alive and kicking.");
fflush(stdout);
status_t status; status_t status;
LaunchDaemon* daemon = new LaunchDaemon(status); LaunchDaemon* daemon = new LaunchDaemon(status);