Compare commits

..
8 Commits
Author SHA1 Message Date
Joachim Nilsson b373e199a8 Install fixes, $prefix supported better, strip binaries and .so files
- Makefile fixes for installation, paths encoded wrong
- Strip binaries + .so files, support for $(CROSS) toolchain strip
- Default install is now to /sbin/finit and /usr/
- Use the 'plugindir' environemnt variable instead of 'PLUGIN_DIR'

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-28 16:46:17 +02:00
Joachim Nilsson 149ed0e81c Minor header comment updates and bump version to 1.3
Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-28 15:59:15 +02:00
Joachim Nilsson e32ca1fc83 Keep separate install/uninstall targets for exec, data and dev files.
Break up install/uninstall targets in top Makefile into separate
install-exec, install-data, and install-dev for packagers and
distributions wishing to call Makefile with different DESTDIR's
depending on building -bin or -devel package.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-28 14:23:29 +02:00
Joachim Nilsson 9aa90763b0 Support for installing plugin headers to system include/finit/ directory.
Minor cleanup of Makefile and added support for installing necessary
header files, for developing external plugins, to system include path.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 23:25:41 +02:00
Joachim Nilsson 06759d3544 Streamline plugin include files plugin.h, svc.h, and helpers.h
Move utility macros from finit.h to helpers.h and continue refactoring
and streamlining of public plugin API.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 22:10:07 +02:00
Joachim Nilsson ff73dab447 Slight cleanup of public API in helpers.c
Function renames:
  - set_procname() --> procname_set()
  - kill_procname() --> procname_kill()
  - get_pidname() --> pid_get_name()

Also added three new helper functions, for external plugins:
  - pid_alive()
  - pidfile_poll()
  - pidfile_read()

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 20:56:46 +02:00
Joachim Nilsson 0d70fa4cf0 Let plugins hook into service startup to notify 3rd party daemon.
This commit adds support for calling plugin hooks when all services
have been started properly. Useful for, e.g., a 3rd party service
monitor to trigger further events on.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 15:25:10 +02:00
Joachim Nilsson 103bf33b3c Remove finit.h from includes in svc.h, not needed.
Also, when 3rd party sources include svc.h they would get finit
internals included. Not good.

Signed-off-by: Joachim Nilsson <troglobit@gmail.com>
2012-09-27 13:14:00 +02:00
16 changed files with 405 additions and 233 deletions
+16
View File
@@ -1,3 +1,19 @@
1.3 (20120928)
- Cleanup public plugin API a bit and add new pid/pidfile funcs
- Add plugin hook to end of service startup
- Remove finit.h from svc.h, plugins should not need this.
- Move utility macros etc. to helpers.h
- Make finit.h daemon internal, only
- Move defines of FIFO, conf and rcS.d to Makefile => correct paths
- Add support for installing required headers in system include dir
- Better support for distributions and packagers with install-exec,
install-data, and install-dev targets in Makefile. Useful if you
want to call targets with different $DESTDIR!
- Makefile fixes for installation, paths encoded wrong
- Strip binaries + .so files, support for $(CROSS) toolchain strip
- Default install is now to /sbin/finit and /usr/
- Note change in $PLUGIN_DIR environemnt variable to $plugindir
1.2 (20120927)
- Fix installation paths encoded in finit binary
- Update README with section on building and enviroment variables
+72 -28
View File
@@ -1,4 +1,4 @@
# finit - The Improved fast init
# Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins
#
# Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
# Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -21,40 +21,51 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
.PHONY: all romfs clean
.PHONY: all install clean distclean dist \
install-exec install-data install-dev \
uninstall-exec uninstall-data uninstall-dev
# Top directory for building complete system, fall back to this directory
ROOTDIR ?= $(shell pwd)
# Installation paths, always prepended with DESTDIR if set
prefix ?= /usr/local
sysconfdir ?= /etc
datadir = $(prefix)/share/doc/finit
mandir = $(prefix)/share/man/man8
# Plugin directory, fall back to this directory if unset in environment
PLUGIN_DIR ?= $(prefix)/lib/finit/plugins
#VERSION ?= $(shell git tag -l | tail -1)
VERSION ?= 1.2
VERSION ?= 1.3
EXEC = finit
PKG = $(EXEC)-$(VERSION)
ARCHIVE = $(PKG).tar.xz
HEADERS = plugin.h svc.h helpers.h
DISTFILES = LICENSE README ChangeLog finit.conf services
OBJS = finit.o conf.o helpers.o sig.o svc.o plugin.o
OBJS += strlcpy.o
SRCS = $(OBJS:.o=.c)
DEPS = $(addprefix .,$(SRCS:.c=.d))
# Installation paths, always prepended with DESTDIR if set
prefix ?= /usr
sysconfdir ?= /etc
sbindir ?= /sbin
plugindir ?= /lib/finit/plugins
incdir = $(prefix)/include/finit
datadir = $(prefix)/share/doc/finit
mandir = $(prefix)/share/man/man8
# The initctl FIFO, should probably be in /run, not /dev
FINIT_FIFO ?= /dev/initctl
FINIT_CONF ?= $(sysconfdir)/finit.conf
FINIT_RCSD ?= $(sysconfdir)/finit.d
CFLAGS += -W -Wall -Werror -Os
# Disable annoying gcc warning for "warn_unused_result", see GIT 37af997
CPPFLAGS += -U_FORTIFY_SOURCE
CPPFLAGS += -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_GNU_SOURCE
CPPFLAGS += -DVERSION=\"$(VERSION)\" -DWHOAMI=\"`whoami`@`hostname`\"
CPPFLAGS += -DPLUGIN_PATH=\"$(PLUGIN_DIR)\"
CPPFLAGS += -DFINIT_FIFO=\"$(FINIT_FIFO)\" -DFINIT_CONF=\"$(FINIT_CONF)\"
CPPFLAGS += -DFINIT_RCSD=\"$(FINIT_RCSD)\" -DPLUGIN_PATH=\"$(plugindir)\"
LDFLAGS += -rdynamic
LDLIBS += -ldl
include common.mk
export PLUGIN_DIR ROOTDIR CPPFLAGS
export plugindir ROOTDIR CPPFLAGS
all: Makefile $(EXEC)
$(MAKE) -C plugins $@
@@ -63,24 +74,57 @@ $(OBJS): Makefile
$(EXEC): $(OBJS)
# @ln -sf /sbin/finit /sbin/init
install: all
@install -d $(DESTDIR)$(prefix)/sbin
@install -d $(DESTDIR)$(sysconfdir)
@install -d $(DESTDIR)$(datadir)
@install -d $(DESTDIR)$(mandir)
install-exec: all
@$(INSTALL) -d $(DESTDIR)$(sysconfdir)
@$(INSTALL) -d $(DESTDIR)$(sbindir)
@for file in $(EXEC); do \
printf " INSTALL $(DESTDIR)$(prefix)/sbin/$$file\n"; \
install -m 0755 $$file $(DESTDIR)$(prefix)/sbin/$$file; \
printf " INSTALL $(DESTDIR)$(sbindir)/$$file\n"; \
$(STRIPINST) $$file $(DESTDIR)$(sbindir)/$$file; \
done
$(MAKE) -C plugins $@
$(MAKE) -C plugins install
uninstall:
-@for file in $(EXEC); do \
printf " REMOVE $(DESTDIR)$(prefix)/sbin/$$file\n"; \
rm $(DESTDIR)$(prefix)/sbin/$$file 2>/dev/null; \
install-data:
@$(INSTALL) -d $(DESTDIR)$(datadir)
@$(INSTALL) -d $(DESTDIR)$(mandir)
@for file in $(DISTFILES); do \
printf " INSTALL $(DESTDIR)$(datadir)/$$file\n"; \
$(INSTALL) -m 0644 $$file $(DESTDIR)$(datadir)/$$file; \
done
$(MAKE) -C plugins $@
install-dev:
@$(INSTALL) -d $(DESTDIR)$(incdir)
@for file in $(HEADERS); do \
printf " INSTALL $(DESTDIR)$(incdir)/$$file\n"; \
$(INSTALL) -m 0644 $$file $(DESTDIR)$(incdir)/$$file; \
done
install: install-exec install-data install-dev
uninstall-exec:
-@for file in $(EXEC); do \
printf " REMOVE $(DESTDIR)$(sbindir)/$$file\n"; \
rm $(DESTDIR)$(sbindir)/$$file 2>/dev/null; \
done
-@rmdir $(DESTDIR)$(sbindir) 2>/dev/null
-@rmdir $(DESTDIR)$(sysconfdir) 2>/dev/null
$(MAKE) -C plugins uninstall
uninstall-data:
@for file in $(DISTFILES); do \
printf " REMOVE $(DESTDIR)$(datadir)/$$file\n"; \
rm $(DESTDIR)$(datadir)/$$file 2>/dev/null; \
done
-@rmdir $(DESTDIR)$(mandir)
-@rmdir $(DESTDIR)$(datadir)
uninstall-dev:
-@for file in $(HEADERS); do \
printf " REMOVE $(DESTDIR)$(incdir)/$$file\n"; \
rm $(DESTDIR)$(incdir)/$$file 2>/dev/null; \
done
-@rmdir $(DESTDIR)$(incdir)
uninstall: uninstall-exec uninstall-data uninstall-dev
clean:
-@$(RM) $(OBJS) $(DEPS) $(EXEC)
+1
View File
@@ -3,3 +3,4 @@
* Look at how to support a standard SysV init runlevel mechanism
* Arguments to finit, like to SysV init "init q" to reload finit.conf at runtime, etc.
* Implement initctl stop|start|reload <SVC> and service <SVC> stop|start|reload on top
* Write man pages for finit and finit.conf, steal from pimd man pages...
+3 -1
View File
@@ -1,7 +1,9 @@
# Some junk files we always want to be removed when doing a make clean.
JUNK = *~ *.bak *.aux *.dvi *.idx *.ind *.log *.ps *.map .*.d DEADJOE semantic.cache *.gdb *.elf core core.*
MAKE := @$(MAKE)
MAKEFLAGS = --no-print-directory
MAKEFLAGS = --no-print-directory --silent
INSTALL := install -b
STRIPINST := $(INSTALL) -s --strip-program=$(CROSS)strip -m 0755
# Smart autodependecy generation via GCC -M.
.%.d: %.c
+1 -1
View File
@@ -1,4 +1,4 @@
/* Improved fast init
/* Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
View File
+1 -44
View File
@@ -1,4 +1,4 @@
/* Improved fast init
/* Finit - Extremely fast /sbin/init replacement w/ I/O, hook & service plugins
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -33,21 +33,6 @@
#include <sys/stat.h>
#include <unistd.h>
#include <syslog.h>
#define DO_LOG(level, fmt, args...) \
{ \
openlog("finit", LOG_CONS | LOG_PID, LOG_DAEMON); \
syslog(LOG_DEBUG, fmt, ##args); \
closelog(); \
}
#define DEBUG(fmt, args...) DO_LOG(LOG_DEBUG, fmt, ##args)
#define ERROR(fmt, args...) DO_LOG(LOG_CRIT, fmt, ##args)
#define FINIT_FIFO "/dev/initctl"
#define FINIT_CONF "/etc/finit.conf"
#define FINIT_RCSD "/etc/finit.d"
/* Distribution configuration */
#if defined EMBEDDED_SYSTEM
@@ -79,42 +64,14 @@
#define USERNAME_SIZE 16
#define HOSTNAME_SIZE 32
#ifndef touch
# define touch(x) mknod((x), S_IFREG|0644, 0)
#endif
#ifndef chardev
# define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
#endif
#ifndef blkdev
# define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min)))
#endif
#ifndef fexist
# define fexist(x) (access(x, F_OK) != -1)
#endif
#ifndef UNUSED
#define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#endif
#define echo(fmt, args...) do { if (1) { fprintf(stderr, fmt "\n", ##args); } } while (0)
#define _d(fmt, args...) do { if (debug) { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } } while (0)
#define _e(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } while (0)
#define _pe(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt ". Error %d: %s\n", __func__, ##args, errno, strerror(errno)); } while (0)
extern int debug;
extern int verbose;
extern char *sdown;
extern char *network;
extern char *hostname;
extern char *username;
/* strlcpy.c */
size_t strlcpy(char *dst, const char *src, size_t siz);
/* conf.c */
void parse_finit_conf(char *file);
#endif /* FINIT_H_ */
/**
+232 -126
View File
@@ -1,4 +1,4 @@
/* Misc. utility functions and C-library extensions to simplify finit system setup.
/* Misc. utility functions and C-library extensions for finit and its plugins
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -56,23 +56,30 @@
* Helpers to replace system() calls
*/
int makepath(char *p)
int makepath(char *path)
{
char *x, path[PATH_MAX];
char buf[PATH_MAX];
char *x = buf;
int ret;
x = path;
if (!path) {
errno = EINVAL;
return -1;
}
do {
do { *x++ = *p++; } while (*p && *p != '/');
do {
*x++ = *path++;
} while (*path && *path != '/');
*x = 0;
ret = mkdir(path, 0777);
} while (*p && (*p != '/' || *(p + 1))); /* ignore trailing slash */
ret = mkdir(buf, 0777);
} while (*path && (*path != '/' || *(path + 1))); /* ignore trailing slash */
return ret;
}
void ifconfig(char *name, char *inet, char *mask, int up)
void ifconfig(char *ifname, char *addr, char *mask, int up)
{
struct ifreq ifr;
struct sockaddr_in *a = (struct sockaddr_in *)&ifr.ifr_addr;
@@ -82,11 +89,11 @@ void ifconfig(char *name, char *inet, char *mask, int up)
return;
memset(&ifr, 0, sizeof (ifr));
strlcpy(ifr.ifr_name, name, IFNAMSIZ);
strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_addr.sa_family = AF_INET;
if (up) {
inet_aton(inet, &a->sin_addr);
inet_aton(addr, &a->sin_addr);
ioctl(sock, SIOCSIFADDR, &ifr);
inet_aton(mask, &a->sin_addr);
ioctl(sock, SIOCSIFNETMASK, &ifr);
@@ -129,6 +136,213 @@ void copyfile(char *src, char *dst, int size)
}
}
/**
* pidfile_read - Reads a PID value from a pidfile.
* @pidfile: File containing PID, usually in /var/run/<PROC>.pid
*
* This function takes a @pidfile and returns the PID found therein.
*
* Returns:
* On invalid @pidfile -1 and @errno set to %EINVAL, when @pidfile does not exist -1
* and errno set to %ENOENT. When the pidfile is empty or when its contents cannot
* be translated this function returns zero (0), on success this function returns
* a PID value greater than one. PID 1 is reserved for the system init process.
*/
pid_t pidfile_read(const char *pidfile)
{
pid_t pid = 0;
char buf[16];
FILE *fp;
if (!pidfile) {
errno = EINVAL;
return -1;
}
if (!fexist(pidfile))
return -1;
fp = fopen(pidfile, "r");
if (!fp)
return -1;
if (fgets(buf, sizeof(buf), fp)) {
errno = 0;
pid = strtoul(buf, NULL, 0);
if (errno)
pid = 0; /* Failed conversion. */
}
fclose(fp);
return pid;
}
/**
* pidfile_poll - Poll for the existence of a pidfile and return PID
* @cmd: Process name, or command, called to expect a pidfile
* @path: Path to pidfile to poll for
*
* This function polls for the pidfile at @path for at most 5 seconds
* before timing out. If the file is created within that time span the
* file is read and its PID contents returned.
*
* Returns:
* The PID read from @path, or zero on timeout.
*/
pid_t pidfile_poll(char *cmd, const char *path)
{
pid_t pid = 0;
int tries = 0;
/* Timeout = 100 * 50ms = 5s */
while (!fexist(path) && tries++ < 100) {
/* Wait 50ms between retries */
usleep(50000);
}
if (!fexist(path)) {
_e("Timeout! No PID found for %s, pidfile %s does not exist?", cmd, path);
pid = 0;
} else {
pid = pidfile_read(path);
}
return pid;
}
/**
* pid_alive - Check if a given process ID is running
* @pid: Process ID to check for.
*
* Returns:
* %TRUE(1) if pid is alive (/proc/pid exists), otherwise %FALSE(0)
*/
int pid_alive(pid_t pid)
{
char name[24]; /* Enough for max pid_t */
snprintf(name, sizeof(name), "/proc/%d", pid);
return fexist(name);
}
/**
* pid_get_name - Find name of a process
* @pid: PID of process to find.
* @name: Pointer to buffer where to return process name, may be %NULL
* @len: Length in bytes of @name buffer.
*
* If @name is %NULL, or @len is zero the function will return
* a static string. This may be useful to one-off calls.
*
* Returns:
* %NULL on error, otherwise a va
*/
char *pid_get_name(pid_t pid, char *name, size_t len)
{
int ret = 1;
FILE *fp;
char path[32];
static char line[64];
if (!name || len == 0)
name = line;
snprintf(path, sizeof(path), "/proc/%d/status", pid);
if ((fp = fopen(path, "r")) != NULL) {
if (fgets(line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
chomp(pname);
strlcpy(name, pname, len);
ret = 0; /* Found it! */
}
fclose(fp);
}
if (ret)
return NULL;
return name;
}
/**
* procname_set - Change process name, as seen in process listnings
* @name: New name of process
* @args: The process' argv[] vector.
*/
void procname_set(const char *name, char *args[])
{
size_t len = strlen(args[0]) + 1; /* Include terminating '\0' */
prctl(PR_SET_NAME, name, 0, 0, 0);
memset(args[0], 0, len);
strlcpy(args[0], name, len);
}
/**
* procname_kill - Send a signal to a process group by name.
* @name: Name of process to send signal to.
* @signo: Signal to send.
*
* Send a signal to a running process (group). This function searches
* for a given process @name and sends a signal, @signo, to each
* process ID matching that @name.
*
* Returns:
* Number of signals sent, i.e. number of processes who have received the signal.
*/
int procname_kill (const char *name, int signo)
{
int result = 0;
char path[32], line[64];
FILE *fp;
DIR *dir;
struct dirent *entry;
dir = opendir("/proc");
if (!dir || !name) {
errno = EINVAL;
return 0;
}
while ((entry = readdir (dir)) != NULL) {
/* Skip non-process entries in /proc */
if (!isdigit (*entry->d_name))
continue;
snprintf (path, sizeof(path), "/proc/%s/status", entry->d_name);
/* Skip non-readable files (protected?) */
if ((fp = fopen (path, "r")) == NULL)
continue;
if (fgets (line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
if (strncmp(pname, name, strlen(pname) - 1) == 0) {
int error = errno;
if (kill(atoi(entry->d_name), signo)) {
ERROR("Failed signalling(%d) %s: %s!", signo, name, strerror(error));
} else {
result++; /* Track number of processes we deliver the signal to. */
}
}
}
fclose(fp);
}
closedir(dir);
return result;
}
static int print_uptime(void)
{
#if defined(CONFIG_PRINTK_TIME)
@@ -347,7 +561,7 @@ pid_t run_getty(char *cmd, char *argv[])
dup2(0, STDOUT_FILENO);
dup2(0, STDERR_FILENO);
set_procname(argv, "console");
procname_set("console", argv);
while (!fexist(SYNC_SHUTDOWN)) {
static const char msg[] = "\nPlease press Enter to activate this console. ";
@@ -446,21 +660,21 @@ int run_parts(char *dir, ...)
return 0;
}
int getuser(char *s)
int getuser(char *username)
{
struct passwd *usr;
if (!s || (usr = getpwnam(s)) == NULL)
if (!username || (usr = getpwnam(username)) == NULL)
return -1;
return usr->pw_uid;
}
int getgroup(char *s)
int getgroup(char *group)
{
struct group *grp;
if ((grp = getgrnam(s)) == NULL)
if ((grp = getgrnam(group)) == NULL)
return -1;
return grp->gr_gid;
@@ -478,122 +692,14 @@ void cls(void)
fprintf (stderr, "%s", cls);
}
void chomp(char *s)
void chomp(char *str)
{
char *x;
if ((x = strchr((s), 0x0a)) != NULL)
if ((x = strchr((str), 0x0a)) != NULL)
*x = 0;
}
void set_procname(char *args[], char *name)
{
size_t len = strlen(args[0]) + 1; /* Include terminating '\0' */
prctl(PR_SET_NAME, name, 0, 0, 0);
memset(args[0], 0, len);
strlcpy(args[0], name, len);
}
/**
* get_pidname - Find name of a process
* @pid: PID of process to find.
* @name: Pointer to buffer where to return process name, may be %NULL
* @len: Length in bytes of @name buffer.
*
* If @name is %NULL, or @len is zero the function will return
* a static string. This may be useful to one-off calls.
*
* Returns:
* %NULL on error, otherwise a va
*/
char *get_pidname(pid_t pid, char *name, size_t len)
{
int ret = 1;
FILE *fp;
char path[32];
static char line[64];
if (!name || len == 0)
name = line;
snprintf(path, sizeof(path), "/proc/%d/status", pid);
if ((fp = fopen(path, "r")) != NULL) {
if (fgets(line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
chomp(pname);
strlcpy(name, pname, len);
ret = 0; /* Found it! */
}
fclose(fp);
}
if (ret)
return NULL;
return name;
}
/**
* kill_procname - Send a signal to a process group by name.
* @name: Name of process to send signal to.
* @signo: Signal to send.
*
* Send a signal to a running process (group). This function searches
* for a given process @name and sends a signal, @signo, to each
* process ID matching that @name.
*
* Returns:
* Number of signals sent, i.e. number of processes who have received the signal.
*/
int kill_procname (const char *name, int signo)
{
int result = 0;
char path[32], line[64];
FILE *fp;
DIR *dir;
struct dirent *entry;
dir = opendir("/proc");
if (!dir || !name) {
errno = EINVAL;
return 0;
}
while ((entry = readdir (dir)) != NULL) {
/* Skip non-process entries in /proc */
if (!isdigit (*entry->d_name))
continue;
snprintf (path, sizeof(path), "/proc/%s/status", entry->d_name);
/* Skip non-readable files (protected?) */
if ((fp = fopen (path, "r")) == NULL)
continue;
if (fgets (line, sizeof (line), fp)) {
char *pname = line + 6; /* Skip first part of line --> "Name:\t" */
if (strncmp(pname, name, strlen(pname) - 1) == 0) {
int error = errno;
if (kill(atoi(entry->d_name), signo)) {
ERROR("Failed signalling(%d) %s: %s!", signo, name, strerror(error));
} else {
result++; /* Track number of processes we deliver the signal to. */
}
}
}
fclose(fp);
}
closedir(dir);
return result;
}
void set_hostname(char *hostname)
{
FILE *fp;
+58 -10
View File
@@ -1,4 +1,4 @@
/* Misc. utility functions and C-library extensions to simplify finit system setup.
/* Misc. utility functions and C-library extensions for finit and its plugins
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -25,19 +25,64 @@
#ifndef FINIT_HELPERS_H_
#define FINIT_HELPERS_H_
int makepath (char *);
void ifconfig (char *, char *, char *, int);
void copyfile (char *, char *, int);
#include <stdio.h>
#include <syslog.h>
#define DO_LOG(level, fmt, args...) \
{ \
openlog("finit", LOG_CONS | LOG_PID, LOG_DAEMON); \
syslog(LOG_DEBUG, fmt, ##args); \
closelog(); \
}
#define DEBUG(fmt, args...) DO_LOG(LOG_DEBUG, fmt, ##args)
#define ERROR(fmt, args...) DO_LOG(LOG_CRIT, fmt, ##args)
#ifndef touch
# define touch(x) mknod((x), S_IFREG|0644, 0)
#endif
#ifndef chardev
# define chardev(x,m,maj,min) mknod((x), S_IFCHR|(m), makedev((maj),(min)))
#endif
#ifndef blkdev
# define blkdev(x,m,maj,min) mknod((x), S_IFBLK|(m), makedev((maj),(min)))
#endif
#ifndef fexist
# define fexist(x) (access(x, F_OK) != -1)
#endif
#ifndef UNUSED
#define UNUSED(x) UNUSED_ ## x __attribute__ ((unused))
#endif
#define echo(fmt, args...) do { if (1) { fprintf(stderr, fmt "\n", ##args); } } while (0)
#define _d(fmt, args...) do { if (debug) { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } } while (0)
#define _e(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt "\n", __func__, ##args); } while (0)
#define _pe(fmt, args...) do { fprintf(stderr, "finit:%s() - " fmt ". Error %d: %s\n", __func__, ##args, errno, strerror(errno)); } while (0)
extern int debug;
extern int verbose;
int makepath (char *path);
void ifconfig (char *ifname, char *addr, char *mask, int up);
void copyfile (char *src, char *dst, int size);
pid_t pidfile_read (const char *pidfile);
pid_t pidfile_poll (char *cmd, const char *path);
int pid_alive (pid_t pid);
char *pid_get_name (pid_t pid, char *name, size_t len);
void procname_set (const char *name, char *args[]);
int procname_kill (const char *name, int signo);
void print_descr (char *action, char *descr);
int print_result (int fail);
int start_process (char *cmd, char *args[], int console);
void cls (void);
void chomp (char *);
int getuser (char *);
int getgroup (char *);
void set_procname (char *args[], char *name);
char *get_pidname (pid_t pid, char *name, size_t len);
int kill_procname (const char *name, int signo);
void chomp (char *str);
int getuser (char *username);
int getgroup (char *group);
void set_hostname (char *hostname);
int run (char *cmd);
@@ -45,6 +90,9 @@ int run_interactive (char *cmd, char *fmt, ...);
pid_t run_getty (char *cmd, char *argv[]);
int run_parts (char *dir, ...);
/* strlcpy.c */
size_t strlcpy(char *dst, const char *src, size_t siz);
#endif /* FINIT_HELPERS_H_ */
/**
+1
View File
@@ -42,6 +42,7 @@ typedef enum {
HOOK_BASEFS_UP = 0,
HOOK_NETWORK_UP,
HOOK_SYSTEM_UP,
HOOK_SVC_UP,
HOOK_SHUTDOWN,
HOOK_MAX_NUM
} hook_point_t;
+6 -6
View File
@@ -17,18 +17,18 @@ distclean: clean
-@$(RM) $(JUNK) $(DEPS)
install: all
@install -d $(DESTDIR)$(prefix)$(PLUGIN_DIR)
@install -d $(DESTDIR)$(plugindir)
@for plugin in $(PLUGINS); do \
echo " INSTALL $(DESTDIR)$(prefix)$(PLUGIN_DIR)/$$plugin"; \
cp $$plugin $(DESTDIR)$(prefix)$(PLUGIN_DIR); \
echo " INSTALL $(DESTDIR)$(plugindir)/$$plugin"; \
$(STRIPINST) $$plugin $(DESTDIR)$(plugindir)/$$plugin; \
done
uninstall:
-@for plugin in $(PLUGINS); do \
echo " RM $(PLUGIN_DIR)/$$plugin"; \
rm $(DESTDIR)$(prefix)$(PLUGIN_DIR)/$$plugin 2>/dev/null; \
echo " RM $(DESTDIR)$(plugindir)/$$plugin"; \
rm $(DESTDIR)$(plugindir)/$$plugin 2>/dev/null; \
done
-@rmdir $(DESTDIR)$(prefix)$(PLUGIN_DIR) 2>/dev/null
-@rmdir $(DESTDIR)$(plugindir) 2>/dev/null
ifneq ($(MAKECMDGOALS),clean)
-include $(DEPS)
+2 -4
View File
@@ -23,10 +23,11 @@
*/
#include <errno.h>
#include <fcntl.h> /* O_RDONLY et al */
#include <signal.h>
#include <string.h>
#include "finit.h"
#include "helpers.h"
#include "plugin.h"
#define INIT_MAGIC 0x03091969
@@ -40,7 +41,6 @@ struct init_request {
char data[368];
};
#ifdef LISTEN_INITCTL
/* Standard reboot/shutdown utilities talk to init using /dev/initctl.
* We should check if the fifo was recreated and reopen it.
*/
@@ -109,8 +109,6 @@ PLUGIN_EXIT(plugin_exit)
plugin_unregister(&plugin);
}
#endif /* LISTEN_INITCTL */
/**
* Local Variables:
* version-control: t
View File
+3 -3
View File
@@ -87,7 +87,7 @@ void do_shutdown (int sig)
static void shutdown_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Rebooting on signal %d from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
do_shutdown(sig);
}
@@ -106,14 +106,14 @@ static void chld_handler(int UNUSED(sig), siginfo_t *UNUSED(info), void *UNUSED(
static void sigstop_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Received SIGSTOP(%d) from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
touch(SYNC_STOPPED);
stopped ++;
}
static void sigcont_handler(int sig, siginfo_t *info, void *UNUSED(ctx))
{
_d("Received SIGCONT(%d) from %s (PID %d)",
sig, get_pidname(info->si_pid, NULL, 0), info->si_pid);
sig, pid_get_name(info->si_pid, NULL, 0), info->si_pid);
stopped = 0;
remove(SYNC_STOPPED);
}
+7 -5
View File
@@ -1,4 +1,4 @@
/* Generic API for managing svc_t structures
/* Finit service monitor and heneric API for managing svc_t structures
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -46,7 +46,7 @@ static void __connect_shm(void)
if (!services) {
/* This should never happen, but if it does we're probably
* knee-deep in more serious problems already... */
_e("Failed setting up shared memory for service monitor.\n");
_e("Failed allocating shared memory, error %d: %s", errno, strerror (errno));
abort();
}
}
@@ -270,7 +270,7 @@ void svc_monitor(void)
/* Cleanup any lingering or semi-restarting tasks before respawning */
_d("Sending SIGTERM to service group %s", name);
kill_procname(name, SIGTERM);
procname_kill(name, SIGTERM);
/* Restarting lost service. */
if (svc_enabled(svc, 0))
@@ -280,6 +280,7 @@ void svc_monitor(void)
}
}
/* Remember: svc_enabled() must be called before calling svc_start() */
int svc_start(svc_t *svc)
{
int respawn = svc->pid != 0;
@@ -362,7 +363,7 @@ int svc_stop(svc_t *svc)
}
print_descr("Stopping ", svc->descr);
_d("Sending SIGTERM to pid:%d name:'%s'", svc->pid, get_pidname(svc->pid, NULL, 0));
_d("Sending SIGTERM to pid:%d name:'%s'", svc->pid, pid_get_name(svc->pid, NULL, 0));
res = kill(svc->pid, SIGTERM);
print_result(res);
svc->pid = 0;
@@ -400,7 +401,8 @@ void svc_start_all(void)
svc_reload(svc);
}
/* XXX: Hook point for plugins. */
_d("Running svc up hooks ...");
run_hooks(HOOK_SVC_UP);
}
+2 -5
View File
@@ -1,4 +1,4 @@
/* Generic API for managing svc_t structures
/* Finit service monitor and heneric API for managing svc_t structures
*
* Copyright (c) 2008-2010 Claudio Matsuoka <cmatsuoka@gmail.com>
* Copyright (c) 2008-2012 Joachim Nilsson <troglobit@gmail.com>
@@ -30,7 +30,6 @@
#include <sys/shm.h> /* shmat() */
#include <sys/types.h> /* pid_t */
#include "finit.h"
#include "plugin.h"
typedef enum {
@@ -73,10 +72,8 @@ static inline svc_t *finit_svc_connect(void)
if ((void *)-1 == ptr) {
ptr = shmat (shmget (ID, sizeof(svc_t) * MAX_NUM_SVC, 0600 | IPC_CREAT), NULL, 0);
if ((void *)-1 == ptr) {
_d("Failed allocating shared memory, error %d: %s", errno, strerror (errno));
if ((void *)-1 == ptr)
return NULL;
}
}
return (svc_t *)ptr;