~ubuntu-branches/ubuntu/maverick/tomcat6/maverick

« back to all changes in this revision

Viewing changes to native/connector/os/unix/system.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2010-01-23 19:40:38 UTC
  • mfrom: (2.2.6 sid)
  • Revision ID: james.westby@ubuntu.com-20100123194038-0tnrf6kiy0wrjrw9
Tags: 6.0.20-dfsg1-1
* Fix debian/orig-tar.sh to exclude binary only standard.jar and jstl.jar.
  (Closes: #528119)
* Upload a cleaned tarball.
* Add ${misc:Depends} in debian/control.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Licensed to the Apache Software Foundation (ASF) under one or more
2
 
 * contributor license agreements.  See the NOTICE file distributed with
3
 
 * this work for additional information regarding copyright ownership.
4
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
5
 
 * (the "License"); you may not use this file except in compliance with
6
 
 * the License.  You may obtain a copy of the License at
7
 
 *
8
 
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
/*
18
 
 *
19
 
 * @author Mladen Turk
20
 
 * @version $Revision: 708867 $, $Date: 2008-10-29 11:39:16 +0100 (Wed, 29 Oct 2008) $
21
 
 */
22
 
 
23
 
#include "apr.h"
24
 
#include "apr_pools.h"
25
 
#include "apr_network_io.h"
26
 
#include "apr_poll.h"
27
 
 
28
 
#include "tcn.h"
29
 
#if defined(__linux__)
30
 
#include <sys/sysinfo.h>
31
 
#elif defined(sun)
32
 
#include <unistd.h>
33
 
#include <sys/swap.h>
34
 
#include <procfs.h>
35
 
#include <kstat.h>
36
 
#include <sys/sysinfo.h>
37
 
#endif
38
 
 
39
 
#if defined(DARWIN)
40
 
#include <mach/mach_init.h>
41
 
#include <mach/mach_host.h>
42
 
#include <mach/host_info.h>
43
 
#include <sys/sysctl.h>
44
 
#include <sys/stat.h>
45
 
#endif
46
 
 
47
 
#include <syslog.h>
48
 
#include <stdarg.h>
49
 
 
50
 
#ifndef LOG_WARN
51
 
#define LOG_WARN LOG_WARNING
52
 
#endif
53
 
 
54
 
#if defined(sun)
55
 
#define MAX_PROC_PATH_LEN 64
56
 
#define MAX_CPUS 512
57
 
#define PSINFO_T_SZ sizeof(psinfo_t)
58
 
#define PRUSAGE_T_SZ sizeof(prusage_t)
59
 
 
60
 
static int proc_open(const char *type)
61
 
{
62
 
    char proc_path[MAX_PROC_PATH_LEN+1];
63
 
 
64
 
    sprintf(proc_path, "/proc/self/%s", type);
65
 
    return open(proc_path, O_RDONLY);
66
 
}
67
 
 
68
 
static int proc_read(void *buf, const size_t size, int filedes)
69
 
{
70
 
    ssize_t bytes;
71
 
 
72
 
    if (filedes >= 0) {
73
 
        bytes = pread(filedes, buf, size, 0);
74
 
        if (bytes != size)
75
 
            return -1;
76
 
        else
77
 
            return 0;
78
 
    }
79
 
    else
80
 
        return -1;
81
 
}
82
 
 
83
 
#endif
84
 
 
85
 
TCN_IMPLEMENT_CALL(jboolean, OS, is)(TCN_STDARGS, jint type)
86
 
{
87
 
    UNREFERENCED_STDARGS;
88
 
    if (type == 1)
89
 
        return JNI_TRUE;
90
 
#if defined(__linux__)
91
 
    else if (type == 5)
92
 
        return JNI_TRUE;
93
 
#endif
94
 
#if defined(sun)
95
 
    else if (type == 6)
96
 
        return JNI_TRUE;
97
 
#endif
98
 
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
99
 
    else if (type == 7)
100
 
        return JNI_TRUE;
101
 
#endif
102
 
#if defined(__APPLE__) || defined(DARWIN)
103
 
    else if (type == 8)
104
 
        return JNI_TRUE;
105
 
#endif
106
 
    else
107
 
        return JNI_FALSE;
108
 
}
109
 
 
110
 
TCN_IMPLEMENT_CALL(jint, OS, info)(TCN_STDARGS,
111
 
                                   jlongArray inf)
112
 
{
113
 
    jint rv;
114
 
    int  i;
115
 
    jsize ilen = (*e)->GetArrayLength(e, inf);
116
 
    jlong *pvals = (*e)->GetLongArrayElements(e, inf, NULL);
117
 
 
118
 
    UNREFERENCED(o);
119
 
    if (ilen < 16) {
120
 
        return APR_EINVAL;
121
 
    }
122
 
    for (i = 0; i < 16; i++)
123
 
        pvals[i] = 0;
124
 
#if defined(__linux__)
125
 
    {
126
 
        struct sysinfo info;
127
 
        if (sysinfo(&info))
128
 
            rv = apr_get_os_error();
129
 
        else {
130
 
            pvals[0] = (jlong)(info.totalram  * info.mem_unit);
131
 
            pvals[1] = (jlong)(info.freeram   * info.mem_unit);
132
 
            pvals[2] = (jlong)(info.totalswap * info.mem_unit);
133
 
            pvals[3] = (jlong)(info.freeswap  * info.mem_unit);
134
 
            pvals[4] = (jlong)(info.sharedram * info.mem_unit);
135
 
            pvals[5] = (jlong)(info.bufferram * info.mem_unit);
136
 
            pvals[6] = (jlong)(100 - (info.freeram * 100 / info.totalram));
137
 
            rv = APR_SUCCESS;
138
 
        }
139
 
    }
140
 
#elif defined(sun)
141
 
    {
142
 
        /* static variables with basic procfs info */
143
 
        static long creation = 0;              /* unix timestamp of process creation */
144
 
        static int psinf_fd = 0;               /* file descriptor for the psinfo procfs file */
145
 
        static int prusg_fd = 0;               /* file descriptor for the usage procfs file */
146
 
        static size_t rss = 0;                 /* maximum of resident set size from previous calls */
147
 
        /* static variables with basic kstat info */
148
 
        static kstat_ctl_t *kstat_ctl = NULL;  /* kstat control object, only initialized once */
149
 
        static kstat_t *kstat_cpu[MAX_CPUS];   /* array of kstat objects for per cpu statistics */
150
 
        static int cpu_count = 0;              /* number of cpu structures found in kstat */
151
 
        static kid_t kid = 0;                  /* kstat ID, for which the kstat_ctl holds the correct chain */
152
 
        /* non-static variables - general use */
153
 
        int res = 0;                           /* general result state */
154
 
        /* non-static variables - sysinfo/swapctl use */
155
 
        long ret_sysconf;                      /* value returned from sysconf call */
156
 
        long tck_dividend;                     /* factor used by transforming tick numbers to milliseconds */
157
 
        long tck_divisor;                      /* divisor used by transforming tick numbers to milliseconds */
158
 
        long sys_pagesize = sysconf(_SC_PAGESIZE); /* size of a system memory page in bytes */
159
 
        long sys_clk_tck = sysconf(_SC_CLK_TCK); /* number of system ticks per second */
160
 
        struct anoninfo info;                  /* structure for information about sizes in anonymous memory system */
161
 
        /* non-static variables - procfs use */
162
 
        psinfo_t psinf;                        /* psinfo structure from procfs */
163
 
        prusage_t prusg;                       /* usage structure from procfs */
164
 
        size_t new_rss = 0;                    /* resident set size read from procfs */
165
 
        time_t now;                            /* time needed for calculating process creation time */
166
 
        /* non-static variables - kstat use */
167
 
        kstat_t *kstat = NULL;                 /* kstat working pointer */
168
 
        cpu_sysinfo_t cpu;                     /* cpu sysinfo working pointer */
169
 
        kid_t new_kid = 0;                     /* kstat ID returned from chain update */
170
 
        int new_kstat = 0;                     /* flag indicating, if kstat structure has changed since last call */
171
 
 
172
 
        rv = APR_SUCCESS;
173
 
 
174
 
        if (sys_pagesize <= 0) {
175
 
            rv = apr_get_os_error();
176
 
        }
177
 
        else {
178
 
            ret_sysconf = sysconf(_SC_PHYS_PAGES);
179
 
            if (ret_sysconf >= 0) {
180
 
                pvals[0] = (jlong)((jlong)sys_pagesize * ret_sysconf);
181
 
            }
182
 
            else {
183
 
                rv = apr_get_os_error();
184
 
            }
185
 
            ret_sysconf = sysconf(_SC_AVPHYS_PAGES);
186
 
            if (ret_sysconf >= 0) {
187
 
                pvals[1] = (jlong)((jlong)sys_pagesize * ret_sysconf);
188
 
            }
189
 
            else {
190
 
                rv = apr_get_os_error();
191
 
            }
192
 
            res=swapctl(SC_AINFO, &info);
193
 
            if (res >= 0) {
194
 
                pvals[2] = (jlong)((jlong)sys_pagesize * info.ani_max);
195
 
                pvals[3] = (jlong)((jlong)sys_pagesize * info.ani_free);
196
 
                pvals[6] = (jlong)(100 - (jlong)info.ani_free * 100 / info.ani_max);
197
 
            }
198
 
            else {
199
 
                rv = apr_get_os_error();
200
 
            }
201
 
        }
202
 
 
203
 
        if (psinf_fd == 0) {
204
 
            psinf_fd = proc_open("psinfo");
205
 
        }
206
 
        res = proc_read(&psinf, PSINFO_T_SZ, psinf_fd);
207
 
        if (res >= 0) {
208
 
            new_rss = psinf.pr_rssize*1024;
209
 
            pvals[13] = (jlong)(new_rss);
210
 
            if (new_rss > rss) {
211
 
                rss = new_rss;
212
 
            }
213
 
            pvals[14] = (jlong)(rss);
214
 
        }
215
 
        else {
216
 
            psinf_fd = 0;
217
 
            rv = apr_get_os_error();
218
 
        }
219
 
        if (prusg_fd == 0) {
220
 
            prusg_fd = proc_open("usage");
221
 
        }
222
 
        res = proc_read(&prusg, PRUSAGE_T_SZ, prusg_fd);
223
 
        if (res >= 0) {
224
 
            if (creation <= 0) {
225
 
                time(&now);
226
 
                creation = (long)(now - (prusg.pr_tstamp.tv_sec -
227
 
                                         prusg.pr_create.tv_sec));
228
 
            }
229
 
            pvals[10] = (jlong)(creation);
230
 
            pvals[11] = (jlong)((jlong)prusg.pr_stime.tv_sec * 1000 +
231
 
                                (prusg.pr_stime.tv_nsec / 1000000));
232
 
            pvals[12] = (jlong)((jlong)prusg.pr_utime.tv_sec * 1000 +
233
 
                                (prusg.pr_utime.tv_nsec / 1000000));
234
 
            pvals[15] = (jlong)(prusg.pr_majf);
235
 
        }
236
 
        else {
237
 
            prusg_fd = 0;
238
 
            rv = apr_get_os_error();
239
 
        }
240
 
 
241
 
        if (sys_clk_tck <= 0) {
242
 
            rv = apr_get_os_error();
243
 
        }
244
 
        else {
245
 
            tck_dividend = 1000;
246
 
            tck_divisor = sys_clk_tck;
247
 
            for (i = 0; i < 3; i++) {
248
 
                if (tck_divisor % 2 == 0) {
249
 
                    tck_divisor = tck_divisor / 2;
250
 
                    tck_dividend = tck_dividend / 2;
251
 
                }
252
 
                if (tck_divisor % 5 == 0) {
253
 
                    tck_divisor = tck_divisor / 5;
254
 
                    tck_dividend = tck_dividend / 5;
255
 
                }
256
 
            }
257
 
            if (kstat_ctl == NULL) {
258
 
                kstat_ctl = kstat_open();
259
 
                kid = kstat_ctl->kc_chain_id;
260
 
                new_kstat = 1;
261
 
            } else {
262
 
                new_kid = kstat_chain_update(kstat_ctl);
263
 
                if (new_kid < 0) {
264
 
                    res=kstat_close(kstat_ctl);
265
 
                    kstat_ctl = kstat_open();
266
 
                    kid = kstat_ctl->kc_chain_id;
267
 
                    new_kstat = 1;
268
 
                } else if (new_kid > 0 && kid != new_kid) {
269
 
                    kid = new_kid;
270
 
                    new_kstat = 1;
271
 
                }
272
 
            }
273
 
            if (new_kstat) {
274
 
                cpu_count = 0;
275
 
                for (kstat = kstat_ctl->kc_chain; kstat; kstat = kstat->ks_next) {
276
 
                    if (strncmp(kstat->ks_name, "cpu_stat", 8) == 0) {
277
 
                        kstat_cpu[cpu_count++]=kstat;
278
 
                    }
279
 
                }
280
 
            }
281
 
            for (i = 0; i < cpu_count; i++) {
282
 
                new_kid = kstat_read(kstat_ctl, kstat_cpu[i], NULL);
283
 
                if (new_kid >= 0) {
284
 
                    cpu = ((cpu_stat_t *)kstat_cpu[i]->ks_data)->cpu_sysinfo;
285
 
                    if ( tck_divisor == 1 ) {
286
 
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend);
287
 
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend);
288
 
                        pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend);
289
 
                        pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend);
290
 
                    } else {
291
 
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_IDLE]) * tck_dividend / tck_divisor);
292
 
                        pvals[7] += (jlong)(((jlong)cpu.cpu[CPU_WAIT]) * tck_dividend / tck_divisor);
293
 
                        pvals[8] += (jlong)(((jlong)cpu.cpu[CPU_KERNEL]) * tck_dividend / tck_divisor);
294
 
                        pvals[9] += (jlong)(((jlong)cpu.cpu[CPU_USER]) * tck_dividend / tck_divisor);
295
 
                    }
296
 
                }
297
 
            }
298
 
        }
299
 
 
300
 
        /*
301
 
         * The next two are not implemented yet for Solaris
302
 
         * inf[4]  - Amount of shared memory
303
 
         * inf[5]  - Memory used by buffers
304
 
         *
305
 
         */
306
 
    }
307
 
 
308
 
#elif defined(DARWIN)
309
 
 
310
 
    uint64_t mem_total;
311
 
    size_t len = sizeof(mem_total);
312
 
 
313
 
    vm_statistics_data_t vm_info;
314
 
    mach_msg_type_number_t info_count = HOST_VM_INFO_COUNT;
315
 
 
316
 
    sysctlbyname("hw.memsize", &mem_total, &len, NULL, 0);
317
 
    pvals[0] = (jlong)mem_total;
318
 
 
319
 
    host_statistics(mach_host_self (), HOST_VM_INFO, (host_info_t)&vm_info, &info_count);
320
 
    pvals[1] = (jlong)(((double)vm_info.free_count)*vm_page_size);
321
 
    pvals[6] = (jlong)(100 - (pvals[1] * 100 / mem_total));
322
 
    rv = APR_SUCCESS;
323
 
 
324
 
/* DARWIN */
325
 
#else
326
 
    rv = APR_ENOTIMPL;
327
 
#endif
328
 
   (*e)->ReleaseLongArrayElements(e, inf, pvals, 0);
329
 
    return rv;
330
 
}
331
 
 
332
 
#define LOG_MSG_DOMAIN                   "Native"
333
 
 
334
 
 
335
 
TCN_IMPLEMENT_CALL(jstring, OS, expand)(TCN_STDARGS, jstring val)
336
 
{
337
 
    jstring str;
338
 
    TCN_ALLOC_CSTRING(val);
339
 
 
340
 
    UNREFERENCED(o);
341
 
 
342
 
    /* TODO: Make ${ENVAR} expansion */
343
 
    str = (*e)->NewStringUTF(e, J2S(val));
344
 
 
345
 
    TCN_FREE_CSTRING(val);
346
 
    return str;
347
 
}
348
 
 
349
 
TCN_IMPLEMENT_CALL(void, OS, sysloginit)(TCN_STDARGS, jstring domain)
350
 
{
351
 
    const char *d;
352
 
    TCN_ALLOC_CSTRING(domain);
353
 
 
354
 
    UNREFERENCED(o);
355
 
    if ((d = J2S(domain)) == NULL)
356
 
        d = LOG_MSG_DOMAIN;
357
 
 
358
 
    openlog(d, LOG_CONS | LOG_PID, LOG_LOCAL0);
359
 
    TCN_FREE_CSTRING(domain);
360
 
}
361
 
 
362
 
TCN_IMPLEMENT_CALL(void, OS, syslog)(TCN_STDARGS, jint level,
363
 
                                     jstring msg)
364
 
{
365
 
    TCN_ALLOC_CSTRING(msg);
366
 
    int id = LOG_DEBUG;
367
 
    UNREFERENCED(o);
368
 
 
369
 
    switch (level) {
370
 
        case TCN_LOG_EMERG:
371
 
            id = LOG_EMERG;
372
 
        break;
373
 
        case TCN_LOG_ERROR:
374
 
            id = LOG_ERR;
375
 
        break;
376
 
        case TCN_LOG_NOTICE:
377
 
            id = LOG_NOTICE;
378
 
        break;
379
 
        case TCN_LOG_WARN:
380
 
            id = LOG_WARN;
381
 
        break;
382
 
        case TCN_LOG_INFO:
383
 
            id = LOG_INFO;
384
 
        break;
385
 
    }
386
 
    syslog (id, "%s", J2S(msg));
387
 
 
388
 
    TCN_FREE_CSTRING(msg);
389
 
}