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
d9de619c
Commit
d9de619c
authored
2 years ago
by
Eric Vidal
Browse files
Options
Downloads
Patches
Plain Diff
[WIP]revamp ssexec_disable function
parent
06978a20
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
src/lib66/exec/ssexec_disable.c
+69
-308
69 additions, 308 deletions
src/lib66/exec/ssexec_disable.c
with
69 additions
and
308 deletions
src/lib66/exec/ssexec_disable.c
+
69
−
308
View file @
d9de619c
...
...
@@ -13,366 +13,127 @@
*/
#include
<string.h>
#include
<errno.h>
#include
<stdint.h>
#include
<stdlib.h>
#include
<oblibs/obgetopt.h>
#include
<oblibs/log.h>
#include
<oblibs/types.h>
#include
<oblibs/string.h>
#include
<oblibs/sastr.h>
#include
<skalibs/sgetopt.h>
#include
<skalibs/stralloc.h>
#include
<skalibs/genalloc.h>
#include
<skalibs/djbunix.h>
#include
<66/constants.h>
#include
<66/tree.h>
#include
<66/db.h>
#include
<66/resolve.h>
#include
<66/svc.h>
#include
<66/state.h>
#include
<66/utils.h>
#include
<66/ssexec.h>
#include
<66/config.h>
#include
<66/service.h>
#include
<66/graph.h>
#include
<66/resolve.h>
static
stralloc
workdir
=
STRALLOC_ZERO
;
static
uint8_t
FORCE
=
0
;
static
uint8_t
REMOVE
=
0
;
static
void
cleanup
(
void
)
static
void
check_identifier
(
char
const
*
name
)
{
log_flow
()
;
int
e
=
errno
;
rm_rf
(
workdir
.
s
)
;
errno
=
e
;
int
logname
=
get_rstrlen_until
(
name
,
SS_LOG_SUFFIX
)
;
if
(
logname
>
0
)
log_die
(
LOG_EXIT_USER
,
"service: "
,
name
,
": ends with reserved suffix -log"
)
;
if
(
!
memcmp
(
name
,
SS_MASTER
+
1
,
6
))
log_die
(
LOG_EXIT_USER
,
"service: "
,
name
,
": starts with reserved prefix Master"
)
;
if
(
!
strcmp
(
name
,
SS_SERVICE
))
log_die
(
LOG_EXIT_USER
,
"service as service name is a reserved name"
)
;
if
(
!
strcmp
(
name
,
"service@"
))
log_die
(
LOG_EXIT_USER
,
"service@ as service name is a reserved name"
)
;
}
int
s
vc_remove
(
genalloc
*
tostop
,
resolve_service_t
*
res
,
char
const
*
src
,
ssexec_t
*
info
)
int
s
sexec_disable
(
int
argc
,
char
const
*
const
*
argv
,
ssexec_t
*
info
)
{
log_flow
()
;
unsigned
int
i
=
0
;
int
r
,
e
=
0
;
genalloc
rdeps
=
GENALLOC_ZERO
;
stralloc
dst
=
STRALLOC_ZERO
;
resolve_service_t
cp
=
RESOLVE_SERVICE_ZERO
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_SERVICE
,
&
cp
)
;
ss_state_t
sta
=
STATE_ZERO
;
size_t
newlen
;
char
*
name
=
res
->
sa
.
s
+
res
->
name
;
if
(
!
service_resolve_copy
(
&
cp
,
res
))
{
log_warnusys
(
"copy resolve file"
)
;
goto
err
;
}
if
(
!
stralloc_cats
(
&
dst
,
src
))
goto
err
;
if
(
cp
.
type
==
TYPE_CLASSIC
)
{
if
(
!
stralloc_cats
(
&
dst
,
SS_SVC
))
goto
err
;
}
else
if
(
!
stralloc_cats
(
&
dst
,
SS_DB
SS_SRC
))
goto
err
;
if
(
!
stralloc_cats
(
&
dst
,
"/"
))
goto
err
;
newlen
=
dst
.
len
;
if
(
!
FORCE
)
{
if
(
!
service_resolve_add_rdeps
(
&
rdeps
,
&
cp
,
src
))
{
log_warnusys
(
"resolve recursive dependencies of: "
,
name
)
;
goto
err
;
}
}
else
{
if
(
!
resolve_append
(
&
rdeps
,
wres
))
goto
err
;
}
uint32_t
flag
=
0
;
uint8_t
stop
=
0
,
remove
=
0
;
int
n
=
0
,
e
=
1
;
size_t
pos
=
0
;
graph_t
graph
=
GRAPH_ZERO
;
stralloc
sa
=
STRALLOC_ZERO
;
if
(
!
service_resolve_add_logger
(
&
rdeps
,
src
))
{
log_warnusys
(
"resolve logger"
)
;
goto
err
;
}
unsigned
int
areslen
=
0
;
resolve_service_t
ares
[
SS_MAX_SERVICE
]
;
resolve_free
(
wres
)
;
for
(;
i
<
genalloc_len
(
resolve_service_t
,
&
rdeps
)
;
i
++
)
{
resolve_service_t_ref
pres
=
&
genalloc_s
(
resolve_service_t
,
&
rdeps
)[
i
]
;
resolve_wrapper_t_ref
dwres
=
resolve_set_struct
(
DATA_SERVICE
,
pres
)
;
char
*
str
=
pres
->
sa
.
s
;
char
*
name
=
str
+
pres
->
name
;
char
*
ste
=
str
+
pres
->
state
;
dst
.
len
=
newlen
;
if
(
!
stralloc_cats
(
&
dst
,
name
))
goto
err
;
if
(
!
stralloc_0
(
&
dst
))
goto
err
;
log_trace
(
"delete source service file of: "
,
name
)
;
if
(
rm_rf
(
dst
.
s
)
<
0
)
{
log_warnusys
(
"delete source service file: "
,
dst
.
s
)
;
goto
err
;
}
/** r == -1 means the state file is not present,
* r > 0 means service need to be initialized,
* so not initialized at all.*/
r
=
state_check_flags
(
ste
,
name
,
SS_FLAGS_INIT
)
;
if
(
!
r
)
{
/** modify the resolve file for 66-stop*/
pres
->
disen
=
0
;
log_trace
(
"Write resolve file of: "
,
name
)
;
if
(
!
resolve_write
(
dwres
,
src
,
name
))
{
log_warnusys
(
"write resolve file of: "
,
name
)
;
goto
err
;
}
if
(
!
state_read
(
&
sta
,
ste
,
name
))
{
log_warnusys
(
"read state of: "
,
name
)
;
goto
err
;
}
state_setflag
(
&
sta
,
SS_FLAGS_RELOAD
,
SS_FLAGS_FALSE
)
;
state_setflag
(
&
sta
,
SS_FLAGS_INIT
,
SS_FLAGS_FALSE
)
;
state_setflag
(
&
sta
,
SS_FLAGS_UNSUPERVISE
,
SS_FLAGS_TRUE
)
;
log_trace
(
"Write state file of: "
,
name
)
;
if
(
!
state_write
(
&
sta
,
ste
,
name
))
{
log_warnusys
(
"write state file of: "
,
name
)
;
goto
err
;
}
}
else
{
if
(
REMOVE
)
{
// remove configuration file
log_trace
(
"Delete configuration file of: "
,
name
)
;
if
(
rm_rf
(
str
+
pres
->
srconf
)
==
-
1
)
log_warnusys
(
"remove configuration file of: "
,
name
)
;
// remove the logger directory
log_trace
(
"Delete logger directory of: "
,
name
)
;
if
(
rm_rf
(
str
+
pres
->
dstlog
)
==
-
1
)
log_warnusys
(
"remove logger directory of: "
,
name
)
;
if
(
pres
->
type
==
TYPE_MODULE
)
{
// remove service source file
log_trace
(
"Delete service file of: "
,
name
)
;
if
(
rm_rf
(
str
+
pres
->
src
)
==
-
1
)
log_warnusys
(
"remove configuration file of: "
,
name
)
;
}
}
log_trace
(
"Delete resolve file of: "
,
name
)
;
resolve_rmfile
(
src
,
name
)
;
}
if
(
!
resolve_cmp
(
tostop
,
name
,
DATA_SERVICE
))
if
(
!
resolve_append
(
tostop
,
wres
))
goto
err
;
free
(
dwres
)
;
}
e
=
1
;
err:
resolve_free
(
wres
)
;
resolve_deep_free
(
DATA_SERVICE
,
&
rdeps
)
;
stralloc_free
(
&
dst
)
;
return
e
;
}
int
ssexec_disable
(
int
argc
,
char
const
*
const
*
argv
,
char
const
*
const
*
envp
,
ssexec_t
*
info
)
{
int
r
,
logname
;
unsigned
int
nlongrun
,
nclassic
,
stop
,
force
;
genalloc
tostop
=
GENALLOC_ZERO
;
//resolve_service_t
genalloc
gares
=
GENALLOC_ZERO
;
//resolve_service_t
resolve_service_t
res
=
RESOLVE_SERVICE_ZERO
;
resolve_service_t_ref
pres
;
resolve_wrapper_t_ref
wres
=
resolve_set_struct
(
DATA_SERVICE
,
&
res
)
;
r
=
nclassic
=
nlongrun
=
stop
=
logname
=
force
=
0
;
FLAGS_SET
(
flag
,
STATE_FLAGS_TOPROPAGATE
|
STATE_FLAGS_WANTUP
)
;
{
subgetopt
l
=
SUBGETOPT_ZERO
;
for
(;;)
{
int
opt
=
getopt_
args
(
argc
,
argv
,
">"
OPTS_DISABLE
,
&
l
)
;
int
opt
=
sub
getopt_
r
(
argc
,
argv
,
OPTS_DISABLE
,
&
l
)
;
if
(
opt
==
-
1
)
break
;
if
(
opt
==
-
2
)
log_die
(
LOG_EXIT_USER
,
"options must be set first"
)
;
switch
(
opt
)
{
case
'S'
:
if
(
FORCE
)
log_usage
(
usage_disable
)
;
stop
=
1
;
break
;
case
'F'
:
if
(
stop
)
log_usage
(
usage_disable
)
;
FORCE
=
1
;
break
;
case
'R'
:
if
(
stop
)
log_usage
(
usage_disable
)
;
REMOVE
=
1
;
break
;
default
:
log_usage
(
usage_disable
)
;
}
}
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
}
if
(
argc
<
1
)
log_usage
(
usage_disable
)
;
if
(
!
tree_copy
(
&
workdir
,
info
->
tree
.
s
,
info
->
treename
.
s
))
log_dieusys
(
LOG_EXIT_SYS
,
"create tmp working directory"
)
;
for
(;
*
argv
;
argv
++
)
{
char
const
*
name
=
*
argv
;
if
(
!
resolve_check
(
workdir
.
s
,
name
))
log_info_nclean_return
(
LOG_EXIT_ZERO
,
&
cleanup
,
name
,
" is not enabled"
)
;
if
(
!
resolve_read
(
wres
,
workdir
.
s
,
name
))
log_dieusys_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"read resolve file of: "
,
name
)
;
switch
(
opt
)
{
if
(
REMOVE
)
{
stralloc
sa
=
STRALLOC_ZERO
;
r
=
service_intree
(
&
sa
,
name
,
0
)
;
if
(
r
>
2
)
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"use -R option -- "
,
name
,
" is set on different tree"
)
;
stralloc_free
(
&
sa
)
;
}
if
(
res
.
type
==
TYPE_MODULE
)
{
if
(
!
module_in_cmdline
(
&
gares
,
&
res
,
workdir
.
s
))
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"add dependencies of module: "
,
name
)
;
}
else
{
if
(
!
resolve_append
(
&
gares
,
wres
))
log_dieusys_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"append services selection with: "
,
name
)
;
}
}
case
'S'
:
for
(
unsigned
int
i
=
0
;
i
<
genalloc_len
(
resolve_service_t
,
&
gares
)
;
i
++
)
{
pres
=
&
genalloc_s
(
resolve_service_t
,
&
gares
)[
i
]
;
char
*
string
=
pres
->
sa
.
s
;
char
*
name
=
string
+
pres
->
name
;
char
*
state
=
string
+
pres
->
state
;
uint8_t
found
=
0
;
char
module_name
[
256
]
;
/** The force options can be only used if the service is not marked initialized.
* This option should only be used when we have a inconsistent state between
* the /var/lib/66/system/<tree>/servicedirs/ and /var/lib/66/system/<tree>/.resolve
* directory meaning a service which is not present in the compiled db but its resolve file
* exist.
* Also, the remove option can be only used if the service is not marked initialized too.*/
if
(
FORCE
||
REMOVE
)
{
r
=
state_check_flags
(
state
,
name
,
SS_FLAGS_INIT
)
;
if
(
!
r
)
log_die_nclean
(
LOG_EXIT_USER
,
&
cleanup
,
name
,
" is marked initialized -- "
,
FORCE
?
"-F"
:
"-R"
,
" is not allowed"
)
;
}
stop
=
1
;
break
;
if
(
!
module_search_service
(
workdir
.
s
,
&
gares
,
name
,
&
found
,
module_name
))
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"search in module"
)
;
case
'F'
:
if
(
found
&&
!
FORCE
)
log_die_nclean
(
LOG_EXIT_USER
,
&
cleanup
,
name
,
" is a part of: "
,
module_name
,
" module -- it's not allowed to disable it alone"
)
;
log_1_warn
(
"options -F is deprecated -- skipping it"
)
;
break
;
if
(
found
&&
REMOVE
)
log_die_nclean
(
LOG_EXIT_USER
,
&
cleanup
,
name
,
" is a part of: "
,
module_name
,
" module -- -R options is not allowed"
)
;
case
'R'
:
logname
=
0
;
if
(
obstr_equal
(
name
,
SS_MASTER
+
1
))
log_die_nclean
(
LOG_EXIT_USER
,
&
cleanup
,
"nice try peon"
)
;
if
(
stop
)
log_usage
(
usage_disable
)
;
remove
=
1
;
break
;
logname
=
get_rstrlen_until
(
name
,
SS_LOG_SUFFIX
)
;
if
(
logname
>
0
&&
(
!
resolve_cmp
(
&
gares
,
string
+
pres
->
logassoc
,
DATA_SERVICE
)))
log_die_nclean
(
LOG_EXIT_USER
,
&
cleanup
,
"logger detected - disabling is not allowed"
)
;
if
(
!
pres
->
disen
&&
!
FORCE
)
{
log_info
(
name
,
": is already disabled"
)
;
continue
;
default
:
log_usage
(
usage_disable
)
;
}
}
if
(
!
svc_remove
(
&
tostop
,
pres
,
workdir
.
s
,
info
))
log_dieusys_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"remove service: "
,
name
)
;
if
(
pres
->
type
==
TYPE_CLASSIC
)
nclassic
++
;
else
nlongrun
++
;
argc
-=
l
.
ind
;
argv
+=
l
.
ind
;
}
if
(
nclassic
)
{
if
(
!
svc_switch_to
(
info
,
SS_SWBACK
))
log_dieusys_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"switch classic service to backup"
)
;
}
if
(
argc
<
1
)
log_usage
(
usage_disable
)
;
if
(
nlongrun
)
{
ss_resolve_graph_t
graph
=
RESOLVE_GRAPH_ZERO
;
r
=
ss_resolve_graph_src
(
&
graph
,
workdir
.
s
,
0
,
1
)
;
if
(
!
r
)
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"resolve source of graph for tree: "
,
info
->
treename
.
s
)
;
/** build the graph of the entire system */
graph_build_service
(
&
graph
,
ares
,
&
areslen
,
info
,
flag
)
;
r
=
ss_resolve_graph_publish
(
&
graph
,
0
)
;
if
(
r
<=
0
)
{
cleanup
()
;
if
(
r
<
0
)
log_die
(
LOG_EXIT_USER
,
"cyclic graph detected"
)
;
log_dieusys
(
LOG_EXIT_SYS
,
"publish service graph"
)
;
}
if
(
!
service_resolve_master_write
(
info
,
&
graph
,
workdir
.
s
,
1
))
log_dieusys_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"update inner bundle"
)
;
if
(
!
graph
.
mlen
)
log_die
(
LOG_EXIT_USER
,
"services selection is not available -- try to parse it first"
)
;
ss_resolve_graph_free
(
&
graph
)
;
if
(
!
db_compile
(
workdir
.
s
,
info
->
tree
.
s
,
info
->
treename
.
s
,
envp
))
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"compile "
,
workdir
.
s
,
"/"
,
info
->
treename
.
s
)
;
for
(;
n
<
argc
;
n
++
)
{
check_identifier
(
argv
[
n
])
;
service_enable_disable
(
&
graph
,
info
->
base
.
s
,
argv
[
n
],
0
)
;
/** this is an important part, we call s6-rc-update here */
if
(
!
db_switch_to
(
info
,
envp
,
SS_SWBACK
))
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"switch "
,
info
->
treename
.
s
,
" to backup"
)
;
if
(
!
sastr_add_string
(
&
sa
,
argv
[
n
]))
log_dieu
(
LOG_EXIT_SYS
,
"add string"
)
;
}
if
(
!
tree_copy_tmp
(
workdir
.
s
,
info
))
log_dieu_nclean
(
LOG_EXIT_SYS
,
&
cleanup
,
"copy: "
,
workdir
.
s
,
" to: "
,
info
->
tree
.
s
)
;
if
(
stop
&&
sa
.
len
)
{
cleanup
()
;
stralloc_free
(
&
workdir
)
;
resolve_free
(
wres
)
;
resolve_deep_free
(
DATA_SERVICE
,
&
gares
)
;
for
(
unsigned
int
i
=
0
;
i
<
genalloc_len
(
resolve_service_t
,
&
tostop
);
i
++
)
log_info
(
"Disabled successfully: "
,
genalloc_s
(
resolve_service_t
,
&
tostop
)[
i
].
sa
.
s
+
genalloc_s
(
resolve_service_t
,
&
tostop
)[
i
].
name
)
;
if
(
stop
&&
genalloc_len
(
resolve_service_t
,
&
tostop
))
{
int
nargc
=
3
+
genalloc_len
(
resolve_service_t
,
&
tostop
)
;
size_t
len
=
sastr_nelement
(
&
sa
)
;
int
nargc
=
2
+
len
;
char
const
*
prog
=
PROG
;
char
const
*
newargv
[
nargc
]
;
unsigned
int
m
=
0
;
newargv
[
m
++
]
=
"
fake_name
"
;
newargv
[
m
++
]
=
"
stop
"
;
newargv
[
m
++
]
=
"-u"
;
for
(
unsigned
int
i
=
0
;
i
<
genalloc_len
(
resolve_service_t
,
&
tostop
);
i
++
)
newargv
[
m
++
]
=
genalloc_s
(
resolve_service_t
,
&
tostop
)[
i
].
sa
.
s
+
genalloc_s
(
resolve_service_t
,
&
tostop
)[
i
].
name
;
newargv
[
m
++
]
=
0
;
if
(
ssexec_stop
(
nargc
,
newargv
,
envp
,
info
))
{
resolve_deep_free
(
DATA_SERVICE
,
&
tostop
)
;
return
111
;
}
FOREACH_SASTR
(
&
sa
,
pos
)
newargv
[
m
++
]
=
sa
.
s
+
pos
;
newargv
[
m
]
=
0
;
PROG
=
"stop"
;
e
=
ssexec_stop
(
nargc
,
newargv
,
info
)
;
PROG
=
prog
;
goto
end
;
}
e
=
0
;
resolve_deep_free
(
DATA_SERVICE
,
&
tostop
)
;
end:
stralloc_free
(
&
sa
)
;
service_resolve_array_free
(
ares
,
areslen
)
;
graph_free_all
(
&
graph
)
;
return
0
;
return
e
;
}
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