Add new utility and init script swclock that sets the system time based on
the mtime of a file. It saves the shutdown time to this file also. This is handy for systems without a working RTC chip. Based on an idea by Michael A. Smith <michael@smith-li.com>. Fixes Gentoo #272073.
This commit is contained in:
parent
aaa0498bf8
commit
a8f6a9b654
11
init.d.misc/.gitignore
vendored
Normal file
11
init.d.misc/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
avahi-dnsconfd
|
||||
avahid
|
||||
dhcpcd
|
||||
dbus
|
||||
hald
|
||||
named
|
||||
ntpd
|
||||
openvpn
|
||||
polkitd
|
||||
sshd
|
||||
wpa_supplicant
|
1
init.d/.gitignore
vendored
1
init.d/.gitignore
vendored
@ -34,6 +34,7 @@ rc-enabled
|
||||
rpcbind
|
||||
savecore
|
||||
swap-blk
|
||||
swclock
|
||||
syslogd
|
||||
termencoding
|
||||
ttys
|
||||
|
@ -1,6 +1,6 @@
|
||||
DIR= ${INITDIR}
|
||||
SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in netmount.in \
|
||||
network.in root.in savecache.in swap.in sysctl.in urandom.in
|
||||
network.in root.in savecache.in swap.in swclock.in sysctl.in urandom.in
|
||||
BIN= ${OBJS}
|
||||
|
||||
# Build our old net foo or not
|
||||
|
@ -22,7 +22,7 @@ start()
|
||||
fi
|
||||
fi
|
||||
local save=
|
||||
for x in deptree depconfig softlevel nettree rc.log; do
|
||||
for x in deptree depconfig shutdowntime softlevel nettree rc.log; do
|
||||
[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
|
||||
done
|
||||
if [ -n "$save" ]; then
|
||||
|
27
init.d/swclock.in
Normal file
27
init.d/swclock.in
Normal file
@ -0,0 +1,27 @@
|
||||
#!@PREFIX@/sbin/runscript
|
||||
# Copyright (c) 2009 Roy Marples <roy@marples.name>
|
||||
# All rights reserved. Released under the 2-clause BSD license.
|
||||
|
||||
description="Sets the local clock to the mtime of a given file."
|
||||
|
||||
depend()
|
||||
{
|
||||
before *
|
||||
keyword -openvz -prefix -uml -vserver -xenu
|
||||
}
|
||||
|
||||
# swclock is an OpenRC built in
|
||||
|
||||
start()
|
||||
{
|
||||
ebegin "Setting the local clock based on last shutdown time"
|
||||
swclock
|
||||
eend $?
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
ebegin "Saving the shutdown time"
|
||||
swclock --save
|
||||
eend $?
|
||||
}
|
@ -35,6 +35,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define RC_LEVEL_BOOT "boot"
|
||||
|
2
src/rc/.gitignore
vendored
2
src/rc/.gitignore
vendored
@ -38,6 +38,7 @@ service_crashed
|
||||
checkpath
|
||||
fstabinfo
|
||||
mountinfo
|
||||
swclock
|
||||
rc-depend
|
||||
service_get_value
|
||||
service_set_value
|
||||
@ -59,6 +60,7 @@ checkpath.o
|
||||
fstabinfo.o
|
||||
mountinfo.o
|
||||
start-stop-daemon.o
|
||||
swclock.o
|
||||
rc-applets.o
|
||||
rc-depend.o
|
||||
rc-logger.o
|
||||
|
@ -2,7 +2,7 @@ PROG= rc
|
||||
SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
|
||||
rc-applets.c rc-depend.c rc-logger.c \
|
||||
rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \
|
||||
runscript.c rc.c
|
||||
runscript.c rc.c swclock.c
|
||||
|
||||
CLEANFILES= version.h
|
||||
|
||||
@ -26,7 +26,7 @@ RC_SBINLINKS= mark_service_starting mark_service_started \
|
||||
mark_service_stopping mark_service_stopped \
|
||||
mark_service_inactive mark_service_wasinactive \
|
||||
mark_service_hotplugged mark_service_failed \
|
||||
rc-abort
|
||||
rc-abort swclock
|
||||
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
|
||||
CLEANFILES+= ${ALL_LINKS}
|
||||
|
||||
|
@ -35,6 +35,7 @@ int rc_status(int, char **);
|
||||
int rc_update(int, char **);
|
||||
int runscript(int, char **);
|
||||
int start_stop_daemon(int, char **);
|
||||
int swclock(int, char **);
|
||||
|
||||
void run_applets(int, char **);
|
||||
|
||||
|
@ -449,6 +449,8 @@ run_applets(int argc, char **argv)
|
||||
exit(start_stop_daemon(argc, argv));
|
||||
else if (strcmp (applet, "checkpath") == 0)
|
||||
exit(checkpath(argc, argv));
|
||||
else if (strcmp(applet, "swclock") == 0)
|
||||
exit(swclock(argc, argv));
|
||||
|
||||
/* These could also be applications in their own right */
|
||||
if (strcmp(applet, "shell_var") == 0)
|
||||
|
110
src/rc/swclock.c
Normal file
110
src/rc/swclock.c
Normal file
@ -0,0 +1,110 @@
|
||||
/*
|
||||
swclock.c
|
||||
Sets the system time from the mtime of the given file.
|
||||
This is useful for systems who do not have a working RTC and rely on ntp.
|
||||
OpenRC relies on the correct system time for a lot of operations so this is needed
|
||||
quite early.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <getopt.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
|
||||
#include "builtins.h"
|
||||
#include "einfo.h"
|
||||
#include "rc-misc.h"
|
||||
|
||||
#define RC_SHUTDOWNTIME RC_SVCDIR "/shutdowntime"
|
||||
|
||||
extern const char *applet;
|
||||
|
||||
#include "_usage.h"
|
||||
#define extraopts "file"
|
||||
#define getoptstring "s" getoptstring_COMMON
|
||||
static const struct option longopts[] = {
|
||||
{ "save", 0, NULL, 's' },
|
||||
longopts_COMMON
|
||||
};
|
||||
static const char * const longopts_help[] = {
|
||||
"saves the time",
|
||||
longopts_help_COMMON
|
||||
};
|
||||
#include "_usage.c"
|
||||
|
||||
int
|
||||
swclock(int argc, char **argv)
|
||||
{
|
||||
int opt, sflag = 0;
|
||||
const char *file = RC_SHUTDOWNTIME;
|
||||
struct stat sb;
|
||||
struct timeval tv;
|
||||
|
||||
while ((opt = getopt_long(argc, argv, getoptstring,
|
||||
longopts, (int *) 0)) != -1)
|
||||
{
|
||||
switch (opt) {
|
||||
case 's':
|
||||
sflag = 1;
|
||||
break;
|
||||
case_RC_COMMON_GETOPT;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind < argc)
|
||||
file = argv[optind++];
|
||||
|
||||
if (sflag) {
|
||||
if (stat(file, &sb) == -1) {
|
||||
opt = open(file, O_WRONLY | O_CREAT, 0644);
|
||||
if (opt == -1)
|
||||
eerrorx("swclock: open: %s", strerror(errno));
|
||||
close(opt);
|
||||
} else
|
||||
if (utime(file, NULL) == -1)
|
||||
eerrorx("swclock: utime: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (stat(file, &sb) == -1)
|
||||
eerrorx("swclock: `%s': %s", file, strerror(errno));
|
||||
|
||||
tv.tv_sec = sb.st_mtime;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (settimeofday(&tv, NULL) == -1)
|
||||
eerrorx("swclock: settimeofday: %s", strerror(errno));
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user