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
cdc9615f
Commit
cdc9615f
authored
2 years ago
by
Eric Vidal
Browse files
Options
Downloads
Patches
Plain Diff
[WIP] revamp 66-start and 66-stop
parent
521b2009
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/lib66/exec/ssexec_start.c
+101
-325
101 additions, 325 deletions
src/lib66/exec/ssexec_start.c
src/lib66/exec/ssexec_stop.c
+103
-210
103 additions, 210 deletions
src/lib66/exec/ssexec_stop.c
with
204 additions
and
535 deletions
src/lib66/exec/ssexec_start.c
+
101
−
325
View file @
cdc9615f
...
@@ -12,380 +12,156 @@
...
@@ -12,380 +12,156 @@
* except according to the terms contained in the LICENSE file./
* except according to the terms contained in the LICENSE file./
*/
*/
#include
<string.h>
#include
<stdint.h>
#include
<stdlib.h>
#include
<oblibs/obgetopt.h>
#include
<oblibs/log.h>
#include
<oblibs/log.h>
#include
<oblibs/string.h>
#include
<oblibs/types.h>
#include
<oblibs/types.h>
#include
<oblibs/obgetopt.h>
#include
<oblibs/graph.h>
#include
<skalibs/s
tralloc
.h>
#include
<skalibs/s
getopt
.h>
#include
<skalibs/genalloc.h>
#include
<skalibs/genalloc.h>
#include
<66/db.h>
#include
<66/utils.h>
#include
<66/constants.h>
#include
<66/svc.h>
#include
<66/ssexec.h>
#include
<66/ssexec.h>
#include
<66/
resolve
.h>
#include
<66/
config
.h>
#include
<66/
rc
.h>
#include
<66/
graph
.h>
#include
<66/state.h>
#include
<66/state.h>
#include
<66/svc.h>
#include
<66/sanitize.h>
#include
<66/service.h>
#include
<66/service.h>
static
int
empty
=
0
;
int
ssexec_start
(
int
argc
,
char
const
*
const
*
argv
,
ssexec_t
*
info
)
static
unsigned
int
RELOAD
=
0
;
static
unsigned
int
DEADLINE
=
0
;
static
char
*
SIG
=
"-u"
;
static
genalloc
nclassic
=
GENALLOC_ZERO
;
//resolve_t type
static
genalloc
nrc
=
GENALLOC_ZERO
;
//resolve_t type
static
ss_resolve_graph_t
graph_init_cl
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_reload_cl
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_init_rc
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_reload_rc
=
RESOLVE_GRAPH_ZERO
;
int
svc_sanitize
(
ssexec_t
*
info
,
char
const
*
const
*
envp
)
{
{
log_flow
()
;
log_flow
()
;
unsigned
int
reverse
=
0
;
uint32_t
flag
=
0
;
int
r
;
graph_t
graph
=
GRAPH_ZERO
;
stralloc
sares
=
STRALLOC_ZERO
;
unsigned
int
siglen
=
2
;
char
*
sig
[
siglen
+
1
]
;
if
(
!
sa_pointo
(
&
sares
,
info
,
TYPE_CLASSIC
,
SS_RESOLVE_SRC
))
unsigned
int
areslen
=
0
,
list
[
SS_MAX_SERVICE
],
nservice
=
0
;
{
resolve_service_t
ares
[
SS_MAX_SERVICE
]
;
log_warnu
(
"set revolve pointer to source"
)
;
goto
err
;
}
if
(
genalloc_len
(
resolve_service_t
,
&
graph_reload_cl
.
name
))
{
//reverse = 1 ;
r
=
ss_resolve_graph_publish
(
&
graph_reload_cl
,
reverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
svc_unsupervise
(
info
,
&
graph_reload_cl
.
sorted
,
"-d"
,
envp
))
FLAGS_SET
(
flag
,
STATE_FLAGS_TOPROPAGATE
|
STATE_FLAGS_TOINIT
|
STATE_FLAGS_WANTUP
)
;
goto
err
;
genalloc_reverse
(
resolve_service_t
,
&
graph_reload_cl
.
sorted
)
;
if
(
!
svc_init
(
info
,
sares
.
s
,
&
graph_reload_cl
.
sorted
))
{
log_warnu
(
"iniatiate service list"
)
;
goto
err
;
}
goto
end
;
}
if
(
genalloc_len
(
resolve_service_t
,
&
graph_init_cl
.
name
))
{
{
r
=
ss_resolve_graph_publish
(
&
graph_init_cl
,
reverse
)
;
subgetopt
l
=
SUBGETOPT_ZERO
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
svc_init
(
info
,
sares
.
s
,
&
graph_init_cl
.
sorted
))
{
log_warnu
(
"iniatiate service list"
)
;
goto
err
;
}
}
end:
for
(;;)
{
stralloc_free
(
&
sares
)
;
ss_resolve_graph_free
(
&
graph_reload_cl
)
;
ss_resolve_graph_free
(
&
graph_init_cl
)
;
return
1
;
err:
stralloc_free
(
&
sares
)
;
ss_resolve_graph_free
(
&
graph_reload_cl
)
;
ss_resolve_graph_free
(
&
graph_init_cl
)
;
return
0
;
}
int
rc_sanitize
(
ssexec_t
*
info
,
char
const
*
const
*
envp
)
int
opt
=
getopt_args
(
argc
,
argv
,
">"
OPTS_START
,
&
l
)
;
{
if
(
opt
==
-
1
)
break
;
log_flow
(
)
;
if
(
opt
==
-
2
)
log_die
(
LOG_EXIT_USER
,
"options must be set first"
)
;
int
r
,
reverse
=
1
,
done
=
0
;
switch
(
opt
)
{
stralloc
sares
=
STRALLOC_ZERO
;
char
db
[
info
->
livetree
.
len
+
1
+
info
->
treename
.
len
+
1
]
;
case
'r'
:
memcpy
(
db
,
info
->
livetree
.
s
,
info
->
livetree
.
len
)
;
db
[
info
->
livetree
.
len
]
=
'/'
;
memcpy
(
db
+
info
->
livetree
.
len
+
1
,
info
->
treename
.
s
,
info
->
treename
.
len
)
;
db
[
info
->
livetree
.
len
+
1
+
info
->
treename
.
len
]
=
0
;
if
(
!
db_ok
(
info
->
livetree
.
s
,
info
->
treename
.
s
))
if
(
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TORESTART
))
{
log_usage
(
usage_start
)
;
r
=
rc_init
(
info
,
envp
)
;
if
(
!
r
)
goto
err
;
else
if
(
r
>
1
)
{
empty
=
1
;
goto
end
;
}
done
=
1
;
}
if
(
!
sa_pointo
(
&
sares
,
info
,
SS_NOTYPE
,
SS_RESOLVE_SRC
))
{
log_warnu
(
"set revolve pointer to source"
)
;
goto
err
;
}
if
(
genalloc_len
(
resolve_service_t
,
&
graph_init_rc
.
name
)
&&
!
done
)
{
int
ireverse
=
0
;
r
=
ss_resolve_graph_publish
(
&
graph_init_rc
,
ireverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
rc_manage
(
info
,
&
graph_init_rc
.
sorted
))
{
log_warnu
(
"iniatiate service list"
)
;
goto
err
;
}
}
if
(
genalloc_len
(
resolve_service_t
,
&
graph_reload_rc
.
name
))
{
r
=
ss_resolve_graph_publish
(
&
graph_reload_rc
,
reverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWBACK
))
{
log_warnu
(
"switch "
,
info
->
treename
.
s
,
" to backup"
)
;
goto
err
;
}
if
(
!
db_compile
(
sares
.
s
,
info
->
tree
.
s
,
info
->
treename
.
s
,
envp
))
{
log_warnu
(
"compile "
,
sares
.
s
,
"/"
,
info
->
treename
.
s
)
;
goto
err
;
}
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWSRC
))
FLAGS_SET
(
flag
,
STATE_FLAGS_TORELOAD
)
;
{
break
;
log_warnu
(
"switch "
,
info
->
treename
.
s
,
" to source"
)
;
goto
err
;
}
if
(
!
rc_send
(
info
,
&
graph_reload_rc
.
sorted
,
"-d"
,
envp
))
goto
err
;
case
'R'
:
}
end:
ss_resolve_graph_free
(
&
graph_reload_rc
)
;
ss_resolve_graph_free
(
&
graph_init_rc
)
;
stralloc_free
(
&
sares
)
;
return
1
;
err:
ss_resolve_graph_free
(
&
graph_reload_rc
)
;
ss_resolve_graph_free
(
&
graph_init_rc
)
;
stralloc_free
(
&
sares
)
;
return
0
;
}
int
rc_start
(
ssexec_t
*
info
,
genalloc
*
ga
,
char
const
*
signal
,
char
const
*
const
*
envp
)
if
(
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TORELOAD
))
{
log_usage
(
usage_start
)
;
log_flow
()
;
char
const
*
sig
;
FLAGS_SET
(
flag
,
STATE_FLAGS_TORESTART
)
;
if
(
RELOAD
>=
1
)
sig
=
"-r"
;
break
;
else
sig
=
"-u"
;
int
r
=
db_find_compiled_state
(
info
->
livetree
.
s
,
info
->
treename
.
s
)
;
default
:
if
(
r
>=
1
)
{
log_usage
(
usage_start
)
;
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWSRC
))
}
log_warnu_return
(
LOG_EXIT_ZERO
,
"switch: "
,
info
->
treename
.
s
,
" to source"
)
;
}
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
}
}
if
(
!
rc_send
(
info
,
ga
,
sig
,
envp
))
return
0
;
return
1
;
if
(
argc
<
1
)
}
log_usage
(
usage_start
)
;
int
ssexec_start
(
int
argc
,
char
const
*
const
*
argv
,
char
const
*
const
*
envp
,
ssexec_t
*
info
)
if
((
svc_scandir_ok
(
info
->
scandir
.
s
))
!=
1
)
{
log_diesys
(
LOG_EXIT_SYS
,
"scandir: "
,
info
->
scandir
.
s
,
" is not running"
)
;
// be sure that the global var are set correctly
RELOAD
=
0
;
DEADLINE
=
0
;
SIG
=
"-u"
;
if
(
info
->
timeout
)
DEADLINE
=
info
->
timeout
;
int
n
=
0
;
for
(;
n
<
argc
;
n
++
)
/** If it's the first use of 66, we don't have
* any resolve files available or the service was
* never parsed, the graph is empty in the first case or
* the later call of service_array_search do not found the corresponding
* resolve file for the second case.
* Try at least to parse the corresponding frontend file. */
sanitize_source
(
argv
[
n
],
info
,
STATE_FLAGS_UNKNOWN
)
;
int
cl
,
rc
,
logname
;
/** build the graph of the entire system */
stralloc
sares
=
STRALLOC_ZERO
;
graph_build_service
(
&
graph
,
ares
,
&
areslen
,
info
,
flag
)
;
stralloc
sasta
=
STRALLOC_ZERO
;
genalloc
gares
=
GENALLOC_ZERO
;
//resolve_service_t
resolve_service_t_ref
pres
;
resolve_service_t
res
=
RESOLVE_SERVICE_ZERO
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_SERVICE
,
&
res
)
;
ss_state_t
sta
=
STATE_ZERO
;
cl
=
rc
=
logname
=
0
;
if
(
!
graph
.
mlen
)
log_die
(
LOG_EXIT_USER
,
"services selection is not available -- try first to install the corresponding frontend file"
)
;
{
for
(
n
=
0
;
n
<
argc
;
n
++
)
{
subgetopt
l
=
SUBGETOPT_ZERO
;
for
(;;)
int
aresid
=
service_resolve_array_search
(
ares
,
areslen
,
argv
[
n
])
;
{
if
(
aresid
<
0
)
int
opt
=
getopt_args
(
argc
,
argv
,
">"
OPTS_START
,
&
l
)
;
log_die
(
LOG_EXIT_USER
,
"service: "
,
*
argv
,
" not available -- did you parsed it?"
)
;
if
(
opt
==
-
1
)
break
;
if
(
opt
==
-
2
)
log_die
(
LOG_EXIT_USER
,
"options must be set first"
)
;
switch
(
opt
)
list
[
nservice
++
]
=
aresid
;
{
unsigned
int
l
[
graph
.
mlen
]
;
case
'r'
:
if
(
RELOAD
)
log_usage
(
usage_start
)
;
RELOAD
=
1
;
SIG
=
"-r"
;
break
;
unsigned
int
c
=
0
;
case
'R'
:
if
(
RELOAD
)
log_usage
(
usage_start
)
;
RELOAD
=
2
;
SIG
=
"-u"
;
break
;
default
:
log_usage
(
usage_start
)
;
/** find dependencies of the service from the graph, do it recursively */
}
c
=
graph_matrix_get_edge_g_list
(
l
,
&
graph
,
argv
[
n
],
0
,
1
)
;
}
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
/** append to the list to deal with */
for
(
unsigned
int
pos
=
0
;
pos
<
c
;
pos
++
)
list
[
nservice
+
pos
]
=
l
[
pos
]
;
nservice
+=
c
;
}
}
if
(
argc
<
1
)
log_usage
(
usage_start
)
;
/** initiate services at the corresponding scandir */
sanitize_init
(
list
,
nservice
,
&
graph
,
ares
,
areslen
,
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TORESTART
)
?
STATE_FLAGS_TOINIT
:
STATE_FLAGS_UNKNOWN
)
;
if
((
scandir_ok
(
info
->
scandir
.
s
))
!=
1
)
log_diesys
(
LOG_EXIT_SYS
,
"scandir: "
,
info
->
scandir
.
s
,
" is not running"
)
;
service_resolve_array_free
(
ares
,
areslen
)
;
if
(
!
sa_pointo
(
&
sasta
,
info
,
SS_NOTYPE
,
SS_RESOLVE_STATE
))
log_dieusys
(
LOG_EXIT_SYS
,
"set revolve pointer to state"
)
;
graph_free_all
(
&
graph
)
;
/** the tree may not initialized already, check it and create
* the live directory if it's the case */
if
(
!
scan_mode
(
sasta
.
s
,
S_IFDIR
))
if
(
!
create_live
(
info
))
log_dieusys
(
LOG_EXIT_SYS
,
"create live state"
)
;
if
(
!
sa_pointo
(
&
sares
,
info
,
SS_NOTYPE
,
SS_RESOLVE_SRC
))
log_dieusys
(
LOG_EXIT_SYS
,
"set revolve pointer to source"
)
;
if
(
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TORELOAD
))
{
for
(;
*
argv
;
argv
++
)
sig
[
0
]
=
"-wU"
;
{
sig
[
1
]
=
"-ru"
;
char
const
*
name
=
*
argv
;
sig
[
2
]
=
0
;
if
(
!
resolve_check
(
sares
.
s
,
name
))
log_info_return
(
LOG_EXIT_ZERO
,
name
,
" is not enabled"
)
;
if
(
!
resolve_read
(
wres
,
sares
.
s
,
name
))
log_dieusys
(
LOG_EXIT_SYS
,
"read resolve file of: "
,
name
)
;
if
(
res
.
type
==
TYPE_MODULE
)
{
if
(
!
module_in_cmdline
(
&
gares
,
&
res
,
sares
.
s
))
log_dieu
(
LOG_EXIT_SYS
,
"add dependencies of module: "
,
name
)
;
}
else
{
if
(
!
resolve_append
(
&
gares
,
wres
))
log_dieusys
(
LOG_EXIT_SYS
,
"append services selection with: "
,
name
)
;
}
}
for
(
unsigned
int
i
=
0
;
i
<
genalloc_len
(
resolve_service_t
,
&
gares
)
;
i
++
)
if
(
!
svc_send
(
argv
,
argc
,
sig
,
siglen
,
info
))
{
log_dieu
(
LOG_EXIT_SYS
,
"send -wU -ru signal"
)
;
int
init
=
0
;
int
reload
=
0
;
int
reverse
=
0
;
pres
=
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
]
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_SERVICE
,
pres
)
;
char
*
string
=
pres
->
sa
.
s
;
char
*
name
=
string
+
pres
->
name
;
logname
=
0
;
if
(
!
state_check
(
sasta
.
s
,
name
))
{
init
=
1
;
goto
append
;
}
else
if
(
!
state_read
(
&
sta
,
sasta
.
s
,
name
))
log_dieusys
(
LOG_EXIT_SYS
,
"read state file of: "
,
name
)
;
if
(
obstr_equal
(
name
,
SS_MASTER
+
1
))
goto
append
;
}
else
if
(
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TORESTART
))
{
if
(
!
pres
->
disen
)
sig
[
0
]
=
"-wD"
;
log_die
(
LOG_EXIT_USER
,
"service: "
,
name
,
" was disabled, you can only stop it"
)
;
sig
[
1
]
=
"-d"
;
sig
[
2
]
=
0
;
logname
=
get_rstrlen_until
(
name
,
SS_LOG_SUFFIX
)
;
if
(
!
svc_send
(
argv
,
argc
,
sig
,
siglen
,
info
))
if
(
logname
>
0
&&
(
!
resolve_cmp
(
&
gares
,
string
+
pres
->
logassoc
,
DATA_SERVICE
)))
log_dieu
(
LOG_EXIT_SYS
,
"send -wD -d signal"
)
;
{
if
(
RELOAD
>
1
)
log_die
(
LOG_EXIT_SYS
,
"-R signal is not allowed to a logger"
)
;
if
(
sta
.
init
)
reverse
=
1
;
}
if
(
RELOAD
>
1
||
sta
.
reload
)
reload
=
1
;
if
(
sta
.
init
){
reload
=
0
;
init
=
1
;
}
append:
if
(
pres
->
type
==
TYPE_CLASSIC
)
{
if
(
reload
)
{
reverse
=
1
;
if
(
!
ss_resolve_graph_build
(
&
graph_reload_cl
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
}
else
if
(
init
)
{
reverse
=
0
;
if
(
!
ss_resolve_graph_build
(
&
graph_init_cl
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
}
if
(
!
resolve_append
(
&
nclassic
,
wres
))
log_dieusys
(
LOG_EXIT_SYS
,
"append services selection with: "
,
name
)
;
cl
++
;
}
else
{
if
(
reload
)
{
reverse
=
1
;
if
(
!
ss_resolve_graph_build
(
&
graph_reload_rc
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
}
else
if
(
init
)
{
reverse
=
0
;
if
(
!
ss_resolve_graph_build
(
&
graph_init_rc
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
}
if
(
!
resolve_append
(
&
nrc
,
wres
))
log_dieusys
(
LOG_EXIT_SYS
,
"append services selection with: "
,
name
)
;
rc
++
;
}
free
(
wres
)
;
}
if
(
cl
)
sig
[
0
]
=
"-wU"
;
{
sig
[
1
]
=
"-ru"
;
log_trace
(
"sanitize classic services list..."
)
;
sig
[
2
]
=
0
;
if
(
!
svc_sanitize
(
info
,
envp
))
log_dieu
(
LOG_EXIT_SYS
,
"sanitize classic services list"
)
;
log_trace
(
"start classic services list ..."
)
;
{
/** In case of -R asked by user, svc service will be unsupervised.
* In this case the log will be started directly by the service (log is
* a part of the service directory A.K.A. service/log).
* So we need to make a distinction for 66-svctl between -r and -R to avoid
* to start the logger before the service itself because the resolution of
* the graph will append the service log. */
if
(
RELOAD
==
2
)
SIG
=
"-R"
;
if
(
!
svc_send
(
info
,
&
nclassic
,
SIG
,
envp
))
log_dieu
(
LOG_EXIT_SYS
,
"start classic services list"
)
;
}
log_trace
(
"switch classic service list of: "
,
info
->
treename
.
s
,
" to source"
)
;
if
(
!
svc_switch_to
(
info
,
SS_SWSRC
))
log_dieu
(
LOG_EXIT_SYS
,
"switch classic service list of: "
,
info
->
treename
.
s
,
" to source"
)
;
resolve_deep_free
(
DATA_SERVICE
,
&
nclassic
)
;
if
(
!
svc_send
(
argv
,
argc
,
sig
,
siglen
,
info
))
}
log_dieu
(
LOG_EXIT_SYS
,
"send -wU -u signal"
)
;
if
(
rc
)
{
}
else
{
log_trace
(
"sanitize atomic services list..."
)
;
if
(
!
rc_sanitize
(
info
,
envp
))
sig
[
0
]
=
"-wU"
;
log_dieu
(
LOG_EXIT_SYS
,
"sanitize atomic services list"
)
;
sig
[
1
]
=
"-u"
;
if
(
!
empty
)
sig
[
2
]
=
0
;
{
log_trace
(
"start atomic services list ..."
)
;
if
(
!
svc_send
(
argv
,
argc
,
sig
,
siglen
,
info
))
if
(
!
rc_start
(
info
,
&
nrc
,
SIG
,
envp
))
log_dieu
(
LOG_EXIT_SYS
,
"send -wU -u signal"
)
;
log_dieu
(
LOG_EXIT_SYS
,
"start atomic services list "
)
;
log_trace
(
"switch atomic services list of: "
,
info
->
treename
.
s
,
" to source"
)
;
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWSRC
))
log_dieu
(
LOG_EXIT_SYS
,
"switch atomic services list of: "
,
info
->
treename
.
s
,
" to source"
)
;
}
resolve_deep_free
(
DATA_SERVICE
,
&
nrc
)
;
}
}
stralloc_free
(
&
sares
)
;
stralloc_free
(
&
sasta
)
;
resolve_deep_free
(
DATA_SERVICE
,
&
gares
)
;
resolve_free
(
wres
)
;
return
0
;
return
0
;
}
}
This diff is collapsed.
Click to expand it.
src/lib66/exec/ssexec_stop.c
+
103
−
210
View file @
cdc9615f
...
@@ -12,258 +12,151 @@
...
@@ -12,258 +12,151 @@
* except according to the terms contained in the LICENSE file./
* except according to the terms contained in the LICENSE file./
*/
*/
#include
<st
r
in
g
.h>
#include
<st
d
in
t
.h>
#include
<oblibs/obgetopt.h>
#include
<oblibs/log.h>
#include
<oblibs/log.h>
#include
<oblibs/string.h>
#include
<oblibs/types.h>
#include
<oblibs/obgetopt.h>
#include
<oblibs/graph.h>
#include
<skalibs/stralloc.h>
#include
<skalibs/sgetopt.h>
#include
<skalibs/djbunix.h>
#include
<skalibs/genalloc.h>
#include
<skalibs/genalloc.h>
#include
<66/utils.h>
#include
<66/graph.h>
#include
<66/constants.h>
#include
<66/config.h>
#include
<66/db.h>
#include
<66/svc.h>
#include
<66/rc.h>
#include
<66/ssexec.h>
#include
<66/ssexec.h>
#include
<66/resolve.h>
#include
<66/service.h>
#include
<66/state.h>
#include
<66/state.h>
#include
<66/svc.h>
#include
<66/service.h>
static
unsigned
int
DEADLINE
=
0
;
int
ssexec_stop
(
int
argc
,
char
const
*
const
*
argv
,
ssexec_t
*
info
)
static
unsigned
int
UNSUP
=
0
;
static
char
*
SIG
=
"-d"
;
static
ss_resolve_graph_t
graph_unsup_cl
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_cl
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_unsup_rc
=
RESOLVE_GRAPH_ZERO
;
static
ss_resolve_graph_t
graph_rc
=
RESOLVE_GRAPH_ZERO
;
int
svc_down
(
ssexec_t
*
info
,
char
const
*
const
*
envp
)
{
{
log_flow
()
;
log_flow
()
;
u
nsigned
int
reverse
=
1
;
u
int32_t
flag
=
0
;
int
r
;
graph_t
graph
=
GRAPH_ZERO
;
if
(
genalloc_len
(
resolve_service_t
,
&
graph_unsup_cl
.
name
))
unsigned
int
areslen
=
0
,
list
[
SS_MAX_SERVICE
],
nservice
=
0
;
{
resolve_service_t
ares
[
SS_MAX_SERVICE
]
;
UNSUP
=
1
;
r
=
ss_resolve_graph_publish
(
&
graph_unsup_cl
,
reverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
svc_unsupervise
(
info
,
&
graph_unsup_cl
.
sorted
,
SIG
,
envp
))
goto
err
;
}
else
{
r
=
ss_resolve_graph_publish
(
&
graph_cl
,
reverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
svc_send
(
info
,
&
graph_cl
.
sorted
,
SIG
,
envp
))
goto
err
;
}
ss_resolve_graph_free
(
&
graph_unsup_cl
)
;
ss_resolve_graph_free
(
&
graph_cl
)
;
return
1
;
err:
ss_resolve_graph_free
(
&
graph_unsup_cl
)
;
ss_resolve_graph_free
(
&
graph_cl
)
;
return
0
;
}
int
rc_down
(
ssexec_t
*
info
,
char
const
*
const
*
envp
)
FLAGS_SET
(
flag
,
STATE_FLAGS_TOPROPAGATE
|
STATE_FLAGS_ISSUPERVISED
|
STATE_FLAGS_WANTDOWN
)
;
{
log_flow
()
;
unsigned
int
reverse
=
1
;
int
r
;
if
(
genalloc_len
(
resolve_service_t
,
&
graph_unsup_rc
.
name
))
{
UNSUP
=
1
;
r
=
ss_resolve_graph_publish
(
&
graph_unsup_rc
,
reverse
)
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
rc_unsupervise
(
info
,
&
graph_unsup_rc
.
sorted
,
"-d"
,
envp
))
goto
err
;
}
else
{
{
r
=
ss_resolve_graph_publish
(
&
graph_rc
,
reverse
)
;
subgetopt
l
=
SUBGETOPT_ZERO
;
if
(
r
<
0
||
!
r
)
{
log_warnusys
(
"publish service graph"
)
;
goto
err
;
}
if
(
!
rc_send
(
info
,
&
graph_rc
.
sorted
,
"-d"
,
envp
))
goto
err
;
}
ss_resolve_graph_free
(
&
graph_unsup_rc
)
;
for
(;;)
{
ss_resolve_graph_free
(
&
graph_rc
)
;
return
1
;
err:
ss_resolve_graph_free
(
&
graph_unsup_rc
)
;
ss_resolve_graph_free
(
&
graph_rc
)
;
return
0
;
}
int
ssexec_stop
(
int
argc
,
char
const
*
const
*
argv
,
char
const
*
const
*
envp
,
ssexec_t
*
info
)
int
opt
=
getopt_args
(
argc
,
argv
,
">"
OPTS_STOP
,
&
l
)
;
{
if
(
opt
==
-
1
)
break
;
// be sure that the global var are set correctly
if
(
opt
==
-
2
)
log_die
(
LOG_EXIT_USER
,
"options must be set first"
)
;
DEADLINE
=
0
;
UNSUP
=
0
;
SIG
=
"-d"
;
if
(
info
->
timeout
)
DEADLINE
=
info
->
timeout
;
switch
(
opt
)
{
int
cl
,
rc
,
sigopt
;
case
'u'
:
stralloc
sares
=
STRALLOC_ZERO
;
genalloc
gares
=
GENALLOC_ZERO
;
//resolve_service_t
resolve_service_t_ref
pres
;
resolve_service_t
res
=
RESOLVE_SERVICE_ZERO
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_SERVICE
,
&
res
)
;
ss_state_t
sta
=
STATE_ZERO
;
cl
=
rc
=
sigopt
=
0
;
FLAGS_SET
(
flag
,
STATE_FLAGS_TOUNSUPERVISE
|
STATE_FLAGS_WANTUP
)
;
break
;
{
case
'X'
:
subgetopt
l
=
SUBGETOPT_ZERO
;
for
(;;)
log_1_warn
(
"deprecated option -- use 66-svctl -xd instead"
)
;
{
return
0
;
int
opt
=
getopt_args
(
argc
,
argv
,
">"
OPTS_STOP
,
&
l
)
;
if
(
opt
==
-
1
)
break
;
case
'K'
:
if
(
opt
==
-
2
)
log_die
(
LOG_EXIT_USER
,
"options must be set first"
)
;
switch
(
opt
)
log_1_warn
(
"deprecated option -- use 66-svctl -kd instead"
)
;
{
return
0
;
case
'u'
:
UNSUP
=
1
;
break
;
case
'X'
:
if
(
sigopt
)
log_usage
(
usage_stop
)
;
sigopt
=
1
;
SIG
=
"-X"
;
break
;
default
:
case
'K'
:
if
(
sigopt
)
log_usage
(
usage_stop
)
;
sigopt
=
1
;
SIG
=
"-K"
;
break
;
log_usage
(
usage_stop
)
;
default
:
log_usage
(
usage_stop
)
;
}
}
}
}
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
}
}
if
(
argc
<
1
)
log_usage
(
usage_stop
)
;
if
(
argc
<
1
)
log_usage
(
usage_stop
)
;
if
((
scandir_ok
(
info
->
scandir
.
s
))
!=
1
)
log_diesys
(
LOG_EXIT_SYS
,
"scandir: "
,
info
->
scandir
.
s
,
" is not running"
)
;
if
((
svc_scandir_ok
(
info
->
scandir
.
s
))
!=
1
)
log_diesys
(
LOG_EXIT_SYS
,
"scandir: "
,
info
->
scandir
.
s
,
" is not running"
)
;
if
(
!
sa_pointo
(
&
sares
,
info
,
SS_NOTYPE
,
SS_RESOLVE_SRC
))
log_dieusys
(
LOG_EXIT_SYS
,
"set revolve pointer to source"
)
;
/** build the graph of the entire system */
graph_build_service
(
&
graph
,
ares
,
&
areslen
,
info
,
flag
)
;
for
(;
*
argv
;
argv
++
)
if
(
!
graph
.
mlen
)
{
log_die
(
LOG_EXIT_USER
,
"services selection is not available -- try first to install the corresponding frontend file"
)
;
char
const
*
name
=
*
argv
;
if
(
!
resolve_check
(
sares
.
s
,
name
))
log_info_return
(
LOG_EXIT_ZERO
,
name
,
" is not enabled"
)
;
if
(
!
resolve_read
(
wres
,
sares
.
s
,
name
))
log_dieusys
(
LOG_EXIT_SYS
,
"read resolve file of: "
,
name
)
;
if
(
res
.
type
==
TYPE_MODULE
)
{
if
(
!
module_in_cmdline
(
&
gares
,
&
res
,
sares
.
s
))
log_dieu
(
LOG_EXIT_SYS
,
"add dependencies of module: "
,
name
)
;
}
else
{
if
(
!
resolve_append
(
&
gares
,
wres
))
log_dieusys
(
LOG_EXIT_SYS
,
"append resolve file of: "
,
name
)
;
}
}
for
(
unsigned
int
i
=
0
;
i
<
genalloc_len
(
resolve_service_t
,
&
gares
)
;
i
++
)
int
n
=
0
;
{
for
(;
n
<
argc
;
n
++
)
{
int
unsup
=
0
,
reverse
=
1
;
pres
=
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
]
;
char
const
*
string
=
pres
->
sa
.
s
;
char
const
*
name
=
string
+
pres
->
name
;
char
const
*
state
=
string
+
pres
->
state
;
if
(
!
state_check
(
state
,
name
))
log_die
(
LOG_EXIT_USER
,
name
,
" : is not initialized"
)
;
int
aresid
=
service_resolve_array_search
(
ares
,
areslen
,
argv
[
n
])
;
else
if
(
!
state_read
(
&
sta
,
state
,
name
))
log_dieusys
(
LOG_EXIT_SYS
,
"read state file of: "
,
name
)
;
if
(
aresid
<
0
)
log_die
(
LOG_EXIT_USER
,
"service: "
,
*
argv
,
" not available -- did you started it?"
)
;
int
logname
=
get_rstrlen_until
(
name
,
SS_LOG_SUFFIX
)
;
list
[
nservice
++
]
=
aresid
;
unsigned
int
l
[
graph
.
mlen
]
;
unsigned
int
c
=
0
;
if
(
obstr_equal
(
name
,
SS_MASTER
+
1
))
/** find requiredby of the service from the graph, do it recursively */
{
c
=
graph_matrix_get_edge_g_list
(
l
,
&
graph
,
argv
[
n
],
1
,
1
)
;
if
(
pres
->
ndepends
)
goto
append
;
else
continue
;
}
/** logger cannot be unsupervised alone */
/** append to the list to deal with */
if
(
logname
>
0
&&
(
!
resolve_cmp
(
&
gares
,
string
+
pres
->
logassoc
,
DATA_SERVICE
)))
for
(
unsigned
int
pos
=
0
;
pos
<
c
;
pos
++
)
{
list
[
nservice
+
pos
]
=
l
[
pos
]
;
if
(
UNSUP
)
log_die
(
LOG_EXIT_SYS
,
"logger detected - unsupervise request is not allowed"
)
;
}
nservice
+=
c
;
if
(
UNSUP
)
unsup
=
1
;
if
(
sta
.
unsupervise
)
unsup
=
1
;
append:
if
(
pres
->
type
==
TYPE_CLASSIC
)
{
if
(
unsup
)
{
if
(
!
ss_resolve_graph_build
(
&
graph_unsup_cl
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
if
(
!
service_resolve_add_logger
(
&
graph_unsup_cl
.
name
,
sares
.
s
))
log_dieusys
(
LOG_EXIT_SYS
,
"append service selection with logger"
)
;
}
if
(
!
ss_resolve_graph_build
(
&
graph_cl
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
cl
++
;
}
else
{
if
(
unsup
)
{
if
(
!
ss_resolve_graph_build
(
&
graph_unsup_rc
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
if
(
!
service_resolve_add_logger
(
&
graph_unsup_rc
.
name
,
sares
.
s
))
log_dieusys
(
LOG_EXIT_SYS
,
"append service selection with logger"
)
;
}
if
(
!
ss_resolve_graph_build
(
&
graph_rc
,
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
],
sares
.
s
,
reverse
))
log_dieusys
(
LOG_EXIT_SYS
,
"build services graph"
)
;
rc
++
;
}
}
}
/** rc work */
if
(
FLAGS_ISSET
(
flag
,
STATE_FLAGS_TOUNSUPERVISE
))
{
if
(
rc
)
{
log_trace
(
"stop atomic services ..."
)
;
if
(
!
rc_down
(
info
,
envp
))
log_dieu
(
LOG_EXIT_SYS
,
"stop atomic services"
)
;
log_trace
(
"switch atomic services of: "
,
info
->
treename
.
s
,
" to source"
)
;
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWSRC
))
log_dieu
(
LOG_EXIT_SYS
,
"switch"
,
info
->
livetree
.
s
,
"/"
,
info
->
treename
.
s
,
" to source"
)
;
}
/** we cannot pass through the svc_send() function which
* call ssexec_svctl(). The ssexec_svctl function is asynchronous.
* So, when child exist, the svc_send is "unblocked" and the program
* continue to execute. We need to wait for all services to be brought
* down before executing the unsupervise.*/
pid_t
pid
;
int
wstat
;
/** svc work */
int
nargc
=
4
+
nservice
;
if
(
cl
)
char
const
*
newargv
[
nargc
]
;
{
unsigned
int
m
=
0
,
n
=
0
;
log_trace
(
"stop classic services ..."
)
;
if
(
!
svc_down
(
info
,
envp
))
log_dieu
(
LOG_EXIT_SYS
,
"stop classic services"
)
;
log_trace
(
"switch classic services of: "
,
info
->
treename
.
s
,
" to source"
)
;
if
(
!
svc_switch_to
(
info
,
SS_SWSRC
))
log_dieu
(
LOG_EXIT_SYS
,
"switch classic service of: "
,
info
->
treename
.
s
,
" to source"
)
;
}
if
(
UNSUP
)
newargv
[
m
++
]
=
"66-svctl"
;
{
newargv
[
m
++
]
=
"-wD"
;
log_trace
(
"send signal -an to scandir: "
,
info
->
scandir
.
s
)
;
newargv
[
m
++
]
=
"-d"
;
if
(
scandir_send_signal
(
info
->
scandir
.
s
,
"h"
)
<=
0
)
log_dieu
(
LOG_EXIT_SYS
,
"send signal to scandir: "
,
info
->
scandir
.
s
)
;
for
(;
n
<
nservice
;
n
++
)
newargv
[
m
++
]
=
graph
.
data
.
s
+
genalloc_s
(
graph_hash_t
,
&
graph
.
hash
)[
list
[
n
]].
vertex
;
newargv
[
m
++
]
=
0
;
pid
=
child_spawn0
(
newargv
[
0
],
newargv
,
(
char
const
*
const
*
)
environ
)
;
if
(
waitpid_nointr
(
pid
,
&
wstat
,
0
)
<
0
)
log_dieusys
(
LOG_EXIT_SYS
,
"wait for 66-svctl"
)
;
if
(
wstat
)
log_dieu
(
LOG_EXIT_SYS
,
"stop services selection"
)
;
svc_unsupervise
(
list
,
nservice
,
&
graph
,
ares
,
areslen
)
;
}
else
{
unsigned
int
siglen
=
2
;
char
*
sig
[
siglen
+
1
]
;
sig
[
0
]
=
"-wD"
;
sig
[
1
]
=
"-d"
;
sig
[
2
]
=
0
;
if
(
!
svc_send
(
argv
,
argc
,
sig
,
siglen
,
info
))
log_dieu
(
LOG_EXIT_SYS
,
"send -wD -d signal"
)
;
}
}
stralloc_free
(
&
sares
)
;
resolve_free
(
wres
)
;
service_resolve_array_free
(
ares
,
areslen
)
;
resolve_deep_free
(
DATA_SERVICE
,
&
gares
)
;
graph_free_all
(
&
graph
)
;
return
0
;
return
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