* Re: [PATCH] chrt: Add support for SCHED_FLAG_DL_OVERRUN
From: Furkan Çalışkan @ 2026-05-13 11:16 UTC (permalink / raw)
To: Karel Zak; +Cc: util-linux, bensberg, vineethr
In-Reply-To: <vokmtg7drod6gzs5wdltod32yx5absvzf7spdne5wdu7gnv6x4@ujrijopovjn5>
Hi Karel,
On 5/13/26 13:56, Karel Zak wrote:
> On Wed, May 13, 2026 at 01:01:00PM +0300, Furkan Caliskan wrote:
>> When set on a SCHED_DEADLINE task, the kernel sends SIGXCPU to the
>> task if it exceeds its runtime budget within a period. Without this
>> flag the task is silently throttled until the next period. Useful
>> for real-time applications that need to detect when they are not
>> meeting their timing requirements.
>
> I have added this to the TODO list:
> https://github.com/util-linux/util-linux/issues/4339 ;-)
>
> It seems you (1frn10) already use GitHub. Creating a pull request
> there will speed up testing, reviews, and CI.
>
> Karel
>
Thanks for the feedback. I have opened a pull request here:
https://github.com/util-linux/util-linux/pull/4347
--
Furkan Caliskan
^ permalink raw reply
* Re: [PATCH] chrt: Add support for SCHED_FLAG_DL_OVERRUN
From: Karel Zak @ 2026-05-13 10:56 UTC (permalink / raw)
To: Furkan Caliskan; +Cc: util-linux, bensberg, vineethr
In-Reply-To: <20260513100100.31857-1-frn1furkan10@gmail.com>
On Wed, May 13, 2026 at 01:01:00PM +0300, Furkan Caliskan wrote:
> When set on a SCHED_DEADLINE task, the kernel sends SIGXCPU to the
> task if it exceeds its runtime budget within a period. Without this
> flag the task is silently throttled until the next period. Useful
> for real-time applications that need to detect when they are not
> meeting their timing requirements.
I have added this to the TODO list:
https://github.com/util-linux/util-linux/issues/4339 ;-)
It seems you (1frn10) already use GitHub. Creating a pull request
there will speed up testing, reviews, and CI.
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* [PATCH] chrt: Add support for SCHED_FLAG_DL_OVERRUN
From: Furkan Caliskan @ 2026-05-13 10:01 UTC (permalink / raw)
To: util-linux; +Cc: kzak, bensberg, vineethr, Furkan Caliskan
When set on a SCHED_DEADLINE task, the kernel sends SIGXCPU to the
task if it exceeds its runtime budget within a period. Without this
flag the task is silently throttled until the next period. Useful
for real-time applications that need to detect when they are not
meeting their timing requirements.
Add -O/--deadline-overrun option to allow users to toggle this
feature using the deadline scheduling class.
Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
bash-completion/chrt | 1 +
schedutils/chrt.1.adoc | 3 +++
schedutils/chrt.c | 17 ++++++++++++++++-
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/bash-completion/chrt b/bash-completion/chrt
index 363efdfa1..ead03b023 100644
--- a/bash-completion/chrt
+++ b/bash-completion/chrt
@@ -19,6 +19,7 @@ _chrt_module()
--all-tasks
--batch
--deadline
+ --deadline-overrun
--ext
--fifo
--help
diff --git a/schedutils/chrt.1.adoc b/schedutils/chrt.1.adoc
index 7c2ceab86..13a785c7e 100644
--- a/schedutils/chrt.1.adoc
+++ b/schedutils/chrt.1.adoc
@@ -85,6 +85,9 @@ Specifies deadline parameter for *SCHED_DEADLINE* policy (Linux-specific).
*-G*, *--reclaim-grub*::
Enables GRUB (Greedy Reclamation of Unused Bandwidth) algorithm. Linux-specific, supported since 4.13.
+*-O*, *--deadline-overrun*::
+Set *SCHED_FLAG_DL_OVERRUN* to receive *SIGXCPU* when a *SCHED_DEADLINE* task exceeds its runtime budget within a period. Without this flag the task is silently throttled until the next period. Linux-specific, supported since 4.16.
+
*-R*, *--reset-on-fork*::
Use *SCHED_RESET_ON_FORK* or *SCHED_FLAG_RESET_ON_FORK* flag. Linux-specific, supported since 2.6.31.
+
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
index 6bf08c5c1..cec41468a 100644
--- a/schedutils/chrt.c
+++ b/schedutils/chrt.c
@@ -93,6 +93,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(_("Scheduling options:\n"), out);
fputs(_(" -R, --reset-on-fork set reset-on-fork flag\n"), out);
fputs(_(" -G, --reclaim-grub set SCHED_FLAG_RECLAIM\n"), out);
+ fputs(_(" -O, --deadline-overrun set SCHED_FLAG_DL_OVERRUN\n"), out);
fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out);
fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out);
fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out);
@@ -440,6 +441,7 @@ int main(int argc, char **argv)
{ "all-tasks", no_argument, NULL, 'a' },
{ "batch", no_argument, NULL, 'b' },
{ "deadline", no_argument, NULL, 'd' },
+ { "deadline-overrun", no_argument, NULL, 'O' },
{ "ext", no_argument, NULL, 'e' },
{ "fifo", no_argument, NULL, 'f' },
{ "idle", no_argument, NULL, 'i' },
@@ -463,7 +465,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
close_stdout_atexit();
- while((c = getopt_long(argc, argv, "+abdD:efiphmoP:T:rRGvV", longopts, NULL)) != -1)
+ while((c = getopt_long(argc, argv, "+abdD:efiphmoOP:T:rRGvV", longopts, NULL)) != -1)
{
switch (c) {
case 'a':
@@ -499,6 +501,11 @@ int main(int argc, char **argv)
case 'G':
#ifdef SCHED_FLAG_RECLAIM
ctl->sched_flags |= SCHED_FLAG_RECLAIM;
+#endif
+ break;
+ case 'O':
+#ifdef SCHED_FLAG_DL_OVERRUN
+ ctl->sched_flags |= SCHED_FLAG_DL_OVERRUN;
#endif
break;
case 'i':
@@ -596,6 +603,14 @@ int main(int argc, char **argv)
# endif
if ((ctl->sched_flags & SCHED_FLAG_RECLAIM) && ctl->policy != SCHED_DEADLINE)
errx(EXIT_FAILURE, _("--reclaim-grub is only supported for SCHED_DEADLINE"));
+# endif
+# ifdef SCHED_FLAG_DL_OVERRUN
+# ifndef HAVE_SCHED_SETATTR
+ if (ctl->sched_flags & SCHED_FLAG_DL_OVERRUN)
+ errx(EXIT_FAILURE, _("SCHED_FLAG_DL_OVERRUN is unsupported"));
+# endif
+ if ((ctl->sched_flags & SCHED_FLAG_DL_OVERRUN) && ctl->policy != SCHED_DEADLINE)
+ errx(EXIT_FAILURE, _("--deadline-overrun is only supported for SCHED_DEADLINE"));
# endif
if (ctl->policy == SCHED_DEADLINE) {
/* The basic rule is runtime <= deadline <= period, so we can
--
2.34.1
^ permalink raw reply related
* Re: [PATCH v2] chrt: Add support for (GRUB) bandwidth reclaim
From: Karel Zak @ 2026-05-13 9:56 UTC (permalink / raw)
To: Furkan Caliskan; +Cc: util-linux
In-Reply-To: <20260511141030.16291-1-frn1furkan10@gmail.com>
On Mon, May 11, 2026 at 05:10:30PM +0300, Furkan Caliskan wrote:
> bash-completion/chrt | 1 +
> schedutils/chrt.1.adoc | 3 +++
> schedutils/chrt.c | 17 ++++++++++++++++-
> 3 files changed, 20 insertions(+), 1 deletion(-)
Applied, thanks.
https://github.com/util-linux/util-linux/commit/81c2eb29486281367b81baaa8ddf0f27f60877d3
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* [PATCH v2] chrt: Add support for (GRUB) bandwidth reclaim
From: Furkan Caliskan @ 2026-05-11 14:10 UTC (permalink / raw)
To: util-linux; +Cc: kzak, Furkan Caliskan
In-Reply-To: <qa5c2sqdvxiclkfszc7wdfdd3naa7e2w42mip3abj4auisqw6r@o2jtcbaibyep>
The SCHED_DEADLINE policy supports the (GRUB) Greedy Reclamation
of Unused Bandwidth algorithm. This allows tasks to reclaim
bandwidth that are left over by other deadline tasks that finish
their work early, or voluntarily yield the cpu.
Currently, chrt has no way to set the SCHED_FLAG_RECLAIM bit in
the sched_flags field of the sched_attr structure.
Add -G/--reclaim-grub option to allow users to toggle this feature
using the deadline scheduling class.
Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
bash-completion/chrt | 1 +
schedutils/chrt.1.adoc | 3 +++
schedutils/chrt.c | 17 ++++++++++++++++-
3 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/bash-completion/chrt b/bash-completion/chrt
index 3ca13fc05..363efdfa1 100644
--- a/bash-completion/chrt
+++ b/bash-completion/chrt
@@ -26,6 +26,7 @@ _chrt_module()
--max
--other
--pid
+ --reclaim-grub
--reset-on-fork
--rr
--sched-deadline
diff --git a/schedutils/chrt.1.adoc b/schedutils/chrt.1.adoc
index b8d8874bc..90a3d376a 100644
--- a/schedutils/chrt.1.adoc
+++ b/schedutils/chrt.1.adoc
@@ -81,6 +81,9 @@ Specifies period parameter for *SCHED_DEADLINE* policy (Linux-specific). Note th
*-D*, *--sched-deadline* _nanoseconds_::
Specifies deadline parameter for *SCHED_DEADLINE* policy (Linux-specific).
+*-G*, *--reclaim-grub*::
+Enables GRUB (Greedy Reclamation of Unused Bandwidth) algorithm. Linux-specific, supported since 4.13.
+
*-R*, *--reset-on-fork*::
Use *SCHED_RESET_ON_FORK* or *SCHED_FLAG_RESET_ON_FORK* flag. Linux-specific, supported since 2.6.31.
+
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
index 5ba9964c1..ab7e8e895 100644
--- a/schedutils/chrt.c
+++ b/schedutils/chrt.c
@@ -46,6 +46,7 @@ struct chrt_ctl {
uint64_t runtime; /* --sched-* options */
uint64_t deadline;
uint64_t period;
+ uint64_t sched_flags; /* For sched_attr->sched_flags member */
unsigned int all_tasks : 1, /* all threads of the PID */
reset_on_fork : 1, /* SCHED_RESET_ON_FORK or SCHED_FLAG_RESET_ON_FORK */
@@ -79,6 +80,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(USAGE_SEPARATOR, out);
fputs(_("Scheduling options:\n"), out);
fputs(_(" -R, --reset-on-fork set reset-on-fork flag\n"), out);
+ fputs(_(" -G, --reclaim-grub set SCHED_FLAG_RECLAIM\n"), out);
fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out);
fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out);
fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out);
@@ -359,6 +361,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
sa.sched_runtime = ctl->runtime;
sa.sched_period = ctl->period;
sa.sched_deadline = ctl->deadline;
+ sa.sched_flags = ctl->sched_flags;
# ifdef SCHED_FLAG_RESET_ON_FORK
/* Don't use SCHED_RESET_ON_FORK for sched_setattr()! */
@@ -417,6 +420,7 @@ int main(int argc, char **argv)
{ "sched-period", required_argument, NULL, 'P' },
{ "sched-deadline", required_argument, NULL, 'D' },
{ "reset-on-fork", no_argument, NULL, 'R' },
+ { "reclaim-grub", no_argument, NULL, 'G' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ NULL, no_argument, NULL, 0 }
@@ -427,7 +431,7 @@ int main(int argc, char **argv)
textdomain(PACKAGE);
close_stdout_atexit();
- while((c = getopt_long(argc, argv, "+abdD:efiphmoP:T:rRvV", longopts, NULL)) != -1)
+ while((c = getopt_long(argc, argv, "+abdD:efiphmoP:T:rRGvV", longopts, NULL)) != -1)
{
switch (c) {
case 'a':
@@ -460,6 +464,11 @@ int main(int argc, char **argv)
case 'R':
ctl->reset_on_fork = 1;
break;
+ case 'G':
+#ifdef SCHED_FLAG_RECLAIM
+ ctl->sched_flags |= SCHED_FLAG_RECLAIM;
+#endif
+ break;
case 'i':
#ifdef SCHED_IDLE
ctl->policy = SCHED_IDLE;
@@ -547,6 +556,12 @@ int main(int argc, char **argv)
if ((ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
errx(EXIT_FAILURE, _("--sched-{deadline,period} options are "
"supported for SCHED_DEADLINE only"));
+#ifndef HAVE_SCHED_SETATTR
+ if (ctl->sched_flags & SCHED_FLAG_RECLAIM)
+ errx(EXIT_FAILURE, _("SCHED_FLAG_RECLAIM is unsupported"));
+#endif
+ if ((ctl->sched_flags & SCHED_FLAG_RECLAIM) && ctl->policy != SCHED_DEADLINE)
+ errx(EXIT_FAILURE, _("--reclaim-grub is only supported for SCHED_DEADLINE"));
if (ctl->policy == SCHED_DEADLINE) {
/* The basic rule is runtime <= deadline <= period, so we can
* make deadline and runtime optional on command line. Note we
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] chrt: Add support for (GRUB) bandwidth reclaim
From: Karel Zak @ 2026-05-11 11:20 UTC (permalink / raw)
To: Furkan Caliskan; +Cc: util-linux, bensberg, vineethr
In-Reply-To: <20260423101407.35502-1-frn1furkan10@gmail.com>
On Thu, Apr 23, 2026 at 01:14:07PM +0300, Furkan Caliskan wrote:
> Currently, chrt has no way to set the SCHED_FLAG_RECLAIM bit in
> the sched_flags field of the sched_attr structure.
I have added a TODO entry to track the missing scheduler flags: https://github.com/util-linux/util-linux/issues/4339.
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* Re: [PATCH] chrt: Add support for (GRUB) bandwidth reclaim
From: Karel Zak @ 2026-05-11 11:10 UTC (permalink / raw)
To: Furkan Caliskan; +Cc: util-linux, bensberg, vineethr
In-Reply-To: <20260423101407.35502-1-frn1furkan10@gmail.com>
Hi Furkan,
Sorry for the delay in reviewing.
On Thu, Apr 23, 2026 at 01:14:07PM +0300, Furkan Caliskan wrote:
> --- a/schedutils/chrt.1.adoc
> +++ b/schedutils/chrt.1.adoc
> @@ -83,6 +83,9 @@ Specifies deadline parameter for *SCHED_DEADLINE* policy (Linux-specific).
>
> *-R*, *--reset-on-fork*::
> Use *SCHED_RESET_ON_FORK* or *SCHED_FLAG_RESET_ON_FORK* flag. Linux-specific, supported since 2.6.31.
> +
> +*-G*, *--reclaim-grub*::
> +Enables GRUB (Greedy Reclamation of Unused Bandwidth) algorithm.
> +
> Each thread has a _reset-on-fork_ scheduling flag. When this flag is set, children created by *fork*(2) do not inherit privileged scheduling policies. After the _reset-on-fork_ flag has been enabled, it can be reset only if the thread has the *CAP_SYS_NICE* capability. This flag is disabled in child processes created by *fork*(2).
> +
You have added *--reclaim-grub* to the reset-on-fork description block.
Please, also add "Linux-specific, supported since 4.13".
> diff --git a/schedutils/chrt.c b/schedutils/chrt.c
> index 273905e5d..1a081e566 100644
> --- a/schedutils/chrt.c
> +++ b/schedutils/chrt.c
> @@ -46,6 +46,7 @@ struct chrt_ctl {
> uint64_t runtime; /* --sched-* options */
> uint64_t deadline;
> uint64_t period;
> + uint64_t flag; /* For sched_attr->sched_flags member */
What about to use sched_flags rather than generic
>
> unsigned int all_tasks : 1, /* all threads of the PID */
> reset_on_fork : 1, /* SCHED_RESET_ON_FORK or SCHED_FLAG_RESET_ON_FORK */
> @@ -79,6 +80,7 @@ static void __attribute__((__noreturn__)) usage(void)
> fputs(USAGE_SEPARATOR, out);
> fputs(_("Scheduling options:\n"), out);
> fputs(_(" -R, --reset-on-fork set reset-on-fork flag\n"), out);
> + fputs(_(" -G, --reclaim-grub set SCHED_FLAG_RECLAIM\n"), out);
> fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out);
> fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out);
> fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out);
> @@ -349,7 +351,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
> /* old API is good enough for non-deadline */
> if (!supports_runtime_param(ctl->policy))
> return set_sched_one_by_setscheduler(ctl, pid);
> -
> +
> /* not changed by chrt, follow the current setting */
> sa.sched_nice = getpriority(PRIO_PROCESS, pid);
>
> @@ -359,6 +361,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
> sa.sched_runtime = ctl->runtime;
> sa.sched_period = ctl->period;
> sa.sched_deadline = ctl->deadline;
> + sa.sched_flags = ctl->flag;
Please be careful and consistently use tabs. Use an editor that
follows .editorconfig.
>
> # ifdef SCHED_FLAG_RESET_ON_FORK
> /* Don't use SCHED_RESET_ON_FORK for sched_setattr()! */
> @@ -417,6 +420,7 @@ int main(int argc, char **argv)
> { "sched-period", required_argument, NULL, 'P' },
> { "sched-deadline", required_argument, NULL, 'D' },
> { "reset-on-fork", no_argument, NULL, 'R' },
> + { "reclaim-grub", no_argument, NULL, 'G' },
> { "verbose", no_argument, NULL, 'v' },
> { "version", no_argument, NULL, 'V' },
> { NULL, no_argument, NULL, 0 }
You need to add 'G' to the getopt_long() call as well; currently, only
--reclaim-grub works.
You also need to add --reclaim-grub to bash-completion/chrt.
> @@ -460,6 +464,11 @@ int main(int argc, char **argv)
> case 'R':
> ctl->reset_on_fork = 1;
> break;
> + case 'G':
> +#ifdef SCHED_DEADLINE
#ifdef SCHED_FLAG_RECLAIM
> + ctl->flag |= SCHED_FLAG_RECLAIM;
> +#endif
> + break;
> case 'i':
> #ifdef SCHED_IDLE
> ctl->policy = SCHED_IDLE;
> @@ -546,6 +555,8 @@ int main(int argc, char **argv)
> if ((ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
> errx(EXIT_FAILURE, _("--sched-{deadline,period} options are "
> "supported for SCHED_DEADLINE only"));
> + if ((ctl->flag & SCHED_FLAG_RECLAIM) && ctl->policy != SCHED_DEADLINE)
> + errx(EXIT_FAILURE, _("--reclaim-grub is only supported for SCHED_DEADLINE"));
chrt is possible compile without sched_setattr. The ideal would be to
add there also
#indef HAVE_SCHED_SETATTR
if (ctl->flag & SCHED_FLAG_RECLAIM)
errx(EXIT_FAILURE, _("SCHED_FLAG_RECLAIM is unsupported"));
#endif
Thanks!
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* [PATCH] mount: (man) Fix grammar mistake on conv option
From: Eleftherios Kourmpalidis @ 2026-05-10 14:18 UTC (permalink / raw)
To: util-linux
Signed-off-by: Eleftherios Kourmpalidis <lefteriskourbal@gmail.com>
---
sys-utils/mount.8.adoc | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sys-utils/mount.8.adoc b/sys-utils/mount.8.adoc
index 55f522750..44eb97f38 100644
--- a/sys-utils/mount.8.adoc
+++ b/sys-utils/mount.8.adoc
@@ -1102,7 +1102,7 @@ Set the umask (the bit mask of the permissions that are *not* present). The defa
Convert all files names to lowercase, or leave them. (Default: *case=lower*.)
**conv=**__mode__::
-This option is obsolete and may fail or being ignored.
+This option is obsolete and may fail or be ignored.
*nocheck*::
Do not abort mounting when certain consistency checks fail.
@@ -1140,7 +1140,7 @@ Also show hidden and associated files. (If the ordinary files and the associated
Set the block size to the indicated value. (Default: *block=1024*.)
**conv=**__mode__::
-This option is obsolete and may fail or being ignored.
+This option is obsolete and may fail or be ignored.
*cruft*::
If the high byte of the file length contains other garbage, set this mount option to ignore the high order bits of the file length. This implies that a file cannot be larger than 16 MB.
--
2.54.0
^ permalink raw reply related
* Re: Bug#1132887: script: "script file -c command" stopped working
From: Karel Zak @ 2026-05-07 8:45 UTC (permalink / raw)
To: Evgeny Kapun; +Cc: util-linux, wanbingjiang
In-Reply-To: <cc9deabe-7529-440d-bb42-67740f47dfc9@gmail.com>
On Wed, Apr 08, 2026 at 04:36:50PM +0300, Evgeny Kapun wrote:
> On 4/7/26 16:26, Karel Zak wrote:
> > I have created bugfix for this, see https://github.com/util-linux/util-linux/pull/4201
>
> It seems that this fix doesn't handle the case where -- is used as an
> argument to an option. For example, `script -I --` before v2.42 would
> interpret -- as an argument to -I, but the pre-scanning in that PR would
> break it.
>
> The value can come from a variable, e.g. `script -I "$VAR"` and `script
> --log-in "$VAR"` will usually work, but break if $VAR is --. Similarly,
> `script "-I$VAR"` will usually work, but break if $VAR is the empty
> string. The only approach without special cases seems to be `script
> "--log-in=$VAR"`, but it doesn't seem to be very popular.
I have updated the patch to accept "--" as argument for your cases.
https://github.com/util-linux/util-linux/pull/4326
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* strange falures of lsfd checks
From: Stanislav Brabec @ 2026-05-07 0:14 UTC (permalink / raw)
To: util-linux
Hi.
I am just preparing util-linux-2.42 for the next SUSE product: Leap and
SUSE Linux Enterprise 16.1.
I experienced a strange failures of several lsfd checks when running
inside a qemu virtual machine and building in chroot. Surprisingly,
problems are not consistently reproducible. It seems that parallel
checksuite is more vulnerable to the failures. And the problem appears
only in some build environments.
I cannot cleanly say it is a regression, as 2.41.2 fails on some build
machines as well.
Did anybody experience similar problems?
Failing tests:
tests/ts/lsfd/option-hyperlink: Leaves a running task (tee?) and never
finishes.
tests/ts/lsfd/option-inet: Leaves a running task (tee?) and never finishes.
Note that the build environment is limited and does not support UDP
networking.
-- Stanislav Brabec
^ permalink raw reply
* Re: [PATCH] Secure login and sulogin on S390x
From: Dr. Werner Fink @ 2026-05-05 9:39 UTC (permalink / raw)
To: Chris Hofstaedtler; +Cc: util-linux
In-Reply-To: <afjqh57bXkLJ_FKr@zeha.at>
[-- Attachment #1: Type: text/plain, Size: 2049 bytes --]
On 2026/05/04 20:53:30 +0200, Chris Hofstaedtler wrote:
> * Werner Fink <werner@suse.de> [260429 11:30]:
> > Some remarks: on S390x architecture of modern zSeries the hypervisor
> > does log the console I/O. For both the 3215 half duplex line mode as
> > well as the 3270 full-screen/block mode console type the I/O is logged
> > on the hypervisor's side. To control this there are command send via
> > /dev/vmcp to tell the z/VM control program of the hypervisor not to
> > log during entering the password. For the 3215 console also automatic
> > scroll is enabled which avoid to press CLEAR to get the password prompt
> > if on the next block.
>
> [..]
> > 9 files changed, 436 insertions(+), 12 deletions(-)
>
> This seems to add a lot of code to util-linux. I was wondering if sulogin is
> the only place that needs this log filtering. What about su, sudo, doas and
> so on? Note that there are different su (and probably doas) versions in use
> across distributions.
>
> Wouldn't it be better if the hypervisor would not log input if the terminal
> output was disabled? That seems like behaviour commonly found in other
> virtual terminal emulators.
>
> Best,
> Chris
Maybe other hypervisors have the same behaviour. Nevertheless the
3215 console is half duplex printer like a punchcard based teletypewriter
running within the hypervisor of an zSystem firmware. Means every zOS and
Linux instances are VMs on such zSystem. The 3270 console type is a bit
better as it understands escape sequences and is a block mode console type,
but still you have primitiv local prompt within the hypervisor and not on
the linux side its self. You can compare this with qemu within virt-manager,
but AFAIK qemu does not log keystrokes.
The vmcp.c is a copy of the version I use for my blogd in the showconsole
project at https://github.com/bitstreamout/showconsole
Werner
--
"Having a smoking section in a restaurant is like having
a peeing section in a swimming pool." -- Edward Burr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 894 bytes --]
^ permalink raw reply
* Re: [PATCH] Secure login and sulogin on S390x
From: Chris Hofstaedtler @ 2026-05-04 18:53 UTC (permalink / raw)
To: Werner Fink; +Cc: util-linux
In-Reply-To: <20260429092825.17623-2-werner@suse.de>
* Werner Fink <werner@suse.de> [260429 11:30]:
>Some remarks: on S390x architecture of modern zSeries the hypervisor
>does log the console I/O. For both the 3215 half duplex line mode as
>well as the 3270 full-screen/block mode console type the I/O is logged
>on the hypervisor's side. To control this there are command send via
>/dev/vmcp to tell the z/VM control program of the hypervisor not to
>log during entering the password. For the 3215 console also automatic
>scroll is enabled which avoid to press CLEAR to get the password prompt
>if on the next block.
[..]
> 9 files changed, 436 insertions(+), 12 deletions(-)
This seems to add a lot of code to util-linux. I was wondering if
sulogin is the only place that needs this log filtering. What
about su, sudo, doas and so on? Note that there are different su
(and probably doas) versions in use across distributions.
Wouldn't it be better if the hypervisor would not log input if the
terminal output was disabled? That seems like behaviour commonly
found in other virtual terminal emulators.
Best,
Chris
^ permalink raw reply
* Re: [PATCH] Secure login and sulogin on S390x
From: Dr. Werner Fink @ 2026-05-04 11:31 UTC (permalink / raw)
To: util-linux
In-Reply-To: <20260429092825.17623-2-werner@suse.de>
[-- Attachment #1.1: Type: text/plain, Size: 234 bytes --]
Hi,
just to extend the last patch with a further one ro catch
all corner cases as well.
Werner
--
"Having a smoking section in a restaurant is like having
a peeing section in a swimming pool." -- Edward Burr
[-- Attachment #1.2: x.patch --]
[-- Type: text/x-patch, Size: 3949 bytes --]
From a6c23b4d8ad84fff4a58855b76b56a261ff8aa5e Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de>
Date: Mon, 4 May 2026 13:20:13 +0200
Subject: [PATCH] Ensure to detect all special console case on S390x
Signed-off-by: Werner Fink <werner@suse.de>
---
login-utils/sulogin-consoles.c | 46 ++++++++++++++++++++++------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c
index f09d90ece..4cce4f078 100644
--- a/login-utils/sulogin-consoles.c
+++ b/login-utils/sulogin-consoles.c
@@ -312,7 +312,7 @@ static
#ifdef __GNUC__
__attribute__((__hot__))
#endif
-int append_console(struct list_head *consoles, const char * const name)
+int append_console(struct list_head *consoles, const char * const name, dev_t dev)
{
struct console *restrict tail;
const struct console *last = NULL;
@@ -343,7 +343,29 @@ int append_console(struct list_head *consoles, const char * const name)
tail->reset_tty_context = NULL;
tail->user_tty_context = NULL;
#endif
-
+#if defined(__s390__) || defined(__s390x__)
+ /*
+ * Stat the device path to determine its major/minor numbers.
+ * This ensures we detect s390x terminal types regardless of whether
+ * the console was found via /proc, /sys, cmdline, or a direct stdin
+ * fallback (e.g. sulogin < /dev/ttyS0).
+ */
+ if (!dev) {
+ struct stat st;
+ if (stat(name, &st) == 0 && S_ISCHR(st.st_mode))
+ dev = st.st_rdev;
+ }
+ if (dev) {
+ unsigned int maj = major(dev);
+ unsigned int min = minor(dev);
+ if (maj == 4 && min == 64)
+ tail->flags |= CON_3215;
+ else if (maj == 4 && min >= 65)
+ tail->flags |= CON_SCLP;
+ else if (maj == 227 && min >= 1)
+ tail->flags |= CON_3270;
+ }
+#endif
return 0;
}
@@ -385,7 +407,7 @@ static int detect_consoles_from_proc(struct list_head *consoles)
name = scandev(dir, comparedev);
if (!name)
continue;
- rc = append_console(consoles, name);
+ rc = append_console(consoles, name, comparedev);
free(name);
if (rc < 0)
goto done;
@@ -394,14 +416,6 @@ static int detect_consoles_from_proc(struct list_head *consoles)
last = list_last_entry(consoles, struct console, entry);
if (!strchr(fbuf, 'C'))
last->flags |= CON_CONSDEV;
-#if defined(__s390__) || defined(__s390x__)
- if (maj == 4 && min == 64)
- last->flags |= CON_3215;
- if (maj == 4 && min >= 65)
- last->flags |= CON_SCLP;
- else if (maj == 227 && min >= 1)
- last->flags |= CON_3270;
-#endif
}
}
@@ -461,7 +475,7 @@ static int detect_consoles_from_sysfs(struct list_head *consoles)
name = scandev(dir, comparedev);
if (!name)
continue;
- rc = append_console(consoles, name);
+ rc = append_console(consoles, name, comparedev);
free(name);
if (rc < 0)
goto done;
@@ -549,7 +563,7 @@ static int detect_consoles_from_cmdline(struct list_head *consoles)
name = scandev(dir, comparedev);
if (!name)
continue;
- rc = append_console(consoles, name);
+ rc = append_console(consoles, name, comparedev);
free(name);
if (rc < 0)
goto done;
@@ -607,7 +621,7 @@ static int detect_consoles_from_tiocgdev(struct list_head *consoles,
goto done;
}
}
- rc = append_console(consoles, name);
+ rc = append_console(consoles, name, comparedev);
free(name);
if (rc < 0)
goto done;
@@ -721,7 +735,7 @@ int detect_consoles(const char *device, const int fallback, struct list_head *co
closedir(dir);
if (name) {
- rc = append_console(consoles, name);
+ rc = append_console(consoles, name, comparedev);
free(name);
if (rc < 0)
return rc;
@@ -798,7 +812,7 @@ fallback:
n = strdup(name);
if (!n)
return -ENOMEM;
- rc = append_console(consoles, n);
+ rc = append_console(consoles, n, 0);
free(n);
if (rc < 0)
return rc;
--
2.51.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 894 bytes --]
^ permalink raw reply related
* [PATCH] Secure login and sulogin on S390x
From: Werner Fink @ 2026-04-29 9:28 UTC (permalink / raw)
To: util-linux; +Cc: Werner Fink
Some remarks: on S390x architecture of modern zSeries the hypervisor
does log the console I/O. For both the 3215 half duplex line mode as
well as the 3270 full-screen/block mode console type the I/O is logged
on the hypervisor's side. To control this there are command send via
/dev/vmcp to tell the z/VM control program of the hypervisor not to
log during entering the password. For the 3215 console also automatic
scroll is enabled which avoid to press CLEAR to get the password prompt
if on the next block.
Beside this for the ttysclp0, the serial ASCII terminal accessed via
a websocket has since ncurses 6.5-20250405 a new terminfo entry called
"sclp" to support not only the vt220 like behaviour but also the
colouring feature of ttysclp0.
Signed-off-by: Werner Fink <werner@suse.de>
---
lib/ttyutils.c | 5 +-
login-utils/Makemodule.am | 6 +-
login-utils/login.c | 85 +++++++++++-
login-utils/meson.build | 5 +
login-utils/sulogin-consoles.c | 14 ++
login-utils/sulogin-consoles.h | 4 +
login-utils/sulogin.c | 64 +++++++--
login-utils/vmcp.c | 236 +++++++++++++++++++++++++++++++++
login-utils/vmcp.h | 29 ++++
9 files changed, 436 insertions(+), 12 deletions(-)
create mode 100644 login-utils/vmcp.c
create mode 100644 login-utils/vmcp.h
diff --git a/lib/ttyutils.c b/lib/ttyutils.c
index bacd73077..3085419bd 100644
--- a/lib/ttyutils.c
+++ b/lib/ttyutils.c
@@ -21,7 +21,7 @@
# if defined (__s390__) || defined (__s390x__)
# define DEFAULT_TTYS0 "dumb"
# define DEFAULT_TTY32 "ibm327x"
-# define DEFAULT_TTYS1 "vt220"
+# define DEFAULT_TTYS1 "sclp"
# endif
# ifndef DEFAULT_STERM
# define DEFAULT_STERM "vt102"
@@ -176,7 +176,8 @@ char *get_terminal_default_type(const char *ttyname, int is_serial)
* Special terminal on first serial line on a S/390(x) which
* is due legacy reasons a block terminal of type 3270 or
* higher. Whereas the second serial line on a S/390(x) is
- * a real character terminal which is compatible with VT220.
+ * a real character terminal which is compatible with "sclp"
+ * since ncurses 6.5-20250405 for e.g. color support.
*/
if (strcmp(ttyname, "ttyS0") == 0) /* linux/drivers/s390/char/con3215.c */
return strdup(DEFAULT_TTYS0);
diff --git a/login-utils/Makemodule.am b/login-utils/Makemodule.am
index d288a06c3..599547f7b 100644
--- a/login-utils/Makemodule.am
+++ b/login-utils/Makemodule.am
@@ -33,7 +33,9 @@ dist_noinst_DATA += login-utils/sulogin.8.adoc
sulogin_SOURCES = \
login-utils/sulogin.c \
login-utils/sulogin-consoles.c \
- login-utils/sulogin-consoles.h
+ login-utils/sulogin-consoles.h \
+ login-utils/vmcp.c \
+ login-utils/vmcp.h
if USE_PLYMOUTH_SUPPORT
sulogin_SOURCES += lib/plymouth-ctrl.c
endif
@@ -59,6 +61,8 @@ MANPAGES += login-utils/login.1
dist_noinst_DATA += login-utils/login.1.adoc
login_SOURCES = \
login-utils/login.c \
+ login-utils/vmcp.c \
+ login-utils/vmcp.h \
lib/logindefs.c
login_LDADD = $(LDADD) libcommon.la -lpam
if HAVE_LINUXPAM
diff --git a/login-utils/login.c b/login-utils/login.c
index d9e93d0dd..5b10cb83d 100644
--- a/login-utils/login.c
+++ b/login-utils/login.c
@@ -85,6 +85,7 @@
#include "pwdutils.h"
#include "logindefs.h"
+#include "vmcp.h"
#define LOGIN_MAX_TRIES 3
#define LOGIN_EXIT_TIMEOUT 5
@@ -161,6 +162,85 @@ static int is_consoletty(int fd)
}
#endif
+#if defined(__s390__) || defined(__s390x__)
+/* Avoid that passwords are logged on the hypervisors console log */
+
+#define CON_3215 0x0010 /* s390x 3215 halfduplex console */
+#define CON_3270 0x0020 /* s390x 3270 console */
+#define CON_SCLP 0x0040 /* s390x sclp terminals */
+
+struct s390con {
+ int flags;
+ int vmcpfd;
+};
+
+static struct s390con s390_console_spool_stop(int fd)
+{
+ struct stat stb;
+ struct s390con con = { .flags = 0, .vmcpfd = -1 };
+
+ if ((fstat(fd, &stb) >= 0)) {
+ if (major(stb.st_rdev) == 4 && minor(stb.st_rdev) == 64)
+ con.flags |= CON_3215;
+ if (major(stb.st_rdev) == 4 && minor(stb.st_rdev) >= 65)
+ con.flags |= CON_SCLP;
+ else if (major(stb.st_rdev) == 227 && minor(stb.st_rdev) >= 1)
+ con.flags |= CON_3270;
+ }
+ if (con.flags & (CON_3215|CON_3270)) {
+ con.vmcpfd = openvmcp();
+ if (con.vmcpfd >= 0) {
+ char *msg = queryspool(con.vmcpfd);
+ if (msg) {
+ parsespool(msg);
+ free(msg);
+ }
+ /*
+ * Avoid that console log during
+ * password input
+ */
+ stopspool(con.vmcpfd);
+ }
+ }
+ if (con.flags & CON_3215) {
+ if (con.vmcpfd >= 0) {
+ char *msg = queryterm(con.vmcpfd);
+ if (msg) {
+ parseterm(msg);
+ free(msg);
+ }
+ /*
+ * Avoid that CLEAR has to be pressed for
+ * password input
+ */
+ setterm(con.vmcpfd, "0");
+# ifdef WARN_WITH_VMCP
+ warning3215(con.vmcpfd);
+# endif
+ }
+ }
+ return con;
+}
+
+static void s390_console_spool_restore(struct s390con *con)
+{
+ if (con->vmcpfd >= 0) {
+ if (con->flags & CON_3215)
+ restoreterm(con->vmcpfd);
+ if (con->flags & (CON_3215|CON_3270))
+ restorespool(con->vmcpfd);
+ clearvmcp();
+ close(con->vmcpfd);
+ con->vmcpfd = -1;
+ }
+}
+# define PREPARE_CONSOLE(fd) struct s390con con = s390_console_spool_stop(fd)
+# define RESTORE_CONSOLE() s390_console_spool_restore(&con)
+#else
+# define PREPARE_CONSOLE(fd) /* */
+# define RESTORE_CONSOLE() /* */
+#endif
+
/*
* Robert Ambrose writes:
* A couple of my users have a problem with login processes hanging around
@@ -1580,8 +1660,11 @@ int main(int argc, char **argv)
/* login -f, then the user has already been authenticated */
cxt.noauth = cxt.noauth && getuid() == 0 ? 1 : 0;
- if (!cxt.noauth)
+ if (!cxt.noauth) {
+ PREPARE_CONSOLE(0);
loginpam_auth(&cxt);
+ RESTORE_CONSOLE();
+ }
/*
* Authentication may be skipped (for example, during krlogin, rlogin,
diff --git a/login-utils/meson.build b/login-utils/meson.build
index 251d8de46..5f6310b01 100644
--- a/login-utils/meson.build
+++ b/login-utils/meson.build
@@ -49,6 +49,7 @@ test_islocal_sources = files(
test_consoles_sources = files(
'sulogin-consoles.c',
+ 'vmcp.c',
)
last_sources = files(
@@ -59,6 +60,8 @@ last_manadocs = files('last.1.adoc')
login_sources = files(
'login.c',
+ 'vmcp.c',
+ 'vmcp.h',
)
login_manadocs = files('login.1.adoc')
@@ -66,6 +69,8 @@ sulogin_sources = files(
'sulogin.c',
'sulogin-consoles.c',
'sulogin-consoles.h',
+ 'vmcp.c',
+ 'vmcp.h',
)
sulogin_manadocs = files('sulogin.8.adoc')
diff --git a/login-utils/sulogin-consoles.c b/login-utils/sulogin-consoles.c
index c35922ff1..f09d90ece 100644
--- a/login-utils/sulogin-consoles.c
+++ b/login-utils/sulogin-consoles.c
@@ -389,6 +389,20 @@ static int detect_consoles_from_proc(struct list_head *consoles)
free(name);
if (rc < 0)
goto done;
+ if (!list_empty(consoles)) {
+ struct console *last;
+ last = list_last_entry(consoles, struct console, entry);
+ if (!strchr(fbuf, 'C'))
+ last->flags |= CON_CONSDEV;
+#if defined(__s390__) || defined(__s390x__)
+ if (maj == 4 && min == 64)
+ last->flags |= CON_3215;
+ if (maj == 4 && min >= 65)
+ last->flags |= CON_SCLP;
+ else if (maj == 227 && min >= 1)
+ last->flags |= CON_3270;
+#endif
+ }
}
rc = list_empty(consoles) ? 1 : 0;
diff --git a/login-utils/sulogin-consoles.h b/login-utils/sulogin-consoles.h
index d3b4298e4..10fdf612c 100644
--- a/login-utils/sulogin-consoles.h
+++ b/login-utils/sulogin-consoles.h
@@ -39,6 +39,10 @@ struct console {
#define CON_SERIAL 0x0001
#define CON_NOTTY 0x0002
#define CON_EIO 0x0004
+#define CON_CONSDEV 0x0008 /* Last on the kernel command line */
+#define CON_3215 0x0010 /* s390x 3215 halfduplex console */
+#define CON_3270 0x0020 /* s390x 3270 console */
+#define CON_SCLP 0x0040 /* s390x sclp terminals */
pid_t pid;
struct chardata cp;
struct termios tio;
diff --git a/login-utils/sulogin.c b/login-utils/sulogin.c
index 23f5164e6..1984e6912 100644
--- a/login-utils/sulogin.c
+++ b/login-utils/sulogin.c
@@ -66,6 +66,7 @@
#include "strutils.h"
#include "ttyutils.h"
#include "sulogin-consoles.h"
+#include "vmcp.h"
#define CONMAX 16
static unsigned int timeout;
@@ -218,7 +219,7 @@ static void tcinit(struct console *con)
#endif
#ifdef KDGKBMODE
- if (!(con->flags & CON_SERIAL)
+ if (!(con->flags & (CON_SERIAL|CON_3215|CON_3270|CON_SCLP))
&& ioctl(fd, KDGKBMODE, &mode) < 0)
con->flags |= CON_SERIAL;
errno = 0;
@@ -265,6 +266,13 @@ static void tcinit(struct console *con)
}
}
+#if defined(__s390__) || defined(__s390x__)
+ if (con->flags & (CON_3215|CON_3270)) {
+ setlocale(LC_CTYPE, "POSIX");
+ setlocale(LC_MESSAGES, "POSIX");
+ goto setattr;
+ }
+#endif
/* Handle lines other than virtual consoles here */
#if defined(KDGKBMODE) || defined(TIOCGSERIAL)
if (con->flags & CON_SERIAL)
@@ -292,7 +300,7 @@ static void tcinit(struct console *con)
cfsetospeed(tio, ospeed);
#ifdef HAVE_STRUCT_TERMIOS_C_LINE
- tio->c_line = 0;
+ tio->c_line = 0;
#endif
tio->c_cc[VTIME] = 0;
tio->c_cc[VMIN] = 1;
@@ -364,6 +372,10 @@ static void tcfinal(struct console *con)
free(term);
}
+#if defined(__s390__) || defined(__s390x__)
+ if (con->flags & (CON_3215|CON_3270))
+ return;
+#endif
if (!(con->flags & CON_SERIAL) || (con->flags & CON_NOTTY))
return;
@@ -983,9 +995,9 @@ static void usage(void)
fputs(_("Single-user login.\n"), out);
fputs(USAGE_OPTIONS, out);
- fputs(_(" -p, --login-shell start a login shell\n"
+ fputs(_(" -p, --login-shell start a login shell\n"
" -t, --timeout <seconds> max time to wait for a password (default: no limit)\n"
- " -e, --force examine password files directly if getpwnam(3) fails\n"),
+ " -e, --force examine password files directly if getpwnam(3) fails\n"),
out);
fputs(USAGE_SEPARATOR, out);
@@ -1012,8 +1024,8 @@ int main(int argc, char **argv)
static const struct option longopts[] = {
{ "login-shell", no_argument, NULL, 'p' },
{ "timeout", required_argument, NULL, 't' },
- { "force", no_argument, NULL, 'e' },
- { "help", no_argument, NULL, 'h' },
+ { "force", no_argument, NULL, 'e' },
+ { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 }
};
@@ -1193,10 +1205,46 @@ int main(int argc, char **argv)
char *answer;
int doshell = 0;
int deny = !opt_e && locked_account_password(pwd->pw_passwd);
-
+#if defined(__s390__) || defined(__s390x__)
+ int vmcpfd = -1;
+ if (con->flags & (CON_3215|CON_3270)) {
+ vmcpfd = openvmcp();
+ if (vmcpfd >= 0) {
+ char *msg = queryspool(vmcpfd);
+ if (msg) {
+ parsespool(msg);
+ free(msg);
+ }
+ stopspool(vmcpfd);
+ }
+ }
+ if (con->flags & CON_3215) {
+ if (vmcpfd >= 0) {
+ char *msg = queryterm(vmcpfd);
+ if (msg) {
+ parseterm(msg);
+ free(msg);
+ }
+ setterm(vmcpfd, "0");
+ warning3215(vmcpfd);
+ }
+ }
+#endif
doprompt(passwd, con, deny);
- if ((answer = getpasswd(con)) == NULL)
+ answer = getpasswd(con);
+#if defined(__s390__) || defined(__s390x__)
+ if (vmcpfd >= 0) {
+ if (con->flags & CON_3215)
+ restoreterm(vmcpfd);
+ if (con->flags & (CON_3215|CON_3270))
+ restorespool(vmcpfd);
+ clearvmcp();
+ close(vmcpfd);
+ vmcpfd = -1;
+ }
+#endif
+ if (answer == NULL)
break;
if (deny) {
#ifdef HAVE_EXPLICIT_BZERO
diff --git a/login-utils/vmcp.c b/login-utils/vmcp.c
new file mode 100644
index 000000000..52c2d4a6b
--- /dev/null
+++ b/login-utils/vmcp.c
@@ -0,0 +1,236 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * vmcp.c - s390x 3215 console spool and terminal management
+ *
+ * Copyright 2026 Werner Fink, SUSE Software Solutions Germany GmbH
+ *
+ * Based on:
+ *
+ * Copyright IBM Corp. 2018
+ * s390-tools is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ *
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+
+int isinteger(const char *str)
+{
+ int errs = errno, ret = 1;
+ long __attribute__((__unused__)) val;
+ char *endptr;
+
+ errno = 0;
+ val = strtol(str, &endptr, 10);
+
+ /* Check if no digits were found at all */
+ if (str == endptr)
+ ret = 0;
+
+ /* Check for overflow or underflow */
+ if (errno == ERANGE)
+ ret = 0;
+
+ /* Check for trailing non-numeric characters (e.g., "123abc") */
+ if (*endptr != '\0')
+ ret = 0;
+
+ errno = errs;
+ return ret;
+}
+
+#if defined(__s390__) || defined(__s390x__)
+
+#define VMCP_DEVICE_NODE "/dev/vmcp"
+#define VMCP_GETSIZE _IOR(0x10, 3, int)
+#define VMCP_SETBUF _IOW(0x10, 2, int)
+#define VMCP_GETCODE _IOR(0x10, 1, int)
+
+static char *more, *hold;
+static int spooling;
+
+int openvmcp(void)
+{
+ return open(VMCP_DEVICE_NODE, O_RDWR|O_NOCTTY);
+}
+
+void clearvmcp(void)
+{
+ if (more) {
+ free(more);
+ more = NULL;
+ }
+ if (hold) {
+ free(hold);
+ hold = NULL;
+ }
+}
+
+static char* askvmcp(int fd, const char *question)
+{
+ long pagesize = sysconf(_SC_PAGESIZE);
+ int rc = 0, num, buffersize;
+ char* ret = NULL;
+
+ num = (strlen(question) + pagesize - 1)/pagesize;
+ buffersize = num * pagesize;
+
+ if (ioctl(fd, VMCP_SETBUF, &buffersize) == -1)
+ goto out;
+ do {
+ rc = write(fd, question, strlen(question));
+ if (rc < 0) {
+ if (errno != EINTR)
+ goto out;
+ }
+ } while (rc < 0);
+ if (ioctl(fd, VMCP_GETCODE, &rc) == -1)
+ goto out;
+ if (ioctl(fd, VMCP_GETSIZE, &buffersize) == -1)
+ goto out;
+ ret = (char*)malloc(buffersize);
+ if (!ret)
+ goto out;
+ do {
+ rc = read(fd, ret, buffersize);
+ if (rc < 0) {
+ if (errno != EINTR)
+ goto out;
+ }
+ } while (rc < 0);
+out:
+ return ret;
+}
+
+char* queryterm(int fd)
+{
+ const char* question = "QUERY TERMINAL";
+ return askvmcp(fd, question);
+}
+
+char* queryspool(int fd)
+{
+ const char* question = "QUERY VIRTUAL CONSOLE";
+ return askvmcp(fd, question);
+}
+
+static int writevmcp(int fd, char *instruction)
+{
+ long pagesize = sysconf(_SC_PAGESIZE);
+ int rc = 0, num, buffersize;
+ int ret = -1;
+
+ num = (strlen(instruction) + pagesize - 1)/pagesize;
+ buffersize = num * pagesize;
+
+ if (ioctl(fd, VMCP_SETBUF, &buffersize) == -1)
+ goto out;
+ do {
+ rc = write(fd, instruction, strlen(instruction));
+ if (rc < 0) {
+ if (errno != EINTR)
+ goto out;
+ }
+ } while (rc < 0);
+ if (ioctl(fd, VMCP_GETCODE, &rc) == -1)
+ goto out;
+ if (ioctl(fd, VMCP_GETSIZE, &buffersize) == -1)
+ goto out;
+ if (rc == 0 && buffersize == 0)
+ ret = 0;
+out:
+ return ret;
+}
+
+int setterm(int fd, char *tout)
+{
+ char *instruction;
+ int ret = -1;
+
+ if (asprintf(&instruction, "TERMINAL MORE %s 0 HOLD OFF", tout) == -1)
+ goto out;
+
+ ret = writevmcp(fd, instruction);
+ free(instruction);
+out:
+ return ret;
+}
+
+int restoreterm(int fd)
+{
+ char* instruction;
+ int ret = -1;
+
+ if (!more || !hold)
+ goto out;
+ if (asprintf(&instruction, "TERMINAL %s %s", more, hold) == -1)
+ goto out;
+
+ ret = writevmcp(fd, instruction);
+ free(instruction);
+out:
+ return ret;
+}
+
+int stopspool(int fd)
+{
+ char* instruction = "SPOOL CONSOLE STOP";
+ if (!spooling)
+ return 1;
+ return writevmcp(fd, instruction);
+}
+
+int restorespool(int fd)
+{
+ char* instruction = "SPOOL CONSOLE START";
+ if (!spooling)
+ return 1;
+ return writevmcp(fd, instruction);
+}
+
+void parseterm(char *msg)
+{
+ int n;
+ char *token, *ptr;
+ for (n = 1, ptr = msg; ; n++, ptr = NULL) {
+ token = strtok(ptr, ",\n");
+ if (!token)
+ break;
+ if (hold && more)
+ break;
+ while (*token == ' ')
+ token++;
+ if (strncmp("MORE ", token, 5) == 0)
+ more = strdup(token);
+ if (strncmp("HOLD ", token, 5) == 0)
+ hold = strdup(token);
+ }
+}
+
+void parsespool(char *msg)
+{
+ spooling = 0;
+ if (strstr(msg, " TERM START ") != NULL)
+ spooling = 1;
+}
+
+void warning3215(int fd)
+{
+ /*
+ * Warning: Do not translate this test as it might inlude then so called
+ * umlauts which in fact can not be encoded for the 3215 console interface.
+ * The 3215 console driver work in fact with EBCDIC codepage and the
+ * kernel has to translate such umlauts (multi or single bytes) with the
+ * correct EBCDIC character table (for german e.g. IBM-1141 or IBM-273).
+ */
+ (void) writevmcp(fd, "MESSAGE * WARNING: 3215 mode. Password visible!");
+ (void) writevmcp(fd, "MESSAGE * Ensure nobody is watching the screen.");
+}
+#endif
diff --git a/login-utils/vmcp.h b/login-utils/vmcp.h
new file mode 100644
index 000000000..50ef1ba90
--- /dev/null
+++ b/login-utils/vmcp.h
@@ -0,0 +1,29 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * vmcp.c - s390x 3215 console spool and terminal management
+ *
+ * Copyright 2026 Werner Fink, SUSE Software Solutions Germany GmbH
+ *
+ * Based on:
+ *
+ * Copyright IBM Corp. 2018
+ * s390-tools is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ *
+ */
+
+extern int isinteger(const char *str);
+#if defined(__s390__) || defined(__s390x__)
+extern int openvmcp(void);
+extern void clearvmcp(void);
+extern char* queryterm(int fd);
+extern char* queryspool(int fd);
+extern int setterm(int fd, char *tout);
+extern int stopspool(int fd);
+extern int restoreterm(int fd);
+extern int restorespool(int fd);
+extern void parseterm(char *msg);
+extern void parsespool(char *msg);
+extern void warning3215(int fd);
+#endif
--
2.51.0
^ permalink raw reply related
* Re: [PATCH] copyfilerange: (man) fix swapped offsets in command example
From: Karel Zak @ 2026-04-27 8:14 UTC (permalink / raw)
To: Benno Schulenberg; +Cc: Štěpán Němec, util-linux
In-Reply-To: <294a8ef5-e73d-4715-a824-ba0ca40e1067@telfort.nl>
On Thu, Apr 23, 2026 at 11:48:12AM +0200, Benno Schulenberg wrote:
>
> Op 22-04-2026 om 20:25 schreef Štěpán Němec:
> > Signed-off-by: Štěpán Němec <stepnem@smrk.net>
> > ---
>
> Thanks for the tweaked re-submission.
The patch has been applied. Thanks Štěpán.
> > In any case, if the preference is felt strongly enough to require
> > rerolls just for that, I believe it would make a great addition to
> > howto-contribute.txt
>
> Good idea. Will post a patch for that.
+1
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply
* [PATCH] chrt: Add support for (GRUB) bandwidth reclaim
From: Furkan Caliskan @ 2026-04-23 10:14 UTC (permalink / raw)
To: util-linux; +Cc: kzak, bensberg, vineethr, Furkan Caliskan
The SCHED_DEADLINE policy supports the (GRUB) Greedy Reclamation
of Unused Bandwidth algorithm. This allows tasks to reclaim
bandwidth that are left over by other deadline tasks that finish
their work early, or voluntarily yield the cpu.
Currently, chrt has no way to set the SCHED_FLAG_RECLAIM bit in
the sched_flags field of the sched_attr structure.
Add -G/--reclaim-grub option to allow users to toggle this feature
using the deadline scheduling class.
Signed-off-by: Furkan Caliskan <frn1furkan10@gmail.com>
---
schedutils/chrt.1.adoc | 3 +++
schedutils/chrt.c | 13 ++++++++++++-
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/schedutils/chrt.1.adoc b/schedutils/chrt.1.adoc
index b8d8874bc..da607d958 100644
--- a/schedutils/chrt.1.adoc
+++ b/schedutils/chrt.1.adoc
@@ -83,6 +83,9 @@ Specifies deadline parameter for *SCHED_DEADLINE* policy (Linux-specific).
*-R*, *--reset-on-fork*::
Use *SCHED_RESET_ON_FORK* or *SCHED_FLAG_RESET_ON_FORK* flag. Linux-specific, supported since 2.6.31.
+
+*-G*, *--reclaim-grub*::
+Enables GRUB (Greedy Reclamation of Unused Bandwidth) algorithm.
+
Each thread has a _reset-on-fork_ scheduling flag. When this flag is set, children created by *fork*(2) do not inherit privileged scheduling policies. After the _reset-on-fork_ flag has been enabled, it can be reset only if the thread has the *CAP_SYS_NICE* capability. This flag is disabled in child processes created by *fork*(2).
+
diff --git a/schedutils/chrt.c b/schedutils/chrt.c
index 273905e5d..1a081e566 100644
--- a/schedutils/chrt.c
+++ b/schedutils/chrt.c
@@ -46,6 +46,7 @@ struct chrt_ctl {
uint64_t runtime; /* --sched-* options */
uint64_t deadline;
uint64_t period;
+ uint64_t flag; /* For sched_attr->sched_flags member */
unsigned int all_tasks : 1, /* all threads of the PID */
reset_on_fork : 1, /* SCHED_RESET_ON_FORK or SCHED_FLAG_RESET_ON_FORK */
@@ -79,6 +80,7 @@ static void __attribute__((__noreturn__)) usage(void)
fputs(USAGE_SEPARATOR, out);
fputs(_("Scheduling options:\n"), out);
fputs(_(" -R, --reset-on-fork set reset-on-fork flag\n"), out);
+ fputs(_(" -G, --reclaim-grub set SCHED_FLAG_RECLAIM\n"), out);
fputs(_(" -T, --sched-runtime <ns> runtime parameter for DEADLINE\n"), out);
fputs(_(" -P, --sched-period <ns> period parameter for DEADLINE\n"), out);
fputs(_(" -D, --sched-deadline <ns> deadline parameter for DEADLINE\n"), out);
@@ -349,7 +351,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
/* old API is good enough for non-deadline */
if (!supports_runtime_param(ctl->policy))
return set_sched_one_by_setscheduler(ctl, pid);
-
+
/* not changed by chrt, follow the current setting */
sa.sched_nice = getpriority(PRIO_PROCESS, pid);
@@ -359,6 +361,7 @@ static int set_sched_one(struct chrt_ctl *ctl, pid_t pid)
sa.sched_runtime = ctl->runtime;
sa.sched_period = ctl->period;
sa.sched_deadline = ctl->deadline;
+ sa.sched_flags = ctl->flag;
# ifdef SCHED_FLAG_RESET_ON_FORK
/* Don't use SCHED_RESET_ON_FORK for sched_setattr()! */
@@ -417,6 +420,7 @@ int main(int argc, char **argv)
{ "sched-period", required_argument, NULL, 'P' },
{ "sched-deadline", required_argument, NULL, 'D' },
{ "reset-on-fork", no_argument, NULL, 'R' },
+ { "reclaim-grub", no_argument, NULL, 'G' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
{ NULL, no_argument, NULL, 0 }
@@ -460,6 +464,11 @@ int main(int argc, char **argv)
case 'R':
ctl->reset_on_fork = 1;
break;
+ case 'G':
+#ifdef SCHED_DEADLINE
+ ctl->flag |= SCHED_FLAG_RECLAIM;
+#endif
+ break;
case 'i':
#ifdef SCHED_IDLE
ctl->policy = SCHED_IDLE;
@@ -546,6 +555,8 @@ int main(int argc, char **argv)
if ((ctl->deadline || ctl->period) && ctl->policy != SCHED_DEADLINE)
errx(EXIT_FAILURE, _("--sched-{deadline,period} options are "
"supported for SCHED_DEADLINE only"));
+ if ((ctl->flag & SCHED_FLAG_RECLAIM) && ctl->policy != SCHED_DEADLINE)
+ errx(EXIT_FAILURE, _("--reclaim-grub is only supported for SCHED_DEADLINE"));
if (ctl->policy == SCHED_DEADLINE) {
/* The basic rule is runtime <= deadline <= period, so we can
* make deadline and runtime optional on command line. Note we
--
2.34.1
^ permalink raw reply related
* Re: [PATCH] copyfilerange: (man) fix swapped offsets in command example
From: Benno Schulenberg @ 2026-04-23 9:48 UTC (permalink / raw)
To: Štěpán Němec, util-linux
In-Reply-To: <20260422182503.1111558-1-stepnem@smrk.net>
[-- Attachment #1.1: Type: text/plain, Size: 934 bytes --]
Op 22-04-2026 om 20:25 schreef Štěpán Němec:
> Signed-off-by: Štěpán Němec <stepnem@smrk.net>
> ---
Thanks for the tweaked re-submission.
> That said, I see now that, had I gone more quantitative about it, I
> might have picked the one you prefer :-D
>
> ; git log | grep -c '(man): '
> 21
> ; git log | grep -c ': (man)'
> 289
That counts also the occurrences of those strings in the body of
the commit messages. Using --oneline would be more accurate:
$ git log --oneline | grep -c '(man): '
10
$ git log --oneline | grep -c ': (man)'
207
Those ten occurrences are all from the last three weeks. When
running those same commands for v2.42, the first count is zero.
> In any case, if the preference is felt strongly enough to require
> rerolls just for that, I believe it would make a great addition to
> howto-contribute.txt
Good idea. Will post a patch for that.
Benno
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply
* [PATCH] copyfilerange: (man) fix swapped offsets in command example
From: Štěpán Němec @ 2026-04-22 18:25 UTC (permalink / raw)
To: util-linux, Benno Schulenberg
In-Reply-To: <bd1c4673-ab3a-4934-a7d1-8113a48c9811@telfort.nl>
Signed-off-by: Štěpán Němec <stepnem@smrk.net>
---
On Wed, 22 Apr 2026 08:17:46 +0200
Benno Schulenberg wrote:
> The convention for the subject line when man pages are affected is:
>
> program: (man) description of change
Interesting.
I did recheck both Documentation/howto-contribute.txt and recent man
page commits before sending the patch, and, having failed to identify
clear guidance, went with the pattern that made more sense to me.
That said, I see now that, had I gone more quantitative about it, I
might have picked the one you prefer :-D
; git log | grep -c '(man): '
21
; git log | grep -c ': (man)'
289
Unfortunately I didn't.
In any case, if the preference is felt strongly enough to require
rerolls just for that, I believe it would make a great addition to
howto-contribute.txt (or at least applying it consistently in the actual
project commit messages; the most recent '(man): ' is from 19. 4.).
Thanks,
Štěpán
misc-utils/copyfilerange.1.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc-utils/copyfilerange.1.adoc b/misc-utils/copyfilerange.1.adoc
index 303a1a7b25e2..89b95e9516fa 100644
--- a/misc-utils/copyfilerange.1.adoc
+++ b/misc-utils/copyfilerange.1.adoc
@@ -71,7 +71,7 @@
copyfilerange split-first-mb join ::
-copyfilerange split-remainder join 1M::
+copyfilerange split-remainder join :1M:
....
== SEE ALSO
base-commit: fff8c59c75355d365a69f86719e7bd7818c1daf4
--
2.53.0
^ permalink raw reply related
* Re: [PATCH] copyfilerange(man): fix swapped offsets in command example
From: Benno Schulenberg @ 2026-04-22 6:17 UTC (permalink / raw)
To: Štěpán Němec, util-linux
In-Reply-To: <20260420180528.943663-1-stepnem@smrk.net>
[-- Attachment #1.1: Type: text/plain, Size: 372 bytes --]
Op 20-04-2026 om 20:05 schreef Štěpán Němec:
> [...]
The convention for the subject line when man pages are affected is:
program: (man) description of change
So in this case:
copyfilerange: (man) fix swapped offsets in command example
Otherwise it looks as if copyfilerange is a function that is called
with man as argument.
Benno
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply
* Re: [PATCH] copyfilerange(man): fix swapped offsets in command example
From: Dick Marinus @ 2026-04-21 18:32 UTC (permalink / raw)
To: util-linux, Štěpán Němec
In-Reply-To: <20260420180528.943663-1-stepnem@smrk.net>
Thanks Štěpán,
I mixed up, thanks for correcting this!
greetings,
Dick Marinus
Quoting Štěpán Němec (2026-04-20 20:05:28)
> Signed-off-by: Štěpán Němec <stepnem@smrk.net>
> ---
> misc-utils/copyfilerange.1.adoc | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/misc-utils/copyfilerange.1.adoc b/misc-utils/copyfilerange.1.adoc
> index 303a1a7b25e2..89b95e9516fa 100644
> --- a/misc-utils/copyfilerange.1.adoc
> +++ b/misc-utils/copyfilerange.1.adoc
> @@ -71,7 +71,7 @@
>
> copyfilerange split-first-mb join ::
>
> -copyfilerange split-remainder join 1M::
> +copyfilerange split-remainder join :1M:
> ....
>
> == SEE ALSO
>
> base-commit: 2f0a4512ea813b050172207c88ddfa9ace12d830
> --
> 2.53.0
>
>
^ permalink raw reply
* [PATCH] copyfilerange(man): fix swapped offsets in command example
From: Štěpán Němec @ 2026-04-20 18:05 UTC (permalink / raw)
To: util-linux
Signed-off-by: Štěpán Němec <stepnem@smrk.net>
---
misc-utils/copyfilerange.1.adoc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/misc-utils/copyfilerange.1.adoc b/misc-utils/copyfilerange.1.adoc
index 303a1a7b25e2..89b95e9516fa 100644
--- a/misc-utils/copyfilerange.1.adoc
+++ b/misc-utils/copyfilerange.1.adoc
@@ -71,7 +71,7 @@
copyfilerange split-first-mb join ::
-copyfilerange split-remainder join 1M::
+copyfilerange split-remainder join :1M:
....
== SEE ALSO
base-commit: 2f0a4512ea813b050172207c88ddfa9ace12d830
--
2.53.0
^ permalink raw reply related
* Re: the bad effect of tables on msgids
From: Benno Schulenberg @ 2026-04-19 14:29 UTC (permalink / raw)
To: Karel Zak; +Cc: Util-Linux, Mario Blättermann
In-Reply-To: <dseehzodgm5vt2bmqewjf5oilq2vgfjno3ty6svabzf5q5ulo7@obi2pce56mfh>
[-- Attachment #1.1: Type: text/plain, Size: 2054 bytes --]
Op 08-04-2026 om 10:38 schreef Karel Zak:
> I have no strong opinion about it. For me, as a user, it is important
> to have data in man pages structured and easy to navigate without
> reading large paragraphs.
As said: simple list are less than three times the size of tables,
making them easier to navigate. And the lists are nicely indented,
whereas tables are flush with the left margin,leaving a big ugly-
looking empty space on the right.
> If you see a way to make things usable for others with a list, go ahead.
When I do:
git checkout v2.42
make distclean
./autogen.sh
./configure
make gen-poman-dist
git diff po-man/util-linux-man.pot
then I get differences: added "#, no-wrap" tags and added newlines (\n)
(see below), both with gettext-0.21 and with gettext-1.0. That probably
explains why a simple list (that is: a "delimited block") looks good for
me in the newly generated POT file, but ends up a messy long string in
the distributed util-linux-man.pot.
What is it the util-linux build environment that prevents these
"no-wrap" tags and the extra newlines that are in my build?
@@ -461,7 +463,8 @@ msgstr ""
#. type: Plain text
#: ../disk-utils/addpart.8.adoc:24
-msgid "*addpart* _device partition start length_"
+#, no-wrap
+msgid "*addpart* _device partition start length_\n"
msgstr ""
#. type: Title ==
@@ -552,10 +555,11 @@ msgstr ""
#. type: Plain text
#: ../disk-utils/addpart.8.adoc:28
+#, no-wrap
msgid ""
"*addpart* tells the Linux kernel about the existence of the specified "
"partition. The command is a simple wrapper around the \"add partition\" "
-"ioctl."
+"ioctl.\n"
msgstr ""
#. type: Plain text
@@ -695,7 +699,13 @@ msgstr ""
#. type: Plain text
#: ../disk-utils/addpart.8.adoc:54
-msgid "*delpart*(8), *fdisk*(8), *parted*(8), *partprobe*(8), *partx*(8)"
+#, no-wrap
+msgid ""
+"*delpart*(8),\n"
+"*fdisk*(8),\n"
+"*parted*(8),\n"
+"*partprobe*(8),\n"
+"*partx*(8)\n"
msgstr ""
Benno
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 840 bytes --]
^ permalink raw reply
* Re: Bug#1132887: script: "script file -c command" stopped working
From: Chris Hofstaedtler @ 2026-04-10 8:42 UTC (permalink / raw)
To: Karel Zak, 1132887; +Cc: Evgeny Kapun, util-linux, wanbingjiang
In-Reply-To: <x7m64hxjjld7rkfjwuta75hzmj3f6en57mpvdfttzdliebdqxn@ym5mhuzim23o>
On Tue, Apr 07, 2026 at 03:26:58PM +0200, Karel Zak wrote:
> On Tue, Apr 07, 2026 at 10:17:45AM +0200, Chris Hofstaedtler wrote:
> > thank you for the report, CC'ing upstream.
> >
> > On Tue, Apr 07, 2026 at 07:07:59AM +0300, Evgeny Kapun wrote:
> > > If I run script(1) as "script file -c command", it returns an error:
> > >
> > > script: unexpected number of arguments
> > > Try 'script --help' for more information.
> > >
> > > It used to work in earlier versions, so now scripts that rely on the old
> > > behavior are broken.
>
> I have created bugfix for this, see https://github.com/util-linux/util-linux/pull/4201
I've applied this fix to Debian as 2.42-2.
> Seems we will need v2.42.1 ASAP :-)
:-)
Thank you!
Chris
^ permalink raw reply
* Re: [PATCH RFC 0/2] Fix API breakage in libblkid
From: Zdenek Kabelac @ 2026-04-08 15:10 UTC (permalink / raw)
To: Carlos Maiolino; +Cc: kzak, util-linux, amulhern
In-Reply-To: <adZnDrqOXWtV9nUB@nidhogg.toxiclabs.cc>
Dne 08. 04. 26 v 16:49 Carlos Maiolino napsal(a):
> On Wed, Apr 08, 2026 at 03:32:14PM +0200, Zdenek Kabelac wrote:
>> Dne 08. 04. 26 v 15:19 Carlos Maiolino napsal(a):
>>> On Wed, Apr 08, 2026 at 01:47:27PM +0200, Zdenek Kabelac wrote:
>>>> Dne 08. 04. 26 v 12:35 cem@kernel.org napsal(a):
>>>>> From: Carlos Maiolino <cem@kernel.org>
>>>>>
>>> So, although I agree with you that Stratis is using libblkid incorrectly,
>>> I still think this patch is wrong, as it changes the library's behavior
>>> to fix a problem in LVM (if there is where the race was), and not some
>>> inherent library problem. If, no user can use libblkid to query into a
>>> private device, then the above lib call sequence wasn't supposed to work
>>> either, and perhaps then, blkid_probe_set_device() should actually fail
>>> in a private device.
>>>
>>> Again, I just looked into the libblkid low-level implementation today,
>>> but it doesn't seem to be the library's job to be responsible for a race
>>> between open() and ioctl(DM_DEVICE_REMOVE).
>>>
>>
>> Hi
>>
>> The main missed concept here is - this is not breaking any API.
>
> I disagree... Same lib call, same device, works before your patch, does
> not after... You may call it a bug that shouldn't be relied on, but
> that's for sure an API breakage.
>
Well - DM with private suffix is private - that's the API and defined long
time in history - to avoid any interaction with private device and libblkid.
The fact here was a bug for a long while that such device could have been
still explored by some libblkid calls does not make it a legit API.
Stratis has 2 easy solutions/fixes:
a) dropping 'private' check for their device in util-linux.
b) use non-private UUID for a device that should be managed by user-space tools.
For lvm2/dm - it's clear we never want libblkid to access internal raid legs
or other types of private DM devs.
Also it should be noted - Stratis should not have been using 'internal' logic
without fully understanding concept of 'private' device in the 1st. place....
So eventually as a 'middle' ground solution we may possibly have new:
sysfs_devno_is_dm_really_private()
that would be called in my patch in this function that would be a replica of
sysfs_devno_is_dm_private() just with LVM suffix check.
But still this kind of defeats the original 'intention' of this check and
makes the code harder to follow.
So I'd still prefer a fix on Stratis to correct notation of the private device.
Regads
Zdenek
^ permalink raw reply
* Re: [PATCH RFC 0/2] Fix API breakage in libblkid
From: Carlos Maiolino @ 2026-04-08 14:49 UTC (permalink / raw)
To: Zdenek Kabelac; +Cc: kzak, util-linux, amulhern
In-Reply-To: <94e57a5d-2f49-4e16-8328-5cf30b41d7ff@redhat.com>
On Wed, Apr 08, 2026 at 03:32:14PM +0200, Zdenek Kabelac wrote:
> Dne 08. 04. 26 v 15:19 Carlos Maiolino napsal(a):
> > On Wed, Apr 08, 2026 at 01:47:27PM +0200, Zdenek Kabelac wrote:
> > > Dne 08. 04. 26 v 12:35 cem@kernel.org napsal(a):
> > > > From: Carlos Maiolino <cem@kernel.org>
> > > >
> > So, although I agree with you that Stratis is using libblkid incorrectly,
> > I still think this patch is wrong, as it changes the library's behavior
> > to fix a problem in LVM (if there is where the race was), and not some
> > inherent library problem. If, no user can use libblkid to query into a
> > private device, then the above lib call sequence wasn't supposed to work
> > either, and perhaps then, blkid_probe_set_device() should actually fail
> > in a private device.
> >
> > Again, I just looked into the libblkid low-level implementation today,
> > but it doesn't seem to be the library's job to be responsible for a race
> > between open() and ioctl(DM_DEVICE_REMOVE).
> >
>
> Hi
>
> The main missed concept here is - this is not breaking any API.
I disagree... Same lib call, same device, works before your patch, does
not after... You may call it a bug that shouldn't be relied on, but
that's for sure an API breakage.
>
> The concept of private DM device is to be a device that is not being touched
> by libblkid. So this was a pure bug in the libblkid code when there was a
> code path skipping check (and actually doing this check after opening
> private device).
Ok, you told me from where it comes from.
How different is it of any other tool that uses libblkid doing
open(); blkid_new_probe(); blkid_probe_set_device();
Instead of calling blkid_new_probe_from_filename() directly?
Because this still can easily access a private device.
>
> And actually IMHO there is a bigger issue - xfs tools are actually relying
> too much on content of udev DB - this DB is by design unreliable - so it's
> likely good for some quick checking - but i.e. in lvm2 - we always do a real
> disk read - udevDB is only advisory.
We don't do anything with udev. We use libblkid to query device's
geometry to properly configure the filesystem to be initialized there.
If blkid_new_probe_from_filename() fails, mkfs abort. It's up to the
user to pass the right device.
>
>
> Regards
>
> Zdenek
>
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox