Merge ~ahasenack/ubuntu/+source/ndctl:ndctl-update-61.2 into ubuntu/+source/ndctl:ubuntu/devel
- Git
- lp:~ahasenack/ubuntu/+source/ndctl
- ndctl-update-61.2
- Merge into ubuntu/devel
Status: | Merged |
---|---|
Merge reported by: | Christian Ehrhardt |
Merged at revision: | 47adf392aa25bc4fc06b633c2eb79c4e57771cb0 |
Proposed branch: | ~ahasenack/ubuntu/+source/ndctl:ndctl-update-61.2 |
Merge into: | ubuntu/+source/ndctl:ubuntu/devel |
Diff against target: |
4760 lines (+1911/-844) 63 files modified
.gitignore (+3/-0) Documentation/asciidoctor-extensions.rb.in (+30/-0) Documentation/daxctl/Makefile.am (+27/-2) Documentation/daxctl/daxctl-list.txt (+7/-6) Documentation/ndctl/Makefile.am (+27/-2) Documentation/ndctl/namespace-description.txt (+50/-6) Documentation/ndctl/ndctl-create-namespace.txt (+1/-0) Documentation/ndctl/ndctl-disable-dimm.txt (+1/-1) Documentation/ndctl/ndctl-enable-region.txt (+1/-1) Documentation/ndctl/ndctl-init-labels.txt (+10/-5) Documentation/ndctl/ndctl-inject-error.txt (+14/-0) Documentation/ndctl/ndctl-list.txt (+8/-5) Documentation/ndctl/ndctl-start-scrub.txt (+4/-2) Documentation/ndctl/ndctl-wait-scrub.txt (+4/-2) Makefile.am (+2/-1) Makefile.am.in (+3/-3) README.md (+61/-41) autogen.sh (+1/-1) configure.ac (+28/-3) contrib/do_abidiff (+73/-0) contrib/prepare-release.sh (+198/-0) debian/changelog (+9/-0) debian/control (+1/-1) debian/libndctl6.symbols (+5/-0) git-version (+1/-1) ndctl/inject-error.c (+24/-16) ndctl/lib/ars.c (+60/-26) ndctl/lib/inject.c (+151/-50) ndctl/lib/libndctl.c (+11/-4) ndctl/lib/libndctl.sym (+8/-0) ndctl/lib/private.h (+3/-0) ndctl/libndctl.h (+12/-0) ndctl/util/json-smart.c (+27/-0) test.h (+12/-0) test/Makefile.am (+20/-3) test/blk-exhaust.sh (+11/-29) test/btt-check.sh (+34/-53) test/btt-errors.sh (+19/-31) test/btt-pad-compat.sh (+35/-53) test/clear.sh (+13/-33) test/common (+83/-0) test/create.sh (+16/-31) test/dax-pmd.c (+25/-8) test/dax-poison.c (+153/-0) test/dax.sh (+14/-5) test/daxdev-errors.sh (+14/-34) test/device-dax.c (+19/-9) test/dsm-fail.c (+254/-59) test/firmware-update.sh (+12/-39) test/inject-error.sh (+18/-37) test/label-compat.sh (+9/-27) test/libndctl.c (+10/-10) test/multi-dax.sh (+11/-31) test/pmem-errors.sh (+12/-27) test/rescan-partitions.sh (+22/-46) test/sector-mode.sh (+13/-26) util/abspath.c (+29/-0) util/filter.c (+104/-49) util/help.c (+0/-5) util/json.c (+27/-12) util/parse-options.c (+41/-6) util/parse-options.h (+9/-2) util/util.h (+7/-0) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Christian Ehrhardt (community) | Approve | ||
Canonical Server | Pending | ||
Review via email: mp+349590@code.launchpad.net |
Commit message
Description of the change
Update to new upstream release 61.2
I bumped standards-version to 4.1.5, after going over the checklist at https:/
Lintian output for ndctl 61.2-0ubuntu1, pedantic level: https:/
https:/
DEP8 run with packages from the ppa: http://
Christian Ehrhardt (paelzer) wrote : | # |
Andreas Hasenack (ahasenack) wrote : | # |
I'll check the orig tarball against the git content. Regarding versioning, I wouldn't want to make this a native package. There are other packages with a 0ubuntuN suffix, I just checked uvtool and it also doesn't have an original maintainer field in d/control, and doesn't exist in debian. I guess the warning has just been ignored in such cases.
- 22b52ab... by Andreas Hasenack
-
uupdate to 61.2
Andreas Hasenack (ahasenack) wrote : | # |
Ok, as discussed in standup, my uupdate was incorrect as it added built files into the branch, files that are not part of the orig tarball. I don't know how the ppa build worked, but it was incorrect and thanks for catching it.
I fixed that and pushed --force. I'm about to run dep8 tests.
Andreas Hasenack (ahasenack) wrote : | # |
Tests are good, ppa updated, dep8 results updated at http://
Christian Ehrhardt (paelzer) wrote : | # |
Thanks for fixing the built files!
It now also builds fine and LGTM.
If there is prio-art for the ignoring of the warning about Ubuntu versions without being a derivative then I'll be fine.
I tagged and pushed upload/
Andreas Hasenack (ahasenack) wrote : | # |
The upload tag is pointing at the correct hash, please sponsor. Thanks!
Christian Ehrhardt (paelzer) wrote : | # |
Done
Preview Diff
1 | diff --git a/.gitignore b/.gitignore |
2 | index 20a04de..1016b3b 100644 |
3 | --- a/.gitignore |
4 | +++ b/.gitignore |
5 | @@ -15,6 +15,8 @@ Makefile.in |
6 | *.1 |
7 | Documentation/daxctl/asciidoc.conf |
8 | Documentation/ndctl/asciidoc.conf |
9 | +Documentation/daxctl/asciidoctor-extensions.rb |
10 | +Documentation/ndctl/asciidoctor-extensions.rb |
11 | .dirstamp |
12 | daxctl/daxctl |
13 | daxctl/lib/libdaxctl.la |
14 | @@ -53,3 +55,4 @@ test/smart-listen |
15 | test/smart-notify |
16 | test/fio.job |
17 | test/local-write-0-verify.state |
18 | +test/ack-shutdown-count-set |
19 | diff --git a/Documentation/asciidoctor-extensions.rb.in b/Documentation/asciidoctor-extensions.rb.in |
20 | new file mode 100644 |
21 | index 0000000..a0307d0 |
22 | --- /dev/null |
23 | +++ b/Documentation/asciidoctor-extensions.rb.in |
24 | @@ -0,0 +1,30 @@ |
25 | +require 'asciidoctor' |
26 | +require 'asciidoctor/extensions' |
27 | + |
28 | +module @Utility@ |
29 | + module Documentation |
30 | + class Link@Utility@Processor < Asciidoctor::Extensions::InlineMacroProcessor |
31 | + use_dsl |
32 | + |
33 | + named :chrome |
34 | + |
35 | + def process(parent, target, attrs) |
36 | + if parent.document.basebackend? 'html' |
37 | + prefix = parent.document.attr('@utility@-relative-html-prefix') |
38 | + %(<a href="#{prefix}#{target}.html">#{target}(#{attrs[1]})</a>\n) |
39 | + elsif parent.document.basebackend? 'manpage' |
40 | + "#{target}(#{attrs[1]})" |
41 | + elsif parent.document.basebackend? 'docbook' |
42 | + "<citerefentry>\n" \ |
43 | + "<refentrytitle>#{target}</refentrytitle>" \ |
44 | + "<manvolnum>#{attrs[1]}</manvolnum>\n" \ |
45 | + "</citerefentry>\n" |
46 | + end |
47 | + end |
48 | + end |
49 | + end |
50 | +end |
51 | + |
52 | +Asciidoctor::Extensions.register do |
53 | + inline_macro @Utility@::Documentation::Link@Utility@Processor, :link@utility@ |
54 | +end |
55 | diff --git a/Documentation/daxctl/Makefile.am b/Documentation/daxctl/Makefile.am |
56 | index 259dafd..fc0fbe1 100644 |
57 | --- a/Documentation/daxctl/Makefile.am |
58 | +++ b/Documentation/daxctl/Makefile.am |
59 | @@ -9,11 +9,22 @@ |
60 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
61 | # General Public License for more details. |
62 | |
63 | -do_subst = sed -e 's,UTILITY,daxctl,g' |
64 | +if USE_ASCIIDOCTOR |
65 | + |
66 | +do_subst = sed -e 's,@Utility@,Daxctl,g' -e's,@utility@,daxctl,g' |
67 | +CONFFILE = asciidoctor-extensions.rb |
68 | +asciidoctor-extensions.rb: ../asciidoctor-extensions.rb.in |
69 | + $(AM_V_GEN) $(do_subst) < $< > $@ |
70 | |
71 | +else |
72 | + |
73 | +do_subst = sed -e 's,UTILITY,daxctl,g' |
74 | +CONFFILE = asciidoc.conf |
75 | asciidoc.conf: ../asciidoc.conf.in |
76 | $(AM_V_GEN) $(do_subst) < $< > $@ |
77 | |
78 | +endif |
79 | + |
80 | man1_MANS = \ |
81 | daxctl.1 \ |
82 | daxctl-list.1 |
83 | @@ -24,10 +35,22 @@ XML_DEPS = \ |
84 | ../../version.m4 \ |
85 | ../copyright.txt \ |
86 | Makefile \ |
87 | - asciidoc.conf |
88 | + $(CONFFILE) |
89 | |
90 | RM ?= rm -f |
91 | |
92 | +if USE_ASCIIDOCTOR |
93 | + |
94 | +%.1: %.txt $(XML_DEPS) |
95 | + $(AM_V_GEN)$(RM) $@+ $@ && \ |
96 | + $(ASCIIDOC) -b manpage -d manpage -acompat-mode \ |
97 | + -I. -rasciidoctor-extensions \ |
98 | + -amansource=daxctl -amanmanual="daxctl Manual" \ |
99 | + -andctl_version=$(VERSION) -o $@+ $< && \ |
100 | + mv $@+ $@ |
101 | + |
102 | +else |
103 | + |
104 | %.xml: %.txt $(XML_DEPS) |
105 | $(AM_V_GEN)$(RM) $@+ $@ && \ |
106 | $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \ |
107 | @@ -37,3 +60,5 @@ RM ?= rm -f |
108 | %.1: %.xml $(XML_DEPS) |
109 | $(AM_V_GEN)$(RM) $@ && \ |
110 | $(XMLTO) -o . -m ../manpage-normal.xsl man $< |
111 | + |
112 | +endif |
113 | diff --git a/Documentation/daxctl/daxctl-list.txt b/Documentation/daxctl/daxctl-list.txt |
114 | index 99ca4a1..cb82c3c 100644 |
115 | --- a/Documentation/daxctl/daxctl-list.txt |
116 | +++ b/Documentation/daxctl/daxctl-list.txt |
117 | @@ -1,7 +1,7 @@ |
118 | // SPDX-License-Identifier: GPL-2.0 |
119 | |
120 | daxctl-list(1) |
121 | -============= |
122 | +============== |
123 | |
124 | NAME |
125 | ---- |
126 | @@ -24,10 +24,9 @@ daxctl list --devices |
127 | |
128 | EXAMPLE |
129 | ------- |
130 | -[verse] |
131 | +---- |
132 | # daxctl list --regions --devices |
133 | |
134 | -["literal"] |
135 | { |
136 | "id":1, |
137 | "devices":[ |
138 | @@ -37,6 +36,7 @@ EXAMPLE |
139 | } |
140 | ] |
141 | } |
142 | +---- |
143 | |
144 | OPTIONS |
145 | ------- |
146 | @@ -54,14 +54,14 @@ OPTIONS |
147 | tuple, or keyword 'all' to filter the listing. For |
148 | example to list the first device instance in region1: |
149 | |
150 | -[verse] |
151 | +---- |
152 | # daxctl list --dev=1.0 |
153 | |
154 | -["literal"] |
155 | { |
156 | "chardev":"dax1.0", |
157 | "size":3233808384 |
158 | } |
159 | +---- |
160 | |
161 | -D:: |
162 | --devices:: |
163 | @@ -82,7 +82,7 @@ OPTIONS |
164 | will be formatted as human readable strings with units, other |
165 | fields are converted to hexadecimal strings. Example: |
166 | |
167 | -[verse] |
168 | +---- |
169 | # daxctl list |
170 | { |
171 | "chardev":"dax1.0", |
172 | @@ -94,5 +94,6 @@ OPTIONS |
173 | "chardev":"dax1.0", |
174 | "size":"30.57 GiB (32.83 GB)" |
175 | } |
176 | +---- |
177 | |
178 | include::../copyright.txt[] |
179 | diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am |
180 | index fab05b9..4fd9636 100644 |
181 | --- a/Documentation/ndctl/Makefile.am |
182 | +++ b/Documentation/ndctl/Makefile.am |
183 | @@ -9,11 +9,22 @@ |
184 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
185 | # General Public License for more details. |
186 | |
187 | -do_subst = sed -e 's,UTILITY,ndctl,g' |
188 | +if USE_ASCIIDOCTOR |
189 | + |
190 | +do_subst = sed -e 's,@Utility@,Ndctl,g' -e's,@utility@,ndctl,g' |
191 | +CONFFILE = asciidoctor-extensions.rb |
192 | +asciidoctor-extensions.rb: ../asciidoctor-extensions.rb.in |
193 | + $(AM_V_GEN) $(do_subst) < $< > $@ |
194 | |
195 | +else |
196 | + |
197 | +do_subst = sed -e 's,UTILITY,ndctl,g' |
198 | +CONFFILE = asciidoc.conf |
199 | asciidoc.conf: ../asciidoc.conf.in |
200 | $(AM_V_GEN) $(do_subst) < $< > $@ |
201 | |
202 | +endif |
203 | + |
204 | man1_MANS = \ |
205 | ndctl.1 \ |
206 | ndctl-wait-scrub.1 \ |
207 | @@ -42,7 +53,7 @@ CLEANFILES = $(man1_MANS) |
208 | XML_DEPS = \ |
209 | ../../version.m4 \ |
210 | Makefile \ |
211 | - asciidoc.conf \ |
212 | + $(CONFFILE) \ |
213 | ../copyright.txt \ |
214 | region-description.txt \ |
215 | xable-region-options.txt \ |
216 | @@ -55,6 +66,18 @@ XML_DEPS = \ |
217 | |
218 | RM ?= rm -f |
219 | |
220 | +if USE_ASCIIDOCTOR |
221 | + |
222 | +%.1: %.txt $(XML_DEPS) |
223 | + $(AM_V_GEN)$(RM) $@+ $@ && \ |
224 | + $(ASCIIDOC) -b manpage -d manpage -acompat-mode \ |
225 | + -I. -rasciidoctor-extensions \ |
226 | + -amansource=ndctl -amanmanual="ndctl Manual" \ |
227 | + -andctl_version=$(VERSION) -o $@+ $< && \ |
228 | + mv $@+ $@ |
229 | + |
230 | +else |
231 | + |
232 | %.xml: %.txt $(XML_DEPS) |
233 | $(AM_V_GEN)$(RM) $@+ $@ && \ |
234 | $(ASCIIDOC) -b docbook -d manpage -f asciidoc.conf \ |
235 | @@ -64,3 +87,5 @@ RM ?= rm -f |
236 | %.1: %.xml $(XML_DEPS) |
237 | $(AM_V_GEN)$(RM) $@ && \ |
238 | $(XMLTO) -o . -m ../manpage-normal.xsl man $< |
239 | + |
240 | +endif |
241 | diff --git a/Documentation/ndctl/namespace-description.txt b/Documentation/ndctl/namespace-description.txt |
242 | index 32ab5cd..1dd687e 100644 |
243 | --- a/Documentation/ndctl/namespace-description.txt |
244 | +++ b/Documentation/ndctl/namespace-description.txt |
245 | @@ -1,8 +1,52 @@ |
246 | // SPDX-License-Identifier: GPL-2.0 |
247 | |
248 | -DESCRIPTION |
249 | ------------ |
250 | -A REGION, after resolving DPA aliasing and LABEL specified boundaries, |
251 | -surfaces one or more "namespace" devices. The arrival of a "namespace" |
252 | -device currently triggers either the nd_blk or nd_pmem driver to load |
253 | -and register a disk/block device. |
254 | +THEORY OF OPERATION |
255 | +------------------- |
256 | +The capacity of an NVDIMM REGION (contiguous span of persistent memory) |
257 | +is accessed via one or more NAMESPACE devices. REGION is the Linux term |
258 | +for what ACPI and UEFI call a DIMM-interleave-set, or a |
259 | +system-physical-address-range that is striped (by the memory controller) |
260 | +across one or more memory modules. |
261 | + |
262 | +The UEFI specification defines the 'NVDIMM Label Protocol' as the |
263 | +combination of label area access methods and a data format for |
264 | +provisioning one or more NAMESPACE objects from a REGION. Note that |
265 | +label support is optional and if Linux does not detect the label |
266 | +capability it will automatically instantiate a "label-less" namespace |
267 | +per region. Examples of label-less namespaces are the ones created by |
268 | +the kernel's 'memmap=ss!nn' command line option (see the nvdimm wiki on |
269 | +kernel.org), or NVDIMMs without a valid 'namespace index' in their label |
270 | +area. |
271 | + |
272 | +A namespace can be provisioned to operate in one of 4 modes, 'fsdax', |
273 | +'devdax', 'sector', and 'raw'. Here are the expected usage models for |
274 | +these modes: |
275 | + - fsdax: Filesystem-DAX mode is the default mode of a namespace |
276 | + when specifying 'ndctl create-namespace' with no options. It creates |
277 | + a block device (/dev/pmemX[.Y]) that supports the DAX capabilities |
278 | + of Linux filesystems (xfs and ext4 to date). DAX removes the page |
279 | + cache from the I/O path and allows mmap(2) to establish direct |
280 | + mappings to persistent memory media. The DAX capability enables |
281 | + workloads / working-sets that would exceed the capacity of the page |
282 | + cache to scale up to the capacity of persistent memory. Workloads |
283 | + that fit in page cache or perform bulk data transfers may not see |
284 | + benefit from DAX. When in doubt, pick this mode. |
285 | + |
286 | + - devdax: Device-DAX mode enables similar mmap(2) DAX mapping |
287 | + capabilities as Filesystem-DAX. However, instead of a block-device |
288 | + that can support a DAX-enabled filesystem, this mode emits a single |
289 | + character device file (/dev/daxX.Y). Use this mode to assign |
290 | + persistent memory to a virtual-machine, register persistent memory |
291 | + for RDMA, or when gigantic mappings are needed. |
292 | + |
293 | + - sector: Use this mode to host legacy filesystems that do |
294 | + not checksum metadata or applications that are not prepared for torn |
295 | + sectors after a crash. Expected usage for this mode is for small |
296 | + boot volumes. This mode is compatible with other operating systems. |
297 | + |
298 | + - raw: Raw mode is effectively just a memory disk that does |
299 | + not support DAX. Typically this indicates a namespace that was |
300 | + created by tooling or another operating system that did not know how |
301 | + to create a Linux 'fsdax' or 'devdax' mode namespace. This mode is |
302 | + compatible with other operating systems, but again, does not support |
303 | + DAX operation. |
304 | diff --git a/Documentation/ndctl/ndctl-create-namespace.txt b/Documentation/ndctl/ndctl-create-namespace.txt |
305 | index 14c5409..4b8b0d1 100644 |
306 | --- a/Documentation/ndctl/ndctl-create-namespace.txt |
307 | +++ b/Documentation/ndctl/ndctl-create-namespace.txt |
308 | @@ -219,3 +219,4 @@ linkndctl:ndctl-init-labels[1], |
309 | linkndctl:ndctl-disable-namespace[1], |
310 | linkndctl:ndctl-enable-namespace[1], |
311 | http://www.uefi.org/sites/default/files/resources/UEFI_Spec_2_7.pdf[UEFI NVDIMM Label Protocol] |
312 | +https://nvdimm.wiki.kernel.org[Linux Persistent Memory Wiki] |
313 | diff --git a/Documentation/ndctl/ndctl-disable-dimm.txt b/Documentation/ndctl/ndctl-disable-dimm.txt |
314 | index d5a8d19..7706ac3 100644 |
315 | --- a/Documentation/ndctl/ndctl-disable-dimm.txt |
316 | +++ b/Documentation/ndctl/ndctl-disable-dimm.txt |
317 | @@ -1,7 +1,7 @@ |
318 | // SPDX-License-Identifier: GPL-2.0 |
319 | |
320 | ndctl-disable-dimm(1) |
321 | -======================= |
322 | +===================== |
323 | |
324 | NAME |
325 | ---- |
326 | diff --git a/Documentation/ndctl/ndctl-enable-region.txt b/Documentation/ndctl/ndctl-enable-region.txt |
327 | index 6c4ad9f..e5cbddb 100644 |
328 | --- a/Documentation/ndctl/ndctl-enable-region.txt |
329 | +++ b/Documentation/ndctl/ndctl-enable-region.txt |
330 | @@ -1,7 +1,7 @@ |
331 | // SPDX-License-Identifier: GPL-2.0 |
332 | |
333 | ndctl-enable-region(1) |
334 | -==================== |
335 | +====================== |
336 | |
337 | NAME |
338 | ---- |
339 | diff --git a/Documentation/ndctl/ndctl-init-labels.txt b/Documentation/ndctl/ndctl-init-labels.txt |
340 | index 580d82a..736d52d 100644 |
341 | --- a/Documentation/ndctl/ndctl-init-labels.txt |
342 | +++ b/Documentation/ndctl/ndctl-init-labels.txt |
343 | @@ -26,7 +26,7 @@ the DIMM. |
344 | EXAMPLE |
345 | ------- |
346 | Find the DIMMs that comprise a given region: |
347 | -[verse] |
348 | +---- |
349 | # ndctl list -RD --region=region1 |
350 | { |
351 | "dimms":[ |
352 | @@ -51,23 +51,28 @@ Find the DIMMs that comprise a given region: |
353 | } |
354 | ] |
355 | } |
356 | +---- |
357 | |
358 | Disable that region so the DIMM label area can be written from |
359 | userspace: |
360 | -[verse] |
361 | +---- |
362 | # ndctl disable-region region1 |
363 | +---- |
364 | |
365 | Initialize labels: |
366 | -[verse] |
367 | +---- |
368 | # ndctl init-labels nmem0 |
369 | +---- |
370 | |
371 | Re-enable the region: |
372 | -[verse] |
373 | +---- |
374 | # ndctl enable-region region1 |
375 | +---- |
376 | |
377 | Create a namespace in that region: |
378 | -[verse] |
379 | +---- |
380 | # ndctl create-namespace --region=region1 |
381 | +---- |
382 | |
383 | OPTIONS |
384 | ------- |
385 | diff --git a/Documentation/ndctl/ndctl-inject-error.txt b/Documentation/ndctl/ndctl-inject-error.txt |
386 | index 94c4e69..744ea50 100644 |
387 | --- a/Documentation/ndctl/ndctl-inject-error.txt |
388 | +++ b/Documentation/ndctl/ndctl-inject-error.txt |
389 | @@ -18,6 +18,15 @@ ndctl-inject-error can be used to ask the platform to simulate media errors |
390 | in the NVDIMM address space to aid debugging and development of features |
391 | related to error handling. |
392 | |
393 | +By default, injecting an error actually only injects an error to the first 'n' |
394 | +bytes of the block, where 'n' is the output of ndctl_cmd_ars_cap_get_size(). |
395 | +In other words, we only inject one 'ars_unit' per sector. This is sufficient |
396 | +for Linux to mark the whole sector as bad, and will show up as such in the |
397 | +various 'badblocks' lists in the kernel. If multiple blocks are being injected, |
398 | +only the first 'n' bytes of each block specified will be injected as errors. |
399 | +This can be overridden by the --saturate option, which will force the entire |
400 | +block to be injected as an error. |
401 | + |
402 | WARNING: These commands are DANGEROUS and can cause data loss. They are |
403 | only provided for testing and debugging purposes. |
404 | |
405 | @@ -88,6 +97,11 @@ OPTIONS |
406 | when the location is accessed. If the platform firmware does not |
407 | support this feature, this will have no effect. |
408 | |
409 | +-S:: |
410 | +--saturate:: |
411 | + This option forces error injection or un-injection to cover the entire |
412 | + address range covered by the specified block(s). |
413 | + |
414 | -v:: |
415 | --verbose:: |
416 | Emit debug messages for the error injection process |
417 | diff --git a/Documentation/ndctl/ndctl-list.txt b/Documentation/ndctl/ndctl-list.txt |
418 | index 2abc572..13ebdcd 100644 |
419 | --- a/Documentation/ndctl/ndctl-list.txt |
420 | +++ b/Documentation/ndctl/ndctl-list.txt |
421 | @@ -23,10 +23,9 @@ ndctl list --namespaces --bus=all --region=all |
422 | |
423 | EXAMPLE |
424 | ------- |
425 | -[verse] |
426 | +---- |
427 | # ndctl list --buses --namespaces |
428 | |
429 | -["literal"] |
430 | { |
431 | "provider":"nfit_test.1", |
432 | "dev":"ndbus2", |
433 | @@ -55,6 +54,7 @@ EXAMPLE |
434 | } |
435 | ] |
436 | } |
437 | +---- |
438 | |
439 | OPTIONS |
440 | ------- |
441 | @@ -67,8 +67,9 @@ include::xable-region-options.txt[] |
442 | An 'nmemX' device name, or dimm id number. Filter listing by |
443 | devices that reference the given dimm. For example to see all |
444 | namespaces comprised of storage capacity on nmem0: |
445 | -[verse] |
446 | +---- |
447 | # ndctl list --dimm=nmem0 --namespaces |
448 | +---- |
449 | |
450 | -n:: |
451 | --namespace=:: |
452 | @@ -201,7 +202,7 @@ include::xable-region-options.txt[] |
453 | |
454 | include::human-option.txt[] |
455 | |
456 | -[verse] |
457 | +---- |
458 | # ndctl list --region=7 |
459 | { |
460 | "dev":"region7", |
461 | @@ -211,8 +212,9 @@ include::human-option.txt[] |
462 | "iset_id":-6382611090938810793, |
463 | "badblock_count":8 |
464 | } |
465 | +---- |
466 | |
467 | -[verse] |
468 | +---- |
469 | # ndctl list --human --region=7 |
470 | { |
471 | "dev":"region7", |
472 | @@ -222,6 +224,7 @@ include::human-option.txt[] |
473 | "iset_id":"0xa76c6907811fae57", |
474 | "badblock_count":8 |
475 | } |
476 | +---- |
477 | |
478 | include::../copyright.txt[] |
479 | |
480 | diff --git a/Documentation/ndctl/ndctl-start-scrub.txt b/Documentation/ndctl/ndctl-start-scrub.txt |
481 | index 365918d..eb49fc2 100644 |
482 | --- a/Documentation/ndctl/ndctl-start-scrub.txt |
483 | +++ b/Documentation/ndctl/ndctl-start-scrub.txt |
484 | @@ -24,7 +24,7 @@ EXAMPLE |
485 | ------- |
486 | Start a scrub on all nvdimm buses in the system. The json listing report |
487 | only includes the buses that support ARS operations. |
488 | -[verse] |
489 | +---- |
490 | |
491 | # ndctl start-scrub |
492 | [ |
493 | @@ -39,12 +39,14 @@ only includes the buses that support ARS operations. |
494 | "scrub_state":"active" |
495 | } |
496 | ] |
497 | +---- |
498 | |
499 | When specifying an individual bus, or if there is only one bus in the |
500 | system, the command reports whether ARS support is available. |
501 | -[verse] |
502 | +---- |
503 | # ndctl start-scrub e820 |
504 | error starting scrub: Operation not supported |
505 | +---- |
506 | |
507 | OPTIONS |
508 | ------- |
509 | diff --git a/Documentation/ndctl/ndctl-wait-scrub.txt b/Documentation/ndctl/ndctl-wait-scrub.txt |
510 | index 6b5f61f..9aef687 100644 |
511 | --- a/Documentation/ndctl/ndctl-wait-scrub.txt |
512 | +++ b/Documentation/ndctl/ndctl-wait-scrub.txt |
513 | @@ -25,7 +25,7 @@ EXAMPLE |
514 | ------- |
515 | Wait for scrub on all nvdimm buses in the system. The json listing |
516 | report at the end only includes the buses that support ARS operations. |
517 | -[verse] |
518 | +---- |
519 | # ndctl wait-scrub |
520 | [ |
521 | { |
522 | @@ -39,12 +39,14 @@ report at the end only includes the buses that support ARS operations. |
523 | "scrub_state":"idle" |
524 | } |
525 | ] |
526 | +---- |
527 | |
528 | When specifying an individual bus, or if there is only one bus in the |
529 | system, the command reports whether ARS support is available. |
530 | -[verse] |
531 | +---- |
532 | # ndctl wait-scrub e820 |
533 | error waiting for scrub completion: Operation not supported |
534 | +---- |
535 | |
536 | OPTIONS |
537 | ------- |
538 | diff --git a/Makefile.am b/Makefile.am |
539 | index b538b1f..e0c463a 100644 |
540 | --- a/Makefile.am |
541 | +++ b/Makefile.am |
542 | @@ -69,6 +69,7 @@ libutil_a_SOURCES = \ |
543 | util/strbuf.c \ |
544 | util/wrapper.c \ |
545 | util/filter.c \ |
546 | - util/bitmap.c |
547 | + util/bitmap.c \ |
548 | + util/abspath.c |
549 | |
550 | nobase_include_HEADERS = daxctl/libdaxctl.h |
551 | diff --git a/Makefile.am.in b/Makefile.am.in |
552 | index 8a7bb6f..a148490 100644 |
553 | --- a/Makefile.am.in |
554 | +++ b/Makefile.am.in |
555 | @@ -35,9 +35,9 @@ SED_PROCESS = \ |
556 | -e 's,@includedir\@,$(includedir),g' \ |
557 | < $< > $@ || rm $@ |
558 | |
559 | -LIBNDCTL_CURRENT=15 |
560 | -LIBNDCTL_REVISION=0 |
561 | -LIBNDCTL_AGE=9 |
562 | +LIBNDCTL_CURRENT=16 |
563 | +LIBNDCTL_REVISION=1 |
564 | +LIBNDCTL_AGE=10 |
565 | |
566 | LIBDAXCTL_CURRENT=3 |
567 | LIBDAXCTL_REVISION=0 |
568 | diff --git a/README.md b/README.md |
569 | index 899dcbb..b4cf673 100644 |
570 | --- a/README.md |
571 | +++ b/README.md |
572 | @@ -5,11 +5,14 @@ sub-system in the Linux kernel |
573 | |
574 | Build |
575 | ===== |
576 | -`./autogen.sh` |
577 | -`./configure CFLAGS='-g -O0' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64` |
578 | -`make` |
579 | -`make check` |
580 | -`sudo make install` |
581 | + |
582 | +``` |
583 | +./autogen.sh |
584 | +./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64 |
585 | +make |
586 | +make check |
587 | +sudo make install |
588 | +``` |
589 | |
590 | There are a number of packages required for the build steps that may not |
591 | be installed by default. For information about the required packages, |
592 | @@ -23,45 +26,56 @@ See the latest documentation for the NVDIMM kernel sub-system here: |
593 | |
594 | https://git.kernel.org/cgit/linux/kernel/git/nvdimm/nvdimm.git/tree/Documentation/nvdimm/nvdimm.txt?h=libnvdimm-for-next |
595 | |
596 | +A getting started guide is also available on the kernel.org nvdimm wiki: |
597 | + |
598 | +https://nvdimm.wiki.kernel.org/start |
599 | + |
600 | Unit Tests |
601 | ========== |
602 | The unit tests run by `make check` require the nfit_test.ko module to be |
603 | loaded. To build and install nfit_test.ko: |
604 | |
605 | 1. Obtain the kernel source. For example, |
606 | -`git clone -b libnvdimm-for-next |
607 | -git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git` |
608 | + `git clone -b libnvdimm-for-next git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm.git` |
609 | |
610 | -2. Skip to step 3 if the kernel version is >= v4.8. Otherwise, for |
611 | +1. Skip to step 3 if the kernel version is >= v4.8. Otherwise, for |
612 | kernel versions < v4.8, configure the kernel to make some memory |
613 | available to CMA (contiguous memory allocator). This will be used to |
614 | emulate DAX. |
615 | -`CONFIG_DMA_CMA=y` |
616 | -`CONFIG_CMA_SIZE_MBYTES=200` |
617 | -**or** |
618 | -`cma=200M` on the kernel command line. |
619 | + ``` |
620 | + CONFIG_DMA_CMA=y |
621 | + CONFIG_CMA_SIZE_MBYTES=200 |
622 | + ``` |
623 | + **or** |
624 | + `cma=200M` on the kernel command line. |
625 | |
626 | -3. Compile the libnvdimm sub-system as a module, make sure "zone device" |
627 | +1. Compile the libnvdimm sub-system as a module, make sure "zone device" |
628 | memory is enabled, and enable the btt, pfn, and dax features of the |
629 | sub-system: |
630 | -`CONFIG_X86_PMEM_LEGACY=m` |
631 | -`CONFIG_ZONE_DEVICE=y` |
632 | -`CONFIG_LIBNVDIMM=m` |
633 | -`CONFIG_BLK_DEV_PMEM=m` |
634 | -`CONFIG_ND_BLK=m` |
635 | -`CONFIG_BTT=y` |
636 | -`CONFIG_NVDIMM_PFN=y` |
637 | -`CONFIG_NVDIMM_DAX=y` |
638 | -`CONFIG_DEV_DAX_PMEM=m` |
639 | - |
640 | -4. Build and install the unit test enabled libnvdimm modules in the |
641 | + |
642 | + ``` |
643 | + CONFIG_X86_PMEM_LEGACY=m |
644 | + CONFIG_ZONE_DEVICE=y |
645 | + CONFIG_LIBNVDIMM=m |
646 | + CONFIG_BLK_DEV_PMEM=m |
647 | + CONFIG_ND_BLK=m |
648 | + CONFIG_BTT=y |
649 | + CONFIG_NVDIMM_PFN=y |
650 | + CONFIG_NVDIMM_DAX=y |
651 | + CONFIG_DEV_DAX_PMEM=m |
652 | + ``` |
653 | + |
654 | +1. Build and install the unit test enabled libnvdimm modules in the |
655 | following order. The unit test modules need to be in place prior to |
656 | the `depmod` that runs during the final `modules_install` |
657 | -`make M=tools/testing/nvdimm` |
658 | -`sudo make M=tools/testing/nvdimm modules_install` |
659 | -`sudo make modules_install` |
660 | |
661 | -5. Now run `make check` in the ndctl source directory, or `ndctl test`, |
662 | + ``` |
663 | + make M=tools/testing/nvdimm |
664 | + sudo make M=tools/testing/nvdimm modules_install |
665 | + sudo make modules_install |
666 | + ``` |
667 | + |
668 | +1. Now run `make check` in the ndctl source directory, or `ndctl test`, |
669 | if ndctl was built with `--enable-test`. |
670 | |
671 | Troubleshooting |
672 | @@ -73,23 +87,29 @@ test modules are not available, or the test versions of the modules are |
673 | superseded by the "in-tree/production" version of the modules `make |
674 | check` will skip tests and report a message like the following in |
675 | test/test-suite.log: |
676 | -`SKIP: libndctl` |
677 | -`==============` |
678 | -`test/init: nfit_test_init: nfit.ko: appears to be production version: /lib/modules/4.8.8-200.fc24.x86_64/kernel/drivers/acpi/nfit/nfit.ko.xz` |
679 | -`__ndctl_test_skip: explicit skip test_libndctl:2684` |
680 | -`nfit_test unavailable skipping tests` |
681 | + |
682 | +``` |
683 | +SKIP: libndctl |
684 | +============== |
685 | +test/init: nfit_test_init: nfit.ko: appears to be production version: /lib/modules/4.8.8-200.fc24.x86_64/kernel/drivers/acpi/nfit/nfit.ko.xz |
686 | +__ndctl_test_skip: explicit skip test_libndctl:2684 |
687 | +nfit_test unavailable skipping tests |
688 | +``` |
689 | |
690 | If the unit test modules are indeed available in the modules 'extra' |
691 | directory the default depmod policy can be overridden by adding a file |
692 | to /etc/depmod.d with the following contents: |
693 | -`override nfit * extra` |
694 | -`override device_dax * extra` |
695 | -`override dax_pmem * extra` |
696 | -`override libnvdimm * extra` |
697 | -`override nd_blk * extra` |
698 | -`override nd_btt * extra` |
699 | -`override nd_e820 * extra` |
700 | -`override nd_pmem * extra` |
701 | + |
702 | +``` |
703 | +override nfit * extra |
704 | +override device_dax * extra |
705 | +override dax_pmem * extra |
706 | +override libnvdimm * extra |
707 | +override nd_blk * extra |
708 | +override nd_btt * extra |
709 | +override nd_e820 * extra |
710 | +override nd_pmem * extra |
711 | +``` |
712 | |
713 | The nfit_test module emulates pmem with memory allocated via vmalloc(). |
714 | One of the side effects is that this breaks 'physically contiguous' |
715 | diff --git a/autogen.sh b/autogen.sh |
716 | index a23cf53..2a52688 100755 |
717 | --- a/autogen.sh |
718 | +++ b/autogen.sh |
719 | @@ -24,5 +24,5 @@ echo "----------------------------------------------------------------" |
720 | echo "Initialized build system. For a common configuration please run:" |
721 | echo "----------------------------------------------------------------" |
722 | echo |
723 | -echo "./configure CFLAGS='-g -O0' $args" |
724 | +echo "./configure CFLAGS='-g -O2' $args" |
725 | echo |
726 | diff --git a/configure.ac b/configure.ac |
727 | index 3eaac32..cf44260 100644 |
728 | --- a/configure.ac |
729 | +++ b/configure.ac |
730 | @@ -42,16 +42,29 @@ AS_IF([test "x$enable_docs" = "xyes"], [ |
731 | ]) |
732 | AM_CONDITIONAL([ENABLE_DOCS], [test "x$enable_docs" = "xyes"]) |
733 | |
734 | -AC_CHECK_PROG(ASCIIDOC, [asciidoc], [$(which asciidoc)], [missing]) |
735 | +AC_ARG_ENABLE([asciidoctor], |
736 | + AS_HELP_STRING([--enable-asciidoctor], |
737 | + [use asciidoctor for documentation build]), |
738 | + [], enable_asciidoctor=no) |
739 | +AM_CONDITIONAL([USE_ASCIIDOCTOR], [test "x$enable_asciidoctor" = "xyes"]) |
740 | +if test "x$enable_asciidoctor" = "xyes"; then |
741 | + asciidoc="asciidoctor" |
742 | +else |
743 | + asciidoc="asciidoc" |
744 | +fi |
745 | +AC_CHECK_PROG(ASCIIDOC, [$asciidoc], [$(which $asciidoc)], [missing]) |
746 | if test "x$ASCIIDOC" = xmissing -a "x$enable_docs" = "xyes"; then |
747 | - AC_MSG_ERROR([asciidoc needed to build documentation]) |
748 | + AC_MSG_ERROR([$asciidoc needed to build documentation]) |
749 | fi |
750 | AC_SUBST([ASCIIDOC]) |
751 | + |
752 | +if test x"$asciidoc" = x"asciidoc"; then |
753 | AC_CHECK_PROG(XMLTO, [xmlto], [$(which xmlto)], [missing]) |
754 | if test "x$XMLTO" = xmissing -a "x$enable_docs" = "xyes"; then |
755 | AC_MSG_ERROR([xmlto needed to build documentation]) |
756 | fi |
757 | AC_SUBST([XMLTO]) |
758 | +fi |
759 | |
760 | AC_C_TYPEOF |
761 | AC_DEFINE([HAVE_STATEMENT_EXPR], 1, [Define to 1 if you have statement expressions.]) |
762 | @@ -89,6 +102,14 @@ AS_IF([test "x$enable_test" = "xyes"], |
763 | [AC_DEFINE([ENABLE_TEST], [1], [ndctl test support])]) |
764 | AM_CONDITIONAL([ENABLE_TEST], [test "x$enable_test" = "xyes"]) |
765 | |
766 | +AC_CHECK_DECLS([BUS_MCEERR_AR], [enable_bus_mc_err=yes], [], [[#include <signal.h>]]) |
767 | +AC_CHECK_DECLS([MAP_SYNC], [enable_map_sync=yes], [], [[#include <linux/mman.h>]]) |
768 | + |
769 | +AS_IF([test "x$enable_bus_mc_err" = "xyes" -a "x$enable_map_sync" = "xyes"], |
770 | + [AC_DEFINE([ENABLE_POISON], [1], [ndctl test poison support])]) |
771 | +AM_CONDITIONAL([ENABLE_POISON], |
772 | + [test "x$enable_bus_mc_err" = "xyes" -a "x$enable_map_sync" = "xyes"]) |
773 | + |
774 | PKG_CHECK_MODULES([KMOD], [libkmod]) |
775 | PKG_CHECK_MODULES([UDEV], [libudev]) |
776 | PKG_CHECK_MODULES([UUID], [uuid]) |
777 | @@ -134,7 +155,11 @@ my_CFLAGS="\ |
778 | -Wsign-compare \ |
779 | -Wstrict-prototypes \ |
780 | -Wtype-limits \ |
781 | --Wmaybe-uninitialized |
782 | +-Wmaybe-uninitialized \ |
783 | +-Wdeclaration-after-statement \ |
784 | +-Wunused-result \ |
785 | +-D_FORTIFY_SOURCE=2 \ |
786 | +-O2 |
787 | " |
788 | AC_SUBST([my_CFLAGS]) |
789 | |
790 | diff --git a/contrib/do_abidiff b/contrib/do_abidiff |
791 | new file mode 100755 |
792 | index 0000000..a520c3c |
793 | --- /dev/null |
794 | +++ b/contrib/do_abidiff |
795 | @@ -0,0 +1,73 @@ |
796 | +#!/bin/bash -e |
797 | + |
798 | +range="$*" |
799 | +old="${range%%..*}" |
800 | +new="${range##*..}" |
801 | + |
802 | +err() |
803 | +{ |
804 | + echo "$1" |
805 | + exit 1 |
806 | +} |
807 | + |
808 | +build_rpm() |
809 | +{ |
810 | + local cur=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) |
811 | + local ref="$1" |
812 | + local version="" |
813 | + |
814 | + # prepare ndctl tree |
815 | + rm -rf results_ndctl |
816 | + git checkout -b rel_${ref} $ref |
817 | + ./autogen.sh |
818 | + ./configure CFLAGS='-g -O2' --prefix=/usr --sysconfdir=/etc --libdir=/usr/lib64 |
819 | + make clean |
820 | + make rhel/ndctl.spec |
821 | + cp rhel/ndctl.spec . |
822 | + |
823 | + # build and copy RPMs |
824 | + version="$(./git-version)" |
825 | + git archive --format=tar --prefix="ndctl-${version}/" HEAD | gzip > ndctl-${version}.tar.gz |
826 | + fedpkg --release master --module-name ndctl mockbuild |
827 | + mkdir -p release/rel_${ref}/ |
828 | + cp results_ndctl/*/*/*.x86_64.rpm release/rel_${ref}/ |
829 | + |
830 | + # restore ndctl branch and cleanup |
831 | + git checkout $cur |
832 | + git branch -D rel_${ref} |
833 | + rm ndctl-${version}.tar.gz |
834 | + rm ndctl-${version}*.src.rpm |
835 | + rm -rf results_ndctl |
836 | + rm -f ndctl.spec |
837 | +} |
838 | + |
839 | +do_diff() |
840 | +{ |
841 | + local pkg="$1" |
842 | + local old_base="$(find . -regex "./release/rel_${old}/${pkg}-[0-9]+.*" | head -1)" |
843 | + local new_base="$(find . -regex "./release/rel_${new}/${pkg}-[0-9]+.*" | head -1)" |
844 | + local old_dev="$(find . -regex "./release/rel_${old}/${pkg}-devel-[0-9]+.*" | head -1)" |
845 | + local new_dev="$(find . -regex "./release/rel_${new}/${pkg}-devel-[0-9]+.*" | head -1)" |
846 | + local old_lib="$(find . -regex "./release/rel_${old}/${pkg}-libs-[0-9]+.*" | head -1)" |
847 | + local new_lib="$(find . -regex "./release/rel_${new}/${pkg}-libs-[0-9]+.*" | head -1)" |
848 | + |
849 | + [ -n "$pkg" ] || err "specify a package for diff (ndctl, daxctl)" |
850 | + |
851 | + abipkgdiff --dso-only --no-added-syms --harmless --drop-private-types \ |
852 | + --devel1 "$old_dev" --devel2 "$new_dev" \ |
853 | + "$old_base" "$new_base" |
854 | + abipkgdiff --no-added-syms --harmless --drop-private-types \ |
855 | + --devel1 "$old_dev" --devel2 "$new_dev" \ |
856 | + "$old_lib" "$new_lib" |
857 | +} |
858 | + |
859 | +[ -e "COPYING" ] || err "Run from the top level of an ndctl tree" |
860 | +if ! command -v "abipkgdiff" >/dev/null; then |
861 | + err "missing abipkgdiff. Please install libabigail" |
862 | +fi |
863 | +rm -rf release/rel* |
864 | + |
865 | +build_rpm $old > release/buildlog_$old 2>&1 |
866 | +build_rpm $new > release/buildlog_$new 2>&1 |
867 | +do_diff ndctl |
868 | +do_diff daxctl |
869 | diff --git a/contrib/prepare-release.sh b/contrib/prepare-release.sh |
870 | new file mode 100755 |
871 | index 0000000..45be4d8 |
872 | --- /dev/null |
873 | +++ b/contrib/prepare-release.sh |
874 | @@ -0,0 +1,198 @@ |
875 | +#!/bin/bash -e |
876 | + |
877 | +# Arguments: |
878 | +# fix - fixup release instead of a full release |
879 | +# ignore_rev - ignore the check for _REVISION in libtool versioning checks |
880 | + |
881 | +# Notes: |
882 | +# - Checkout to the appropriate branch beforehand |
883 | +# master - for major release |
884 | +# ndctl-xx.y - for fixup release |
885 | +# This is important for generating the shortlog |
886 | +# - Add a temporary commit that updates the libtool versions as needed. |
887 | +# This will later become the release commit. Use --amend to add in the |
888 | +# git-version update and the message body. |
889 | + |
890 | +# Pre-reqs: |
891 | +# - libabigail (for abipkgdiff) |
892 | +# - fedpkg (for mock build) |
893 | + |
894 | +# TODO |
895 | +# - auto generate a release commit/tag message template |
896 | +# - determine the most recent kernel release and add it to the above |
897 | +# - perform documentation update for pmem.io/ndctl |
898 | + |
899 | +cleanup() |
900 | +{ |
901 | + rm -rf release |
902 | + mkdir release/ |
903 | +} |
904 | + |
905 | +err() |
906 | +{ |
907 | + echo "$1" |
908 | + exit 1 |
909 | +} |
910 | + |
911 | +parse_args() |
912 | +{ |
913 | + local args="$*" |
914 | + grep -q "fix" <<< "$args" && rel_fix="1" || rel_fix="" |
915 | + grep -q "ignore_rev" <<< "$args" && ignore_rev="1" || ignore_rev="" |
916 | +} |
917 | + |
918 | +check_branch() |
919 | +{ |
920 | + local cur=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) |
921 | + if [ -n "$rel_fix" ]; then |
922 | + # fixup release, expect ndctl-xx.y branch |
923 | + if ! grep -Eq "^ndctl.[0-9]+\.y$" <<< "$cur"; then |
924 | + err "expected an ndctl-xx.y branch for fixup release" |
925 | + fi |
926 | + else |
927 | + # major release, expect master branch |
928 | + if ! grep -Eq "^master$" <<< "$cur"; then |
929 | + err "expected master branch for a major release" |
930 | + fi |
931 | + fi |
932 | + if ! git diff-index --quiet HEAD --; then |
933 | + err "$cur has uncommitted/unstaged changes" |
934 | + fi |
935 | +} |
936 | + |
937 | +last_maj() |
938 | +{ |
939 | + git tag | sort -V | grep -E "v[0-9]+$" | tail -1 |
940 | +} |
941 | + |
942 | +last_fix() |
943 | +{ |
944 | + local base="$1" |
945 | + git tag | sort -V | grep -E "$base\.?[0-9]*$" | tail -1 |
946 | +} |
947 | + |
948 | +next_maj() |
949 | +{ |
950 | + local last="$1" |
951 | + local num=${last#v} |
952 | + |
953 | + newnum="$((num + 1))" |
954 | + echo "v$newnum" |
955 | +} |
956 | + |
957 | +next_fix() |
958 | +{ |
959 | + local last="$1" |
960 | + local num=${last##*.} |
961 | + local base=${last%%.*} |
962 | + |
963 | + newnum=$((num + 1)) |
964 | + echo "$base.$newnum" |
965 | +} |
966 | + |
967 | +gen_lists() |
968 | +{ |
969 | + local range="$1" |
970 | + |
971 | + git shortlog "$range" > release/shortlog |
972 | + git log --pretty=format:"%s" "$range" > release/commits |
973 | + c_count=$(git log --pretty=format:"%s" "$range" | wc -l) |
974 | +} |
975 | + |
976 | +# Check libtool versions in Makefile.am.in |
977 | +# $1: lib name (currently libndctl or libdaxctl) |
978 | +check_libtool_vers() |
979 | +{ |
980 | + local lib="$1" |
981 | + local lib_u="${lib^^}" |
982 | + local libdir="${lib##lib}" |
983 | + local symfile="${libdir}/lib/${lib}.sym" |
984 | + local last_cur=$(git show $last_ref:Makefile.am.in | grep -E "^${lib_u}_CURRENT" | cut -d'=' -f2) |
985 | + local last_rev=$(git show $last_ref:Makefile.am.in | grep -E "^${lib_u}_REVISION" | cut -d'=' -f2) |
986 | + local last_age=$(git show $last_ref:Makefile.am.in | grep -E "^${lib_u}_AGE" | cut -d'=' -f2) |
987 | + local last_soname=$((last_cur - last_age)) |
988 | + local next_cur=$(git show HEAD:Makefile.am.in | grep -E "^${lib_u}_CURRENT" | cut -d'=' -f2) |
989 | + local next_rev=$(git show HEAD:Makefile.am.in | grep -E "^${lib_u}_REVISION" | cut -d'=' -f2) |
990 | + local next_age=$(git show HEAD:Makefile.am.in | grep -E "^${lib_u}_AGE" | cut -d'=' -f2) |
991 | + local next_soname=$((next_cur - next_age)) |
992 | + local soname_diff=$((next_soname - last_soname)) |
993 | + |
994 | + # generally libtool versions either reset to zero or increase only by one |
995 | + # _CURRENT monotonically increases (by one) |
996 | + if [ "$((next_cur - last_cur))" -gt 1 ]; then |
997 | + err "${lib_u}_CURRENT can increase at most by 1" |
998 | + fi |
999 | + if [ "$next_rev" -ne 0 ]; then |
1000 | + if [ "$((next_rev - last_rev))" -gt 1 ]; then |
1001 | + err "${lib_u}_REVISION can increase at most by 1" |
1002 | + fi |
1003 | + fi |
1004 | + if [ "$next_age" -ne 0 ]; then |
1005 | + if [ "$((next_age - last_age))" -gt 1 ]; then |
1006 | + err "${lib_u}_AGE can increase at most by 1" |
1007 | + fi |
1008 | + fi |
1009 | + |
1010 | + # test for soname change |
1011 | + if [ "$soname_diff" -ne 0 ]; then |
1012 | + err "${lib}: expected soname to stay unchanged" |
1013 | + fi |
1014 | + |
1015 | + # tests based on whether symfile changed |
1016 | + # compatibility breaking changes are left for libabigail to detect |
1017 | + test -s "$symfile" || err "$symfile: not found" |
1018 | + if [ -n "$(git diff --name-only $last_ref..HEAD $symfile)" ]; then |
1019 | + # symfile has changed, cur and age should increase |
1020 | + if [ "$((next_cur - last_cur))" -ne 1 ]; then |
1021 | + err "based on $symfile, ${lib_u}_CURRENT should've increased by 1" |
1022 | + fi |
1023 | + if [ "$((next_age - last_age))" -ne 1 ]; then |
1024 | + err "based on $symfile, ${lib_u}_AGE should've increased by 1" |
1025 | + fi |
1026 | + else |
1027 | + # no changes to symfile, revision should've increased if source changed |
1028 | + if [ -n "$ignore_rev" ]; then |
1029 | + : # skip |
1030 | + elif [ -n "$(git diff --name-only $last_ref..HEAD $libdir/)" ]; then |
1031 | + if [ "$((next_rev - last_rev))" -ne 1 ]; then |
1032 | + err "based on $symfile, ${lib_u}_REVISION should've increased by 1" |
1033 | + fi |
1034 | + fi |
1035 | + fi |
1036 | +} |
1037 | + |
1038 | + |
1039 | +# main |
1040 | +cleanup |
1041 | +parse_args "$*" |
1042 | +check_branch |
1043 | +[ -e "COPYING" ] || err "Run from the top level of an ndctl tree" |
1044 | + |
1045 | +last_maj=$(last_maj) |
1046 | +test -n "$last_maj" || err "Unable to determine last release" |
1047 | + |
1048 | +last_fix=$(last_fix $last_maj) |
1049 | +test -n "$last_fix" || err "Unable to determine last fixup tag for $last_maj" |
1050 | + |
1051 | +next_maj=$(next_maj "$last_maj") |
1052 | +next_fix=$(next_fix "$last_fix") |
1053 | +[ -n "$rel_fix" ] && last_ref="$last_fix" || last_ref="$last_maj" |
1054 | +[ -n "$rel_fix" ] && next_ref="$next_fix" || next_ref="$next_maj" |
1055 | + |
1056 | +check_libtool_vers "libndctl" |
1057 | +check_libtool_vers "libdaxctl" |
1058 | + |
1059 | +gen_lists ${last_ref}..HEAD |
1060 | + |
1061 | +# For ABI diff purposes, use the latest fixes tag |
1062 | +contrib/do_abidiff ${last_fix}..HEAD |
1063 | + |
1064 | +# once everything passes, update the git-version |
1065 | +sed -i -e "s/DEF_VER=[0-9]\+.*/DEF_VER=${next_ref#v}/" git-version |
1066 | + |
1067 | +echo "Ready to release ndctl-$next_ref with $c_count new commits." |
1068 | +echo "Add git-version to the top commit to get the updated version." |
1069 | +echo "Use release/commits and release/shortlog to compose the release message" |
1070 | +echo "The release commit typically contains the Makefile.am.in libtool version" |
1071 | +echo "update, and the git-version update." |
1072 | +echo "Finally, ensure the release commit as well as the tag are PGP signed." |
1073 | diff --git a/debian/changelog b/debian/changelog |
1074 | index 3185fb0..0996418 100644 |
1075 | --- a/debian/changelog |
1076 | +++ b/debian/changelog |
1077 | @@ -1,3 +1,12 @@ |
1078 | +ndctl (61.2-0ubuntu1) cosmic; urgency=medium |
1079 | + |
1080 | + * New upstream release |
1081 | + * d/libndctl6.symbols: added new symbols for version 61.2 |
1082 | + * d/control: updated Standards-Version to 4.1.5, no changes necessary. |
1083 | + Verified that the package isn't affected by the FHS 2.3->3.0 bump. |
1084 | + |
1085 | + -- Andreas Hasenack <andreas@canonical.com> Thu, 12 Jul 2018 12:00:59 -0300 |
1086 | + |
1087 | ndctl (60.1-0ubuntu1) cosmic; urgency=medium |
1088 | |
1089 | * Initial release. Closes: LP: #1752378. |
1090 | diff --git a/debian/control b/debian/control |
1091 | index b0617a4..c774907 100644 |
1092 | --- a/debian/control |
1093 | +++ b/debian/control |
1094 | @@ -11,7 +11,7 @@ Build-Depends: asciidoc, |
1095 | pkg-config, |
1096 | uuid-dev, |
1097 | xmlto |
1098 | -Standards-Version: 4.1.4 |
1099 | +Standards-Version: 4.1.5 |
1100 | Homepage: https://github.com/pmem/ndctl |
1101 | Vcs-Git: https://git.launchpad.net/ubuntu/+source/ndctl |
1102 | Vcs-Browser: https://code.launchpad.net/ubuntu/+source/ndctl/+git |
1103 | diff --git a/debian/libndctl6.symbols b/debian/libndctl6.symbols |
1104 | index 655be41..c4d186c 100644 |
1105 | --- a/debian/libndctl6.symbols |
1106 | +++ b/debian/libndctl6.symbols |
1107 | @@ -2,6 +2,7 @@ libndctl.so.6 libndctl6 #MINVER# |
1108 | LIBNDCTL_13@LIBNDCTL_13 60.1 |
1109 | LIBNDCTL_14@LIBNDCTL_14 60.1 |
1110 | LIBNDCTL_15@LIBNDCTL_15 60.1 |
1111 | + LIBNDCTL_16@LIBNDCTL_16 61.2 |
1112 | LIBNDCTL_1@LIBNDCTL_1 60.1 |
1113 | LIBNDCTL_3@LIBNDCTL_3 60.1 |
1114 | ndctl_bb_get_block@LIBNDCTL_14 60.1 |
1115 | @@ -55,12 +56,14 @@ libndctl.so.6 libndctl6 #MINVER# |
1116 | ndctl_bus_start_scrub@LIBNDCTL_15 60.1 |
1117 | ndctl_bus_wait_for_scrub_completion@LIBNDCTL_14 60.1 |
1118 | ndctl_bus_wait_probe@LIBNDCTL_3 60.1 |
1119 | + ndctl_cmd_ars_cap_get_clear_unit@LIBNDCTL_16 61.2 |
1120 | ndctl_cmd_ars_cap_get_range@LIBNDCTL_3 60.1 |
1121 | ndctl_cmd_ars_cap_get_size@LIBNDCTL_3 60.1 |
1122 | ndctl_cmd_ars_get_record_addr@LIBNDCTL_3 60.1 |
1123 | ndctl_cmd_ars_get_record_len@LIBNDCTL_3 60.1 |
1124 | ndctl_cmd_ars_in_progress@LIBNDCTL_3 60.1 |
1125 | ndctl_cmd_ars_num_records@LIBNDCTL_3 60.1 |
1126 | + ndctl_cmd_ars_stat_get_flag_overflow@LIBNDCTL_16 61.2 |
1127 | ndctl_cmd_cfg_read_get_data@LIBNDCTL_3 60.1 |
1128 | ndctl_cmd_cfg_read_get_size@LIBNDCTL_3 60.1 |
1129 | ndctl_cmd_cfg_size_get_size@LIBNDCTL_3 60.1 |
1130 | @@ -259,6 +262,7 @@ libndctl.so.6 libndctl6 #MINVER# |
1131 | ndctl_namespace_get_type@LIBNDCTL_3 60.1 |
1132 | ndctl_namespace_get_type_name@LIBNDCTL_3 60.1 |
1133 | ndctl_namespace_get_uuid@LIBNDCTL_3 60.1 |
1134 | + ndctl_namespace_inject_error2@LIBNDCTL_16 61.2 |
1135 | ndctl_namespace_inject_error@LIBNDCTL_14 60.1 |
1136 | ndctl_namespace_injection_get_first_bb@LIBNDCTL_14 60.1 |
1137 | ndctl_namespace_injection_get_next_bb@LIBNDCTL_14 60.1 |
1138 | @@ -273,6 +277,7 @@ libndctl.so.6 libndctl6 #MINVER# |
1139 | ndctl_namespace_set_sector_size@LIBNDCTL_3 60.1 |
1140 | ndctl_namespace_set_size@LIBNDCTL_3 60.1 |
1141 | ndctl_namespace_set_uuid@LIBNDCTL_3 60.1 |
1142 | + ndctl_namespace_uninject_error2@LIBNDCTL_16 61.2 |
1143 | ndctl_namespace_uninject_error@LIBNDCTL_14 60.1 |
1144 | ndctl_namespace_write_cache_is_enabled@LIBNDCTL_15 60.1 |
1145 | ndctl_new@LIBNDCTL_1 60.1 |
1146 | diff --git a/git-version b/git-version |
1147 | index 19983ff..acc1d78 100755 |
1148 | --- a/git-version |
1149 | +++ b/git-version |
1150 | @@ -19,7 +19,7 @@ dirty() { |
1151 | fi |
1152 | } |
1153 | |
1154 | -DEF_VER=60.1 |
1155 | +DEF_VER=61.2 |
1156 | |
1157 | LF=' |
1158 | ' |
1159 | diff --git a/ndctl/inject-error.c b/ndctl/inject-error.c |
1160 | index 32a58a5..2b2fec0 100644 |
1161 | --- a/ndctl/inject-error.c |
1162 | +++ b/ndctl/inject-error.c |
1163 | @@ -47,6 +47,7 @@ static struct parameters { |
1164 | bool clear; |
1165 | bool status; |
1166 | bool no_notify; |
1167 | + bool saturate; |
1168 | bool human; |
1169 | } param; |
1170 | |
1171 | @@ -54,8 +55,8 @@ static struct inject_ctx { |
1172 | u64 block; |
1173 | u64 count; |
1174 | unsigned int op_mask; |
1175 | - unsigned long flags; |
1176 | - bool notify; |
1177 | + unsigned long json_flags; |
1178 | + unsigned int inject_flags; |
1179 | } ictx; |
1180 | |
1181 | #define BASE_OPTIONS() \ |
1182 | @@ -74,6 +75,8 @@ OPT_BOOLEAN('d', "uninject", ¶m.clear, \ |
1183 | "un-inject a previously injected error"), \ |
1184 | OPT_BOOLEAN('t', "status", ¶m.status, "get error injection status"), \ |
1185 | OPT_BOOLEAN('N', "no-notify", ¶m.no_notify, "firmware should not notify OS"), \ |
1186 | +OPT_BOOLEAN('S', "saturate", ¶m.saturate, \ |
1187 | + "inject full sector, not just 'ars_unit' bytes"), \ |
1188 | OPT_BOOLEAN('u', "human", ¶m.human, "use human friendly number formats ") |
1189 | |
1190 | static const struct option inject_options[] = { |
1191 | @@ -92,9 +95,9 @@ static int inject_init(void) |
1192 | { |
1193 | if (!param.clear && !param.status) { |
1194 | ictx.op_mask |= 1 << OP_INJECT; |
1195 | - ictx.notify = true; |
1196 | + ictx.inject_flags |= (1 << NDCTL_NS_INJECT_NOTIFY); |
1197 | if (param.no_notify) |
1198 | - ictx.notify = false; |
1199 | + ictx.inject_flags &= ~(1 << NDCTL_NS_INJECT_NOTIFY); |
1200 | } |
1201 | if (param.clear) { |
1202 | if (param.status) { |
1203 | @@ -104,7 +107,7 @@ static int inject_init(void) |
1204 | ictx.op_mask |= 1 << OP_CLEAR; |
1205 | } |
1206 | if (param.status) { |
1207 | - if (param.block || param.count) { |
1208 | + if (param.block || param.count || param.saturate) { |
1209 | error("status is invalid with inject or uninject\n"); |
1210 | return -EINVAL; |
1211 | } |
1212 | @@ -144,7 +147,9 @@ static int inject_init(void) |
1213 | } |
1214 | |
1215 | if (param.human) |
1216 | - ictx.flags |= UTIL_JSON_HUMAN; |
1217 | + ictx.json_flags |= UTIL_JSON_HUMAN; |
1218 | + if (param.saturate) |
1219 | + ictx.inject_flags |= 1 << NDCTL_NS_INJECT_SATURATE; |
1220 | |
1221 | return 0; |
1222 | } |
1223 | @@ -152,14 +157,15 @@ static int inject_init(void) |
1224 | static int ns_errors_to_json(struct ndctl_namespace *ndns, |
1225 | unsigned int start_count) |
1226 | { |
1227 | - unsigned long flags = ictx.flags | UTIL_JSON_MEDIA_ERRORS; |
1228 | + unsigned long json_flags = ictx.json_flags | UTIL_JSON_MEDIA_ERRORS; |
1229 | struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1230 | struct json_object *jndns; |
1231 | unsigned int count; |
1232 | int rc, tmo = 30; |
1233 | |
1234 | /* only wait for scrubs for the inject and notify case */ |
1235 | - if ((ictx.op_mask & (1 << OP_INJECT)) && ictx.notify) { |
1236 | + if ((ictx.op_mask & (1 << OP_INJECT)) && |
1237 | + (ictx.inject_flags & (1 << NDCTL_NS_INJECT_NOTIFY))) { |
1238 | do { |
1239 | /* wait for a scrub to start */ |
1240 | count = ndctl_bus_get_scrub_count(bus); |
1241 | @@ -177,7 +183,7 @@ static int ns_errors_to_json(struct ndctl_namespace *ndns, |
1242 | } |
1243 | } |
1244 | |
1245 | - jndns = util_namespace_to_json(ndns, flags); |
1246 | + jndns = util_namespace_to_json(ndns, json_flags); |
1247 | if (jndns) |
1248 | printf("%s\n", json_object_to_json_string_ext(jndns, |
1249 | JSON_C_TO_STRING_PRETTY)); |
1250 | @@ -185,7 +191,7 @@ static int ns_errors_to_json(struct ndctl_namespace *ndns, |
1251 | } |
1252 | |
1253 | static int inject_error(struct ndctl_namespace *ndns, u64 offset, u64 length, |
1254 | - bool notify) |
1255 | + unsigned int flags) |
1256 | { |
1257 | struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1258 | unsigned int scrub_count; |
1259 | @@ -197,7 +203,7 @@ static int inject_error(struct ndctl_namespace *ndns, u64 offset, u64 length, |
1260 | return -ENXIO; |
1261 | } |
1262 | |
1263 | - rc = ndctl_namespace_inject_error(ndns, offset, length, notify); |
1264 | + rc = ndctl_namespace_inject_error2(ndns, offset, length, flags); |
1265 | if (rc) { |
1266 | fprintf(stderr, "Unable to inject error: %s (%d)\n", |
1267 | strerror(abs(rc)), rc); |
1268 | @@ -207,11 +213,12 @@ static int inject_error(struct ndctl_namespace *ndns, u64 offset, u64 length, |
1269 | return ns_errors_to_json(ndns, scrub_count); |
1270 | } |
1271 | |
1272 | -static int uninject_error(struct ndctl_namespace *ndns, u64 offset, u64 length) |
1273 | +static int uninject_error(struct ndctl_namespace *ndns, u64 offset, u64 length, |
1274 | + unsigned int flags) |
1275 | { |
1276 | int rc; |
1277 | |
1278 | - rc = ndctl_namespace_uninject_error(ndns, offset, length); |
1279 | + rc = ndctl_namespace_uninject_error2(ndns, offset, length, flags); |
1280 | if (rc) { |
1281 | fprintf(stderr, "Unable to uninject error: %s (%d)\n", |
1282 | strerror(abs(rc)), rc); |
1283 | @@ -254,7 +261,7 @@ static int injection_status(struct ndctl_namespace *ndns) |
1284 | |
1285 | block = ndctl_bb_get_block(bb); |
1286 | count = ndctl_bb_get_count(bb); |
1287 | - jbb = util_badblock_rec_to_json(block, count, ictx.flags); |
1288 | + jbb = util_badblock_rec_to_json(block, count, ictx.json_flags); |
1289 | if (!jbb) |
1290 | break; |
1291 | json_object_array_add(jbbs, jbb); |
1292 | @@ -280,13 +287,14 @@ static int err_inject_ns(struct ndctl_namespace *ndns) |
1293 | while (op_mask) { |
1294 | if (op_mask & (1 << OP_INJECT)) { |
1295 | rc = inject_error(ndns, ictx.block, ictx.count, |
1296 | - ictx.notify); |
1297 | + ictx.inject_flags); |
1298 | if (rc) |
1299 | return rc; |
1300 | op_mask &= ~(1 << OP_INJECT); |
1301 | } |
1302 | if (op_mask & (1 << OP_CLEAR)) { |
1303 | - rc = uninject_error(ndns, ictx.block, ictx.count); |
1304 | + rc = uninject_error(ndns, ictx.block, ictx.count, |
1305 | + ictx.inject_flags); |
1306 | if (rc) |
1307 | return rc; |
1308 | op_mask &= ~(1 << OP_CLEAR); |
1309 | diff --git a/ndctl/lib/ars.c b/ndctl/lib/ars.c |
1310 | index d53d898..c78e3bf 100644 |
1311 | --- a/ndctl/lib/ars.c |
1312 | +++ b/ndctl/lib/ars.c |
1313 | @@ -180,36 +180,61 @@ NDCTL_EXPORT int ndctl_cmd_ars_cap_get_range(struct ndctl_cmd *ars_cap, |
1314 | return -EINVAL; |
1315 | } |
1316 | |
1317 | +NDCTL_EXPORT unsigned int ndctl_cmd_ars_cap_get_clear_unit( |
1318 | + struct ndctl_cmd *ars_cap) |
1319 | +{ |
1320 | + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(ars_cap)); |
1321 | + |
1322 | + if (ars_cap->type == ND_CMD_ARS_CAP && ars_cap->status == 0) { |
1323 | + dbg(ctx, "clear_err_unit: %d\n", |
1324 | + ars_cap->ars_cap->clear_err_unit); |
1325 | + return ars_cap->ars_cap->clear_err_unit; |
1326 | + } |
1327 | + |
1328 | + dbg(ctx, "invalid ars_cap\n"); |
1329 | + return 0; |
1330 | +} |
1331 | + |
1332 | +static bool __validate_ars_stat(struct ndctl_cmd *ars_stat) |
1333 | +{ |
1334 | + /* |
1335 | + * A positive status indicates an underrun, but that is fine since |
1336 | + * the firmware is not expected to completely fill the max_ars_out |
1337 | + * sized buffer. |
1338 | + */ |
1339 | + if (ars_stat->type != ND_CMD_ARS_STATUS || ars_stat->status < 0) |
1340 | + return false; |
1341 | + if ((ndctl_cmd_get_firmware_status(ars_stat) & ARS_STATUS_MASK) != 0) |
1342 | + return false; |
1343 | + return true; |
1344 | +} |
1345 | + |
1346 | +#define validate_ars_stat(ctx, ars_stat) \ |
1347 | +({ \ |
1348 | + bool __valid = __validate_ars_stat(ars_stat); \ |
1349 | + if (!__valid) \ |
1350 | + dbg(ctx, "expected sucessfully completed ars_stat command\n"); \ |
1351 | + __valid; \ |
1352 | +}) |
1353 | + |
1354 | NDCTL_EXPORT int ndctl_cmd_ars_in_progress(struct ndctl_cmd *cmd) |
1355 | { |
1356 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(cmd)); |
1357 | |
1358 | - if (cmd->type == ND_CMD_ARS_STATUS && cmd->status == 0) { |
1359 | - if (cmd->ars_status->status == 1 << 16) { |
1360 | - /* |
1361 | - * If in-progress, invalidate the ndctl_cmd, so |
1362 | - * that if we're called again without a fresh |
1363 | - * ars_status command, we fail. |
1364 | - */ |
1365 | - cmd->status = 1; |
1366 | - return 1; |
1367 | - } |
1368 | + if (!validate_ars_stat(ctx, cmd)) |
1369 | return 0; |
1370 | - } |
1371 | |
1372 | - dbg(ctx, "invalid ars_status\n"); |
1373 | - return 0; |
1374 | + return (ndctl_cmd_get_firmware_status(cmd) == 1 << 16); |
1375 | } |
1376 | |
1377 | NDCTL_EXPORT unsigned int ndctl_cmd_ars_num_records(struct ndctl_cmd *ars_stat) |
1378 | { |
1379 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(ars_stat)); |
1380 | |
1381 | - if (ars_stat->type == ND_CMD_ARS_STATUS && ars_stat->status == 0) |
1382 | - return ars_stat->ars_status->num_records; |
1383 | + if (!validate_ars_stat(ctx, ars_stat)) |
1384 | + return 0; |
1385 | |
1386 | - dbg(ctx, "invalid ars_status\n"); |
1387 | - return 0; |
1388 | + return ars_stat->ars_status->num_records; |
1389 | } |
1390 | |
1391 | NDCTL_EXPORT unsigned long long ndctl_cmd_ars_get_record_addr( |
1392 | @@ -217,16 +242,15 @@ NDCTL_EXPORT unsigned long long ndctl_cmd_ars_get_record_addr( |
1393 | { |
1394 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(ars_stat)); |
1395 | |
1396 | + if (!validate_ars_stat(ctx, ars_stat)) |
1397 | + return 0; |
1398 | + |
1399 | if (rec_index >= ars_stat->ars_status->num_records) { |
1400 | dbg(ctx, "invalid record index\n"); |
1401 | return 0; |
1402 | } |
1403 | |
1404 | - if (ars_stat->type == ND_CMD_ARS_STATUS && ars_stat->status == 0) |
1405 | - return ars_stat->ars_status->records[rec_index].err_address; |
1406 | - |
1407 | - dbg(ctx, "invalid ars_status\n"); |
1408 | - return 0; |
1409 | + return ars_stat->ars_status->records[rec_index].err_address; |
1410 | } |
1411 | |
1412 | NDCTL_EXPORT unsigned long long ndctl_cmd_ars_get_record_len( |
1413 | @@ -234,16 +258,26 @@ NDCTL_EXPORT unsigned long long ndctl_cmd_ars_get_record_len( |
1414 | { |
1415 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(ars_stat)); |
1416 | |
1417 | + if (!validate_ars_stat(ctx, ars_stat)) |
1418 | + return 0; |
1419 | + |
1420 | if (rec_index >= ars_stat->ars_status->num_records) { |
1421 | dbg(ctx, "invalid record index\n"); |
1422 | return 0; |
1423 | } |
1424 | |
1425 | - if (ars_stat->type == ND_CMD_ARS_STATUS && ars_stat->status == 0) |
1426 | - return ars_stat->ars_status->records[rec_index].length; |
1427 | + return ars_stat->ars_status->records[rec_index].length; |
1428 | +} |
1429 | |
1430 | - dbg(ctx, "invalid ars_status\n"); |
1431 | - return 0; |
1432 | +NDCTL_EXPORT int ndctl_cmd_ars_stat_get_flag_overflow( |
1433 | + struct ndctl_cmd *ars_stat) |
1434 | +{ |
1435 | + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(cmd_to_bus(ars_stat)); |
1436 | + |
1437 | + if (!validate_ars_stat(ctx, ars_stat)) |
1438 | + return -EINVAL; |
1439 | + |
1440 | + return !!(ars_stat->ars_status->flags & ND_ARS_STAT_FLAG_OVERFLOW); |
1441 | } |
1442 | |
1443 | NDCTL_EXPORT struct ndctl_cmd *ndctl_bus_cmd_new_clear_error( |
1444 | diff --git a/ndctl/lib/inject.c b/ndctl/lib/inject.c |
1445 | index 8bfb5c9..f9da02d 100644 |
1446 | --- a/ndctl/lib/inject.c |
1447 | +++ b/ndctl/lib/inject.c |
1448 | @@ -89,90 +89,191 @@ static int translate_status(u32 status) |
1449 | return 0; |
1450 | } |
1451 | |
1452 | -NDCTL_EXPORT int ndctl_namespace_inject_error(struct ndctl_namespace *ndns, |
1453 | - unsigned long long block, unsigned long long count, bool notify) |
1454 | +static int ndctl_namespace_get_clear_unit(struct ndctl_namespace *ndns) |
1455 | +{ |
1456 | + struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1457 | + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); |
1458 | + unsigned long long ns_offset, ns_size; |
1459 | + unsigned int clear_unit; |
1460 | + struct ndctl_cmd *cmd; |
1461 | + int rc; |
1462 | + |
1463 | + ndctl_namespace_get_injection_bounds(ndns, &ns_offset, |
1464 | + &ns_size); |
1465 | + cmd = ndctl_bus_cmd_new_ars_cap(bus, ns_offset, ns_size); |
1466 | + rc = ndctl_cmd_submit(cmd); |
1467 | + if (rc) { |
1468 | + dbg(ctx, "Error submitting ars_cap: %d\n", rc); |
1469 | + return rc; |
1470 | + } |
1471 | + clear_unit = ndctl_cmd_ars_cap_get_clear_unit(cmd); |
1472 | + if (clear_unit == 0) { |
1473 | + dbg(ctx, "Got an invalid clear_err_unit from ars_cap\n"); |
1474 | + return -EINVAL; |
1475 | + } |
1476 | + |
1477 | + ndctl_cmd_unref(cmd); |
1478 | + return clear_unit; |
1479 | +} |
1480 | + |
1481 | +static int ndctl_namespace_inject_one_error(struct ndctl_namespace *ndns, |
1482 | + unsigned long long block, unsigned int flags) |
1483 | { |
1484 | struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1485 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); |
1486 | struct nd_cmd_ars_err_inj *err_inj; |
1487 | struct nd_cmd_pkg *pkg; |
1488 | struct ndctl_cmd *cmd; |
1489 | - int rc = -EOPNOTSUPP; |
1490 | + u64 offset, length; |
1491 | + int rc, clear_unit; |
1492 | |
1493 | - if (!ndctl_bus_has_error_injection(bus)) |
1494 | - return -EOPNOTSUPP; |
1495 | + rc = block_to_spa_offset(ndns, block, 1, &offset, &length); |
1496 | + if (rc) |
1497 | + return rc; |
1498 | |
1499 | - if (ndctl_bus_has_nfit(bus)) { |
1500 | - u64 offset, length; |
1501 | + clear_unit = ndctl_namespace_get_clear_unit(ndns); |
1502 | + if (clear_unit < 0) |
1503 | + return clear_unit; |
1504 | |
1505 | - rc = block_to_spa_offset(ndns, block, count, &offset, &length); |
1506 | - if (rc) |
1507 | - return rc; |
1508 | - cmd = ndctl_bus_cmd_new_err_inj(bus); |
1509 | - if (!cmd) |
1510 | - return -ENOMEM; |
1511 | + if (!(flags & (1 << NDCTL_NS_INJECT_SATURATE))) { |
1512 | + /* clamp injection length per block to the clear_unit */ |
1513 | + if (length > (unsigned int)clear_unit) |
1514 | + length = clear_unit; |
1515 | + } |
1516 | |
1517 | - pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0]; |
1518 | - err_inj = (struct nd_cmd_ars_err_inj *)&pkg->nd_payload[0]; |
1519 | - err_inj->err_inj_spa_range_base = offset; |
1520 | - err_inj->err_inj_spa_range_length = length; |
1521 | - if (notify) |
1522 | - err_inj->err_inj_options |= |
1523 | - (1 << ND_ARS_ERR_INJ_OPT_NOTIFY); |
1524 | + cmd = ndctl_bus_cmd_new_err_inj(bus); |
1525 | + if (!cmd) |
1526 | + return -ENOMEM; |
1527 | |
1528 | - rc = ndctl_cmd_submit(cmd); |
1529 | + pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0]; |
1530 | + err_inj = (struct nd_cmd_ars_err_inj *)&pkg->nd_payload[0]; |
1531 | + err_inj->err_inj_spa_range_base = offset; |
1532 | + err_inj->err_inj_spa_range_length = length; |
1533 | + if (flags & (1 << NDCTL_NS_INJECT_NOTIFY)) |
1534 | + err_inj->err_inj_options |= |
1535 | + (1 << ND_ARS_ERR_INJ_OPT_NOTIFY); |
1536 | + |
1537 | + rc = ndctl_cmd_submit(cmd); |
1538 | + if (rc) { |
1539 | + dbg(ctx, "Error submitting command: %d\n", rc); |
1540 | + goto out; |
1541 | + } |
1542 | + rc = translate_status(err_inj->status); |
1543 | + out: |
1544 | + ndctl_cmd_unref(cmd); |
1545 | + return rc; |
1546 | +} |
1547 | + |
1548 | +NDCTL_EXPORT int ndctl_namespace_inject_error2(struct ndctl_namespace *ndns, |
1549 | + unsigned long long block, unsigned long long count, |
1550 | + unsigned int flags) |
1551 | +{ |
1552 | + struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1553 | + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); |
1554 | + unsigned long long i; |
1555 | + int rc = -EINVAL; |
1556 | + |
1557 | + if (!ndctl_bus_has_error_injection(bus)) |
1558 | + return -EOPNOTSUPP; |
1559 | + if (!ndctl_bus_has_nfit(bus)) |
1560 | + return -EOPNOTSUPP; |
1561 | + |
1562 | + for (i = 0; i < count; i++) { |
1563 | + rc = ndctl_namespace_inject_one_error(ndns, block + i, flags); |
1564 | if (rc) { |
1565 | - dbg(ctx, "Error submitting command: %d\n", rc); |
1566 | - goto out; |
1567 | + err(ctx, "Injection failed at block %llx\n", |
1568 | + block + i); |
1569 | + return rc; |
1570 | } |
1571 | - rc = translate_status(err_inj->status); |
1572 | - out: |
1573 | - ndctl_cmd_unref(cmd); |
1574 | } |
1575 | return rc; |
1576 | } |
1577 | |
1578 | -NDCTL_EXPORT int ndctl_namespace_uninject_error(struct ndctl_namespace *ndns, |
1579 | - unsigned long long block, unsigned long long count) |
1580 | +NDCTL_EXPORT int ndctl_namespace_inject_error(struct ndctl_namespace *ndns, |
1581 | + unsigned long long block, unsigned long long count, bool notify) |
1582 | +{ |
1583 | + return ndctl_namespace_inject_error2(ndns, block, count, |
1584 | + notify ? (1 << NDCTL_NS_INJECT_NOTIFY) : 0); |
1585 | +} |
1586 | + |
1587 | +static int ndctl_namespace_uninject_one_error(struct ndctl_namespace *ndns, |
1588 | + unsigned long long block, unsigned int flags) |
1589 | { |
1590 | struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1591 | struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); |
1592 | struct nd_cmd_ars_err_inj_clr *err_inj_clr; |
1593 | struct nd_cmd_pkg *pkg; |
1594 | struct ndctl_cmd *cmd; |
1595 | - int rc = -EOPNOTSUPP; |
1596 | + u64 offset, length; |
1597 | + int rc, clear_unit; |
1598 | |
1599 | - if (!ndctl_bus_has_error_injection(bus)) |
1600 | - return -EOPNOTSUPP; |
1601 | + rc = block_to_spa_offset(ndns, block, 1, &offset, &length); |
1602 | + if (rc) |
1603 | + return rc; |
1604 | |
1605 | - if (ndctl_bus_has_nfit(bus)) { |
1606 | - u64 offset, length; |
1607 | + clear_unit = ndctl_namespace_get_clear_unit(ndns); |
1608 | + if (clear_unit < 0) |
1609 | + return clear_unit; |
1610 | |
1611 | - rc = block_to_spa_offset(ndns, block, count, &offset, &length); |
1612 | - if (rc) |
1613 | - return rc; |
1614 | - cmd = ndctl_bus_cmd_new_err_inj_clr(bus); |
1615 | - if (!cmd) |
1616 | - return -ENOMEM; |
1617 | + if (!(flags & (1 << NDCTL_NS_INJECT_SATURATE))) { |
1618 | + /* clamp injection length per block to the clear_unit */ |
1619 | + if (length > (unsigned int)clear_unit) |
1620 | + length = clear_unit; |
1621 | + } |
1622 | |
1623 | - pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0]; |
1624 | - err_inj_clr = |
1625 | - (struct nd_cmd_ars_err_inj_clr *)&pkg->nd_payload[0]; |
1626 | - err_inj_clr->err_inj_clr_spa_range_base = offset; |
1627 | - err_inj_clr->err_inj_clr_spa_range_length = length; |
1628 | + cmd = ndctl_bus_cmd_new_err_inj_clr(bus); |
1629 | + if (!cmd) |
1630 | + return -ENOMEM; |
1631 | |
1632 | - rc = ndctl_cmd_submit(cmd); |
1633 | + pkg = (struct nd_cmd_pkg *)&cmd->cmd_buf[0]; |
1634 | + err_inj_clr = |
1635 | + (struct nd_cmd_ars_err_inj_clr *)&pkg->nd_payload[0]; |
1636 | + err_inj_clr->err_inj_clr_spa_range_base = offset; |
1637 | + err_inj_clr->err_inj_clr_spa_range_length = length; |
1638 | + |
1639 | + rc = ndctl_cmd_submit(cmd); |
1640 | + if (rc) { |
1641 | + dbg(ctx, "Error submitting command: %d\n", rc); |
1642 | + goto out; |
1643 | + } |
1644 | + rc = translate_status(err_inj_clr->status); |
1645 | + out: |
1646 | + ndctl_cmd_unref(cmd); |
1647 | + return rc; |
1648 | +} |
1649 | + |
1650 | +NDCTL_EXPORT int ndctl_namespace_uninject_error2(struct ndctl_namespace *ndns, |
1651 | + unsigned long long block, unsigned long long count, |
1652 | + unsigned int flags) |
1653 | +{ |
1654 | + struct ndctl_bus *bus = ndctl_namespace_get_bus(ndns); |
1655 | + struct ndctl_ctx *ctx = ndctl_bus_get_ctx(bus); |
1656 | + unsigned long long i; |
1657 | + int rc = -EINVAL; |
1658 | + |
1659 | + if (!ndctl_bus_has_error_injection(bus)) |
1660 | + return -EOPNOTSUPP; |
1661 | + if (!ndctl_bus_has_nfit(bus)) |
1662 | + return -EOPNOTSUPP; |
1663 | + |
1664 | + for (i = 0; i < count; i++) { |
1665 | + rc = ndctl_namespace_uninject_one_error(ndns, block + i, |
1666 | + flags); |
1667 | if (rc) { |
1668 | - dbg(ctx, "Error submitting command: %d\n", rc); |
1669 | - goto out; |
1670 | + err(ctx, "Un-injection failed at block %llx\n", |
1671 | + block + i); |
1672 | + return rc; |
1673 | } |
1674 | - rc = translate_status(err_inj_clr->status); |
1675 | - out: |
1676 | - ndctl_cmd_unref(cmd); |
1677 | } |
1678 | return rc; |
1679 | } |
1680 | |
1681 | +NDCTL_EXPORT int ndctl_namespace_uninject_error(struct ndctl_namespace *ndns, |
1682 | + unsigned long long block, unsigned long long count) |
1683 | +{ |
1684 | + return ndctl_namespace_uninject_error2(ndns, block, count, 0); |
1685 | +} |
1686 | + |
1687 | static int bb_add_record(struct list_head *h, u64 block, u64 count) |
1688 | { |
1689 | struct ndctl_bb *bb, *bb_iter, *bb_next, *bb_prev; |
1690 | diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c |
1691 | index 59ea82a..47e005e 100644 |
1692 | --- a/ndctl/lib/libndctl.c |
1693 | +++ b/ndctl/lib/libndctl.c |
1694 | @@ -1243,12 +1243,19 @@ NDCTL_EXPORT int ndctl_bus_wait_for_scrub_completion(struct ndctl_bus *bus) |
1695 | break; |
1696 | } |
1697 | dbg(ctx, "poll wake: revents: %d\n", fds.revents); |
1698 | - pread(fd, buf, 1, 0); |
1699 | + if (pread(fd, buf, 1, 0) == -1) { |
1700 | + rc = -errno; |
1701 | + break; |
1702 | + } |
1703 | fds.revents = 0; |
1704 | } |
1705 | } |
1706 | |
1707 | - dbg(ctx, "bus%d: scrub complete\n", ndctl_bus_get_id(bus)); |
1708 | + if (rc == 0) |
1709 | + dbg(ctx, "bus%d: scrub complete\n", ndctl_bus_get_id(bus)); |
1710 | + else |
1711 | + dbg(ctx, "bus%d: error waiting for scrub completion: %s\n", |
1712 | + ndctl_bus_get_id(bus), strerror(-rc)); |
1713 | if (fd) |
1714 | close (fd); |
1715 | return rc; |
1716 | @@ -3991,10 +3998,10 @@ static int __ndctl_namespace_set_write_cache(struct ndctl_namespace *ndns, |
1717 | { |
1718 | struct ndctl_ctx *ctx = ndctl_namespace_get_ctx(ndns); |
1719 | struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns); |
1720 | + char *path = ndns->ndns_buf; |
1721 | char buf[SYSFS_ATTR_SIZE]; |
1722 | int len = ndns->buf_len; |
1723 | const char *bdev; |
1724 | - char path[50]; |
1725 | |
1726 | if (state != 1 && state != 0) |
1727 | return -ENXIO; |
1728 | @@ -4034,9 +4041,9 @@ NDCTL_EXPORT int ndctl_namespace_write_cache_is_enabled( |
1729 | struct ndctl_ctx *ctx = ndctl_namespace_get_ctx(ndns); |
1730 | struct ndctl_pfn *pfn = ndctl_namespace_get_pfn(ndns); |
1731 | int len = ndns->buf_len, wc; |
1732 | + char *path = ndns->ndns_buf; |
1733 | char buf[SYSFS_ATTR_SIZE]; |
1734 | const char *bdev; |
1735 | - char path[50]; |
1736 | |
1737 | if (pfn) |
1738 | bdev = ndctl_pfn_get_block_device(pfn); |
1739 | diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym |
1740 | index 65e735f..e939993 100644 |
1741 | --- a/ndctl/lib/libndctl.sym |
1742 | +++ b/ndctl/lib/libndctl.sym |
1743 | @@ -359,3 +359,11 @@ global: |
1744 | ndctl_bus_start_scrub; |
1745 | ndctl_region_deep_flush; |
1746 | } LIBNDCTL_14; |
1747 | + |
1748 | +LIBNDCTL_16 { |
1749 | +global: |
1750 | + ndctl_cmd_ars_cap_get_clear_unit; |
1751 | + ndctl_namespace_inject_error2; |
1752 | + ndctl_namespace_uninject_error2; |
1753 | + ndctl_cmd_ars_stat_get_flag_overflow; |
1754 | +} LIBNDCTL_15; |
1755 | diff --git a/ndctl/lib/private.h b/ndctl/lib/private.h |
1756 | index 73bbeed..b756b74 100644 |
1757 | --- a/ndctl/lib/private.h |
1758 | +++ b/ndctl/lib/private.h |
1759 | @@ -278,6 +278,9 @@ struct ndctl_bb { |
1760 | struct list_node list; |
1761 | }; |
1762 | |
1763 | +/* ars_status flags */ |
1764 | +#define ND_ARS_STAT_FLAG_OVERFLOW (1 << 0) |
1765 | + |
1766 | struct ndctl_dimm_ops { |
1767 | const char *(*cmd_desc)(int); |
1768 | struct ndctl_cmd *(*new_smart)(struct ndctl_dimm *); |
1769 | diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h |
1770 | index 498ae19..9270bae 100644 |
1771 | --- a/ndctl/libndctl.h |
1772 | +++ b/ndctl/libndctl.h |
1773 | @@ -209,6 +209,8 @@ struct ndctl_cmd *ndctl_bus_cmd_new_clear_error(unsigned long long address, |
1774 | unsigned long long len, struct ndctl_cmd *ars_cap); |
1775 | unsigned long long ndctl_cmd_clear_error_get_cleared( |
1776 | struct ndctl_cmd *clear_err); |
1777 | +unsigned int ndctl_cmd_ars_cap_get_clear_unit(struct ndctl_cmd *ars_cap); |
1778 | +int ndctl_cmd_ars_stat_get_flag_overflow(struct ndctl_cmd *ars_stat); |
1779 | |
1780 | /* |
1781 | * Note: ndctl_cmd_smart_get_temperature is an alias for |
1782 | @@ -478,9 +480,19 @@ int ndctl_namespace_get_numa_node(struct ndctl_namespace *ndns); |
1783 | int ndctl_namespace_inject_error(struct ndctl_namespace *ndns, |
1784 | unsigned long long block, unsigned long long count, |
1785 | bool notify); |
1786 | +int ndctl_namespace_inject_error2(struct ndctl_namespace *ndns, |
1787 | + unsigned long long block, unsigned long long count, |
1788 | + unsigned int flags); |
1789 | int ndctl_namespace_uninject_error(struct ndctl_namespace *ndns, |
1790 | unsigned long long block, unsigned long long count); |
1791 | +int ndctl_namespace_uninject_error2(struct ndctl_namespace *ndns, |
1792 | + unsigned long long block, unsigned long long count, |
1793 | + unsigned int flags); |
1794 | int ndctl_namespace_injection_status(struct ndctl_namespace *ndns); |
1795 | +enum ndctl_namespace_inject_flags { |
1796 | + NDCTL_NS_INJECT_NOTIFY = 0, |
1797 | + NDCTL_NS_INJECT_SATURATE, |
1798 | +}; |
1799 | |
1800 | struct ndctl_bb; |
1801 | unsigned long long ndctl_bb_get_block(struct ndctl_bb *bb); |
1802 | diff --git a/ndctl/util/json-smart.c b/ndctl/util/json-smart.c |
1803 | index 4020423..6a1f294 100644 |
1804 | --- a/ndctl/util/json-smart.c |
1805 | +++ b/ndctl/util/json-smart.c |
1806 | @@ -47,6 +47,18 @@ static void smart_threshold_to_json(struct ndctl_dimm *dimm, |
1807 | "temperature_threshold", jobj); |
1808 | } |
1809 | |
1810 | + if (alarm_control & ND_SMART_CTEMP_TRIP) { |
1811 | + unsigned int temp; |
1812 | + double t; |
1813 | + |
1814 | + temp = ndctl_cmd_smart_threshold_get_ctrl_temperature(cmd); |
1815 | + t = ndctl_decode_smart_temperature(temp); |
1816 | + jobj = json_object_new_double(t); |
1817 | + if (jobj) |
1818 | + json_object_object_add(jhealth, |
1819 | + "controller_temperature_threshold", jobj); |
1820 | + } |
1821 | + |
1822 | if (alarm_control & ND_SMART_SPARE_TRIP) { |
1823 | unsigned int spares; |
1824 | |
1825 | @@ -109,6 +121,16 @@ struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm) |
1826 | json_object_object_add(jhealth, "temperature_celsius", jobj); |
1827 | } |
1828 | |
1829 | + if (flags & ND_SMART_CTEMP_VALID) { |
1830 | + unsigned int temp = ndctl_cmd_smart_get_ctrl_temperature(cmd); |
1831 | + double t = ndctl_decode_smart_temperature(temp); |
1832 | + |
1833 | + jobj = json_object_new_double(t); |
1834 | + if (jobj) |
1835 | + json_object_object_add(jhealth, |
1836 | + "controller_temperature_celsius", jobj); |
1837 | + } |
1838 | + |
1839 | if (flags & ND_SMART_SPARES_VALID) { |
1840 | unsigned int spares = ndctl_cmd_smart_get_spares(cmd); |
1841 | |
1842 | @@ -120,12 +142,17 @@ struct json_object *util_dimm_health_to_json(struct ndctl_dimm *dimm) |
1843 | if (flags & ND_SMART_ALARM_VALID) { |
1844 | unsigned int alarm_flags = ndctl_cmd_smart_get_alarm_flags(cmd); |
1845 | bool temp_flag = !!(alarm_flags & ND_SMART_TEMP_TRIP); |
1846 | + bool ctrl_temp_flag = !!(alarm_flags & ND_SMART_CTEMP_TRIP); |
1847 | bool spares_flag = !!(alarm_flags & ND_SMART_SPARE_TRIP); |
1848 | |
1849 | jobj = json_object_new_boolean(temp_flag); |
1850 | if (jobj) |
1851 | json_object_object_add(jhealth, "alarm_temperature", jobj); |
1852 | |
1853 | + jobj = json_object_new_boolean(ctrl_temp_flag); |
1854 | + if (jobj) |
1855 | + json_object_object_add(jhealth, "alarm_controller_temperature", jobj); |
1856 | + |
1857 | jobj = json_object_new_boolean(spares_flag); |
1858 | if (jobj) |
1859 | json_object_object_add(jhealth, "alarm_spares", jobj); |
1860 | diff --git a/test.h b/test.h |
1861 | index 5f2d629..fa0c0cf 100644 |
1862 | --- a/test.h |
1863 | +++ b/test.h |
1864 | @@ -12,6 +12,8 @@ |
1865 | */ |
1866 | #ifndef __TEST_H__ |
1867 | #define __TEST_H__ |
1868 | +#include <stdbool.h> |
1869 | + |
1870 | struct ndctl_test; |
1871 | struct ndctl_ctx; |
1872 | struct ndctl_test *ndctl_test_new(unsigned int kver); |
1873 | @@ -36,6 +38,16 @@ struct ndctl_ctx; |
1874 | int test_parent_uuid(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx); |
1875 | int test_multi_pmem(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx); |
1876 | int test_dax_directio(int dax_fd, unsigned long align, void *dax_addr, off_t offset); |
1877 | +#ifdef ENABLE_POISON |
1878 | +int test_dax_poison(struct ndctl_test *test, int dax_fd, unsigned long align, |
1879 | + void *dax_addr, off_t offset, bool fsdax); |
1880 | +#else |
1881 | +static inline int test_dax_poison(struct ndctl_test *test, int dax_fd, |
1882 | + unsigned long align, void *dax_addr, off_t offset, bool fsdax) |
1883 | +{ |
1884 | + return 0; |
1885 | +} |
1886 | +#endif |
1887 | int test_dpa_alloc(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx); |
1888 | int test_dsm_fail(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx); |
1889 | int test_libndctl(int loglevel, struct ndctl_test *test, struct ndctl_ctx *ctx); |
1890 | diff --git a/test/Makefile.am b/test/Makefile.am |
1891 | index 496a663..cd451e9 100644 |
1892 | --- a/test/Makefile.am |
1893 | +++ b/test/Makefile.am |
1894 | @@ -69,9 +69,16 @@ libndctl_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS) |
1895 | |
1896 | dsm_fail_SOURCES =\ |
1897 | dsm-fail.c \ |
1898 | - $(testcore) |
1899 | + $(testcore) \ |
1900 | + ../ndctl/namespace.c \ |
1901 | + ../ndctl/check.c \ |
1902 | + ../util/json.c |
1903 | |
1904 | -dsm_fail_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS) |
1905 | +dsm_fail_LDADD = $(LIBNDCTL_LIB) \ |
1906 | + $(KMOD_LIBS) \ |
1907 | + $(JSON_LIBS) \ |
1908 | + $(UUID_LIBS) \ |
1909 | + ../libutil.a |
1910 | |
1911 | ack_shutdown_count_set_SOURCES =\ |
1912 | ack-shutdown-count-set.c \ |
1913 | @@ -94,9 +101,12 @@ parent_uuid_LDADD = $(LIBNDCTL_LIB) $(UUID_LIBS) $(KMOD_LIBS) |
1914 | dax_dev_SOURCES = dax-dev.c $(testcore) |
1915 | dax_dev_LDADD = $(LIBNDCTL_LIB) $(KMOD_LIBS) |
1916 | |
1917 | -dax_pmd_SOURCES = dax-pmd.c |
1918 | +dax_pmd_SOURCES = dax-pmd.c \ |
1919 | + $(testcore) |
1920 | + |
1921 | hugetlb_SOURCES = hugetlb.c \ |
1922 | dax-pmd.c |
1923 | + |
1924 | mmap_SOURCES = mmap.c |
1925 | dax_errors_SOURCES = dax-errors.c |
1926 | daxdev_errors_SOURCES = daxdev-errors.c \ |
1927 | @@ -111,6 +121,13 @@ device_dax_SOURCES = \ |
1928 | ../ndctl/namespace.c \ |
1929 | ../ndctl/check.c \ |
1930 | ../util/json.c |
1931 | + |
1932 | +if ENABLE_POISON |
1933 | +dax_pmd_SOURCES += dax-poison.c |
1934 | +hugetlb_SOURCES += dax-poison.c |
1935 | +device_dax_SOURCES += dax-poison.c |
1936 | +endif |
1937 | + |
1938 | device_dax_LDADD = \ |
1939 | $(LIBNDCTL_LIB) \ |
1940 | $(KMOD_LIBS) \ |
1941 | diff --git a/test/blk-exhaust.sh b/test/blk-exhaust.sh |
1942 | index b6991f6..326ce73 100755 |
1943 | --- a/test/blk-exhaust.sh |
1944 | +++ b/test/blk-exhaust.sh |
1945 | @@ -11,49 +11,31 @@ |
1946 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
1947 | # General Public License for more details. |
1948 | |
1949 | -NDCTL="../ndctl/ndctl" |
1950 | -BUS="-b nfit_test.0" |
1951 | -BUS1="-b nfit_test.1" |
1952 | -rc=77 |
1953 | - |
1954 | set -e |
1955 | |
1956 | -err() { |
1957 | - echo "test/label-compat.sh: failed at line $1" |
1958 | - exit $rc |
1959 | -} |
1960 | - |
1961 | -check_min_kver() |
1962 | -{ |
1963 | - local ver="$1" |
1964 | - : "${KVER:=$(uname -r)}" |
1965 | +rc=77 |
1966 | |
1967 | - [ -n "$ver" ] || return 1 |
1968 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
1969 | -} |
1970 | +. ./common |
1971 | |
1972 | -check_min_kver "4.11" || { echo "kernel $KVER may lack blk-exhaustion fix"; exit $rc; } |
1973 | +check_min_kver "4.11" || do_skip "may lack blk-exhaustion fix" |
1974 | |
1975 | -set -e |
1976 | trap 'err $LINENO' ERR |
1977 | |
1978 | # setup (reset nfit_test dimms) |
1979 | modprobe nfit_test |
1980 | -$NDCTL disable-region $BUS all |
1981 | -$NDCTL zero-labels $BUS all |
1982 | -$NDCTL enable-region $BUS all |
1983 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
1984 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
1985 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
1986 | |
1987 | # if the kernel accounting is correct we should be able to create two |
1988 | # pmem and two blk namespaces on nfit_test.0 |
1989 | rc=1 |
1990 | -$NDCTL create-namespace $BUS -t pmem |
1991 | -$NDCTL create-namespace $BUS -t pmem |
1992 | -$NDCTL create-namespace $BUS -t blk -m raw |
1993 | -$NDCTL create-namespace $BUS -t blk -m raw |
1994 | +$NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem |
1995 | +$NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem |
1996 | +$NDCTL create-namespace -b $NFIT_TEST_BUS0 -t blk -m raw |
1997 | +$NDCTL create-namespace -b $NFIT_TEST_BUS0 -t blk -m raw |
1998 | |
1999 | # clearnup and exit |
2000 | -$NDCTL disable-region $BUS all |
2001 | -$NDCTL disable-region $BUS1 all |
2002 | -modprobe -r nfit_test |
2003 | +_cleanup |
2004 | |
2005 | exit 0 |
2006 | diff --git a/test/btt-check.sh b/test/btt-check.sh |
2007 | index 353d437..ceabee5 100755 |
2008 | --- a/test/btt-check.sh |
2009 | +++ b/test/btt-check.sh |
2010 | @@ -11,11 +11,6 @@ |
2011 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2012 | # General Public License for more details. |
2013 | |
2014 | -[ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ] && ndctl="../ndctl/ndctl" |
2015 | -[ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ] && ndctl="./ndctl/ndctl" |
2016 | -[ -z "$ndctl" ] && echo "Couldn't find an ndctl binary" && exit 1 |
2017 | -bus="nfit_test.0" |
2018 | -json2var="s/[{}\",]//g; s/:/=/g" |
2019 | dev="" |
2020 | mode="" |
2021 | size="" |
2022 | @@ -24,6 +19,8 @@ blockdev="" |
2023 | bs=4096 |
2024 | rc=77 |
2025 | |
2026 | +. ./common |
2027 | + |
2028 | trap 'err $LINENO' ERR |
2029 | |
2030 | # sample json: |
2031 | @@ -36,43 +33,26 @@ trap 'err $LINENO' ERR |
2032 | # "blockdev":"pmem5s" |
2033 | # } |
2034 | |
2035 | -# $1: Line number |
2036 | -# $2: exit code |
2037 | -err() |
2038 | -{ |
2039 | - [ -n "$2" ] && rc="$2" |
2040 | - echo "test/btt-check: failed at line $1" |
2041 | - exit "$rc" |
2042 | -} |
2043 | - |
2044 | -check_min_kver() |
2045 | -{ |
2046 | - local ver="$1" |
2047 | - : "${KVER:=$(uname -r)}" |
2048 | - |
2049 | - [ -n "$ver" ] || return 1 |
2050 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
2051 | -} |
2052 | - |
2053 | -check_min_kver "4.14" || { echo "kernel $KVER may not support badblocks clearing on pmem via btt"; exit $rc; } |
2054 | +check_min_kver "4.14" || do_skip "may not support badblocks clearing on pmem via btt" |
2055 | |
2056 | create() |
2057 | { |
2058 | - json=$($ndctl create-namespace -b "$bus" -t pmem -m sector) |
2059 | - eval "$(echo "$json" | sed -e "$json2var")" |
2060 | - [ -n "$dev" ] || err "$LINENO" 2 |
2061 | - [ "$mode" = "sector" ] || err "$LINENO" 2 |
2062 | - [ -n "$size" ] || err "$LINENO" 2 |
2063 | - [ -n "$sector_size" ] || err "$LINENO" 2 |
2064 | - [ -n "$blockdev" ] || err "$LINENO" 2 |
2065 | - [ $size -gt 0 ] || err "$LINENO" 2 |
2066 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m sector) |
2067 | + rc=2 |
2068 | + eval "$(echo "$json" | json2var)" |
2069 | + [ -n "$dev" ] || err "$LINENO" |
2070 | + [ "$mode" = "sector" ] || err "$LINENO" |
2071 | + [ -n "$size" ] || err "$LINENO" |
2072 | + [ -n "$sector_size" ] || err "$LINENO" |
2073 | + [ -n "$blockdev" ] || err "$LINENO" |
2074 | + [ $size -gt 0 ] || err "$LINENO" |
2075 | } |
2076 | |
2077 | reset() |
2078 | { |
2079 | - $ndctl disable-region -b "$bus" all |
2080 | - $ndctl zero-labels -b "$bus" all |
2081 | - $ndctl enable-region -b "$bus" all |
2082 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2083 | + $NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2084 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2085 | } |
2086 | |
2087 | # re-enable the BTT namespace, and do IO to it in an attempt to |
2088 | @@ -93,25 +73,25 @@ test_normal() |
2089 | { |
2090 | echo "=== ${FUNCNAME[0]} ===" |
2091 | # disable the namespace |
2092 | - $ndctl disable-namespace $dev |
2093 | - $ndctl check-namespace $dev |
2094 | - $ndctl enable-namespace $dev |
2095 | + $NDCTL disable-namespace $dev |
2096 | + $NDCTL check-namespace $dev |
2097 | + $NDCTL enable-namespace $dev |
2098 | post_repair_test |
2099 | } |
2100 | |
2101 | test_force() |
2102 | { |
2103 | echo "=== ${FUNCNAME[0]} ===" |
2104 | - $ndctl check-namespace --force $dev |
2105 | + $NDCTL check-namespace --force $dev |
2106 | post_repair_test |
2107 | } |
2108 | |
2109 | set_raw() |
2110 | { |
2111 | - $ndctl disable-namespace $dev |
2112 | + $NDCTL disable-namespace $dev |
2113 | echo -n "set raw_mode: " |
2114 | echo 1 | tee /sys/bus/nd/devices/$dev/force_raw |
2115 | - $ndctl enable-namespace $dev |
2116 | + $NDCTL enable-namespace $dev |
2117 | raw_bdev="${blockdev%%s}" |
2118 | test -b /dev/$raw_bdev |
2119 | raw_size="$(cat /sys/bus/nd/devices/$dev/size)" |
2120 | @@ -119,10 +99,10 @@ set_raw() |
2121 | |
2122 | unset_raw() |
2123 | { |
2124 | - $ndctl disable-namespace $dev |
2125 | + $NDCTL disable-namespace $dev |
2126 | echo -n "set raw_mode: " |
2127 | echo 0 | tee /sys/bus/nd/devices/$dev/force_raw |
2128 | - $ndctl enable-namespace $dev |
2129 | + $NDCTL enable-namespace $dev |
2130 | raw_bdev="" |
2131 | } |
2132 | |
2133 | @@ -134,10 +114,10 @@ test_bad_info2() |
2134 | echo "wiping info2 block (offset = $seek blocks)" |
2135 | dd if=/dev/zero of=/dev/$raw_bdev bs=$bs count=1 seek=$seek |
2136 | unset_raw |
2137 | - $ndctl disable-namespace $dev |
2138 | - $ndctl check-namespace $dev 2>&1 | grep "info2 needs to be restored" |
2139 | - $ndctl check-namespace --repair $dev |
2140 | - $ndctl enable-namespace $dev |
2141 | + $NDCTL disable-namespace $dev |
2142 | + $NDCTL check-namespace $dev 2>&1 | grep "info2 needs to be restored" |
2143 | + $NDCTL check-namespace --repair $dev |
2144 | + $NDCTL enable-namespace $dev |
2145 | post_repair_test |
2146 | } |
2147 | |
2148 | @@ -148,10 +128,10 @@ test_bad_info() |
2149 | echo "wiping info block" |
2150 | dd if=/dev/zero of=/dev/$raw_bdev bs=$bs count=2 seek=0 |
2151 | unset_raw |
2152 | - $ndctl disable-namespace $dev |
2153 | - $ndctl check-namespace $dev 2>&1 | grep -E "info block at offset .* needs to be restored" |
2154 | - $ndctl check-namespace --repair $dev |
2155 | - $ndctl enable-namespace $dev |
2156 | + $NDCTL disable-namespace $dev |
2157 | + $NDCTL check-namespace $dev 2>&1 | grep -E "info block at offset .* needs to be restored" |
2158 | + $NDCTL check-namespace --repair $dev |
2159 | + $NDCTL enable-namespace $dev |
2160 | post_repair_test |
2161 | } |
2162 | |
2163 | @@ -170,8 +150,8 @@ test_bitmap() |
2164 | dd if=/tmp/scribble of=/dev/$raw_bdev bs=$bs seek=$seek |
2165 | rm -f /tmp/scribble |
2166 | unset_raw |
2167 | - $ndctl disable-namespace $dev |
2168 | - $ndctl check-namespace $dev 2>&1 | grep "bitmap error" |
2169 | + $NDCTL disable-namespace $dev |
2170 | + $NDCTL check-namespace $dev 2>&1 | grep "bitmap error" |
2171 | # This is not repairable |
2172 | reset && create |
2173 | } |
2174 | @@ -191,4 +171,5 @@ rc=1 |
2175 | reset && create |
2176 | do_tests |
2177 | reset |
2178 | +_cleanup |
2179 | exit 0 |
2180 | diff --git a/test/btt-errors.sh b/test/btt-errors.sh |
2181 | index ecc1282..e9cc209 100755 |
2182 | --- a/test/btt-errors.sh |
2183 | +++ b/test/btt-errors.sh |
2184 | @@ -11,18 +11,15 @@ |
2185 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2186 | # General Public License for more details. |
2187 | |
2188 | -NDCTL="../ndctl/ndctl" |
2189 | -BUS="nfit_test.0" |
2190 | MNT=test_btt_mnt |
2191 | FILE=image |
2192 | -json2var="s/[{}\",]//g; s/:/=/g" |
2193 | blockdev="" |
2194 | rc=77 |
2195 | |
2196 | -err() { |
2197 | - rc=1 |
2198 | - echo "test/btt-errors: failed at line $1" |
2199 | +. ./common |
2200 | |
2201 | +cleanup() |
2202 | +{ |
2203 | rm -f $FILE |
2204 | rm -f $MNT/$FILE |
2205 | if [ -n "$blockdev" ]; then |
2206 | @@ -31,16 +28,6 @@ err() { |
2207 | rc=77 |
2208 | fi |
2209 | rmdir $MNT |
2210 | - exit $rc |
2211 | -} |
2212 | - |
2213 | -check_min_kver() |
2214 | -{ |
2215 | - local ver="$1" |
2216 | - : "${KVER:=$(uname -r)}" |
2217 | - |
2218 | - [ -n "$ver" ] || return 1 |
2219 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
2220 | } |
2221 | |
2222 | force_raw() |
2223 | @@ -59,24 +46,24 @@ force_raw() |
2224 | fi |
2225 | } |
2226 | |
2227 | -check_min_kver "4.15" || { echo "kernel $KVER may lack BTT error handling"; exit $rc; } |
2228 | +check_min_kver "4.15" || do_skip "may lack BTT error handling" |
2229 | |
2230 | set -e |
2231 | mkdir -p $MNT |
2232 | -trap 'err $LINENO' ERR |
2233 | +trap 'err $LINENO cleanup' ERR |
2234 | |
2235 | # setup (reset nfit_test dimms) |
2236 | modprobe nfit_test |
2237 | -$NDCTL disable-region -b "$BUS" all |
2238 | -$NDCTL zero-labels -b "$BUS" all |
2239 | -$NDCTL enable-region -b "$BUS" all |
2240 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2241 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2242 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2243 | |
2244 | rc=1 |
2245 | |
2246 | # create a btt namespace and clear errors (if any) |
2247 | dev="x" |
2248 | -json=$($NDCTL create-namespace -b "$BUS" -t pmem -m sector) |
2249 | -eval "$(echo "$json" | sed -e "$json2var")" |
2250 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m sector) |
2251 | +eval "$(echo "$json" | json2var)" |
2252 | [ $dev = "x" ] && echo "fail: $LINENO" && exit 1 |
2253 | |
2254 | force_raw 1 |
2255 | @@ -147,12 +134,12 @@ dd if=$MNT/$FILE of=/dev/null iflag=direct bs=4096 count=1 |
2256 | |
2257 | # reset everything to get a clean log |
2258 | if grep -q "$MNT" /proc/mounts; then umount $MNT; fi |
2259 | -$NDCTL disable-region -b "$BUS" all |
2260 | -$NDCTL zero-labels -b "$BUS" all |
2261 | -$NDCTL enable-region -b "$BUS" all |
2262 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2263 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2264 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2265 | dev="x" |
2266 | -json=$($NDCTL create-namespace -b "$BUS" -t pmem -m sector) |
2267 | -eval "$(echo "$json" | sed -e "$json2var")" |
2268 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m sector) |
2269 | +eval "$(echo "$json" | json2var)" |
2270 | [ $dev = "x" ] && echo "fail: $LINENO" && exit 1 |
2271 | |
2272 | # insert error at an arbitrary offset in the map (sector 0) |
2273 | @@ -168,7 +155,8 @@ force_raw 0 |
2274 | dd if=/dev/$blockdev of=/dev/null iflag=direct bs=4096 count=1 && err $LINENO || true |
2275 | |
2276 | # done, exit |
2277 | -$NDCTL disable-region -b "$BUS" all |
2278 | -$NDCTL zero-labels -b "$BUS" all |
2279 | -$NDCTL enable-region -b "$BUS" all |
2280 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2281 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2282 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2283 | +_cleanup |
2284 | exit 0 |
2285 | diff --git a/test/btt-pad-compat.sh b/test/btt-pad-compat.sh |
2286 | index 281a8e5..2c1f271 100755 |
2287 | --- a/test/btt-pad-compat.sh |
2288 | +++ b/test/btt-pad-compat.sh |
2289 | @@ -11,16 +11,13 @@ |
2290 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2291 | # General Public License for more details. |
2292 | |
2293 | -[ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ] && ndctl="../ndctl/ndctl" |
2294 | -[ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ] && ndctl="./ndctl/ndctl" |
2295 | -[ -z "$ndctl" ] && echo "Couldn't find an ndctl binary" && exit 1 |
2296 | -bus="nfit_test.0" |
2297 | -json2var="s/[{}\",]//g; s/:/=/g" |
2298 | dev="" |
2299 | size="" |
2300 | blockdev="" |
2301 | rc=77 |
2302 | |
2303 | +. ./common |
2304 | + |
2305 | trap 'err $LINENO' ERR |
2306 | |
2307 | # sample json: |
2308 | @@ -32,44 +29,27 @@ trap 'err $LINENO' ERR |
2309 | # "blockdev":"pmem7", |
2310 | #} |
2311 | |
2312 | -# $1: Line number |
2313 | -# $2: exit code |
2314 | -err() |
2315 | -{ |
2316 | - [ -n "$2" ] && rc="$2" |
2317 | - echo "test/btt-pad-compat.sh: failed at line $1" |
2318 | - exit "$rc" |
2319 | -} |
2320 | - |
2321 | -check_prereq() |
2322 | -{ |
2323 | - if ! command -v "$1" >/dev/null; then |
2324 | - echo "missing '$1', skipping.." |
2325 | - exit "$rc" |
2326 | - fi |
2327 | -} |
2328 | - |
2329 | create() |
2330 | { |
2331 | - json=$($ndctl create-namespace -b "$bus" -t pmem -m sector) |
2332 | - eval "$(echo "$json" | sed -e "$json2var")" |
2333 | - [ -n "$dev" ] || err "$LINENO" 2 |
2334 | - [ -n "$size" ] || err "$LINENO" 2 |
2335 | - [ -n "$blockdev" ] || err "$LINENO" 2 |
2336 | - [ $size -gt 0 ] || err "$LINENO" 2 |
2337 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m sector) |
2338 | + rc=2 |
2339 | + eval "$(echo "$json" | json2var)" |
2340 | + [ -n "$dev" ] || err "$LINENO" |
2341 | + [ -n "$size" ] || err "$LINENO" |
2342 | + [ -n "$blockdev" ] || err "$LINENO" |
2343 | + [ $size -gt 0 ] || err "$LINENO" |
2344 | bttdev=$(cat /sys/bus/nd/devices/$dev/holder) |
2345 | - [ -n "$bttdev" ] || err "$LINENO" 2 |
2346 | + [ -n "$bttdev" ] || err "$LINENO" |
2347 | if [ ! -e /sys/kernel/debug/btt/$bttdev/arena0/log_index_0 ]; then |
2348 | - echo "kernel $(uname -r) seems to be missing the BTT compatibility fixes, skipping" |
2349 | - exit 77 |
2350 | + do_skip "seems to be missing the BTT compatibility fixes, skipping." |
2351 | fi |
2352 | } |
2353 | |
2354 | reset() |
2355 | { |
2356 | - $ndctl disable-region -b "$bus" all |
2357 | - $ndctl zero-labels -b "$bus" all |
2358 | - $ndctl enable-region -b "$bus" all |
2359 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2360 | + $NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2361 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2362 | } |
2363 | |
2364 | verify_idx() |
2365 | @@ -105,16 +85,16 @@ cycle_ns() |
2366 | { |
2367 | local ns="$1" |
2368 | |
2369 | - $ndctl disable-namespace $ns |
2370 | - $ndctl enable-namespace $ns |
2371 | + $NDCTL disable-namespace $ns |
2372 | + $NDCTL enable-namespace $ns |
2373 | } |
2374 | |
2375 | force_raw() |
2376 | { |
2377 | raw="$1" |
2378 | - $ndctl disable-namespace "$dev" |
2379 | + $NDCTL disable-namespace "$dev" |
2380 | echo "$raw" > "/sys/bus/nd/devices/$dev/force_raw" |
2381 | - $ndctl enable-namespace "$dev" |
2382 | + $NDCTL enable-namespace "$dev" |
2383 | echo "Set $dev to raw mode: $raw" |
2384 | if [[ "$raw" == "1" ]]; then |
2385 | raw_bdev=${blockdev%s} |
2386 | @@ -140,23 +120,24 @@ create_oldfmt_ns() |
2387 | # that supports a raw namespace with a 4K sector size, prior to |
2388 | # v4.13 raw namespaces are limited to 512-byte sector size. |
2389 | rc=77 |
2390 | - json=$($ndctl create-namespace -b "$bus" -s 64M -t pmem -m raw -l 4096 -u 00000000-0000-0000-0000-000000000000) |
2391 | - rc=1 |
2392 | - eval "$(echo "$json" | sed -e "$json2var")" |
2393 | - [ -n "$dev" ] || err "$LINENO" 2 |
2394 | - [ -n "$size" ] || err "$LINENO" 2 |
2395 | - [ $size -gt 0 ] || err "$LINENO" 2 |
2396 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -s 64M -t pmem -m raw -l 4096 -u 00000000-0000-0000-0000-000000000000) |
2397 | + rc=2 |
2398 | + eval "$(echo "$json" | json2var)" |
2399 | + [ -n "$dev" ] || err "$LINENO" |
2400 | + [ -n "$size" ] || err "$LINENO" |
2401 | + [ $size -gt 0 ] || err "$LINENO" |
2402 | |
2403 | # reconfig it to sector mode |
2404 | - json=$($ndctl create-namespace -b "$bus" -e $dev -m sector --force) |
2405 | - eval "$(echo "$json" | sed -e "$json2var")" |
2406 | - [ -n "$dev" ] || err "$LINENO" 2 |
2407 | - [ -n "$size" ] || err "$LINENO" 2 |
2408 | - [ -n "$blockdev" ] || err "$LINENO" 2 |
2409 | - [ $size -gt 0 ] || err "$LINENO" 2 |
2410 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -e $dev -m sector --force) |
2411 | + eval "$(echo "$json" | json2var)" |
2412 | + [ -n "$dev" ] || err "$LINENO" |
2413 | + [ -n "$size" ] || err "$LINENO" |
2414 | + [ -n "$blockdev" ] || err "$LINENO" |
2415 | + [ $size -gt 0 ] || err "$LINENO" |
2416 | bttdev=$(cat /sys/bus/nd/devices/$dev/holder) |
2417 | - [ -n "$bttdev" ] || err "$LINENO" 2 |
2418 | + [ -n "$bttdev" ] || err "$LINENO" |
2419 | |
2420 | + rc=1 |
2421 | # copy old-padding-format btt image, and try to re-enable the resulting btt |
2422 | force_raw 1 |
2423 | copy_xxd_img "/dev/$raw_bdev" |
2424 | @@ -192,13 +173,13 @@ do_tests() |
2425 | verify_idx 0 2 |
2426 | |
2427 | # rewrite log using ndctl, verify conversion to new format |
2428 | - $ndctl check-namespace --rewrite-log --repair --force --verbose $dev |
2429 | + $NDCTL check-namespace --rewrite-log --repair --force --verbose $dev |
2430 | do_random_io "/dev/$blockdev" |
2431 | cycle_ns "$dev" |
2432 | verify_idx 0 1 |
2433 | |
2434 | # check-namespace again to make sure everything is ok |
2435 | - $ndctl check-namespace --force --verbose $dev |
2436 | + $NDCTL check-namespace --force --verbose $dev |
2437 | |
2438 | # the old format btt metadata was created with a null parent uuid, |
2439 | # making it 'stickier' than a normally created btt. Be sure to clean |
2440 | @@ -212,4 +193,5 @@ rc=1 |
2441 | reset |
2442 | do_tests |
2443 | reset |
2444 | +_cleanup |
2445 | exit 0 |
2446 | diff --git a/test/clear.sh b/test/clear.sh |
2447 | index d64dd27..6cc43db 100755 |
2448 | --- a/test/clear.sh |
2449 | +++ b/test/clear.sh |
2450 | @@ -11,46 +11,28 @@ |
2451 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2452 | # General Public License for more details. |
2453 | |
2454 | -DEV="" |
2455 | -NDCTL="../ndctl/ndctl" |
2456 | -BUS="-b nfit_test.0" |
2457 | -BUS1="-b nfit_test.1" |
2458 | -json2var="s/[{}\",]//g; s/:/=/g" |
2459 | -rc=77 |
2460 | - |
2461 | set -e |
2462 | |
2463 | -err() { |
2464 | - echo "test/clear: failed at line $1" |
2465 | - exit $rc |
2466 | -} |
2467 | - |
2468 | -check_min_kver() |
2469 | -{ |
2470 | - local ver="$1" |
2471 | - : "${KVER:=$(uname -r)}" |
2472 | +rc=77 |
2473 | |
2474 | - [ -n "$ver" ] || return 1 |
2475 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
2476 | -} |
2477 | +. ./common |
2478 | |
2479 | -check_min_kver "4.6" || { echo "kernel $KVER lacks clear poison support"; exit $rc; } |
2480 | +check_min_kver "4.6" || do_skip "lacks clear poison support" |
2481 | |
2482 | -set -e |
2483 | trap 'err $LINENO' ERR |
2484 | |
2485 | # setup (reset nfit_test dimms) |
2486 | modprobe nfit_test |
2487 | -$NDCTL disable-region $BUS all |
2488 | -$NDCTL zero-labels $BUS all |
2489 | -$NDCTL enable-region $BUS all |
2490 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2491 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2492 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2493 | |
2494 | rc=1 |
2495 | |
2496 | # create pmem |
2497 | dev="x" |
2498 | -json=$($NDCTL create-namespace $BUS -t pmem -m raw) |
2499 | -eval $(echo $json | sed -e "$json2var") |
2500 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m raw) |
2501 | +eval $(echo $json | json2var) |
2502 | [ $dev = "x" ] && echo "fail: $LINENO" && exit 1 |
2503 | [ $mode != "raw" ] && echo "fail: $LINENO" && exit 1 |
2504 | |
2505 | @@ -71,7 +53,7 @@ sector_raw=$sector |
2506 | |
2507 | # convert pmem to fsdax mode |
2508 | json=$($NDCTL create-namespace -m fsdax -f -e $dev) |
2509 | -eval $(echo $json | sed -e "$json2var") |
2510 | +eval $(echo $json | json2var) |
2511 | [ $mode != "fsdax" ] && echo "fail: $LINENO" && exit 1 |
2512 | |
2513 | # check for errors relative to the offset injected by the pfn device |
2514 | @@ -88,10 +70,10 @@ if read sector len < /sys/block/$blockdev/badblocks; then |
2515 | echo "fail: $LINENO" && exit 1 |
2516 | fi |
2517 | |
2518 | -if check_min_kver "4.9.0"; then |
2519 | +if check_min_kver "4.9"; then |
2520 | # check for re-appearance of stale badblocks from poison_list |
2521 | - $NDCTL disable-region $BUS all |
2522 | - $NDCTL enable-region $BUS all |
2523 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2524 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2525 | |
2526 | # since we have cleared the errors, a disable/reenable shouldn't bring them back |
2527 | if read sector len < /sys/block/$blockdev/badblocks; then |
2528 | @@ -100,8 +82,6 @@ if check_min_kver "4.9.0"; then |
2529 | fi |
2530 | fi |
2531 | |
2532 | -$NDCTL disable-region $BUS all |
2533 | -$NDCTL disable-region $BUS1 all |
2534 | -modprobe -r nfit_test |
2535 | +_cleanup |
2536 | |
2537 | exit 0 |
2538 | diff --git a/test/common b/test/common |
2539 | new file mode 100644 |
2540 | index 0000000..fb4e18e |
2541 | --- /dev/null |
2542 | +++ b/test/common |
2543 | @@ -0,0 +1,83 @@ |
2544 | + |
2545 | +# SPDX-License-Identifier: GPL-2.0 |
2546 | +# Copyright(c) 2018, FUJITSU LIMITED. All rights reserved. |
2547 | + |
2548 | +# Global variables |
2549 | + |
2550 | +# NDCTL |
2551 | +# |
2552 | +if [ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ]; then |
2553 | + export NDCTL=../ndctl/ndctl |
2554 | +elif [ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ]; then |
2555 | + export NDCTL=./ndctl/ndctl |
2556 | +else |
2557 | + echo "Couldn't find an ndctl binary" |
2558 | + exit 1 |
2559 | +fi |
2560 | + |
2561 | +# NFIT_TEST_BUS[01] |
2562 | +# |
2563 | +NFIT_TEST_BUS0=nfit_test.0 |
2564 | +NFIT_TEST_BUS1=nfit_test.1 |
2565 | + |
2566 | + |
2567 | +# Functions |
2568 | + |
2569 | +# err |
2570 | +# $1: line number which error detected |
2571 | +# $2: cleanup function (optional) |
2572 | +# |
2573 | +err() |
2574 | +{ |
2575 | + echo test/$(basename $0): failed at line $1 |
2576 | + [ -n "$2" ] && "$2" |
2577 | + exit $rc |
2578 | +} |
2579 | + |
2580 | +# check_min_kver |
2581 | +# $1: Supported kernel version. format: X.Y |
2582 | +# |
2583 | +check_min_kver() |
2584 | +{ |
2585 | + local ver="$1" |
2586 | + : "${KVER:=$(uname -r)}" |
2587 | + |
2588 | + [ -n "$ver" ] || return 1 |
2589 | + [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
2590 | +} |
2591 | + |
2592 | +# do_skip |
2593 | +# $1: Skip message |
2594 | +# |
2595 | +do_skip() |
2596 | +{ |
2597 | + echo kernel $(uname -r): $1 |
2598 | + exit 77 |
2599 | +} |
2600 | + |
2601 | +# check_prereq |
2602 | +# $1: command to check |
2603 | +# |
2604 | +check_prereq() |
2605 | +{ |
2606 | + if ! command -v "$1" >/dev/null; then |
2607 | + do_skip "missing $1, skipping..." |
2608 | + fi |
2609 | +} |
2610 | + |
2611 | +# _cleanup |
2612 | +# |
2613 | +_cleanup() |
2614 | +{ |
2615 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2616 | + $NDCTL disable-region -b $NFIT_TEST_BUS1 all |
2617 | + modprobe -r nfit_test |
2618 | +} |
2619 | + |
2620 | +# json2var |
2621 | +# stdin: json |
2622 | +# |
2623 | +json2var() |
2624 | +{ |
2625 | + sed -e "s/[{}\",]//g; s/:/=/g" |
2626 | +} |
2627 | diff --git a/test/create.sh b/test/create.sh |
2628 | index 3f30d6e..8d78797 100755 |
2629 | --- a/test/create.sh |
2630 | +++ b/test/create.sh |
2631 | @@ -11,57 +11,40 @@ |
2632 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
2633 | # General Public License for more details. |
2634 | |
2635 | -DEV="" |
2636 | -NDCTL="../ndctl/ndctl" |
2637 | -BUS="-b nfit_test.0" |
2638 | -json2var="s/[{}\",]//g; s/:/=/g" |
2639 | -SECTOR_SIZE="4096" |
2640 | -rc=77 |
2641 | - |
2642 | set -e |
2643 | |
2644 | -err() { |
2645 | - echo "test/create: failed at line $1" |
2646 | - exit $rc |
2647 | -} |
2648 | - |
2649 | -check_min_kver() |
2650 | -{ |
2651 | - local ver="$1" |
2652 | - : "${KVER:=$(uname -r)}" |
2653 | +SECTOR_SIZE="4096" |
2654 | +rc=77 |
2655 | |
2656 | - [ -n "$ver" ] || return 1 |
2657 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
2658 | -} |
2659 | +. ./common |
2660 | |
2661 | -check_min_kver "4.5" || { echo "kernel $KVER may lack namespace mode attribute"; exit $rc; } |
2662 | +check_min_kver "4.5" || do_skip "may lack namespace mode attribute" |
2663 | |
2664 | -set -e |
2665 | trap 'err $LINENO' ERR |
2666 | |
2667 | # setup (reset nfit_test dimms) |
2668 | modprobe nfit_test |
2669 | -$NDCTL disable-region $BUS all |
2670 | -$NDCTL zero-labels $BUS all |
2671 | -$NDCTL enable-region $BUS all |
2672 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
2673 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
2674 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
2675 | |
2676 | rc=1 |
2677 | |
2678 | # create pmem |
2679 | dev="x" |
2680 | -json=$($NDCTL create-namespace $BUS -t pmem -m raw) |
2681 | -eval $(echo $json | sed -e "$json2var") |
2682 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m raw) |
2683 | +eval $(echo $json | json2var ) |
2684 | [ $dev = "x" ] && echo "fail: $LINENO" && exit 1 |
2685 | [ $mode != "raw" ] && echo "fail: $LINENO" && exit 1 |
2686 | |
2687 | # convert pmem to fsdax mode |
2688 | json=$($NDCTL create-namespace -m fsdax -f -e $dev) |
2689 | -eval $(echo $json | sed -e "$json2var") |
2690 | +eval $(echo $json | json2var) |
2691 | [ $mode != "fsdax" ] && echo "fail: $LINENO" && exit 1 |
2692 | |
2693 | # convert pmem to sector mode |
2694 | json=$($NDCTL create-namespace -m sector -l $SECTOR_SIZE -f -e $dev) |
2695 | -eval $(echo $json | sed -e "$json2var") |
2696 | +eval $(echo $json | json2var) |
2697 | [ $sector_size != $SECTOR_SIZE ] && echo "fail: $LINENO" && exit 1 |
2698 | [ $mode != "sector" ] && echo "fail: $LINENO" && exit 1 |
2699 | |
2700 | @@ -70,15 +53,17 @@ $NDCTL destroy-namespace -f $dev |
2701 | |
2702 | # create blk |
2703 | dev="x" |
2704 | -json=$($NDCTL create-namespace $BUS -t blk -m raw -v) |
2705 | -eval $(echo $json | sed -e "$json2var") |
2706 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t blk -m raw -v) |
2707 | +eval $(echo $json | json2var) |
2708 | [ $dev = "x" ] && echo "fail: $LINENO" && exit 1 |
2709 | [ $mode != "raw" ] && echo "fail: $LINENO" && exit 1 |
2710 | |
2711 | # convert blk to sector mode |
2712 | json=$($NDCTL create-namespace -m sector -l $SECTOR_SIZE -f -e $dev) |
2713 | -eval $(echo $json | sed -e "$json2var") |
2714 | +eval $(echo $json | json2var) |
2715 | [ $sector_size != $SECTOR_SIZE ] && echo "fail: $LINENO" && exit 1 |
2716 | [ $mode != "sector" ] && echo "fail: $LINENO" && exit 1 |
2717 | |
2718 | +_cleanup |
2719 | + |
2720 | exit 0 |
2721 | diff --git a/test/dax-pmd.c b/test/dax-pmd.c |
2722 | index 06fe522..8ed3e9b 100644 |
2723 | --- a/test/dax-pmd.c |
2724 | +++ b/test/dax-pmd.c |
2725 | @@ -12,6 +12,7 @@ |
2726 | */ |
2727 | #include <stdio.h> |
2728 | #include <unistd.h> |
2729 | +#include <setjmp.h> |
2730 | #include <sys/mman.h> |
2731 | #include <linux/mman.h> |
2732 | #include <sys/types.h> |
2733 | @@ -125,7 +126,10 @@ int test_dax_directio(int dax_fd, unsigned long align, void *dax_addr, off_t off |
2734 | rc = -ENXIO; |
2735 | } |
2736 | ((char *) buf)[0] = 0; |
2737 | - pread(fd2, buf, 4096, 0); |
2738 | + if (pread(fd2, buf, 4096, 0) != 4096) { |
2739 | + faili(i); |
2740 | + rc = -ENXIO; |
2741 | + } |
2742 | if (strcmp(buf, "odirect data") != 0) { |
2743 | faili(i); |
2744 | rc = -ENXIO; |
2745 | @@ -190,14 +194,15 @@ int test_dax_directio(int dax_fd, unsigned long align, void *dax_addr, off_t off |
2746 | } |
2747 | |
2748 | /* test_pmd assumes that fd references a pre-allocated + dax-capable file */ |
2749 | -static int test_pmd(int fd) |
2750 | +static int test_pmd(struct ndctl_test *test, int fd) |
2751 | { |
2752 | - unsigned long long m_align, p_align; |
2753 | + unsigned long long m_align, p_align, pmd_off; |
2754 | + static const bool fsdax = true; |
2755 | struct fiemap_extent *ext; |
2756 | + void *base, *pmd_addr; |
2757 | struct fiemap *map; |
2758 | int rc = -ENXIO; |
2759 | unsigned long i; |
2760 | - void *base; |
2761 | |
2762 | if (fd < 0) { |
2763 | fail(); |
2764 | @@ -246,9 +251,15 @@ static int test_pmd(int fd) |
2765 | m_align = ALIGN(base, HPAGE_SIZE) - ((unsigned long) base); |
2766 | p_align = ALIGN(ext->fe_physical, HPAGE_SIZE) - ext->fe_physical; |
2767 | |
2768 | - rc = test_dax_directio(fd, HPAGE_SIZE, (char *) base + m_align, |
2769 | - ext->fe_logical + p_align); |
2770 | + pmd_addr = (char *) base + m_align; |
2771 | + pmd_off = ext->fe_logical + p_align; |
2772 | + rc = test_dax_directio(fd, HPAGE_SIZE, pmd_addr, pmd_off); |
2773 | + if (rc) |
2774 | + goto err_directio; |
2775 | + |
2776 | + rc = test_dax_poison(test, fd, HPAGE_SIZE, pmd_addr, pmd_off, fsdax); |
2777 | |
2778 | + err_directio: |
2779 | err_extent: |
2780 | err_mmap: |
2781 | free(map); |
2782 | @@ -257,14 +268,20 @@ static int test_pmd(int fd) |
2783 | |
2784 | int __attribute__((weak)) main(int argc, char *argv[]) |
2785 | { |
2786 | + struct ndctl_test *test = ndctl_test_new(0); |
2787 | int fd, rc; |
2788 | |
2789 | + if (!test) { |
2790 | + fprintf(stderr, "failed to initialize test\n"); |
2791 | + return EXIT_FAILURE; |
2792 | + } |
2793 | + |
2794 | if (argc < 1) |
2795 | return -EINVAL; |
2796 | |
2797 | fd = open(argv[1], O_RDWR); |
2798 | - rc = test_pmd(fd); |
2799 | + rc = test_pmd(test, fd); |
2800 | if (fd >= 0) |
2801 | close(fd); |
2802 | - return rc; |
2803 | + return ndctl_test_result(test, rc); |
2804 | } |
2805 | diff --git a/test/dax-poison.c b/test/dax-poison.c |
2806 | new file mode 100644 |
2807 | index 0000000..a25bf0b |
2808 | --- /dev/null |
2809 | +++ b/test/dax-poison.c |
2810 | @@ -0,0 +1,153 @@ |
2811 | +/* SPDX-License-Identifier: GPL-2.0 */ |
2812 | +/* Copyright(c) 2018 Intel Corporation. All rights reserved. */ |
2813 | +#include <stdio.h> |
2814 | +#include <unistd.h> |
2815 | +#include <signal.h> |
2816 | +#include <setjmp.h> |
2817 | +#include <sys/mman.h> |
2818 | +#include <linux/mman.h> |
2819 | +#include <fcntl.h> |
2820 | +#include <string.h> |
2821 | +#include <errno.h> |
2822 | +#include <sys/ioctl.h> |
2823 | +#include <stdlib.h> |
2824 | +#include <linux/fs.h> |
2825 | +#include <test.h> |
2826 | +#include <util/size.h> |
2827 | +#include <stdbool.h> |
2828 | +#include <linux/version.h> |
2829 | + |
2830 | +#define fail() fprintf(stderr, "%s: failed at: %d (%s)\n", \ |
2831 | + __func__, __LINE__, strerror(errno)) |
2832 | + |
2833 | +static sigjmp_buf sj_env; |
2834 | +static int sig_mcerr_ao, sig_mcerr_ar, sig_count; |
2835 | + |
2836 | +static void sigbus_hdl(int sig, siginfo_t *si, void *ptr) |
2837 | +{ |
2838 | + switch (si->si_code) { |
2839 | + case BUS_MCEERR_AO: |
2840 | + fprintf(stderr, "%s: BUS_MCEERR_AO addr: %p len: %d\n", |
2841 | + __func__, si->si_addr, 1 << si->si_addr_lsb); |
2842 | + sig_mcerr_ao++; |
2843 | + break; |
2844 | + case BUS_MCEERR_AR: |
2845 | + fprintf(stderr, "%s: BUS_MCEERR_AR addr: %p len: %d\n", |
2846 | + __func__, si->si_addr, 1 << si->si_addr_lsb); |
2847 | + sig_mcerr_ar++; |
2848 | + break; |
2849 | + default: |
2850 | + sig_count++; |
2851 | + break; |
2852 | + } |
2853 | + |
2854 | + siglongjmp(sj_env, 1); |
2855 | +} |
2856 | + |
2857 | +int test_dax_poison(struct ndctl_test *test, int dax_fd, unsigned long align, |
2858 | + void *dax_addr, off_t offset, bool fsdax) |
2859 | +{ |
2860 | + unsigned char *addr = MAP_FAILED; |
2861 | + struct sigaction act; |
2862 | + unsigned x = x; |
2863 | + void *buf; |
2864 | + int rc; |
2865 | + |
2866 | + if (!ndctl_test_attempt(test, KERNEL_VERSION(4, 19, 0))) |
2867 | + return 77; |
2868 | + |
2869 | + /* |
2870 | + * MADV_HWPOISON must be page aligned, and this routine assumes |
2871 | + * align is >= 8K |
2872 | + */ |
2873 | + if (align < SZ_2M) |
2874 | + return 0; |
2875 | + |
2876 | + if (posix_memalign(&buf, 4096, 4096) != 0) |
2877 | + return -ENOMEM; |
2878 | + |
2879 | + memset(&act, 0, sizeof(act)); |
2880 | + act.sa_sigaction = sigbus_hdl; |
2881 | + act.sa_flags = SA_SIGINFO; |
2882 | + |
2883 | + if (sigaction(SIGBUS, &act, 0)) { |
2884 | + fail(); |
2885 | + rc = -errno; |
2886 | + goto out; |
2887 | + } |
2888 | + |
2889 | + /* dirty the block on disk to bypass the default zero page */ |
2890 | + if (fsdax) { |
2891 | + rc = pwrite(dax_fd, buf, 4096, offset + align / 2); |
2892 | + if (rc < 4096) { |
2893 | + fail(); |
2894 | + rc = -ENXIO; |
2895 | + goto out; |
2896 | + } |
2897 | + fsync(dax_fd); |
2898 | + } |
2899 | + |
2900 | + addr = mmap(dax_addr, 2*align, PROT_READ|PROT_WRITE, |
2901 | + MAP_SHARED_VALIDATE|MAP_POPULATE|MAP_SYNC, dax_fd, offset); |
2902 | + if (addr == MAP_FAILED) { |
2903 | + fail(); |
2904 | + rc = -errno; |
2905 | + goto out; |
2906 | + } |
2907 | + |
2908 | + if (sigsetjmp(sj_env, 1)) { |
2909 | + if (sig_mcerr_ar) { |
2910 | + fprintf(stderr, "madvise triggered 'action required' sigbus\n"); |
2911 | + goto clear_error; |
2912 | + } else if (sig_count) { |
2913 | + fail(); |
2914 | + return -ENXIO; |
2915 | + } |
2916 | + } |
2917 | + |
2918 | + rc = madvise(addr + align / 2, 4096, MADV_HWPOISON); |
2919 | + if (rc) { |
2920 | + fail(); |
2921 | + rc = -errno; |
2922 | + goto out; |
2923 | + } |
2924 | + |
2925 | + /* clear the error */ |
2926 | +clear_error: |
2927 | + if (!sig_mcerr_ar) { |
2928 | + fail(); |
2929 | + rc = -ENXIO; |
2930 | + goto out; |
2931 | + } |
2932 | + |
2933 | + if (!fsdax) { |
2934 | + rc = 0; |
2935 | + goto out; |
2936 | + } |
2937 | + |
2938 | + rc = fallocate(dax_fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, |
2939 | + offset + align / 2, 4096); |
2940 | + if (rc) { |
2941 | + fail(); |
2942 | + rc = -errno; |
2943 | + goto out; |
2944 | + } |
2945 | + |
2946 | + rc = pwrite(dax_fd, buf, 4096, offset + align / 2); |
2947 | + if (rc < 4096) { |
2948 | + fail(); |
2949 | + rc = -ENXIO; |
2950 | + goto out; |
2951 | + } |
2952 | + fsync(dax_fd); |
2953 | + |
2954 | + /* check that we can fault in the poison page */ |
2955 | + x = *(volatile unsigned *) addr + align / 2; |
2956 | + rc = 0; |
2957 | + |
2958 | +out: |
2959 | + if (addr != MAP_FAILED) |
2960 | + munmap(addr, 2 * align); |
2961 | + free(buf); |
2962 | + return rc; |
2963 | +} |
2964 | diff --git a/test/dax.sh b/test/dax.sh |
2965 | index e35f914..30fe167 100755 |
2966 | --- a/test/dax.sh |
2967 | +++ b/test/dax.sh |
2968 | @@ -28,6 +28,15 @@ err() { |
2969 | exit $rc |
2970 | } |
2971 | |
2972 | +run_test() { |
2973 | + if ! ./dax-pmd $MNT/$FILE; then |
2974 | + rc=$? |
2975 | + if [ $rc -ne 77 -a $rc -ne 0 ]; then |
2976 | + err |
2977 | + fi |
2978 | + fi |
2979 | +} |
2980 | + |
2981 | set -e |
2982 | mkdir -p $MNT |
2983 | trap 'err $LINENO' ERR |
2984 | @@ -40,7 +49,7 @@ rc=1 |
2985 | mkfs.ext4 /dev/$blockdev |
2986 | mount /dev/$blockdev $MNT -o dax |
2987 | fallocate -l 1GiB $MNT/$FILE |
2988 | -./dax-pmd $MNT/$FILE |
2989 | +run_test |
2990 | umount $MNT |
2991 | |
2992 | # convert pmem to put the memmap on the device |
2993 | @@ -52,7 +61,7 @@ eval $(echo $json | sed -e "$json2var") |
2994 | mkfs.ext4 /dev/$blockdev |
2995 | mount /dev/$blockdev $MNT -o dax |
2996 | fallocate -l 1GiB $MNT/$FILE |
2997 | -./dax-pmd $MNT/$FILE |
2998 | +run_test |
2999 | umount $MNT |
3000 | |
3001 | json=$($NDCTL create-namespace -m raw -f -e $dev) |
3002 | @@ -62,7 +71,7 @@ eval $(echo $json | sed -e "$json2var") |
3003 | mkfs.xfs -f /dev/$blockdev |
3004 | mount /dev/$blockdev $MNT -o dax |
3005 | fallocate -l 1GiB $MNT/$FILE |
3006 | -./dax-pmd $MNT/$FILE |
3007 | +run_test |
3008 | umount $MNT |
3009 | |
3010 | # convert pmem to put the memmap on the device |
3011 | @@ -73,7 +82,7 @@ eval $(echo $json | sed -e "$json2var") |
3012 | mkfs.xfs -f /dev/$blockdev |
3013 | mount /dev/$blockdev $MNT -o dax |
3014 | fallocate -l 1GiB $MNT/$FILE |
3015 | -./dax-pmd $MNT/$FILE |
3016 | +run_test |
3017 | umount $MNT |
3018 | |
3019 | # revert namespace to raw mode |
3020 | @@ -81,4 +90,4 @@ json=$($NDCTL create-namespace -m raw -f -e $dev) |
3021 | eval $(echo $json | sed -e "$json2var") |
3022 | [ $mode != "fsdax" ] && echo "fail: $LINENO" && exit 1 |
3023 | |
3024 | -exit 0 |
3025 | +exit $rc |
3026 | diff --git a/test/daxdev-errors.sh b/test/daxdev-errors.sh |
3027 | index 0c8acf5..c5adb72 100755 |
3028 | --- a/test/daxdev-errors.sh |
3029 | +++ b/test/daxdev-errors.sh |
3030 | @@ -11,45 +11,28 @@ |
3031 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3032 | # General Public License for more details. |
3033 | |
3034 | -DEV="" |
3035 | -NDCTL="../ndctl/ndctl" |
3036 | -DAXCTL="../daxctl/daxctl" |
3037 | -BUS="-b nfit_test.0" |
3038 | -BUS1="-b nfit_test.1" |
3039 | -json2var="s/[{}\",]//g; s/:/=/g" |
3040 | -rc=77 |
3041 | - |
3042 | -err() { |
3043 | - echo "test/daxdev-errors: failed at line $1" |
3044 | - exit $rc |
3045 | -} |
3046 | +set -e |
3047 | |
3048 | -check_min_kver() |
3049 | -{ |
3050 | - local ver="$1" |
3051 | - : "${KVER:=$(uname -r)}" |
3052 | +rc=77 |
3053 | |
3054 | - [ -n "$ver" ] || return 1 |
3055 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3056 | -} |
3057 | +. ./common |
3058 | |
3059 | -check_min_kver "4.12" || { echo "kernel $KVER lacks dax dev error handling"; exit $rc; } |
3060 | +check_min_kver "4.12" || do_skip "lacks dax dev error handling" |
3061 | |
3062 | -set -e |
3063 | trap 'err $LINENO' ERR |
3064 | |
3065 | # setup (reset nfit_test dimms) |
3066 | modprobe nfit_test |
3067 | -$NDCTL disable-region $BUS all |
3068 | -$NDCTL zero-labels $BUS all |
3069 | -$NDCTL enable-region $BUS all |
3070 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3071 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3072 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3073 | |
3074 | rc=1 |
3075 | |
3076 | query=". | sort_by(.available_size) | reverse | .[0].dev" |
3077 | -region=$($NDCTL list $BUS -t pmem -Ri | jq -r "$query") |
3078 | +region=$($NDCTL list -b $NFIT_TEST_BUS0 -t pmem -Ri | jq -r "$query") |
3079 | |
3080 | -json=$($NDCTL create-namespace $BUS -r $region -t pmem -m devdax -a 4096) |
3081 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -r $region -t pmem -m devdax -a 4096) |
3082 | chardev=$(echo $json | jq ". | select(.mode == \"devdax\") | .daxregion.devices[0].chardev") |
3083 | |
3084 | #{ |
3085 | @@ -70,12 +53,12 @@ chardev=$(echo $json | jq ". | select(.mode == \"devdax\") | .daxregion.devices[ |
3086 | # } |
3087 | #} |
3088 | |
3089 | -json1=$($NDCTL list $BUS --mode=devdax --namespaces) |
3090 | -eval $(echo $json1 | sed -e "$json2var") |
3091 | +json1=$($NDCTL list -b $NFIT_TEST_BUS0 --mode=devdax --namespaces) |
3092 | +eval $(echo $json1 | json2var) |
3093 | nsdev=$dev |
3094 | |
3095 | -json1=$($NDCTL list $BUS) |
3096 | -eval $(echo $json1 | sed -e "$json2var") |
3097 | +json1=$($NDCTL list -b $NFIT_TEST_BUS0) |
3098 | +eval $(echo $json1 | json2var) |
3099 | busdev=$dev |
3100 | |
3101 | # inject errors in the middle of the namespace |
3102 | @@ -98,9 +81,6 @@ if read sector len < /sys/bus/platform/devices/nfit_test.0/$busdev/$region/badbl |
3103 | fi |
3104 | [ -n "$sector" ] && echo "fail: $LINENO" && exit 1 |
3105 | |
3106 | -# cleanup |
3107 | -$NDCTL disable-region $BUS all |
3108 | -$NDCTL disable-region $BUS1 all |
3109 | -modprobe -r nfit_test |
3110 | +_cleanup |
3111 | |
3112 | exit 0 |
3113 | diff --git a/test/device-dax.c b/test/device-dax.c |
3114 | index 0a42a32..dd92f9a 100644 |
3115 | --- a/test/device-dax.c |
3116 | +++ b/test/device-dax.c |
3117 | @@ -151,15 +151,6 @@ static int __test_device_dax(unsigned long align, int loglevel, |
3118 | struct daxctl_region *dax_region; |
3119 | char *buf, path[100], data[VERIFY_BUF_SIZE]; |
3120 | |
3121 | - memset (&act, 0, sizeof(act)); |
3122 | - act.sa_sigaction = sigbus; |
3123 | - act.sa_flags = SA_SIGINFO; |
3124 | - |
3125 | - if (sigaction(SIGBUS, &act, 0)) { |
3126 | - perror("sigaction"); |
3127 | - return 1; |
3128 | - } |
3129 | - |
3130 | ndctl_set_log_priority(ctx, loglevel); |
3131 | |
3132 | ndns = ndctl_get_test_dev(ctx); |
3133 | @@ -276,6 +267,7 @@ static int __test_device_dax(unsigned long align, int loglevel, |
3134 | * otherwise not supported. |
3135 | */ |
3136 | if (ndctl_test_attempt(test, KERNEL_VERSION(4, 9, 0))) { |
3137 | + static const bool devdax = false; |
3138 | int fd2; |
3139 | |
3140 | rc = test_dax_directio(fd, align, NULL, 0); |
3141 | @@ -285,6 +277,15 @@ static int __test_device_dax(unsigned long align, int loglevel, |
3142 | goto out; |
3143 | } |
3144 | |
3145 | + fprintf(stderr, "%s: test dax poison\n", |
3146 | + ndctl_namespace_get_devname(ndns)); |
3147 | + rc = test_dax_poison(test, fd, align, NULL, 0, devdax); |
3148 | + if (rc) { |
3149 | + fprintf(stderr, "%s: failed dax poison\n", |
3150 | + ndctl_namespace_get_devname(ndns)); |
3151 | + goto out; |
3152 | + } |
3153 | + |
3154 | fd2 = open("/proc/self/smaps", O_RDONLY); |
3155 | if (fd2 < 0) { |
3156 | fprintf(stderr, "%s: failed smaps open\n", |
3157 | @@ -312,6 +313,15 @@ static int __test_device_dax(unsigned long align, int loglevel, |
3158 | goto out; |
3159 | } |
3160 | |
3161 | + memset(&act, 0, sizeof(act)); |
3162 | + act.sa_sigaction = sigbus; |
3163 | + act.sa_flags = SA_SIGINFO; |
3164 | + if (sigaction(SIGBUS, &act, 0)) { |
3165 | + perror("sigaction"); |
3166 | + rc = EXIT_FAILURE; |
3167 | + goto out; |
3168 | + } |
3169 | + |
3170 | /* test fault after device-dax instance disabled */ |
3171 | if (sigsetjmp(sj_env, 1)) { |
3172 | /* got sigbus, success */ |
3173 | diff --git a/test/dsm-fail.c b/test/dsm-fail.c |
3174 | index 90d3e07..6845f81 100644 |
3175 | --- a/test/dsm-fail.c |
3176 | +++ b/test/dsm-fail.c |
3177 | @@ -24,12 +24,13 @@ |
3178 | |
3179 | #include <ccan/array_size/array_size.h> |
3180 | #include <ndctl/libndctl.h> |
3181 | +#include <builtin.h> |
3182 | #include <ndctl.h> |
3183 | #include <test.h> |
3184 | |
3185 | #define DIMM_PATH "/sys/devices/platform/nfit_test.0/nfit_test_dimm/test_dimm0" |
3186 | |
3187 | -static void reset_bus(struct ndctl_bus *bus) |
3188 | +static int reset_bus(struct ndctl_bus *bus) |
3189 | { |
3190 | struct ndctl_region *region; |
3191 | struct ndctl_dimm *dimm; |
3192 | @@ -38,20 +39,154 @@ static void reset_bus(struct ndctl_bus *bus) |
3193 | ndctl_region_foreach(bus, region) |
3194 | ndctl_region_disable_invalidate(region); |
3195 | |
3196 | - ndctl_dimm_foreach(bus, dimm) |
3197 | - ndctl_dimm_zero_labels(dimm); |
3198 | + ndctl_dimm_foreach(bus, dimm) { |
3199 | + if (!ndctl_dimm_read_labels(dimm)) |
3200 | + return -ENXIO; |
3201 | + ndctl_dimm_disable(dimm); |
3202 | + ndctl_dimm_init_labels(dimm, NDCTL_NS_VERSION_1_2); |
3203 | + ndctl_dimm_enable(dimm); |
3204 | + } |
3205 | |
3206 | /* set regions back to their default state */ |
3207 | ndctl_region_foreach(bus, region) |
3208 | ndctl_region_enable(region); |
3209 | + return 0; |
3210 | +} |
3211 | + |
3212 | +static int set_dimm_response(const char *dimm_path, int cmd, int error_code, |
3213 | + struct log_ctx *log_ctx) |
3214 | +{ |
3215 | + char path[1024], buf[SYSFS_ATTR_SIZE]; |
3216 | + int rc; |
3217 | + |
3218 | + if (error_code) { |
3219 | + sprintf(path, "%s/fail_cmd", dimm_path); |
3220 | + sprintf(buf, "%#x\n", 1 << cmd); |
3221 | + rc = __sysfs_write_attr(log_ctx, path, buf); |
3222 | + if (rc) |
3223 | + goto out; |
3224 | + sprintf(path, "%s/fail_cmd_code", dimm_path); |
3225 | + sprintf(buf, "%d\n", error_code); |
3226 | + rc = __sysfs_write_attr(log_ctx, path, buf); |
3227 | + if (rc) |
3228 | + goto out; |
3229 | + } else { |
3230 | + sprintf(path, "%s/fail_cmd", dimm_path); |
3231 | + sprintf(buf, "0\n"); |
3232 | + rc = __sysfs_write_attr(log_ctx, path, buf); |
3233 | + if (rc) |
3234 | + goto out; |
3235 | + } |
3236 | +out: |
3237 | + if (rc < 0) |
3238 | + fprintf(stderr, "%s failed, cmd: %d code: %d\n", |
3239 | + __func__, cmd, error_code); |
3240 | + return 0; |
3241 | +} |
3242 | + |
3243 | +static int dimms_disable(struct ndctl_bus *bus) |
3244 | +{ |
3245 | + struct ndctl_dimm *dimm; |
3246 | + |
3247 | + ndctl_dimm_foreach(bus, dimm) { |
3248 | + int rc = ndctl_dimm_disable(dimm); |
3249 | + |
3250 | + if (rc) { |
3251 | + fprintf(stderr, "dimm: %s failed to disable: %d\n", |
3252 | + ndctl_dimm_get_devname(dimm), rc); |
3253 | + return rc; |
3254 | + } |
3255 | + } |
3256 | + return 0; |
3257 | +} |
3258 | + |
3259 | +static int test_dimms_enable(struct ndctl_bus *bus, struct ndctl_dimm *victim, |
3260 | + bool expect) |
3261 | +{ |
3262 | + struct ndctl_dimm *dimm; |
3263 | + |
3264 | + ndctl_dimm_foreach(bus, dimm) { |
3265 | + int rc = ndctl_dimm_enable(dimm); |
3266 | + |
3267 | + if (((expect != (rc == 0)) && (dimm == victim)) |
3268 | + || (rc && dimm != victim)) { |
3269 | + bool __expect = true; |
3270 | + |
3271 | + if (dimm == victim) |
3272 | + __expect = expect; |
3273 | + fprintf(stderr, "fail expected %s enable %s victim: %s rc: %d\n", |
3274 | + ndctl_dimm_get_devname(dimm), |
3275 | + __expect ? "success" : "failure", |
3276 | + ndctl_dimm_get_devname(victim), rc); |
3277 | + return -ENXIO; |
3278 | + } |
3279 | + } |
3280 | + return 0; |
3281 | +} |
3282 | + |
3283 | +static int test_regions_enable(struct ndctl_bus *bus, |
3284 | + struct ndctl_dimm *victim, struct ndctl_region *victim_region, |
3285 | + bool region_expect, int namespace_count) |
3286 | +{ |
3287 | + struct ndctl_region *region; |
3288 | + |
3289 | + ndctl_region_foreach(bus, region) { |
3290 | + struct ndctl_namespace *ndns; |
3291 | + struct ndctl_dimm *dimm; |
3292 | + bool has_victim = false; |
3293 | + int rc, count = 0; |
3294 | + |
3295 | + ndctl_dimm_foreach_in_region(region, dimm) { |
3296 | + if (dimm == victim) { |
3297 | + has_victim = true; |
3298 | + break; |
3299 | + } |
3300 | + } |
3301 | + |
3302 | + rc = ndctl_region_enable(region); |
3303 | + fprintf(stderr, "region: %s enable: %d has_victim: %d\n", |
3304 | + ndctl_region_get_devname(region), rc, has_victim); |
3305 | + if (((region_expect != (rc == 0)) && has_victim) |
3306 | + || (rc && !has_victim)) { |
3307 | + bool __expect = true; |
3308 | + |
3309 | + if (has_victim) |
3310 | + __expect = region_expect; |
3311 | + fprintf(stderr, "%s: fail expected enable: %s with %s\n", |
3312 | + ndctl_region_get_devname(region), |
3313 | + __expect ? "success" : "failure", |
3314 | + ndctl_dimm_get_devname(victim)); |
3315 | + return -ENXIO; |
3316 | + } |
3317 | + if (region != victim_region) |
3318 | + continue; |
3319 | + ndctl_namespace_foreach(region, ndns) { |
3320 | + if (ndctl_namespace_is_enabled(ndns)) { |
3321 | + fprintf(stderr, "%s: enabled, expected disabled\n", |
3322 | + ndctl_namespace_get_devname(ndns)); |
3323 | + return -ENXIO; |
3324 | + } |
3325 | + fprintf(stderr, "%s: %s: size: %lld\n", __func__, |
3326 | + ndctl_namespace_get_devname(ndns), |
3327 | + ndctl_namespace_get_size(ndns)); |
3328 | + count++; |
3329 | + } |
3330 | + if (count != namespace_count) { |
3331 | + fprintf(stderr, "%s: fail expected %d namespaces got %d\n", |
3332 | + ndctl_region_get_devname(region), |
3333 | + namespace_count, count); |
3334 | + return -ENXIO; |
3335 | + } |
3336 | + } |
3337 | + return 0; |
3338 | } |
3339 | |
3340 | static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test) |
3341 | { |
3342 | struct ndctl_bus *bus = ndctl_bus_get_by_provider(ctx, "nfit_test.0"); |
3343 | + struct ndctl_region *region, *victim_region = NULL; |
3344 | struct ndctl_dimm *dimm, *victim = NULL; |
3345 | char path[1024], buf[SYSFS_ATTR_SIZE]; |
3346 | - struct ndctl_region *region; |
3347 | struct log_ctx log_ctx; |
3348 | unsigned int handle; |
3349 | int rc, err = 0; |
3350 | @@ -64,11 +199,10 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test) |
3351 | |
3352 | log_init(&log_ctx, "test/dsm-fail", "NDCTL_TEST"); |
3353 | |
3354 | - ndctl_bus_wait_probe(bus); |
3355 | - |
3356 | - /* disable all regions so that we can disable a dimm */ |
3357 | - ndctl_region_foreach(bus, region) |
3358 | - ndctl_region_disable_invalidate(region); |
3359 | + if (reset_bus(bus)) { |
3360 | + fprintf(stderr, "failed to read labels\n"); |
3361 | + return -ENXIO; |
3362 | + } |
3363 | |
3364 | sprintf(path, "%s/handle", DIMM_PATH); |
3365 | rc = __sysfs_read_attr(&log_ctx, path, buf); |
3366 | @@ -79,16 +213,11 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test) |
3367 | |
3368 | handle = strtoul(buf, NULL, 0); |
3369 | |
3370 | - ndctl_dimm_foreach(bus, dimm) { |
3371 | - if (ndctl_dimm_get_handle(dimm) == handle) |
3372 | + ndctl_dimm_foreach(bus, dimm) |
3373 | + if (ndctl_dimm_get_handle(dimm) == handle) { |
3374 | victim = dimm; |
3375 | - |
3376 | - if (ndctl_dimm_disable(dimm)) { |
3377 | - fprintf(stderr, "failed to disable: %s\n", |
3378 | - ndctl_dimm_get_devname(dimm)); |
3379 | - return -ENXIO; |
3380 | + break; |
3381 | } |
3382 | - } |
3383 | |
3384 | if (!victim) { |
3385 | fprintf(stderr, "failed to find victim dimm\n"); |
3386 | @@ -96,67 +225,133 @@ static int do_test(struct ndctl_ctx *ctx, struct ndctl_test *test) |
3387 | } |
3388 | fprintf(stderr, "victim: %s\n", ndctl_dimm_get_devname(victim)); |
3389 | |
3390 | - sprintf(path, "%s/fail_cmd", DIMM_PATH); |
3391 | - sprintf(buf, "%#x\n", 1 << ND_CMD_GET_CONFIG_SIZE); |
3392 | - rc = __sysfs_write_attr(&log_ctx, path, buf); |
3393 | - if (rc) { |
3394 | - fprintf(stderr, "failed to set fail cmd mask\n"); |
3395 | - return -ENXIO; |
3396 | - } |
3397 | + ndctl_region_foreach(bus, region) { |
3398 | + if (ndctl_region_get_type(region) != ND_DEVICE_REGION_PMEM) |
3399 | + continue; |
3400 | + ndctl_dimm_foreach_in_region(region, dimm) { |
3401 | + const char *argv[] = { |
3402 | + "__func__", "-v", "-r", |
3403 | + ndctl_region_get_devname(region), |
3404 | + "-s", "4M", "-m", "raw", |
3405 | + }; |
3406 | + struct ndctl_namespace *ndns; |
3407 | + int count, i; |
3408 | |
3409 | - ndctl_dimm_foreach(bus, dimm) { |
3410 | - rc = ndctl_dimm_enable(dimm); |
3411 | - fprintf(stderr, "dimm: %s enable: %d\n", |
3412 | - ndctl_dimm_get_devname(dimm), rc); |
3413 | - if ((rc == 0) == (dimm == victim)) { |
3414 | - fprintf(stderr, "fail expected %s enable %s victim: %s\n", |
3415 | - ndctl_dimm_get_devname(dimm), |
3416 | - (dimm == victim) ? "failure" : "success", |
3417 | - ndctl_dimm_get_devname(victim)); |
3418 | - err = -ENXIO; |
3419 | - goto out; |
3420 | + if (dimm != victim) |
3421 | + continue; |
3422 | + /* |
3423 | + * Validate that we only have the one seed |
3424 | + * namespace, and then create one so that we can |
3425 | + * verify namespace enumeration while locked. |
3426 | + */ |
3427 | + count = 0; |
3428 | + ndctl_namespace_foreach(region, ndns) |
3429 | + count++; |
3430 | + if (count != 1) { |
3431 | + fprintf(stderr, "%s: found %d namespaces expected 1\n", |
3432 | + ndctl_region_get_devname(region), |
3433 | + count); |
3434 | + rc = -ENXIO; |
3435 | + goto out; |
3436 | + } |
3437 | + if (ndctl_region_get_size(region) |
3438 | + != ndctl_region_get_available_size(region)) { |
3439 | + fprintf(stderr, "%s: expected empty region\n", |
3440 | + ndctl_region_get_devname(region)); |
3441 | + rc = -ENXIO; |
3442 | + goto out; |
3443 | + } |
3444 | + for (i = 0; i < 2; i++) { |
3445 | + builtin_xaction_namespace_reset(); |
3446 | + rc = cmd_create_namespace(ARRAY_SIZE(argv), argv, |
3447 | + ndctl_region_get_ctx(region)); |
3448 | + if (rc) { |
3449 | + fprintf(stderr, "%s: failed to create namespace\n", |
3450 | + ndctl_region_get_devname(region)); |
3451 | + rc = -ENXIO; |
3452 | + goto out; |
3453 | + } |
3454 | + } |
3455 | + victim_region = region; |
3456 | } |
3457 | + if (victim_region) |
3458 | + break; |
3459 | } |
3460 | |
3461 | - ndctl_region_foreach(bus, region) { |
3462 | - bool has_victim = false; |
3463 | + /* disable all regions so that we can disable a dimm */ |
3464 | + ndctl_region_foreach(bus, region) |
3465 | + ndctl_region_disable_invalidate(region); |
3466 | |
3467 | - ndctl_dimm_foreach_in_region(region, dimm) { |
3468 | - if (dimm == victim) { |
3469 | - has_victim = true; |
3470 | - break; |
3471 | - } |
3472 | - } |
3473 | + rc = dimms_disable(bus); |
3474 | + if (rc) |
3475 | + goto out; |
3476 | |
3477 | - rc = ndctl_region_enable(region); |
3478 | - fprintf(stderr, "region: %s enable: %d has_victim: %d\n", |
3479 | - ndctl_region_get_devname(region), rc, has_victim); |
3480 | - if ((rc == 0) == has_victim) { |
3481 | - fprintf(stderr, "fail expected %s enable %s with %s disabled\n", |
3482 | - ndctl_region_get_devname(region), |
3483 | - has_victim ? "failure" : "success", |
3484 | - ndctl_dimm_get_devname(victim)); |
3485 | - err = -ENXIO; |
3486 | - goto out; |
3487 | - } |
3488 | - } |
3489 | + |
3490 | + rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, -EACCES, |
3491 | + &log_ctx); |
3492 | + if (rc) |
3493 | + goto out; |
3494 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3495 | + rc = test_dimms_enable(bus, victim, true); |
3496 | + if (rc) |
3497 | + goto out; |
3498 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3499 | + rc = test_regions_enable(bus, victim, victim_region, true, 2); |
3500 | + if (rc) |
3501 | + goto out; |
3502 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3503 | + rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_SIZE, 0, &log_ctx); |
3504 | + if (rc) |
3505 | + goto out; |
3506 | + |
3507 | + ndctl_region_foreach(bus, region) |
3508 | + ndctl_region_disable_invalidate(region); |
3509 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3510 | + rc = dimms_disable(bus); |
3511 | + if (rc) |
3512 | + goto out; |
3513 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3514 | + |
3515 | + rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, -EACCES, |
3516 | + &log_ctx); |
3517 | + if (rc) |
3518 | + goto out; |
3519 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3520 | + rc = test_dimms_enable(bus, victim, false); |
3521 | + if (rc) |
3522 | + goto out; |
3523 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3524 | + rc = test_regions_enable(bus, victim, victim_region, false, 0); |
3525 | + if (rc) |
3526 | + goto out; |
3527 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3528 | + rc = set_dimm_response(DIMM_PATH, ND_CMD_GET_CONFIG_DATA, 0, &log_ctx); |
3529 | + if (rc) |
3530 | + goto out; |
3531 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3532 | + rc = dimms_disable(bus); |
3533 | + if (rc) |
3534 | + goto out; |
3535 | + fprintf(stderr, "%s:%d\n", __func__, __LINE__); |
3536 | |
3537 | out: |
3538 | + err = rc; |
3539 | + sprintf(path, "%s/fail_cmd", DIMM_PATH); |
3540 | sprintf(buf, "0\n"); |
3541 | rc = __sysfs_write_attr(&log_ctx, path, buf); |
3542 | - if (rc) { |
3543 | + if (rc) |
3544 | fprintf(stderr, "%s: failed to clear fail_cmd mask\n", |
3545 | ndctl_dimm_get_devname(victim)); |
3546 | - err = -ENXIO; |
3547 | - } |
3548 | rc = ndctl_dimm_enable(victim); |
3549 | if (rc) { |
3550 | fprintf(stderr, "failed to enable victim: %s after clearing error\n", |
3551 | ndctl_dimm_get_devname(victim)); |
3552 | - err = -ENXIO; |
3553 | + rc = -ENXIO; |
3554 | } |
3555 | reset_bus(bus); |
3556 | |
3557 | + if (rc) |
3558 | + err = rc; |
3559 | return err; |
3560 | } |
3561 | |
3562 | diff --git a/test/firmware-update.sh b/test/firmware-update.sh |
3563 | index c2cf578..50674a6 100755 |
3564 | --- a/test/firmware-update.sh |
3565 | +++ b/test/firmware-update.sh |
3566 | @@ -2,70 +2,43 @@ |
3567 | # SPDX-License-Identifier: GPL-2.0 |
3568 | # Copyright(c) 2018 Intel Corporation. All rights reserved. |
3569 | |
3570 | -[ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ] && ndctl="../ndctl/ndctl" |
3571 | -[ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ] && ndctl="./ndctl/ndctl" |
3572 | -[ -z "$ndctl" ] && echo "Couldn't find an ndctl binary" && exit 1 |
3573 | -bus="nfit_test.0" |
3574 | -bus1="nfit_test.1" |
3575 | -json2var="s/[{}\",]//g; s/:/=/g" |
3576 | rc=77 |
3577 | dev="" |
3578 | image="update-fw.img" |
3579 | |
3580 | -trap 'err $LINENO' ERR |
3581 | - |
3582 | -# $1: Line number |
3583 | -# $2: exit code |
3584 | -err() |
3585 | -{ |
3586 | - [ -n "$2" ] && rc="$2" |
3587 | - echo "test/firmware-update.sh: failed at line $1" |
3588 | - exit "$rc" |
3589 | -} |
3590 | - |
3591 | -check_min_kver() |
3592 | -{ |
3593 | - local ver="$1" |
3594 | - : "${KVER:=$(uname -r)}" |
3595 | +. ./common |
3596 | |
3597 | - [ -n "$ver" ] || return 1 |
3598 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3599 | -} |
3600 | +trap 'err $LINENO' ERR |
3601 | |
3602 | reset() |
3603 | { |
3604 | - $ndctl disable-region -b "$bus" all |
3605 | - $ndctl zero-labels -b "$bus" all |
3606 | - $ndctl enable-region -b "$bus" all |
3607 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3608 | + $NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3609 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3610 | if [ -f $image ]; then |
3611 | rm -f $image |
3612 | fi |
3613 | } |
3614 | |
3615 | -cleanup() |
3616 | -{ |
3617 | - $ndctl disable-region -b "$bus" all |
3618 | - $ndctl disable-region -b "$bus1" all |
3619 | - modprobe -r nfit_test |
3620 | -} |
3621 | - |
3622 | detect() |
3623 | { |
3624 | - dev=$($ndctl list -b "$bus" -D | jq .[0].dev | tr -d '"') |
3625 | - [ -n "$dev" ] || err "$LINENO" 2 |
3626 | + dev=$($NDCTL list -b $NFIT_TEST_BUS0 -D | jq .[0].dev | tr -d '"') |
3627 | + [ -n "$dev" ] || err "$LINENO" |
3628 | } |
3629 | |
3630 | do_tests() |
3631 | { |
3632 | truncate -s 196608 $image |
3633 | - $ndctl update-firmware -f $image $dev |
3634 | + $NDCTL update-firmware -f $image $dev |
3635 | } |
3636 | |
3637 | -check_min_kver "4.16" || { echo "kernel $KVER may lack firmware update test handling"; exit $rc; } |
3638 | +check_min_kver "4.16" || do_skip "may lack firmware update test handling" |
3639 | + |
3640 | modprobe nfit_test |
3641 | rc=1 |
3642 | reset |
3643 | +rc=2 |
3644 | detect |
3645 | do_tests |
3646 | -cleanup |
3647 | +_cleanup |
3648 | exit 0 |
3649 | diff --git a/test/inject-error.sh b/test/inject-error.sh |
3650 | index 8630745..7bda35b 100755 |
3651 | --- a/test/inject-error.sh |
3652 | +++ b/test/inject-error.sh |
3653 | @@ -11,11 +11,6 @@ |
3654 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3655 | # General Public License for more details. |
3656 | |
3657 | -[ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ] && ndctl="../ndctl/ndctl" |
3658 | -[ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ] && ndctl="./ndctl/ndctl" |
3659 | -[ -z "$ndctl" ] && echo "Couldn't find an ndctl binary" && exit 1 |
3660 | -bus="nfit_test.0" |
3661 | -json2var="s/[{}\",]//g; s/:/=/g" |
3662 | dev="" |
3663 | size="" |
3664 | blockdev="" |
3665 | @@ -23,6 +18,8 @@ rc=77 |
3666 | err_block=42 |
3667 | err_count=8 |
3668 | |
3669 | +. ./common |
3670 | + |
3671 | trap 'err $LINENO' ERR |
3672 | |
3673 | # sample json: |
3674 | @@ -34,41 +31,24 @@ trap 'err $LINENO' ERR |
3675 | # "blockdev":"pmem7", |
3676 | #} |
3677 | |
3678 | -# $1: Line number |
3679 | -# $2: exit code |
3680 | -err() |
3681 | -{ |
3682 | - [ -n "$2" ] && rc="$2" |
3683 | - echo "test/inject-error.sh: failed at line $1" |
3684 | - exit "$rc" |
3685 | -} |
3686 | - |
3687 | -check_min_kver() |
3688 | -{ |
3689 | - local ver="$1" |
3690 | - : "${KVER:=$(uname -r)}" |
3691 | - |
3692 | - [ -n "$ver" ] || return 1 |
3693 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3694 | -} |
3695 | - |
3696 | -check_min_kver "4.15" || { echo "kernel $KVER may not support error injection"; exit "$rc"; } |
3697 | +check_min_kver "4.15" || do_skip "kernel $KVER may not support error injection" |
3698 | |
3699 | create() |
3700 | { |
3701 | - json=$($ndctl create-namespace -b "$bus" -t pmem --align=4k) |
3702 | - eval "$(echo "$json" | sed -e "$json2var")" |
3703 | - [ -n "$dev" ] || err "$LINENO" 2 |
3704 | - [ -n "$size" ] || err "$LINENO" 2 |
3705 | - [ -n "$blockdev" ] || err "$LINENO" 2 |
3706 | - [ $size -gt 0 ] || err "$LINENO" 2 |
3707 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem --align=4k) |
3708 | + rc=2 |
3709 | + eval "$(echo "$json" | json2var)" |
3710 | + [ -n "$dev" ] || err "$LINENO" |
3711 | + [ -n "$size" ] || err "$LINENO" |
3712 | + [ -n "$blockdev" ] || err "$LINENO" |
3713 | + [ $size -gt 0 ] || err "$LINENO" |
3714 | } |
3715 | |
3716 | reset() |
3717 | { |
3718 | - $ndctl disable-region -b "$bus" all |
3719 | - $ndctl zero-labels -b "$bus" all |
3720 | - $ndctl enable-region -b "$bus" all |
3721 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3722 | + $NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3723 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3724 | } |
3725 | |
3726 | check_status() |
3727 | @@ -76,7 +56,7 @@ check_status() |
3728 | local sector="$1" |
3729 | local count="$2" |
3730 | |
3731 | - json="$($ndctl inject-error --status $dev)" |
3732 | + json="$($NDCTL inject-error --status $dev)" |
3733 | [[ "$sector" == "$(jq ".badblocks[0].block" <<< "$json")" ]] |
3734 | [[ "$count" == "$(jq ".badblocks[0].count" <<< "$json")" ]] |
3735 | } |
3736 | @@ -84,7 +64,7 @@ check_status() |
3737 | do_tests() |
3738 | { |
3739 | # inject without notification |
3740 | - $ndctl inject-error --block=$err_block --count=$err_count --no-notify $dev |
3741 | + $NDCTL inject-error --block=$err_block --count=$err_count --no-notify $dev |
3742 | check_status "$err_block" "$err_count" |
3743 | if read -r sector len < /sys/block/$blockdev/badblocks; then |
3744 | # fail if reading badblocks returns data |
3745 | @@ -92,11 +72,11 @@ do_tests() |
3746 | fi |
3747 | |
3748 | # clear via err-inj-clear |
3749 | - $ndctl inject-error --block=$err_block --count=$err_count --uninject $dev |
3750 | + $NDCTL inject-error --block=$err_block --count=$err_count --uninject $dev |
3751 | check_status |
3752 | |
3753 | # inject normally |
3754 | - $ndctl inject-error --block=$err_block --count=$err_count $dev |
3755 | + $NDCTL inject-error --block=$err_block --count=$err_count $dev |
3756 | check_status "$err_block" "$err_count" |
3757 | if read -r sector len < /sys/block/$blockdev/badblocks; then |
3758 | test "$sector" -eq "$err_block" |
3759 | @@ -117,4 +97,5 @@ rc=1 |
3760 | reset && create |
3761 | do_tests |
3762 | reset |
3763 | +_cleanup |
3764 | exit 0 |
3765 | diff --git a/test/label-compat.sh b/test/label-compat.sh |
3766 | index 8c9ee63..dc6226d 100755 |
3767 | --- a/test/label-compat.sh |
3768 | +++ b/test/label-compat.sh |
3769 | @@ -11,40 +11,24 @@ |
3770 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3771 | # General Public License for more details. |
3772 | |
3773 | -NDCTL="../ndctl/ndctl" |
3774 | -BUS="-b nfit_test.0" |
3775 | -BUS1="-b nfit_test.1" |
3776 | -rc=77 |
3777 | - |
3778 | set -e |
3779 | |
3780 | -err() { |
3781 | - echo "test/label-compat.sh: failed at line $1" |
3782 | - exit $rc |
3783 | -} |
3784 | - |
3785 | -check_min_kver() |
3786 | -{ |
3787 | - local ver="$1" |
3788 | - : "${KVER:=$(uname -r)}" |
3789 | +rc=77 |
3790 | |
3791 | - [ -n "$ver" ] || return 1 |
3792 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3793 | -} |
3794 | +. ./common |
3795 | |
3796 | -check_min_kver "4.11" || { echo "kernel $KVER may not provide reliable isetcookie values"; exit $rc; } |
3797 | +check_min_kver "4.11" || do_skip "may not provide reliable isetcookie values" |
3798 | |
3799 | -set -e |
3800 | trap 'err $LINENO' ERR |
3801 | |
3802 | # setup (reset nfit_test dimms) |
3803 | modprobe nfit_test |
3804 | -$NDCTL disable-region $BUS all |
3805 | -$NDCTL zero-labels $BUS all |
3806 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3807 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3808 | |
3809 | -# grab the largest pmem region on $BUS |
3810 | +# grab the largest pmem region on -b $NFIT_TEST_BUS0 |
3811 | query=". | sort_by(.available_size) | reverse | .[0].dev" |
3812 | -region=$($NDCTL list $BUS -t pmem -Ri | jq -r "$query") |
3813 | +region=$($NDCTL list -b $NFIT_TEST_BUS0 -t pmem -Ri | jq -r "$query") |
3814 | |
3815 | # we assume that $region is comprised of 4 dimms |
3816 | query=". | .regions[0].mappings | sort_by(.dimm) | .[].dimm" |
3817 | @@ -56,7 +40,7 @@ do |
3818 | i=$((i+1)) |
3819 | done |
3820 | |
3821 | -$NDCTL enable-region $BUS all |
3822 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3823 | |
3824 | len=$($NDCTL list -r $region -N | jq -r "length") |
3825 | |
3826 | @@ -66,8 +50,6 @@ if [ -z $len ]; then |
3827 | exit 1 |
3828 | fi |
3829 | |
3830 | -$NDCTL disable-region $BUS all |
3831 | -$NDCTL disable-region $BUS1 all |
3832 | -modprobe -r nfit_test |
3833 | +_cleanup |
3834 | |
3835 | exit 0 |
3836 | diff --git a/test/libndctl.c b/test/libndctl.c |
3837 | index 8098c1c..edff0af 100644 |
3838 | --- a/test/libndctl.c |
3839 | +++ b/test/libndctl.c |
3840 | @@ -2177,8 +2177,8 @@ static int check_set_config_data(struct ndctl_bus *bus, struct ndctl_dimm *dimm, |
3841 | return 0; |
3842 | } |
3843 | |
3844 | -#define __check_smart(dimm, cmd, field) ({ \ |
3845 | - if (ndctl_cmd_smart_get_##field(cmd) != smart_data.field) { \ |
3846 | +#define __check_smart(dimm, cmd, field, mask) ({ \ |
3847 | + if ((ndctl_cmd_smart_get_##field(cmd) & mask) != smart_data.field) { \ |
3848 | fprintf(stderr, "%s dimm: %#x expected \'" #field \ |
3849 | "\' %#x got: %#x\n", __func__, \ |
3850 | ndctl_dimm_get_handle(dimm), \ |
3851 | @@ -2230,14 +2230,14 @@ static int check_smart(struct ndctl_bus *bus, struct ndctl_dimm *dimm, |
3852 | return rc; |
3853 | } |
3854 | |
3855 | - __check_smart(dimm, cmd, flags); |
3856 | - __check_smart(dimm, cmd, health); |
3857 | - __check_smart(dimm, cmd, temperature); |
3858 | - __check_smart(dimm, cmd, spares); |
3859 | - __check_smart(dimm, cmd, alarm_flags); |
3860 | - __check_smart(dimm, cmd, life_used); |
3861 | - __check_smart(dimm, cmd, shutdown_state); |
3862 | - __check_smart(dimm, cmd, vendor_size); |
3863 | + __check_smart(dimm, cmd, flags, ~ND_SMART_CTEMP_VALID); |
3864 | + __check_smart(dimm, cmd, health, -1); |
3865 | + __check_smart(dimm, cmd, temperature, -1); |
3866 | + __check_smart(dimm, cmd, spares, -1); |
3867 | + __check_smart(dimm, cmd, alarm_flags, -1); |
3868 | + __check_smart(dimm, cmd, life_used, -1); |
3869 | + __check_smart(dimm, cmd, shutdown_state, -1); |
3870 | + __check_smart(dimm, cmd, vendor_size, -1); |
3871 | |
3872 | check->cmd = cmd; |
3873 | return 0; |
3874 | diff --git a/test/multi-dax.sh b/test/multi-dax.sh |
3875 | index 59ec6d6..0829bf2 100755 |
3876 | --- a/test/multi-dax.sh |
3877 | +++ b/test/multi-dax.sh |
3878 | @@ -11,51 +11,31 @@ |
3879 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
3880 | # General Public License for more details. |
3881 | |
3882 | -DEV="" |
3883 | -NDCTL="../ndctl/ndctl" |
3884 | -DAXCTL="../daxctl/daxctl" |
3885 | -BUS="-b nfit_test.0" |
3886 | -BUS1="-b nfit_test.1" |
3887 | -json2var="s/[{}\",]//g; s/:/=/g" |
3888 | -rc=77 |
3889 | - |
3890 | -err() { |
3891 | - echo "test/multi-dax: failed at line $1" |
3892 | - exit $rc |
3893 | -} |
3894 | +set -e |
3895 | |
3896 | -check_min_kver() |
3897 | -{ |
3898 | - local ver="$1" |
3899 | - : "${KVER:=$(uname -r)}" |
3900 | +rc=77 |
3901 | |
3902 | - [ -n "$ver" ] || return 1 |
3903 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3904 | -} |
3905 | +. ./common |
3906 | |
3907 | -check_min_kver "4.13" || { echo "kernel $KVER may lack multi-dax support"; exit $rc; } |
3908 | +check_min_kver "4.13" || do_skip "may lack multi-dax support" |
3909 | |
3910 | -set -e |
3911 | trap 'err $LINENO' ERR |
3912 | |
3913 | # setup (reset nfit_test dimms) |
3914 | modprobe nfit_test |
3915 | -$NDCTL disable-region $BUS all |
3916 | -$NDCTL zero-labels $BUS all |
3917 | -$NDCTL enable-region $BUS all |
3918 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3919 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3920 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3921 | rc=1 |
3922 | |
3923 | query=". | sort_by(.available_size) | reverse | .[0].dev" |
3924 | -region=$($NDCTL list $BUS -t pmem -Ri | jq -r "$query") |
3925 | +region=$($NDCTL list -b $NFIT_TEST_BUS0 -t pmem -Ri | jq -r "$query") |
3926 | |
3927 | -json=$($NDCTL create-namespace $BUS -r $region -t pmem -m devdax -a 4096 -s 16M) |
3928 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -r $region -t pmem -m devdax -a 4096 -s 16M) |
3929 | chardev1=$(echo $json | jq ". | select(.mode == \"devdax\") | .daxregion.devices[0].chardev") |
3930 | -json=$($NDCTL create-namespace $BUS -r $region -t pmem -m devdax -a 4096 -s 16M) |
3931 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -r $region -t pmem -m devdax -a 4096 -s 16M) |
3932 | chardev2=$(echo $json | jq ". | select(.mode == \"devdax\") | .daxregion.devices[0].chardev") |
3933 | |
3934 | -# cleanup |
3935 | -$NDCTL disable-region $BUS all |
3936 | -$NDCTL disable-region $BUS1 all |
3937 | -modprobe -r nfit_test |
3938 | +_cleanup |
3939 | |
3940 | exit 0 |
3941 | diff --git a/test/pmem-errors.sh b/test/pmem-errors.sh |
3942 | index e0ab9e8..9553a3f 100755 |
3943 | --- a/test/pmem-errors.sh |
3944 | +++ b/test/pmem-errors.sh |
3945 | @@ -2,17 +2,14 @@ |
3946 | # SPDX-License-Identifier: GPL-2.0 |
3947 | # Copyright(c) 2015-2017 Intel Corporation. All rights reserved. |
3948 | |
3949 | -DEV="" |
3950 | -NDCTL="../ndctl/ndctl" |
3951 | -BUS="-b nfit_test.0" |
3952 | -BUS1="-b nfit_test.1" |
3953 | MNT=test_dax_mnt |
3954 | FILE=image |
3955 | -json2var="s/[{}\",]//g; s/:/=/g" |
3956 | rc=77 |
3957 | |
3958 | -err() { |
3959 | - echo "test/dax-errors: failed at line $1" |
3960 | +. ./common |
3961 | + |
3962 | +cleanup() |
3963 | +{ |
3964 | rm -f $FILE |
3965 | rm -f $MNT/$FILE |
3966 | if [ -n "$blockdev" ]; then |
3967 | @@ -21,36 +18,26 @@ err() { |
3968 | rc=77 |
3969 | fi |
3970 | rmdir $MNT |
3971 | - exit $rc |
3972 | -} |
3973 | - |
3974 | -check_min_kver() |
3975 | -{ |
3976 | - local ver="$1" |
3977 | - : "${KVER:=$(uname -r)}" |
3978 | - |
3979 | - [ -n "$ver" ] || return 1 |
3980 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
3981 | } |
3982 | |
3983 | -check_min_kver "4.7" || { echo "kernel $KVER may lack dax error handling"; exit $rc; } |
3984 | +check_min_kver "4.7" || do_skip "may lack dax error handling" |
3985 | |
3986 | set -e |
3987 | mkdir -p $MNT |
3988 | -trap 'err $LINENO' ERR |
3989 | +trap 'err $LINENO cleanup' ERR |
3990 | |
3991 | # setup (reset nfit_test dimms) |
3992 | modprobe nfit_test |
3993 | -$NDCTL disable-region $BUS all |
3994 | -$NDCTL zero-labels $BUS all |
3995 | -$NDCTL enable-region $BUS all |
3996 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
3997 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
3998 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
3999 | |
4000 | rc=1 |
4001 | |
4002 | # create pmem |
4003 | dev="x" |
4004 | -json=$($NDCTL create-namespace $BUS -t pmem -m raw) |
4005 | -eval $(echo $json | sed -e "$json2var") |
4006 | +json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m raw) |
4007 | +eval $(echo $json | json2var) |
4008 | [ $dev = "x" ] && echo "fail: $LINENO" && false |
4009 | [ $mode != "raw" ] && echo "fail: $LINENO" && false |
4010 | |
4011 | @@ -134,8 +121,6 @@ if [ -n "$blockdev" ]; then |
4012 | fi |
4013 | rmdir $MNT |
4014 | |
4015 | -$NDCTL disable-region $BUS all |
4016 | -$NDCTL disable-region $BUS1 all |
4017 | -modprobe -r nfit_test |
4018 | +_cleanup |
4019 | |
4020 | exit 0 |
4021 | diff --git a/test/rescan-partitions.sh b/test/rescan-partitions.sh |
4022 | index eb313fb..9c7b7a0 100755 |
4023 | --- a/test/rescan-partitions.sh |
4024 | +++ b/test/rescan-partitions.sh |
4025 | @@ -2,16 +2,13 @@ |
4026 | # SPDX-License-Identifier: GPL-2.0 |
4027 | # Copyright(c) 2018 Intel Corporation. All rights reserved. |
4028 | |
4029 | -[ -f "../ndctl/ndctl" ] && [ -x "../ndctl/ndctl" ] && ndctl="../ndctl/ndctl" |
4030 | -[ -f "./ndctl/ndctl" ] && [ -x "./ndctl/ndctl" ] && ndctl="./ndctl/ndctl" |
4031 | -[ -z "$ndctl" ] && echo "Couldn't find an ndctl binary" && exit 1 |
4032 | -bus="nfit_test.0" |
4033 | -json2var="s/[{}\",]//g; s/:/=/g" |
4034 | dev="" |
4035 | size="" |
4036 | blockdev="" |
4037 | rc=77 |
4038 | |
4039 | +. ./common |
4040 | + |
4041 | trap 'err $LINENO' ERR |
4042 | |
4043 | # sample json: |
4044 | @@ -23,40 +20,16 @@ trap 'err $LINENO' ERR |
4045 | # "blockdev":"pmem5s", |
4046 | #} |
4047 | |
4048 | -# $1: Line number |
4049 | -# $2: exit code |
4050 | -err() |
4051 | -{ |
4052 | - [ -n "$2" ] && rc="$2" |
4053 | - echo "test/rescan-partitions.sh: failed at line $1" |
4054 | - exit "$rc" |
4055 | -} |
4056 | - |
4057 | -check_min_kver() |
4058 | -{ |
4059 | - local ver="$1" |
4060 | - : "${KVER:=$(uname -r)}" |
4061 | - |
4062 | - [ -n "$ver" ] || return 1 |
4063 | - [[ "$ver" == "$(echo -e "$ver\n$KVER" | sort -V | head -1)" ]] |
4064 | -} |
4065 | -check_min_kver "4.16" || { echo "kernel $KVER may not contain fixes for partition rescanning"; exit "$rc"; } |
4066 | +check_min_kver "4.16" || do_skip "may not contain fixes for partition rescanning" |
4067 | |
4068 | -check_prereq() |
4069 | -{ |
4070 | - if ! command -v "$1" >/dev/null; then |
4071 | - echo "missing '$1', skipping.." |
4072 | - exit "$rc" |
4073 | - fi |
4074 | -} |
4075 | check_prereq "parted" |
4076 | check_prereq "blockdev" |
4077 | |
4078 | reset() |
4079 | { |
4080 | - $ndctl disable-region -b "$bus" all |
4081 | - $ndctl zero-labels -b "$bus" all |
4082 | - $ndctl enable-region -b "$bus" all |
4083 | + $NDCTL disable-region -b $NFIT_TEST_BUS0 all |
4084 | + $NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
4085 | + $NDCTL enable-region -b $NFIT_TEST_BUS0 all |
4086 | } |
4087 | |
4088 | test_mode() |
4089 | @@ -64,13 +37,15 @@ test_mode() |
4090 | local mode="$1" |
4091 | |
4092 | # create namespace |
4093 | - json=$($ndctl create-namespace -b "$bus" -t pmem -m "$mode") |
4094 | - eval "$(echo "$json" | sed -e "$json2var")" |
4095 | - [ -n "$dev" ] || err "$LINENO" 2 |
4096 | - [ -n "$size" ] || err "$LINENO" 2 |
4097 | - [ -n "$blockdev" ] || err "$LINENO" 2 |
4098 | - [ $size -gt 0 ] || err "$LINENO" 2 |
4099 | - |
4100 | + json=$($NDCTL create-namespace -b $NFIT_TEST_BUS0 -t pmem -m "$mode") |
4101 | + rc=2 |
4102 | + eval "$(echo "$json" | json2var)" |
4103 | + [ -n "$dev" ] || err "$LINENO" |
4104 | + [ -n "$size" ] || err "$LINENO" |
4105 | + [ -n "$blockdev" ] || err "$LINENO" |
4106 | + [ $size -gt 0 ] || err "$LINENO" |
4107 | + |
4108 | + rc=1 |
4109 | # create partition |
4110 | parted --script /dev/$blockdev mklabel gpt mkpart primary 1MiB 10MiB |
4111 | |
4112 | @@ -83,17 +58,18 @@ test_mode() |
4113 | |
4114 | # cycle the namespace, and verify the partition is read |
4115 | # without needing to do a blockdev --rereadpt |
4116 | - $ndctl disable-namespace $dev |
4117 | - $ndctl enable-namespace $dev |
4118 | + $NDCTL disable-namespace $dev |
4119 | + $NDCTL enable-namespace $dev |
4120 | if [ -b /dev/$partdev ]; then |
4121 | echo "mode: $mode - partition read successful" |
4122 | else |
4123 | echo "mode: $mode - partition read failed" |
4124 | - err "$LINENO" 1 |
4125 | + rc=1 |
4126 | + err "$LINENO" |
4127 | fi |
4128 | |
4129 | - $ndctl disable-namespace $dev |
4130 | - $ndctl destroy-namespace $dev |
4131 | + $NDCTL disable-namespace $dev |
4132 | + $NDCTL destroy-namespace $dev |
4133 | } |
4134 | |
4135 | modprobe nfit_test |
4136 | @@ -102,5 +78,5 @@ reset |
4137 | test_mode "raw" |
4138 | test_mode "fsdax" |
4139 | test_mode "sector" |
4140 | - |
4141 | +_cleanup |
4142 | exit 0 |
4143 | diff --git a/test/sector-mode.sh b/test/sector-mode.sh |
4144 | index ee364eb..16c1ddf 100755 |
4145 | --- a/test/sector-mode.sh |
4146 | +++ b/test/sector-mode.sh |
4147 | @@ -11,45 +11,32 @@ |
4148 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
4149 | # General Public License for more details. |
4150 | |
4151 | -NDCTL="../ndctl/ndctl" |
4152 | -BUS="-b nfit_test.0" |
4153 | -BUS1="-b nfit_test.1" |
4154 | -TEST=$0 |
4155 | rc=77 |
4156 | |
4157 | -err() { |
4158 | - echo "$TEST: failed at line $1" |
4159 | - exit $rc |
4160 | -} |
4161 | +. ./common |
4162 | |
4163 | set -e |
4164 | trap 'err $LINENO' ERR |
4165 | |
4166 | # setup (reset nfit_test dimms) |
4167 | modprobe nfit_test |
4168 | -$NDCTL disable-region $BUS all |
4169 | -$NDCTL zero-labels $BUS all |
4170 | -$NDCTL enable-region $BUS all |
4171 | - |
4172 | -$NDCTL disable-region $BUS1 all |
4173 | -if $NDCTL zero-labels $BUS1 all; then |
4174 | - echo "DIMMs on $BUS1 support labels, skip..." |
4175 | - $NDCTL enable-region $BUS1 all |
4176 | - false |
4177 | -fi |
4178 | -$NDCTL enable-region $BUS1 all |
4179 | +$NDCTL disable-region -b $NFIT_TEST_BUS0 all |
4180 | +$NDCTL zero-labels -b $NFIT_TEST_BUS0 all |
4181 | +$NDCTL enable-region -b $NFIT_TEST_BUS0 all |
4182 | + |
4183 | +$NDCTL disable-region -b $NFIT_TEST_BUS1 all |
4184 | +$NDCTL zero-labels -b $NFIT_TEST_BUS1 all |
4185 | +$NDCTL enable-region -b $NFIT_TEST_BUS1 all |
4186 | |
4187 | rc=1 |
4188 | query=". | sort_by(.size) | reverse | .[0].dev" |
4189 | -NAMESPACE=$($NDCTL list $BUS1 -N | jq -r "$query") |
4190 | +NAMESPACE=$($NDCTL list -b $NFIT_TEST_BUS1 -N | jq -r "$query") |
4191 | REGION=$($NDCTL list -R --namespace=$NAMESPACE | jq -r ".dev") |
4192 | echo 0 > /sys/bus/nd/devices/$REGION/read_only |
4193 | -$NDCTL create-namespace -e $NAMESPACE -m sector -f -l 4K |
4194 | -$NDCTL create-namespace -e $NAMESPACE -m dax -f -a 4K |
4195 | -$NDCTL create-namespace -e $NAMESPACE -m sector -f -l 4K |
4196 | +$NDCTL create-namespace --no-autolabel -e $NAMESPACE -m sector -f -l 4K |
4197 | +$NDCTL create-namespace --no-autolabel -e $NAMESPACE -m dax -f -a 4K |
4198 | +$NDCTL create-namespace --no-autolabel -e $NAMESPACE -m sector -f -l 4K |
4199 | |
4200 | -$NDCTL disable-region $BUS all |
4201 | -$NDCTL disable-region $BUS1 all |
4202 | -modprobe -r nfit_test |
4203 | +_cleanup |
4204 | |
4205 | exit 0 |
4206 | diff --git a/util/abspath.c b/util/abspath.c |
4207 | new file mode 100644 |
4208 | index 0000000..09bbd27 |
4209 | --- /dev/null |
4210 | +++ b/util/abspath.c |
4211 | @@ -0,0 +1,29 @@ |
4212 | +/* SPDX-License-Identifier: GPL-2.0 */ |
4213 | +/* originally copied from git/abspath.c */ |
4214 | + |
4215 | +#include <util/util.h> |
4216 | +#include <util/strbuf.h> |
4217 | + |
4218 | +char *prefix_filename(const char *pfx, const char *arg) |
4219 | +{ |
4220 | + struct strbuf path = STRBUF_INIT; |
4221 | + size_t pfx_len = pfx ? strlen(pfx) : 0; |
4222 | + |
4223 | + if (!pfx_len) |
4224 | + ; |
4225 | + else if (is_absolute_path(arg)) |
4226 | + pfx_len = 0; |
4227 | + else |
4228 | + strbuf_add(&path, pfx, pfx_len); |
4229 | + |
4230 | + strbuf_addstr(&path, arg); |
4231 | + return strbuf_detach(&path, NULL); |
4232 | +} |
4233 | + |
4234 | +void fix_filename(const char *prefix, const char **file) |
4235 | +{ |
4236 | + if (!file || !*file || !prefix || is_absolute_path(*file) |
4237 | + || !strcmp("-", *file)) |
4238 | + return; |
4239 | + *file = prefix_filename(prefix, *file); |
4240 | +} |
4241 | diff --git a/util/filter.c b/util/filter.c |
4242 | index 6ab391a..1734bce 100644 |
4243 | --- a/util/filter.c |
4244 | +++ b/util/filter.c |
4245 | @@ -25,101 +25,156 @@ |
4246 | |
4247 | #define NUMA_NO_NODE (-1) |
4248 | |
4249 | -struct ndctl_bus *util_bus_filter(struct ndctl_bus *bus, const char *ident) |
4250 | +struct ndctl_bus *util_bus_filter(struct ndctl_bus *bus, const char *__ident) |
4251 | { |
4252 | - char *end = NULL; |
4253 | + char *end = NULL, *ident, *save; |
4254 | unsigned long bus_id, id; |
4255 | - const char *provider, *devname; |
4256 | + const char *provider, *devname, *name; |
4257 | |
4258 | - if (!ident || strcmp(ident, "all") == 0) |
4259 | + if (!__ident) |
4260 | return bus; |
4261 | |
4262 | - bus_id = strtoul(ident, &end, 0); |
4263 | - if (end == ident || end[0]) |
4264 | - bus_id = ULONG_MAX; |
4265 | + ident = strdup(__ident); |
4266 | + if (!ident) |
4267 | + return NULL; |
4268 | |
4269 | - provider = ndctl_bus_get_provider(bus); |
4270 | - devname = ndctl_bus_get_devname(bus); |
4271 | - id = ndctl_bus_get_id(bus); |
4272 | + for (name = strtok_r(ident, " ", &save); name; |
4273 | + name = strtok_r(NULL, " ", &save)) { |
4274 | + if (strcmp(name, "all") == 0) |
4275 | + break; |
4276 | |
4277 | - if (bus_id < ULONG_MAX && bus_id == id) |
4278 | - return bus; |
4279 | + bus_id = strtoul(ident, &end, 0); |
4280 | + if (end == ident || end[0]) |
4281 | + bus_id = ULONG_MAX; |
4282 | |
4283 | - if (bus_id == ULONG_MAX && (strcmp(ident, provider) == 0 |
4284 | - || strcmp(ident, devname) == 0)) |
4285 | - return bus; |
4286 | + provider = ndctl_bus_get_provider(bus); |
4287 | + devname = ndctl_bus_get_devname(bus); |
4288 | + id = ndctl_bus_get_id(bus); |
4289 | + |
4290 | + if (bus_id < ULONG_MAX && bus_id == id) |
4291 | + break; |
4292 | |
4293 | + if (bus_id == ULONG_MAX && (strcmp(provider, name) == 0 |
4294 | + || strcmp(devname, name) == 0)) |
4295 | + break; |
4296 | + } |
4297 | + free(ident); |
4298 | + |
4299 | + if (name) |
4300 | + return bus; |
4301 | return NULL; |
4302 | } |
4303 | |
4304 | struct ndctl_region *util_region_filter(struct ndctl_region *region, |
4305 | - const char *ident) |
4306 | + const char *__ident) |
4307 | { |
4308 | - char *end = NULL; |
4309 | - const char *name; |
4310 | + char *end = NULL, *ident, *save; |
4311 | + const char *name, *region_name; |
4312 | unsigned long region_id, id; |
4313 | |
4314 | - if (!ident || strcmp(ident, "all") == 0) |
4315 | + if (!__ident) |
4316 | return region; |
4317 | |
4318 | - region_id = strtoul(ident, &end, 0); |
4319 | - if (end == ident || end[0]) |
4320 | - region_id = ULONG_MAX; |
4321 | + ident = strdup(__ident); |
4322 | + if (!ident) |
4323 | + return NULL; |
4324 | |
4325 | - name = ndctl_region_get_devname(region); |
4326 | - id = ndctl_region_get_id(region); |
4327 | + for (name = strtok_r(ident, " ", &save); name; |
4328 | + name = strtok_r(NULL, " ", &save)) { |
4329 | + if (strcmp(name, "all") == 0) |
4330 | + break; |
4331 | |
4332 | - if (region_id < ULONG_MAX && region_id == id) |
4333 | - return region; |
4334 | + region_id = strtoul(ident, &end, 0); |
4335 | + if (end == ident || end[0]) |
4336 | + region_id = ULONG_MAX; |
4337 | |
4338 | - if (region_id == ULONG_MAX && strcmp(ident, name) == 0) |
4339 | - return region; |
4340 | + region_name = ndctl_region_get_devname(region); |
4341 | + id = ndctl_region_get_id(region); |
4342 | |
4343 | + if (region_id < ULONG_MAX && region_id == id) |
4344 | + break; |
4345 | + |
4346 | + if (region_id == ULONG_MAX && strcmp(region_name, name) == 0) |
4347 | + break; |
4348 | + } |
4349 | + free(ident); |
4350 | + |
4351 | + if (name) |
4352 | + return region; |
4353 | return NULL; |
4354 | } |
4355 | |
4356 | struct ndctl_namespace *util_namespace_filter(struct ndctl_namespace *ndns, |
4357 | - const char *ident) |
4358 | + const char *__ident) |
4359 | { |
4360 | struct ndctl_region *region = ndctl_namespace_get_region(ndns); |
4361 | unsigned long region_id, ndns_id; |
4362 | + const char *name; |
4363 | + char *ident, *save; |
4364 | |
4365 | - if (!ident || strcmp(ident, "all") == 0) |
4366 | + if (!__ident) |
4367 | return ndns; |
4368 | |
4369 | - if (strcmp(ident, ndctl_namespace_get_devname(ndns)) == 0) |
4370 | - return ndns; |
4371 | + ident = strdup(__ident); |
4372 | + if (!ident) |
4373 | + return NULL; |
4374 | |
4375 | - if (sscanf(ident, "%ld.%ld", ®ion_id, &ndns_id) == 2 |
4376 | - && ndctl_region_get_id(region) == region_id |
4377 | - && ndctl_namespace_get_id(ndns) == ndns_id) |
4378 | - return ndns; |
4379 | + for (name = strtok_r(ident, " ", &save); name; |
4380 | + name = strtok_r(NULL, " ", &save)) { |
4381 | + if (strcmp(name, "all") == 0) |
4382 | + break; |
4383 | |
4384 | + if (strcmp(name, ndctl_namespace_get_devname(ndns)) == 0) |
4385 | + break; |
4386 | + |
4387 | + if (sscanf(name, "%ld.%ld", ®ion_id, &ndns_id) == 2 |
4388 | + && ndctl_region_get_id(region) == region_id |
4389 | + && ndctl_namespace_get_id(ndns) == ndns_id) |
4390 | + break; |
4391 | + } |
4392 | + free(ident); |
4393 | + |
4394 | + if (name) |
4395 | + return ndns; |
4396 | return NULL; |
4397 | } |
4398 | |
4399 | -struct ndctl_dimm *util_dimm_filter(struct ndctl_dimm *dimm, const char *ident) |
4400 | +struct ndctl_dimm *util_dimm_filter(struct ndctl_dimm *dimm, |
4401 | + const char *__ident) |
4402 | { |
4403 | - char *end = NULL; |
4404 | - const char *name; |
4405 | + char *end = NULL, *ident, *save; |
4406 | + const char *name, *dimm_name; |
4407 | unsigned long dimm_id, id; |
4408 | |
4409 | - if (!ident || strcmp(ident, "all") == 0) |
4410 | + if (!__ident) |
4411 | return dimm; |
4412 | |
4413 | - dimm_id = strtoul(ident, &end, 0); |
4414 | - if (end == ident || end[0]) |
4415 | - dimm_id = ULONG_MAX; |
4416 | + ident = strdup(__ident); |
4417 | + if (!ident) |
4418 | + return NULL; |
4419 | |
4420 | - name = ndctl_dimm_get_devname(dimm); |
4421 | - id = ndctl_dimm_get_id(dimm); |
4422 | + for (name = strtok_r(ident, " ", &save); name; |
4423 | + name = strtok_r(NULL, " ", &save)) { |
4424 | + if (strcmp(name, "all") == 0) |
4425 | + break; |
4426 | |
4427 | - if (dimm_id < ULONG_MAX && dimm_id == id) |
4428 | - return dimm; |
4429 | + dimm_id = strtoul(ident, &end, 0); |
4430 | + if (end == ident || end[0]) |
4431 | + dimm_id = ULONG_MAX; |
4432 | |
4433 | - if (dimm_id == ULONG_MAX && strcmp(ident, name) == 0) |
4434 | - return dimm; |
4435 | + dimm_name = ndctl_dimm_get_devname(dimm); |
4436 | + id = ndctl_dimm_get_id(dimm); |
4437 | |
4438 | + if (dimm_id < ULONG_MAX && dimm_id == id) |
4439 | + break; |
4440 | + |
4441 | + if (dimm_id == ULONG_MAX && strcmp(dimm_name, name) == 0) |
4442 | + break; |
4443 | + } |
4444 | + free(ident); |
4445 | + |
4446 | + if (name) |
4447 | + return dimm; |
4448 | return NULL; |
4449 | } |
4450 | |
4451 | diff --git a/util/help.c b/util/help.c |
4452 | index 8b8f951..2d57fa1 100644 |
4453 | --- a/util/help.c |
4454 | +++ b/util/help.c |
4455 | @@ -89,11 +89,6 @@ static char *cmd_to_page(const char *cmd, char **page, const char *util_name) |
4456 | return *page; |
4457 | } |
4458 | |
4459 | -static int is_absolute_path(const char *path) |
4460 | -{ |
4461 | - return path[0] == '/'; |
4462 | -} |
4463 | - |
4464 | static const char *system_path(const char *path) |
4465 | { |
4466 | static const char *prefix = PREFIX; |
4467 | diff --git a/util/json.c b/util/json.c |
4468 | index 1772177..94ed948 100644 |
4469 | --- a/util/json.c |
4470 | +++ b/util/json.c |
4471 | @@ -652,10 +652,12 @@ static struct json_object *util_dax_badblocks_to_json(struct ndctl_dax *dax, |
4472 | |
4473 | static struct json_object *util_raw_uuid(struct ndctl_namespace *ndns) |
4474 | { |
4475 | - uuid_t raw_uuid; |
4476 | char buf[40]; |
4477 | + uuid_t raw_uuid; |
4478 | |
4479 | ndctl_namespace_get_uuid(ndns, raw_uuid); |
4480 | + if (uuid_is_null(raw_uuid)) |
4481 | + return NULL; |
4482 | uuid_unparse(raw_uuid, buf); |
4483 | return json_object_new_string(buf); |
4484 | } |
4485 | @@ -664,7 +666,13 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4486 | unsigned long flags) |
4487 | { |
4488 | struct json_object *jndns = json_object_new_object(); |
4489 | + enum ndctl_pfn_loc loc = NDCTL_PFN_LOC_NONE; |
4490 | struct json_object *jobj, *jbbs = NULL; |
4491 | + const char *locations[] = { |
4492 | + [NDCTL_PFN_LOC_NONE] = "none", |
4493 | + [NDCTL_PFN_LOC_RAM] = "mem", |
4494 | + [NDCTL_PFN_LOC_PMEM] = "dev", |
4495 | + }; |
4496 | unsigned long long size = ULLONG_MAX; |
4497 | unsigned int sector_size = UINT_MAX; |
4498 | enum ndctl_namespace_mode mode; |
4499 | @@ -691,10 +699,13 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4500 | mode = ndctl_namespace_get_mode(ndns); |
4501 | switch (mode) { |
4502 | case NDCTL_NS_MODE_MEMORY: |
4503 | - if (pfn) /* dynamic memory mode */ |
4504 | + if (pfn) { /* dynamic memory mode */ |
4505 | size = ndctl_pfn_get_size(pfn); |
4506 | - else /* native/static memory mode */ |
4507 | + loc = ndctl_pfn_get_location(pfn); |
4508 | + } else { /* native/static memory mode */ |
4509 | size = ndctl_namespace_get_size(ndns); |
4510 | + loc = NDCTL_PFN_LOC_RAM; |
4511 | + } |
4512 | jobj = json_object_new_string("fsdax"); |
4513 | break; |
4514 | case NDCTL_NS_MODE_DAX: |
4515 | @@ -702,6 +713,7 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4516 | goto err; |
4517 | size = ndctl_dax_get_size(dax); |
4518 | jobj = json_object_new_string("devdax"); |
4519 | + loc = ndctl_dax_get_location(dax); |
4520 | break; |
4521 | case NDCTL_NS_MODE_SAFE: |
4522 | if (!btt) |
4523 | @@ -719,6 +731,12 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4524 | if (jobj) |
4525 | json_object_object_add(jndns, "mode", jobj); |
4526 | |
4527 | + if ((mode != NDCTL_NS_MODE_SAFE) && (mode != NDCTL_NS_MODE_RAW)) { |
4528 | + jobj = json_object_new_string(locations[loc]); |
4529 | + if (jobj) |
4530 | + json_object_object_add(jndns, "map", jobj); |
4531 | + } |
4532 | + |
4533 | if (size < ULLONG_MAX) { |
4534 | jobj = util_json_object_size(size, flags); |
4535 | if (jobj) |
4536 | @@ -734,9 +752,8 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4537 | json_object_object_add(jndns, "uuid", jobj); |
4538 | |
4539 | jobj = util_raw_uuid(ndns); |
4540 | - if (!jobj) |
4541 | - goto err; |
4542 | - json_object_object_add(jndns, "raw_uuid", jobj); |
4543 | + if (jobj) |
4544 | + json_object_object_add(jndns, "raw_uuid", jobj); |
4545 | bdev = ndctl_btt_get_block_device(btt); |
4546 | } else if (pfn) { |
4547 | ndctl_pfn_get_uuid(pfn, uuid); |
4548 | @@ -746,9 +763,8 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4549 | goto err; |
4550 | json_object_object_add(jndns, "uuid", jobj); |
4551 | jobj = util_raw_uuid(ndns); |
4552 | - if (!jobj) |
4553 | - goto err; |
4554 | - json_object_object_add(jndns, "raw_uuid", jobj); |
4555 | + if (jobj) |
4556 | + json_object_object_add(jndns, "raw_uuid", jobj); |
4557 | bdev = ndctl_pfn_get_block_device(pfn); |
4558 | } else if (dax) { |
4559 | struct daxctl_region *dax_region; |
4560 | @@ -761,9 +777,8 @@ struct json_object *util_namespace_to_json(struct ndctl_namespace *ndns, |
4561 | goto err; |
4562 | json_object_object_add(jndns, "uuid", jobj); |
4563 | jobj = util_raw_uuid(ndns); |
4564 | - if (!jobj) |
4565 | - goto err; |
4566 | - json_object_object_add(jndns, "raw_uuid", jobj); |
4567 | + if (jobj) |
4568 | + json_object_object_add(jndns, "raw_uuid", jobj); |
4569 | if ((flags & UTIL_JSON_DAX) && dax_region) { |
4570 | jobj = util_daxctl_region_to_json(dax_region, NULL, |
4571 | flags); |
4572 | diff --git a/util/parse-options.c b/util/parse-options.c |
4573 | index 751c091..c781174 100644 |
4574 | --- a/util/parse-options.c |
4575 | +++ b/util/parse-options.c |
4576 | @@ -55,6 +55,7 @@ static int get_value(struct parse_opt_ctx_t *p, |
4577 | { |
4578 | const char *s, *arg = NULL; |
4579 | const int unset = flags & OPT_UNSET; |
4580 | + int err; |
4581 | |
4582 | if (unset && p->opt) |
4583 | return opterror(opt, "takes no value", flags); |
4584 | @@ -77,6 +78,7 @@ static int get_value(struct parse_opt_ctx_t *p, |
4585 | case OPTION_ARGUMENT: |
4586 | case OPTION_GROUP: |
4587 | case OPTION_STRING: |
4588 | + case OPTION_FILENAME: |
4589 | case OPTION_INTEGER: |
4590 | case OPTION_UINTEGER: |
4591 | case OPTION_LONG: |
4592 | @@ -121,6 +123,19 @@ static int get_value(struct parse_opt_ctx_t *p, |
4593 | return get_arg(p, opt, flags, (const char **)opt->value); |
4594 | return 0; |
4595 | |
4596 | + case OPTION_FILENAME: |
4597 | + err = 0; |
4598 | + if (unset) |
4599 | + *(const char **)opt->value = NULL; |
4600 | + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) |
4601 | + *(const char **)opt->value = (const char *)opt->defval; |
4602 | + else |
4603 | + err = get_arg(p, opt, flags, (const char **)opt->value); |
4604 | + |
4605 | + if (!err) |
4606 | + fix_filename(p->prefix, (const char **)opt->value); |
4607 | + return err; |
4608 | + |
4609 | case OPTION_CALLBACK: |
4610 | if (unset) |
4611 | return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; |
4612 | @@ -339,13 +354,14 @@ static void check_typos(const char *arg, const struct option *options) |
4613 | } |
4614 | } |
4615 | |
4616 | -void parse_options_start(struct parse_opt_ctx_t *ctx, |
4617 | - int argc, const char **argv, int flags) |
4618 | +void parse_options_start(struct parse_opt_ctx_t *ctx, int argc, |
4619 | + const char **argv, const char *prefix, int flags) |
4620 | { |
4621 | memset(ctx, 0, sizeof(*ctx)); |
4622 | ctx->argc = argc - 1; |
4623 | ctx->argv = argv + 1; |
4624 | ctx->out = argv; |
4625 | + ctx->prefix = prefix; |
4626 | ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0); |
4627 | ctx->flags = flags; |
4628 | if ((flags & PARSE_OPT_KEEP_UNKNOWN) && |
4629 | @@ -453,8 +469,10 @@ int parse_options_end(struct parse_opt_ctx_t *ctx) |
4630 | return ctx->cpidx + ctx->argc; |
4631 | } |
4632 | |
4633 | -int parse_options_subcommand(int argc, const char **argv, const struct option *options, |
4634 | - const char *const subcommands[], const char *usagestr[], int flags) |
4635 | +static int parse_options_subcommand_prefix(int argc, const char **argv, |
4636 | + const char *prefix, const struct option *options, |
4637 | + const char *const subcommands[], |
4638 | + const char *usagestr[], int flags) |
4639 | { |
4640 | struct parse_opt_ctx_t ctx; |
4641 | |
4642 | @@ -474,7 +492,7 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o |
4643 | strbuf_release(&buf); |
4644 | } |
4645 | |
4646 | - parse_options_start(&ctx, argc, argv, flags); |
4647 | + parse_options_start(&ctx, argc, argv, prefix, flags); |
4648 | switch (parse_options_step(&ctx, options, usagestr)) { |
4649 | case PARSE_OPT_HELP: |
4650 | exit(129); |
4651 | @@ -503,10 +521,26 @@ int parse_options_subcommand(int argc, const char **argv, const struct option *o |
4652 | return parse_options_end(&ctx); |
4653 | } |
4654 | |
4655 | +int parse_options_subcommand(int argc, const char **argv, |
4656 | + const struct option *options, const char *const subcommands[], |
4657 | + const char *usagestr[], int flags) |
4658 | +{ |
4659 | + return parse_options_subcommand_prefix(argc, argv, NULL, options, |
4660 | + subcommands, usagestr, flags); |
4661 | +} |
4662 | + |
4663 | +int parse_options_prefix(int argc, const char **argv, const char *prefix, |
4664 | + const struct option *options, |
4665 | + const char * const usagestr[], int flags) |
4666 | +{ |
4667 | + return parse_options_subcommand_prefix(argc, argv, prefix, options, |
4668 | + NULL, (const char **) usagestr, flags); |
4669 | +} |
4670 | + |
4671 | int parse_options(int argc, const char **argv, const struct option *options, |
4672 | const char * const usagestr[], int flags) |
4673 | { |
4674 | - return parse_options_subcommand(argc, argv, options, NULL, |
4675 | + return parse_options_subcommand_prefix(argc, argv, NULL, options, NULL, |
4676 | (const char **) usagestr, flags); |
4677 | } |
4678 | |
4679 | @@ -557,6 +591,7 @@ static void print_option_help(const struct option *opts, int full) |
4680 | if (opts->flags & PARSE_OPT_NOARG) |
4681 | break; |
4682 | /* FALLTHROUGH */ |
4683 | + case OPTION_FILENAME: |
4684 | case OPTION_STRING: |
4685 | if (opts->argh) { |
4686 | if (opts->flags & PARSE_OPT_OPTARG) |
4687 | diff --git a/util/parse-options.h b/util/parse-options.h |
4688 | index 6fd6b24..fc5015a 100644 |
4689 | --- a/util/parse-options.h |
4690 | +++ b/util/parse-options.h |
4691 | @@ -38,6 +38,7 @@ enum parse_opt_type { |
4692 | OPTION_CALLBACK, |
4693 | OPTION_U64, |
4694 | OPTION_UINTEGER, |
4695 | + OPTION_FILENAME, |
4696 | }; |
4697 | |
4698 | enum parse_opt_flags { |
4699 | @@ -135,6 +136,7 @@ struct option { |
4700 | #define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = check_vtype(v, long *), .help = (h) } |
4701 | #define OPT_U64(s, l, v, h) { .type = OPTION_U64, .short_name = (s), .long_name = (l), .value = check_vtype(v, u64 *), .help = (h) } |
4702 | #define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) } |
4703 | +#define OPT_FILENAME(s, l, v, a, h) { .type = OPTION_FILENAME, .short_name = (s), .long_name = (l), .value = check_vtype(v, const char **), (a), .help = (h) } |
4704 | #define OPT_DATE(s, l, v, h) \ |
4705 | { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb } |
4706 | #define OPT_CALLBACK(s, l, v, a, h, f) \ |
4707 | @@ -156,6 +158,10 @@ extern int parse_options(int argc, const char **argv, |
4708 | const struct option *options, |
4709 | const char * const usagestr[], int flags); |
4710 | |
4711 | +extern int parse_options_prefix(int argc, const char **argv, |
4712 | + const char *prefix, const struct option *options, |
4713 | + const char * const usagestr[], int flags); |
4714 | + |
4715 | extern int parse_options_subcommand(int argc, const char **argv, |
4716 | const struct option *options, |
4717 | const char *const subcommands[], |
4718 | @@ -185,6 +191,7 @@ struct parse_opt_ctx_t { |
4719 | int argc, cpidx; |
4720 | const char *opt; |
4721 | int flags; |
4722 | + const char *prefix; |
4723 | }; |
4724 | |
4725 | extern int parse_options_usage(const char * const *usagestr, |
4726 | @@ -192,8 +199,8 @@ extern int parse_options_usage(const char * const *usagestr, |
4727 | const char *optstr, |
4728 | bool short_opt); |
4729 | |
4730 | -extern void parse_options_start(struct parse_opt_ctx_t *ctx, |
4731 | - int argc, const char **argv, int flags); |
4732 | +extern void parse_options_start(struct parse_opt_ctx_t *ctx, int argc, |
4733 | + const char **argv, const char *prefix, int flags); |
4734 | |
4735 | extern int parse_options_step(struct parse_opt_ctx_t *ctx, |
4736 | const struct option *options, |
4737 | diff --git a/util/util.h b/util/util.h |
4738 | index 162aade..001707e 100644 |
4739 | --- a/util/util.h |
4740 | +++ b/util/util.h |
4741 | @@ -79,6 +79,11 @@ static inline const char *skip_prefix(const char *str, const char *prefix) |
4742 | return strncmp(str, prefix, len) ? NULL : str + len; |
4743 | } |
4744 | |
4745 | +static inline int is_absolute_path(const char *path) |
4746 | +{ |
4747 | + return path[0] == '/'; |
4748 | +} |
4749 | + |
4750 | void usage(const char *err) NORETURN; |
4751 | void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); |
4752 | int error(const char *err, ...) __attribute__((format (printf, 1, 2))); |
4753 | @@ -87,5 +92,7 @@ void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); |
4754 | char *xstrdup(const char *str); |
4755 | void *xrealloc(void *ptr, size_t size); |
4756 | int prefixcmp(const char *str, const char *prefix); |
4757 | +char *prefix_filename(const char *pfx, const char *arg); |
4758 | +void fix_filename(const char *prefix, const char **file); |
4759 | |
4760 | #endif /* __UTIL_H__ */ |
The changes I see LGTM, I can't test build it on my own as with being a native package in Ubuntu there is no tarball at all yet on the review.
In general we should think about that case on the sprint, I'll take a note.
I tried to fetch the one from your ppa but that fails to buildpackage for a hell lot of diff of git to the tarball. 3a97608ae1f7951 2ff ../ndctl_ 61.2.orig. tar.gz 4ef30740c67f44f 991291528f5 HEAD -> ndctl-update-61.2
I got:
4cc7c300703dc3
And Build against:
037e8f8b4c84fd
Isn't that the same you have?
I might be too late on the versioning discussion (and I actually agree to the version). Maintainer field"
But I saw "dpkg-source: warning: Version number suggests Ubuntu changes, but there is no XSBC-Original-
Do you think we should extend that test to not report on -0ubuntu ?
TL;DR: Changes LGTM, some confusion on package details