openzfsonosx / zfs

OpenZFS on OS X
https://openzfsonosx.org/
Other
823 stars 72 forks source link

ZVOLs do not show in diskutil or Disk Utility arbitration #29

Closed lundman closed 5 years ago

lundman commented 11 years ago

Currently if you create ZVOLs, the kernel/BSD/Unix side of things work great, but the Apple OS X sections does not recognise (or possible is not told about) the volume.

# ./zpool.sh create -f BOOM ~/pool-image.bin 
# ./cmd.sh zfs create -V 50M -o volblocksize=4096 BOOM/vol
# ls -l /dev/*disk*
brw-r-----  1 root      operator    1,   3 Apr  9 01:48 disk0s2
brw-r-----  1 root      operator    1,   2 Apr  9 01:48 disk0s1
brw-r-----  1 root      operator    1,   0 Apr  9 01:48 disk0
crw-r-----  1 root      operator    1,   0 Apr  9 01:48 rdisk0
crw-------  1 root      operator    33,   1 May 27 08:53 rdisk_BOOM_vol
brw-------  1 root      operator    3,   1 May 27 08:53 disk_BOOM_vol
# newfs_msdos  /dev/rdisk_BOOM_vol
/dev/rdisk_BOOM_vol: 12781 sectors in 12781 FAT16 clusters (4096 bytes/cluster)
bps=4096 spc=1 res=1 nft=2 rde=512 sec=12800 mid=0xf0 spf=7 spt=32 hds=16 hid=0 drv=0x00
# mkdir /Volumes/pc
# mount_msdos /dev/disk_BOOM_vol /Volumes/pc
# df -h
/dev/disk_BOOM_vol   102248    560  101688     1%     512   0  100%   /Volumes/pc
# mkdir /Volumes/pc/HELLO
# ls -l /Volumes/pc
drwxrwxrwx  1 _unknown  _unknown  4096 May 27 08:53 HELLO
# diskutil list
/dev/disk0
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *21.5 GB    disk0
   1:                        EFI                         209.7 MB   disk0s1
   2:                  Apple_HFS Dev                     21.1 GB    disk0s2
# diskutil list /dev/rdisk_BOOM_vol
Could not find whole disk for disk: /dev/rdisk_BOOM_vol

Naturally, I have attempted to name the device nodes 'disk3' and 'rdisk3' (the next one along) and it does not make any difference. Possibly we need to contact IOkit about the new device/disk.

I hope that the major numbers of the c and b devices differing to not be relevant.

I can successfully newfs to msdos, udf and hfs. Although hfs fails to mount. I can also use gpt to write a partition table, although we do not create diskXsY nodes as of yet.

lundman commented 11 years ago

It looks like the answer is to use IOkit, and IOService. Setup a handler for the various callbacks, call attach() and so on. This needs C++ in the kernel, even if only a wrapper, so it will take a bit more tinkering to get setup. Deferring this for another day.

lundman commented 11 years ago
 # ./cmd.sh zfs create -V 1G BOOM/vol

screen shot 2013-06-26 at 12 48 02 screen shot 2013-06-26 at 12 48 20

Fails to automount due to

 diskmanagementd[212]: mount blocked by dissenter PID=0 (unknown)   status=0xf8da000c 
     log=kDAReturnUnsupported message=(null)

# mount -t hfs /dev/disk2s1 /Volumes/testing
/dev/disk2s1   1.0Gi   32Mi  992Mi     4%    8198    253942    3%       /Volumes/testing

screen shot 2013-06-26 at 12 54 14

lundman commented 11 years ago

https://github.com/zfs-osx/zfs/commit/a0873afa0ff8bd0529c778ff1bf1ff3c16060dd5

I will leave this ticket open a bit longer, I think the C++ code I added is wrong, and hopefully someone with more C++ knowledge can check over it. I suspect that keeping a class reference in the C structure is prone to 'luck'.

BjoKaSH commented 11 years ago

In principle one can pass around C++ class pointers in plain C structures. But passing references in a C structure shouldn't even compile, IIRC.

lundman commented 11 years ago

The commit https://github.com/zfs-osx/zfs/commit/5969c8d33326893a8d38979c0bb2373181222123 fixes a few things wrong with the ZVOL code. It assumed it would get a single block request each time, but when IOKit asks for multiple, we read/wrote each one to the start of the memory pointer only. We only handled the first block request.

This fixes the problem with using the GUI. You can now partition the volume as GUID, put HFS+ on it, and it is automatically mounted. Even on import.

We may need to think about some way to disable the automatic mounts on import at some point.

screen shot 2013-07-09 at 15 02 48

lundman commented 11 years ago

Turns out the commandline partitioning tools gpt have an upper block size limit of 4096, so we have made the default blocksize for ZFS-Volumes on OSX be 4096. You can set it higher, and work around that limit just fine. But it is nice that the default can be formatted in Disk Utility and automatically mounted.

The ZFS Volume code is complete in terms of Usage.

I will leave this open a little longer, since I suspect there is a better way to do the C++ and C interaction.

We currently need to do a little more work on the ZFS Volume device-node-names. Ie, OSX will create /dev/diskX and we will create /var/run/zfs/zvol/dsk/POOL/dataset -> /dev/diskX. For those using ZFS Volumes with the GUI, this is not needed. For those using the volumes from Unix side, the exact names are required.

Beyond that, ZEVO appears to create a Linux equivalence of /dev/disk/by-id in its /var/zfs/dsk/GPTE_4F7D6484-3DB9-441A-BC9F-DDB29B76A76C -> /dev/disk4s1. This is most likely so that you can create pools using the disk-name, instead of /dev/diskX - which is not fixed.

We may need to consider if we want to do something like this as well.

JMoVS commented 5 years ago

this has been fixed and works as of issue116_lite being merged.