Subject: Re: bug#21018: Support for "libnvdimm BLK" devices

From: Dan Williams <[email-masked]>
Date: Mon, 3 Aug 2015 22:24:32 -0700

On Thu, Jul 9, 2015 at 2:52 PM, Brian C. Lane <[email-masked]> wrote:
> On Thu, Jul 09, 2015 at 10:00:10AM -0700, Dan Williams wrote:
>> BLK mode devices emitted by the libnvdimm sub-system [1] have a "." in
>> their name.  When parted calls _probe_sys_block() it trips over this
>> fact and unconditionally re-writes the block device name.
>>
>>                 /* in /sys/block, '/'s are replaced with '!' or '.' */
>>                 for (ptr = dev_name; *ptr != '\0'; ptr++) {
>>                         if (*ptr == '!' || *ptr == '.')
>>                                 *ptr = '/';
>>                 }
>>
>> This is confirmed by strace where parted emits calls to
>>
>> lstat("/dev/ndblk2", 0x7ffec6b33e50)    = -1 ENOENT (No such file or directory)
>> stat("/dev/ndblk2/0", 0x7ffec6b33dc0)   = -1 ENOENT (No such file or directory)
>>
>> The original BLK device name is /dev/ndblk2.0.
>>
>> This can be reproduced with a 4.2-rc1+ kernel and the nfit_test
>> module.  See the libndctl readme for instructions on getting the test
>> environment running [2].
>>
>> [1]: https://git.kernel.org/cgit/linux/kernel/git/djbw/nvdimm.git/tree/Documentation/nvdimm/nvdimm.txt?h=libnvdimm-for-next
>>
>> [2]: https://github.com/pmem/ndctl
>
> Thanks for the report. I think we can reduce this to just replacing '!',
> as far as I can tell cciss is the only device that has subdirectories
> and uses the ! in the name. Looking at the current kernel code it looks
> like the substitution is done in drivers/base/core.c ->
> device_get_devnode()
>
> I'm no kernel expert though. What does everyone think about dropping the
> '.'? Do you know of anything that this would break?
>
> In blivet (our storage library which handles all the devices we've ever
> seen) it only looks for ! so that's reassuring.
>

Any update on this?

With this one line change, parted can list libnvdimm "BLK" devices:

diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 27bbb8043e4f..2719ac327236 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -2237,7 +2237,7 @@ _probe_sys_block ()
                strcat (dev_name, dirent->d_name);
                /* in /sys/block, '/'s are replaced with '!' or '.' */
                for (ptr = dev_name; *ptr != '\0'; ptr++) {
-                       if (*ptr == '!' || *ptr == '.')
+                       if (*ptr == '!')
                                *ptr = '/';
                }
                _ped_device_probe (dev_name);