summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorThe Android Open Source Project2008-12-17 20:08:08 -0600
committerThe Android Open Source Project2008-12-17 20:08:08 -0600
commit35237d135807af84bf9b0e5b8d7f8633e58db6f5 (patch)
treed8bcf3ada2182d248604728285dd80abb466f22a /init
parent4f6e8d7a00cbeda1e70cc15be9c4af1018bdad53 (diff)
downloadplatform-system-core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.tar.gz
platform-system-core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.tar.xz
platform-system-core-35237d135807af84bf9b0e5b8d7f8633e58db6f5.zip
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'init')
-rw-r--r--init/README.BOOTCHART44
-rw-r--r--init/bootchart.c73
-rw-r--r--init/bootchart.h36
-rw-r--r--init/builtins.c46
-rw-r--r--init/devices.c21
-rwxr-xr-xinit/grab-bootchart.sh4
-rw-r--r--init/init.c21
-rw-r--r--init/keywords.h2
-rw-r--r--init/parser.c1
-rw-r--r--init/property_service.c2
-rw-r--r--init/readme.txt3
11 files changed, 195 insertions, 58 deletions
diff --git a/init/README.BOOTCHART b/init/README.BOOTCHART
index 489936973..70cf2c39b 100644
--- a/init/README.BOOTCHART
+++ b/init/README.BOOTCHART
@@ -1,32 +1,50 @@
1this version of init contains code to perform "bootcharting", i.e. generating log 1This version of init contains code to perform "bootcharting", i.e. generating log
2files that can be later processed by the tools provided by www.bootchart.org. 2files that can be later processed by the tools provided by www.bootchart.org.
3 3
4to activate it, you need to define build 'init' with the INIT_BOOTCHART environment 4To activate it, you need to define build 'init' with the INIT_BOOTCHART environment
5variable defined to 'true', then create a file on the /data partition with a command 5variable defined to 'true', for example:
6like the following:
7 6
8 adb shell 'echo 1 > /data/bootchart' 7 touch system/init/init.c
8 m INIT_BOOTCHART=true
9 9
10if the '/data/bootchart' file doesn't exist, or doesn't contain a '1' in its first 10On the emulator, use the new -bootchart <timeout> option to boot with bootcharting
11byte, init will proceed normally. 11activated for <timeout> seconds.
12 12
13by default, the bootchart log stops after 2 minutes, but you can stop it earlier 13Otherwise, flash your device, and start it. Then create a file on the /data partition
14with the following command while the device is booting: 14with a command like the following:
15
16 adb shell 'echo $TIMEOUT > /data/bootchart-start'
17
18Where the value of $TIMEOUT corresponds to the wanted bootcharted period in seconds;
19for example, to bootchart for 2 minutes, do:
20
21 adb shell 'echo 120 > /data/bootchart-start'
22
23Reboot your device, bootcharting will begin and stop after the period you gave.
24You can also stop the bootcharting at any moment by doing the following:
15 25
16 adb shell 'echo 1 > /data/bootchart-stop' 26 adb shell 'echo 1 > /data/bootchart-stop'
17 27
18note that /data/bootchart-stop is deleted automatically by init at the end of the 28Note that /data/bootchart-stop is deleted automatically by init at the end of the
19bootcharting. this is not the case of /data/bootchart, so don't forget to delete it 29bootcharting. This is not the case of /data/bootchart-start, so don't forget to delete it
20when you're done collecting data: 30when you're done collecting data:
21 31
22 adb shell rm /data/bootchart 32 adb shell rm /data/bootchart-start
23 33
24the log files are placed in /tmp/bootchart/. you must run the script tools/grab-bootchart.sh 34The log files are placed in /data/bootchart/. you must run the script tools/grab-bootchart.sh
25which will use ADB to retrieve them and create a bootchart.tgz file that can be used with 35which will use ADB to retrieve them and create a bootchart.tgz file that can be used with
26the bootchart parser/renderer, or even uploaded directly to the form located at: 36the bootchart parser/renderer, or even uploaded directly to the form located at:
27 37
28 http://www.bootchart.org/download.html 38 http://www.bootchart.org/download.html
29 39
40NOTE: the bootchart.org webform doesn't seem to work at the moment, you can generate an
41 image on your machine by doing the following:
42
43 1/ download the sources from www.bootchart.org
44 2/ unpack them
45 3/ in the source directory, type 'ant' to build the bootchart program
46 4/ type 'java -jar bootchart.jar /path/to/bootchart.tgz
47
30technical note: 48technical note:
31 49
32this implementation of bootcharting does use the 'bootchartd' script provided by 50this implementation of bootcharting does use the 'bootchartd' script provided by
diff --git a/init/bootchart.c b/init/bootchart.c
index 2afe98b6b..f72fcaaca 100644
--- a/init/bootchart.c
+++ b/init/bootchart.c
@@ -1,3 +1,19 @@
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * 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
1/* this code is used to generate a boot sequence profile that can be used 17/* this code is used to generate a boot sequence profile that can be used
2 * with the 'bootchart' graphics generation tool. see www.bootchart.org 18 * with the 'bootchart' graphics generation tool. see www.bootchart.org
3 * note that unlike the original bootchartd, this is not a Bash script but 19 * note that unlike the original bootchartd, this is not a Bash script but
@@ -16,17 +32,18 @@
16#include <errno.h> 32#include <errno.h>
17#include <stdlib.h> 33#include <stdlib.h>
18#include <sys/stat.h> 34#include <sys/stat.h>
35#include "bootchart.h"
19 36
20#define VERSION "0.8" 37#define VERSION "0.8"
21#define SAMPLE_PERIOD 0.2 38#define SAMPLE_PERIOD 0.2
22#define LOG_ROOT "/tmp/bootchart" 39#define LOG_ROOT "/data/bootchart"
23#define LOG_STAT LOG_ROOT"/proc_stat.log" 40#define LOG_STAT LOG_ROOT"/proc_stat.log"
24#define LOG_PROCS LOG_ROOT"/proc_ps.log" 41#define LOG_PROCS LOG_ROOT"/proc_ps.log"
25#define LOG_DISK LOG_ROOT"/proc_diskstats.log" 42#define LOG_DISK LOG_ROOT"/proc_diskstats.log"
26#define LOG_HEADER LOG_ROOT"/header" 43#define LOG_HEADER LOG_ROOT"/header"
27#define LOG_ACCT LOG_ROOT"/kernel_pacct" 44#define LOG_ACCT LOG_ROOT"/kernel_pacct"
28 45
29#define LOG_STARTFILE "/data/bootchart" 46#define LOG_STARTFILE "/data/bootchart-start"
30#define LOG_STOPFILE "/data/bootchart-stop" 47#define LOG_STOPFILE "/data/bootchart-stop"
31 48
32static int 49static int
@@ -54,12 +71,11 @@ proc_read(const char* filename, char* buff, size_t buffsize)
54 len = unix_read(fd, buff, buffsize-1); 71 len = unix_read(fd, buff, buffsize-1);
55 close(fd); 72 close(fd);
56 } 73 }
57 buff[len] = 0; 74 buff[len > 0 ? len : 0] = 0;
58 return len; 75 return len;
59} 76}
60 77
61#define FILE_BUFF_SIZE 65536 78#define FILE_BUFF_SIZE 65536
62#define FILE_BUFF_RESERVE (FILE_BUFF_SIZE - 4096)
63 79
64typedef struct { 80typedef struct {
65 int count; 81 int count;
@@ -81,7 +97,7 @@ file_buff_write( FileBuff buff, const void* src, int len )
81 int avail = sizeof(buff->data) - buff->count; 97 int avail = sizeof(buff->data) - buff->count;
82 if (avail > len) 98 if (avail > len)
83 avail = len; 99 avail = len;
84 100
85 memcpy( buff->data + buff->count, src, avail ); 101 memcpy( buff->data + buff->count, src, avail );
86 len -= avail; 102 len -= avail;
87 src = (char*)src + avail; 103 src = (char*)src + avail;
@@ -115,7 +131,7 @@ log_header(void)
115 time_t now_t = time(NULL); 131 time_t now_t = time(NULL);
116 struct tm now = *localtime(&now_t); 132 struct tm now = *localtime(&now_t);
117 strftime(date, sizeof(date), "%x %X", &now); 133 strftime(date, sizeof(date), "%x %X", &now);
118 134
119 out = fopen( LOG_HEADER, "w" ); 135 out = fopen( LOG_HEADER, "w" );
120 if (out == NULL) 136 if (out == NULL)
121 return; 137 return;
@@ -123,7 +139,7 @@ log_header(void)
123 proc_read("/proc/cmdline", cmdline, sizeof(cmdline)); 139 proc_read("/proc/cmdline", cmdline, sizeof(cmdline));
124 proc_read("/proc/version", uname, sizeof(uname)); 140 proc_read("/proc/version", uname, sizeof(uname));
125 proc_read("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo)); 141 proc_read("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo));
126 142
127 cpu = strchr( cpuinfo, ':' ); 143 cpu = strchr( cpuinfo, ':' );
128 if (cpu) { 144 if (cpu) {
129 char* p = strchr(cpu, '\n'); 145 char* p = strchr(cpu, '\n');
@@ -131,7 +147,7 @@ log_header(void)
131 if (p) 147 if (p)
132 *p = 0; 148 *p = 0;
133 } 149 }
134 150
135 fprintf(out, "version = %s\n", VERSION); 151 fprintf(out, "version = %s\n", VERSION);
136 fprintf(out, "title = Boot chart for Android ( %s )\n", date); 152 fprintf(out, "title = Boot chart for Android ( %s )\n", date);
137 fprintf(out, "system.uname = %s\n", uname); 153 fprintf(out, "system.uname = %s\n", uname);
@@ -174,7 +190,6 @@ do_log_uptime(FileBuff log)
174 fd = open("/proc/uptime",O_RDONLY); 190 fd = open("/proc/uptime",O_RDONLY);
175 if (fd >= 0) { 191 if (fd >= 0) {
176 int ret; 192 int ret;
177 close_on_exec(fd);
178 ret = unix_read(fd, buff, 64); 193 ret = unix_read(fd, buff, 64);
179 close(fd); 194 close(fd);
180 buff[64] = 0; 195 buff[64] = 0;
@@ -212,7 +227,7 @@ do_log_file(FileBuff log, const char* procfile)
212 ret = unix_read(fd, buff, sizeof(buff)); 227 ret = unix_read(fd, buff, sizeof(buff));
213 if (ret <= 0) 228 if (ret <= 0)
214 break; 229 break;
215 230
216 file_buff_write(log, buff, ret); 231 file_buff_write(log, buff, ret);
217 if (ret < (int)sizeof(buff)) 232 if (ret < (int)sizeof(buff))
218 break; 233 break;
@@ -230,7 +245,7 @@ do_log_procs(FileBuff log)
230 struct dirent* entry; 245 struct dirent* entry;
231 246
232 do_log_uptime(log); 247 do_log_uptime(log);
233 248
234 while ((entry = readdir(dir)) != NULL) { 249 while ((entry = readdir(dir)) != NULL) {
235 /* only match numeric values */ 250 /* only match numeric values */
236 char* end; 251 char* end;
@@ -241,7 +256,7 @@ do_log_procs(FileBuff log)
241 char cmdline[1024]; 256 char cmdline[1024];
242 int len; 257 int len;
243 int fd; 258 int fd;
244 259
245 /* read command line and extract program name */ 260 /* read command line and extract program name */
246 snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid); 261 snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid);
247 proc_read(filename, cmdline, sizeof(cmdline)); 262 proc_read(filename, cmdline, sizeof(cmdline));
@@ -285,11 +300,36 @@ int bootchart_init( void )
285{ 300{
286 int ret; 301 int ret;
287 char buff[4]; 302 char buff[4];
288 303 int timeout = 0, count = 0;
304
289 buff[0] = 0; 305 buff[0] = 0;
290 proc_read( LOG_STARTFILE, buff, sizeof(buff) ); 306 proc_read( LOG_STARTFILE, buff, sizeof(buff) );
291 if (buff[0] != '1') 307 if (buff[0] != 0) {
292 return -1; 308 timeout = atoi(buff);
309 }
310 else {
311 /* when running with emulator, androidboot.bootchart=<timeout>
312 * might be passed by as kernel parameters to specify the bootchart
313 * timeout. this is useful when using -wipe-data since the /data
314 * partition is fresh
315 */
316 char cmdline[1024];
317 char* s;
318#define KERNEL_OPTION "androidboot.bootchart="
319 proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) );
320 s = strstr(cmdline, KERNEL_OPTION);
321 if (s) {
322 s += sizeof(KERNEL_OPTION)-1;
323 timeout = atoi(s);
324 }
325 }
326 if (timeout == 0)
327 return 0;
328
329 if (timeout > BOOTCHART_MAX_TIME_SEC)
330 timeout = BOOTCHART_MAX_TIME_SEC;
331
332 count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS;
293 333
294 do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR); 334 do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR);
295 335
@@ -307,7 +347,7 @@ int bootchart_init( void )
307 } 347 }
308 348
309 log_header(); 349 log_header();
310 return 0; 350 return count;
311} 351}
312 352
313/* called each time you want to perform a bootchart sampling op */ 353/* called each time you want to perform a bootchart sampling op */
@@ -324,6 +364,7 @@ int bootchart_step( void )
324 return -1; 364 return -1;
325 } 365 }
326 } 366 }
367
327 return 0; 368 return 0;
328} 369}
329 370
diff --git a/init/bootchart.h b/init/bootchart.h
new file mode 100644
index 000000000..39d2d4f20
--- /dev/null
+++ b/init/bootchart.h
@@ -0,0 +1,36 @@
1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * 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#ifndef _BOOTCHART_H
18#define _BOOTCHART_H
19
20#ifndef BOOTCHART
21# define BOOTCHART 0
22#endif
23
24#if BOOTCHART
25
26extern int bootchart_init(void);
27extern int bootchart_step(void);
28extern void bootchart_finish(void);
29
30# define BOOTCHART_POLLING_MS 200 /* polling period in ms */
31# define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */
32# define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */
33
34#endif /* BOOTCHART */
35
36#endif /* _BOOTCHART_H */
diff --git a/init/builtins.c b/init/builtins.c
index ba344100c..95fb22304 100644
--- a/init/builtins.c
+++ b/init/builtins.c
@@ -64,7 +64,7 @@ static int write_file(const char *path, const char *value)
64 } 64 }
65} 65}
66 66
67static int insmod(const char *filename) 67static int insmod(const char *filename, char *options)
68{ 68{
69 void *module; 69 void *module;
70 unsigned size; 70 unsigned size;
@@ -74,7 +74,7 @@ static int insmod(const char *filename)
74 if (!module) 74 if (!module)
75 return -1; 75 return -1;
76 76
77 ret = init_module(module, size, ""); 77 ret = init_module(module, size, options);
78 78
79 free(module); 79 free(module);
80 80
@@ -172,9 +172,35 @@ int do_ifup(int nargs, char **args)
172 return __ifupdown(args[1], 1); 172 return __ifupdown(args[1], 1);
173} 173}
174 174
175
176static int do_insmod_inner(int nargs, char **args, int opt_len)
177{
178 char options[opt_len + 1];
179 int i;
180
181 options[0] = '\0';
182 if (nargs > 2) {
183 strcpy(options, args[2]);
184 for (i = 3; i < nargs; ++i) {
185 strcat(options, " ");
186 strcat(options, args[i]);
187 }
188 }
189
190 return insmod(args[1], options);
191}
192
175int do_insmod(int nargs, char **args) 193int do_insmod(int nargs, char **args)
176{ 194{
177 return insmod(args[1]); 195 int i;
196 int size = 0;
197
198 if (nargs > 2) {
199 for (i = 2; i < nargs; ++i)
200 size += strlen(args[i]) + 1;
201 }
202
203 return do_insmod_inner(nargs, args, size);
178} 204}
179 205
180int do_import(int nargs, char **args) 206int do_import(int nargs, char **args)
@@ -326,6 +352,20 @@ int do_symlink(int nargs, char **args)
326 return symlink(args[1], args[2]); 352 return symlink(args[1], args[2]);
327} 353}
328 354
355int do_sysclktz(int nargs, char **args)
356{
357 struct timezone tz;
358
359 if (nargs != 2)
360 return -1;
361
362 memset(&tz, 0, sizeof(tz));
363 tz.tz_minuteswest = atoi(args[1]);
364 if (settimeofday(NULL, &tz))
365 return -1;
366 return 0;
367}
368
329int do_write(int nargs, char **args) 369int do_write(int nargs, char **args)
330{ 370{
331 return write_file(args[1], args[2]); 371 return write_file(args[1], args[2]);
diff --git a/init/devices.c b/init/devices.c
index 7aea24623..f86eab991 100644
--- a/init/devices.c
+++ b/init/devices.c
@@ -98,9 +98,12 @@ static struct perms_ devperms[] = {
98 /* these should not be world writable */ 98 /* these should not be world writable */
99 { "/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 }, 99 { "/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 },
100 { "/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 }, 100 { "/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 },
101 { "/dev/ttyMSM0", 0660, AID_BLUETOOTH, AID_BLUETOOTH, 0 }, 101 /* TODO: remove legacy ttyMSM0 */
102 { "/dev/ttyMSM0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
103 { "/dev/ttyHS0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
104 { "/dev/uinput", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 },
102 { "/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 }, 105 { "/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 },
103 { "/dev/tty0", 0666, AID_ROOT, AID_SYSTEM, 0 }, 106 { "/dev/tty0", 0660, AID_ROOT, AID_SYSTEM, 0 },
104 { "/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 }, 107 { "/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 },
105 { "/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 }, 108 { "/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 },
106 { "/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 }, 109 { "/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 },
@@ -360,29 +363,29 @@ static void handle_device_event(struct uevent *uevent)
360 return; 363 return;
361 364
362 /* are we block or char? where should we live? */ 365 /* are we block or char? where should we live? */
363 if(!strncmp(uevent->path, "/block", 6)) { 366 if(!strncmp(uevent->subsystem, "block", 5)) {
364 block = 1; 367 block = 1;
365 base = "/dev/block/"; 368 base = "/dev/block/";
366 mkdir(base, 0755); 369 mkdir(base, 0755);
367 } else { 370 } else {
368 block = 0; 371 block = 0;
369 /* this should probably be configurable somehow */ 372 /* this should probably be configurable somehow */
370 if(!strncmp(uevent->path, "/class/graphics/", 16)) { 373 if(!strncmp(uevent->subsystem, "graphics", 8)) {
371 base = "/dev/graphics/"; 374 base = "/dev/graphics/";
372 mkdir(base, 0755); 375 mkdir(base, 0755);
373 } else if (!strncmp(uevent->path, "/class/oncrpc/", 14)) { 376 } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) {
374 base = "/dev/oncrpc/"; 377 base = "/dev/oncrpc/";
375 mkdir(base, 0755); 378 mkdir(base, 0755);
376 } else if (!strncmp(uevent->path, "/class/adsp/", 12)) { 379 } else if (!strncmp(uevent->subsystem, "adsp", 4)) {
377 base = "/dev/adsp/"; 380 base = "/dev/adsp/";
378 mkdir(base, 0755); 381 mkdir(base, 0755);
379 } else if(!strncmp(uevent->path, "/class/input/", 13)) { 382 } else if(!strncmp(uevent->subsystem, "input", 5)) {
380 base = "/dev/input/"; 383 base = "/dev/input/";
381 mkdir(base, 0755); 384 mkdir(base, 0755);
382 } else if(!strncmp(uevent->path, "/class/mtd/", 11)) { 385 } else if(!strncmp(uevent->subsystem, "mtd", 3)) {
383 base = "/dev/mtd/"; 386 base = "/dev/mtd/";
384 mkdir(base, 0755); 387 mkdir(base, 0755);
385 } else if(!strncmp(uevent->path, "/class/misc/", 12) && 388 } else if(!strncmp(uevent->subsystem, "misc", 4) &&
386 !strncmp(name, "log_", 4)) { 389 !strncmp(name, "log_", 4)) {
387 base = "/dev/log/"; 390 base = "/dev/log/";
388 mkdir(base, 0755); 391 mkdir(base, 0755);
diff --git a/init/grab-bootchart.sh b/init/grab-bootchart.sh
index 57c955688..7fe890436 100755
--- a/init/grab-bootchart.sh
+++ b/init/grab-bootchart.sh
@@ -9,13 +9,13 @@ TMPDIR=/tmp/android-bootchart
9rm -rf $TMPDIR 9rm -rf $TMPDIR
10mkdir -p $TMPDIR 10mkdir -p $TMPDIR
11 11
12LOGROOT=/tmp/bootchart 12LOGROOT=/data/bootchart
13TARBALL=bootchart.tgz 13TARBALL=bootchart.tgz
14 14
15FILES="header proc_stat.log proc_ps.log proc_diskstats.log kernel_pacct" 15FILES="header proc_stat.log proc_ps.log proc_diskstats.log kernel_pacct"
16 16
17for f in $FILES; do 17for f in $FILES; do
18 adb pull $LOGROOT/$f $TMPDIR/$f &> /dev/null 18 adb pull $LOGROOT/$f $TMPDIR/$f 2>&1 > /dev/null
19done 19done
20(cd $TMPDIR && tar -czf $TARBALL $FILES) 20(cd $TMPDIR && tar -czf $TARBALL $FILES)
21cp -f $TMPDIR/$TARBALL ./$TARBALL 21cp -f $TMPDIR/$TARBALL ./$TARBALL
diff --git a/init/init.c b/init/init.c
index f6e9b398b..361684095 100644
--- a/init/init.c
+++ b/init/init.c
@@ -43,21 +43,12 @@
43#include "devices.h" 43#include "devices.h"
44#include "init.h" 44#include "init.h"
45#include "property_service.h" 45#include "property_service.h"
46 46#include "bootchart.h"
47#ifndef BOOTCHART
48# define BOOTCHART 0
49#endif
50 47
51static int property_triggers_enabled = 0; 48static int property_triggers_enabled = 0;
52 49
53#if BOOTCHART 50#if BOOTCHART
54static int bootchart_count; 51static int bootchart_count;
55extern int bootchart_init(void);
56extern int bootchart_step(void);
57extern void bootchart_finish(void);
58# define BOOTCHART_POLLING_MS 200 /* polling period in ms */
59# define BOOTCHART_MAX_TIME_MS (2*60*1000) /* max polling time from boot */
60# define BOOTCHART_MAX_COUNT (BOOTCHART_MAX_TIME_MS/BOOTCHART_POLLING_MS)
61#endif 52#endif
62 53
63static char console[32]; 54static char console[32];
@@ -834,11 +825,13 @@ int main(int argc, char **argv)
834 ufds[2].events = POLLIN; 825 ufds[2].events = POLLIN;
835 826
836#if BOOTCHART 827#if BOOTCHART
837 if (bootchart_init() < 0) 828 bootchart_count = bootchart_init();
829 if (bootchart_count < 0) {
838 ERROR("bootcharting init failure\n"); 830 ERROR("bootcharting init failure\n");
839 else { 831 } else if (bootchart_count > 0) {
840 NOTICE("bootcharting started\n"); 832 NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
841 bootchart_count = BOOTCHART_MAX_COUNT; 833 } else {
834 NOTICE("bootcharting ignored\n");
842 } 835 }
843#endif 836#endif
844 837
diff --git a/init/keywords.h b/init/keywords.h
index f09bad242..058996e3b 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -19,6 +19,7 @@ int do_start(int nargs, char **args);
19int do_stop(int nargs, char **args); 19int do_stop(int nargs, char **args);
20int do_trigger(int nargs, char **args); 20int do_trigger(int nargs, char **args);
21int do_symlink(int nargs, char **args); 21int do_symlink(int nargs, char **args);
22int do_sysclktz(int nargs, char **args);
22int do_write(int nargs, char **args); 23int do_write(int nargs, char **args);
23int do_chown(int nargs, char **args); 24int do_chown(int nargs, char **args);
24int do_chmod(int nargs, char **args); 25int do_chmod(int nargs, char **args);
@@ -60,6 +61,7 @@ enum {
60 KEYWORD(stop, COMMAND, 1, do_stop) 61 KEYWORD(stop, COMMAND, 1, do_stop)
61 KEYWORD(trigger, COMMAND, 1, do_trigger) 62 KEYWORD(trigger, COMMAND, 1, do_trigger)
62 KEYWORD(symlink, COMMAND, 1, do_symlink) 63 KEYWORD(symlink, COMMAND, 1, do_symlink)
64 KEYWORD(sysclktz, COMMAND, 1, do_sysclktz)
63 KEYWORD(user, OPTION, 0, 0) 65 KEYWORD(user, OPTION, 0, 0)
64 KEYWORD(write, COMMAND, 2, do_write) 66 KEYWORD(write, COMMAND, 2, do_write)
65 KEYWORD(chown, COMMAND, 2, do_chown) 67 KEYWORD(chown, COMMAND, 2, do_chown)
diff --git a/init/parser.c b/init/parser.c
index 95bf01791..a51691be2 100644
--- a/init/parser.c
+++ b/init/parser.c
@@ -183,6 +183,7 @@ int lookup_keyword(const char *s)
183 if (!strcmp(s, "tart")) return K_start; 183 if (!strcmp(s, "tart")) return K_start;
184 if (!strcmp(s, "top")) return K_stop; 184 if (!strcmp(s, "top")) return K_stop;
185 if (!strcmp(s, "ymlink")) return K_symlink; 185 if (!strcmp(s, "ymlink")) return K_symlink;
186 if (!strcmp(s, "ysclktz")) return K_sysclktz;
186 break; 187 break;
187 case 't': 188 case 't':
188 if (!strcmp(s, "rigger")) return K_trigger; 189 if (!strcmp(s, "rigger")) return K_trigger;
diff --git a/init/property_service.c b/init/property_service.c
index 0bc403f63..7a6416b5e 100644
--- a/init/property_service.c
+++ b/init/property_service.c
@@ -343,7 +343,7 @@ void handle_property_set_fd(int fd)
343 socklen_t addr_size = sizeof(addr); 343 socklen_t addr_size = sizeof(addr);
344 socklen_t cr_size = sizeof(cr); 344 socklen_t cr_size = sizeof(cr);
345 345
346 if ((s = accept(fd, &addr, &addr_size)) < 0) { 346 if ((s = accept(fd, (struct sockaddr *) &addr, &addr_size)) < 0) {
347 return; 347 return;
348 } 348 }
349 349
diff --git a/init/readme.txt b/init/readme.txt
index 360a1b709..665090bad 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -194,6 +194,9 @@ stop <service>
194symlink <target> <path> 194symlink <target> <path>
195 Create a symbolic link at <path> with the value <target> 195 Create a symbolic link at <path> with the value <target>
196 196
197sysclktz <mins_west_of_gmt>
198 Set the system clock base (0 if system clock ticks in GMT)
199
197trigger <event> 200trigger <event>
198 Trigger an event. Used to queue an action from another 201 Trigger an event. Used to queue an action from another
199 action. 202 action.