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
|
rpcbind
|
||||||
savecore
|
savecore
|
||||||
swap-blk
|
swap-blk
|
||||||
|
swclock
|
||||||
syslogd
|
syslogd
|
||||||
termencoding
|
termencoding
|
||||||
ttys
|
ttys
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
DIR= ${INITDIR}
|
DIR= ${INITDIR}
|
||||||
SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in netmount.in \
|
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}
|
BIN= ${OBJS}
|
||||||
|
|
||||||
# Build our old net foo or not
|
# Build our old net foo or not
|
||||||
|
@ -22,7 +22,7 @@ start()
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
local save=
|
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"
|
[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
|
||||||
done
|
done
|
||||||
if [ -n "$save" ]; then
|
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 <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#define RC_LEVEL_BOOT "boot"
|
#define RC_LEVEL_BOOT "boot"
|
||||||
|
2
src/rc/.gitignore
vendored
2
src/rc/.gitignore
vendored
@ -38,6 +38,7 @@ service_crashed
|
|||||||
checkpath
|
checkpath
|
||||||
fstabinfo
|
fstabinfo
|
||||||
mountinfo
|
mountinfo
|
||||||
|
swclock
|
||||||
rc-depend
|
rc-depend
|
||||||
service_get_value
|
service_get_value
|
||||||
service_set_value
|
service_set_value
|
||||||
@ -59,6 +60,7 @@ checkpath.o
|
|||||||
fstabinfo.o
|
fstabinfo.o
|
||||||
mountinfo.o
|
mountinfo.o
|
||||||
start-stop-daemon.o
|
start-stop-daemon.o
|
||||||
|
swclock.o
|
||||||
rc-applets.o
|
rc-applets.o
|
||||||
rc-depend.o
|
rc-depend.o
|
||||||
rc-logger.o
|
rc-logger.o
|
||||||
|
@ -2,7 +2,7 @@ PROG= rc
|
|||||||
SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
|
SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
|
||||||
rc-applets.c rc-depend.c rc-logger.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 \
|
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
|
CLEANFILES= version.h
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ RC_SBINLINKS= mark_service_starting mark_service_started \
|
|||||||
mark_service_stopping mark_service_stopped \
|
mark_service_stopping mark_service_stopped \
|
||||||
mark_service_inactive mark_service_wasinactive \
|
mark_service_inactive mark_service_wasinactive \
|
||||||
mark_service_hotplugged mark_service_failed \
|
mark_service_hotplugged mark_service_failed \
|
||||||
rc-abort
|
rc-abort swclock
|
||||||
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
|
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
|
||||||
CLEANFILES+= ${ALL_LINKS}
|
CLEANFILES+= ${ALL_LINKS}
|
||||||
|
|
||||||
|
@ -35,6 +35,7 @@ int rc_status(int, char **);
|
|||||||
int rc_update(int, char **);
|
int rc_update(int, char **);
|
||||||
int runscript(int, char **);
|
int runscript(int, char **);
|
||||||
int start_stop_daemon(int, char **);
|
int start_stop_daemon(int, char **);
|
||||||
|
int swclock(int, char **);
|
||||||
|
|
||||||
void run_applets(int, char **);
|
void run_applets(int, char **);
|
||||||
|
|
||||||
|
@ -449,6 +449,8 @@ run_applets(int argc, char **argv)
|
|||||||
exit(start_stop_daemon(argc, argv));
|
exit(start_stop_daemon(argc, argv));
|
||||||
else if (strcmp (applet, "checkpath") == 0)
|
else if (strcmp (applet, "checkpath") == 0)
|
||||||
exit(checkpath(argc, argv));
|
exit(checkpath(argc, argv));
|
||||||
|
else if (strcmp(applet, "swclock") == 0)
|
||||||
|
exit(swclock(argc, argv));
|
||||||
|
|
||||||
/* These could also be applications in their own right */
|
/* These could also be applications in their own right */
|
||||||
if (strcmp(applet, "shell_var") == 0)
|
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…
x
Reference in New Issue
Block a user