示例#1
0
文件: ach_klinux.c 项目: golems/ach
static long ach_ch_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    /* TODO: Validate argument */
    int ret = 0;
    struct ach_ch_file *ch_file = (struct ach_ch_file *)file->private_data;

    KDEBUG("ach: In ach_ch_ioctl\n");

    switch (cmd) {

    case ACH_CH_SET_MODE: {
        struct achk_opt opt;
        if (copy_from_user(&opt, (void*)arg, sizeof(opt)) ) {
            ret = -EFAULT;
        } else {
            /* This is not threadsafe */
            ch_file->mode = opt;
            /* if (ch_file->mode.reltime.tv_sec != 0 */
            /*     || ch_file->mode.reltime.tv_nsec != 0) */
            /*	KDEBUG("ach: Setting wait time to %ld.%09ld\n", */
            /*	       ch_file->mode.reltime.tv_sec, */
            /*	       ch_file->mode.reltime.tv_nsec); */
            /* KDEBUG("ach: Got cmd ACH_CH_SET_MODE: \n"); */
            /* KDEBUG1("    ACH_O_WAIT=%d\n", */
            /*	ch_file->mode.mode & ACH_O_WAIT); */
            /* KDEBUG1("    ACH_O_LAST=%d\n", */
            /*	ch_file->mode.mode & ACH_O_LAST); */
            /* KDEBUG1("    ACH_O_COPY=%d\n", */
            /*	ch_file->mode.mode & ACH_O_COPY); */
            ret = 0;
            break;
        }
    }
    case ACH_CH_GET_MODE: {
        KDEBUG("ach: Got cmd ACH_CH_GET_MODE: %ld\n", arg);
        if( copy_to_user((void*)arg, &ch_file->mode, sizeof(ch_file->mode)) )
            ret = -EFAULT;
        else
            ret = 0;
        break;
    }

    case ACH_CH_GET_STATUS: {
        KDEBUG("ach: Got cmd ACH_CH_GET_STATUS\n");
        if (rt_mutex_lock_interruptible(&ch_file->shm->sync.mutex)) {
            ret = -ERESTARTSYS;
            break;
        }

        {
            struct ach_ch_status stat;
            struct ach_header *shm = ch_file->shm;
            ach_index_t *index_ar = ACH_SHM_INDEX(shm);
            size_t oldest_index = oldest_index_i(shm);
            uint64_t oldest_seq =
                index_ar[oldest_index].seq_num;

            stat.mode = ch_file->mode.options;
            stat.size = shm->len;
            stat.count = shm->index_cnt - shm->index_free;

            if (oldest_seq > ch_file->seq_num) {
                stat.new_msgs = shm->last_seq - oldest_seq;
            } else {
                stat.new_msgs =
                    shm->last_seq - ch_file->seq_num;
            }

            stat.last_seq = shm->last_seq;
            stat.last_seq_read = ch_file->seq_num;
            printk(KERN_INFO "ach: Status:\n");
            printk(KERN_INFO "ach:            mode : %02x\n",
                   stat.mode);
            printk(KERN_INFO "ach:            size : %zu\n",
                   stat.size);
            printk(KERN_INFO "ach:            count: %zu\n",
                   stat.count);
            printk(KERN_INFO "ach:            new  : %zu\n",
                   stat.new_msgs);
            printk(KERN_INFO "ach:   last_seq      : %lu\n",
                   stat.last_seq);
            printk(KERN_INFO "ach:   last_seq_read : %lu\n",
                   stat.last_seq_read);

            if (copy_to_user((void *)arg, &stat, sizeof(stat))) {
                ret = -EFAULT;
            }
        }
        rt_mutex_unlock(&ch_file->shm->sync.mutex);
    }
    case ACH_CH_FLUSH:
        KDEBUG("ach: Got cmd ACH_CH_FLUSH\n");
        ret = -get_errno( ach_flush(ch_file) );
        break;
    case ACH_CH_CANCEL: {
        unsigned int unsafe = (unsigned int)arg;
        KDEBUG("ach: Got cmd ACH_CH_CANCEL\n");
        ret = -get_errno(ach_cancel(ch_file, unsafe));
        break;
    }
    case ACH_CH_GET_OPTIONS: {
        struct ach_ch_options retval;
        retval.mode = ch_file->mode;
        retval.clock = ch_file->shm->clock;
        if( copy_to_user( (void*)arg, &retval, sizeof(retval) ) )
            ret = -EFAULT;
        else
            ret = 0;
        break;
    }
    default:
        printk(KERN_ERR "ach: Unknown ioctl option: %d\n", cmd);
        ret = -ENOSYS;
        break;
    }

    return ret;
}
示例#2
0
文件: achlog.c 项目: penghou620/ach
int main( int argc, char **argv ) {
    /* Check if we're running under achcop */
    if( getenv("ACHCOP") ) {
        ach_pid_notify = getppid();
    }

    int c;
    while( (c = getopt( argc, argv, "zlnh?V")) != -1 ) {
        switch(c) {
        case 'v':
            ach_verbosity ++;
            break;
        case 'l':
            opt_last = 1;
            break;
        case 'n':
            opt_last = 0;
            break;
        case 'z':
            opt_gzip = 1;
            break;
        /* case 'f': */
        /*     opt_freq = atof(optarg); */
        /*     break; */
        case 'V':   /* version     */
            ach_print_version("achpipe.bin");
            exit(EXIT_SUCCESS);
        case '?':
        case 'h':
        case 'H':
            puts( "Usage: achlog [OPTIONS] channels...\n"
                  "Log ach channels to files"
                  "\n"
                  "Options:\n"
                  "  -?,                  Show help\n"
                  "  -z,                  Filter output through gzip\n"
                  "\n"
                  "Examples:\n"
                  "  achlog foo bar       Log channels foo and bar\n"
                  "\n"
                  "Report bugs to <*****@*****.**>"
                );
            exit(EXIT_SUCCESS);
        default:
            posarg(optarg);
        }
    }
    while( optind < argc ) {
        posarg(argv[optind++]);
    }
    if( 0 == n_log ) ACH_DIE("No channels to log\n");

    /* Block Signals */
    /* Have to block these before forking so ctrl-C doesn't kill the
     * gzip */
    int sigs[] = {SIGTERM, SIGINT, 0};
    ach_sig_block_dummy( sigs );

    /* Open Channels */
    size_t i;
    for( i = 0; i < n_log; i ++ ) {
        ach_status_t r = ach_open(&log_desc[i].chan, log_desc[i].name, NULL);
        if( ACH_OK != r ) {
            ACH_DIE( "Could not open channel %s: %s\n",
                     log_desc[i].name, ach_result_to_string(r) );
        }
        /* Open log file */
        if( opt_gzip ) {
            log_desc[i].fout = filter( "gzip -c", log_desc[i].name, ".gz" );
        } else {
            log_desc[i].fout = fopen(log_desc[i].name, "w");
        }
        if( NULL == log_desc[i].fout ) {
            ACH_DIE( "Could not open log file for %s: %s\n",
                     log_desc[i].name, strerror(errno) );
        }
    }

    /* get some data */
    if( clock_gettime(ACH_DEFAULT_CLOCK, &now_ach ) ||
        clock_gettime(CLOCK_REALTIME,    &now_real ) )
    {
        ACH_DIE( "Could not get time: %s\n", strerror(errno) );
    }
    if( gethostname( host, sizeof(host) ) ) {
        ACH_LOG(LOG_ERR, "Could not get host name: %s\n", strerror(errno));
    }
    host[sizeof(host)-1] = '\0';
    passwd = getpwuid(getuid());
    if( passwd ) {
        strtok(passwd->pw_gecos, ",");
    }
    now_real_str = ctime( &now_real.tv_sec );

    /* Create Workers */
    pthread_t thread[n_log];
    for( i = 0; i < n_log; i ++ ) {
        int r = pthread_create( thread+i, NULL, worker, (void*)(log_desc+i) );
        if( r ) ACH_DIE( "Couldn't start worker thread: %s\n", strerror(r) );
    }
    ach_notify(ACH_SIG_OK);

    /* Wait for Signal */
    ach_sig_wait( sigs );

    /* Cancel workers */
    ach_cancel_attr_t cattr;
    ach_cancel_attr_init( &cattr );
    cattr.async_unsafe = 1;
    for( i = 0; i < n_log; i ++ ) {
        ach_cancel( &log_desc[i].chan, &cattr );
    }

    /* Join worker threads */
    for( i = 0; i < n_log; i ++ ) {
        int r = pthread_join( thread[i], NULL );
        if( r ) ACH_DIE( "Couldn't join worker thread: %s\n", strerror(r) );
        if( opt_gzip ) {
            if( pclose(log_desc[i].fout) < 0 ) {
                ACH_LOG( LOG_ERR, "Could not pclose output for %s: %s\n",
                         log_desc[i].name, strerror(errno) );
            }
        } else {
            fclose(log_desc[i].fout);
        }
    }

    return 0;
}