Skip to content

Commit 2f4a98e

Browse files
adrien-cottexdelaruelle
authored andcommitted
Preserve sticky module requirements during purge
Purge skips sticky and super-sticky modules but still attempts to unload their non-sticky requirements. This reports an unrelated dependency error without explaining why the requirement remains loaded. Preserve requirements needed by retained sticky modules and apply the sticky_purge reporting mode to their skipped unload. Fixes #582 Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Adrien Cotte <adrien.cotte@asplus.fr>
1 parent 3e543d9 commit 2f4a98e

7 files changed

Lines changed: 83 additions & 0 deletions

File tree

‎.hunspell.en.dic‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ gh
492492
ghcommit
493493
gitlog
494494
gmake
495+
gpt
495496
grp
496497
gz
497498
gzip

‎NEWS.rst‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,9 @@ Modules 5.7.0 (not yet released)
251251
* Doc: add the :ref:`user-guide` document that explains a selection of
252252
useful but lesser known features through practical examples and common
253253
use cases.
254+
* Keep non-sticky requirements of sticky modules loaded during a
255+
:subcmd:`purge` and explicitly report why their unload is skipped according
256+
to the :mconfig:`sticky_purge` configuration. (fix issue #582)
254257

255258

256259
.. _5.6 release notes:

‎tcl/modeval.tcl‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,19 @@ proc isModuleSticky {mod} {
959959
$mod sticky 1] && ![getState force])}]
960960
}
961961

962+
proc getModuleStickyDependentTag {mod} {
963+
set sticky_tag {}
964+
foreach dep_mod [getDependentLoadedModuleList [list $mod] 1 0 0 0] {
965+
if {[isModuleTagged $dep_mod super-sticky 1]} {
966+
set sticky_tag super-sticky
967+
break
968+
} elseif {![getState force] && [isModuleTagged $dep_mod sticky 1]} {
969+
set sticky_tag sticky
970+
}
971+
}
972+
return $sticky_tag
973+
}
974+
962975
proc saveLoadedReqOfUnloadingModule {unload_mod} {
963976
# fetch requirements of unloading module
964977
set ::g_savedLoReqOfUnloadMod($unload_mod)\
@@ -1172,6 +1185,21 @@ proc failOrSkipUnloadIfSticky {modname modfile} {
11721185
return 0
11731186
}
11741187

1188+
proc failOrSkipUnloadIfRequiredBySticky {mod} {
1189+
set sticky_tag [getModuleStickyDependentTag $mod]
1190+
if {$sticky_tag eq {}} {
1191+
return 0
1192+
}
1193+
1194+
set msg [getStickyReqUnloadMsg $sticky_tag]
1195+
switch -- [getConf sticky_purge] {
1196+
error {knerror $msg}
1197+
warning {reportWarning $msg}
1198+
}
1199+
1200+
return 1
1201+
}
1202+
11751203
# ;;; Local Variables:
11761204
# ;;; Mode: tcl-mode
11771205
# ;;; tcl-indent-level: 3

‎tcl/report.tcl.in‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1115,6 +1115,10 @@ proc getStickyUnloadMsg {{tag sticky}} {
11151115
return "Unload of $tag module skipped"
11161116
}
11171117
1118+
proc getStickyReqUnloadMsg {{tag sticky}} {
1119+
return "Unload skipped because module is required by a $tag module"
1120+
}
1121+
11181122
proc getStickyForcedUnloadMsg {} {
11191123
return {Unload of sticky module forced}
11201124
}

‎tcl/subcmd.tcl.in‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,6 +1577,11 @@ proc cmdModuleUnload {context match auto force onlyureq args} {
15771577
set prereq_list [getDependentLoadedModuleList [list $modname]]
15781578
set prereq_loaded_list [getDependentLoadedModuleList [list $modname]\
15791579
1 1 0 0]
1580+
if {[llength $prereq_loaded_list] &&\
1581+
[getState commandname] eq {purge} &&\
1582+
[failOrSkipUnloadIfRequiredBySticky $modname]} {
1583+
continue
1584+
}
15801585
if {[llength $prereq_loaded_list] && (![getConf auto_handling] ||\
15811586
!$auto)} {
15821587
# force mode should not affect if we only look for mods w/o dep

‎testsuite/modules.00-init/005-init_ts.exp‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,14 @@ set warn_stickyunload "$::warn_msgs: Unload of sticky module skipped"
455455
set err_stickyunloadf "$::warn_msgs: Unload of sticky module forced"
456456
set err_superstickyunload "$::error_msgs: Unload of super-sticky module skipped"
457457
set warn_superstickyunload "$::warn_msgs: Unload of super-sticky module skipped"
458+
set err_stickyrequnload "$::error_msgs: Unload skipped because module is\
459+
required by a sticky module"
460+
set warn_stickyrequnload "$::warn_msgs: Unload skipped because module is\
461+
required by a sticky module"
462+
set err_superstickyrequnload "$::error_msgs: Unload skipped because module\
463+
is required by a super-sticky module"
464+
set warn_superstickyrequnload "$::warn_msgs: Unload skipped because module\
465+
is required by a super-sticky module"
458466
set err_reqfull "$::error_msgs: Module version must be specified to load module"
459467
set err_nomodloaded "$error_msgs: $msg_nomodloaded"
460468
set err_modfromdiffpathloaded "$error_msgs: Module already loaded from a different modulepath"

‎testsuite/modules.50-cmds/464-sticky_purge.exp‎

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,40 @@ testouterr_cmd sh {purge} $ans {}
9797
testouterr_cmd sh {purge -f} $ans {}
9898

9999

100+
# super-sticky module with non-sticky requirement
101+
setenv_var TESTSUITE_STICKY purge_req
102+
setenv_loaded_module [list sticky1/1.0 sticky2/1.0] [list\
103+
$mp/sticky1/1.0 $mp/sticky2/1.0]
104+
setenv_var __MODULES_LMTAG sticky2/1.0&super-sticky
105+
setenv_var __MODULES_LMPREREQ sticky2/1.0&sticky1/1.0|sticky1/2.0
106+
107+
set ans [list]
108+
lappend ans [list set _LMFILES_ $mp/sticky1/1.0:$mp/sticky2/1.0]
109+
lappend ans [list set LOADEDMODULES sticky1/1.0:sticky2/1.0]
110+
111+
setenv_var MODULES_STICKY_PURGE error
112+
set anserr $ans
113+
lappend anserr [list ERR]
114+
set tserr [msg_unload {sticky2/1.0 <sS>}\
115+
$err_superstickyunload]\n\n[msg_unload sticky1/1.0\
116+
$err_superstickyrequnload]
117+
testouterr_cmd sh {purge} $anserr $tserr
118+
testouterr_cmd sh {purge -f} $anserr $tserr
119+
120+
setenv_var MODULES_STICKY_PURGE warning
121+
set tserr [msg_unload {sticky2/1.0 <sS>}\
122+
$warn_superstickyunload]\n\n[msg_unload sticky1/1.0\
123+
$warn_superstickyrequnload]
124+
testouterr_cmd sh {purge} $ans $tserr
125+
testouterr_cmd sh {purge -f} $ans $tserr
126+
127+
setenv_var MODULES_STICKY_PURGE silent
128+
testouterr_cmd sh {purge} $ans {}
129+
testouterr_cmd sh {purge -f} $ans {}
130+
131+
unsetenv_var TESTSUITE_STICKY
132+
133+
100134
# module both sticky and super-sticky
101135
setenv_var TESTSUITE_FPMOD_TAG sticky2
102136
setenv_loaded_module [list foo/1.0 tag/1.0] [list $mp/foo/1.0 $mp/tag/1.0]

0 commit comments

Comments
 (0)