1
0
mirror of https://github.com/systemd/systemd synced 2026-03-15 01:24:51 +01:00

Compare commits

..

11 Commits

Author SHA1 Message Date
Mike Yuan
95a7b7d474
core: several follow-ups for varlink EnqueueMarkedJobs() method (#40365) 2026-01-30 08:38:13 +01:00
Yu Watanabe
1d60b723a3
Fix bug in DM iteration and standardise how to iterate through DM layers (#40426)
get_block_device_harder_fd() currently only traverses one level of
device mapper stacking when looking for the underlying block device.
This causes issues with nested DM setups like dm-crypt on top of
dm-integrity, where we don't traverse enough to get the actual physical
device.

Fix this by iterating through all DM layers until we reach a device with
no underlying device. And while we're at it also make cgroups use the
same logic.

Fixes: #40419
2026-01-30 15:36:03 +09:00
Lennart Poettering
1ccf4fe026 discover-image: carefully process sidecars
We have been a bit sloppy with caring for the various sidecards. Address
that.
2026-01-30 14:13:49 +09:00
Philip Withnall
a05439097f docs: Add a diagram for the internals of sysupdate
I had to sketch this out before I could get the internals of
systemd-sysupdate straight in my head, particularly around how an
`UpdateSet` points to one `Instance` from each of a set of `Resource`s,
and those `Instance`s are either all sources or all targets.

Hopefully this is useful to the next person to look at the code.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2026-01-30 13:19:33 +09:00
Mike Yuan
f7823fdae0
core/varlink-manager: report individual job enqueue result if client sets 'more'
One nice property varlink has is that we can nicely report result
of individual operations on each unit, through the 'more' mechanism.
Hence do so for the EnqueueMarkedJobs() method.

Also, apply 502d6f4bc9b96009627f923dcc0ab53e5a181d78 for varlink
method too.

While at it, use lowerCamelCase for method reply fields,
as requested in
https://github.com/systemd/systemd/pull/40365#discussion_r2702344239.
2026-01-24 00:48:03 +01:00
Mike Yuan
927b861add
core/unit: make unit_queue_job_check_and_mangle_type() report bus error
Our internal logic speaks dbus errors, and that's not changing
anytime soon. Bus errors carried more comprehensive error message
hence let's always return a sd_bus_error on failure, and introduce
varlink_error_id_from_bus_error() for translation.
2026-01-24 00:48:02 +01:00
Mike Yuan
7228da61b9
core/varlink-manager: move varlink_unit_queue_job_one() to varlink-unit
It's quite likely that we'll introduce StartUnit() and alike
for varlink in the future, so the job enqueuing interface
should be generic. On top of that, the errors really belong
to Unit rather than Manager.
2026-01-24 00:48:02 +01:00
Mike Yuan
339fa01d21
core/varlink-manager: fix reload unit marker handling
If both restart and reload markers are set, the former takes
precedence.
2026-01-24 00:48:02 +01:00
Chris Down
b38943b01b blockdev-util: Iterate through all DM layers
get_block_device_harder_fd() currently only traverses one level of
device mapper stacking when looking for the underlying block device.
This causes issues with nested DM setups like dm-crypt on top of
dm-integrity, where we don't traverse enough to get the actual physical
device.

Fix this by iterating through all DM layers until we reach a device with
no underlying device.

Fixes: #40419
2026-01-23 21:27:12 +08:00
Chris Down
53c7b19572 storagetm: Track backing device recursively
device_track_back() only checks a single DM layer when resolving the
originating device. Use
block_device_get_originating(..., /* recursive= */ true) to follow
stacked layers.
2026-01-23 21:26:34 +08:00
Chris Down
7b8c4d01e6 blockdev-util: Add recursive lookup flag
Originating device lookups currently use separate entry points and
callers must decide between the single-step helper and manual looping.

Add a recursive flag to block_device_get_originating() and
block_get_originating(), and update callers to pass an explicit value.
2026-01-23 13:26:08 +08:00
21 changed files with 1103 additions and 153 deletions

851
docs/sysupdate-objects.svg Normal file
View File

@ -0,0 +1,851 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="316.28293mm"
height="306.23108mm"
viewBox="0 0 316.28293 306.23108"
version="1.1"
id="svg1"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
sodipodi:docname="drawing.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.74118967"
inkscape:cx="540.34752"
inkscape:cy="712.36826"
inkscape:window-width="1920"
inkscape:window-height="1043"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs1">
<marker
style="overflow:visible"
id="marker10"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path10" />
</marker>
<marker
style="overflow:visible"
id="Triangle"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135" />
</marker>
<marker
style="overflow:visible"
id="Triangle-8"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9" />
</marker>
<marker
style="overflow:visible"
id="marker10-2"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path10-6" />
</marker>
<marker
style="overflow:visible"
id="Triangle-8-6"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path135-9-3" />
</marker>
<marker
style="overflow:visible"
id="marker10-2-1"
refX="0"
refY="0"
orient="auto-start-reverse"
inkscape:stockid="Triangle arrow"
markerWidth="3"
markerHeight="3"
viewBox="0 0 1 1"
inkscape:isstock="true"
inkscape:collect="always"
preserveAspectRatio="xMidYMid">
<path
transform="scale(0.5)"
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
d="M 5.77,0 -2.88,5 V -5 Z"
id="path10-6-7" />
</marker>
</defs>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-6.3824526,-3.5266833)">
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3"
width="131.36539"
height="128.86658"
x="6.7824521"
y="61.045975"
rx="5.0009999"
ry="5" />
<g
id="g2">
<g
id="g1">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1"><tspan
sodipodi:role="line"
id="tspan1"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="110.50744"
id="text2"><tspan
sodipodi:role="line"
id="tspan2"
style="stroke-width:0.264583"
x="113.87379"
y="110.50744">pattern</tspan></text>
</g>
<g
id="g2-3"
transform="translate(0,17.732698)">
<g
id="g1-5">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1-2"><tspan
sodipodi:role="line"
id="tspan1-9"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="110.50744"
id="text2-1"><tspan
sodipodi:role="line"
id="tspan2-2"
style="stroke-width:0.264583"
x="113.87379"
y="110.50744">pattern</tspan></text>
</g>
<g
id="g3">
<g
id="g1-0"
transform="translate(0,35.465397)">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1-6"><tspan
sodipodi:role="line"
id="tspan1-1"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="145.97284"
id="text2-8"><tspan
sodipodi:role="line"
id="tspan2-7"
style="stroke-width:0.264583"
x="113.87379"
y="145.97284">pattern</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="47.416828"
y="162.0649"
id="text3"><tspan
sodipodi:role="line"
id="tspan3"
style="stroke-width:0.264583"
x="47.416828"
y="162.0649">⋮</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="59.971153"
y="74.610878"
id="text4"><tspan
sodipodi:role="line"
id="tspan4"
style="stroke-width:0.264583"
x="59.971153"
y="74.610878">Resource</tspan></text>
<text
xml:space="preserve"
style="font-size:6.35px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="118.45662"
y="86.030052"
id="text5"><tspan
sodipodi:role="line"
id="tspan5"
style="font-size:6.35px;stroke-width:0.264583"
x="118.45662"
y="86.030052">Partially loaded from .transfer file</tspan></text>
<g
id="g5"
transform="translate(0,-16.876938)">
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3-3"
width="131.36539"
height="128.86658"
x="190.90001"
y="77.922913"
rx="5.0009999"
ry="5" />
<g
id="g2-7"
transform="translate(184.11755,16.87694)">
<g
id="g1-59">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-2"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1-28"><tspan
sodipodi:role="line"
id="tspan1-97"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="110.50744"
id="text2-3"><tspan
sodipodi:role="line"
id="tspan2-6"
style="stroke-width:0.264583"
x="113.87379"
y="110.50744">pattern</tspan></text>
</g>
<g
id="g2-3-1"
transform="translate(184.11755,34.609638)">
<g
id="g1-5-2">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6-9"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1-2-3"><tspan
sodipodi:role="line"
id="tspan1-9-1"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="110.50744"
id="text2-1-9"><tspan
sodipodi:role="line"
id="tspan2-2-4"
style="stroke-width:0.264583"
x="113.87379"
y="110.50744">pattern</tspan></text>
</g>
<g
id="g3-7"
transform="translate(184.11755,16.87694)">
<g
id="g1-0-8"
transform="translate(0,35.465397)">
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62-4"
width="52.697277"
height="12.002567"
x="15.773956"
y="100.73308"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="64.392487"
y="110.51707"
id="text1-6-5"><tspan
sodipodi:role="line"
id="tspan1-1-0"
style="stroke-width:0.264583"
x="64.392487"
y="110.51707">Instance</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.87379"
y="145.97284"
id="text2-8-3"><tspan
sodipodi:role="line"
id="tspan2-7-6"
style="stroke-width:0.264583"
x="113.87379"
y="145.97284">pattern</tspan></text>
</g>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="231.53438"
y="178.94183"
id="text3-1"><tspan
sodipodi:role="line"
id="tspan3-0"
style="stroke-width:0.264583"
x="231.53438"
y="178.94183">⋮</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="244.0887"
y="91.487816"
id="text4-6"><tspan
sodipodi:role="line"
id="tspan4-3"
style="stroke-width:0.264583"
x="244.0887"
y="91.487816">Resource</tspan></text>
<text
xml:space="preserve"
style="font-size:6.35px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="302.57416"
y="102.90699"
id="text5-2"><tspan
sodipodi:role="line"
id="tspan5-0"
style="font-size:6.35px;stroke-width:0.264583"
x="302.57416"
y="102.90699">Partially loaded from .transfer file</tspan></text>
</g>
<rect
style="fill:#ff7f2a;fill-opacity:1;stroke:#b56f0d;stroke-width:0.880404;stroke-opacity:1"
id="rect6"
width="111.65157"
height="42.399162"
x="6.8226547"
y="3.9668853"
rx="4.9974012"
ry="6.0599365" />
<text
xml:space="preserve"
style="font-size:6.35px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="92.622543"
y="28.901594"
id="text5-8"><tspan
sodipodi:role="line"
id="tspan5-8"
style="font-size:6.35px;stroke-width:0.264583"
x="92.622543"
y="28.901594">Loaded from .transfer file</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="55.061909"
y="16.949841"
id="text6"><tspan
sodipodi:role="line"
id="tspan6"
style="stroke-width:0.264583"
x="55.061913"
y="16.949841">Transfer</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="39.600597"
y="41.837189"
id="text7"><tspan
sodipodi:role="line"
id="tspan7"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;font-family:monospace;-inkscape-font-specification:monospace;stroke-width:0.264583"
x="39.600597"
y="41.837189">source</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;line-height:1.25;font-family:monospace;-inkscape-font-specification:monospace;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="113.82346"
y="41.837189"
id="text8"><tspan
sodipodi:role="line"
id="tspan8"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.76111px;font-family:monospace;-inkscape-font-specification:monospace;stroke-width:0.264583"
x="113.82346"
y="41.837189">target</tspan></text>
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Triangle)"
d="m 27.129808,44.621394 -0.356973,18.91947"
id="path8"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10)"
d="m 116.01562,40.337739 75.67789,23.203125"
id="path9"
sodipodi:nodetypes="cc" />
<g
id="g16"
transform="translate(-194.19231,210.25601)">
<rect
style="fill:#55d400;fill-opacity:1;stroke:#58b50d;stroke-width:1.12104;stroke-opacity:1"
id="rect10"
width="121.40612"
height="78.56958"
x="217.91293"
y="4.087204"
rx="5.8448224"
ry="8.4007883" />
<text
xml:space="preserve"
style="font-size:6.35px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="28.901594"
id="text5-8-9"><tspan
sodipodi:role="line"
id="tspan5-8-2"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="28.901594">Set of Instances taken from across</tspan><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="36.839092"
id="tspan11">all Transfers, matching a certain</tspan><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="44.776592"
id="tspan12">version; either all source Instances</tspan><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="52.714092"
id="tspan13">or all target Instances.</tspan><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="60.651592"
id="tspan14" /><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="68.589096"
id="tspan15">For example: verity, root FS,</tspan><tspan
sodipodi:role="line"
style="font-size:6.35px;text-align:start;text-anchor:start;stroke-width:0.264583"
x="222.03329"
y="76.526596"
id="tspan16">and kernel boot image</tspan></text>
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="277.00961"
y="16.949841"
id="text10"><tspan
sodipodi:role="line"
id="tspan10"
style="stroke-width:0.264583"
x="277.00961"
y="16.949841">UpdateSet</tspan></text>
</g>
<g
id="g19"
transform="matrix(0.26299485,0,0,0.26299485,127.72763,135.80969)">
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3-9"
width="131.36539"
height="128.86658"
x="202.28317"
y="291.19574"
rx="5.0009999"
ry="5" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-8"
width="52.697277"
height="12.002567"
x="211.27467"
y="330.88284"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6-1"
width="52.697277"
height="12.002567"
x="211.27467"
y="348.61554"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62-9"
width="52.697277"
height="12.002567"
x="211.27467"
y="366.34824"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="242.91754"
y="392.21466"
id="text3-7"><tspan
sodipodi:role="line"
id="tspan3-1"
style="stroke-width:0.264583"
x="242.91754"
y="392.21466">⋮</tspan></text>
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3-3-6"
width="131.36539"
height="128.86658"
x="386.40073"
y="291.19574"
rx="5.0009999"
ry="5" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-2-6"
width="52.697277"
height="12.002567"
x="395.39221"
y="330.88284"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6-9-1"
width="52.697277"
height="12.002567"
x="395.39221"
y="348.61554"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62-4-8"
width="52.697277"
height="12.002567"
x="395.39221"
y="366.34824"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="427.0351"
y="392.21466"
id="text3-1-3"><tspan
sodipodi:role="line"
id="tspan3-0-8"
style="stroke-width:0.264583"
x="427.0351"
y="392.21466">⋮</tspan></text>
<rect
style="fill:#ff7f2a;fill-opacity:1;stroke:#b56f0d;stroke-width:0.880404;stroke-opacity:1"
id="rect6-5"
width="111.65157"
height="42.399162"
x="202.32336"
y="234.11665"
rx="4.9974012"
ry="6.0599365" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Triangle-8)"
d="m 222.63053,274.77115 -0.35698,18.91947"
id="path8-4"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10-2)"
d="m 311.51634,270.4875 75.67789,23.20312"
id="path9-4"
sodipodi:nodetypes="cc" />
</g>
<g
id="g19-6"
transform="matrix(0.26299485,0,0,0.26299485,127.72763,199.17835)">
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3-9-2"
width="131.36539"
height="128.86658"
x="202.28317"
y="291.19574"
rx="5.0009999"
ry="5" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-8-1"
width="52.697277"
height="12.002567"
x="211.27467"
y="330.88284"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6-1-7"
width="52.697277"
height="12.002567"
x="211.27467"
y="348.61554"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62-9-8"
width="52.697277"
height="12.002567"
x="211.27467"
y="366.34824"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="242.91754"
y="392.21466"
id="text3-7-5"><tspan
sodipodi:role="line"
id="tspan3-1-7"
style="stroke-width:0.264583"
x="242.91754"
y="392.21466">⋮</tspan></text>
<rect
style="fill:#008075;fill-opacity:1;stroke:#0d64b5;stroke-width:0.799999;stroke-opacity:1"
id="rect3-3-6-4"
width="131.36539"
height="128.86658"
x="386.40073"
y="291.19574"
rx="5.0009999"
ry="5" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-2-6-1"
width="52.697277"
height="12.002567"
x="395.39221"
y="330.88284"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-6-9-1-8"
width="52.697277"
height="12.002567"
x="395.39221"
y="348.61554"
rx="6.8996673"
ry="4.9446111" />
<rect
style="fill:#f13900;stroke:#a93019;stroke-width:0.93445"
id="rect1-62-4-8-5"
width="52.697277"
height="12.002567"
x="395.39221"
y="366.34824"
rx="6.8996673"
ry="4.9446111" />
<text
xml:space="preserve"
style="font-size:10.5833px;line-height:1.25;font-family:sans-serif;-inkscape-font-specification:sans-serif;text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;stroke-width:0.264583"
x="427.0351"
y="392.21466"
id="text3-1-3-9"><tspan
sodipodi:role="line"
id="tspan3-0-8-7"
style="stroke-width:0.264583"
x="427.0351"
y="392.21466">⋮</tspan></text>
<rect
style="fill:#ff7f2a;fill-opacity:1;stroke:#b56f0d;stroke-width:0.880404;stroke-opacity:1"
id="rect6-5-5"
width="111.65157"
height="42.399162"
x="202.32336"
y="234.11665"
rx="4.9974012"
ry="6.0599365" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Triangle-8-6)"
d="m 222.63053,274.77115 -0.35698,18.91947"
id="path8-4-3"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10-2-1)"
d="m 311.51634,270.4875 75.67789,23.20312"
id="path9-4-8"
sodipodi:nodetypes="cc" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10)"
d="m 142.02963,226.88607 c 29.98558,-7.85336 26.92872,-47.36399 27.13167,-52.37021 2.14182,-52.83172 30.34254,-50.6899 30.34254,-50.6899"
id="path19"
sodipodi:nodetypes="csc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10)"
d="m 142.03149,232.34519 c 29.27163,16.0637 88.04009,-2.54025 88.04009,-2.54025"
id="path20"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker10)"
d="m 142.07294,241.56334 c 55.80936,38.16624 88.27271,50.05886 88.27271,50.05886"
id="path21"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -973,8 +973,7 @@ static int lookup_block_device(const char *p, dev_t *ret) {
} }
/* If this is a LUKS/DM device, recursively try to get the originating block device */ /* If this is a LUKS/DM device, recursively try to get the originating block device */
while (block_get_originating(*ret, ret) >= 0) (void) block_get_originating(*ret, ret, /* recursive= */ true);
;
/* If this is a partition, try to get the originating block device */ /* If this is a partition, try to get the originating block device */
(void) block_get_whole_disk(*ret, ret); (void) block_get_whole_disk(*ret, ret);

View File

@ -1962,19 +1962,11 @@ int bus_unit_queue_job_one(
assert(u); assert(u);
r = unit_queue_job_check_and_mangle_type(u, &type, /* reload_if_possible= */ FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE)); r = unit_queue_job_check_and_mangle_type(
if (r == -ENOENT) u,
return sd_bus_error_setf(reterr_error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id); &type,
if (r == -ELIBEXEC) /* reload_if_possible= */ FLAGS_SET(flags, BUS_UNIT_QUEUE_RELOAD_IF_POSSIBLE),
return sd_bus_error_setf(reterr_error, reterr_error);
BUS_ERROR_ONLY_BY_DEPENDENCY,
"Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
u->id);
if (r == -ESHUTDOWN)
return sd_bus_error_setf(reterr_error,
BUS_ERROR_SHUTTING_DOWN,
"Operation for unit %s refused, D-Bus is shutting down.",
u->id);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -7005,13 +7005,8 @@ UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependency
int unit_queue_job_check_and_mangle_type( int unit_queue_job_check_and_mangle_type(
Unit *u, Unit *u,
JobType *type, /* input and output */ JobType *type, /* input and output */
bool reload_if_possible) { bool reload_if_possible,
sd_bus_error *reterr_error) {
/* Returns:
*
* -ENOENT Unit not loaded
* -ELIBEXEC Unit can only be activated via dependency, not directly
* -ESHUTDOWN System bus is shutting down */
JobType t; JobType t;
@ -7030,13 +7025,16 @@ int unit_queue_job_check_and_mangle_type(
/* Our transaction logic allows units not properly loaded to be stopped. But if already dead /* Our transaction logic allows units not properly loaded to be stopped. But if already dead
* let's return clear error to caller. */ * let's return clear error to caller. */
if (t == JOB_STOP && UNIT_IS_LOAD_ERROR(u->load_state) && unit_active_state(u) == UNIT_INACTIVE) if (t == JOB_STOP && UNIT_IS_LOAD_ERROR(u->load_state) && unit_active_state(u) == UNIT_INACTIVE)
return -ENOENT; return sd_bus_error_setf(reterr_error, BUS_ERROR_NO_SUCH_UNIT, "Unit %s not loaded.", u->id);
if ((t == JOB_START && u->refuse_manual_start) || if ((t == JOB_START && u->refuse_manual_start) ||
(t == JOB_STOP && u->refuse_manual_stop) || (t == JOB_STOP && u->refuse_manual_stop) ||
(IN_SET(t, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) || (IN_SET(t, JOB_RESTART, JOB_TRY_RESTART) && (u->refuse_manual_start || u->refuse_manual_stop)) ||
(t == JOB_RELOAD_OR_START && job_type_collapse(t, u) == JOB_START && u->refuse_manual_start)) (t == JOB_RELOAD_OR_START && job_type_collapse(t, u) == JOB_START && u->refuse_manual_start))
return -ELIBEXEC; return sd_bus_error_setf(reterr_error,
BUS_ERROR_ONLY_BY_DEPENDENCY,
"Operation refused, unit %s may be requested by dependency only (it is configured to refuse manual start/stop).",
u->id);
/* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically /* dbus-broker issues StartUnit for activation requests, and Type=dbus services automatically
* gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start * gain dependency on dbus.socket. Therefore, if dbus has a pending stop job, the new start
@ -7050,7 +7048,10 @@ int unit_queue_job_check_and_mangle_type(
FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) { FOREACH_STRING(dbus_unit, SPECIAL_DBUS_SOCKET, SPECIAL_DBUS_SERVICE) {
Unit *dbus = manager_get_unit(u->manager, dbus_unit); Unit *dbus = manager_get_unit(u->manager, dbus_unit);
if (dbus && unit_stop_pending(dbus)) if (dbus && unit_stop_pending(dbus))
return -ESHUTDOWN; return sd_bus_error_setf(reterr_error,
BUS_ERROR_SHUTTING_DOWN,
"Operation for unit %s refused, D-Bus is shutting down.",
u->id);
} }
*type = t; *type = t;

View File

@ -1092,7 +1092,7 @@ UnitDependency unit_mount_dependency_type_to_dependency_type(UnitMountDependency
DECLARE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy); DECLARE_STRING_TABLE_LOOKUP(oom_policy, OOMPolicy);
int unit_queue_job_check_and_mangle_type(Unit *u, JobType *type, bool reload_if_possible); int unit_queue_job_check_and_mangle_type(Unit *u, JobType *type, bool reload_if_possible, sd_bus_error *reterr_error);
/* Macros which append UNIT= or USER_UNIT= to the message */ /* Macros which append UNIT= or USER_UNIT= to the message */

View File

@ -1,9 +1,33 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */ /* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "sd-bus.h"
#include "bus-common-errors.h"
#include "cpu-set-util.h" #include "cpu-set-util.h"
#include "json-util.h" #include "json-util.h"
#include "rlimit-util.h" #include "rlimit-util.h"
#include "varlink-common.h" #include "varlink-common.h"
#include "varlink-unit.h"
const char* varlink_error_id_from_bus_error(const sd_bus_error *e) {
static const struct {
const char *bus_error;
const char *varlink_error;
} map[] = {
{ BUS_ERROR_NO_SUCH_UNIT, VARLINK_ERROR_UNIT_NO_SUCH_UNIT },
{ BUS_ERROR_ONLY_BY_DEPENDENCY, VARLINK_ERROR_UNIT_ONLY_BY_DEPENDENCY },
{ BUS_ERROR_SHUTTING_DOWN, VARLINK_ERROR_UNIT_DBUS_SHUTTING_DOWN },
};
if (!sd_bus_error_is_set(e))
return NULL;
FOREACH_ELEMENT(i, map)
if (sd_bus_error_has_name(e, i->bus_error))
return i->varlink_error;
return NULL;
}
int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata) { int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata) {
const struct rlimit *rl = userdata; const struct rlimit *rl = userdata;

View File

@ -6,3 +6,5 @@
int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata); int rlimit_build_json(sd_json_variant **ret, const char *name, void *userdata);
int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata); int rlimit_table_build_json(sd_json_variant **ret, const char *name, void *userdata);
int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata); int cpuset_build_json(sd_json_variant **ret, const char *name, void *userdata);
const char* varlink_error_id_from_bus_error(const sd_bus_error *e);

View File

@ -2,15 +2,16 @@
#include <sys/prctl.h> #include <sys/prctl.h>
#include "sd-bus.h"
#include "sd-varlink.h" #include "sd-varlink.h"
#include "alloc-util.h" #include "alloc-util.h"
#include "architecture.h" #include "architecture.h"
#include "bitfield.h" #include "bitfield.h"
#include "build.h" #include "build.h"
#include "bus-error.h"
#include "bus-polkit.h" #include "bus-polkit.h"
#include "confidential-virt.h" #include "confidential-virt.h"
#include "dbus-job.h"
#include "errno-util.h" #include "errno-util.h"
#include "glyph-util.h" #include "glyph-util.h"
#include "json-util.h" #include "json-util.h"
@ -304,40 +305,6 @@ int vl_method_reexecute_manager(sd_varlink *link, sd_json_variant *parameters, s
return 1; return 1;
} }
static int varlink_manager_queue_job_one(
sd_varlink *link,
Unit *u,
JobType type,
JobMode mode,
uint32_t *ret_job_id) {
int r;
assert(u);
r = unit_queue_job_check_and_mangle_type(u, &type, /* reload_if_possible= */ BIT_SET(u->markers, UNIT_MARKER_NEEDS_RELOAD));
if (r == -ENOENT)
return varlink_error_no_such_unit(link, "name");
if (r == -ELIBEXEC)
return sd_varlink_errorb(link, VARLINK_ERROR_MANAGER_ONLY_BY_DEPENDENCY);
if (r == -ESHUTDOWN)
return sd_varlink_errorb(link, VARLINK_ERROR_MANAGER_BUS_SHUTTING_DOWN);
if (r < 0)
return r;
Job *j;
r = manager_add_job(u->manager, type, u, mode, /* reterr_error= */ NULL, &j);
if (r < 0)
return r;
/* Before we send the method reply, force out the announcement JobNew for this job */
bus_job_send_pending_change_signal(j, /* including_new= */ true);
if (ret_job_id)
*ret_job_id = j->id;
return 0;
}
int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) { int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
Manager *manager = ASSERT_PTR(userdata); Manager *manager = ASSERT_PTR(userdata);
@ -365,11 +332,12 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS)); log_info("Queuing reload/restart jobs for marked units%s", glyph(GLYPH_ELLIPSIS));
_cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL, *reply = NULL;
Unit *u; Unit *u;
char *k; char *k;
int ret = 0; int ret = 0;
HASHMAP_FOREACH_KEY(u, k, manager->units) { HASHMAP_FOREACH_KEY(u, k, manager->units) {
_cleanup_(sd_bus_error_free) sd_bus_error bus_error = SD_BUS_ERROR_NULL;
const char *error_id = NULL;
uint32_t job_id = 0; /* silence 'maybe-uninitialized' compiler warning */ uint32_t job_id = 0; /* silence 'maybe-uninitialized' compiler warning */
/* ignore aliases */ /* ignore aliases */
@ -380,33 +348,45 @@ int vl_method_enqueue_marked_jobs_manager(sd_varlink *link, sd_json_variant *par
continue; continue;
r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(JOB_TRY_RESTART)); r = mac_selinux_unit_access_check_varlink(u, link, job_type_to_access_method(JOB_TRY_RESTART));
if (r >= 0) if (r < 0)
r = varlink_manager_queue_job_one( error_id = SD_VARLINK_ERROR_PERMISSION_DENIED;
link, else
r = varlink_unit_queue_job_one(
u, u,
JOB_TRY_RESTART, JOB_TRY_RESTART,
JOB_FAIL, JOB_FAIL,
&job_id); /* reload_if_possible= */ !BIT_SET(u->markers, UNIT_MARKER_NEEDS_RESTART),
&job_id,
&bus_error);
if (ERRNO_IS_NEG_RESOURCE(r)) if (ERRNO_IS_NEG_RESOURCE(r))
return r; return r;
RET_GATHER(ret, r); if (r < 0)
if (r >= 0) { RET_GATHER(ret, log_unit_warning_errno(u, r, "Failed to enqueue marked job: %s",
r = sd_json_variant_append_arrayb(&array, SD_JSON_BUILD_UNSIGNED(job_id)); bus_error_message(&bus_error, r)));
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
continue;
if (r < 0) {
if (!error_id)
error_id = varlink_error_id_from_bus_error(&bus_error);
const char *error_msg = bus_error.message ?: error_id ? NULL : STRERROR(r);
r = sd_varlink_notifybo(link,
SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
JSON_BUILD_PAIR_STRING_NON_EMPTY("error", error_id),
JSON_BUILD_PAIR_STRING_NON_EMPTY("errorMessage", error_msg));
} else
r = sd_varlink_notifybo(link,
SD_JSON_BUILD_PAIR_STRING("unitID", u->id),
SD_JSON_BUILD_PAIR_INTEGER("jobID", job_id));
if (r < 0) if (r < 0)
return r; return r;
} }
}
if (ret < 0) if (ret < 0)
return ret; return ret;
/* Return parameter is not nullable, build empty array if there's nothing to return */ return sd_varlink_reply(link, NULL);
if (array)
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_VARIANT("JobIDs", array));
else
r = sd_json_buildo(&reply, SD_JSON_BUILD_PAIR_EMPTY_ARRAY("JobIDs"));
if (r < 0)
return r;
return sd_varlink_reply(link, reply);
} }

View File

@ -4,8 +4,6 @@
#include "core-forward.h" #include "core-forward.h"
#define VARLINK_ERROR_MANAGER_RATE_LIMIT_REACHED "io.systemd.Manager.RateLimitReached" #define VARLINK_ERROR_MANAGER_RATE_LIMIT_REACHED "io.systemd.Manager.RateLimitReached"
#define VARLINK_ERROR_MANAGER_ONLY_BY_DEPENDENCY "io.systemd.Manager.OnlyByDependency"
#define VARLINK_ERROR_MANAGER_BUS_SHUTTING_DOWN "io.systemd.Manager.BusShuttingDown"
int vl_method_describe_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_describe_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int vl_method_reexecute_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata); int vl_method_reexecute_manager(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -5,6 +5,7 @@
#include "bitfield.h" #include "bitfield.h"
#include "cgroup.h" #include "cgroup.h"
#include "condition.h" #include "condition.h"
#include "dbus-job.h"
#include "execute.h" #include "execute.h"
#include "format-util.h" #include "format-util.h"
#include "install.h" #include "install.h"
@ -382,13 +383,6 @@ static void unit_lookup_parameters_done(UnitLookupParameters *p) {
pidref_done(&p->pidref); pidref_done(&p->pidref);
} }
int varlink_error_no_such_unit(sd_varlink *v, const char *name) {
return sd_varlink_errorbo(
ASSERT_PTR(v),
VARLINK_ERROR_UNIT_NO_SUCH_UNIT,
JSON_BUILD_PAIR_STRING_NON_EMPTY("parameter", name));
}
static int varlink_error_conflict_lookup_parameters(sd_varlink *v, const UnitLookupParameters *p) { static int varlink_error_conflict_lookup_parameters(sd_varlink *v, const UnitLookupParameters *p) {
log_debug_errno( log_debug_errno(
ESRCH, ESRCH,
@ -511,3 +505,40 @@ int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varli
return sd_varlink_error(link, "io.systemd.Manager.NoSuchUnit", NULL); return sd_varlink_error(link, "io.systemd.Manager.NoSuchUnit", NULL);
} }
int varlink_unit_queue_job_one(
Unit *u,
JobType type,
JobMode mode,
bool reload_if_possible,
uint32_t *ret_job_id,
sd_bus_error *reterr_bus_error) {
int r;
assert(u);
r = unit_queue_job_check_and_mangle_type(u, &type, reload_if_possible, reterr_bus_error);
if (r < 0)
return r;
Job *j;
r = manager_add_job(u->manager, type, u, mode, reterr_bus_error, &j);
if (r < 0)
return r;
/* Before we send the method reply, force out the announcement JobNew for this job */
bus_job_send_pending_change_signal(j, /* including_new= */ true);
if (ret_job_id)
*ret_job_id = j->id;
return 0;
}
int varlink_error_no_such_unit(sd_varlink *v, const char *name) {
return sd_varlink_errorbo(
ASSERT_PTR(v),
VARLINK_ERROR_UNIT_NO_SUCH_UNIT,
JSON_BUILD_PAIR_STRING_NON_EMPTY("parameter", name));
}

View File

@ -4,6 +4,17 @@
#include "core-forward.h" #include "core-forward.h"
#define VARLINK_ERROR_UNIT_NO_SUCH_UNIT "io.systemd.Unit.NoSuchUnit" #define VARLINK_ERROR_UNIT_NO_SUCH_UNIT "io.systemd.Unit.NoSuchUnit"
#define VARLINK_ERROR_UNIT_ONLY_BY_DEPENDENCY "io.systemd.Unit.OnlyByDependency"
#define VARLINK_ERROR_UNIT_DBUS_SHUTTING_DOWN "io.systemd.Unit.DBusShuttingDown"
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);
int varlink_unit_queue_job_one(
Unit *u,
JobType type,
JobMode mode,
bool reload_if_possible,
uint32_t *ret_job_id,
sd_bus_error *reterr_bus_error);
int varlink_error_no_such_unit(sd_varlink *v, const char *name); int varlink_error_no_such_unit(sd_varlink *v, const char *name);
int vl_method_list_units(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata);

View File

@ -152,7 +152,7 @@ static int determine_default_node(void) {
return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Block device backing /var/ is not a LUKS2 device."); return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Block device backing /var/ is not a LUKS2 device.");
_cleanup_(sd_device_unrefp) sd_device *origin = NULL; _cleanup_(sd_device_unrefp) sd_device *origin = NULL;
r = block_device_get_originating(dev, &origin); r = block_device_get_originating(dev, &origin, /* recursive= */ false);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get originating device of LUKS2 device backing /var/: %m"); return log_error_errno(r, "Failed to get originating device of LUKS2 device backing /var/: %m");

View File

@ -9935,7 +9935,7 @@ static int acquire_root_devno(
return -ENOTBLK; return -ENOTBLK;
/* From dm-crypt to backing partition */ /* From dm-crypt to backing partition */
r = block_get_originating(devno, &devno); r = block_get_originating(devno, &devno, /* recursive= */ false);
if (r == -ENOENT) if (r == -ENOENT)
log_debug_errno(r, "Device '%s' has no dm-crypt/dm-verity device, no need to look for underlying block device.", p); log_debug_errno(r, "Device '%s' has no dm-crypt/dm-verity device, no need to look for underlying block device.", p);
else if (r < 0) else if (r < 0)

View File

@ -101,7 +101,7 @@ int block_device_get_whole_disk(sd_device *dev, sd_device **ret) {
return 0; return 0;
} }
int block_device_get_originating(sd_device *dev, sd_device **ret) { static int block_device_get_originating_one(sd_device *dev, sd_device **ret) {
_cleanup_(sd_device_unrefp) sd_device *first_found = NULL; _cleanup_(sd_device_unrefp) sd_device *first_found = NULL;
const char *suffix; const char *suffix;
dev_t devnum = 0; /* avoid false maybe-uninitialized warning */ dev_t devnum = 0; /* avoid false maybe-uninitialized warning */
@ -148,6 +148,39 @@ int block_device_get_originating(sd_device *dev, sd_device **ret) {
return 0; return 0;
} }
int block_device_get_originating(sd_device *dev, sd_device **ret, bool recursive) {
_cleanup_(sd_device_unrefp) sd_device *current = NULL;
int r;
assert(dev);
assert(ret);
if (!recursive)
return block_device_get_originating_one(dev, ret);
current = sd_device_ref(dev);
for (;;) {
sd_device *origin;
r = block_device_get_originating_one(current, &origin);
if (r == -ENOENT)
break;
if (r < 0)
return r;
sd_device_unref(current);
current = origin;
}
if (current == dev)
return -ENOENT;
*ret = TAKE_PTR(current);
return 0;
}
int block_device_new_from_fd(int fd, BlockDeviceLookupFlags flags, sd_device **ret) { int block_device_new_from_fd(int fd, BlockDeviceLookupFlags flags, sd_device **ret) {
_cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
dev_t devnum; dev_t devnum;
@ -172,7 +205,7 @@ int block_device_new_from_fd(int fd, BlockDeviceLookupFlags flags, sd_device **r
if (r < 0) if (r < 0)
return r; return r;
r = block_device_get_originating(dev_whole_disk, &dev_origin); r = block_device_get_originating(dev_whole_disk, &dev_origin, /* recursive= */ false);
if (r >= 0) if (r >= 0)
device_unref_and_replace(dev, dev_origin); device_unref_and_replace(dev, dev_origin);
else if (r != -ENOENT) else if (r != -ENOENT)
@ -290,7 +323,7 @@ int get_block_device(const char *path, dev_t *ret) {
return get_block_device_fd(fd, ret); return get_block_device_fd(fd, ret);
} }
int block_get_originating(dev_t dt, dev_t *ret) { int block_get_originating(dev_t dt, dev_t *ret, bool recursive) {
_cleanup_(sd_device_unrefp) sd_device *dev = NULL, *origin = NULL; _cleanup_(sd_device_unrefp) sd_device *dev = NULL, *origin = NULL;
int r; int r;
@ -300,7 +333,7 @@ int block_get_originating(dev_t dt, dev_t *ret) {
if (r < 0) if (r < 0)
return r; return r;
r = block_device_get_originating(dev, &origin); r = block_device_get_originating(dev, &origin, recursive);
if (r < 0) if (r < 0)
return r; return r;
@ -313,14 +346,14 @@ int get_block_device_harder_fd(int fd, dev_t *ret) {
assert(fd >= 0); assert(fd >= 0);
assert(ret); assert(ret);
/* Gets the backing block device for a file system, and handles LUKS encrypted file systems, looking for its /* Gets the backing block device for a file system, and handles LUKS encrypted file systems, looking
* immediate parent, if there is one. */ * for its underlying physical device, if there is one. */
r = get_block_device_fd(fd, ret); r = get_block_device_fd(fd, ret);
if (r <= 0) if (r <= 0)
return r; return r;
r = block_get_originating(*ret, ret); r = block_get_originating(*ret, ret, /* recursive= */ true);
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to chase block device, ignoring: %m"); log_debug_errno(r, "Failed to chase block device, ignoring: %m");

View File

@ -24,10 +24,9 @@ int block_device_new_from_path(const char *path, BlockDeviceLookupFlags flags, s
int block_device_is_whole_disk(sd_device *dev); int block_device_is_whole_disk(sd_device *dev);
int block_device_get_whole_disk(sd_device *dev, sd_device **ret); int block_device_get_whole_disk(sd_device *dev, sd_device **ret);
int block_device_get_originating(sd_device *dev, sd_device **ret); int block_device_get_originating(sd_device *dev, sd_device **ret, bool recursive);
int block_get_whole_disk(dev_t d, dev_t *ret); int block_get_whole_disk(dev_t d, dev_t *ret);
int block_get_originating(dev_t d, dev_t *ret); int block_get_originating(dev_t d, dev_t *ret, bool recursive);
int get_block_device_fd(int fd, dev_t *ret); int get_block_device_fd(int fd, dev_t *ret);
int get_block_device(const char *path, dev_t *ret); int get_block_device(const char *path, dev_t *ret);

View File

@ -131,6 +131,15 @@ static const char *const image_dirname_table[_IMAGE_CLASS_MAX] = {
[IMAGE_CONFEXT] = "confexts", [IMAGE_CONFEXT] = "confexts",
}; };
static const char auxiliary_suffixes_nulstr[] =
".nspawn\0"
".oci-config\0"
".roothash\0"
".roothash.p7s\0"
".usrhash\0"
".usrhash.p7s\0"
".verity\0";
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_dirname, ImageClass); DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_dirname, ImageClass);
static Image* image_free(Image *i) { static Image* image_free(Image *i) {
@ -221,12 +230,11 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
return TAKE_PTR(l); return TAKE_PTR(l);
} }
static int image_roothash_path(Image *image, char **ret) { static int image_auxiliary_path(Image *image, const char *suffix, char **ret) {
_cleanup_free_ char *fn = NULL;
assert(image); assert(image);
assert(suffix);
fn = strjoin(image->name, ".roothash"); _cleanup_free_ char *fn = strjoin(image->name, suffix);
if (!fn) if (!fn)
return -ENOMEM; return -ENOMEM;
@ -1200,7 +1208,6 @@ static int unprivileged_remove(Image *i) {
int image_remove(Image *i, RuntimeScope scope) { int image_remove(Image *i, RuntimeScope scope) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
_cleanup_free_ char *roothash = NULL;
int r; int r;
assert(i); assert(i);
@ -1212,10 +1219,6 @@ int image_remove(Image *i, RuntimeScope scope) {
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
r = image_roothash_path(i, &roothash);
if (r < 0)
return r;
/* Make sure we don't interfere with a running nspawn */ /* Make sure we don't interfere with a running nspawn */
r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
@ -1272,20 +1275,31 @@ int image_remove(Image *i, RuntimeScope scope) {
if (unlink(*j) < 0 && errno != ENOENT) if (unlink(*j) < 0 && errno != ENOENT)
log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j); log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j);
if (unlink(roothash) < 0 && errno != ENOENT) NULSTR_FOREACH(suffix, auxiliary_suffixes_nulstr) {
log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", roothash); _cleanup_free_ char *aux = NULL;
r = image_auxiliary_path(i, suffix, &aux);
if (r < 0)
return r;
if (unlink(aux) < 0 && errno != ENOENT)
log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", aux);
}
return 0; return 0;
} }
static int rename_auxiliary_file(const char *path, const char *new_name, const char *suffix) { static int rename_auxiliary_file(const char *path, const char *new_name, const char *suffix) {
_cleanup_free_ char *fn = NULL, *rs = NULL;
int r; int r;
fn = strjoin(new_name, suffix); assert(path);
assert(new_name);
assert(suffix);
_cleanup_free_ char *fn = strjoin(new_name, suffix);
if (!fn) if (!fn)
return -ENOMEM; return -ENOMEM;
_cleanup_free_ char *rs = NULL;
r = file_in_same_dir(path, fn, &rs); r = file_in_same_dir(path, fn, &rs);
if (r < 0) if (r < 0)
return r; return r;
@ -1295,7 +1309,7 @@ static int rename_auxiliary_file(const char *path, const char *new_name, const c
int image_rename(Image *i, const char *new_name, RuntimeScope scope) { int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
_cleanup_free_ char *new_path = NULL, *nn = NULL, *roothash = NULL; _cleanup_free_ char *new_path = NULL, *nn = NULL;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
unsigned file_attr = 0; unsigned file_attr = 0;
int r; int r;
@ -1312,10 +1326,6 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
r = image_roothash_path(i, &roothash);
if (r < 0)
return r;
/* Make sure we don't interfere with a running nspawn */ /* Make sure we don't interfere with a running nspawn */
r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
@ -1393,21 +1403,32 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j); log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j);
} }
r = rename_auxiliary_file(roothash, new_name, ".roothash"); NULSTR_FOREACH(suffix, auxiliary_suffixes_nulstr) {
_cleanup_free_ char *aux = NULL;
r = image_auxiliary_path(i, suffix, &aux);
if (r < 0)
return r;
r = rename_auxiliary_file(aux, new_name, suffix);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
log_debug_errno(r, "Failed to rename roothash file %s, ignoring: %m", roothash); log_debug_errno(r, "Failed to rename roothash file %s, ignoring: %m", aux);
}
return 0; return 0;
} }
static int clone_auxiliary_file(const char *path, const char *new_name, const char *suffix) { static int clone_auxiliary_file(const char *path, const char *new_name, const char *suffix) {
_cleanup_free_ char *fn = NULL, *rs = NULL;
int r; int r;
fn = strjoin(new_name, suffix); assert(path);
assert(new_name);
assert(suffix);
_cleanup_free_ char *fn = strjoin(new_name, suffix);
if (!fn) if (!fn)
return -ENOMEM; return -ENOMEM;
_cleanup_free_ char *rs = NULL;
r = file_in_same_dir(path, fn, &rs); r = file_in_same_dir(path, fn, &rs);
if (r < 0) if (r < 0)
return r; return r;
@ -1516,7 +1537,6 @@ static int unprivileged_clone(Image *i, const char *new_path) {
int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope) { int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope) {
_cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
_cleanup_free_ char *roothash = NULL;
int r; int r;
assert(i); assert(i);
@ -1528,10 +1548,6 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
r = image_roothash_path(i, &roothash);
if (r < 0)
return r;
/* Make sure nobody takes the new name, between the time we /* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the * checked it is currently unused in all search paths, and the
* time we take possession of it */ * time we take possession of it */
@ -1601,9 +1617,16 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j); log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j);
} }
r = clone_auxiliary_file(roothash, new_name, ".roothash"); NULSTR_FOREACH(suffix, auxiliary_suffixes_nulstr) {
_cleanup_free_ char *aux = NULL;
r = image_auxiliary_path(i, suffix, &aux);
if (r < 0)
return r;
r = clone_auxiliary_file(aux, new_name, suffix);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
log_debug_errno(r, "Failed to clone root hash file %s, ignoring: %m", roothash); log_debug_errno(r, "Failed to clone root hash file %s, ignoring: %m", aux);
}
return 0; return 0;
} }

View File

@ -181,17 +181,20 @@ static SD_VARLINK_DEFINE_METHOD(
static SD_VARLINK_DEFINE_METHOD( static SD_VARLINK_DEFINE_METHOD(
Reload); Reload);
static SD_VARLINK_DEFINE_METHOD( static SD_VARLINK_DEFINE_METHOD_FULL(
EnqueueMarkedJobs, EnqueueMarkedJobs,
SD_VARLINK_FIELD_COMMENT("IDs of enqueued jobs"), SD_VARLINK_SUPPORTS_MORE,
SD_VARLINK_DEFINE_OUTPUT(JobIDs, SD_VARLINK_INT, SD_VARLINK_ARRAY)); SD_VARLINK_FIELD_COMMENT("Enqueued unit ID"),
SD_VARLINK_DEFINE_OUTPUT(unitID, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("ID of enqueued job (if successful)"),
SD_VARLINK_DEFINE_OUTPUT(jobID, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Varlink error ID (on failure)"),
SD_VARLINK_DEFINE_OUTPUT(error, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
SD_VARLINK_FIELD_COMMENT("Job enqueue error message (on failure)"),
SD_VARLINK_DEFINE_OUTPUT(errorMessage, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(RateLimitReached); static SD_VARLINK_DEFINE_ERROR(RateLimitReached);
static SD_VARLINK_DEFINE_ERROR(OnlyByDependency);
static SD_VARLINK_DEFINE_ERROR(BusShuttingDown);
SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Manager, io_systemd_Manager,
"io.systemd.Manager", "io.systemd.Manager",
@ -203,10 +206,6 @@ SD_VARLINK_DEFINE_INTERFACE(
SD_VARLINK_SYMBOL_COMMENT("Enqueue all marked jobs"), SD_VARLINK_SYMBOL_COMMENT("Enqueue all marked jobs"),
&vl_method_EnqueueMarkedJobs, &vl_method_EnqueueMarkedJobs,
&vl_error_RateLimitReached, &vl_error_RateLimitReached,
SD_VARLINK_SYMBOL_COMMENT("Unit operation may be requested by dependency only"),
&vl_error_OnlyByDependency,
SD_VARLINK_SYMBOL_COMMENT("Operation refused, the bus is shutting down"),
&vl_error_BusShuttingDown,
&vl_type_ManagerContext, &vl_type_ManagerContext,
&vl_type_ManagerRuntime, &vl_type_ManagerRuntime,
&vl_type_Timestamp, &vl_type_Timestamp,

View File

@ -1003,10 +1003,6 @@ static SD_VARLINK_DEFINE_STRUCT_TYPE(
SD_VARLINK_FIELD_COMMENT("The cgroup runtime of the unit"), SD_VARLINK_FIELD_COMMENT("The cgroup runtime of the unit"),
SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupRuntime, SD_VARLINK_NULLABLE)); SD_VARLINK_DEFINE_FIELD_BY_TYPE(CGroup, CGroupRuntime, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(
NoSuchUnit,
SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_METHOD_FULL( static SD_VARLINK_DEFINE_METHOD_FULL(
List, List,
SD_VARLINK_SUPPORTS_MORE, SD_VARLINK_SUPPORTS_MORE,
@ -1023,6 +1019,13 @@ static SD_VARLINK_DEFINE_METHOD_FULL(
SD_VARLINK_FIELD_COMMENT("Runtime information of the unit"), SD_VARLINK_FIELD_COMMENT("Runtime information of the unit"),
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(runtime, UnitRuntime, 0)); SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(runtime, UnitRuntime, 0));
static SD_VARLINK_DEFINE_ERROR(
NoSuchUnit,
SD_VARLINK_DEFINE_FIELD(parameter, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
static SD_VARLINK_DEFINE_ERROR(OnlyByDependency);
static SD_VARLINK_DEFINE_ERROR(DBusShuttingDown);
SD_VARLINK_DEFINE_INTERFACE( SD_VARLINK_DEFINE_INTERFACE(
io_systemd_Unit, io_systemd_Unit,
"io.systemd.Unit", "io.systemd.Unit",
@ -1087,4 +1090,8 @@ SD_VARLINK_DEFINE_INTERFACE(
/* Errors */ /* Errors */
SD_VARLINK_SYMBOL_COMMENT("No matching unit found"), SD_VARLINK_SYMBOL_COMMENT("No matching unit found"),
&vl_error_NoSuchUnit); &vl_error_NoSuchUnit,
SD_VARLINK_SYMBOL_COMMENT("Job for the unit may only be enqueued by dependencies"),
&vl_error_OnlyByDependency,
SD_VARLINK_SYMBOL_COMMENT("A unit that requires D-Bus cannot be started as D-Bus is shutting down"),
&vl_error_DBusShuttingDown);

View File

@ -61,7 +61,7 @@ static int determine_auto_swap(sd_device *device) {
assert(device); assert(device);
r = block_device_get_originating(device, &origin); r = block_device_get_originating(device, &origin, /* recursive= */ false);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
return r; return r;
if (r >= 0) if (r >= 0)

View File

@ -848,7 +848,7 @@ static void device_track_back(sd_device *d, sd_device **ret) {
(void) sd_device_get_devname(d, &devname); (void) sd_device_get_devname(d, &devname);
_cleanup_(sd_device_unrefp) sd_device *d_originating = NULL; _cleanup_(sd_device_unrefp) sd_device *d_originating = NULL;
r = block_device_get_originating(d, &d_originating); r = block_device_get_originating(d, &d_originating, /* recursive= */ true);
if (r < 0 && r != -ENOENT) if (r < 0 && r != -ENOENT)
log_device_debug_errno(d, r, "Failed to get originating device for '%s', ignoring: %m", strna(devname)); log_device_debug_errno(d, r, "Failed to get originating device for '%s', ignoring: %m", strna(devname));

View File

@ -678,7 +678,7 @@ static int get_sysext_overlay_block(const char *p, dev_t *ret) {
return 0; return 0;
} }
(void) block_get_originating(*ret, ret); (void) block_get_originating(*ret, ret, /* recursive= */ false);
return 1; return 1;
} }