I'm currently use IOUserBlockStorageDevice to simulate a ram disk. To simulate a pluggable ramdisk that can commute, I would like to use a hierarcy architecture.
However, something strange happened while I'm using hierarcy architecture.
The hierarcy architecture might shows as following in ioreg
...
+-o IOUserResources <class IOUserResources, id 0x10000011b, registered, matched, active, busy 0 (571 ms), retain 9>
| +-o IOUserDockChannelSerial <class IOUserService, id 0x10000040c, registered, matched, active, busy 0 (0 ms), retain 8>
| +-o MyService <class IOUserService, id 0x10000040d, registered, matched, active, busy 0 (2 ms), retain 9>
| +-o MyUserClient <class IOUserUserClient, id 0x100000760, registered, matched, active, busy 0 (2 ms), retain 9>
| +-o MyDevice <class IOUserBlockStorageDevice, id 0x100000762, registered, matched, active, busy 0 (2 ms), retain 8>
| +-o IOBlockStorageDriver <class IOBlockStorageDriver, id 0x100000763, registered, matched, active, busy 0 (1 ms), retain 8>
| +-o Testing Media <class IOMedia, id 0x100000764, registered, matched, active, busy 0 (1 ms), retain 9>
| +-o IOMediaBSDClient <class IOMediaBSDClient, id 0x100000765, registered, matched, active, busy 0 (0 ms), retain 6>
+-o IOUserServer(com.apple.IOUserDockChannelSerial-0x10000040c) <class IOUserServer, id 0x100000472, registered, matched, active, busy 0 (0 ms), retain 11>
+-o IOUserServer(com.example.apple-samplecode.dext-to-user-client.driver-0x10000040d) <class IOUserServer, id 0x100000474, registered, matched, active, busy 0 (0 ms), retain 13>
MyService is the loaded dext, which create an UserClient while a client connect.
MyUserClient has two interface: adddevice / remove which will add or remove a MyDevice instance.
MyDevice is the IOUserBlockStorageDevice create by MyuserClient.
I'm using the following plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>IOKitPersonalities</key>
<dict>
<key>testDevice</key>
<dict>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.kpi.iokit</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOMatchCategory</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOProviderClass</key>
<string>IOUserResources</string>
<key>IOResourceMatch</key>
<string>IOKit</string>
<key>IOUserClass</key>
<string>MyService</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>UserClientProperties</key>
<dict>
<key>MyDeviceProperties</key>
<dict>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.iokit.IOStorageFamily</string>
<key>IOClass</key>
<string>IOUserBlockStorageDevice</string>
<key>IOUserClass</key>
<string>MyDevice</string>
</dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>MyUserClient</string>
</dict>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string></string>
</dict>
</plist>
and MyDevice is create by "auto kr = Create(this, "MyDeviceProperties", &client);" in MyUserClient.
To make sure the flow of MyDevice, I add an simple log (inside *** function) while entering each function implement.
Following is the system log after adddevice:
=== ExternalMethod AddDevice ===
2022-10-21 12:08:20.424783+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ccc Inside ExternalMethod!!!!!
2022-10-21 12:08:20.424803+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient ExternalMethodType_AddDevice
2022-10-21 12:08:20.424812+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice
2022-10-21 12:08:20.424847+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO virtual bool IOUserBlockStorageDevice::init(OSDictionary *): Allocate resources
2022-10-21 12:08:20.425059+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init.....
2022-10-21 12:08:20.425145+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice init done
2022-10-21 12:08:20.425152+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start
2022-10-21 12:08:20.425158+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) IOUserBlockStorageDevice::Start()
2022-10-21 12:08:20.425201+0800 0xcd3cd Default 0x0 0 0 kernel: (IOStorageFamily) INFO kern_return_t IOUserBlockStorageDevice::RegisterDext_Impl(): Registering dext
2022-10-21 12:08:20.425212+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Reg service
2022-10-21 12:08:20.425270+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice Start() - Finished.
2022-10-21 12:08:20.425281+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyUserClient NewDevice done
2022-10-21 12:08:20.425598+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportRemovability
2022-10-21 12:08:20.425852+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside ReportWriteProtection
2022-10-21 12:08:20.425916+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetVendorString
2022-10-21 12:08:20.426022+0800 0xcd3cd Default 0x0 0 0 kernel: (dext) AAABBB MyDevice inside GetProductString
<log end, device stuch here>
The IOUserBlockStorageDevice stuck after calling GetProductString, not called GetDeviceParam, and the device size remains be zero in this case. I'm not sure why MyDevice stuck.
Could anyone help for this case? I'll post some detailed test in reply.