2 * Copyright (c) 1998-2011 Apple Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 #include <IOKit/IOBSD.h>
29 #include <IOKit/IOLib.h>
30 #include <IOKit/IOService.h>
31 #include <IOKit/IOCatalogue.h>
32 #include <IOKit/IODeviceTreeSupport.h>
33 #include <IOKit/IOKitKeys.h>
34 #include <IOKit/IOPlatformExpert.h>
35 #include <IOKit/IOUserClient.h>
39 #include <pexpert/pexpert.h>
40 #include <kern/clock.h>
41 #include <uuid/uuid.h>
42 #include <sys/vnode_internal.h>
43 #include <sys/mount.h>
45 // how long to wait for matching root device, secs
47 #define ROOTDEVICETIMEOUT 120
49 #define ROOTDEVICETIMEOUT 60
52 int panic_on_exception_triage
= 0;
54 extern dev_t
mdevadd(int devid
, uint64_t base
, unsigned int size
, int phys
);
55 extern dev_t
mdevlookup(int devid
);
56 extern void mdevremoveall(void);
57 extern int mdevgetrange(int devid
, uint64_t *base
, uint64_t *size
);
58 extern void di_root_ramfile(IORegistryEntry
* entry
);
62 #define IOPOLLED_COREFILE (CONFIG_KDP_INTERACTIVE_DEBUGGING)
63 #define kIOCoreDumpPath "/private/var/vm/kernelcore"
64 #define kIOCoreDumpSize 350ULL*1024ULL*1024ULL
65 // leave free space on volume:
66 #define kIOCoreDumpFreeSize 350ULL*1024ULL*1024ULL
68 #define IOPOLLED_COREFILE 1
70 #define kIOCoreDumpSize 0ULL
71 #define kIOCoreDumpFreeSize 0ULL
73 #define IOPOLLED_COREFILE 0
79 NewKernelCoreMedia(void * target
, void * refCon
,
80 IOService
* newService
,
81 IONotifier
* notifier
);
82 #endif /* IOPOLLED_COREFILE */
84 #if CONFIG_KDP_INTERACTIVE_DEBUGGING
86 * Touched by IOFindBSDRoot() if a RAMDisk is used for the root device.
88 extern uint64_t kdp_core_ramdisk_addr
;
89 extern uint64_t kdp_core_ramdisk_size
;
95 IOService::publishResource("IOBSD");
97 return( kIOReturnSuccess
);
101 IOServicePublishResource( const char * property
, boolean_t value
)
104 IOService::publishResource( property
, kOSBooleanTrue
);
106 IOService::getResourceService()->removeProperty( property
);
110 IOServiceWaitForMatchingResource( const char * property
, uint64_t timeout
)
112 OSDictionary
* dict
= 0;
113 IOService
* match
= 0;
114 boolean_t found
= false;
118 dict
= IOService::resourceMatching( property
);
121 match
= IOService::waitForMatchingService( dict
, timeout
);
136 IOCatalogueMatchingDriversPresent( const char * property
)
138 OSDictionary
* dict
= 0;
139 OSOrderedSet
* set
= 0;
140 SInt32 generationCount
= 0;
141 boolean_t found
= false;
145 dict
= OSDictionary::withCapacity(1);
148 dict
->setObject( property
, kOSBooleanTrue
);
149 set
= gIOCatalogue
->findDrivers( dict
, &generationCount
);
150 if ( set
&& (set
->getCount() > 0))
163 OSDictionary
* IOBSDNameMatching( const char * name
)
166 const OSSymbol
* str
= 0;
170 dict
= IOService::serviceMatching( gIOServiceKey
);
173 str
= OSSymbol::withCString( name
);
176 dict
->setObject( kIOBSDNameKey
, (OSObject
*) str
);
191 OSDictionary
* IOUUIDMatching( void )
193 return IOService::resourceMatching( "boot-uuid-media" );
196 OSDictionary
* IONetworkNamePrefixMatching( const char * prefix
)
198 OSDictionary
* matching
;
199 OSDictionary
* propDict
= 0;
200 const OSSymbol
* str
= 0;
201 char networkType
[128];
204 matching
= IOService::serviceMatching( "IONetworkInterface" );
208 propDict
= OSDictionary::withCapacity(1);
212 str
= OSSymbol::withCString( prefix
);
216 propDict
->setObject( "IOInterfaceNamePrefix", (OSObject
*) str
);
220 // see if we're contrained to netroot off of specific network type
221 if(PE_parse_boot_argn( "network-type", networkType
, 128 ))
223 str
= OSSymbol::withCString( networkType
);
226 propDict
->setObject( "IONetworkRootType", str
);
232 if ( matching
->setObject( gIOPropertyMatchKey
,
233 (OSObject
*) propDict
) != true )
243 if ( matching
) matching
->release();
244 if ( propDict
) propDict
->release();
245 if ( str
) str
->release();
250 static bool IORegisterNetworkInterface( IOService
* netif
)
252 // A network interface is typically named and registered
253 // with BSD after receiving a request from a user space
254 // "namer". However, for cases when the system needs to
255 // root from the network, this registration task must be
256 // done inside the kernel and completed before the root
257 // device is handed to BSD.
262 OSDictionary
* dict
= 0;
265 enum { kMaxPathLen
= 512 };
268 stack
= IOService::waitForService(
269 IOService::serviceMatching("IONetworkStack") );
270 if ( stack
== 0 ) break;
272 dict
= OSDictionary::withCapacity(3);
273 if ( dict
== 0 ) break;
275 zero
= OSNumber::withNumber((UInt64
) 0, 32);
276 if ( zero
== 0 ) break;
278 pathBuf
= (char *) IOMalloc( kMaxPathLen
);
279 if ( pathBuf
== 0 ) break;
282 if ( netif
->getPath( pathBuf
, &len
, gIOServicePlane
)
285 path
= OSString::withCStringNoCopy( pathBuf
);
286 if ( path
== 0 ) break;
288 dict
->setObject( "IOInterfaceUnit", zero
);
289 dict
->setObject( kIOPathMatchKey
, path
);
291 stack
->setProperties( dict
);
295 if ( zero
) zero
->release();
296 if ( path
) path
->release();
297 if ( dict
) dict
->release();
298 if ( pathBuf
) IOFree(pathBuf
, kMaxPathLen
);
300 return ( netif
->getProperty( kIOBSDNameKey
) != 0 );
303 OSDictionary
* IOOFPathMatching( const char * path
, char * buf
, int maxLen
)
305 OSDictionary
* matching
= NULL
;
312 len
= strlen( kIODeviceTreePlane
":" );
317 strlcpy( buf
, kIODeviceTreePlane
":", len
+ 1 );
320 len
= strlen( path
);
324 strlcpy( comp
, path
, len
+ 1 );
326 matching
= OSDictionary::withCapacity( 1 );
330 str
= OSString::withCString( buf
);
333 matching
->setObject( kIOPathMatchKey
, str
);
346 static int didRam
= 0;
347 enum { kMaxPathBuf
= 512, kMaxBootVar
= 128 };
349 kern_return_t
IOFindBSDRoot( char * rootName
, unsigned int rootNameSize
,
350 dev_t
* root
, u_int32_t
* oflags
)
354 IORegistryEntry
* regEntry
;
355 OSDictionary
* matching
= 0;
362 const char * mediaProperty
= 0;
365 const char * look
= 0;
367 bool debugInfoPrintedOnce
= false;
368 const char * uuidStr
= NULL
;
370 static int mountAttempts
= 0;
374 // stall here for anyone matching on the IOBSD resource to finish (filesystems)
375 matching
= IOService::serviceMatching(gIOResourcesKey
);
377 matching
->setObject(gIOResourceMatchedKey
, gIOBSDKey
);
379 if ((service
= IOService::waitForMatchingService(matching
, 30ULL * kSecondScale
))) {
389 IOLog("mount(%d) failed\n", mountAttempts
);
393 str
= (char *) IOMalloc( kMaxPathBuf
+ kMaxBootVar
);
395 return( kIOReturnNoMemory
);
396 rdBootVar
= str
+ kMaxPathBuf
;
398 if (!PE_parse_boot_argn("rd", rdBootVar
, kMaxBootVar
)
399 && !PE_parse_boot_argn("rootdev", rdBootVar
, kMaxBootVar
))
403 if( (regEntry
= IORegistryEntry::fromPath( "/chosen", gIODTPlane
))) {
404 di_root_ramfile(regEntry
);
405 data
= OSDynamicCast(OSData
, regEntry
->getProperty( "root-matching" ));
407 matching
= OSDynamicCast(OSDictionary
, OSUnserializeXML((char *)data
->getBytesNoCopy()));
413 data
= (OSData
*) regEntry
->getProperty( "boot-uuid" );
415 uuidStr
= (const char*)data
->getBytesNoCopy();
416 OSString
*uuidString
= OSString::withCString( uuidStr
);
418 // match the boot-args boot-uuid processing below
420 IOLog("rooting via boot-uuid from /chosen: %s\n", uuidStr
);
421 IOService::publishResource( "boot-uuid", uuidString
);
422 uuidString
->release();
423 matching
= IOUUIDMatching();
424 mediaProperty
= "boot-uuid-media";
436 // See if we have a RAMDisk property in /chosen/memory-map. If so, make it into a device.
437 // It will become /dev/mdx, where x is 0-f.
440 if(!didRam
) { /* Have we already build this ram disk? */
441 didRam
= 1; /* Remember we did this */
442 if((regEntry
= IORegistryEntry::fromPath( "/chosen/memory-map", gIODTPlane
))) { /* Find the map node */
443 data
= (OSData
*)regEntry
->getProperty("RAMDisk"); /* Find the ram disk, if there */
444 if(data
) { /* We found one */
445 uintptr_t *ramdParms
;
446 ramdParms
= (uintptr_t *)data
->getBytesNoCopy(); /* Point to the ram disk base and size */
447 (void)mdevadd(-1, ml_static_ptovirt(ramdParms
[0]) >> 12, ramdParms
[1] >> 12, 0); /* Initialize it and pass back the device number */
449 regEntry
->release(); /* Toss the entry */
454 // Now check if we are trying to root on a memory device
457 if((rdBootVar
[0] == 'm') && (rdBootVar
[1] == 'd') && (rdBootVar
[3] == 0)) {
458 dchar
= xchar
= rdBootVar
[2]; /* Get the actual device */
459 if((xchar
>= '0') && (xchar
<= '9')) xchar
= xchar
- '0'; /* If digit, convert */
461 xchar
= xchar
& ~' '; /* Fold to upper case */
462 if((xchar
>= 'A') && (xchar
<= 'F')) { /* Is this a valid digit? */
463 xchar
= (xchar
& 0xF) + 9; /* Convert the hex digit */
464 dchar
= dchar
| ' '; /* Fold to lower case */
466 else xchar
= -1; /* Show bogus */
468 if(xchar
>= 0) { /* Do we have a valid memory device name? */
469 *root
= mdevlookup(xchar
); /* Find the device number */
470 if(*root
>= 0) { /* Did we find one? */
471 rootName
[0] = 'm'; /* Build root name */
472 rootName
[1] = 'd'; /* Build root name */
473 rootName
[2] = dchar
; /* Build root name */
474 rootName
[3] = 0; /* Build root name */
475 IOLog("BSD root: %s, major %d, minor %d\n", rootName
, major(*root
), minor(*root
));
476 *oflags
= 0; /* Show that this is not network */
478 #if CONFIG_KDP_INTERACTIVE_DEBUGGING
479 /* retrieve final ramdisk range and initialize KDP variables */
480 if (mdevgetrange(xchar
, &kdp_core_ramdisk_addr
, &kdp_core_ramdisk_size
) != 0) {
481 IOLog("Unable to retrieve range for root memory device %d\n", xchar
);
482 kdp_core_ramdisk_addr
= 0;
483 kdp_core_ramdisk_size
= 0;
487 goto iofrootx
; /* Join common exit... */
489 panic("IOFindBSDRoot: specified root memory device, %s, has not been configured\n", rdBootVar
); /* Not there */
493 if( (!matching
) && rdBootVar
[0] ) {
499 if ( strncmp( look
, "en", strlen( "en" )) == 0 ) {
500 matching
= IONetworkNamePrefixMatching( "en" );
501 } else if ( strncmp( look
, "uuid", strlen( "uuid" )) == 0 ) {
503 OSString
*uuidString
;
505 uuid
= (char *)IOMalloc( kMaxBootVar
);
508 if (!PE_parse_boot_argn( "boot-uuid", uuid
, kMaxBootVar
)) {
509 panic( "rd=uuid but no boot-uuid=<value> specified" );
511 uuidString
= OSString::withCString( uuid
);
513 IOService::publishResource( "boot-uuid", uuidString
);
514 uuidString
->release();
515 IOLog( "\nWaiting for boot volume with UUID %s\n", uuid
);
516 matching
= IOUUIDMatching();
517 mediaProperty
= "boot-uuid-media";
519 IOFree( uuid
, kMaxBootVar
);
522 matching
= IOBSDNameMatching( look
);
528 // Match any HFS media
530 matching
= IOService::serviceMatching( "IOMedia" );
531 astring
= OSString::withCStringNoCopy("Apple_HFS");
533 matching
->setObject("Content", astring
);
538 if( gIOKitDebug
& kIOWaitQuietBeforeRoot
) {
539 IOLog( "Waiting for matching to complete\n" );
540 IOService::getPlatform()->waitQuiet();
543 if( true && matching
) {
544 OSSerialize
* s
= OSSerialize::withCapacity( 5 );
546 if( matching
->serialize( s
)) {
547 IOLog( "Waiting on %s\n", s
->text() );
553 t
.tv_sec
= ROOTDEVICETIMEOUT
;
556 service
= IOService::waitForService( matching
, &t
);
557 if( (!service
) || (mountAttempts
== 10)) {
558 PE_display_icon( 0, "noroot");
559 IOLog( "Still waiting for root device\n" );
561 if( !debugInfoPrintedOnce
) {
562 debugInfoPrintedOnce
= true;
563 if( gIOKitDebug
& kIOLogDTree
) {
564 IOLog("\nDT plane:\n");
565 IOPrintPlane( gIODTPlane
);
567 if( gIOKitDebug
& kIOLogServiceTree
) {
568 IOLog("\nService plane:\n");
569 IOPrintPlane( gIOServicePlane
);
571 if( gIOKitDebug
& kIOLogMemory
)
578 if ( service
&& mediaProperty
) {
579 service
= (IOService
*)service
->getProperty(mediaProperty
);
585 // If the IOService we matched to is a subclass of IONetworkInterface,
586 // then make sure it has been registered with BSD and has a BSD name
590 && service
->metaCast( "IONetworkInterface" )
591 && !IORegisterNetworkInterface( service
) )
599 service
->getPath( str
, &len
, gIOServicePlane
);
600 IOLog( "Got boot device = %s\n", str
);
602 iostr
= (OSString
*) service
->getProperty( kIOBSDNameKey
);
604 strlcpy( rootName
, iostr
->getCStringNoCopy(), rootNameSize
);
605 off
= (OSNumber
*) service
->getProperty( kIOBSDMajorKey
);
607 mjr
= off
->unsigned32BitValue();
608 off
= (OSNumber
*) service
->getProperty( kIOBSDMinorKey
);
610 mnr
= off
->unsigned32BitValue();
612 if( service
->metaCast( "IONetworkInterface" ))
617 IOLog( "Wait for root failed\n" );
618 strlcpy( rootName
, "en0", rootNameSize
);
622 IOLog( "BSD root: %s", rootName
);
624 IOLog(", major %d, minor %d\n", mjr
, mnr
);
628 *root
= makedev( mjr
, mnr
);
631 IOFree( str
, kMaxPathBuf
+ kMaxBootVar
);
634 if( (gIOKitDebug
& (kIOLogDTree
| kIOLogServiceTree
| kIOLogMemory
)) && !debugInfoPrintedOnce
) {
636 IOService::getPlatform()->waitQuiet();
637 if( gIOKitDebug
& kIOLogDTree
) {
638 IOLog("\nDT plane:\n");
639 IOPrintPlane( gIODTPlane
);
641 if( gIOKitDebug
& kIOLogServiceTree
) {
642 IOLog("\nService plane:\n");
643 IOPrintPlane( gIOServicePlane
);
645 if( gIOKitDebug
& kIOLogMemory
)
649 return( kIOReturnSuccess
);
652 bool IORamDiskBSDRoot(void)
654 char rdBootVar
[kMaxBootVar
];
655 if (PE_parse_boot_argn("rd", rdBootVar
, kMaxBootVar
)
656 || PE_parse_boot_argn("rootdev", rdBootVar
, kMaxBootVar
)) {
657 if((rdBootVar
[0] == 'm') && (rdBootVar
[1] == 'd') && (rdBootVar
[3] == 0)) {
664 void IOSecureBSDRoot(const char * rootName
)
669 IOPlatformExpert
*pe
;
670 OSDictionary
*matching
;
671 const OSSymbol
*functionName
= OSSymbol::withCStringNoCopy("SecureRootName");
673 matching
= IOService::serviceMatching("IOPlatformExpert");
675 pe
= (IOPlatformExpert
*) IOService::waitForMatchingService(matching
, 30ULL * kSecondScale
);
678 // Returns kIOReturnNotPrivileged is the root device is not secure.
679 // Returns kIOReturnUnsupported if "SecureRootName" is not implemented.
680 result
= pe
->callPlatformFunction(functionName
, false, (void *)rootName
, (void *)0, (void *)0, (void *)0);
681 functionName
->release();
682 OSSafeReleaseNULL(pe
);
684 if (result
== kIOReturnNotPrivileged
) {
686 } else if (result
== kIOReturnSuccess
) {
687 // If we are booting with a secure root, and we have the right
688 // boot-arg, we will want to panic on exception triage. This
689 // behavior is intended as a debug aid (we can look at why an
690 // exception occured in the kernel debugger).
691 if (PE_parse_boot_argn("-panic_on_exception_triage", &tmpInt
, sizeof(tmpInt
))) {
692 panic_on_exception_triage
= 1;
696 #endif // CONFIG_EMBEDDED
700 IOBSDRegistryEntryForDeviceTree(char * path
)
702 return (IORegistryEntry::fromPath(path
, gIODTPlane
));
706 IOBSDRegistryEntryRelease(void * entry
)
708 IORegistryEntry
* regEntry
= (IORegistryEntry
*)entry
;
716 IOBSDRegistryEntryGetData(void * entry
, char * property_name
,
720 IORegistryEntry
* regEntry
= (IORegistryEntry
*)entry
;
722 data
= (OSData
*) regEntry
->getProperty(property_name
);
724 *packet_length
= data
->getLength();
725 return (data
->getBytesNoCopy());
730 kern_return_t
IOBSDGetPlatformUUID( uuid_t uuid
, mach_timespec_t timeout
)
732 IOService
* resources
;
735 resources
= IOService::waitForService( IOService::resourceMatching( kIOPlatformUUIDKey
), ( timeout
.tv_sec
|| timeout
.tv_nsec
) ? &timeout
: 0 );
736 if ( resources
== 0 ) return KERN_OPERATION_TIMED_OUT
;
738 string
= ( OSString
* ) IOService::getPlatform( )->getProvider( )->getProperty( kIOPlatformUUIDKey
);
739 if ( string
== 0 ) return KERN_NOT_SUPPORTED
;
741 uuid_parse( string
->getCStringNoCopy( ), uuid
);
748 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
750 #include <sys/conf.h>
751 #include <sys/vnode.h>
752 #include <sys/vnode_internal.h>
753 #include <sys/fcntl.h>
754 #include <IOKit/IOPolledInterface.h>
755 #include <IOKit/IOBufferMemoryDescriptor.h>
757 IOPolledFileIOVars
* gIOPolledCoreFileVars
;
759 #if IOPOLLED_COREFILE
762 IOOpenPolledCoreFile(const char * filename
)
767 if (gIOPolledCoreFileVars
) return (kIOReturnBusy
);
768 if (!IOPolledInterface::gMetaClass
.getInstanceCount()) return (kIOReturnUnsupported
);
771 PE_parse_boot_argn("debug", &debug
, sizeof (debug
));
772 if (DB_DISABLE_LOCAL_CORE
& debug
) return (kIOReturnUnsupported
);
774 err
= IOPolledFileOpen(filename
, kIOCoreDumpSize
, kIOCoreDumpFreeSize
,
776 &gIOPolledCoreFileVars
, NULL
, NULL
, 0);
777 if (kIOReturnSuccess
!= err
) return (err
);
779 err
= IOPolledFilePollersSetup(gIOPolledCoreFileVars
, kIOPolledPreflightCoreDumpState
);
780 if (kIOReturnSuccess
!= err
)
782 IOPolledFileClose(&gIOPolledCoreFileVars
, NULL
, NULL
, 0, 0, 0);
789 IOClosePolledCoreFile(void)
791 IOPolledFilePollersClose(gIOPolledCoreFileVars
, kIOPolledPostflightCoreDumpState
);
792 IOPolledFileClose(&gIOPolledCoreFileVars
, NULL
, NULL
, 0, 0, 0);
795 static thread_call_t gIOOpenPolledCoreFileTC
;
796 static IONotifier
* gIOPolledCoreFileNotifier
;
797 static IONotifier
* gIOPolledCoreFileInterestNotifier
;
800 KernelCoreMediaInterest(void * target
, void * refCon
,
801 UInt32 messageType
, IOService
* provider
,
802 void * messageArgument
, vm_size_t argSize
)
804 if (kIOMessageServiceIsTerminated
== messageType
)
806 gIOPolledCoreFileInterestNotifier
->remove();
807 gIOPolledCoreFileInterestNotifier
= 0;
808 IOClosePolledCoreFile();
811 return (kIOReturnSuccess
);
815 OpenKernelCoreMedia(thread_call_param_t p0
, thread_call_param_t p1
)
817 IOService
* newService
;
821 newService
= (IOService
*) p1
;
824 if (gIOPolledCoreFileVars
) break;
825 string
= OSDynamicCast(OSString
, newService
->getProperty(kIOBSDNameKey
));
827 snprintf(filename
, sizeof(filename
), "/dev/%s", string
->getCStringNoCopy());
828 if (kIOReturnSuccess
!= IOOpenPolledCoreFile(filename
)) break;
829 gIOPolledCoreFileInterestNotifier
= newService
->registerInterest(
830 gIOGeneralInterest
, &KernelCoreMediaInterest
, NULL
, 0);
834 newService
->release();
838 NewKernelCoreMedia(void * target
, void * refCon
,
839 IOService
* newService
,
840 IONotifier
* notifier
)
842 static volatile UInt32 onlyOneCorePartition
= 0;
845 if (!OSCompareAndSwap(0, 1, &onlyOneCorePartition
)) break;
846 if (gIOPolledCoreFileVars
) break;
847 if (!gIOOpenPolledCoreFileTC
) break;
848 newService
= newService
->getProvider();
849 if (!newService
) break;
850 newService
->retain();
851 thread_call_enter1(gIOOpenPolledCoreFileTC
, newService
);
858 #endif /* IOPOLLED_COREFILE */
861 IOBSDMountChange(struct mount
* mp
, uint32_t op
)
863 #if IOPOLLED_COREFILE
865 OSDictionary
* bsdMatching
;
866 OSDictionary
* mediaMatching
;
869 if (!gIOPolledCoreFileNotifier
) do
871 if (!gIOOpenPolledCoreFileTC
) gIOOpenPolledCoreFileTC
= thread_call_allocate(&OpenKernelCoreMedia
, NULL
);
872 bsdMatching
= IOService::serviceMatching("IOMediaBSDClient");
873 if (!bsdMatching
) break;
874 mediaMatching
= IOService::serviceMatching("IOMedia");
875 string
= OSString::withCStringNoCopy("5361644D-6163-11AA-AA11-00306543ECAC");
876 if (!string
|| !mediaMatching
) break;
877 mediaMatching
->setObject("Content", string
);
879 bsdMatching
->setObject(gIOParentMatchKey
, mediaMatching
);
880 mediaMatching
->release();
882 gIOPolledCoreFileNotifier
= IOService::addMatchingNotification(
883 gIOFirstMatchNotification
, bsdMatching
,
884 &NewKernelCoreMedia
, NULL
, NULL
, -1000);
897 case kIOMountChangeMount
:
898 case kIOMountChangeDidResize
:
900 if (gIOPolledCoreFileVars
) break;
901 flags
= vfs_flags(mp
);
902 if (MNT_RDONLY
& flags
) break;
903 if (!(MNT_LOCAL
& flags
)) break;
905 vn
= vfs_vnodecovered(mp
);
907 pathLen
= sizeof(path
);
908 result
= vn_getpath(vn
, &path
[0], &pathLen
);
910 if (0 != result
) break;
912 if (0 != bcmp(path
, kIOCoreDumpPath
, pathLen
- 1)) break;
913 IOOpenPolledCoreFile(kIOCoreDumpPath
);
916 case kIOMountChangeUnmount
:
917 case kIOMountChangeWillResize
:
918 if (gIOPolledCoreFileVars
&& (mp
== kern_file_mount(gIOPolledCoreFileVars
->fileRef
)))
920 IOClosePolledCoreFile();
924 #endif /* CONFIG_EMBEDDED */
925 #endif /* IOPOLLED_COREFILE */
928 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
931 IOTaskHasEntitlement(task_t task
, const char * entitlement
)
934 obj
= IOUserClient::copyClientEntitlement(task
, entitlement
);
935 if (!obj
) return (false);
937 return (obj
!= kOSBooleanFalse
);