Annotation of driverkit/Examples/loadable/User/kl_com.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*     @(#)kl_com.m    2.0     27/07/90        (c) 1990 NeXT   */
        !            25: 
        !            26: /* 
        !            27:  * kl_com.m -- common kern_loader communication module.
        !            28:  *
        !            29:  * HISTORY
        !            30:  * 27-Jul-90   Doug Mitchell at NeXT
        !            31:  *     Cloned from DOS source.
        !            32:  */
        !            33: 
        !            34: #import <mach/mach_traps.h>
        !            35: #import <mach/mach.h>
        !            36: #import <ansi/stdlib.h>
        !            37: #import <bsd/libc.h>
        !            38: #import <ansi/stdio.h>
        !            39: #import <bsd/strings.h>
        !            40: #import <mach/mach_error.h>
        !            41: #import <mach/mig_errors.h>
        !            42: #import <mach/cthreads.h>
        !            43: #import <servers/bootstrap.h>
        !            44: #import <kernserv/kern_loader_error.h>
        !            45: #import <kernserv/kern_loader_types.h>
        !            46: #import <kernserv/kern_loader.h>
        !            47: #import <kernserv/kern_loader_reply_handler.h>
        !            48: #import <bsd/sys/param.h>
        !            49: #import <mach/notify.h>
        !            50: #import <mach/message.h>
        !            51: #import "kl_com.h"
        !            52: #import <machkit/NXLock.h>
        !            53: #import <driverkit/generalFuncs.h>
        !            54: 
        !            55: static int kl_init();
        !            56: static int kl_com_log(port_name_t port);
        !            57: static kern_return_t print_string (
        !            58:        void            *arg,
        !            59:        printf_data_t   string,
        !            60:        u_int           stringCnt,
        !            61:        int             level);
        !            62: static kern_return_t ping (
        !            63:        void            *arg,
        !            64:        int             id);
        !            65: static void kl_com_error(char *err_str, kern_return_t rtn);
        !            66: 
        !            67: port_name_t kl_port;
        !            68: port_name_t kernel_task, reply_port;
        !            69: boolean_t kl_init_flag = FALSE;
        !            70: static id ping_lock;
        !            71: 
        !            72: /*
        !            73:  * Set up ports, etc. for kern_loader communication.
        !            74:  */
        !            75: static int 
        !            76: kl_init() {
        !            77:        kern_return_t r;
        !            78:        boolean_t isactive;
        !            79: 
        !            80:        if(kl_init_flag)
        !            81:                return(0);
        !            82:        r = kern_loader_look_up(&kl_port);
        !            83:        if (r != KERN_SUCCESS) {
        !            84:                kl_com_error("can't find kernel loader", r);
        !            85:                return(1);
        !            86:        }
        !            87: 
        !            88:        r = task_by_unix_pid(task_self(), 0, &kernel_task);
        !            89:        if (r != KERN_SUCCESS) {
        !            90:                kl_com_error("cannot get kernel task port\n", r);
        !            91:                return(1);
        !            92:        }
        !            93: 
        !            94:        r = port_allocate(task_self(), &reply_port);
        !            95:        if (r != KERN_SUCCESS) {
        !            96:                kl_com_error("can't allocate reply port", r);
        !            97:                return(1);
        !            98:        }
        !            99: 
        !           100:        r = bootstrap_status(bootstrap_port, KERN_LOADER_NAME, &isactive);
        !           101:        if (r != KERN_SUCCESS) {
        !           102:                kl_com_error("can't find kernel loader status", r);
        !           103:                return(1);
        !           104:        }
        !           105:        /*
        !           106:         * Create a thread to listen on reply_port
        !           107:         * and print out anything that comes back.
        !           108:         */
        !           109:        cthread_init();
        !           110:        cthread_set_name(cthread_self(), "command thread");
        !           111:        cthread_detach(cthread_fork((cthread_fn_t)kl_com_log,
        !           112:                (any_t)reply_port));
        !           113: 
        !           114:        if (!isactive)
        !           115:                printf("kernel loader inactive, pausing\n");
        !           116: 
        !           117:        r = kern_loader_status_port(kl_port, reply_port);
        !           118:        if(r) {
        !           119:                kl_com_error("can't get status back\n", r);
        !           120:                return(1);
        !           121:        }
        !           122:        ping_lock = [[NXConditionLock alloc] initWith:FALSE];
        !           123:        kl_init_flag = TRUE;
        !           124:        return(0);
        !           125: }
        !           126: 
        !           127: 
        !           128: kern_loader_reply_t kern_loader_reply = {
        !           129:        0,
        !           130:        0,
        !           131:        print_string,
        !           132:        ping
        !           133: };
        !           134: 
        !           135: /*
        !           136:  * wait for reply messages.
        !           137:  */
        !           138: static int 
        !           139: kl_com_log(port_name_t port)
        !           140: {
        !           141:        char msg_buf[kern_loader_replyMaxRequestSize];
        !           142:        msg_header_t *msg = (msg_header_t *)msg_buf;
        !           143:        port_name_t notify_port;
        !           144:        port_set_name_t port_set;
        !           145:        kern_return_t r;
        !           146: 
        !           147:        r = port_allocate(task_self(), &notify_port);
        !           148:        if (r != KERN_SUCCESS) {
        !           149:                kl_com_error("allocating notify port", r);
        !           150:                return(1);
        !           151:        }
        !           152: 
        !           153:        r = task_set_notify_port(task_self(), notify_port);
        !           154:        if (r != KERN_SUCCESS) {
        !           155:                kl_com_error("cannot set notify port", r);
        !           156:                return(1);
        !           157:        }
        !           158: 
        !           159:        r = port_set_allocate(task_self(), &port_set);
        !           160:        if (r != KERN_SUCCESS) {
        !           161:                kl_com_error("allocating port set", r);
        !           162:                return(1);
        !           163:        }
        !           164: 
        !           165:        r = port_set_add(task_self(), port_set, notify_port);
        !           166:        if (r != KERN_SUCCESS) {
        !           167:                kl_com_error("adding notify port to port set", r);
        !           168:                return(1);
        !           169:        }
        !           170: 
        !           171:        r = port_set_add(task_self(), port_set, port);
        !           172:        if (r != KERN_SUCCESS) {
        !           173:                kl_com_error("adding listener port to port set", r);
        !           174:                return(1);
        !           175:        }
        !           176:        while(1) {
        !           177:                msg->msg_size = kern_loader_replyMaxRequestSize;
        !           178:                msg->msg_local_port = port_set;
        !           179:                r = msg_receive(msg, MSG_OPTION_NONE, 0);
        !           180:                if (r != KERN_SUCCESS) {
        !           181:                        kl_com_error("log_thread receive", r);
        !           182:                        return(1);
        !           183:                }
        !           184:                if (msg->msg_local_port == notify_port) {
        !           185:                        notification_t *n = (notification_t *)msg;
        !           186:                        
        !           187:                        if(msg->msg_id == NOTIFY_PORT_DELETED) {
        !           188:                            if(n->notify_port == kl_port) {
        !           189:                                printf("kdb: kern_loader port "
        !           190:                                        "deleted\n");
        !           191:                                continue;
        !           192:                            }
        !           193:                            else {
        !           194:                                printf("kdb: port death detected"
        !           195:                                        "(port %d)\n", n->notify_port);
        !           196:                                continue;
        !           197:                            }
        !           198:                        }
        !           199:                        else {
        !           200:                                printf("kdb: weird notification "
        !           201:                                        "(msg_id %d)\n", msg->msg_id);
        !           202:                                continue;
        !           203:                        }
        !           204:                } 
        !           205:                else 
        !           206:                        kern_loader_reply_handler(msg, &kern_loader_reply);
        !           207:        }
        !           208:        return(0);
        !           209: }
        !           210: 
        !           211: static kern_return_t 
        !           212: print_string (
        !           213:        void            *arg,
        !           214:        printf_data_t   string,
        !           215:        u_int           stringCnt,
        !           216:        int             level)
        !           217: {
        !           218: #if    DEBUG
        !           219:        if (stringCnt == 0 || !string)
        !           220:                return KERN_SUCCESS;
        !           221:        fputs(string, stdout);
        !           222:        fflush(stdout);
        !           223: #endif DEBUG
        !           224:        return KERN_SUCCESS;
        !           225: }
        !           226: 
        !           227: static kern_return_t 
        !           228: ping (
        !           229:        void            *arg,
        !           230:        int             id)
        !           231: {
        !           232:        [ping_lock lockWhen:FALSE];
        !           233:        [ping_lock unlockWith:TRUE];
        !           234:        return KERN_SUCCESS;
        !           235: }
        !           236: 
        !           237: /*
        !           238:  * Exported functions.
        !           239:  */
        !           240:  
        !           241: /*
        !           242:  * Add specified server ("kl_util -a"). If server already exists, this
        !           243:  * is a nop.
        !           244:  *
        !           245:  * path_name is the location of the relocatable.
        !           246:  * server_name is kern_loader's notion of the server's identity.
        !           247:  */
        !           248: int 
        !           249: kl_com_add(char *path_name, char *server_name) {
        !           250:        int rtn;
        !           251:        kern_return_t r;
        !           252:        
        !           253:        if(rtn = kl_init())
        !           254:                return(rtn);
        !           255:        switch(kl_com_get_state(server_name)) {
        !           256:            case KSS_LOADED:
        !           257:            case KSS_ALLOCATED:
        !           258:                return(0);              /* this function is a nop */
        !           259:           default:
        !           260:                break;
        !           261:        }
        !           262:        r = kern_loader_add_server(kl_port, kernel_task, path_name);
        !           263:        if((r != KERN_SUCCESS) && 
        !           264:           (r != KERN_LOADER_SERVER_EXISTS) &&
        !           265:           /* bogus - covers kern_loader bug #7190 */
        !           266:           (r != KERN_LOADER_SERVER_WONT_LOAD)) {
        !           267:                kl_com_error("kern_loader_add_server", r);
        !           268:                rtn = 1;
        !           269:        }
        !           270:        return(rtn);
        !           271: }
        !           272: 
        !           273: /*
        !           274:  * Delete specified server.
        !           275:  */
        !           276: int 
        !           277: kl_com_delete(char *server_name) {
        !           278:        int rtn;
        !           279:        kern_return_t r;
        !           280: 
        !           281:        if(rtn = kl_init())
        !           282:                return(rtn);
        !           283:        r = kern_loader_delete_server(kl_port, kernel_task, server_name);
        !           284:        if(r) {
        !           285:                kl_com_error("kern_loader_delete_server", r);
        !           286:                rtn = 1;
        !           287:        }
        !           288:        return(rtn);
        !           289: }
        !           290: 
        !           291: /*
        !           292:  * Load the specified server into kernel memory if it isn't already loaded.
        !           293:  */
        !           294: int 
        !           295: kl_com_load(char *server_name) {
        !           296:        int rtn;
        !           297:        kern_return_t r;
        !           298: 
        !           299:        if(rtn = kl_init())
        !           300:                return(rtn);
        !           301:        switch(kl_com_get_state(server_name)) {
        !           302:            case KSS_LOADED:
        !           303:                return(0);              /* this function is a nop */
        !           304:           default:
        !           305:                break;
        !           306:        }
        !           307:        r = kern_loader_load_server(kl_port, server_name);
        !           308:        if(r) {
        !           309:                kl_com_error("kern_loader_load_server", r);
        !           310:                rtn = 1;
        !           311:        }
        !           312:        return(rtn);
        !           313: }
        !           314: 
        !           315: /*
        !           316:  * Unload specified server from kernel memory. The server is not deleted
        !           317:  * from kern_loader's list of servers.
        !           318:  */
        !           319: int 
        !           320: kl_com_unload(char *server_name) {
        !           321:        int rtn = 0;
        !           322:        kern_return_t r;
        !           323: 
        !           324:        if(rtn = kl_init())
        !           325:                return(rtn);
        !           326:        r = kern_loader_unload_server(kl_port, kernel_task, server_name);
        !           327:        if(r) {
        !           328:                kl_com_error("kern_loader_unload_server", r);
        !           329:                rtn = 1;
        !           330:        }
        !           331:        return(rtn);
        !           332: }
        !           333: 
        !           334: klc_server_state 
        !           335: kl_com_get_state(char *server_name)
        !           336: {
        !           337:        server_state_t state;
        !           338:        /*
        !           339:         * remainder are unused...
        !           340:         */
        !           341:        vm_address_t load_address;
        !           342:        vm_size_t load_size;
        !           343:        server_reloc_t reloc, loadable;
        !           344:        port_name_t *ports;
        !           345:        port_name_string_array_t port_names;
        !           346:        u_int cnt;
        !           347:        boolean_t *advertised;
        !           348:        kern_return_t rtn;
        !           349:        
        !           350:        if(rtn = kl_init())
        !           351:                return(rtn);
        !           352:        rtn = kern_loader_server_info(kl_port, PORT_NULL, server_name,
        !           353:                &state, &load_address, &load_size, reloc, loadable,
        !           354:                &ports, &cnt, &port_names, &cnt, &advertised, &cnt);
        !           355:        if(rtn != KERN_SUCCESS) {
        !           356:                return(KSS_UNKNOWN);
        !           357:        }
        !           358:        switch(state) {
        !           359:            case Allocating:
        !           360:            case Allocated:
        !           361:                return(KSS_ALLOCATED);
        !           362:            case Loading:
        !           363:            case Loaded:
        !           364:                return(KSS_LOADED);
        !           365:            case Zombie:
        !           366:            case Unloading:
        !           367:            case Deallocated:
        !           368:            default:
        !           369:                return(KSS_UNKNOWN);
        !           370:        }
        !           371: 
        !           372: }
        !           373: 
        !           374: void 
        !           375: kl_com_error(char *err_str, kern_return_t rtn)
        !           376: {
        !           377:        IOLog("%s: error %d\n", err_str, rtn);
        !           378: }
        !           379: 
        !           380: void 
        !           381: kl_com_wait()
        !           382: {
        !           383:        kern_loader_ping(kl_port, reply_port, 0);
        !           384:        
        !           385:        
        !           386:        /*
        !           387:         * ping() is called when this is done...
        !           388:         */
        !           389:        [ping_lock lockWhen:TRUE];
        !           390:        [ping_lock unlockWith:FALSE];
        !           391: }
        !           392: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.