openzfsonwindows / ZFSin

OpenZFS on Windows port
https://openzfsonwindows.org
1.2k stars 68 forks source link

EFI Partitions and Virtual Volumes #15

Open lundman opened 6 years ago

lundman commented 6 years ago

To handle EFI partitions, a possible good solution would be to take the sources for disk.sys kindly opensourced by Microsoft.

Rename it efidisk.sys or similar, and remove the regular partition support (So that MS is still controlling that part). Then link with libefi, and create the Volumes as needed but for EFI partitions instead.

We could even add code to SET_PARTITION_INFORMATION as well, and properly handle creating of pools on Windows to be the same partition layout as upstream.

In addition to this, if the functions for creating volumes (and removing) can be called directly, the ZFS current sources can call them for the MOUNT, and ZVOL creation. Since now, that Volume code is not quite right, and hopefully disk.sys's Volume code will be perfection.

Should be about a week's worth of work.

lundman commented 6 years ago

5

jheuking commented 6 years ago

I think, I am currently dealing with the same problem, but I don't get where this occurs exactly. And I don't really understand why we have to deal with EFI-Partitions at all? Shouldn't it be sufficient to just ignore them? Or do you expect to find a ZFS filesystem there? :smile:

I experimented a bit around this problem and got some strange behavior ..

Installed FreeBSD with GPT (UEFI), which has a leading EFI-Partition with FAT filesystem. This leads to the problem that datasets are not mountable anymore. The mount process seems to succeed with error 0, which turns out to be a lie, as neither the device is appearing in the explorer nor does the dataset get listed with zfs mount. Plus the pool hangs in active state, which makes it unexportable (error EBUSY).

it works when I... ... write zeros to the efi-partition ... change the filesystem to something else, e.g. NTFS (the problem still occurs with FAT32 instead of FAT) ...or delete the partition completely

it seems to be irrelevant... ...which attributes I set on the partition (tested HIDDEN and NOAUTOMOUNT) ...which partition label is set

As the mount process seems to fail, if there is a leading FAT-formatted partition on the disk, I assume that there is something done, which fails but is neither recognized nor processed. So we return 0 on mount and recognize the error in the later course...but I don't know where this happens..? Maybe you can enlighten me ...

edit: seems that I got to the same point, where IRP_MN_MOUNT_VOLUME is not received, as you described in #5

Another strange thing: Even if I only plug in a FAT32 USB-Stick in addition to my zfs drive, I am not able to mount...

edit: ah, mounting alongside with FAT filesystems seems to be solved in 34da2961c3f326c777cb67983285aa445fb4216e :)

lundman commented 5 years ago

Having worked with Storport example WDKStorPortVirtualMiniport, it turns out to be quite easy to work with. We can make an efidisk.sys driver using it, which;

When you make up a new TargetId+LUN, or remove one, you issue StorPortNotification(BusChangeDetected to announce it.

The Storport example itself builds a DeviceList that should be ignored and deleted - it is just for the sample disks. In the function ScsiOpInquiry() use the TargetId and Lun to lookup the disk we are emulating, and reply with success if we have a match.

Likewise in ScsiOpReadCapacity() - match TargetId and Lun, and reply with disksize.

In WkRtn() define the read and write calls to get data from real device, with partition offset added on.

Anything to do with pDiskBuf should be cut, that's the memory allocated for the sample's virtual disk.

As a bonus, we could implement the various IRPs for PARTITION tables, so you could create new EFI partitions using the standard Windows API, but not required for ZFS.

jheuking commented 5 years ago

when we get correct handles for partitions to directly read the partitions size, we need to partially revert this one 482eb610c93375dcc8042288cad04c295cb45e11 zpool_read_label_win shouldn't need the len parameter anymore then