Zvol partition not available after send/receive

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Hello,

Our company is active in the video editing domain, we're making use of zvols that are shared through iSCSI using FreeNAS, one zvol being created for each project. Once the zvol is available through iSCSI, it is mounted on a workstation and formatted with a NTFS partition that is used for the video editing process.
Once a project is finished, the corresponding zvol is transferred to an archive server running ZoL on Debian (10). Since all transfers are made on our local network, we're using netcat to achieve faster transfer rates than with ssh, the effective transfer is done issuing commands on both the receiving (archive) system and the sending (FreeNAS server) system, starting on the receiving end to initiate the connection as follows :

On the receiving system (ZoL / Debian 10):
Code:
# nc -lp 44444 | \
mbuffer -q -s 128k -m 1G | \
pv -rtab | \
zfs receive -F ARCHIVEpool/JobID


On the sending system (FreeNAS server 11.2-U8)
Code:
# zfs set readonly=on FNASpool/JobID && \
zfs snapshot -r FNASpool/JobID@DATE && \
zfs send -R FNASpool/JobID@DATE | \
mbuffer -q -s 128k -m 1G | \
pv -rtab | \
nc -N xxx.xxx.xxx.xxx 44444


Once the zvol is available on the archive server, the original gets removed from the FreeNAS server.

One important thing to note is that, on the receiving server running ZoL, the NTFS partition becomes "visible", since the default vfs.zfs.vol.mode value is 1 (geom), whereas FreeNAS uses a default of 2 (dev). Thus, on the FreeNAS server, the zvol's corresponding /dev/ entry only displays the volume itself:
Code:
/dev/zvol/FNASpool/JobID

While the receiving system displays both the volume and it's partition:
Code:
/dev/zvol/ARCHIVEpool/jobID
/dev/zvol/ARCHIVEpool/jobID-part1


We rely on this feature that allows us to mount the partition on the archive system to now and then access old jobs and recover some material, simply using a command like:
Code:
mount -t ntfs-3g /dev/ARCHIVEpool/JobID-part1 /mnt/JobID-HD


THE PROBLEM:
Recently we started observing that, using the exact same process described here above, which we've been using for years, the partition doesn't appear on the archive server anymore!

Although the volume's data is transferred, as can be seen by listing the volume:
Code:
# zfs list ARCHIVEpool/JobID
NAME                                                USED  AVAIL  REFER  MOUNTPOINT
JobID                                                 180G  77.7T  180G    -


I wasn't able to find a way to access the NTFS partition, using gdisk to recreate a GPT partition on top of the existing data didn't help, issuing a message when attempting to mount, stating:
Code:
NTFS signature is missing.
Failed to mount '/dev/zd1280p1': Invalid argument
The device '/dev/zd1280p1' doesn't seem to have a valid NTFS.
Maybe the wrong device is used? Or the whole disk instead of a
partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?


In the end, the only way I found to finally access the partition's data, which DOES EXIST, was performing data recovery using testdisk on the gdisk re-created, still unmountable, partition.


I have absolutely no clue regarding what causes this new, very annoying, behavior i.e. not showing the partition and rendering it inaccessible in ZoL, although the data is well there as can be attested by the fact that testdisk is able to access it.
As a side note, we currently have volumes showing the "-part1" and others not showing it on the same archive pool, The only noticeable change that occurred since we observe the current situation was updating FreeNAS to 11.2-U8, although we cannot say for sure that the behavior changed right after the upgrade.

Any explanation, suggestion or pointing to a potential way to solve this situation would be greatly appreciated!

Thank you.
 

Samuel Tai

Never underestimate your own stupidity
Moderator
Joined
Apr 24, 2020
Messages
5,399
You could try loop mounting the zvol disk image via losetup -P, which should create a /dev/loopxp1 device you can then mount.
 

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Hello @Samuel Tai, thank you for taking the time to answer me.

Considering the situation where my zvolume is ARCHIVEpool/dataset/JobID, as follows:
Code:
# zfs list ARCHIVEpool/dataset
NAME                            USED  AVAIL  REFER  MOUNTPOINT
ARCHIVEpool/dataset/JobID       100G  77.7T   100G  -


Since we're dealing with a zvolume, it is logical that it has no mountpoint, but it has a corresponding entry under the /dev/zvol/ directory which is a symlink to a /dev/zdxxx block device:
Code:
# ls -la /dev/zvol/ARCHIVEpool/dataset/
lrwxrwxrwx  1 root root  18 Jun 15 14:02 JobID -> ../../../zd1424

# ls -la /dev/ | grep zd1424
brw-rw----  1 root disk    230, 1424 Jun 15 14:02 zd1424


Following your suggestion I couldn't think of anything else but pointing the losetup command at one of those entries:
Code:
# losetup -P /dev/zvol/ARCHIVEpool/dataset/JobID
losetup: /dev/zvol/ARCHIVEpool/dataset/JobID: failed to use device: No such device

# losetup -P /dev/zd1424
losetup: /dev/zd1424: failed to use device: No such device


Though, adding the -f option allowed the creation of the loop device, and subsequent attempt to mount it (specifying the NTFS partition type):
Code:
# losetup -fP /dev/zvol/ARCHIVEpool/dataset/JobID
# losetup -a
/dev/loop0: [0006]:103465443 (/dev/zd1424)

# mkdir /mnt/zd1424
# mount -o loop /dev/loop0 /mnt/zd1424
mount: /mnt/zd1424: wrong fs type, bad option, bad superblock on /dev/loop1, missing codepage or helper program, or other error.
# mount -o loop -t ntfs-3g /dev/loop0 /mnt/zd1424
NTFS signature is missing.                                         
Failed to mount '/dev/loop1': Invalid argument                     
The device '/dev/loop1' doesn't seem to have a valid NTFS.         
Maybe the wrong device is used? Or the whole disk instead of a     
partition (e.g. /dev/sda, not /dev/sda1)? Or the other way around?


Which kinda brings us back to square one unfortunately :(

Anyway, thank you for the suggestion, any other ones being welcome since I'm still stuck at the moment.

Sincerely.
 

Samuel Tai

Never underestimate your own stupidity
Moderator
Joined
Apr 24, 2020
Messages
5,399
After the loop device creation, did you check if there was a /dev/loop0p1 device? The -P option scans the file for partitions, and creates separate devices for each partition.
 

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Yes I did:
Code:
# ls -la /dev/ | grep loop
brw-rw----  1 root disk      7,    0 Jun 15 14:46 loop0       
brw-rw----  1 root disk      7,    1 Jun 15 14:40 loop1       
brw-rw----  1 root disk      7,    2 Jun 15 14:35 loop2       
brw-rw----  1 root disk      7,    3 Jun 15 14:35 loop3       
brw-rw----  1 root disk      7,    4 Jun 15 14:35 loop4       
brw-rw----  1 root disk      7,    5 Jun 15 14:35 loop5       
brw-rw----  1 root disk      7,    6 Jun 15 14:35 loop6       
brw-rw----  1 root disk      7,    7 Jun 15 14:35 loop7       
crw-rw----  1 root disk     10,  237 Jun 15 14:35 loop-control

# losetup -fP /dev/zvol/ARCHIVEpool/dataset/JobID
# losetup -a
/dev/loop0: [0006]:103465443 (/dev/zd1424)                    
# ls -la /dev/ | grep loop                  
brw-rw----  1 root disk      7,    0 Jun 15 15:16 loop0       
brw-rw----  1 root disk      7,    1 Jun 15 14:40 loop1       
brw-rw----  1 root disk      7,    2 Jun 15 14:35 loop2       
brw-rw----  1 root disk      7,    3 Jun 15 14:35 loop3       
brw-rw----  1 root disk      7,    4 Jun 15 14:35 loop4       
brw-rw----  1 root disk      7,    5 Jun 15 14:35 loop5       
brw-rw----  1 root disk      7,    6 Jun 15 14:35 loop6       
brw-rw----  1 root disk      7,    7 Jun 15 14:35 loop7       
crw-rw----  1 root disk     10,  237 Jun 15 14:35 loop-control


No sign of /dev/loop0p1, or am I missing something ?
 

Samuel Tai

Never underestimate your own stupidity
Moderator
Joined
Apr 24, 2020
Messages
5,399
 

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Well that is exactly where the problem lies, when the zfs send/receive command does NOT result in the creation of a ARCHIVEpool/dataset/JobID-part1 volume, the archive system doesn't seem to know about the existing partition, even though, as described in the OP, the data is present and accessible through testdisk.

Here is a comparison of two zvolumes that were transferred from the main server to the archive system, one showing the "-part1" volume, the other not (I used gdisk which outputs more or less the same information as fdsik):

When "-part1" is present after the zfs send/receive operation:
Code:
# zfs list -r ARCHIVEpool/datasetA
NAME                            USED  AVAIL  REFER  MOUNTPOINT
ARCHIVEpool/datasetA/JobID01       180G  77.7T   180G  -

# ls -la /dev/zvol/ARCHIVEpool/datasetA/
total 0
drwxr-xr-x  2 root root  80 Jun 15 14:02 .
drwxr-xr-x 41 root root 820 Jun 15 14:02 ..
lrwxrwxrwx  1 root root  18 Jun 15 14:02 JobID01 -> ../../../zd1344
lrwxrwxrwx  1 root root  20 Jun 15 14:02 JobID01-part1 -> ../../../zd1344p1

# gdisk /dev/zvol/ARCHIVEpool/datasetA/JobID01
GPT fdisk (gdisk) version 1.0.3

The protective MBR's 0xEE partition is oversized! Auto-repairing.

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): p
Disk /dev/zvol/ARCHIVEpool/datasetA/JobID01: 419430400 sectors, 200.0 GiB
Sector size (logical/physical): 512/8192 bytes
Disk identifier (GUID): 2B73E3D9-34B7-462D-880A-50EFC7F4EA1E
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 419430366
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048       419428351   200.0 GiB   0700  Basic data partition

Command (? for help): q

In this situation, the standard mount -t ntfs-3g /dev/zvol/ARCHIVEpool/datasteA/JobID01-part1 /mnt/JobID01 command executes without a problem.

When "-part1" is missing after the zfs send/receive operation:
Code:
# zfs list -r ARCHIVEpool/datasetB
NAME                            USED  AVAIL  REFER  MOUNTPOINT
ARCHIVEpool/datasetB/JobID02       115G  77.7T   115G  -

# ls -la /dev/zvol/ARCHIVEpool/datasetB/
total 0
drwxr-xr-x  2 root root  80 Jun 15 14:02 .
drwxr-xr-x 41 root root 820 Jun 15 14:02 ..
lrwxrwxrwx  1 root root  18 Jun 15 14:02 JobID02 -> ../../../zd1424

# gdisk /dev/zvol/ARCHIVEpool/datasetB/JobID02
GPT fdisk (gdisk) version 1.0.3

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: not present

Creating new GPT entries.

Command (? for help): p
Disk /dev/zvol/ARCHIVEpool/datasetB/JobID02: 419430400 sectors, 200.0 GiB
Sector size (logical/physical): 512/131072 bytes
Disk identifier (GUID): B385F6E6-B7A3-4A0D-B285-ADDE5E6EB07B
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 419430366
Partitions will be aligned on 2048-sector boundaries
Total free space is 419430333 sectors (200.0 GiB)

Number  Start (sector)    End (sector)  Size       Code  Name

Command (? for help): q

This is when it becomes impossible to access the data using the "simple" mount command, forcing to use testdisk to reach the content.

I have absolutely no idea why some of the zvolumes are transferred along with their "-part1" while others don't. I need to delve a little further into what might differentiate one from the other.
Could the NTFS formatting "Allocation Unit Size" play a role here?

Thanks again for taking the time looking at my situation!
 

Samuel Tai

Never underestimate your own stupidity
Moderator
Joined
Apr 24, 2020
Messages
5,399
I looked through your previous posts more carefully, and it seems when the partition isn't broken out is when the "physical" sector size is 128k. I don't know if this is coming from mbuffer or not.
 

Thibaut

Dabbler
Joined
Jun 21, 2014
Messages
33
Thanks @Samuel Tai, you spotted something interesting!

There is this difference in the physical sector size, some zvolumes were created using the volblocksize=128k options while others simply omitted this option and are thus using the default 8K value:
Code:
# zfs get volblocksize ARCHIVEpool/datasetA/JobID01
NAME                          PROPERTY      VALUE     SOURCE
ARCHIVEpool/datasetA/JobID01  volblocksize  8K        default

# zfs get volblocksize ARCHIVEpool/datasetB/JobID02
NAME                          PROPERTY      VALUE     SOURCE
ARCHIVEpool/datasetB/JobID02  volblocksize  128K      -    


But it is when the volblocksize is set to 128K that the partition does not get transferred correctly...
At the moment I cannot figure out why this happens but it is definitely the first direction in which to dig. Thank you for pointing this out!

And of course, in case someone has an explanation/solution it will be more than welcome ;)
Thanks again.
 
Top