From 09e7e81d6e936bce47a9a1a33df6256433e8c1b1 Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Mon, 18 Jun 2007 19:49:49 +0000 Subject: [PATCH] DEVEL15-macos-realtime-ip-updates-20070618 notice and deal with IP address changes (cherry picked from commit 56728676386dfcdb1e9f3938ce9375f9a5531f17) --- src/afs/afs_call.c | 25 +++++- src/afsd/afsd.c | 202 +++++++++++++++++++++++++++++++++++++++++++-- src/cf/osconf.m4 | 4 +- 3 files changed, 220 insertions(+), 11 deletions(-) diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 5d1978bb15..c6cd0eb429 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -846,6 +846,8 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) } else if (parm == AFSOP_ADVISEADDR) { /* pass in the host address to the rx package */ int rxbind = 0; + int refresh = 0; + afs_int32 count = parm2; afs_int32 *buffer = afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR); @@ -855,6 +857,14 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) afs_osi_Alloc(sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR); int i; + /* This is a refresh */ + if (count & 0x40000000) { + count &= ~0x40000000; + /* Can't bind after we start. Fix? */ + count &= ~0x80000000; + refresh = 1; + } + /* Bind, but only if there's only one address configured */ if ( count & 0x80000000) { count &= ~0x80000000; @@ -895,14 +905,21 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) #endif } rxi_setaddr(buffer[0]); - if (rxbind) - rx_bindhost = buffer[0]; - else - rx_bindhost = htonl(INADDR_ANY); + if (!refresh) { + if (rxbind) + rx_bindhost = buffer[0]; + else + rx_bindhost = htonl(INADDR_ANY); + } afs_osi_Free(buffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR); afs_osi_Free(maskbuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR); afs_osi_Free(mtubuffer, sizeof(afs_int32) * AFS_MAX_INTERFACE_ADDR); + + if (refresh) { + afs_CheckServers(1, NULL); /* check down servers */ + afs_CheckServers(0, NULL); /* check down servers */ + } } #ifdef AFS_SGI53_ENV else if (parm == AFSOP_NFSSTATICADDR) { diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index 5db56256a4..e39a9b0c71 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -164,6 +164,36 @@ kern_return_t DiskArbStart(mach_port_t *); kern_return_t DiskArbDiskAppearedWithMountpointPing_auto(char *, unsigned int, char *); #define DISK_ARB_NETWORK_DISK_FLAG 8 + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +typedef struct DNSSDState +{ + DNSServiceRef service; + CFRunLoopSourceRef source; + CFSocketRef socket; +} DNSSDState; + +static io_connect_t root_port; +static IONotificationPortRef notify; +static io_object_t iterator; +static CFRunLoopSourceRef source; +static DNSSDState dnsstate; + +static int event_pid; + #endif /* AFS_DARWIN_ENV */ #ifndef MOUNT_AFS @@ -314,6 +344,162 @@ struct afs_cacheParams cparams; /* params passed to cache manager */ static int HandleMTab(); +#ifdef AFS_DARWIN_ENV +static void +afsd_sleep_callback(void * refCon, io_service_t service, + natural_t messageType, void * messageArgument ) +{ + afs_int32 code; + + switch (messageType) { + case kIOMessageCanSystemSleep: + /* Idle sleep is about to kick in; can + prevent sleep by calling IOCancelPowerChange, otherwise + if we don't ack in 30s the system sleeps anyway */ + + /* allow it */ + IOAllowPowerChange(root_port, (long)messageArgument); + break; + + case kIOMessageSystemWillSleep: + /* The system WILL go to sleep. Ack or suffer delay */ + + IOAllowPowerChange(root_port, (long)messageArgument); + break; + + case kIOMessageSystemWillRestart: + /* The system WILL restart. Ack or suffer delay */ + + IOAllowPowerChange(root_port, (long)messageArgument); + break; + + case kIOMessageSystemWillPowerOn: + case kIOMessageSystemHasPoweredOn: + /* coming back from sleep */ + + IOAllowPowerChange(root_port, (long)messageArgument); + break; + + default: + IOAllowPowerChange(root_port, (long)messageArgument); + break; + } +} + +static void +afsd_update_addresses(CFRunLoopTimerRef timer, void *info) +{ + /* parse multihomed address files */ + afs_int32 addrbuf[MAXIPADDRS], maskbuf[MAXIPADDRS], + mtubuf[MAXIPADDRS]; + char reason[1024]; + afs_int32 code; + + code = + parseNetFiles(addrbuf, maskbuf, mtubuf, MAXIPADDRS, reason, + AFSDIR_CLIENT_NETINFO_FILEPATH, + AFSDIR_CLIENT_NETRESTRICT_FILEPATH); + + if (code > 0) { + /* Note we're refreshing */ + code = code | 0x40000000; + call_syscall(AFSOP_ADVISEADDR, code, addrbuf, maskbuf, mtubuf); + } else + printf("ADVISEADDR: Error in specifying interface addresses:%s\n", + reason); +} + +/* This function is called when the system's ip addresses may have changed. */ +static void +afsd_ipaddr_callback (SCDynamicStoreRef store, CFArrayRef changed_keys, void *info) +{ + CFRunLoopTimerRef timer; + + timer = CFRunLoopTimerCreate (NULL, CFAbsoluteTimeGetCurrent () + 1.0, + 0.0, 0, 0, afsd_update_addresses, NULL); + CFRunLoopAddTimer (CFRunLoopGetCurrent (), timer, + kCFRunLoopDefaultMode); + CFRelease (timer); +} + +static void +afsd_event_cleanup(int signo) { + DNSSDState *query = &dnsstate; + + CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode); + CFRelease (source); + IODeregisterForSystemPower(iterator); + IOServiceClose(root_port); + IONotificationPortDestroy(notify); + + exit(0); +} + +/* Adapted from "Living in a Dynamic TCP/IP Environment" technote. */ +static Boolean +afsd_install_events(void) +{ + SCDynamicStoreContext ctx = {0}; + SCDynamicStoreRef store; + + root_port = IORegisterForSystemPower(0,¬ify,afsd_sleep_callback,&iterator); + + if (root_port) { + CFRunLoopAddSource(CFRunLoopGetCurrent(), + IONotificationPortGetRunLoopSource(notify), + kCFRunLoopDefaultMode); + } + + + store = SCDynamicStoreCreate (NULL, + CFSTR ("AddIPAddressListChangeCallbackSCF"), + afsd_ipaddr_callback, &ctx); + + if (store) { + const void *keys[1]; + + /* Request IPV4 address change notification */ + keys[0] = (SCDynamicStoreKeyCreateNetworkServiceEntity + (NULL, kSCDynamicStoreDomainState, + kSCCompAnyRegex, kSCEntNetIPv4)); + +#if 0 + /* This should tell us when the hostname(s) change. do we care? */ + keys[N] = SCDynamicStoreKeyCreateHostNames (NULL); +#endif + + if (keys[0] != NULL) { + CFArrayRef pattern_array; + + pattern_array = CFArrayCreate (NULL, keys, 1, + &kCFTypeArrayCallBacks); + + if (pattern_array != NULL) + { + SCDynamicStoreSetNotificationKeys (store, NULL, pattern_array); + source = SCDynamicStoreCreateRunLoopSource (NULL, store, 0); + + CFRelease (pattern_array); + } + + if (keys[0] != NULL) + CFRelease (keys[0]); + } + + CFRelease (store); + } + + if (source != NULL) { + CFRunLoopAddSource (CFRunLoopGetCurrent(), + source, kCFRunLoopDefaultMode); + } + + signal(SIGTERM, afsd_event_cleanup); + + CFRunLoopRun(); +} +#endif + /* ParseArgs is now obsolete, being handled by cmd */ /*------------------------------------------------------------------------------ @@ -1251,6 +1437,16 @@ AfsdbLookupHandler() kernelMsg[1] = 0; acellName[0] = '\0'; +#ifdef AFS_DARWIN_ENV + /* Fork the event handler also. */ + code = fork(); + if (code == 0) { + afsd_install_events(); + exit(1); + } else if (code != -1) { + event_pid = code; + } +#endif while (1) { /* On some platforms you only get 4 args to an AFS call */ int sizeArg = ((sizeof acellName) << 16) | (sizeof kernelMsg); @@ -1280,7 +1476,7 @@ AfsdbLookupHandler() acellName[sizeof(acellName) - 1] = '\0'; } } - + kill(event_pid, SIGTERM); exit(1); } #endif @@ -1758,10 +1954,6 @@ mainproc(struct cmd_syndesc *as, char *arock) exit(1); #endif } -#if 0 - fputs(AFS_GOVERNMENT_MESSAGE, stdout); - fflush(stdout); -#endif /* * Set up all the kernel processes needed for AFS. diff --git a/src/cf/osconf.m4 b/src/cf/osconf.m4 index a91a962b24..c5f68bf302 100644 --- a/src/cf/osconf.m4 +++ b/src/cf/osconf.m4 @@ -475,7 +475,7 @@ case $AFS_SYSNAME in ;; *_darwin_80) - AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration" + AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration -framework SystemConfiguration -framework IOKit -framework CoreFoundation" LEX="lex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -D_REENTRANT ${XCFLAGS} ${ARCHFLAGS}' KROOT= @@ -491,7 +491,7 @@ case $AFS_SYSNAME in ;; *_darwin_90) - AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration" + AFSD_LDFLAGS="-F/System/Library/PrivateFrameworks -framework DiskArbitration -framework SystemConfiguration -framework IOKit -framework CoreFoundation" LEX="lex -l" MT_CFLAGS='-DAFS_PTHREAD_ENV -D_REENTRANT ${XCFLAGS} ${ARCHFLAGS}' KROOT=