/*! Gets an iterator for traversing iSCSI LUNs for a specified target in the * I/O registry. * @param targetIQN the name of the target. * @param iterator the iterator used to traverse LUNs for the specified target. * @return a kernel error code indicating the result of the operation. */ kern_return_t iSCSIIORegistryGetLUNs(CFStringRef targetIQN,io_iterator_t * iterator) { if(!iterator) return kIOReturnBadArgument; io_object_t parallelDevice = iSCSIIORegistryGetTargetEntry(targetIQN); if(parallelDevice == IO_OBJECT_NULL) return kIOReturnNotFound; // The children of the IOSCSIParallelInterfaceDevice are IOSCSITargetDevices io_object_t target; IORegistryEntryGetChildEntry(parallelDevice,kIOServicePlane,&target); if(target == IO_OBJECT_NULL) { IOObjectRelease(parallelDevice); return kIOReturnNotFound; } // The children of the target (IOSCSITargetDevice) are the LUNs kern_return_t result = IORegistryEntryGetChildIterator(target,kIOServicePlane,iterator); IOObjectRelease(parallelDevice); IOObjectRelease(target); return result; }
int AoEProperties::number_of_targets(void) { io_registry_entry_t ControllerInterface = NULL; io_iterator_t Controllers = NULL; io_registry_entry_t Controller = NULL; int nCount = 0; if ( 0==m_OurObject ) return 0; IORegistryEntryGetChildEntry(m_OurObject, kIOServicePlane, &ControllerInterface); IORegistryEntryGetChildIterator(ControllerInterface, kIOServicePlane, &Controllers); while ( (Controller = IOIteratorNext(Controllers)) ) { IOObjectRelease(Controller); ++nCount; } if ( Controllers ) IOObjectRelease(Controllers); if ( ControllerInterface ) IOObjectRelease(ControllerInterface); return nCount; }
/*! Gets an iterator for traversing iSCSI targets in the I/O registry. * As targets are iterated, this function may also return an IOObject that * corresponds to the user client, if one is active. Users can check for * this by using standard IOSerivce functions. * @param iterator the iterator. * @return a kernel error code indicating the result of the operation. */ kern_return_t iSCSIIORegistryGetTargets(io_iterator_t * iterator) { if(!iterator) return kIOReturnBadArgument; io_object_t service = iSCSIIORegistryGetiSCSIHBAEntry(); if(service == IO_OBJECT_NULL) return kIOReturnNotFound; // The children of the iSCSI HBA are the targets (IOSCSIParallelInterfaceDevice) IORegistryEntryGetChildIterator(service,kIOServicePlane,iterator); return kIOReturnSuccess; }
int AoEProperties::get_property(CFTypeRef* pType, CFStringRef Property, int nNumber) { io_registry_entry_t ControllerInterface; io_iterator_t Controllers; io_registry_entry_t Controller; int nCount; int nShelf; ControllerInterface = NULL; Controllers = NULL; Controller = NULL; nCount = 0; nShelf = 0; *pType = NULL; if ( 0==m_OurObject ) return 0; IORegistryEntryGetChildEntry(m_OurObject, kIOServicePlane, &ControllerInterface); IORegistryEntryGetChildIterator(ControllerInterface, kIOServicePlane, &Controllers); while ( (Controller = IOIteratorNext(Controllers)) ) { if ( nNumber==nCount ) { *pType = IORegistryEntryCreateCFProperty(Controller,Property,kCFAllocatorDefault,0); if ( *pType ) CFRetain(*pType); IOObjectRelease(Controller); break; } IOObjectRelease(Controller); ++nCount; } if ( Controllers ) IOObjectRelease(Controllers); if ( ControllerInterface ) IOObjectRelease(ControllerInterface); return (*pType && (nCount==nNumber)) ? 0 : -1; }
void genIOKitDeviceChildren(const io_registry_entry_t& service, const io_name_t plane, int depth, QueryData& results) { io_iterator_t it; auto kr = IORegistryEntryGetChildIterator(service, plane, &it); if (kr != KERN_SUCCESS) { return; } io_service_t device; while ((device = IOIteratorNext(it))) { // Use this entry as the parent, and generate a result row. genIOKitDevice(device, service, plane, depth, results); genIOKitDeviceChildren(device, plane, depth + 1, results); IOObjectRelease(device); } IOObjectRelease(it); }
/*! Applies a callback function all IOMedia objects of a particular target. * @param target search children of this node for IOMedia objects. * @param callback the callback function to call on each IOMedia object. * @param context a user-defined parameter to pass to the callback function. */ void iSCSIIORegistryIOMediaApplyFunction(io_object_t target, iSCSIIOMediaCallback callback, void * context) { io_object_t entry = IO_OBJECT_NULL; io_iterator_t iterator = IO_OBJECT_NULL; IORegistryEntryGetChildIterator(target,kIOServicePlane,&iterator); // Iterate over all children of the target object while((entry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) { // Recursively call this function for each child of the target iSCSIIORegistryIOMediaApplyFunction(entry,callback,context); // Find the IOMedia's root provider class (IOBlockStorageDriver) and // get the first child. This ensures that we grab the IOMedia object // for the disk itself and not each individual partition CFStringRef providerClass = IORegistryEntryCreateCFProperty(entry,CFSTR(kIOClassKey),kCFAllocatorDefault,0); if(providerClass && CFStringCompare(providerClass,CFSTR(kIOBlockStorageDriverClass),0) == kCFCompareEqualTo) { // Apply callback function to the child (the child is the the // IOMedia object that pertains to the whole disk) io_object_t child; IORegistryEntryGetChildEntry(entry,kIOServicePlane,&child); callback(child,context); IOObjectRelease(child); } if(providerClass) CFRelease(providerClass); IOObjectRelease(entry); } IOObjectRelease(iterator); }
/*! Finds the target object (IOSCSIParallelInterfaceDevice) in the IO registry that * corresponds to the specified target. * @param targetIQN the name of the target. * @return the IO registry object of the IOSCSITargetDevice for this session. */ io_object_t iSCSIIORegistryGetTargetEntry(CFStringRef targetIQN) { if(!targetIQN) return IO_OBJECT_NULL; io_service_t service; if(!(service = iSCSIIORegistryGetiSCSIHBAEntry())) return IO_OBJECT_NULL; // Iterate over the targets and find the specified target by name io_iterator_t iterator = IO_OBJECT_NULL; IORegistryEntryGetChildIterator(service,kIOServicePlane,&iterator); io_object_t entry; while((entry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) { CFDictionaryRef protocolDict = IORegistryEntryCreateCFProperty( entry,CFSTR(kIOPropertyProtocolCharacteristicsKey),kCFAllocatorDefault,0); if(protocolDict) { CFStringRef IQN = CFDictionaryGetValue(protocolDict,CFSTR(kIOPropertyiSCSIQualifiedNameKey)); if(CFStringCompare(IQN,targetIQN,0) == kCFCompareEqualTo) { CFRelease(protocolDict); IOObjectRelease(iterator); return entry; } CFRelease(protocolDict); } IOObjectRelease(entry); } IOObjectRelease(iterator); return IO_OBJECT_NULL; }
void traverse(unsigned int options, io_name_t plane, io_iterator_t services, io_registry_entry_t serviceUpNext, int depth, UInt64 stackOfBits) { io_registry_entry_t service; ///ok Boolean doProps; // We loop for every service in the list of services provided. while ( (service = serviceUpNext) ) { io_iterator_t children; Boolean hasChildren; io_name_t name; kern_return_t status; io_registry_entry_t child; int busy; // Obtain the next service entry, if any. serviceUpNext = IOIteratorNext(services); // Obtain the current service entry's children, if any. status = IORegistryEntryGetChildIterator(service, plane, &children); assert(status == KERN_SUCCESS); child = IOIteratorNext(children); ///ok hasChildren = child ? true : false; // Save has-more-siblings state into stackOfBits for this depth. if (serviceUpNext) stackOfBits |= (1 << depth); else stackOfBits &= ~(1 << depth); // Save has-children state into stackOfBits for this depth. if (hasChildren) stackOfBits |= (2 << depth); else stackOfBits &= ~(2 << depth); indent(true, depth, stackOfBits); // Print out the name of the service. status = IORegistryEntryGetName(service, name); assert(status == KERN_SUCCESS); printf("%s", name); if (strcmp("Root", name)) doProps = (options & kDoPropsOption) != 0; else doProps = (options & kDoRootOption) != 0; // Print out the class of the service. status = IOObjectGetClass(service, name); assert(status == KERN_SUCCESS); printf(" <class %s", name); status = IOServiceGetBusyState(service, &busy); if(status == KERN_SUCCESS) printf(", busy %d", busy); // Print out the retain count of the service. printf(", retain count %d>\n", IOObjectGetRetainCount(service)); // Print out the properties of the service. if (doProps) properties(service, depth, stackOfBits); // Recurse down. traverse(options, plane, children, child, depth + 1, stackOfBits); // Release resources. IOObjectRelease(children); children = 0; IOObjectRelease(service); service = 0; } }
CFStringRef AoEProperties::get_targets_bsd_name(int nTargetNumber) { io_registry_entry_t ControllerInterface; io_iterator_t Controllers; io_registry_entry_t Controller; io_registry_entry_t Device; io_registry_entry_t DiskDriver; io_registry_entry_t StorageDevice; io_registry_entry_t StorageDriver; io_registry_entry_t Disk; CFStringRef Name; CFNumberRef Target; int nTargetNum; DiskDriver = NULL; StorageDevice = NULL; StorageDriver = NULL; Device = NULL; Disk = NULL; ControllerInterface = NULL; Controllers = NULL; Controller = NULL; Name = NULL; if ( 0==m_OurObject ) return 0; IORegistryEntryGetChildEntry(m_OurObject, kIOServicePlane, &ControllerInterface); IORegistryEntryGetChildIterator(ControllerInterface, kIOServicePlane, &Controllers); // First, find the Controller... while ( (Controller = IOIteratorNext(Controllers)) ) { Target = (CFNumberRef) IORegistryEntryCreateCFProperty(Controller, CFSTR(TARGET_PROPERTY), kCFAllocatorDefault, 0); CFNumberGetValue(Target, kCFNumberIntType, &nTargetNum); CFRelease(Target); if ( nTargetNumber==nTargetNum ) { // Now we have the controller, descend through children IORegistryEntryGetChildEntry(Controller, kIOServicePlane, &Device); IORegistryEntryGetChildEntry(Device, kIOServicePlane, &DiskDriver); IORegistryEntryGetChildEntry(DiskDriver, kIOServicePlane, &StorageDevice); IORegistryEntryGetChildEntry(StorageDevice, kIOServicePlane, &StorageDriver); IORegistryEntryGetChildEntry(StorageDriver, kIOServicePlane, &Disk); if ( Disk ) { Name = (CFStringRef) IORegistryEntryCreateCFProperty(Disk, CFSTR("BSD Name"), kCFAllocatorDefault, 0); if ( Name ) CFRetain(Name); } break; } IOObjectRelease(Controller); } if ( Controllers ) IOObjectRelease(Controllers); if ( DiskDriver ) IOObjectRelease(DiskDriver); if ( StorageDevice ) IOObjectRelease(StorageDevice); if ( StorageDriver ) IOObjectRelease(StorageDriver); if ( Disk ) IOObjectRelease(Disk); if ( Device ) IOObjectRelease(Device); if ( ControllerInterface ) IOObjectRelease(ControllerInterface); return (Name && (nTargetNum==nTargetNumber)) ? Name : NULL; }