Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
6
66
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Eric Vidal
66
Commits
16a7c6b6
Commit
16a7c6b6
authored
3 years ago
by
Eric Vidal
Browse files
Options
Downloads
Patches
Plain Diff
revamp the dependencies waiting process passing through a named pipe
parent
0c89833e
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/include/66/constants.h
+3
-0
3 additions, 0 deletions
src/include/66/constants.h
src/lib66/exec/ssexec_all.c
+296
-144
296 additions, 144 deletions
src/lib66/exec/ssexec_all.c
with
299 additions
and
144 deletions
src/include/66/constants.h
+
3
−
0
View file @
16a7c6b6
...
...
@@ -96,6 +96,9 @@
#define SS_SYM_VERSION_LEN (sizeof SS_SYM_VERSION - 1)
#define SS_CONFIG_VERSION_NDOT 2
#define SS_EVENTDIR "/event"
#define SS_EVENTDIR_LEN (sizeof SS_EVENTDIR - 1)
/** boot */
#define SS_BOOT_CONF "init.conf"
#define SS_BOOT_CONF_LEN (sizeof SS_BOOT_CONF - 1)
...
...
This diff is collapsed.
Click to expand it.
src/lib66/exec/ssexec_all.c
+
296
−
144
View file @
16a7c6b6
...
...
@@ -18,8 +18,8 @@
#include
<unistd.h>
//dup2,setsid,chdir,fork
#include
<sys/ioctl.h>
#include
<stdint.h>
//uint8_t
#include
<stddef.h>
//size_t
#include
<stdlib.h>
//realpath
#include
<string.h>
//strdup
#include
<oblibs/string.h>
#include
<oblibs/types.h>
...
...
@@ -28,6 +28,7 @@
#include
<oblibs/obgetopt.h>
#include
<oblibs/files.h>
#include
<oblibs/graph.h>
#include
<oblibs/directory.h>
#include
<skalibs/types.h>
#include
<skalibs/stralloc.h>
...
...
@@ -35,6 +36,7 @@
#include
<skalibs/posixplz.h>
#include
<skalibs/tai.h>
#include
<skalibs/selfpipe.h>
#include
<skalibs/sig.h>
#include
<skalibs/iopause.h>
#include
<66/ssexec.h>
...
...
@@ -45,15 +47,16 @@
#include
<66/graph.h>
#include
<s6-rc/s6rc-servicedir.h>
#include
<s6/ftrigr.h>
#include
<s6/ftrigw.h>
#define FLAGS_STARTING 1 // starting not really up
#define FLAGS_STOPPING 2 // stopping not really down
#define FLAGS_UP 3 // really up
#define FLAGS_DOWN 4 // really down
#define FLAGS_BLOCK 5 // all deps are not up/down
#define FLAGS_UNBLOCK 6 // all deps up/down
#define FLAGS_FATAL 7 // process crashed
#define FLAGS_EXITED 8 // process exited
#define FLAGS_STARTING 1 // 1 starting not really up
#define FLAGS_STOPPING (1 << 1) // 2 stopping not really down
#define FLAGS_UP (1 << 2) // 4 really up
#define FLAGS_DOWN (1 << 3) // 8 really down
#define FLAGS_BLOCK (1 << 4) // 16 all deps are not up/down
#define FLAGS_UNBLOCK (1 << 5) // 32 all deps up/down
#define FLAGS_FATAL (1 << 6) // 64 process crashed
/** return 1 if set, else 0*/
#define FLAGS_ISSET(has, want) \
...
...
@@ -63,21 +66,71 @@ typedef struct pidvertex_s pidvertex_t, *pidvertex_t_ref ;
struct
pidvertex_s
{
pid_t
pid
;
int
pipe
[
2
]
;
uint16_t
ids
;
char
*
eventdir
;
unsigned
int
vertex
;
// id at graph_hash_t struct
uint8_t
state
;
int
nedge
;
unsigned
int
*
edge
;
// array of id at graph_hash_t struct
}
;
#define PIDINDEX_ZERO { 0, { 0, 0 }, 0, 0, 0, 0 }
#define PIDINDEX_ZERO { 0, 0, 0, 0, 0, 0 }
typedef
enum
fifo_e
fifo_t
,
*
fifo_t_ref
;
enum
fifo_e
{
FIFO_u
=
0
,
FIFO_U
,
FIFO_d
,
FIFO_D
,
FIFO_F
,
FIFO_b
,
FIFO_B
}
;
typedef
enum
tree_action_e
tree_action_t
,
*
tree_action_t_ref
;
enum
tree_action_e
{
GOTIT
=
0
,
WAIT
,
FATAL
,
UNKNOWN
}
;
static
const
unsigned
char
actions
[
2
][
7
]
=
{
// u U d D F b B
{
WAIT
,
GOTIT
,
UNKNOWN
,
UNKNOWN
,
FATAL
,
WAIT
,
GOTIT
},
// !what -> up
{
UNKNOWN
,
UNKNOWN
,
WAIT
,
GOTIT
,
FATAL
,
WAIT
,
GOTIT
}
// what -> down
}
;
// convert signal receive into enum number
static
const
unsigned
int
char2enum
[
128
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//8
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//16
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//24
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//32
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//40
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//48
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//56
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//64
0
,
0
,
FIFO_B
,
0
,
FIFO_D
,
0
,
FIFO_F
,
0
,
//72
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//80
0
,
0
,
0
,
0
,
0
,
FIFO_U
,
0
,
0
,
//88
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//96
0
,
0
,
FIFO_b
,
0
,
FIFO_d
,
0
,
0
,
0
,
//104
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
//112
0
,
0
,
0
,
0
,
0
,
FIFO_u
,
0
,
0
,
//120
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
//128
}
;
static
pidvertex_t
*
apidvertex
;
static
unsigned
int
napid
=
0
;
static
unsigned
int
npid
=
0
;
static
ftrigr_t
FIFO
=
FTRIGR_ZERO
;
static
int
flag
;
static
int
flag_run
;
static
void
async
(
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
)
;
static
int
async
(
pidvertex_t
*
apidv
,
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
,
tain
*
deadline
)
;
static
int
unsupervise
(
ssexec_t
*
info
,
int
what
)
;
static
inline
unsigned
int
lookup
(
char
const
*
const
*
table
,
char
const
*
signal
)
...
...
@@ -135,7 +188,7 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
{
log_flow
()
;
int
r
,
e
=
1
;
int
r
,
e
=
0
;
{
info
->
treename
.
len
=
0
;
...
...
@@ -150,14 +203,14 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
r
=
tree_sethome
(
info
)
;
if
(
r
<=
0
)
log_warnu_return
(
LOG_EXIT_
ONE
,
"find tree: "
,
info
->
treename
.
s
)
;
log_warnu_return
(
LOG_EXIT_
ZERO
,
"find tree: "
,
info
->
treename
.
s
)
;
if
(
!
tree_get_permissions
(
info
->
tree
.
s
,
info
->
owner
))
log_warn_return
(
LOG_EXIT_
ONE
,
"You're not allowed to use the tree: "
,
info
->
tree
.
s
)
;
log_warn_return
(
LOG_EXIT_
ZERO
,
"You're not allowed to use the tree: "
,
info
->
tree
.
s
)
;
}
if
(
!
tree_isinitialized
(
info
->
base
.
s
,
info
->
treename
.
s
))
{
if
(
!
tree_isinitialized
(
info
->
base
.
s
,
info
->
treename
.
s
)
&&
!
what
)
{
if
(
!
what
)
{
...
...
@@ -170,11 +223,11 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
newargv
[
m
++
]
=
0
;
if
(
ssexec_init
(
nargc
,
newargv
,
(
char
const
*
const
*
)
environ
,
info
))
log_warnu_return
(
LOG_EXIT_
ONE
,
"initiate services of tree: "
,
info
->
treename
.
s
)
;
log_warnu_return
(
LOG_EXIT_
ZERO
,
"initiate services of tree: "
,
info
->
treename
.
s
)
;
log_trace
(
"reload scandir: "
,
info
->
scandir
.
s
)
;
if
(
scandir_send_signal
(
info
->
scandir
.
s
,
"h"
)
<=
0
)
log_warnu_return
(
LOG_EXIT_
ONE
,
"reload scandir: "
,
info
->
scandir
.
s
)
;
log_warnu_return
(
LOG_EXIT_
ZERO
,
"reload scandir: "
,
info
->
scandir
.
s
)
;
}
else
{
...
...
@@ -182,12 +235,6 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
goto
end
;
}
}
/** tree can be empty
* In this case ssexec_init do not crash but the
* /run/66/state/<owner>/<treename> doesn't exit.
* So check it again */
if
(
!
tree_isinitialized
(
info
->
base
.
s
,
info
->
treename
.
s
))
goto
end
;
if
(
what
==
2
)
{
...
...
@@ -205,7 +252,7 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
char
src
[
info
->
live
.
len
+
SS_STATE_LEN
+
1
+
ownerlen
+
1
+
info
->
treename
.
len
+
1
]
;
auto_strings
(
src
,
info
->
live
.
s
,
SS_STATE
,
"/"
,
ownerstr
,
"/"
,
info
->
treename
.
s
)
;
auto_strings
(
src
,
info
->
live
.
s
,
SS_STATE
+
1
,
"/"
,
ownerstr
,
"/"
,
info
->
treename
.
s
)
;
if
(
!
sastr_dir_get
(
&
salist
,
src
,
exclude
,
S_IFREG
))
log_warnusys_return
(
LOG_EXIT_ONE
,
"get contents of directory: "
,
src
)
;
...
...
@@ -244,7 +291,7 @@ static int doit(ssexec_t *info, char const *treename, unsigned int what)
}
end:
e
=
0
;
e
=
1
;
err:
return
e
;
}
...
...
@@ -321,6 +368,34 @@ static int unsupervise(ssexec_t *info, int what)
return
0
;
}
static
inline
void
kill_all
(
pidvertex_t
*
apidv
)
{
log_flow
()
;
unsigned
int
j
=
npid
;
while
(
j
--
)
kill
(
apidv
[
j
].
pid
,
SIGKILL
)
;
}
static
void
announce
(
pidvertex_t
*
apidv
,
unsigned
int
i
,
unsigned
int
what
,
unsigned
int
success
,
graph_t
*
graph
,
ssexec_t
*
info
)
{
log_flow
()
;
resolve_tree_t
tres
=
RESOLVE_TREE_ZERO
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_TREE
,
&
tres
)
;
char
*
treename
=
graph
->
data
.
s
+
genalloc_s
(
graph_hash_t
,
&
graph
->
hash
)[
apidv
[
i
].
vertex
].
vertex
;
if
(
!
resolve_modify_field_g
(
wres
,
info
->
base
.
s
,
treename
,
TREE_ENUM_INIT
,
what
?
(
success
?
"1"
:
"0"
)
:
(
success
?
"0"
:
"1"
)))
log_dieusys
(
LOG_EXIT_SYS
,
"modify resolve file of: "
,
treename
)
;
resolve_free
(
wres
)
;
log_trace
(
"sends notification "
,
!
success
?
(
what
?
"D"
:
"U"
)
:
"F"
,
" to : "
,
apidv
[
i
].
eventdir
)
;
if
(
ftrigw_notify
(
apidv
[
i
].
eventdir
,
!
success
?
(
what
?
'D'
:
'U'
)
:
'F'
)
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"notifies event directory: "
,
apidv
[
i
].
eventdir
)
;
}
static
pidvertex_t
pidvertex_init
(
unsigned
int
len
)
{
log_flow
()
;
...
...
@@ -336,7 +411,10 @@ static pidvertex_t pidvertex_init(unsigned int len)
static
void
pidvertex_free
(
pidvertex_t
*
pidv
)
{
log_flow
()
;
free
(
pidv
->
edge
)
;
free
(
pidv
->
eventdir
)
;
}
static
void
pidvertex_array_free
(
pidvertex_t
*
apidv
,
unsigned
int
len
)
...
...
@@ -349,19 +427,31 @@ static void pidvertex_array_free(pidvertex_t *apidv, unsigned int len)
pidvertex_free
(
&
apidv
[
pos
])
;
}
static
void
pidvertex_init_array
(
pidvertex_t
*
apidv
ertex
,
graph_t
*
g
,
unsigned
int
*
list
,
unsigned
int
count
,
ssexec_t
*
info
,
uint8_t
requiredby
)
static
void
pidvertex_init_array
(
pidvertex_t
*
apidv
,
graph_t
*
g
,
unsigned
int
*
list
,
unsigned
int
count
,
ssexec_t
*
info
,
uint8_t
requiredby
)
{
log_flow
()
;
int
r
=
-
1
;
size_t
pos
=
0
;
char
ownerstr
[
UID_FMT
]
;
size_t
ownerlen
=
uid_fmt
(
ownerstr
,
info
->
owner
)
;
ownerstr
[
ownerlen
]
=
0
;
for
(;
pos
<
count
;
pos
++
)
{
char
*
name
=
g
->
data
.
s
+
genalloc_s
(
graph_hash_t
,
&
g
->
hash
)[
list
[
pos
]].
vertex
;
size_t
eventlen
=
info
->
live
.
len
+
SS_STATE_LEN
+
1
+
ownerlen
+
1
+
strlen
(
name
)
+
SS_ENVDIR_LEN
;
char
event
[
eventlen
+
1
]
;
pidvertex_t
pidv
=
pidvertex_init
(
g
->
mlen
)
;
auto_strings
(
event
,
info
->
live
.
s
,
SS_STATE
+
1
,
"/"
,
ownerstr
,
"/"
,
name
,
SS_EVENTDIR
)
;
pidv
.
eventdir
=
strdup
(
event
)
;
pidv
.
nedge
=
graph_matrix_get_edge_g_sorted_list
(
pidv
.
edge
,
g
,
name
,
requiredby
)
;
if
(
pidv
.
nedge
<
0
)
...
...
@@ -382,10 +472,8 @@ static void pidvertex_init_array(pidvertex_t *apidvertex, graph_t *g, unsigned i
else
pidv
.
state
|=
FLAGS_DOWN
;
apidvertex
[
pos
]
=
pidv
;
apidv
[
pos
]
=
pidv
;
}
}
static
int
pidvertex_get_id
(
pidvertex_t
*
apidv
,
unsigned
int
id
)
...
...
@@ -401,15 +489,39 @@ static int pidvertex_get_id(pidvertex_t *apidv, unsigned int id)
return
-
1
;
}
static
inline
void
kill_all
(
void
)
static
void
pidvertex_init_fifo
(
pidvertex_t
*
apidv
,
graph_t
*
graph
,
tain
*
deadline
)
{
log_flow
()
;
unsigned
int
j
=
npid
;
while
(
j
--
)
kill
(
apidvertex
[
j
].
pid
,
SIGKILL
)
;
unsigned
int
pos
=
0
;
gid_t
gid
;
if
(
!
yourgid
(
&
gid
,
getuid
()))
log_dieusys
(
LOG_EXIT_SYS
,
"get gid"
)
;
if
(
!
ftrigr_startf_g
(
&
FIFO
,
deadline
))
log_dieusys
(
LOG_EXIT_SYS
,
"ftrigr_startf"
)
;
for
(;
pos
<
napid
;
pos
++
)
{
if
(
!
dir_create_parent
(
apidv
[
pos
].
eventdir
,
0700
))
log_dieusys
(
LOG_EXIT_SYS
,
"create directory: "
,
apidv
[
pos
].
eventdir
)
;
if
(
!
ftrigw_fifodir_make
(
apidv
[
pos
].
eventdir
,
gid
,
0
))
log_dieusys
(
LOG_EXIT_SYS
,
"make fifo directory: "
,
apidv
[
pos
].
eventdir
)
;
/** may already exist, cleans it */
if
(
!
ftrigw_clean
(
apidv
[
pos
].
eventdir
))
log_dieusys
(
LOG_EXIT_SYS
,
"clean fifo directory: "
,
apidv
[
pos
].
eventdir
)
;
apidv
[
pos
].
ids
=
ftrigr_subscribe_g
(
&
FIFO
,
apidv
[
pos
].
eventdir
,
"[uUdDFbB]"
,
FTRIGR_REPEAT
,
deadline
)
;
if
(
!
apidv
[
pos
].
ids
)
log_dieusys
(
LOG_EXIT_SYS
,
"subcribe to events for: "
,
apidv
[
pos
].
eventdir
)
;
}
}
static
int
handle_signal
(
pidvertex_t
*
apidv
,
unsigned
int
what
)
static
int
handle_signal
(
pidvertex_t
*
apidv
,
unsigned
int
what
,
graph_t
*
graph
,
ssexec_t
*
info
)
{
log_flow
()
;
...
...
@@ -420,13 +532,13 @@ static int handle_signal(pidvertex_t *apidv, unsigned int what)
int
s
=
selfpipe_read
()
;
switch
(
s
)
{
case
-
1
:
log_
warnusys_return
(
LOG_EXIT_
ZERO
,
"selfpipe_read"
)
;
case
-
1
:
log_
dieusys
(
LOG_EXIT_
SYS
,
"selfpipe_read"
)
;
case
0
:
return
ok
;
case
SIGCHLD
:
for
(;;)
{
unsigned
int
j
=
0
;
unsigned
int
pos
=
0
;
int
wstat
;
pid_t
r
=
wait_nohang
(
&
wstat
)
;
...
...
@@ -439,47 +551,31 @@ static int handle_signal(pidvertex_t *apidv, unsigned int what)
}
else
if
(
!
r
)
break
;
for
(;
j
<
napid
;
j
++
)
if
(
apidv
[
j
].
pid
==
r
)
break
;
if
(
j
<
napid
)
{
for
(;
pos
<
napid
;
pos
++
)
if
(
apidv
[
pos
].
pid
==
r
)
break
;
unsigned
int
i
=
j
;
if
(
pos
<
napid
)
{
if
(
!
WIFSIGNALED
(
wstat
)
&&
!
WEXITSTATUS
(
wstat
))
{
apidv
[
i
].
state
=
0
;
if
(
what
)
apidv
[
i
].
state
=
FLAGS_UP
;
else
apidv
[
i
].
state
=
FLAGS_DOWN
;
close
(
apidv
[
i
].
pipe
[
0
])
;
npid
--
;
announce
(
apidv
,
pos
,
what
,
0
,
graph
,
info
)
;
}
else
{
ok
=
0
;
apidv
[
i
].
state
=
0
;
if
(
what
)
apidv
[
i
].
state
=
FLAGS_DOWN
;
else
apidv
[
i
].
state
=
FLAGS_UP
;
close
(
apidv
[
i
].
pipe
[
0
])
;
npid
--
;
announce
(
apidv
,
pos
,
what
,
1
,
graph
,
info
)
;
}
npid
--
;
}
}
break
;
case
SIGTERM
:
case
SIGINT
:
log_
info
(
"received SIGINT, aborting
servic
e transition"
)
;
kill_all
()
;
log_
1_warn
(
"received SIGINT, aborting
tre
e transition"
)
;
kill_all
(
apidv
)
;
break
;
default
:
log_die
(
LOG_EXIT_SYS
,
"unexpected data in selfpipe"
)
;
}
...
...
@@ -488,120 +584,182 @@ static int handle_signal(pidvertex_t *apidv, unsigned int what)
return
ok
;
}
static
int
async_deps
(
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
)
static
int
async_deps
(
pidvertex_t
*
apidv
,
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
,
tain
*
deadline
)
{
log_flow
()
;
int
e
=
0
;
int
e
=
0
,
r
;
unsigned
int
pos
=
0
;
char
trigger
=
0
;
while
(
apidvertex
[
i
].
nedge
)
{
iopause_fd
x
=
{
.
fd
=
ftrigr_fd
(
&
FIFO
),
.
events
=
IOPAUSE_READ
}
;
stralloc
sa
=
STRALLOC_ZERO
;
while
(
apidv
[
i
].
nedge
)
{
/** TODO: the pidvertex_get_id() function make a loop
* through the apidv
ertex
array to find the corresponding
* index of the edge at the apidv
ertex
array.
* This is clearly a waste of time and
need to
be optimized. */
unsigned
int
id
=
pidvertex_get_id
(
apidv
ertex
,
apidv
ertex
[
i
].
edge
[
pos
])
;
* through the apidv array to find the corresponding
* index of the edge at the apidv array.
* This is clearly a waste of time and
should
be optimized. */
unsigned
int
id
=
pidvertex_get_id
(
apidv
,
apidv
[
i
].
edge
[
pos
])
;
if
(
id
<
0
)
log_dieu
(
LOG_EXIT_SYS
,
"get apidvertex id -- please make a bug report"
)
;
/** block until we receive a signal from the dependencies
* which is launched first */
fd_read
(
apidvertex
[
id
].
pipe
[
0
],
(
char
*
)
&
trigger
,
1
)
;
close
(
apidvertex
[
id
].
pipe
[
0
])
;
r
=
iopause_g
(
&
x
,
1
,
deadline
)
;
if
(
r
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"iopause"
)
;
if
(
!
r
)
log_die
(
LOG_EXIT_SYS
,
"time out"
)
;
if
(
x
.
revents
&
IOPAUSE_READ
)
{
if
(
trigger
)
{
if
(
ftrigr_update
(
&
FIFO
)
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"ftrigr_update"
)
;
if
(
trigger
==
(
what
?
'd'
:
'u'
))
async
(
id
,
what
,
info
,
graph
)
;
else
goto
err
;
}
for
(
pos
=
0
;
pos
<
napid
;
pos
++
)
{
sa
.
len
=
0
;
r
=
ftrigr_checksa
(
&
FIFO
,
apidv
[
pos
].
ids
,
&
sa
)
;
if
(
r
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"ftrigr_check"
)
;
else
if
(
r
)
{
size_t
l
=
0
;
for
(;
l
<
sa
.
len
;
l
++
)
{
apidvertex
[
i
].
nedge
--
;
unsigned
int
p
=
char2enum
[(
unsigned
int
)
sa
.
s
[
l
]]
;
unsigned
char
action
=
actions
[
what
][
p
]
;
switch
(
action
)
{
case
GOTIT
:
apidv
[
pos
].
state
=
0
;
apidv
[
pos
].
state
=
(
!
what
?
FLAGS_UP
:
FLAGS_DOWN
)
;
goto
next
;
case
FATAL
:
apidv
[
pos
].
state
=
0
;
apidv
[
pos
].
state
=
FLAGS_FATAL
;
goto
err
;
case
WAIT
:
break
;
case
UNKNOWN
:
default:
log_die
(
LOG_EXIT_ZERO
,
"invalid action -- please make a bug report"
)
;
}
}
}
}
}
next:
apidv
[
i
].
nedge
--
;
pos
++
;
}
e
=
1
;
err:
stralloc_free
(
&
sa
)
;
return
e
;
}
static
void
async
(
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
)
static
int
async
(
pidvertex_t
*
apidv
,
unsigned
int
i
,
unsigned
int
what
,
ssexec_t
*
info
,
graph_t
*
graph
,
tain
*
deadline
)
{
/**
* @i: apidvertex array index
* */
log_flow
()
;
int
r
;
pid_t
pid
;
char
*
treename
=
graph
->
data
.
s
+
genalloc_s
(
graph_hash_t
,
&
graph
->
hash
)[
apidvertex
[
i
].
vertex
].
vertex
;
int
r
=
1
;
if
(
FLAGS_ISSET
(
apidvertex
[
i
].
state
,
flag
)
&&
!
FLAGS_ISSET
(
apidvertex
[
i
].
state
,
flag_run
))
{
apidvertex
[
i
].
state
|=
flag_run
;
if
(
pipe
(
apidvertex
[
i
].
pipe
)
<
0
)
log_dieusys
(
LOG_EXIT_ZERO
,
"pipe"
)
;
pid
=
fork
()
;
char
*
treename
=
graph
->
data
.
s
+
genalloc_s
(
graph_hash_t
,
&
graph
->
hash
)[
apidv
[
i
].
vertex
].
vertex
;
if
(
pid
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"fork"
)
;
if
(
FLAGS_ISSET
(
apidv
[
i
].
state
,
(
!
what
?
FLAGS_DOWN
:
FLAGS_UP
)))
{
if
(
!
pid
)
{
if
(
!
FLAGS_ISSET
(
apidv
[
i
].
state
,
FLAGS_BLOCK
)
)
{
close
(
apidvertex
[
i
].
pipe
[
0
])
;
apidv
[
i
].
state
|=
FLAGS_BLOCK
;
if
(
apidv
ertex
[
i
].
nedge
)
if
(
!
async_deps
(
i
,
what
,
info
,
graph
))
log_
dieu
(
LOG_EXIT_SYS
,
"start
tree: "
,
treename
)
;
if
(
apidv
[
i
].
nedge
)
if
(
!
async_deps
(
apidv
,
i
,
what
,
info
,
graph
,
deadline
))
log_
warnu_return
(
LOG_EXIT_ZERO
,
!
what
?
"start"
:
"stop"
,
" dependencies of
tree: "
,
treename
)
;
r
=
doit
(
info
,
treename
,
what
)
;
char
event
=
r
?
'd'
:
'u'
;
fd_write
(
apidvertex
[
i
].
pipe
[
1
],
(
char
*
)
&
event
,
1
)
;
close
(
apidvertex
[
i
].
pipe
[
1
])
;
if
(
r
)
log_info
(
"Successfully "
,
what
?
"stopped"
:
"started"
,
" tree: "
,
treename
)
;
else
log_info
(
"Unable to "
,
what
?
"stop"
:
"start"
,
" tree: "
,
treename
)
;
selfpipe_finish
()
;
}
else
{
_exit
(
r
)
;
log_info
(
"Skipping tree: "
,
treename
,
" -- already in "
,
what
?
"stopping"
:
"starting"
,
" process"
)
;
log_trace
(
"sends notification "
,
what
?
"d"
:
"u"
,
" to : "
,
apidv
[
i
].
eventdir
)
;
if
(
ftrigw_notify
(
apidv
[
i
].
eventdir
,
what
?
'd'
:
'u'
)
<
0
)
log_warnusys_return
(
LOG_EXIT_ZERO
,
"notifies event directory: "
,
apidv
[
i
].
eventdir
)
;
}
close
(
apidvertex
[
i
].
pipe
[
1
])
;
}
else
{
apidvertex
[
i
].
pid
=
pid
;
log_info
(
"Skipping tree: "
,
treename
,
" -- already "
,
what
?
"down"
:
"up"
)
;
}
else
{
log_trace
(
"sends notification "
,
what
?
"D"
:
"U"
,
" to : "
,
apidv
[
i
].
eventdir
)
;
if
(
ftrigw_notify
(
apidv
[
i
].
eventdir
,
what
?
'D'
:
'U'
)
<
0
)
log_warnusys_return
(
LOG_EXIT_ZERO
,
"notifies event directory: "
,
apidv
[
i
].
eventdir
)
;
log_trace
(
"skipping: "
,
treename
,
" -- already "
,
what
?
"down"
:
"up"
)
;
}
return
;
return
r
;
}
static
int
waitit
(
int
spfd
,
pidvertex_t
*
apidv
,
graph_t
*
graph
,
unsigned
int
what
,
tain
*
deadline
,
ssexec_t
*
info
)
static
int
waitit
(
pidvertex_t
*
apidv
,
unsigned
int
what
,
graph_t
*
graph
,
tain
*
deadline
,
ssexec_t
*
info
)
{
iopause_fd
x
=
{
.
fd
=
spfd
,
.
events
=
IOPAUSE_READ
}
;
log_flow
()
;
unsigned
int
e
=
1
,
pos
=
0
;
int
r
;
pid_t
pid
;
pidvertex_t
apidvertextable
[
napid
]
;
apidvertex
=
apidvertextable
;
npid
=
napid
;
pidvertex_t_ref
apidvertex
=
apidvertextable
;
for
(;
pos
<
napid
;
pos
++
)
apidvertex
[
pos
]
=
apidv
[
pos
]
;
tain_now_set_stopwatch_g
()
;
tain_add_g
(
deadline
,
deadline
)
;
int
spfd
=
selfpipe_init
()
;
if
(
spfd
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"selfpipe_init"
)
;
if
(
!
selfpipe_trap
(
SIGCHLD
)
||
!
selfpipe_trap
(
SIGINT
)
||
!
selfpipe_trap
(
SIGTERM
)
||
!
sig_altignore
(
SIGPIPE
))
log_dieusys
(
LOG_EXIT_SYS
,
"selfpipe_trap"
)
;
pidvertex_init_fifo
(
apidv
,
graph
,
deadline
)
;
for
(
pos
=
0
;
pos
<
napid
;
pos
++
)
async
(
pos
,
what
,
info
,
graph
)
;
apidvertex
[
pos
]
=
apidv
[
pos
]
;
for
(
pos
=
0
;
pos
<
napid
;
pos
++
)
{
pid
=
fork
()
;
if
(
pid
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"fork"
)
;
if
(
!
pid
)
{
r
=
async
(
apidvertex
,
pos
,
what
,
info
,
graph
,
deadline
)
;
_exit
(
!
r
)
;
}
apidvertex
[
pos
].
pid
=
pid
;
npid
++
;
}
iopause_fd
x
=
{
.
fd
=
spfd
,
.
events
=
IOPAUSE_READ
}
;
while
(
npid
)
{
...
...
@@ -610,10 +768,15 @@ static int waitit(int spfd, pidvertex_t *apidv, graph_t *graph, unsigned int wha
log_dieusys
(
LOG_EXIT_SYS
,
"iopause"
)
;
if
(
!
r
)
log_die
(
LOG_EXIT_SYS
,
"time out"
)
;
if
(
!
handle_signal
(
apidvertex
,
what
))
e
=
0
;
if
(
x
.
revents
&
IOPAUSE_READ
)
if
(
!
handle_signal
(
apidvertex
,
what
,
graph
,
info
))
e
=
0
;
}
ftrigr_end
(
&
FIFO
)
;
selfpipe_finish
()
;
return
e
;
}
...
...
@@ -656,7 +819,7 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec
if
(
what
)
{
requiredby
=
1
;
flag
=
FLAGS_UP
;
flag
=
FLAGS_UP
;
flag_run
=
FLAGS_STOPPING
;
}
else
{
...
...
@@ -699,6 +862,9 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec
napid
=
graph
.
sort_count
;
if
(
requiredby
)
graph_matrix_sort_reverse
(
&
graph
)
;
pidvertex_init_array
(
apidv
,
&
graph
,
graph
.
sort
,
graph
.
sort_count
,
info
,
requiredby
)
;
}
...
...
@@ -730,23 +896,9 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec
}
}
tain_now_set_stopwatch_g
()
;
tain_add_g
(
&
deadline
,
&
deadline
)
;
int
spfd
=
selfpipe_init
()
;
if
(
spfd
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"selfpipe_init"
)
;
if
(
!
selfpipe_trap
(
SIGCHLD
)
||
!
selfpipe_trap
(
SIGINT
)
||
!
selfpipe_trap
(
SIGTERM
))
log_dieusys
(
LOG_EXIT_SYS
,
"selfpipe_trap"
)
;
r
=
waitit
(
spfd
,
apidv
,
&
graph
,
what
,
&
deadline
,
info
)
;
r
=
waitit
(
apidv
,
what
,
&
graph
,
&
deadline
,
info
)
;
end:
selfpipe_finish
()
;
if
(
shut
)
{
...
...
@@ -763,5 +915,5 @@ int ssexec_all(int argc, char const *const *argv,char const *const *envp, ssexec
graph_free_all
(
&
graph
)
;
pidvertex_array_free
(
apidv
,
napid
)
;
return
(
!
r
)
?
111
:
0
;
return
(
!
r
)
?
111
:
0
;
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment