runit/*: get rid of tai[a] time abstraction, it's too bloaty.
text data bss dec hex filename 772537 1058 11092 784687 bf92f busybox.t0/busybox 772459 1058 11060 784577 bf8c1 busybox.t1/busybox 772326 1058 11028 784412 bf81c busybox.t2/busybox 772158 1058 10980 784196 bf744 busybox.t3/busybox 771490 1055 10988 783533 bf4ad busybox.t4/busybox
This commit is contained in:
parent
63db27f9f4
commit
45946f8b51
@ -155,9 +155,8 @@ static const signed char width_bytes[] ALIGN1 = {
|
|||||||
};
|
};
|
||||||
/* Ensure that for each member of 'enum size_spec' there is an
|
/* Ensure that for each member of 'enum size_spec' there is an
|
||||||
initializer in the width_bytes array. */
|
initializer in the width_bytes array. */
|
||||||
struct dummy {
|
struct ERR_width_bytes_has_bad_size {
|
||||||
int assert_width_bytes_matches_size_spec_decl
|
char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1];
|
||||||
[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static smallint flag_dump_strings;
|
static smallint flag_dump_strings;
|
||||||
|
@ -34,8 +34,6 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "runit_lib.h"
|
#include "runit_lib.h"
|
||||||
|
|
||||||
/*** byte_chr.c ***/
|
|
||||||
|
|
||||||
unsigned byte_chr(char *s,unsigned n,int c)
|
unsigned byte_chr(char *s,unsigned n,int c)
|
||||||
{
|
{
|
||||||
char ch;
|
char ch;
|
||||||
@ -52,62 +50,14 @@ unsigned byte_chr(char *s,unsigned n,int c)
|
|||||||
return t - s;
|
return t - s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** coe.c ***/
|
|
||||||
|
|
||||||
int coe(int fd)
|
int coe(int fd)
|
||||||
{
|
{
|
||||||
return fcntl(fd,F_SETFD,FD_CLOEXEC);
|
return fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef UNUSED
|
||||||
/*** fmt_ptime.c ***/
|
|
||||||
|
|
||||||
void fmt_ptime30nul(char *s, struct taia *ta) {
|
|
||||||
struct tm *t;
|
|
||||||
unsigned long u;
|
|
||||||
|
|
||||||
if (ta->sec.x < 4611686018427387914ULL)
|
|
||||||
return; /* impossible? */
|
|
||||||
u = ta->sec.x -4611686018427387914ULL;
|
|
||||||
t = gmtime((time_t*)&u);
|
|
||||||
if (!t)
|
|
||||||
return; /* huh? */
|
|
||||||
//fmt_ulong(s, 1900 + t->tm_year);
|
|
||||||
//s[4] = '-'; fmt_uint0(&s[5], t->tm_mon+1, 2);
|
|
||||||
//s[7] = '-'; fmt_uint0(&s[8], t->tm_mday, 2);
|
|
||||||
//s[10] = '_'; fmt_uint0(&s[11], t->tm_hour, 2);
|
|
||||||
//s[13] = ':'; fmt_uint0(&s[14], t->tm_min, 2);
|
|
||||||
//s[16] = ':'; fmt_uint0(&s[17], t->tm_sec, 2);
|
|
||||||
//s[19] = '.'; fmt_uint0(&s[20], ta->nano, 9);
|
|
||||||
sprintf(s, "%04u-%02u-%02u_%02u:%02u:%02u.%09u",
|
|
||||||
(unsigned)(1900 + t->tm_year),
|
|
||||||
(unsigned)(t->tm_mon+1),
|
|
||||||
(unsigned)(t->tm_mday),
|
|
||||||
(unsigned)(t->tm_hour),
|
|
||||||
(unsigned)(t->tm_min),
|
|
||||||
(unsigned)(t->tm_sec),
|
|
||||||
(unsigned)(ta->nano)
|
|
||||||
);
|
|
||||||
/* 4+1 + 2+1 + 2+1 + 2+1 + 2+1 + 2+1 + 9 = */
|
|
||||||
/* 5 + 3 + 3 + 3 + 3 + 3 + 9 = */
|
|
||||||
/* 20 (up to '.' inclusive) + 9 (not including '\0') */
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned fmt_taia25(char *s, struct taia *t) {
|
|
||||||
static char pack[TAIA_PACK];
|
|
||||||
|
|
||||||
taia_pack(pack, t);
|
|
||||||
*s++ = '@';
|
|
||||||
bin2hex(s, pack, 12);
|
|
||||||
return 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*** tai_pack.c ***/
|
|
||||||
|
|
||||||
static /* as it isn't used anywhere else */
|
static /* as it isn't used anywhere else */
|
||||||
void tai_pack(char *s,const struct tai *t)
|
void tai_pack(char *s, const struct tai *t)
|
||||||
{
|
{
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
|
|
||||||
@ -122,19 +72,6 @@ void tai_pack(char *s,const struct tai *t)
|
|||||||
s[0] = x;
|
s[0] = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef UNUSED
|
|
||||||
/*** tai_sub.c ***/
|
|
||||||
|
|
||||||
void tai_sub(struct tai *t, const struct tai *u, const struct tai *v)
|
|
||||||
{
|
|
||||||
t->x = u->x - v->x;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*** tai_unpack.c ***/
|
|
||||||
|
|
||||||
void tai_unpack(const char *s,struct tai *t)
|
void tai_unpack(const char *s,struct tai *t)
|
||||||
{
|
{
|
||||||
uint64_t x;
|
uint64_t x;
|
||||||
@ -151,8 +88,6 @@ void tai_unpack(const char *s,struct tai *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** taia_add.c ***/
|
|
||||||
|
|
||||||
void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
|
void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
|
||||||
{
|
{
|
||||||
t->sec.x = u->sec.x + v->sec.x;
|
t->sec.x = u->sec.x + v->sec.x;
|
||||||
@ -168,9 +103,6 @@ void taia_add(struct taia *t,const struct taia *u,const struct taia *v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** taia_less.c ***/
|
|
||||||
|
|
||||||
int taia_less(const struct taia *t, const struct taia *u)
|
int taia_less(const struct taia *t, const struct taia *u)
|
||||||
{
|
{
|
||||||
if (t->sec.x < u->sec.x) return 1;
|
if (t->sec.x < u->sec.x) return 1;
|
||||||
@ -180,9 +112,6 @@ int taia_less(const struct taia *t, const struct taia *u)
|
|||||||
return t->atto < u->atto;
|
return t->atto < u->atto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** taia_now.c ***/
|
|
||||||
|
|
||||||
void taia_now(struct taia *t)
|
void taia_now(struct taia *t)
|
||||||
{
|
{
|
||||||
struct timeval now;
|
struct timeval now;
|
||||||
@ -192,9 +121,7 @@ void taia_now(struct taia *t)
|
|||||||
t->atto = 0;
|
t->atto = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* UNUSED
|
||||||
/*** taia_pack.c ***/
|
|
||||||
|
|
||||||
void taia_pack(char *s, const struct taia *t)
|
void taia_pack(char *s, const struct taia *t)
|
||||||
{
|
{
|
||||||
unsigned long x;
|
unsigned long x;
|
||||||
@ -213,9 +140,7 @@ void taia_pack(char *s, const struct taia *t)
|
|||||||
s[1] = x & 255; x >>= 8;
|
s[1] = x & 255; x >>= 8;
|
||||||
s[0] = x;
|
s[0] = x;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*** taia_sub.c ***/
|
|
||||||
|
|
||||||
void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
|
void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
|
||||||
{
|
{
|
||||||
@ -235,11 +160,7 @@ void taia_sub(struct taia *t, const struct taia *u, const struct taia *v)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** taia_uint.c ***/
|
|
||||||
|
|
||||||
/* XXX: breaks tai encapsulation */
|
/* XXX: breaks tai encapsulation */
|
||||||
|
|
||||||
void taia_uint(struct taia *t, unsigned s)
|
void taia_uint(struct taia *t, unsigned s)
|
||||||
{
|
{
|
||||||
t->sec.x = s;
|
t->sec.x = s;
|
||||||
@ -247,16 +168,12 @@ void taia_uint(struct taia *t, unsigned s)
|
|||||||
t->atto = 0;
|
t->atto = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** iopause.c ***/
|
|
||||||
|
|
||||||
static
|
static
|
||||||
uint64_t taia2millisec(const struct taia *t)
|
uint64_t taia2millisec(const struct taia *t)
|
||||||
{
|
{
|
||||||
return (t->sec.x * 1000) + (t->nano / 1000000);
|
return (t->sec.x * 1000) + (t->nano / 1000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *stamp)
|
void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *stamp)
|
||||||
{
|
{
|
||||||
int millisecs;
|
int millisecs;
|
||||||
@ -282,59 +199,40 @@ void iopause(iopause_fd *x, unsigned len, struct taia *deadline, struct taia *st
|
|||||||
/* XXX: how to handle EAGAIN? are kernels really this dumb? */
|
/* XXX: how to handle EAGAIN? are kernels really this dumb? */
|
||||||
/* XXX: how to handle EINVAL? when exactly can this happen? */
|
/* XXX: how to handle EINVAL? when exactly can this happen? */
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*** lock_ex.c ***/
|
|
||||||
|
|
||||||
int lock_ex(int fd)
|
int lock_ex(int fd)
|
||||||
{
|
{
|
||||||
return flock(fd,LOCK_EX);
|
return flock(fd,LOCK_EX);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** lock_exnb.c ***/
|
|
||||||
|
|
||||||
int lock_exnb(int fd)
|
int lock_exnb(int fd)
|
||||||
{
|
{
|
||||||
return flock(fd,LOCK_EX | LOCK_NB);
|
return flock(fd,LOCK_EX | LOCK_NB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** open_append.c ***/
|
|
||||||
|
|
||||||
int open_append(const char *fn)
|
int open_append(const char *fn)
|
||||||
{
|
{
|
||||||
return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
|
return open(fn, O_WRONLY|O_NDELAY|O_APPEND|O_CREAT, 0600);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** open_read.c ***/
|
|
||||||
|
|
||||||
int open_read(const char *fn)
|
int open_read(const char *fn)
|
||||||
{
|
{
|
||||||
return open(fn, O_RDONLY|O_NDELAY);
|
return open(fn, O_RDONLY|O_NDELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** open_trunc.c ***/
|
|
||||||
|
|
||||||
int open_trunc(const char *fn)
|
int open_trunc(const char *fn)
|
||||||
{
|
{
|
||||||
return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
|
return open(fn,O_WRONLY | O_NDELAY | O_TRUNC | O_CREAT,0644);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*** open_write.c ***/
|
|
||||||
|
|
||||||
int open_write(const char *fn)
|
int open_write(const char *fn)
|
||||||
{
|
{
|
||||||
return open(fn, O_WRONLY|O_NDELAY);
|
return open(fn, O_WRONLY|O_NDELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned pmatch(const char *p, const char *s, unsigned len)
|
||||||
/*** pmatch.c ***/
|
{
|
||||||
|
|
||||||
unsigned pmatch(const char *p, const char *s, unsigned len) {
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char c = *p++;
|
char c = *p++;
|
||||||
if (!c) return !len;
|
if (!c) return !len;
|
||||||
@ -373,32 +271,3 @@ unsigned pmatch(const char *p, const char *s, unsigned len) {
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef UNUSED
|
|
||||||
/*** seek_set.c ***/
|
|
||||||
|
|
||||||
int seek_set(int fd,seek_pos pos)
|
|
||||||
{
|
|
||||||
if (lseek(fd,(off_t) pos,SEEK_SET) == -1) return -1; return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*** str_chr.c ***/
|
|
||||||
|
|
||||||
// strchrnul?
|
|
||||||
unsigned str_chr(const char *s,int c)
|
|
||||||
{
|
|
||||||
char ch;
|
|
||||||
const char *t;
|
|
||||||
|
|
||||||
ch = c;
|
|
||||||
t = s;
|
|
||||||
for (;;) {
|
|
||||||
if (!*t) break;
|
|
||||||
if (*t == ch) break;
|
|
||||||
++t;
|
|
||||||
}
|
|
||||||
return t - s;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
@ -25,107 +25,75 @@ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|||||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*** byte.h ***/
|
|
||||||
|
|
||||||
extern unsigned byte_chr(char *s,unsigned n,int c);
|
extern unsigned byte_chr(char *s,unsigned n,int c);
|
||||||
|
|
||||||
|
|
||||||
/*** coe.h ***/
|
|
||||||
|
|
||||||
extern int coe(int);
|
extern int coe(int);
|
||||||
|
|
||||||
|
|
||||||
/*** direntry.h ***/
|
|
||||||
|
|
||||||
#define direntry struct dirent
|
#define direntry struct dirent
|
||||||
|
|
||||||
|
//struct tai {
|
||||||
/*** tai.h ***/
|
// uint64_t x;
|
||||||
|
//};
|
||||||
struct tai {
|
//
|
||||||
uint64_t x;
|
//#define tai_unix(t,u) ((void) ((t)->x = 0x400000000000000aULL + (uint64_t) (u)))
|
||||||
};
|
//
|
||||||
|
//#define TAI_PACK 8
|
||||||
#define tai_unix(t,u) ((void) ((t)->x = 4611686018427387914ULL + (uint64_t) (u)))
|
//extern void tai_unpack(const char *,struct tai *);
|
||||||
|
//
|
||||||
#define TAI_PACK 8
|
//extern void tai_uint(struct tai *,unsigned);
|
||||||
//extern void tai_pack(char *,const struct tai *);
|
//
|
||||||
extern void tai_unpack(const char *,struct tai *);
|
//struct taia {
|
||||||
|
// struct tai sec;
|
||||||
extern void tai_uint(struct tai *,unsigned);
|
// unsigned long nano; /* 0...999999999 */
|
||||||
|
// unsigned long atto; /* 0...999999999 */
|
||||||
|
//};
|
||||||
/*** taia.h ***/
|
//
|
||||||
|
//extern void taia_now(struct taia *);
|
||||||
struct taia {
|
//
|
||||||
struct tai sec;
|
//extern void taia_add(struct taia *,const struct taia *,const struct taia *);
|
||||||
unsigned long nano; /* 0...999999999 */
|
//extern void taia_addsec(struct taia *,const struct taia *,int);
|
||||||
unsigned long atto; /* 0...999999999 */
|
//extern void taia_sub(struct taia *,const struct taia *,const struct taia *);
|
||||||
};
|
//extern void taia_half(struct taia *,const struct taia *);
|
||||||
|
//extern int taia_less(const struct taia *,const struct taia *);
|
||||||
//extern void taia_tai(const struct taia *,struct tai *);
|
//
|
||||||
|
//#define TAIA_PACK 16
|
||||||
extern void taia_now(struct taia *);
|
//extern void taia_pack(char *,const struct taia *);
|
||||||
|
//
|
||||||
extern void taia_add(struct taia *,const struct taia *,const struct taia *);
|
//extern void taia_uint(struct taia *,unsigned);
|
||||||
extern void taia_addsec(struct taia *,const struct taia *,int);
|
//
|
||||||
extern void taia_sub(struct taia *,const struct taia *,const struct taia *);
|
//typedef struct pollfd iopause_fd;
|
||||||
extern void taia_half(struct taia *,const struct taia *);
|
//#define IOPAUSE_READ POLLIN
|
||||||
extern int taia_less(const struct taia *,const struct taia *);
|
//#define IOPAUSE_WRITE POLLOUT
|
||||||
|
//
|
||||||
#define TAIA_PACK 16
|
//extern void iopause(iopause_fd *,unsigned,struct taia *,struct taia *);
|
||||||
extern void taia_pack(char *,const struct taia *);
|
|
||||||
//extern void taia_unpack(const char *,struct taia *);
|
|
||||||
|
|
||||||
//#define TAIA_FMTFRAC 19
|
|
||||||
//extern unsigned taia_fmtfrac(char *,const struct taia *);
|
|
||||||
|
|
||||||
extern void taia_uint(struct taia *,unsigned);
|
|
||||||
|
|
||||||
|
|
||||||
/*** fmt_ptime.h ***/
|
|
||||||
|
|
||||||
#define FMT_PTIME 30
|
|
||||||
|
|
||||||
/* NUL terminated */
|
|
||||||
extern void fmt_ptime30nul(char *, struct taia *);
|
|
||||||
/* NOT terminated! */
|
|
||||||
extern unsigned fmt_taia25(char *, struct taia *);
|
|
||||||
|
|
||||||
|
|
||||||
/*** iopause.h ***/
|
|
||||||
|
|
||||||
typedef struct pollfd iopause_fd;
|
|
||||||
#define IOPAUSE_READ POLLIN
|
|
||||||
#define IOPAUSE_WRITE POLLOUT
|
|
||||||
|
|
||||||
extern void iopause(iopause_fd *,unsigned,struct taia *,struct taia *);
|
|
||||||
|
|
||||||
|
|
||||||
/*** lock.h ***/
|
|
||||||
|
|
||||||
extern int lock_ex(int);
|
extern int lock_ex(int);
|
||||||
extern int lock_un(int);
|
extern int lock_un(int);
|
||||||
extern int lock_exnb(int);
|
extern int lock_exnb(int);
|
||||||
|
|
||||||
|
|
||||||
/*** open.h ***/
|
|
||||||
|
|
||||||
extern int open_read(const char *);
|
extern int open_read(const char *);
|
||||||
extern int open_excl(const char *);
|
extern int open_excl(const char *);
|
||||||
extern int open_append(const char *);
|
extern int open_append(const char *);
|
||||||
extern int open_trunc(const char *);
|
extern int open_trunc(const char *);
|
||||||
extern int open_write(const char *);
|
extern int open_write(const char *);
|
||||||
|
|
||||||
|
|
||||||
/*** pmatch.h ***/
|
|
||||||
|
|
||||||
extern unsigned pmatch(const char *, const char *, unsigned);
|
extern unsigned pmatch(const char *, const char *, unsigned);
|
||||||
|
|
||||||
|
|
||||||
/*** str.h ***/
|
|
||||||
|
|
||||||
//extern unsigned str_chr(const char *,int); /* never returns NULL */
|
|
||||||
|
|
||||||
#define str_diff(s,t) strcmp((s), (t))
|
#define str_diff(s,t) strcmp((s), (t))
|
||||||
#define str_equal(s,t) (!strcmp((s), (t)))
|
#define str_equal(s,t) (!strcmp((s), (t)))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* runsv / supervise / sv stuff
|
||||||
|
*/
|
||||||
|
typedef struct svstatus_t {
|
||||||
|
uint64_t time_be64;
|
||||||
|
uint32_t time_nsec_be32;
|
||||||
|
uint32_t pid_le32;
|
||||||
|
uint8_t paused;
|
||||||
|
uint8_t want;
|
||||||
|
uint8_t got_term;
|
||||||
|
uint8_t run_or_finish;
|
||||||
|
} svstatus_t;
|
||||||
|
struct ERR_svstatus_must_be_20_bytes {
|
||||||
|
char ERR_svstatus_must_be_20_bytes[sizeof(svstatus_t) == 20 ? 1 : -1];
|
||||||
|
};
|
||||||
|
153
runit/runsv.c
153
runit/runsv.c
@ -54,21 +54,19 @@ struct svdir {
|
|||||||
smallint ctrl;
|
smallint ctrl;
|
||||||
smallint want;
|
smallint want;
|
||||||
smallint islog;
|
smallint islog;
|
||||||
struct taia start;
|
struct timespec start;
|
||||||
int fdlock;
|
int fdlock;
|
||||||
int fdcontrol;
|
int fdcontrol;
|
||||||
int fdcontrolwrite;
|
int fdcontrolwrite;
|
||||||
};
|
};
|
||||||
static struct svdir svd[2];
|
|
||||||
|
|
||||||
|
static struct svdir svd[2];
|
||||||
static smallint sigterm;
|
static smallint sigterm;
|
||||||
static smallint haslog;
|
static smallint haslog;
|
||||||
static smallint pidchanged = 1;
|
static smallint pidchanged = 1;
|
||||||
static int logpipe[2];
|
static int logpipe[2];
|
||||||
static char *dir;
|
static char *dir;
|
||||||
|
|
||||||
#define usage() bb_show_usage()
|
|
||||||
|
|
||||||
static void fatal2_cannot(const char *m1, const char *m2)
|
static void fatal2_cannot(const char *m1, const char *m2)
|
||||||
{
|
{
|
||||||
bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2);
|
bb_perror_msg_and_die("%s: fatal: cannot %s%s", dir, m1, m2);
|
||||||
@ -88,10 +86,6 @@ static void warn_cannot(const char *m)
|
|||||||
{
|
{
|
||||||
bb_perror_msg("%s: warning: cannot %s", dir, m);
|
bb_perror_msg("%s: warning: cannot %s", dir, m);
|
||||||
}
|
}
|
||||||
static void warnx_cannot(const char *m)
|
|
||||||
{
|
|
||||||
bb_error_msg("%s: warning: cannot %s", dir, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void s_child(int sig_no)
|
static void s_child(int sig_no)
|
||||||
{
|
{
|
||||||
@ -132,11 +126,19 @@ static int rename_or_warn(const char *old, const char *new)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0)
|
||||||
|
|
||||||
|
#include <sys/syscall.h>
|
||||||
|
static void gettimeofday_ns(struct timespec *ts)
|
||||||
|
{
|
||||||
|
syscall(__NR_clock_gettime, CLOCK_REALTIME, ts);
|
||||||
|
}
|
||||||
|
|
||||||
static void update_status(struct svdir *s)
|
static void update_status(struct svdir *s)
|
||||||
{
|
{
|
||||||
unsigned long l;
|
ssize_t sz;
|
||||||
int fd;
|
int fd;
|
||||||
char status[20];
|
svstatus_t status;
|
||||||
|
|
||||||
/* pid */
|
/* pid */
|
||||||
if (pidchanged) {
|
if (pidchanged) {
|
||||||
@ -194,38 +196,27 @@ static void update_status(struct svdir *s)
|
|||||||
s->islog ? "log/supervise/stat" : "log/supervise/stat"+4);
|
s->islog ? "log/supervise/stat" : "log/supervise/stat"+4);
|
||||||
|
|
||||||
/* supervise compatibility */
|
/* supervise compatibility */
|
||||||
taia_pack(status, &s->start);
|
memset(&status, 0, sizeof(status));
|
||||||
l = (unsigned long)s->pid;
|
status.time_be64 = SWAP_BE64(s->start.tv_sec + 0x400000000000000aULL);
|
||||||
status[12] = l; l >>=8;
|
status.time_nsec_be32 = SWAP_BE32(s->start.tv_nsec);
|
||||||
status[13] = l; l >>=8;
|
status.pid_le32 = SWAP_LE32(s->pid);
|
||||||
status[14] = l; l >>=8;
|
|
||||||
status[15] = l;
|
|
||||||
if (s->ctrl & C_PAUSE)
|
if (s->ctrl & C_PAUSE)
|
||||||
status[16] = 1;
|
status.paused = 1;
|
||||||
else
|
|
||||||
status[16] = 0;
|
|
||||||
if (s->want == W_UP)
|
if (s->want == W_UP)
|
||||||
status[17] = 'u';
|
status.want = 'u';
|
||||||
else
|
else
|
||||||
status[17] = 'd';
|
status.want = 'd';
|
||||||
if (s->ctrl & C_TERM)
|
if (s->ctrl & C_TERM)
|
||||||
status[18] = 1;
|
status.got_term = 1;
|
||||||
else
|
status.run_or_finish = s->state;
|
||||||
status[18] = 0;
|
|
||||||
status[19] = s->state;
|
|
||||||
fd = open_trunc_or_warn("supervise/status.new");
|
fd = open_trunc_or_warn("supervise/status.new");
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return;
|
return;
|
||||||
l = write(fd, status, sizeof(status));
|
sz = write(fd, &status, sizeof(status));
|
||||||
if (l < 0) {
|
|
||||||
warn_cannot("write supervise/status.new");
|
|
||||||
close(fd);
|
|
||||||
unlink("supervise/status.new");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
close(fd);
|
close(fd);
|
||||||
if (l < sizeof(status)) {
|
if (sz != sizeof(status)) {
|
||||||
warnx_cannot("write supervise/status.new: partial write");
|
warn_cannot("write supervise/status.new");
|
||||||
|
unlink("supervise/status.new");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rename_or_warn("supervise/status.new",
|
rename_or_warn("supervise/status.new",
|
||||||
@ -329,7 +320,7 @@ static void startservice(struct svdir *s)
|
|||||||
fatal2_cannot(s->islog ? "start log/" : "start ", *run);
|
fatal2_cannot(s->islog ? "start log/" : "start ", *run);
|
||||||
}
|
}
|
||||||
if (s->state != S_FINISH) {
|
if (s->state != S_FINISH) {
|
||||||
taia_now(&s->start);
|
gettimeofday_ns(&s->start);
|
||||||
s->state = S_RUN;
|
s->state = S_RUN;
|
||||||
}
|
}
|
||||||
s->pid = p;
|
s->pid = p;
|
||||||
@ -346,39 +337,48 @@ static int ctrl(struct svdir *s, char c)
|
|||||||
case 'd': /* down */
|
case 'd': /* down */
|
||||||
s->want = W_DOWN;
|
s->want = W_DOWN;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
if (s->pid && s->state != S_FINISH) stopservice(s);
|
if (s->pid && s->state != S_FINISH)
|
||||||
|
stopservice(s);
|
||||||
break;
|
break;
|
||||||
case 'u': /* up */
|
case 'u': /* up */
|
||||||
s->want = W_UP;
|
s->want = W_UP;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
if (s->pid == 0) startservice(s);
|
if (s->pid == 0)
|
||||||
|
startservice(s);
|
||||||
break;
|
break;
|
||||||
case 'x': /* exit */
|
case 'x': /* exit */
|
||||||
if (s->islog) break;
|
if (s->islog)
|
||||||
|
break;
|
||||||
s->want = W_EXIT;
|
s->want = W_EXIT;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case 't': /* sig term */
|
case 't': /* sig term */
|
||||||
if (s->pid && s->state != S_FINISH) stopservice(s);
|
if (s->pid && s->state != S_FINISH)
|
||||||
|
stopservice(s);
|
||||||
break;
|
break;
|
||||||
case 'k': /* sig kill */
|
case 'k': /* sig kill */
|
||||||
if (s->pid && !custom(s, c)) kill(s->pid, SIGKILL);
|
if (s->pid && !custom(s, c))
|
||||||
|
kill(s->pid, SIGKILL);
|
||||||
s->state = S_DOWN;
|
s->state = S_DOWN;
|
||||||
break;
|
break;
|
||||||
case 'p': /* sig pause */
|
case 'p': /* sig pause */
|
||||||
if (s->pid && !custom(s, c)) kill(s->pid, SIGSTOP);
|
if (s->pid && !custom(s, c))
|
||||||
|
kill(s->pid, SIGSTOP);
|
||||||
s->ctrl |= C_PAUSE;
|
s->ctrl |= C_PAUSE;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
break;
|
break;
|
||||||
case 'c': /* sig cont */
|
case 'c': /* sig cont */
|
||||||
if (s->pid && !custom(s, c)) kill(s->pid, SIGCONT);
|
if (s->pid && !custom(s, c))
|
||||||
if (s->ctrl & C_PAUSE) s->ctrl &= ~C_PAUSE;
|
kill(s->pid, SIGCONT);
|
||||||
|
if (s->ctrl & C_PAUSE)
|
||||||
|
s->ctrl &= ~C_PAUSE;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
break;
|
break;
|
||||||
case 'o': /* once */
|
case 'o': /* once */
|
||||||
s->want = W_DOWN;
|
s->want = W_DOWN;
|
||||||
update_status(s);
|
update_status(s);
|
||||||
if (!s->pid) startservice(s);
|
if (!s->pid)
|
||||||
|
startservice(s);
|
||||||
break;
|
break;
|
||||||
case 'a': /* sig alarm */
|
case 'a': /* sig alarm */
|
||||||
sig = SIGALRM;
|
sig = SIGALRM;
|
||||||
@ -414,7 +414,8 @@ int runsv_main(int argc, char **argv)
|
|||||||
int r;
|
int r;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
if (!argv[1] || argv[2]) usage();
|
if (!argv[1] || argv[2])
|
||||||
|
bb_show_usage();
|
||||||
dir = argv[1];
|
dir = argv[1];
|
||||||
|
|
||||||
xpipe(selfpipe);
|
xpipe(selfpipe);
|
||||||
@ -435,22 +436,23 @@ int runsv_main(int argc, char **argv)
|
|||||||
if (W_UP) svd[0].want = W_UP;
|
if (W_UP) svd[0].want = W_UP;
|
||||||
/* bss: svd[0].islog = 0; */
|
/* bss: svd[0].islog = 0; */
|
||||||
/* bss: svd[1].pid = 0; */
|
/* bss: svd[1].pid = 0; */
|
||||||
taia_now(&svd[0].start);
|
gettimeofday_ns(&svd[0].start);
|
||||||
if (stat("down", &s) != -1) svd[0].want = W_DOWN;
|
if (stat("down", &s) != -1) svd[0].want = W_DOWN;
|
||||||
|
|
||||||
if (stat("log", &s) == -1) {
|
if (stat("log", &s) == -1) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
warn_cannot("stat ./log");
|
warn_cannot("stat ./log");
|
||||||
} else {
|
} else {
|
||||||
if (!S_ISDIR(s.st_mode))
|
if (!S_ISDIR(s.st_mode)) {
|
||||||
warnx_cannot("stat log/down: log is not a directory");
|
errno = 0;
|
||||||
else {
|
warn_cannot("stat log/down: log is not a directory");
|
||||||
|
} else {
|
||||||
haslog = 1;
|
haslog = 1;
|
||||||
svd[1].state = S_DOWN;
|
svd[1].state = S_DOWN;
|
||||||
svd[1].ctrl = C_NOOP;
|
svd[1].ctrl = C_NOOP;
|
||||||
svd[1].want = W_UP;
|
svd[1].want = W_UP;
|
||||||
svd[1].islog = 1;
|
svd[1].islog = 1;
|
||||||
taia_now(&svd[1].start);
|
gettimeofday_ns(&svd[1].start);
|
||||||
if (stat("log/down", &s) != -1)
|
if (stat("log/down", &s) != -1)
|
||||||
svd[1].want = W_DOWN;
|
svd[1].want = W_DOWN;
|
||||||
xpipe(logpipe);
|
xpipe(logpipe);
|
||||||
@ -525,9 +527,8 @@ int runsv_main(int argc, char **argv)
|
|||||||
coe(fd);
|
coe(fd);
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
iopause_fd x[3];
|
struct pollfd x[3];
|
||||||
struct taia deadline;
|
unsigned deadline;
|
||||||
struct taia now;
|
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
if (haslog)
|
if (haslog)
|
||||||
@ -538,32 +539,30 @@ int runsv_main(int argc, char **argv)
|
|||||||
startservice(&svd[0]);
|
startservice(&svd[0]);
|
||||||
|
|
||||||
x[0].fd = selfpipe[0];
|
x[0].fd = selfpipe[0];
|
||||||
x[0].events = IOPAUSE_READ;
|
x[0].events = POLLIN;
|
||||||
x[1].fd = svd[0].fdcontrol;
|
x[1].fd = svd[0].fdcontrol;
|
||||||
x[1].events = IOPAUSE_READ;
|
x[1].events = POLLIN;
|
||||||
if (haslog) {
|
/* x[2] is used only if haslog == 1 */
|
||||||
x[2].fd = svd[1].fdcontrol;
|
x[2].fd = svd[1].fdcontrol;
|
||||||
x[2].events = IOPAUSE_READ;
|
x[2].events = POLLIN;
|
||||||
}
|
|
||||||
taia_now(&now);
|
|
||||||
taia_uint(&deadline, 3600);
|
|
||||||
taia_add(&deadline, &now, &deadline);
|
|
||||||
|
|
||||||
sig_unblock(SIGTERM);
|
sig_unblock(SIGTERM);
|
||||||
sig_unblock(SIGCHLD);
|
sig_unblock(SIGCHLD);
|
||||||
iopause(x, 2+haslog, &deadline, &now);
|
poll(x, 2 + haslog, 3600*1000);
|
||||||
sig_block(SIGTERM);
|
sig_block(SIGTERM);
|
||||||
sig_block(SIGCHLD);
|
sig_block(SIGCHLD);
|
||||||
|
|
||||||
while (read(selfpipe[0], &ch, 1) == 1)
|
while (read(selfpipe[0], &ch, 1) == 1)
|
||||||
;
|
continue;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int child;
|
int child;
|
||||||
int wstat;
|
int wstat;
|
||||||
|
|
||||||
child = wait_nohang(&wstat);
|
child = wait_nohang(&wstat);
|
||||||
if (!child) break;
|
if (!child)
|
||||||
if ((child == -1) && (errno != EINTR)) break;
|
break;
|
||||||
|
if ((child == -1) && (errno != EINTR))
|
||||||
|
break;
|
||||||
if (child == svd[0].pid) {
|
if (child == svd[0].pid) {
|
||||||
svd[0].pid = 0;
|
svd[0].pid = 0;
|
||||||
pidchanged = 1;
|
pidchanged = 1;
|
||||||
@ -578,11 +577,11 @@ int runsv_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
svd[0].state = S_DOWN;
|
svd[0].state = S_DOWN;
|
||||||
taia_uint(&deadline, 1);
|
deadline = svd[0].start.tv_sec + 1;
|
||||||
taia_add(&deadline, &svd[0].start, &deadline);
|
gettimeofday_ns(&svd[0].start);
|
||||||
taia_now(&svd[0].start);
|
|
||||||
update_status(&svd[0]);
|
update_status(&svd[0]);
|
||||||
if (taia_less(&svd[0].start, &deadline)) sleep(1);
|
if (LESS(svd[0].start.tv_sec, deadline))
|
||||||
|
sleep(1);
|
||||||
}
|
}
|
||||||
if (haslog) {
|
if (haslog) {
|
||||||
if (child == svd[1].pid) {
|
if (child == svd[1].pid) {
|
||||||
@ -590,11 +589,11 @@ int runsv_main(int argc, char **argv)
|
|||||||
pidchanged = 1;
|
pidchanged = 1;
|
||||||
svd[1].state = S_DOWN;
|
svd[1].state = S_DOWN;
|
||||||
svd[1].ctrl &= ~C_TERM;
|
svd[1].ctrl &= ~C_TERM;
|
||||||
taia_uint(&deadline, 1);
|
deadline = svd[1].start.tv_sec + 1;
|
||||||
taia_add(&deadline, &svd[1].start, &deadline);
|
gettimeofday_ns(&svd[1].start);
|
||||||
taia_now(&svd[1].start);
|
|
||||||
update_status(&svd[1]);
|
update_status(&svd[1]);
|
||||||
if (taia_less(&svd[1].start, &deadline)) sleep(1);
|
if (LESS(svd[1].start.tv_sec, deadline))
|
||||||
|
sleep(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -618,10 +617,6 @@ int runsv_main(int argc, char **argv)
|
|||||||
update_status(&svd[1]);
|
update_status(&svd[1]);
|
||||||
close(logpipe[1]);
|
close(logpipe[1]);
|
||||||
close(logpipe[0]);
|
close(logpipe[0]);
|
||||||
//if (close(logpipe[1]) == -1)
|
|
||||||
// warn_cannot("close logpipe[1]");
|
|
||||||
//if (close(logpipe[0]) == -1)
|
|
||||||
// warn_cannot("close logpipe[0]");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
138
runit/runsvdir.c
138
runit/runsvdir.c
@ -35,26 +35,25 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
|
|
||||||
#define MAXSERVICES 1000
|
#define MAXSERVICES 1000
|
||||||
|
|
||||||
|
struct service {
|
||||||
|
dev_t dev;
|
||||||
|
ino_t ino;
|
||||||
|
pid_t pid;
|
||||||
|
smallint isgone;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct service *sv;
|
||||||
static char *svdir;
|
static char *svdir;
|
||||||
static unsigned long dev;
|
|
||||||
static unsigned long ino;
|
|
||||||
static struct service {
|
|
||||||
unsigned long dev;
|
|
||||||
unsigned long ino;
|
|
||||||
int pid;
|
|
||||||
int isgone;
|
|
||||||
} *sv;
|
|
||||||
static int svnum;
|
static int svnum;
|
||||||
static int check = 1;
|
|
||||||
static char *rplog;
|
static char *rplog;
|
||||||
static int rploglen;
|
static int rploglen;
|
||||||
static int logpipe[2];
|
static int logpipe[2];
|
||||||
static iopause_fd io[1];
|
static struct pollfd pfd[1];
|
||||||
static struct taia stamplog;
|
static unsigned stamplog;
|
||||||
static int exitsoon;
|
static smallint check = 1;
|
||||||
static int pgrp;
|
static smallint exitsoon;
|
||||||
|
static smallint set_pgrp;
|
||||||
|
|
||||||
#define usage() bb_show_usage()
|
|
||||||
static void fatal2_cannot(const char *m1, const char *m2)
|
static void fatal2_cannot(const char *m1, const char *m2)
|
||||||
{
|
{
|
||||||
bb_perror_msg_and_die("%s: fatal: cannot %s%s", svdir, m1, m2);
|
bb_perror_msg_and_die("%s: fatal: cannot %s%s", svdir, m1, m2);
|
||||||
@ -84,25 +83,26 @@ static void s_hangup(int sig_no)
|
|||||||
|
|
||||||
static void runsv(int no, const char *name)
|
static void runsv(int no, const char *name)
|
||||||
{
|
{
|
||||||
int pid = fork();
|
pid_t pid;
|
||||||
|
char *prog[3];
|
||||||
|
|
||||||
|
prog[0] = (char*)"runsv";
|
||||||
|
prog[1] = (char*)name;
|
||||||
|
prog[2] = NULL;
|
||||||
|
|
||||||
|
pid = vfork();
|
||||||
|
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
warn2_cannot("fork for ", name);
|
warn2_cannot("vfork", "");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
/* child */
|
/* child */
|
||||||
char *prog[3];
|
if (set_pgrp)
|
||||||
|
|
||||||
prog[0] = (char*)"runsv";
|
|
||||||
prog[1] = (char*)name;
|
|
||||||
prog[2] = NULL;
|
|
||||||
if (pgrp)
|
|
||||||
setsid();
|
setsid();
|
||||||
signal(SIGHUP, SIG_DFL);
|
signal(SIGHUP, SIG_DFL);
|
||||||
signal(SIGTERM, SIG_DFL);
|
signal(SIGTERM, SIG_DFL);
|
||||||
BB_EXECVP(prog[0], prog);
|
execvp(prog[0], prog);
|
||||||
//pathexec_run(*prog, prog, (char* const*)environ);
|
|
||||||
fatal2_cannot("start runsv ", name);
|
fatal2_cannot("start runsv ", name);
|
||||||
}
|
}
|
||||||
sv[no].pid = pid;
|
sv[no].pid = pid;
|
||||||
@ -124,13 +124,15 @@ static void runsvdir(void)
|
|||||||
sv[i].isgone = 1;
|
sv[i].isgone = 1;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
while ((d = readdir(dir))) {
|
while ((d = readdir(dir))) {
|
||||||
if (d->d_name[0] == '.') continue;
|
if (d->d_name[0] == '.')
|
||||||
|
continue;
|
||||||
if (stat(d->d_name, &s) == -1) {
|
if (stat(d->d_name, &s) == -1) {
|
||||||
warn2_cannot("stat ", d->d_name);
|
warn2_cannot("stat ", d->d_name);
|
||||||
errno = 0;
|
errno = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!S_ISDIR(s.st_mode)) continue;
|
if (!S_ISDIR(s.st_mode))
|
||||||
|
continue;
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
|
if ((sv[i].ino == s.st_ino) && (sv[i].dev == s.st_dev)) {
|
||||||
sv[i].isgone = 0;
|
sv[i].isgone = 0;
|
||||||
@ -152,8 +154,8 @@ static void runsvdir(void)
|
|||||||
memset(&sv[i], 0, sizeof(sv[i]));
|
memset(&sv[i], 0, sizeof(sv[i]));
|
||||||
sv[i].ino = s.st_ino;
|
sv[i].ino = s.st_ino;
|
||||||
sv[i].dev = s.st_dev;
|
sv[i].dev = s.st_dev;
|
||||||
//sv[i].pid = 0;
|
/*sv[i].pid = 0;*/
|
||||||
//sv[i].isgone = 0;
|
/*sv[i].isgone = 0;*/
|
||||||
runsv(i, d->d_name);
|
runsv(i, d->d_name);
|
||||||
check = 1;
|
check = 1;
|
||||||
}
|
}
|
||||||
@ -196,9 +198,9 @@ static int setup_log(void)
|
|||||||
warnx("cannot set filedescriptor for log");
|
warnx("cannot set filedescriptor for log");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
io[0].fd = logpipe[0];
|
pfd[0].fd = logpipe[0];
|
||||||
io[0].events = IOPAUSE_READ;
|
pfd[0].events = POLLIN;
|
||||||
taia_now(&stamplog);
|
stamplog = monotonic_sec();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,24 +208,28 @@ int runsvdir_main(int argc, char **argv);
|
|||||||
int runsvdir_main(int argc, char **argv)
|
int runsvdir_main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat s;
|
struct stat s;
|
||||||
time_t mtime = 0;
|
dev_t last_dev = last_dev; /* for gcc */
|
||||||
|
ino_t last_ino = last_ino; /* for gcc */
|
||||||
|
time_t last_mtime = 0;
|
||||||
int wstat;
|
int wstat;
|
||||||
int curdir;
|
int curdir;
|
||||||
int pid;
|
int pid;
|
||||||
struct taia deadline;
|
unsigned deadline;
|
||||||
struct taia now;
|
unsigned now;
|
||||||
struct taia stampcheck;
|
unsigned stampcheck;
|
||||||
char ch;
|
char ch;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
argv++;
|
argv++;
|
||||||
if (!argv || !*argv) usage();
|
if (!*argv)
|
||||||
if (**argv == '-') {
|
bb_show_usage();
|
||||||
switch (*(*argv + 1)) {
|
if (argv[0][0] == '-') {
|
||||||
case 'P': pgrp = 1;
|
switch (argv[0][1]) {
|
||||||
|
case 'P': set_pgrp = 1;
|
||||||
case '-': ++argv;
|
case '-': ++argv;
|
||||||
}
|
}
|
||||||
if (!argv || !*argv) usage();
|
if (!*argv)
|
||||||
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
sig_catch(SIGTERM, s_term);
|
sig_catch(SIGTERM, s_term);
|
||||||
@ -241,13 +247,14 @@ int runsvdir_main(int argc, char **argv)
|
|||||||
fatal2_cannot("open current directory", "");
|
fatal2_cannot("open current directory", "");
|
||||||
coe(curdir);
|
coe(curdir);
|
||||||
|
|
||||||
taia_now(&stampcheck);
|
stampcheck = monotonic_sec();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* collect children */
|
/* collect children */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
pid = wait_nohang(&wstat);
|
pid = wait_nohang(&wstat);
|
||||||
if (pid <= 0) break;
|
if (pid <= 0)
|
||||||
|
break;
|
||||||
for (i = 0; i < svnum; i++) {
|
for (i = 0; i < svnum; i++) {
|
||||||
if (pid == sv[i].pid) {
|
if (pid == sv[i].pid) {
|
||||||
/* runsv has gone */
|
/* runsv has gone */
|
||||||
@ -258,31 +265,23 @@ int runsvdir_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
taia_now(&now);
|
now = monotonic_sec();
|
||||||
if (now.sec.x < (stampcheck.sec.x - 3)) {
|
if ((int)(now - stampcheck) >= 0) {
|
||||||
/* time warp */
|
|
||||||
warnx("time warp: resetting time stamp");
|
|
||||||
taia_now(&stampcheck);
|
|
||||||
taia_now(&now);
|
|
||||||
if (rplog) taia_now(&stamplog);
|
|
||||||
}
|
|
||||||
if (taia_less(&now, &stampcheck) == 0) {
|
|
||||||
/* wait at least a second */
|
/* wait at least a second */
|
||||||
taia_uint(&deadline, 1);
|
stampcheck = now + 1;
|
||||||
taia_add(&stampcheck, &now, &deadline);
|
|
||||||
|
|
||||||
if (stat(svdir, &s) != -1) {
|
if (stat(svdir, &s) != -1) {
|
||||||
if (check || s.st_mtime != mtime
|
if (check || s.st_mtime != last_mtime
|
||||||
|| s.st_ino != ino || s.st_dev != dev
|
|| s.st_ino != last_ino || s.st_dev != last_dev
|
||||||
) {
|
) {
|
||||||
/* svdir modified */
|
/* svdir modified */
|
||||||
if (chdir(svdir) != -1) {
|
if (chdir(svdir) != -1) {
|
||||||
mtime = s.st_mtime;
|
last_mtime = s.st_mtime;
|
||||||
dev = s.st_dev;
|
last_dev = s.st_dev;
|
||||||
ino = s.st_ino;
|
last_ino = s.st_ino;
|
||||||
check = 0;
|
check = 0;
|
||||||
if (now.sec.x <= (4611686018427387914ULL + (uint64_t)mtime))
|
//if (now <= mtime)
|
||||||
sleep(1);
|
// sleep(1);
|
||||||
runsvdir();
|
runsvdir();
|
||||||
while (fchdir(curdir) == -1) {
|
while (fchdir(curdir) == -1) {
|
||||||
warn2_cannot("change directory, pausing", "");
|
warn2_cannot("change directory, pausing", "");
|
||||||
@ -296,29 +295,30 @@ int runsvdir_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rplog) {
|
if (rplog) {
|
||||||
if (taia_less(&now, &stamplog) == 0) {
|
if ((int)(now - stamplog) >= 0) {
|
||||||
write(logpipe[1], ".", 1);
|
write(logpipe[1], ".", 1);
|
||||||
taia_uint(&deadline, 900);
|
stamplog = now + 900;
|
||||||
taia_add(&stamplog, &now, &deadline);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
taia_uint(&deadline, check ? 1 : 5);
|
deadline = now + (check ? 1 : 5);
|
||||||
taia_add(&deadline, &now, &deadline);
|
|
||||||
|
|
||||||
|
pfd[0].revents = 0;
|
||||||
sig_block(SIGCHLD);
|
sig_block(SIGCHLD);
|
||||||
if (rplog)
|
if (rplog)
|
||||||
iopause(io, 1, &deadline, &now);
|
poll(pfd, 1, deadline*1000);
|
||||||
else
|
else
|
||||||
iopause(0, 0, &deadline, &now);
|
sleep(deadline);
|
||||||
sig_unblock(SIGCHLD);
|
sig_unblock(SIGCHLD);
|
||||||
|
|
||||||
if (rplog && (io[0].revents | IOPAUSE_READ))
|
if (pfd[0].revents & POLLIN) {
|
||||||
while (read(logpipe[0], &ch, 1) > 0)
|
while (read(logpipe[0], &ch, 1) > 0) {
|
||||||
if (ch) {
|
if (ch) {
|
||||||
for (i = 6; i < rploglen; i++)
|
for (i = 6; i < rploglen; i++)
|
||||||
rplog[i-1] = rplog[i];
|
rplog[i-1] = rplog[i];
|
||||||
rplog[rploglen-1] = ch;
|
rplog[rploglen-1] = ch;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (exitsoon) {
|
switch (exitsoon) {
|
||||||
case 1:
|
case 1:
|
||||||
|
128
runit/sv.c
128
runit/sv.c
@ -161,10 +161,10 @@ Exit Codes
|
|||||||
static const char *acts;
|
static const char *acts;
|
||||||
static char **service;
|
static char **service;
|
||||||
static unsigned rc;
|
static unsigned rc;
|
||||||
static struct taia tstart, tnow;
|
/* "Bernstein" time format: unix + 0x400000000000000aULL */
|
||||||
static char svstatus[20];
|
static uint64_t tstart, tnow;
|
||||||
|
svstatus_t svstatus;
|
||||||
|
|
||||||
#define usage() bb_show_usage()
|
|
||||||
|
|
||||||
static void fatal_cannot(const char *m1) ATTRIBUTE_NORETURN;
|
static void fatal_cannot(const char *m1) ATTRIBUTE_NORETURN;
|
||||||
static void fatal_cannot(const char *m1)
|
static void fatal_cannot(const char *m1)
|
||||||
@ -195,15 +195,11 @@ static void failx(const char *m1)
|
|||||||
errno = 0;
|
errno = 0;
|
||||||
fail(m1);
|
fail(m1);
|
||||||
}
|
}
|
||||||
static void warn_cannot(const char *m1)
|
static void warn(const char *m1)
|
||||||
{
|
{
|
||||||
++rc;
|
++rc;
|
||||||
out("warning: cannot ", m1);
|
/* "warning: <service>: <m1>\n" */
|
||||||
}
|
out("warning: ", m1);
|
||||||
static void warnx_cannot(const char *m1)
|
|
||||||
{
|
|
||||||
errno = 0;
|
|
||||||
warn_cannot(m1);
|
|
||||||
}
|
}
|
||||||
static void ok(const char *m1)
|
static void ok(const char *m1)
|
||||||
{
|
{
|
||||||
@ -222,32 +218,38 @@ static int svstatus_get(void)
|
|||||||
: failx("runsv not running");
|
: failx("runsv not running");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
warn_cannot("open supervise/ok");
|
warn("cannot open supervise/ok");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
fd = open_read("supervise/status");
|
fd = open_read("supervise/status");
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
warn_cannot("open supervise/status");
|
warn("cannot open supervise/status");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
r = read(fd, svstatus, 20);
|
r = read(fd, &svstatus, 20);
|
||||||
close(fd);
|
close(fd);
|
||||||
switch (r) {
|
switch (r) {
|
||||||
case 20: break;
|
case 20:
|
||||||
case -1: warn_cannot("read supervise/status"); return -1;
|
break;
|
||||||
default: warnx_cannot("read supervise/status: bad format"); return -1;
|
case -1:
|
||||||
|
warn("cannot read supervise/status");
|
||||||
|
return -1;
|
||||||
|
default:
|
||||||
|
errno = 0;
|
||||||
|
warn("cannot read supervise/status: bad format");
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned svstatus_print(const char *m)
|
static unsigned svstatus_print(const char *m)
|
||||||
{
|
{
|
||||||
long diff;
|
int diff;
|
||||||
int pid;
|
int pid;
|
||||||
int normallyup = 0;
|
int normallyup = 0;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
struct tai tstatus;
|
uint64_t timestamp;
|
||||||
|
|
||||||
if (stat("down", &s) == -1) {
|
if (stat("down", &s) == -1) {
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
@ -256,13 +258,10 @@ static unsigned svstatus_print(const char *m)
|
|||||||
}
|
}
|
||||||
normallyup = 1;
|
normallyup = 1;
|
||||||
}
|
}
|
||||||
pid = (unsigned char) svstatus[15];
|
pid = SWAP_LE32(svstatus.pid_le32);
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[14];
|
timestamp = SWAP_BE64(svstatus.time_be64);
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[13];
|
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[12];
|
|
||||||
tai_unpack(svstatus, &tstatus);
|
|
||||||
if (pid) {
|
if (pid) {
|
||||||
switch (svstatus[19]) {
|
switch (svstatus.run_or_finish) {
|
||||||
case 1: printf("run: "); break;
|
case 1: printf("run: "); break;
|
||||||
case 2: printf("finish: "); break;
|
case 2: printf("finish: "); break;
|
||||||
}
|
}
|
||||||
@ -270,16 +269,16 @@ static unsigned svstatus_print(const char *m)
|
|||||||
} else {
|
} else {
|
||||||
printf("down: %s: ", m);
|
printf("down: %s: ", m);
|
||||||
}
|
}
|
||||||
diff = tnow.sec.x - tstatus.x;
|
diff = tnow - timestamp;
|
||||||
printf("%lds", (diff < 0 ? 0L : diff));
|
printf("%us", (diff < 0 ? 0 : diff));
|
||||||
if (pid) {
|
if (pid) {
|
||||||
if (!normallyup) printf(", normally down");
|
if (!normallyup) printf(", normally down");
|
||||||
if (svstatus[16]) printf(", paused");
|
if (svstatus.paused) printf(", paused");
|
||||||
if (svstatus[17] == 'd') printf(", want down");
|
if (svstatus.want == 'd') printf(", want down");
|
||||||
if (svstatus[18]) printf(", got TERM");
|
if (svstatus.got_term) printf(", got TERM");
|
||||||
} else {
|
} else {
|
||||||
if (normallyup) printf(", normally up");
|
if (normallyup) printf(", normally up");
|
||||||
if (svstatus[17] == 'u') printf(", want up");
|
if (svstatus.want == 'u') printf(", want up");
|
||||||
}
|
}
|
||||||
return pid ? 1 : 2;
|
return pid ? 1 : 2;
|
||||||
}
|
}
|
||||||
@ -336,7 +335,7 @@ static int check(const char *a)
|
|||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
unsigned pid;
|
unsigned pid;
|
||||||
struct tai tstatus;
|
uint64_t timestamp;
|
||||||
|
|
||||||
r = svstatus_get();
|
r = svstatus_get();
|
||||||
if (r == -1)
|
if (r == -1)
|
||||||
@ -346,15 +345,12 @@ static int check(const char *a)
|
|||||||
return 1;
|
return 1;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
pid = (unsigned char)svstatus[15];
|
pid = SWAP_LE32(svstatus.pid_le32);
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[14];
|
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[13];
|
|
||||||
pid <<= 8; pid += (unsigned char)svstatus[12];
|
|
||||||
switch (*a) {
|
switch (*a) {
|
||||||
case 'x':
|
case 'x':
|
||||||
return 0;
|
return 0;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (!pid || svstatus[19] != 1) return 0;
|
if (!pid || svstatus.run_or_finish != 1) return 0;
|
||||||
if (!checkscript()) return 0;
|
if (!checkscript()) return 0;
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
@ -364,14 +360,14 @@ static int check(const char *a)
|
|||||||
if (pid && !checkscript()) return 0;
|
if (pid && !checkscript()) return 0;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (!pid && svstatus[17] == 'd') break;
|
if (!pid && svstatus.want == 'd') break;
|
||||||
tai_unpack(svstatus, &tstatus);
|
timestamp = SWAP_BE64(svstatus.time_be64);
|
||||||
if ((tstart.sec.x > tstatus.x) || !pid || svstatus[18] || !checkscript())
|
if ((tstart > timestamp) || !pid || svstatus.got_term || !checkscript())
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
tai_unpack(svstatus, &tstatus);
|
timestamp = SWAP_BE64(svstatus.time_be64);
|
||||||
if ((!pid && tstart.sec.x > tstatus.x) || (pid && svstatus[17] != 'd'))
|
if ((!pid && tstart > timestamp) || (pid && svstatus.want != 'd'))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf(OK);
|
printf(OK);
|
||||||
@ -384,12 +380,14 @@ static int control(const char *a)
|
|||||||
{
|
{
|
||||||
int fd, r;
|
int fd, r;
|
||||||
|
|
||||||
if (svstatus_get() <= 0) return -1;
|
if (svstatus_get() <= 0)
|
||||||
if (svstatus[17] == *a) return 0;
|
return -1;
|
||||||
|
if (svstatus.want == *a)
|
||||||
|
return 0;
|
||||||
fd = open_write("supervise/control");
|
fd = open_write("supervise/control");
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno != ENODEV)
|
if (errno != ENODEV)
|
||||||
warn_cannot("open supervise/control");
|
warn("cannot open supervise/control");
|
||||||
else
|
else
|
||||||
*a == 'x' ? ok("runsv not running") : failx("runsv not running");
|
*a == 'x' ? ok("runsv not running") : failx("runsv not running");
|
||||||
return -1;
|
return -1;
|
||||||
@ -397,7 +395,7 @@ static int control(const char *a)
|
|||||||
r = write(fd, a, strlen(a));
|
r = write(fd, a, strlen(a));
|
||||||
close(fd);
|
close(fd);
|
||||||
if (r != strlen(a)) {
|
if (r != strlen(a)) {
|
||||||
warn_cannot("write to supervise/control");
|
warn("cannot write to supervise/control");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -413,7 +411,7 @@ int sv_main(int argc, char **argv)
|
|||||||
const char *varservice = "/var/service/";
|
const char *varservice = "/var/service/";
|
||||||
unsigned services;
|
unsigned services;
|
||||||
char **servicex;
|
char **servicex;
|
||||||
unsigned long waitsec = 7;
|
unsigned waitsec = 7;
|
||||||
smallint kll = 0;
|
smallint kll = 0;
|
||||||
smallint verbose = 0;
|
smallint verbose = 0;
|
||||||
int (*act)(const char*);
|
int (*act)(const char*);
|
||||||
@ -425,19 +423,19 @@ int sv_main(int argc, char **argv)
|
|||||||
x = getenv("SVDIR");
|
x = getenv("SVDIR");
|
||||||
if (x) varservice = x;
|
if (x) varservice = x;
|
||||||
x = getenv("SVWAIT");
|
x = getenv("SVWAIT");
|
||||||
if (x) waitsec = xatoul(x);
|
if (x) waitsec = xatou(x);
|
||||||
|
|
||||||
opt = getopt32(argv, "w:v", &x);
|
opt = getopt32(argv, "w:v", &x);
|
||||||
if (opt & 1) waitsec = xatoul(x); // -w
|
if (opt & 1) waitsec = xatou(x); // -w
|
||||||
if (opt & 2) verbose = 1; // -v
|
if (opt & 2) verbose = 1; // -v
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
argv += optind;
|
argv += optind;
|
||||||
action = *argv++;
|
action = *argv++;
|
||||||
if (!action || !*argv) usage();
|
if (!action || !*argv) bb_show_usage();
|
||||||
service = argv;
|
service = argv;
|
||||||
services = argc - 1;
|
services = argc - 1;
|
||||||
|
|
||||||
taia_now(&tnow);
|
tnow = time(0) + 0x400000000000000aULL;
|
||||||
tstart = tnow;
|
tstart = tnow;
|
||||||
curdir = open_read(".");
|
curdir = open_read(".");
|
||||||
if (curdir == -1)
|
if (curdir == -1)
|
||||||
@ -467,7 +465,7 @@ int sv_main(int argc, char **argv)
|
|||||||
kll = 1;
|
kll = 1;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
if (!str_diff(action, "check")) {
|
if (str_equal(action, "check")) {
|
||||||
act = NULL;
|
act = NULL;
|
||||||
acts = "c";
|
acts = "c";
|
||||||
break;
|
break;
|
||||||
@ -479,15 +477,15 @@ int sv_main(int argc, char **argv)
|
|||||||
if (!verbose) cbk = NULL;
|
if (!verbose) cbk = NULL;
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
if (!str_diff(action, "shutdown")) {
|
if (str_equal(action, "shutdown")) {
|
||||||
acts = "x";
|
acts = "x";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!str_diff(action, "start")) {
|
if (str_equal(action, "start")) {
|
||||||
acts = "u";
|
acts = "u";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!str_diff(action, "stop")) {
|
if (str_equal(action, "stop")) {
|
||||||
acts = "d";
|
acts = "d";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -496,34 +494,34 @@ int sv_main(int argc, char **argv)
|
|||||||
cbk = NULL;
|
cbk = NULL;
|
||||||
break;
|
break;
|
||||||
case 'r':
|
case 'r':
|
||||||
if (!str_diff(action, "restart")) {
|
if (str_equal(action, "restart")) {
|
||||||
acts = "tcu";
|
acts = "tcu";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
usage();
|
bb_show_usage();
|
||||||
case 'f':
|
case 'f':
|
||||||
if (!str_diff(action, "force-reload")) {
|
if (str_equal(action, "force-reload")) {
|
||||||
acts = "tc";
|
acts = "tc";
|
||||||
kll = 1;
|
kll = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!str_diff(action, "force-restart")) {
|
if (str_equal(action, "force-restart")) {
|
||||||
acts = "tcu";
|
acts = "tcu";
|
||||||
kll = 1;
|
kll = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!str_diff(action, "force-shutdown")) {
|
if (str_equal(action, "force-shutdown")) {
|
||||||
acts = "x";
|
acts = "x";
|
||||||
kll = 1;
|
kll = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!str_diff(action, "force-stop")) {
|
if (str_equal(action, "force-stop")) {
|
||||||
acts = "d";
|
acts = "d";
|
||||||
kll = 1;
|
kll = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
usage();
|
bb_show_usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
servicex = service;
|
servicex = service;
|
||||||
@ -547,11 +545,9 @@ int sv_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cbk) while (1) {
|
if (cbk) while (1) {
|
||||||
//struct taia tdiff;
|
int diff;
|
||||||
long diff;
|
|
||||||
|
|
||||||
//taia_sub(&tdiff, &tnow, &tstart);
|
diff = tnow - tstart;
|
||||||
diff = tnow.sec.x - tstart.sec.x;
|
|
||||||
service = servicex;
|
service = servicex;
|
||||||
want_exit = 1;
|
want_exit = 1;
|
||||||
for (i = 0; i < services; ++i, ++service) {
|
for (i = 0; i < services; ++i, ++service) {
|
||||||
@ -586,7 +582,7 @@ int sv_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
if (want_exit) break;
|
if (want_exit) break;
|
||||||
usleep(420000);
|
usleep(420000);
|
||||||
taia_now(&tnow);
|
tnow = time(0) + 0x400000000000000aULL;
|
||||||
}
|
}
|
||||||
return rc > 99 ? 99 : rc;
|
return rc > 99 ? 99 : rc;
|
||||||
}
|
}
|
||||||
|
198
runit/svlogd.c
198
runit/svlogd.c
@ -33,6 +33,10 @@ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libbb.h"
|
#include "libbb.h"
|
||||||
#include "runit_lib.h"
|
#include "runit_lib.h"
|
||||||
|
|
||||||
|
#define LESS(a,b) ((int)((unsigned)(b) - (unsigned)(a)) > 0)
|
||||||
|
|
||||||
|
#define FMT_PTIME 30
|
||||||
|
|
||||||
static unsigned verbose;
|
static unsigned verbose;
|
||||||
static int linemax = 1000;
|
static int linemax = 1000;
|
||||||
////static int buflen = 1024;
|
////static int buflen = 1024;
|
||||||
@ -41,7 +45,7 @@ static int linelen;
|
|||||||
static char **fndir;
|
static char **fndir;
|
||||||
static int fdwdir;
|
static int fdwdir;
|
||||||
static int wstat;
|
static int wstat;
|
||||||
static struct taia trotate;
|
static unsigned nearest_rotate;
|
||||||
|
|
||||||
static char *line;
|
static char *line;
|
||||||
static smallint exitasap;
|
static smallint exitasap;
|
||||||
@ -55,7 +59,6 @@ static char repl;
|
|||||||
static const char *replace = "";
|
static const char *replace = "";
|
||||||
|
|
||||||
static sigset_t *blocked_sigset;
|
static sigset_t *blocked_sigset;
|
||||||
static iopause_fd input;
|
|
||||||
static int fl_flag_0;
|
static int fl_flag_0;
|
||||||
|
|
||||||
static struct logdir {
|
static struct logdir {
|
||||||
@ -68,14 +71,13 @@ static struct logdir {
|
|||||||
unsigned sizemax;
|
unsigned sizemax;
|
||||||
unsigned nmax;
|
unsigned nmax;
|
||||||
unsigned nmin;
|
unsigned nmin;
|
||||||
/* int (not long) because of taia_uint() usage: */
|
unsigned rotate_period;
|
||||||
unsigned tmax;
|
|
||||||
int ppid;
|
int ppid;
|
||||||
int fddir;
|
int fddir;
|
||||||
int fdcur;
|
int fdcur;
|
||||||
FILE* filecur; ////
|
FILE* filecur; ////
|
||||||
int fdlock;
|
int fdlock;
|
||||||
struct taia trotate;
|
unsigned next_rotate;
|
||||||
char fnsave[FMT_PTIME];
|
char fnsave[FMT_PTIME];
|
||||||
char match;
|
char match;
|
||||||
char matcherr;
|
char matcherr;
|
||||||
@ -128,6 +130,50 @@ static char* wstrdup(const char *str)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** ex fmt_ptime.[ch] ***/
|
||||||
|
|
||||||
|
/* NUL terminated */
|
||||||
|
static void fmt_time_human_30nul(char *s)
|
||||||
|
{
|
||||||
|
struct tm *t;
|
||||||
|
struct timeval tv;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
t = gmtime(&(tv.tv_sec));
|
||||||
|
sprintf(s, "%04u-%02u-%02u_%02u:%02u:%02u.%06u000",
|
||||||
|
(unsigned)(1900 + t->tm_year),
|
||||||
|
(unsigned)(t->tm_mon + 1),
|
||||||
|
(unsigned)(t->tm_mday),
|
||||||
|
(unsigned)(t->tm_hour),
|
||||||
|
(unsigned)(t->tm_min),
|
||||||
|
(unsigned)(t->tm_sec),
|
||||||
|
(unsigned)(tv.tv_usec)
|
||||||
|
);
|
||||||
|
/* 4+1 + 2+1 + 2+1 + 2+1 + 2+1 + 2+1 + 9 = */
|
||||||
|
/* 5 + 3 + 3 + 3 + 3 + 3 + 9 = */
|
||||||
|
/* 20 (up to '.' inclusive) + 9 (not including '\0') */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* NOT terminated! */
|
||||||
|
static void fmt_time_bernstein_25(char *s)
|
||||||
|
{
|
||||||
|
uint32_t pack[3];
|
||||||
|
struct timeval tv;
|
||||||
|
unsigned sec_hi;
|
||||||
|
|
||||||
|
gettimeofday(&tv, NULL);
|
||||||
|
sec_hi = (0x400000000000000aULL + tv.tv_sec) >> 32;
|
||||||
|
tv.tv_sec = (time_t)(0x400000000000000aULL) + tv.tv_sec;
|
||||||
|
tv.tv_usec *= 1000;
|
||||||
|
/* Network order is big-endian: most significant byte first.
|
||||||
|
* This is exactly what we want here */
|
||||||
|
pack[0] = htonl(sec_hi);
|
||||||
|
pack[1] = htonl(tv.tv_sec);
|
||||||
|
pack[2] = htonl(tv.tv_usec);
|
||||||
|
*s++ = '@';
|
||||||
|
bin2hex(s, (char*)pack, 12);
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned processorstart(struct logdir *ld)
|
static unsigned processorstart(struct logdir *ld)
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
@ -264,15 +310,15 @@ static void rmoldest(struct logdir *ld)
|
|||||||
static unsigned rotate(struct logdir *ld)
|
static unsigned rotate(struct logdir *ld)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct taia now;
|
unsigned now;
|
||||||
|
|
||||||
if (ld->fddir == -1) {
|
if (ld->fddir == -1) {
|
||||||
ld->tmax = 0;
|
ld->rotate_period = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ld->ppid)
|
if (ld->ppid)
|
||||||
while (!processorstop(ld))
|
while (!processorstop(ld))
|
||||||
/* wait */;
|
continue;
|
||||||
|
|
||||||
while (fchdir(ld->fddir) == -1)
|
while (fchdir(ld->fddir) == -1)
|
||||||
pause2cannot("change directory, want rotate", ld->name);
|
pause2cannot("change directory, want rotate", ld->name);
|
||||||
@ -284,17 +330,16 @@ static unsigned rotate(struct logdir *ld)
|
|||||||
ld->fnsave[26] = 'u';
|
ld->fnsave[26] = 'u';
|
||||||
ld->fnsave[27] = '\0';
|
ld->fnsave[27] = '\0';
|
||||||
do {
|
do {
|
||||||
taia_now(&now);
|
fmt_time_bernstein_25(ld->fnsave);
|
||||||
fmt_taia25(ld->fnsave, &now);
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
stat(ld->fnsave, &st);
|
stat(ld->fnsave, &st);
|
||||||
} while (errno != ENOENT);
|
} while (errno != ENOENT);
|
||||||
|
|
||||||
if (ld->tmax && taia_less(&ld->trotate, &now)) {
|
now = monotonic_sec();
|
||||||
taia_uint(&ld->trotate, ld->tmax);
|
if (ld->rotate_period && LESS(ld->next_rotate, now)) {
|
||||||
taia_add(&ld->trotate, &now, &ld->trotate);
|
ld->next_rotate = now + ld->rotate_period;
|
||||||
if (taia_less(&ld->trotate, &trotate))
|
if (LESS(ld->next_rotate, nearest_rotate))
|
||||||
trotate = ld->trotate;
|
nearest_rotate = ld->next_rotate;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ld->size > 0) {
|
if (ld->size > 0) {
|
||||||
@ -425,11 +470,13 @@ static void logdir_close(struct logdir *ld)
|
|||||||
static unsigned logdir_open(struct logdir *ld, const char *fn)
|
static unsigned logdir_open(struct logdir *ld, const char *fn)
|
||||||
{
|
{
|
||||||
char buf[128];
|
char buf[128];
|
||||||
struct taia now;
|
unsigned now;
|
||||||
char *new, *s, *np;
|
char *new, *s, *np;
|
||||||
int i;
|
int i;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
now = monotonic_sec();
|
||||||
|
|
||||||
ld->fddir = open(fn, O_RDONLY|O_NDELAY);
|
ld->fddir = open(fn, O_RDONLY|O_NDELAY);
|
||||||
if (ld->fddir == -1) {
|
if (ld->fddir == -1) {
|
||||||
warn2("cannot open log directory", (char*)fn);
|
warn2("cannot open log directory", (char*)fn);
|
||||||
@ -456,7 +503,7 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
ld->size = 0;
|
ld->size = 0;
|
||||||
ld->sizemax = 1000000;
|
ld->sizemax = 1000000;
|
||||||
ld->nmax = ld->nmin = 10;
|
ld->nmax = ld->nmin = 10;
|
||||||
ld->tmax = 0;
|
ld->rotate_period = 0;
|
||||||
ld->name = (char*)fn;
|
ld->name = (char*)fn;
|
||||||
ld->ppid = 0;
|
ld->ppid = 0;
|
||||||
ld->match = '+';
|
ld->match = '+';
|
||||||
@ -468,7 +515,8 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
if (i < 0 && errno != ENOENT)
|
if (i < 0 && errno != ENOENT)
|
||||||
bb_perror_msg(WARNING": %s/config", ld->name);
|
bb_perror_msg(WARNING": %s/config", ld->name);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
if (verbose) bb_error_msg(INFO"read: %s/config", ld->name);
|
if (verbose)
|
||||||
|
bb_error_msg(INFO"read: %s/config", ld->name);
|
||||||
s = buf;
|
s = buf;
|
||||||
while (s) {
|
while (s) {
|
||||||
np = strchr(s, '\n');
|
np = strchr(s, '\n');
|
||||||
@ -508,12 +556,11 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
/*{ "d", 24*60*60 },*/
|
/*{ "d", 24*60*60 },*/
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
ld->tmax = xatou_sfx(&s[1], mh_suffixes);
|
ld->rotate_period = xatou_sfx(&s[1], mh_suffixes);
|
||||||
if (ld->tmax) {
|
if (ld->rotate_period) {
|
||||||
taia_uint(&ld->trotate, ld->tmax);
|
ld->next_rotate = now + ld->rotate_period;
|
||||||
taia_add(&ld->trotate, &now, &ld->trotate);
|
if (!tmaxflag || LESS(ld->next_rotate, nearest_rotate))
|
||||||
if (!tmaxflag || taia_less(&ld->trotate, &trotate))
|
nearest_rotate = ld->next_rotate;
|
||||||
trotate = ld->trotate;
|
|
||||||
tmaxflag = 1;
|
tmaxflag = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -544,8 +591,7 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
ld->fnsave[26] = 'u';
|
ld->fnsave[26] = 'u';
|
||||||
ld->fnsave[27] = '\0';
|
ld->fnsave[27] = '\0';
|
||||||
do {
|
do {
|
||||||
taia_now(&now);
|
fmt_time_bernstein_25(ld->fnsave);
|
||||||
fmt_taia25(ld->fnsave, &now);
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
stat(ld->fnsave, &st);
|
stat(ld->fnsave, &st);
|
||||||
} while (errno != ENOENT);
|
} while (errno != ENOENT);
|
||||||
@ -589,17 +635,17 @@ static unsigned logdir_open(struct logdir *ld, const char *fn)
|
|||||||
|
|
||||||
static void logdirs_reopen(void)
|
static void logdirs_reopen(void)
|
||||||
{
|
{
|
||||||
struct taia now;
|
|
||||||
int l;
|
int l;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
|
|
||||||
tmaxflag = 0;
|
tmaxflag = 0;
|
||||||
taia_now(&now);
|
|
||||||
for (l = 0; l < dirn; ++l) {
|
for (l = 0; l < dirn; ++l) {
|
||||||
logdir_close(&dir[l]);
|
logdir_close(&dir[l]);
|
||||||
if (logdir_open(&dir[l], fndir[l])) ok = 1;
|
if (logdir_open(&dir[l], fndir[l]))
|
||||||
|
ok = 1;
|
||||||
}
|
}
|
||||||
if (!ok) fatalx("no functional log directories");
|
if (!ok)
|
||||||
|
fatalx("no functional log directories");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Will look good in libbb one day */
|
/* Will look good in libbb one day */
|
||||||
@ -614,42 +660,55 @@ static ssize_t ndelay_read(int fd, void *buf, size_t count)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Used for reading stdin */
|
/* Used for reading stdin */
|
||||||
static int buffer_pread(int fd, char *s, unsigned len, struct taia *now)
|
static int buffer_pread(int fd, char *s, unsigned len)
|
||||||
{
|
{
|
||||||
|
unsigned now;
|
||||||
|
struct pollfd input;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (rotateasap) {
|
input.fd = 0;
|
||||||
for (i = 0; i < dirn; ++i)
|
input.events = POLLIN|POLLHUP|POLLERR;
|
||||||
rotate(dir+i);
|
|
||||||
rotateasap = 0;
|
|
||||||
}
|
|
||||||
if (exitasap) {
|
|
||||||
if (linecomplete)
|
|
||||||
return 0;
|
|
||||||
len = 1;
|
|
||||||
}
|
|
||||||
if (reopenasap) {
|
|
||||||
logdirs_reopen();
|
|
||||||
reopenasap = 0;
|
|
||||||
}
|
|
||||||
taia_uint(&trotate, 2744);
|
|
||||||
taia_add(&trotate, now, &trotate);
|
|
||||||
for (i = 0; i < dirn; ++i)
|
|
||||||
if (dir[i].tmax) {
|
|
||||||
if (taia_less(&dir[i].trotate, now))
|
|
||||||
rotate(dir+i);
|
|
||||||
if (taia_less(&dir[i].trotate, &trotate))
|
|
||||||
trotate = dir[i].trotate;
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
if (rotateasap) {
|
||||||
|
for (i = 0; i < dirn; ++i)
|
||||||
|
rotate(dir + i);
|
||||||
|
rotateasap = 0;
|
||||||
|
}
|
||||||
|
if (exitasap) {
|
||||||
|
if (linecomplete)
|
||||||
|
return 0;
|
||||||
|
len = 1;
|
||||||
|
}
|
||||||
|
if (reopenasap) {
|
||||||
|
logdirs_reopen();
|
||||||
|
reopenasap = 0;
|
||||||
|
}
|
||||||
|
now = monotonic_sec();
|
||||||
|
nearest_rotate = now + (45 * 60 + 45);
|
||||||
|
for (i = 0; i < dirn; ++i) {
|
||||||
|
if (dir[i].rotate_period) {
|
||||||
|
if (LESS(dir[i].next_rotate, now))
|
||||||
|
rotate(dir + i);
|
||||||
|
if (LESS(dir[i].next_rotate, nearest_rotate))
|
||||||
|
nearest_rotate = dir[i].next_rotate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sigprocmask(SIG_UNBLOCK, blocked_sigset, NULL);
|
sigprocmask(SIG_UNBLOCK, blocked_sigset, NULL);
|
||||||
iopause(&input, 1, &trotate, now);
|
i = nearest_rotate - now;
|
||||||
// TODO: do not unblock/block, but use sigpending after iopause
|
if (i > 1000000)
|
||||||
// to see whether there was any sig? (one syscall less...)
|
i = 1000000;
|
||||||
|
if (i <= 0)
|
||||||
|
i = 1;
|
||||||
|
poll(&input, 1, i * 1000);
|
||||||
sigprocmask(SIG_BLOCK, blocked_sigset, NULL);
|
sigprocmask(SIG_BLOCK, blocked_sigset, NULL);
|
||||||
|
|
||||||
i = ndelay_read(fd, s, len);
|
i = ndelay_read(fd, s, len);
|
||||||
if (i >= 0) break;
|
if (i >= 0)
|
||||||
|
break;
|
||||||
|
if (errno == EINTR)
|
||||||
|
continue;
|
||||||
if (errno != EAGAIN) {
|
if (errno != EAGAIN) {
|
||||||
warn("cannot read standard input");
|
warn("cannot read standard input");
|
||||||
break;
|
break;
|
||||||
@ -660,7 +719,8 @@ static int buffer_pread(int fd, char *s, unsigned len, struct taia *now)
|
|||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
int cnt;
|
int cnt;
|
||||||
linecomplete = (s[i-1] == '\n');
|
linecomplete = (s[i-1] == '\n');
|
||||||
if (!repl) return i;
|
if (!repl)
|
||||||
|
return i;
|
||||||
|
|
||||||
cnt = i;
|
cnt = i;
|
||||||
while (--cnt >= 0) {
|
while (--cnt >= 0) {
|
||||||
@ -698,13 +758,15 @@ static void sig_child_handler(int sig_no)
|
|||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
bb_error_msg(INFO"sig%s received", "child");
|
bb_error_msg(INFO"sig%s received", "child");
|
||||||
while ((pid = wait_nohang(&wstat)) > 0)
|
while ((pid = wait_nohang(&wstat)) > 0) {
|
||||||
for (l = 0; l < dirn; ++l)
|
for (l = 0; l < dirn; ++l) {
|
||||||
if (dir[l].ppid == pid) {
|
if (dir[l].ppid == pid) {
|
||||||
dir[l].ppid = 0;
|
dir[l].ppid = 0;
|
||||||
processorstop(&dir[l]);
|
processorstop(&dir[l]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void sig_alarm_handler(int sig_no)
|
static void sig_alarm_handler(int sig_no)
|
||||||
@ -795,8 +857,6 @@ int svlogd_main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
/* line = xmalloc(linemax + (timestamp ? 26 : 0)); */
|
/* line = xmalloc(linemax + (timestamp ? 26 : 0)); */
|
||||||
fndir = argv;
|
fndir = argv;
|
||||||
input.fd = 0;
|
|
||||||
input.events = IOPAUSE_READ;
|
|
||||||
/* We cannot set NONBLOCK on fd #0 permanently - this setting
|
/* We cannot set NONBLOCK on fd #0 permanently - this setting
|
||||||
* _isn't_ per-process! It is shared among all other processes
|
* _isn't_ per-process! It is shared among all other processes
|
||||||
* with the same stdin */
|
* with the same stdin */
|
||||||
@ -826,7 +886,6 @@ int svlogd_main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Each iteration processes one or more lines */
|
/* Each iteration processes one or more lines */
|
||||||
while (1) {
|
while (1) {
|
||||||
struct taia now;
|
|
||||||
char stamp[FMT_PTIME];
|
char stamp[FMT_PTIME];
|
||||||
char *lineptr;
|
char *lineptr;
|
||||||
char *printptr;
|
char *printptr;
|
||||||
@ -846,8 +905,7 @@ int svlogd_main(int argc, char **argv)
|
|||||||
if (!np && !exitasap) {
|
if (!np && !exitasap) {
|
||||||
i = linemax - stdin_cnt; /* avail. bytes at tail */
|
i = linemax - stdin_cnt; /* avail. bytes at tail */
|
||||||
if (i >= 128) {
|
if (i >= 128) {
|
||||||
taia_now(&now);
|
i = buffer_pread(0, lineptr + stdin_cnt, i);
|
||||||
i = buffer_pread(0, lineptr + stdin_cnt, i, &now);
|
|
||||||
if (i <= 0) /* EOF or error on stdin */
|
if (i <= 0) /* EOF or error on stdin */
|
||||||
exitasap = 1;
|
exitasap = 1;
|
||||||
else {
|
else {
|
||||||
@ -879,11 +937,10 @@ int svlogd_main(int argc, char **argv)
|
|||||||
printlen = linelen;
|
printlen = linelen;
|
||||||
printptr = lineptr;
|
printptr = lineptr;
|
||||||
if (timestamp) {
|
if (timestamp) {
|
||||||
taia_now(&now);
|
|
||||||
if (timestamp == 1)
|
if (timestamp == 1)
|
||||||
fmt_taia25(stamp, &now);
|
fmt_time_bernstein_25(stamp);
|
||||||
else /* 2: */
|
else /* 2: */
|
||||||
fmt_ptime30nul(stamp, &now);
|
fmt_time_human_30nul(stamp);
|
||||||
printlen += 26;
|
printlen += 26;
|
||||||
printptr -= 26;
|
printptr -= 26;
|
||||||
memcpy(printptr, stamp, 25);
|
memcpy(printptr, stamp, 25);
|
||||||
@ -905,8 +962,7 @@ int svlogd_main(int argc, char **argv)
|
|||||||
/* read/write repeatedly until we see it */
|
/* read/write repeatedly until we see it */
|
||||||
while (ch != '\n') {
|
while (ch != '\n') {
|
||||||
/* lineptr is emptied now, safe to use as buffer */
|
/* lineptr is emptied now, safe to use as buffer */
|
||||||
taia_now(&now);
|
stdin_cnt = exitasap ? -1 : buffer_pread(0, lineptr, linemax);
|
||||||
stdin_cnt = exitasap ? -1 : buffer_pread(0, lineptr, linemax, &now);
|
|
||||||
if (stdin_cnt <= 0) { /* EOF or error on stdin */
|
if (stdin_cnt <= 0) { /* EOF or error on stdin */
|
||||||
exitasap = 1;
|
exitasap = 1;
|
||||||
lineptr[0] = ch = '\n';
|
lineptr[0] = ch = '\n';
|
||||||
|
Loading…
Reference in New Issue
Block a user