diff options
author | jk7744.park <jk7744.park@samsung.com> | 2015-09-08 21:30:39 +0900 |
---|---|---|
committer | jk7744.park <jk7744.park@samsung.com> | 2015-09-08 21:30:39 +0900 |
commit | f66f61d6d5c9f9928f140ebfbda80284d1331529 (patch) | |
tree | dda135629da91b07d36b25d54258964c185144c7 | |
parent | 7253ef7586e0cc619b996566965a185f0c2a7cbc (diff) | |
download | system-plugin-common-f66f61d6d5c9f9928f140ebfbda80284d1331529.tar.gz system-plugin-common-f66f61d6d5c9f9928f140ebfbda80284d1331529.tar.bz2 system-plugin-common-f66f61d6d5c9f9928f140ebfbda80284d1331529.zip |
tizen 2.3.1 releasetizen_2.3.1_releasesubmit/tizen_2.3.1/20150915.072301tizen_2.3.1
53 files changed, 3599 insertions, 0 deletions
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1841508 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.[ch] whitespace=tab-in-indent,trailing-space diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7385704 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +*.a +*.cache +*.html +*.la +*.lo +*.log +*.o +*.plist +*.pyc +*.stamp +*.swp +*.trs +*~ +.deps/ +.dirstamp +.libs/ +Makefile.in +aclocal.m4 +config.h +config.h.in +config.log +config.status +configure +/Makefile +/TAGS @@ -0,0 +1 @@ +WaLyong Cho <walyong.cho@samsung.com> diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..cb7c5bc --- /dev/null +++ b/Makefile.am @@ -0,0 +1,384 @@ +ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS} + +SUBDIRS = . + +# legacy rc script dir +rcdir=$(sysconfdir)/rc.d + +# Inherit from systemd +systemdsysconfdir=$(sysconfdir)/systemd +systemconfigunitdir=$(systemdsysconfdir)/system +userconfigunitdir=$(systemdsysconfdir)/user +systemdignoreunitdir=$(systemdsysconfdir)/default-extra-dependencies +systemunitdir=$(rootprefix)/lib/systemd/system +userunitdir=$(prefix)/lib/systemd/user +udevlibexecdir=$(rootprefix)/lib/udev +udevhomedir=$(udevlibexecdir) +udevrulesdir=$(udevlibexecdir)/rules.d +if MOBILE +sysctldir=$(prefix)/lib/sysctl.d +endif + +# And these are the special ones for / +rootprefix=@rootprefix@ +rootbindir=$(rootprefix)/bin +rootlibexecdir=$(rootprefix)/lib/systemd + +if WITH_ENGMODE +engbindir=/opt/usr/devel/$(rootbindir) +endif + +if MOBILE +noinst_LTLIBRARIES = +noinst_DATA = +sysctl_DATA = +endif + +bin_SCRIPTS = +rc_SCRIPTS = +SCRIPT_IN_FILES = +sysconf_DATA = +systemdsysconf_DATA = +systemdignoreunit_DATA = +systemconfigunit_DATA = +systemunit_DATA = +udevrules_DATA = + +if WITH_ENGMODE +engbin_PROGRAMS = +endif + +if MOBILE +AM_CPPFLAGS = \ + -include $(top_builddir)/config.h \ + -I $(top_srcdir)/src \ + -I $(top_srcdir)/src/shared \ + $(OUR_CPPFLAGS) + +AM_CFLAGS = $(OUR_CFLAGS) +AM_LDFLAGS = $(OUR_LDFLAGS) +endif + +INSTALL_EXEC_HOOKS = +UNINSTALL_EXEC_HOOKS = + +SHUTDOWN_TARGET_WANTS = +LOCAL_FS_TARGET_WANTS = +BASIC_TARGET_WANTS = +SYSINIT_TARGET_WANTS = +SOCKETS_TARGET_WANTS = +TIMERS_TARGET_WANTS = +TIZEN_INIT_TARGET_WANTS = +TIZEN_BOOT_TARGET_WANTS = +TIZEN_SYSTEM_TARGET_WANTS = +TIZEN_RUNTIME_TARGET_WANTS = +MULTI_USER_TARGET_WANTS = +DEFAULT_TARGET_WANTS = +SYSCONF_LOCAL_FS_TARGET_WANTS = + +if MOBILE +GRAPHICAL_TARGET_WANTS = +endif + +install-target-wants-hook: + where=$(systemunitdir) && what="$(SHUTDOWN_TARGET_WANTS)" && wants=shutdown.target && $(add-wants) + where=$(systemunitdir) && what="$(LOCAL_FS_TARGET_WANTS)" && wants=local-fs.target && $(add-wants) + where=$(systemunitdir) && what="$(BASIC_TARGET_WANTS)" && wants=basic.target && $(add-wants) + where=$(systemunitdir) && what="$(MULTI_USER_TARGET_WANTS)" && wants=multi-user.target && $(add-wants) + where=$(systemunitdir) && what="$(SYSINIT_TARGET_WANTS)" && wants=sysinit.target && $(add-wants) + where=$(systemunitdir) && what="$(SOCKETS_TARGET_WANTS)" && wants=sockets.target && $(add-wants) + where=$(systemunitdir) && what="$(TIMERS_TARGET_WANTS)" && wants=timers.target && $(add-wants) + where=$(systemunitdir) && what="$(SLICES_TARGET_WANTS)" && wants=slices.target && $(add-wants) + where=$(systemunitdir) && what="$(TIZEN_INIT_TARGET_WANTS)" && wants=tizen-init.target && $(add-wants) + where=$(systemunitdir) && what="$(TIZEN_BOOT_TARGET_WANTS)" && wants=tizen-boot.target && $(add-wants) + where=$(systemunitdir) && what="$(TIZEN_SYSTEM_TARGET_WANTS)" && wants=tizen-system.target && $(add-wants) + where=$(systemunitdir) && what="$(TIZEN_RUNTIME_TARGET_WANTS)" && wants=tizen-runtime.target && $(add-wants) + where=$(systemunitdir) && what="$(TIZEN_RUNTIME_TARGET_WANTS)" && wants=tizen-runtime.target && $(add-wants) +if MOBILE + where=$(systemunitdir) && what="$(GRAPHICAL_TARGET_WANTS)" && wants=graphical.target && $(add-wants) +endif + where=$(systemunitdir) && what="$(DEFAULT_TARGET_WANTS)" && wants=default.target && $(add-wants) + where=$(systemconfigunitdir) && what="$(SYSCONF_LOCAL_FS_TARGET_WANTS)" && wants=local-fs.target && $(add-wants) + +define add-wants +[ -z "$$what" -o -z "$$where" ] || ( \ + dir=$(DESTDIR)$$where/$$wants.wants && \ + $(MKDIR_P) -m 0755 $$dir && \ + cd $$dir && \ + rm -f $$what && \ + for i in $$what; do $(LN_S) ../$$i . || exit $$? ; done ) +endef + +INSTALL_EXEC_HOOKS += \ + install-target-wants-hook + +# ------------------------------------------------------------------------------ +# AM_V_M4 = $(AM_V_M4_$(V)) +# AM_V_M4_ = $(AM_V_M4_$(AM_DEFAULT_VERBOSITY)) +# AM_V_M4_0 = @echo " M4 " $@; +# +# AM_V_XSLT = $(AM_V_XSLT_$(V)) +# AM_V_XSLT_ = $(AM_V_XSLT_$(AM_DEFAULT_VERBOSITY)) +# AM_V_XSLT_0 = @echo " XSLT " $@; +# +# AM_V_GPERF = $(AM_V_GPERF_$(V)) +# AM_V_GPERF_ = $(AM_V_GPERF_$(AM_DEFAULT_VERBOSITY)) +# AM_V_GPERF_0 = @echo " GPERF " $@; +# +# AM_V_LN = $(AM_V_LN_$(V)) +# AM_V_LN_ = $(AM_V_LN_$(AM_DEFAULT_VERBOSITY)) +# AM_V_LN_0 = @echo " LN " $@; + +# ------------------------------------------------------------------------------ +if MOBILE +bin_SCRIPTS += \ + scripts/change-booting-mode.sh \ + scripts/cleanup-storage.sh \ + scripts/tizen-fstrim-on-charge.sh + +systemunit_DATA += \ + units/check-mount.service \ + units/cleanup-storage.service \ + units/cleanup-storage.timer \ + units/ghost.service \ + units/init-conf.service \ + units/tizen-boot.target \ + units/tizen-fstrim-user.service \ + units/tizen-fstrim-user.timer \ + units/tizen-generate-env.service \ + units/tizen-init.target \ + units/tizen-init-check.service \ + units/tizen-init-done.service \ + units/tizen-initial-boot-done.service \ + units/tizen-journal-flush.service \ + units/tizen-readahead-collect.service \ + units/tizen-readahead-collect-stop.service \ + units/tizen-readahead-replay.service \ + units/tizen-runtime.target \ + units/tizen-system.target + +SYSINIT_TARGET_WANTS += \ + init-conf.service + +TIMERS_TARGET_WANTS += \ + cleanup-storage.timer + +BASIC_TARGET_WANTS += \ + cleanup-storage.service \ + tizen-generate-env.service \ + tizen-init-check.service + +TIZEN_INIT_TARGET_WANTS += \ + tizen-init-done.service \ + tizen-readahead-collect.service + +MULTI_USER_TARGET_WANTS += \ + ghost.service \ + tizen-boot.target \ + tizen-runtime.target \ + tizen-system.target + +GRAPHICAL_TARGET_WANTS += \ + tizen-fstrim-user.timer \ + tizen-initial-boot-done.service \ + tizen-journal-flush.service \ + tizen-readahead-replay.service + +udevrules_DATA += \ + rules/51-tizen-udev-default.rules +else +bin_SCRIPTS += \ + scripts/change-booting-mode.sh \ + scripts/tizen-fstrim-on-charge.sh + +systemunit_DATA += \ + units/check-mount.service \ + units/tizen-generate-env.service \ + units/tizen-readahead-collect.service \ + units/tizen-readahead-collect-stop.service \ + units/tizen-readahead-replay.service \ + units/tizen-fstrim-user.service \ + units/tizen-fstrim-user.timer \ + units/tizen-init.target \ + units/tizen-init-check.service \ + units/tizen-initial-boot-done.service \ + units/tizen-init-done.service + +BASIC_TARGET_WANTS += \ + tizen-generate-env.service \ + tizen-init-check.service + +TIZEN_INIT_TARGET_WANTS += \ + tizen-readahead-collect.service \ + tizen-init-done.service + +MULTI_USER_TARGET_WANTS += \ + tizen-readahead-replay.service + +DEFAULT_TARGET_WANTS += \ + tizen-fstrim-user.timer \ + tizen-initial-boot-done.service + +udevrules_DATA += \ + rules/51-tizen-udev-default.rules +endif + +systemdignoreunit_DATA += \ + conf/systemd/ignore-units + +TIZEN_SYSTEM_TARGET_WANTS += \ + check-mount.service + +if WITH_UDEVD_KILLER +systemunit_DATA += \ + units/systemd-udevd-kill.service \ + units/systemd-udevd-kill.timer + +if MOBILE +GRAPHICAL_TARGET_WANTS += \ + systemd-udevd-kill.timer +else +DEFAULT_TARGET_WANTS += \ + systemd-udevd-kill.timer +endif +endif + +if MOBILE +sysctl_DATA += \ + sysctl.d/50-tizen-default.conf +endif + +if WITH_WMREADY +systemunit_DATA += \ + units/wm_ready.service + +TIZEN_BOOT_TARGET_WANTS += \ + wm_ready.service +endif + +if MOBILE +sysconf_DATA += \ + src/ghost/ghost.conf + +ghost_SOURCES = \ + src/ghost/ghost.c + +ghost_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) + +bin_PROGRAMS = \ + ghost + +ghost_LDADD = \ + libsystem-plugin-shared.la \ + $(DBUS_LIBS) \ + $(GLIB_LIBS) \ + $(GIO_LIBS) + +# ------------------------------------------------------------------------------ +noinst_LTLIBRARIES += \ + libsystem-plugin-shared.la + +libsystem_plugin_shared_la_SOURCES = \ + src/shared/conf-parser.c \ + src/shared/conf-parser.h \ + src/shared/dbus-common.h \ + src/shared/fileio.c \ + src/shared/fileio.h \ + src/shared/macro.h \ + src/shared/systemd.c \ + src/shared/systemd.h \ + src/shared/util.c \ + src/shared/util.h + +libsystem_plugin_shared_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(DBUS_CFLAGS) \ + $(GLIB_CFLAGS) \ + $(GIO_CFLAGS) + +libsystem_plugin_shared_la_LIBADD = \ + $(DBUS_LIBS) +endif + +# ------------------------------------------------------------------------------ +substitutions = \ + '|rootlibexecdir=$(rootlibexecdir)|' \ + '|rootbindir=$(rootbindir)|' \ + '|bindir=$(bindir)|' \ + '|SYSTEMCTL=$(rootbindir)/systemctl|' \ + '|SYSTEMD_NOTIFY=$(rootbindir)/systemd-notify|' \ + '|systemdsysconfdir=$(systemdsysconfdir)|' \ + '|SYSTEM_CONFIG_UNIT_PATH=$(systemdsysconfdir)/system|' \ + '|USER_CONFIG_UNIT_PATH=$(systemdsysconfdir)/user|' \ + '|pkgdatadir=$(pkgdatadir)|' \ + '|systemunitdir=$(systemunitdir)|' \ + '|userunitdir=$(userunitdir)|' \ + '|systempresetdir=$(systempresetdir)|' \ + '|userpresetdir=$(userpresetdir)|' \ + '|udevhwdbdir=$(udevhwdbdir)|' \ + '|udevrulesdir=$(udevrulesdir)|' \ + '|catalogdir=$(catalogdir)|' \ + '|tmpfilesdir=$(tmpfilesdir)|' \ + '|sysctldir=$(sysctldir)|' \ + '|PACKAGE_VERSION=$(PACKAGE_VERSION)|' \ + '|PACKAGE_NAME=$(PACKAGE_NAME)|' \ + '|PACKAGE_URL=$(PACKAGE_URL)|' \ + '|RANDOM_SEED=$(localstatedir)/lib/random-seed|' \ + '|prefix=$(prefix)|' \ + '|exec_prefix=$(exec_prefix)|' \ + '|libdir=$(libdir)|' \ + '|includedir=$(includedir)|' \ + '|VERSION=$(VERSION)|' \ + '|rootprefix=$(rootprefix)|' \ + '|udevlibexecdir=$(udevlibexecdir)|' \ + '|SUSHELL=$(SUSHELL)|' \ + '|DEBUGTTY=$(DEBUGTTY)|' \ + '|KILL=$(KILL)|' \ + '|KMOD=$(KMOD)|' \ + '|MKDIR_P=$(MKDIR_P)|' \ + '|QUOTAON=$(QUOTAON)|' \ + '|QUOTACHECK=$(QUOTACHECK)|' \ + '|SYSTEM_SYSVINIT_PATH=$(sysvinitdir)|' \ + '|VARLOGDIR=$(varlogdir)|' \ + '|RC_LOCAL_SCRIPT_PATH_START=$(RC_LOCAL_SCRIPT_PATH_START)|' \ + '|RC_LOCAL_SCRIPT_PATH_STOP=$(RC_LOCAL_SCRIPT_PATH_STOP)|' \ + '|PYTHON=$(PYTHON)|' \ + '|PYTHON_BINARY=$(PYTHON_BINARY)|' \ + '|INITAILBOOT_DONE=$(INITAILBOOT_DONE)|' \ + '|INITIALIZE_DONE=$(INITIALIZE_DONE)|' \ + '|READAHEAD_DIR=$(READAHEAD_DIR)|' \ + '|DIRTY_WRITEBACK_CENTISECS=$(DIRTY_WRITEBACK_CENTISECS)|' + +SED_PROCESS = \ + $(AM_V_GEN)$(MKDIR_P) $(dir $@) && \ + $(SED) $(subst '|,-e 's|@,$(subst =,\@|,$(subst |',|g',$(substitutions)))) \ + < $< > $@ + +units/%: units/%.in Makefile + $(SED_PROCESS) + +%.rules: %.rules.in Makefile + $(SED_PROCESS) + +%.sh: %.sh.in Makefile + $(SED_PROCESS) + $(AM_V_GEN)chmod +x $@ + +if MOBILE +src/%: src/%.m4 + $(AM_V_at)$(MKDIR_P) $(dir $@) + $(AM_V_M4)$(M4) -P $(M4_DEFINES) < $< > $@ + +sysctl.d/%: sysctl.d/%.in Makefile + $(SED_PROCESS) +endif + +units/%: units/%.m4 Makefile + $(AM_V_M4)$(MKDIR_P) $(dir $@) + $(AM_V_M4)$(M4) -P $(M4_DEFINES) -DFOR_SYSTEM=1 < $< > $@ + +install-exec-hook: $(INSTALL_EXEC_HOOKS) @@ -0,0 +1,16 @@ +log: + +* There is no regular log api in this package. We need some of regular + log api or wrapper. + +ghost: + +* boottime check point is hard coded now. That should be configurable. + +* bootloader time is not ready yet. After that ghost have to generate + time that and sum of that and platform boot time. + +* ghost dir disk usage threshold should be configurable. + +* bootchart generate directory should be parsed by bootchart.conf. Now + it is hard coded to "/run/log". diff --git a/autogen.sh b/autogen.sh new file mode 100755 index 0000000..968bc8e --- /dev/null +++ b/autogen.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +set -e + +if [ -f .git/hooks/pre-commit.sample ] && [ ! -f .git/hooks/pre-commit ]; then + # This part is allowed to fail + cp -p .git/hooks/pre-commit.sample .git/hooks/pre-commit && \ + chmod +x .git/hooks/pre-commit && \ + echo "Activated pre-commit hook." || : +fi + +# README and INSTALL are required by automake, but may be deleted by +# clean up rules. to get automake to work, simply touch these here, +# they will be regenerated from their corresponding *.in files by +# ./configure anyway. +touch README INSTALL + +# Make sure m4 directory exist +mkdir -p m4 + +autoreconf --force --install --verbose || exit $? diff --git a/conf/systemd/ignore-units b/conf/systemd/ignore-units new file mode 100644 index 0000000..95062a1 --- /dev/null +++ b/conf/systemd/ignore-units @@ -0,0 +1,38 @@ +ac.service +alarm-server.service +boot-osp.service +check-mount.service +crash-daemon.service +csc-starter.service +dbus.service +factory-pretest.service +factory-reset.service +immvibed.service +indicator.service +irsc_util.service +launchpad-preload.service +messagebus.service +ode-server.service +opt-usr-fsck.service +osp-tmpdir-setup.service +pkgmgr_recovery.service +pulseaudio.service +qmuxd.service +qseecom_ready.service +recovery-update.service +reset-verify.service +rmt_storage.service +samsung-secure-storage.service +secure-storage.service +security-server.service +slp-pkgmgr.service +smack-rules.service +sound-server.service +starter.service +system-server.service +tee-qsee.service +telephony-daemon.service +time.service +wifi-module-check.service +wm_ready.service +wrt-security-daemon.service diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..cf97dd4 --- /dev/null +++ b/configure.ac @@ -0,0 +1,188 @@ +# -*- Autoconf -*- +# Process this file with autoconf to produce a configure script. + +AC_PREREQ([2.68]) +AC_INIT(system-plugin-common, 0.0.01, [BUG-REPORT-ADDRESS]) + +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_HEADERS([config.h]) + +AC_USE_SYSTEM_EXTENSIONS +AC_SYS_LARGEFILE +AC_PREFIX_DEFAULT([/usr]) +AM_INIT_AUTOMAKE([foreign]) + +LT_PREREQ(2.2) +LT_INIT([disable-static]) + +# Checks for programs. +AC_PROG_MKDIR_P +AC_PROG_LN_S +AC_PROG_SED +AC_PROG_GREP +AC_PROG_AWK +#AC_PROG_INSTALL + +AC_PROG_CC +AC_PROG_CC_C99 +AM_PROG_CC_C_O +AC_PROG_GCC_TRADITIONAL +AC_PATH_PROG([M4], [m4]) +M4_DEFINES= + +# ------------------------------------------------------------------------------ +AC_ARG_WITH([rootprefix], + AS_HELP_STRING([--with-rootprefix=DIR], + [rootfs directory prefix for config files and kernel modules]), + [], [with_rootprefix=${ac_default_prefix}]) +AC_SUBST([rootprefix], [$with_rootprefix]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([engmode], + AS_HELP_STRING([--enable-engmode], [disable engineer mode]), + [case "${enableval}" in + yes) with_engmode=yes ;; + no) with_engmode=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-engmode) ;; + esac], + with_engmode=yes) +if test "x$with_engmode" != "xno"; then + M4_DEFINES="$M4_DEFINES -DWITH_ENGMODE" +fi +AC_SUBST(WITH_ENGMODE) +AM_CONDITIONAL([WITH_ENGMODE], [test "x$with_engmode" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(initial-boot, + AS_HELP_STRING([--with-initialbootdone=PATH], + [tizen system initial boot done]), + [INITAILBOOT_DONE="$withval"], + [INITAILBOOT_DONE="/opt/etc/.initialboot_done"]) +AC_SUBST(INITAILBOOT_DONE) + +AC_ARG_WITH(need-initialized, + AS_HELP_STRING([--with-initializedone=PATH], + [tizen system need initialized done]), + [INITIALIZE_DONE="$withval"], + [INITIALIZE_DONE="/opt/etc/.initialize_done"]) +AC_SUBST(INITIALIZE_DONE) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(tizen-readahead, + AS_HELP_STRING([--with-tizenreadaheaddir=PATH], + [tizen readahead dir]), + [READAHEAD_DIR="$withval"], + [READAHEAD_DIR="/opt/etc"]) +AC_SUBST(READAHEAD_DIR) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([engmode2], + AS_HELP_STRING([--enable-engmode2], [disable engineer mode2]), + [case "${enableval}" in + yes) with_engmode2=yes ;; + no) with_engmode2=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-engmode2) ;; + esac], + with_engmode2=yes) +if test "x$with_engmode2" != "xno"; then + M4_DEFINES="$M4_DEFINES -DWITH_ENGMODE2" +fi +AC_SUBST(WITH_ENGMODE2) +AM_CONDITIONAL([WITH_ENGMODE2], [test "x$with_engmode2" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([udevd-killer], + AS_HELP_STRING([--enable-udevd-killer], + [install udevd killer service]), + [case "${enableval}" in + yes) enable_udevd_killer=yes ;; + no) enable_udevd_killer=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-udevd-killer) ;; + esac], + enable_udevd_killer=no) +AC_SUBST(WITH_UDEVD_KILLER) +AM_CONDITIONAL([WITH_UDEVD_KILLER], [test "x$enable_udevd_killer" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([mobile], + AS_HELP_STRING([--enable-mobile], + [enable mobile configuration]), + [case "${enableval}" in + yes) enable_mobile=yes ;; + no) enable_mobile=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-mobile) ;; + esac], + enable_mobile=no) +AC_SUBST(MOBILE) +AM_CONDITIONAL([MOBILE], [test "x$enable_mobile" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([wmready], + AS_HELP_STRING([--disable-wmready], [without window manager waiting]), + [case "${enableval}" in + yes) have_winmgr=yes ;; + no) have_winmgr=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --disable-wmready) ;; + esac], + have_winmgr=yes) +AC_SUBST(WITH_WMREADY) +AM_CONDITIONAL([WITH_WMREADY], [test "x$have_winmgr" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_ENABLE([frequent-fstrim], + AS_HELP_STRING([--enable-frequent-fstrim], + [use more frequently fstrim timer]), + [case "${enableval}" in + yes) enable_frequent_fstrim=yes ;; + no) enable_frequent_fstrim=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-frequent-fstrim) ;; + esac], + enable_frequent_fstrim=no) +if test "x$enable_frequent_fstrim" == "xyes"; then + M4_DEFINES="$M4_DEFINES -DWITH_FREQUENT_FSTRIM" +fi + +AC_SUBST(M4_DEFINES) +AC_SUBST(WITH_FREQUENT_FSTRIM) +AM_CONDITIONAL([WITH_FREQUENT_FSTRIM], [test "x$enable_frequent_fstrim" != xno]) + +# ------------------------------------------------------------------------------ +AC_ARG_WITH(dirty-writeback-centisecs, + AS_HELP_STRING([--with-dirty-writeback-centisecs=NUMBER], + [Path to /etc/rc.local]), + [DIRTY_WRITEBACK_CENTISECS="$withval"], + [DIRTY_WRITEBACK_CENTISECS="500"]) + +AC_DEFINE_UNQUOTED(DIRTY_WRITEBACK_CENTISECS, ["$DIRTY_WRITEBACK_CENTISECS"], [Path of /etc/rc.local script]) +AC_SUBST(DIRTY_WRITEBACK_CENTISECS) + +# ------------------------------------------------------------------------------ +PKG_CHECK_MODULES(DBUS, [dbus-1 >= 1.3.2]) +PKG_CHECK_MODULES(GLIB, [glib-2.0]) +PKG_CHECK_MODULES(GIO, [gio-2.0]) + +# ------------------------------------------------------------------------------ +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT +AC_MSG_RESULT([ + $PACKAGE_NAME $VERSION + + prefix: ${prefix} + rootprefix: ${with_rootprefix} + sysconf dir: ${sysconfdir} + datarootdir: ${datarootdir} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + initial boot done flag: ${INITAILBOOT_DONE} + inialized done flag: ${INITIALIZE_DONE} + + XATTR: ${have_xattr} + SMACK: ${have_smack} + + engineer mode: ${with_engmode} + window manager: ${have_winmgr} + udevd killer: ${enable_udevd_killer} + frequent fstrim: ${enable_frequent_fstrim} + enable mobile: ${enable_mobile} +]) diff --git a/packaging/system-plugin-common.manifest b/packaging/system-plugin-common.manifest new file mode 100644 index 0000000..93c2194 --- /dev/null +++ b/packaging/system-plugin-common.manifest @@ -0,0 +1,12 @@ +<manifest> + <request> + <domain name="_"/> + </request> + <assign> + <filesystem path="/bin/*" label="_" exec_label="none" /> + <filesystem path="/sbin/*" label="_" exec_label="none" /> + <filesystem path="/usr/bin/*" label="_" exec_label="none" /> + <filesystem path="/usr/sbin/*" label="_" exec_label="none" /> + <filesystem path="/etc/rc.d/*" label="_" exec_label="none" /> + </assign> +</manifest> diff --git a/packaging/system-plugin-common.spec b/packaging/system-plugin-common.spec new file mode 100644 index 0000000..cb66572 --- /dev/null +++ b/packaging/system-plugin-common.spec @@ -0,0 +1,179 @@ +########################### +# Default feature config. # +########################### + +# udev daemon killer unit +%define WITH_UDEVD_KILLER 0 +# If window manager exist then waiting unit will be installed. +%define WITH_WMREADY 1 + +%define WITH_FREQUENT_FSTRIM 0 + +%if "%{?tizen_profile_name}" == "wearable" +%define WITH_FREQUENT_FSTRIM 1 +%define dirty_writeback_centisecs 1000 +%endif + +Name: system-plugin-common +Summary: system common file of system +Version: 0.0.01 +Release: 1 +License: Apache-2.0 +Group: System/Base +ExclusiveArch: %arm +Source: %{name}-%{version}.tar.gz +Source1001: %{name}.manifest + +BuildRequires: autoconf +BuildRequires: automake +BuildRequires: libtool +BuildRequires: kernel-headers +BuildRequires: pkgconfig(dbus-1) +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(gio-2.0) + +Requires: e2fsprogs +Requires: /bin/grep +Requires: /usr/bin/awk +Requires: psmisc +Requires(post): coreutils + +%description +Startup files + +%prep +%setup -q + +%build +cp %{SOURCE1001} . + +./autogen.sh +%configure CFLAGS='-g -O0 -Werror' \ + --prefix=%{_prefix} \ +%if ! %{WITH_WMREADY} + --disable-wmready \ +%endif +%if %{WITH_UDEVD_KILLER} + --enable-udevd-killer \ +%endif +%if %{WITH_FREQUENT_FSTRIM} + --enable-frequent-fstrim \ +%endif +%if ("%{?dirty_writeback_centisecs}" != "") + --with-dirty-writeback-centisecs=%{dirty_writeback_centisecs} \ +%endif +%if "%{?tizen_profile_name}" == "mobile" + --enable-mobile +%endif + +make %{?_smp_mflags} + +%install +%make_install + +mkdir -p $RPM_BUILD_ROOT%{_datadir}/license +cat LICENSE > $RPM_BUILD_ROOT%{_datadir}/license/%{name} + +%if "%{?tizen_profile_name}" == "mobile" +mkdir -p %{buildroot}%{_libdir}/sysctl.d +mkdir -p %{buildroot}%{_sysconfdir} +touch %{buildroot}%{_sysconfdir}/machine-id +%endif + +%post +touch %{_sysconfdir}/ld.so.nohwcap + +%files +%defattr(-,root,root,-) +%{_datadir}/license/%{name} +%{_sysconfdir}/systemd/default-extra-dependencies/ignore-units +%{_bindir}/change-booting-mode.sh + +# systemd service units +%{_libdir}/systemd/system/tizen-generate-env.service +%{_libdir}/systemd/system/basic.target.wants/tizen-generate-env.service +%if %{WITH_WMREADY} +%{_libdir}/systemd/system/wm_ready.service +%{_libdir}/systemd/system/tizen-boot.target.wants/wm_ready.service +%endif +%{_libdir}/systemd/system/check-mount.service +%{_libdir}/systemd/system/tizen-system.target.wants/check-mount.service + +# system initialize units +%{_libdir}/systemd/system/tizen-init.target +%{_libdir}/systemd/system/tizen-init-check.service +%{_libdir}/systemd/system/basic.target.wants/tizen-init-check.service +%{_libdir}/systemd/system/tizen-init-done.service +%{_libdir}/systemd/system/tizen-init.target.wants/tizen-init-done.service +%{_libdir}/systemd/system/tizen-initial-boot-done.service + +# fstrim units +%{_bindir}/tizen-fstrim-on-charge.sh +%{_libdir}/systemd/system/tizen-fstrim-user.service +%{_libdir}/systemd/system/tizen-fstrim-user.timer + +# readahead units +%{_libdir}/systemd/system/tizen-readahead-collect.service +%{_libdir}/systemd/system/tizen-readahead-collect-stop.service +%{_libdir}/systemd/system/tizen-init.target.wants/tizen-readahead-collect.service +%{_libdir}/systemd/system/tizen-readahead-replay.service + +# udev daemon killer +%if %{WITH_UDEVD_KILLER} +%{_libdir}/systemd/system/systemd-udevd-kill.service +%{_libdir}/systemd/system/systemd-udevd-kill.timer + +%if "%{?tizen_profile_name}" == "mobile" +%{_libdir}/systemd/system/graphical.target.wants/systemd-udevd-kill.timer +%elseif "%{?tizen_profile_name}" == "wearable" +%{_libdir}/systemd/system/default.target.wants/systemd-udevd-kill.timer +%endif + +%endif +%manifest %{name}.manifest + +# mobile & wearable difference +%if "%{?tizen_profile_name}" == "mobile" +%{_libdir}/systemd/system/graphical.target.wants/tizen-initial-boot-done.service +%{_libdir}/systemd/system/graphical.target.wants/tizen-fstrim-user.timer +%{_libdir}/systemd/system/graphical.target.wants/tizen-readahead-replay.service +%elseif "%{?tizen_profile_name}" == "wearable" +%{_libdir}/systemd/system/default.target.wants/tizen-initial-boot-done.service +%{_libdir}/systemd/system/default.target.wants/tizen-fstrim-user.timer +%{_libdir}/systemd/system/multi-user.target.wants/tizen-readahead-replay.service +%endif + +%if "%{?tizen_profile_name}" == "mobile" +%ghost %config(noreplace) %{_sysconfdir}/machine-id + +%{_libdir}/udev/rules.d/51-tizen-udev-default.rules +%{_libdir}/systemd/system/tizen-boot.target +%{_libdir}/systemd/system/multi-user.target.wants/tizen-boot.target +%{_libdir}/systemd/system/tizen-system.target +%{_libdir}/systemd/system/multi-user.target.wants/tizen-system.target +%{_libdir}/systemd/system/tizen-runtime.target +%{_libdir}/systemd/system/multi-user.target.wants/tizen-runtime.target + +%config(noreplace) %{_sysconfdir}/ghost.conf +%{_bindir}/ghost +%{_libdir}/systemd/system/ghost.service +%{_libdir}/systemd/system/multi-user.target.wants/ghost.service + +# sysctl +%{_libdir}/sysctl.d/50-tizen-default.conf + +# cleanup storage +%{_bindir}/cleanup-storage.sh +%{_libdir}/systemd/system/basic.target.wants/cleanup-storage.service +%{_libdir}/systemd/system/timers.target.wants/cleanup-storage.timer +%{_libdir}/systemd/system/cleanup-storage.service +%{_libdir}/systemd/system/cleanup-storage.timer + +%{_libdir}/systemd/system/tizen-journal-flush.service +%{_libdir}/systemd/system/graphical.target.wants/tizen-journal-flush.service + +%{_libdir}/systemd/system/init-conf.service +%{_libdir}/systemd/system/sysinit.target.wants/init-conf.service +%elseif "%{?tizen_profile_name}" == "wearable" +%{_libdir}/udev/rules.d/51-tizen-udev-default.rules +%endif diff --git a/rules/51-tizen-udev-default.rules b/rules/51-tizen-udev-default.rules new file mode 100644 index 0000000..ed45cb6 --- /dev/null +++ b/rules/51-tizen-udev-default.rules @@ -0,0 +1,22 @@ +# Tizen specific additional rules + +SUBSYSTEM=="tty", KERNEL=="ptmx", SECLABEL{smack}="*" +SUBSYSTEM=="tty", KERNEL=="tty", SECLABEL{smack}="*" +SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", SECLABEL{smack}="*" +SUBSYSTEM=="vc", KERNEL=="vcs*|vcsa*", SECLABEL{smack}="*" +KERNEL=="tty[A-Z]*[0-9]|pppox[0-9]*|ircomm[0-9]*|noz[0-9]*|rfcomm[0-9]*", SECLABEL{smack}="*" + +# input +SUBSYSTEM=="input", KERNEL=="mouse*|mice|event*", GROUP="input", MODE="0660" + +# video +KERNEL=="mali", GROUP="video", SECLABEL{smack}="*" +KERNEL=="slp_global_lock", GROUP="video", SECLABEL{smack}="*" +SUBSYSTEM=="video4linux", SECLABEL{smack}="*" +SUBSYSTEM=="drm", SECLABEL{smack}="*" + +SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", SECLABEL{smack}="*" + +KERNEL=="fuse", SECLABEL{smack}="*" + +LABEL="tizen_default_permissions_end" diff --git a/scripts/change-booting-mode.sh b/scripts/change-booting-mode.sh new file mode 100644 index 0000000..2e67a92 --- /dev/null +++ b/scripts/change-booting-mode.sh @@ -0,0 +1,112 @@ +#!/bin/sh +# +# Copyright 2010 +# Read the file COPYING +# +# Authors: Yeongil Jang +# +# Copyright Samsung Electronics +# + +# print help message +do_help() +{ + /bin/cat >&2 <<EOF +change-booting-mode: usage: + -?/--help this message + --fota reboot for fota update (Firmware update On The Air) + --fus reboot for fus update (Firmware Update Service) + --update change system state for developer update +EOF +} + +# get and check specified options +do_options() +{ + # note: default settings have already been loaded + + while [ "$#" -ne 0 ] + do + arg=`/usr/bin/printf %s $1 | /bin/awk -F= '{print $1}'` + val=`/usr/bin/printf %s $1 | /bin/awk -F= '{print $2}'` + shift + if test -z "$val"; then + local possibleval=$1 + /usr/bin/printf %s $1 "$possibleval" | /bin/grep ^- >/dev/null 2>&1 + if test "$?" != "0"; then + val=$possibleval + if [ "$#" -ge 1 ]; then + shift + fi + fi + fi + + case "$arg" in + + --fota) + echo "Setting fota update mode" >&2 + STATUS_DIR=/opt/data/recovery + DELTA_PATH_FILE=${STATUS_DIR}/DELTA.PATH + if [ ! -d ${STATUS_DIR} ]; then + echo ">> ${STATUS_DIR} does not exist. create one" + if [ -f ${STATUS_DIR} ]; then + /bin/rm -f ${STATUS_DIR} + fi + /bin/mkdir -p ${STATUS_DIR} + fi + echo $val > ${DELTA_PATH_FILE} + cmd="fota" + ;; + --fus) + echo "Setting fus update mode" >&2 + cmd="download" + echo "kill mtp-ui, data-router" >> /opt/var/log/fus_update.log 2>&1 + /usr/bin/killall mtp-ui >> /opt/var/log/fus_update.log 2>&1 + /usr/bin/killall data-router >> /opt/var/log/fus_update.log 2>&1 + /bin/umount /dev/gadget >> /opt/var/log/fus_update.log 2>&1 + /sbin/lsmod >> /opt/var/log/fus_update.log 2>&1 + /sbin/rmmod g_samsung >> /opt/var/log/fus_update.log 2>&1 + ;; + --update) + echo "Setting update mode for engineers" >&2 +# echo 1 > /sys/power/noresume +# touch /opt/etc/.hib_capturing # make fastboot image again on next booting + /bin/mount -o remount,rw / + if [ -f /usr/share/usr_share_locale.squash ]; then + SIZE=`df | grep rootfs | awk '{print $4}'` + BLOCK=`du -c /usr/share/locale/ | grep total | awk '{print $1}'` + if [ $BLOCK -lt $SIZE ]; then + /bin/umount -l /usr/share/locale + /bin/rm -rf /usr/share/locale + /usr/bin/unsquashfs -d /usr/share/locale /usr/share/usr_share_locale.squash + /bin/rm -rf /usr/share/usr_share_locale.squash + /usr/bin/find /usr/share/locale -exec /usr/bin/chsmack -a _ {} \; + else + echo "Can NOT unsqaushfs because no space in rootfs" + fi + fi + exit + ;; + -?|--help) + do_help + exit 0 + ;; + *) + echo "Unknown option \"$arg\". See --help" >&2 + do_help + exit 0 + ;; + esac + done +} + +## main + +if test -z "$1"; then + do_help + exit 0 +fi + +do_options $@ +/bin/sync +/sbin/reboot $cmd diff --git a/scripts/cleanup-storage.sh b/scripts/cleanup-storage.sh new file mode 100644 index 0000000..bcbed99 --- /dev/null +++ b/scripts/cleanup-storage.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +BE_VERBOSE="false" +CAN_CLEANALL="false" +CLEANUP_DIR="/var/log" +THRESHOLD=90 +WHITE_LIST='! -name 'messages' ! -name 'dlog_main' ! -name 'dlog_system' ! -name 'dlog_radio' ! -name 'Xorg.0.log' ! -name 'system*'' + +function show_help { + echo " +clean up directory. + +usage: ${0##*/} [OPTION...] + -h, --help show help + -v, --verbose provide more detailed output + -f, --force forced clean all if clean failed + -d, --directory clean up directory (default: /var/log) + -t, --threshold clean up threshold (default: 80%) +" +} + +# Execute getopt +ARGS=$(getopt -o hvfd:t: -l "help,verbose,force,directory:threshold:" -n "$0" -- "$@"); + +eval set -- "$ARGS"; + +while true; do + case "$1" in + -h|--help) + show_help >&2 + exit 0 + ;; + -v|--verbose) + BE_VERBOSE="true" + shift + ;; + -f|--force) + CAN_CLEANALL="true" + shift + ;; + -d|--directory) + CLEANUP_DIR=$2 + shift 2 + ;; + -t|--threshold) + THRESHOLD=$2 + shift 2 + re='^[0-9]+$' + if ! [[ $THRESHOLD =~ $re ]] ; then + echo "error: threshold value($THRESHOLD) not a number" >&2 + exit 1 + fi + ;; + --) + shift; + break; + ;; + esac +done + +if [ $# -ne 0 ]; then + show_help >&2 + exit 1 +fi + +function get_status { + DF_RESULT=$(/bin/df $CLEANUP_DIR) + PERCENT=$(IFS=; echo $DF_RESULT | /bin/awk 'NR==2 {print $5}') + PERCENT_N=${PERCENT%\%} + MOUNT_POINT=$(IFS=; echo $DF_RESULT | /bin/awk 'NR==2 {print $6}') + + if [ "z$BE_VERBOSE" == "ztrue" ]; then + echo "+++ Status of $CLEANUP_DIR +++" + echo "Use%: $PERCENT, Mounted at:$MOUNT_POINT" + fi +} + +function clean_up { + get_status + if [ $PERCENT_N -gt $THRESHOLD ];then + if [ "z$BE_VERBOSE" == "ztrue" ]; then + echo "Do clean up" + fi + /usr/bin/find $CLEANUP_DIR -type f $WHITE_LIST -exec /bin/rm -f {} \; + fi + return 0 +} + +clean_up +if [ $? -ne 0 ];then + echo "clean up failed" +fi diff --git a/scripts/tizen-boot.sh.in b/scripts/tizen-boot.sh.in new file mode 100644 index 0000000..e9f974a --- /dev/null +++ b/scripts/tizen-boot.sh.in @@ -0,0 +1,112 @@ +#!/bin/sh + +TIZEN_LABEL="tizen" + +function do_ext4 { + EMMC_DEVICE="/dev/mmcblk0" + RET_PARTX=$(/usr/sbin/partx -s ${EMMC_DEVICE}) + ROOTFS_PART=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | /bin/awk 'tolower($6) == "rootfs" {print $1}') + SYSTEM_DATA_PART=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | /bin/awk 'tolower($6) == "system-data" {print $1}') + USER_PART=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | /bin/awk 'tolower($6) == "user" {print $1}') + CSC_PART=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | /bin/awk 'tolower($6) == "csc" {print $1}') + MODULES_PART=${EMMC_DEVICE}p$(IFS=; echo $RET_PARTX | /bin/awk 'tolower($6) == "module" {print $1}') + + # rootfs partition + PART_LABEL="$(/sbin/e2label $ROOTFS_PART)" + if [ "z${PART_LABEL}" != "z${TIZEN_LABEL}" ]; then + /bin/mount -o remount,rw / + /sbin/resize2fs -f $ROOTFS_PART + /bin/mount -o remount,ro / + /sbin/e2label $ROOTFS_PART $TIZEN_LABEL + fi + + # system-data partition + PART_LABEL="$(/sbin/e2label $SYSTEM_DATA_PART)" + if [ "z${PART_LABEL}" != "z${TIZEN_LABEL}" ]; then + /bin/grep "$SYSTEM_DATA_PART" /proc/mounts || /sbin/e2fsck -y -f "$SYSTEM_DATA_PART" + /sbin/resize2fs -f $SYSTEM_DATA_PART + if [ $? -ne 0 ]; then + /sbin/e2fsck -y -f $SYSTEM_DATA_PART + /sbin/resize2fs -f $SYSTEM_DATA_PART + fi + /sbin/e2label $SYSTEM_DATA_PART $TIZEN_LABEL + fi + + # CSC partition + PART_LABEL="$(/sbin/e2label $CSC_PART)" + if [ "z${PART_LABEL}" != "z${TIZEN_LABEL}" ]; then + /bin/grep "$CSC_PART" /proc/mounts || /sbin/e2fsck -y -f "$CSC_PART" + /sbin/resize2fs -f $CSC_PART + if [ $? -ne 0 ]; then + /sbin/e2fsck -y -f $CSC_PART + /sbin/resize2fs -f $CSC_PART + fi + /sbin/e2label $CSC_PART $TIZEN_LABEL + fi + + # user partition + PART_LABEL="$(/sbin/e2label $USER_PART)" + if [ "z${PART_LABEL}" != "z${TIZEN_LABEL}" ]; then + /bin/grep "$USER_PART" /proc/mounts || /sbin/e2fsck -y -f "$USER_PART" + /sbin/resize2fs -f $USER_PART + if [ $? -ne 0 ]; then + /sbin/e2fsck -y -f $USER_PART + /sbin/resize2fs -f $USER_PART + fi + /sbin/e2label $USER_PART $TIZEN_LABEL + fi + + # Mount system-data(/opt) partition. + if [ "z$SYSTEM_DATA_PART" != "z${EMMC_DEVICE}p" ]; then + /sbin/e2fsck -y -f $SYSTEM_DATA_PART + /bin/mount -t $FS_TYPE $SYSTEM_DATA_PART /opt -o errors=panic,nosuid + # If /opt partition is not mounted by crashing file system, + # then check partition using e2fsck and re-mount it. + if [ $? -ne 0 ]; then + /sbin/e2fsck -y -f $SYSTEM_DATA_PART + /bin/mount -t $FS_TYPE $SYSTEM_DATA_PART /opt -o errors=panic,nosuid + fi + fi + + # Mount modules(/lib/modules) partition. + if [ "z$MODULES_PART" != "z${EMMC_DEVICE}p" ]; then + /bin/mount -t $FS_TYPE $MODULES_PART /lib/modules -o ro & + fi +} + +function do_ubi { + UBI_DEVICE="ubi0" + ROOTFS_PART=${UBI_DEVICE}:rootfs + SYSTEM_DATA_PART=${UBI_DEVICE}:systemData + USER_PART=${UBI_DEVICE}:user + CSC_PART=${UBI_DEVICE}:csc + MODULES_PART=${UBI_DEVICE}:module + + # Mount system-data(/opt) partition. + /bin/mount -t $FS_TYPE $SYSTEM_DATA_PART /opt -o rw +} + +# !!! Start from here !!! +if [ ! -e /etc/machine-id ]; then + /bin/mount -o remount,rw / + /usr/bin/systemd-machine-id-setup + /bin/mount -o remount,ro / +fi + +for arg in $(/bin/cat /proc/cmdline); do + case "$arg" in + rootfstype=*) + FS_TYPE="${arg//rootfstype=}" + break; + ;; + esac +done + +case $FS_TYPE in + ext4) + do_ext4; + ;; + ubifs) + do_ubi; + ;; +esac diff --git a/scripts/tizen-fstrim-on-charge.sh b/scripts/tizen-fstrim-on-charge.sh new file mode 100644 index 0000000..9aab820 --- /dev/null +++ b/scripts/tizen-fstrim-on-charge.sh @@ -0,0 +1,21 @@ +#!/bin/sh + +if [ "$#" -ne 1 ];then + echo "Argument was missed." + exit 1 +fi + +CHARGE_NOW_FILE=`/usr/bin/find /sys/devices -path */power_supply/battery/charge_now` +if [ "x$CHARGE_NOW_FILE" == "x" ]; then + echo "Can not find 'charge_now'." + exit 1 +else + CHARGE_NOW_VALUE=`/bin/cat $CHARGE_NOW_FILE` +fi + +if [ "$CHARGE_NOW_VALUE" -gt 0 ];then + echo "Do fstrim." + /sbin/fstrim $* +else + echo "Not on charging." +fi diff --git a/src/ghost/ghost.c b/src/ghost/ghost.c new file mode 100644 index 0000000..e9d0bc0 --- /dev/null +++ b/src/ghost/ghost.c @@ -0,0 +1,656 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <dirent.h> +#include <fcntl.h> +#include <limits.h> +#include <assert.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include "util.h" +#include "fileio.h" +#include "conf-parser.h" +#include "systemd.h" + +#define GHOST_CONF "/etc/ghost.conf" +#define GHOST_DIR "/var/log/ghost" +#define GHOST_BOOT_DIR GHOST_DIR "/boot" +#define GHOST_BOOTCOUNT GHOST_BOOT_DIR "/bootcount" +#define GHOST_LINK_CURRENT GHOST_BOOT_DIR "/current" + +#define GHOST_CURRENT_BOOTTIME GHOST_LINK_CURRENT "/boottime" +#define GHOST_CURRENT_PLOTCHART GHOST_LINK_CURRENT "/plotchart.svg" + +#define GHOST_TIME_OUT 120 + +#define GHOST_THRESHOLD_DISK_USAGE_RATIO 3 + +int bootcount; +int ghost_mask; +bool arg_boottime = true; +bool arg_bootchart = false; +bool arg_plotchart = false; + +enum GhostMask { + MASK_BOOTTIME = 0, + MASK_PLOTCHART, + MASK_BOOTCHART, +}; + +static int parse_config_file(void) { + const ConfigTableItem items[] = { + { "Ghost", "boottime", config_parse_bool, 0, &arg_boottime }, + { "Ghost", "plotchart", config_parse_bool, 0, &arg_plotchart }, + { "Ghost", "bootchart", config_parse_bool, 0, &arg_bootchart }, + { NULL, NULL, NULL, 0, NULL } + }; + + int r; + + r = config_parse(GHOST_CONF, (void*) items); + if (r < 0) { + fprintf(stderr, "Failed to parse configuration file: %s\n", strerror(-r)); + return r; + } + + return 0; +} + +static int get_bootcount_from_file(int *count) { + _cleanup_free_ char *s = NULL; + int r; + + r = read_one_line_file(GHOST_BOOTCOUNT, &s); + if (r < 0 && errno != ENOENT) + return r; + + *count = (s) ? atoi(s) : 0; + return 0; +} + +static int get_bootcount_from_dir(int *count) { + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *de; + int c = 0; + + dir = opendir(GHOST_BOOT_DIR); + if (!dir) + return errno; + + FOREACH_DIRENT(de, dir, return -errno) { + if (de->d_type != DT_DIR) + continue; + + c = atoi(de->d_name) > c ? atoi(de->d_name) : c; + } + + *count = c; + return 0; +} + +static int update_bootcount(void) { + _cleanup_free_ char *count = NULL; + int r, from_dir = 0, from_file = 0; + + r = get_bootcount_from_file(&from_file); + if (r < 0) + return r; + + r = get_bootcount_from_dir(&from_dir); + if (r < 0) + return r; + + bootcount = from_file > from_dir ? from_file : from_dir; + + r = asprintf(&count, "%d", ++bootcount); + if (r < 0) + return r; + + r = write_string_file(GHOST_BOOTCOUNT, count); + if (r < 0) + return r; + + return 0; +} + + +struct df_info { + char device[30]; + int blocks; + int used; + int available; + int use_ratio; + char mount_on[PATH_MAX]; +}; + +#define GHOST_CURRENT_DISKINFO GHOST_LINK_CURRENT "/diskinfo" + +static void ghost_parse_df_info(struct df_info *info, char *buf) { + char *p = buf; + char t[30]; + size_t len; + + /* Filesystem */ + len = strcspn(p, WHITESPACE); + snprintf(info->device, len+1, "%s", p); + p += len + strspn(p+len, WHITESPACE); + + /* 1K-blocks */ + len = strcspn(p, WHITESPACE); + snprintf(t, len+1, "%s", p); + info->blocks = atoi(t); + p += len + strspn(p+len, WHITESPACE); + + /* Used */ + len = strcspn(p, WHITESPACE); + snprintf(t, len+1, "%s", p); + info->used = atoi(t); + p += len + strspn(p+len, WHITESPACE); + + /* Available */ + len = strcspn(p, WHITESPACE); + snprintf(t, len+1, "%s", p); + info->available = atoi(t); + p += len + strspn(p+len, WHITESPACE); + + /* Use% */ + len = strcspn(p, WHITESPACE); + snprintf(t, len, "%s", p); + info->use_ratio = atoi(t); + p += len + strspn(p+len, WHITESPACE); + + /* Mounted on */ + len = strcspn(p, NEWLINE); + snprintf(info->mount_on, len+1, "%s", p); +} + +static int ghost_get_disk_info(struct df_info *info) { + int pipefd[2]; + int status; + int r; + + pipe(pipefd); + if(fork() == 0) { + char * const args[] = {"/bin/df", GHOST_DIR, NULL}; + + close(pipefd[0]); + dup2(pipefd[1], 1); + dup2(pipefd[1], 2); + usleep(1000); + execvp(args[0], args); + + close(pipefd[1]); + _exit(1); + } else { + char buf[LINE_MAX*2]; + char *p = buf; + + close(pipefd[1]); + wait(&status); + if (!WIFEXITED(status)) + return -WEXITSTATUS(status); + + /* size of buf maybe bigger than df output */ + r = read(pipefd[0], buf, sizeof(buf)); + if (r < 0) + return -errno; + + /* discard first line */ + p += strcspn(p, NEWLINE)+1; + truncate_nl(p); + + ghost_parse_df_info(info, p); + } + + return 0; +} + +static int ghost_get_disk_usage(int *usage) { + int pipefd[2]; + int status; + int r; + + pipe(pipefd); + if(fork() == 0) { + char * const args[] = {"/usr/bin/du", "-s", GHOST_DIR, NULL}; + + close(pipefd[0]); + dup2(pipefd[1], 1); + dup2(pipefd[1], 2); + usleep(1000); + execvp(args[0], args); + + close(pipefd[1]); + _exit(1); + } else { + char buf[LINE_MAX]; + + close(pipefd[1]); + wait(&status); + if (!WIFEXITED(status)) + return -WEXITSTATUS(status); + + /* size of buf maybe bigger than du output */ + r = read(pipefd[0], buf, sizeof(buf)); + if (r < 0) + return -errno; + + buf[strcspn(buf, WHITESPACE)] = 0; + *usage = atoi(buf); + } + + return 0; +} + +static gint sort_num_str_by_ascending(gconstpointer a, gconstpointer b) { + return atoi(a) - atoi(b); +} + +static int generate_dir_list(GList **list, DIR *dir) { + struct dirent *de; + GList *l = NULL; + + FOREACH_DIRENT(de, dir, goto out) { + if (de->d_type != DT_DIR) + continue; + + l = g_list_prepend(l, de->d_name); + } + + l = g_list_sort(l, sort_num_str_by_ascending); + *list = l; + return 0; + +out: + if (l) + g_list_free(l); + return -errno; +} + +static int check_threshhold(void) { + _cleanup_closedir_ DIR *dir = NULL; + _cleanup_free_ struct df_info *df = NULL; + int r, usage; + GList *list = NULL, *head = NULL; + + df = new0(struct df_info, 1); + r = ghost_get_disk_info(df); + if (r < 0) { + fprintf(stderr, "Failed to get disk info\n"); + return r; + } + + r = ghost_get_disk_usage(&usage); + if (r < 0) { + fprintf(stderr, "Failed to get disk usage\n"); + return r; + } + + if ((usage * 100 / df->blocks) < GHOST_THRESHOLD_DISK_USAGE_RATIO) + return 0; + + dir = opendir(GHOST_BOOT_DIR); + if (!dir) { + fprintf(stderr, "Failed to open dir: %s", GHOST_BOOT_DIR); + return -errno; + } + + r = generate_dir_list(&list, dir); + if (r < 0) + goto finish; + + do { + _cleanup_free_ char *path = NULL; + + head = g_list_first(list); + r = asprintf(&path, "%s/%s", GHOST_BOOT_DIR, (char *)head->data); + if (r < 0) + goto finish; + + r = rmdir_recursive(path); + if (r < 0) { + fprintf(stderr, "Failed to delete directory: %s\n", dir); + r = -errno; + goto finish; + } + + list = g_list_remove(list, list->data); + + r = ghost_get_disk_usage(&usage); + if (r < 0) { + fprintf(stderr, "Failed to get disk usage\n"); + goto finish; + } + } while((usage * 100 / df->blocks) >= GHOST_THRESHOLD_DISK_USAGE_RATIO); + + r = 0; +finish: + g_list_free(list); + return r; +} + +static int prepare_working_dir(void) { + _cleanup_free_ char *path = NULL, *count = NULL; + int r; + + r = asprintf(&path, "%s/%d", GHOST_BOOT_DIR, bootcount); + if (r < 0) + return r; + + r = mkdir(path, 0755); + if (r < 0) + return -errno; + + r = unlink(GHOST_LINK_CURRENT); + if (r < 0 && errno != ENOENT) + return -errno; + + r = asprintf(&count, "%d", bootcount); + if (r < 0) + return r; + + r = symlink(count, GHOST_LINK_CURRENT); + if (r < 0) + return -errno; + + return 0; +} + +static int set_loopmask(void) { + int mask = 0; + + return mask = + (arg_boottime ? (0x01) << MASK_BOOTTIME : 0x00) | + (arg_plotchart ? (0x01) << MASK_PLOTCHART : 0x00) | + (arg_bootchart ? (0x01) << MASK_BOOTCHART : 0x00); +} + +static int get_boottime_checkpoint(void) { + _cleanup_free_ char *result = NULL, *active_state = NULL, *platform_sec = NULL; + unsigned int exec_main_pid = 0, main_pid = 0; + unsigned long long inactive_enter_timestamp_monotonic, exec_main_exit_timestamp_monotonic; + int r, exec_main_code = 0; + + if (!(ghost_mask & 0x01 << MASK_BOOTTIME)) + return 0; + + r = systemd_get_unit_property_as_string("boot-animation.service", + "ActiveState", + &active_state); + if (r < 0) + return -r; + + r = systemd_get_unit_property_as_uint64("boot-animation.service", + "InactiveEnterTimestampMonotonic", + &inactive_enter_timestamp_monotonic); + if (r < 0) + return -r; + + r = systemd_get_service_property_as_string("boot-animation.service", + "Result", + &result); + if (r < 0) + return -r; + + if (streq(active_state, "inactive") && + inactive_enter_timestamp_monotonic != 0 && + streq(result, "success")) { + ghost_mask &= ~(0x01 << MASK_BOOTTIME); + r = systemd_get_service_property_as_uint64("boot-animation.service", + "ExecMainExitTimestampMonotonic", + &exec_main_exit_timestamp_monotonic); + if (r < 0) + return -r; + + r = asprintf(&platform_sec, "platform(sec): %.2lf", + ((float)(exec_main_exit_timestamp_monotonic/1000)/1000)); + if (r < 0) + return r; + + r = write_string_file(GHOST_CURRENT_BOOTTIME, platform_sec); + if (r < 0) + return r; + } + + return 0; +} + +static int ghost_processing_plotchart(void) { + _cleanup_free_ char *active_state = NULL; + pid_t my_pid, parent_pid, child_pid; + int r, status; + unsigned int jobs; + + if (!(ghost_mask & 0x01 << MASK_PLOTCHART)) + return 0; + + r = systemd_get_unit_property_as_string("default.target", + "ActiveState", + &active_state); + if (r < 0) + return -r; + + if (!streq(active_state, "active")) + return 0; + + r = systemd_get_manager_property_as_uint32(DBUS_INTERFACE_SYSTEMD_MANAGER, + "NJobs", + &jobs); + if (r < 0) + return -r; + + if (jobs) + return 0; + + if((child_pid = fork()) < 0 ) { + perror("fork failure"); + exit(1); + } + + if(child_pid == 0) { + char * const args[] = {"/usr/bin/systemd-analyze", "plot", NULL}; + int fd = open(GHOST_CURRENT_PLOTCHART, O_RDWR | O_CREAT, 0644); + + if (fd < 0) + _exit(EXIT_FAILURE); + + dup2(fd, 1); + execvp(args[0], args); + + close(fd); + _exit(1); + } else { + wait(&status); + + if (WIFEXITED(status)) + ghost_mask &= ~(0x01 << MASK_PLOTCHART); + } + return 0; +} + +static bool is_bootchart_set_as_init(void) { + _cleanup_free_ char *cmdline = NULL; + char *w, *state; + size_t l; + bool contained = false; + int r; + + if (read_one_line_file("/proc/cmdline", &cmdline) < 0) { + fprintf(stderr, "Failed to read /proc/cmdline.\n"); + return false; + } + + FOREACH_WORD(w, l, cmdline, state) + if (strneq("init=/usr/lib/systemd/systemd-bootchart", w, l)) + return true; + + return false; +} + +static int ghost_processing_bootchart(pid_t bootchart_pid) { + _cleanup_free_ char *proc_pid = NULL, *bootchart_path = NULL; + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *de; + int r; + + if (!(ghost_mask & 0x01 << MASK_BOOTCHART)) + return 0; + + /* If bootchart_pid is 0, then maybe ghost is started after + * bootchart had finished. So safe and goto copy. */ + if (bootchart_pid == 0) + goto copy_bootchart; + + r = asprintf(&proc_pid, "/proc/%d", bootchart_pid); + if (r < 0) + return r; + + /* Do NOT be confused for the return check. We hope the + * bootchart is finished to get the result. So its process id + * should be disappeared. */ + r = access(proc_pid, F_OK); + if (r == 0) + return 0; + + if (r < 0 && + errno != ENOENT) + return -errno; + +copy_bootchart: + dir = opendir("/run/log"); + if (!dir) + return -errno; + + FOREACH_DIRENT(de, dir, return -errno) { + if (de->d_type != DT_REG) + continue; + + if (startswith(de->d_name, "bootchart-")) { + r = asprintf(&bootchart_path, "/run/log/%s", de->d_name); + if (r < 0) + continue; + + r = do_copy(bootchart_path, GHOST_LINK_CURRENT, NULL); + if (r < 0) { + fprintf(stderr, "Failed to copy bootchart.\n"); + continue; + } + } + } + + ghost_mask &= ~(0x01 << MASK_BOOTCHART); + return 0; +} + +static int ghost_loop(void) { + int sec = 0; + int r; + bool do_bootchart; + pid_t pid_of_bootchart; + + do_bootchart = is_bootchart_set_as_init(); + if (do_bootchart) + pid_of_bootchart = pid_of("systemd-bootchart"); + else + ghost_mask &= ~(0x01 << MASK_BOOTCHART); + + while (ghost_mask) { + /* check boot-animation finished */ + r = get_boottime_checkpoint(); + if (r < 0) + return r; + + /* check booting completed(default.target) */ + r = ghost_processing_plotchart(); + if (r < 0) + return r; + + /* If init=/usr/lib/systemd/systemd-bootchar is + * contained at kernel command line then the bootchart + * will be copied to ghost current working + * directory. */ + if(do_bootchart) { + r = ghost_processing_bootchart(pid_of_bootchart); + if (r < 0) + return r; + } + + sleep(1); + if (sec++ > GHOST_TIME_OUT) { + fprintf(stderr, "ghost loop time(almost %dsec) over.\n", + GHOST_TIME_OUT); + break; + } + } + + return 0; +} + +int main(int argc, char *argv[]) { + int r; + + r = parse_config_file(); + if (r < 0) + return r; + + if (do_mkdir(GHOST_BOOT_DIR, 0755) && errno != EEXIST) { + fprintf(stderr, "Failed to create ghost directory: %s\n", GHOST_BOOT_DIR); + return -errno; + } + + /* boot count update */ + r = update_bootcount(); + if (r < 0) { + fprintf(stderr, "Failed to update bootcount: %s\n", strerror(-r)); + return r; + } else + fprintf(stdout, "[Ghost] Now, %d%s boot.\n", + bootcount, + bootcount == 1 ? "st" : + bootcount == 2 ? "nd" : + bootcount == 3 ? "rd" : "th"); + + r = check_threshhold(); + if (r < 0) { + fprintf(stderr, "Failed to check threshold: %s\n", strerror(-r)); + return r; + } + + r = prepare_working_dir(); + if (r < 0) { + fprintf(stderr, "Failed to make current boot dir: %s\n", strerror(-r)); + return r; + } + + ghost_mask = set_loopmask(); + r = ghost_loop(); + if (r < 0) + return r; + + return 0; +} diff --git a/src/ghost/ghost.conf.m4 b/src/ghost/ghost.conf.m4 new file mode 100644 index 0000000..5815921 --- /dev/null +++ b/src/ghost/ghost.conf.m4 @@ -0,0 +1,10 @@ +[Ghost] +m4_ifdef(`WITH_ENGMODE', +`#output=<folder name, defaults to /var/log/ghost> +boottime=y +plotchart=y +bootchart=y', +`#output=<folder name, defaults to /var/log/ghost> +#boottime=y +#plotchart=n +#bootchart=n') diff --git a/src/shared/conf-parser.c b/src/shared/conf-parser.c new file mode 100644 index 0000000..5f38eee --- /dev/null +++ b/src/shared/conf-parser.c @@ -0,0 +1,243 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <assert.h> +#include <stdbool.h> +#include <limits.h> + +#include "util.h" +#include "conf-parser.h" + +#define MAX_SECTION 64 + +static int config_table_lookup( + void *table, + const char *section, + const char *lvalue, + ConfigParserCallback *func, + int *ltype, + void **data) { + + ConfigTableItem *t; + + assert(table); + assert(lvalue); + assert(func); + assert(ltype); + assert(data); + + for (t = table; t->lvalue; t++) { + + if (!streq(lvalue, t->lvalue)) + continue; + + if (!streq_ptr(section, t->section)) + continue; + + *func = t->cb; + *ltype = t->ltype; + *data = t->data; + return 1; + } + + return 0; +} + +/* Run the user supplied parser for an assignment */ +static int config_parse_table( + const char *filename, + unsigned line, + void *table, + const char *section, + const char *lvalue, + const char *rvalue) { + + ConfigParserCallback cb = NULL; + int ltype = 0; + void *data = NULL; + int r; + + assert(filename); + assert(section); + assert(lvalue); + assert(rvalue); + + r = config_table_lookup(table, + section, + lvalue, + &cb, + <ype, + &data); + if (r <= 0) + return r; + + if (cb) + return cb(filename, + line, + section, + lvalue, + ltype, + rvalue, + data); + + return 0; +} + +int config_parse( + const char *filename, + void *table) { + + _cleanup_fclose_ FILE *f = NULL; + char *sections[MAX_SECTION] = { 0 }; + char *section = NULL, *n, *e, l[LINE_MAX]; + size_t len; + int i, r, num_section = 0; + bool already; + unsigned line = 0; + + assert(filename); + + f = fopen(filename, "r"); + if (!f) { + fprintf(stderr, "Error: Failed to open file %s\n", filename); + return -errno; + } + + while (!feof(f)) { + _cleanup_free_ char *lvalue = NULL, *rvalue = NULL; + + if (fgets(l, LINE_MAX, f) == NULL) { + if (feof(f)) + break; + + fprintf(stderr, "Error: Failed to parse configuration file '%s': %m\n", filename); + r = -errno; + goto finish; + } + + line++; + truncate_nl(l); + + if (strchr(COMMENTS NEWLINE, *l)) + continue; + + if (*l == '[') { + len = strlen(l); + if (l[len-1] != ']') { + fprintf(stderr, "Error: Invalid section header: %s\n", l); + r = -EBADMSG; + goto finish; + } + + n = strndup(l+1, len-2); + if (!n) { + r = -ENOMEM; + goto finish; + } + + already = false; + for (i = 0; i < num_section; i++) { + if (streq(n, sections[i])) { + section = sections[i]; + already = true; + free(n); + break; + } + } + + if (already) + continue; + + section = n; + sections[num_section] = n; + num_section++; + if (num_section > MAX_SECTION) { + fprintf(stderr, "Error: max number of section reached: %d\n", num_section); + r = -EOVERFLOW; + goto finish; + } + + continue; + } + + if (!section) + continue; + + e = strchr(l, '='); + if (e == NULL) { + fprintf(stderr, "Warning: config: no '=' character in line '%s'.\n", l); + continue; + } + + lvalue = strndup(l, e-l); + strstrip(lvalue); + + rvalue = strdup(e+1); + strstrip(rvalue); + + r = config_parse_table(filename, + line, + table, + section, + lvalue, + rvalue); + if (r < 0) + goto finish; + } + + r = 0; + +finish: + for (i=0; i<num_section; i++) + if (sections[i]) + free(sections[i]); + + return r; +} + +int config_parse_bool( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data) { + + int k; + bool *b = data; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(data); + + k = parse_boolean(rvalue); + if (k < 0) { + fprintf(stderr, "Failed to parse boolean value, ignoring: %s\n", rvalue); + return 0; + } + + *b = !!k; + return 0; +} diff --git a/src/shared/conf-parser.h b/src/shared/conf-parser.h new file mode 100644 index 0000000..9ccfc08 --- /dev/null +++ b/src/shared/conf-parser.h @@ -0,0 +1,62 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <stdio.h> +#include <stdbool.h> + +/* Prototype for a parser for a specific configuration setting */ +typedef int (*ConfigParserCallback)( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data); + +/* Wraps information for parsing a specific configuration variable, to + * be stored in a simple array */ +typedef struct ConfigTableItem { + const char *section; /* Section */ + const char *lvalue; /* Name of the variable */ + ConfigParserCallback cb; /* Function that is called to + * parse the variable's + * value */ + int ltype; /* Distinguish different + * variables passed to the + * same callback */ + void *data; /* Where to store the + * variable's data */ +} ConfigTableItem; + +int config_parse( + const char *filename, + void *table); + +int config_parse_bool( + const char *filename, + unsigned line, + const char *section, + const char *lvalue, + int ltype, + const char *rvalue, + void *data); diff --git a/src/shared/dbus-common.h b/src/shared/dbus-common.h new file mode 100644 index 0000000..387f961 --- /dev/null +++ b/src/shared/dbus-common.h @@ -0,0 +1,27 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <dbus/dbus.h> + +#define DBUS_INTERFACE_DBUS_PROPERTIES DBUS_SERVICE_DBUS ".Properties" +#define DBUS_INTERFACE_DBUS_PEER DBUS_SERVICE_DBUS ".Peer" +#define DBUS_INTERFACE_DBUS_INTROSPECTABLE DBUS_SERVICE_DBUS ".Introspectable" diff --git a/src/shared/fileio.c b/src/shared/fileio.c new file mode 100644 index 0000000..83ef0b6 --- /dev/null +++ b/src/shared/fileio.c @@ -0,0 +1,90 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <string.h> +#include <assert.h> +#include <errno.h> +#include <limits.h> + +#include "fileio.h" +#include "util.h" + +int write_string_to_file(FILE *f, const char *line) { + errno = 0; + fputs(line, f); + if (!endswith(line, "\n")) + fputc('\n', f); + + fflush(f); + + if (ferror(f)) + return errno ? -errno : -EIO; + + return 0; +} + +int write_string_file(const char *fn, const char *line) { + _cleanup_fclose_ FILE *f = NULL; + + assert(fn); + assert(line); + + f = fopen(fn, "we"); + if (!f) + return -errno; + + return write_string_to_file(f, line); +} + +int read_one_line_from_file(FILE *f, char **line) { + char t[LINE_MAX], *c; + + errno = 0; + + if (!fgets(t, sizeof(t), f)) { + + if (ferror(f)) + return errno ? -errno : -EIO; + + t[0] = 0; + } + + c = strdup(t); + if (!c) + return -ENOMEM; + + *line = truncate_nl(c); + return 0; +} + +int read_one_line_file(const char *fn, char **line) { + _cleanup_fclose_ FILE *f = NULL; + char t[LINE_MAX], *c; + + assert(fn); + assert(line); + + f = fopen(fn, "re"); + if (!f) + return -errno; + + return read_one_line_from_file(f, line); +} diff --git a/src/shared/fileio.h b/src/shared/fileio.h new file mode 100644 index 0000000..1713535 --- /dev/null +++ b/src/shared/fileio.h @@ -0,0 +1,28 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <stdio.h> + +int write_string_to_file(FILE *f, const char *line); +int write_string_file(const char *fn, const char *line); +int read_one_line_from_file(FILE *f, char **line); +int read_one_line_file(const char *fn, char **line); diff --git a/src/shared/macro.h b/src/shared/macro.h new file mode 100644 index 0000000..5770d4b --- /dev/null +++ b/src/shared/macro.h @@ -0,0 +1,24 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#define _pure_ __attribute__ ((pure)) +#define _cleanup_(x) __attribute__((cleanup(x))) diff --git a/src/shared/systemd.c b/src/shared/systemd.c new file mode 100644 index 0000000..c484095 --- /dev/null +++ b/src/shared/systemd.c @@ -0,0 +1,229 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stdio.h> +#include <gio/gio.h> + +#include "util.h" +#include "dbus-common.h" +#include "systemd.h" + +#define SYSTEMD_UNIT_OBJ_PATH_PREFIX "/org/freedesktop/systemd1/unit/" +#define SYSTEMD_UNIT_ESCAPE_CHAR ".-" + +static char *get_systemd_unit_obj_path(const char* unit) { + char *path = NULL; + int i, j; + size_t p, k, prefix_len, unit_len = strlen(unit); + + for (i=0, p=0; p<unit_len; i++) { + k = strcspn(unit+p, SYSTEMD_UNIT_ESCAPE_CHAR); + p += k+1; + } + + prefix_len = strlen(SYSTEMD_UNIT_OBJ_PATH_PREFIX); + /* assume we try to get object path of foo-bar.service then + * the object path will be + * "/org/freedesktop/systemd1/unit/foo_2dbar_2eservice\n". In + * this case we can find two escape characters, so the total + * length will be: + * (PREFIX_length) + (unit_length - escape + 3*escape) + NULL */ + path = new0(char, + prefix_len + + (unit_len - (i-1)) + ((i-1) * 3 * sizeof(char)) + + 1); + strncpy(path, SYSTEMD_UNIT_OBJ_PATH_PREFIX, prefix_len+1); + + for (j=0, p=0; j < i; j++) { + k = strcspn(unit+p, SYSTEMD_UNIT_ESCAPE_CHAR); + strncpy(path+prefix_len, unit+p, k); + if (k < strlen(unit+p)) { + sprintf(path+prefix_len+k, "_%x", *(unit+p+k) & 0xff); + prefix_len += k+3; + p += k+1; + } + } + + return path; +} + +static int systemd_get_property(GBusType type, + const char *name, + const char *path, + const char *iface, + const char *method, + const char *interface, + const char *property, + GVariant **variant) { + + GDBusConnection *connection; + GVariant *gvar; + GError *error; + GDBusProxy *proxy; + +#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36) + g_type_init (); +#endif + + error = NULL; + proxy = g_dbus_proxy_new_for_bus_sync(type ? G_BUS_TYPE_SYSTEM : G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + name, + path, + iface, + NULL, /* GCancellable */ + &error); + + if (proxy == NULL) { + g_printerr("Error creating proxy: %s\n", error->message); + g_error_free(error); + return -1; + } + + error = NULL; + gvar = g_dbus_proxy_call_sync(proxy, + method, + g_variant_new ("(ss)", + interface, + property), + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, /* GCancellable */ + &error); + + g_assert_no_error(error); + g_assert(gvar != NULL); + *variant = gvar; + g_clear_error (&error); + g_object_unref(proxy); + + return 0; +} + +int systemd_get_manager_property(const char *iface, + const char *property, + GVariant **variant) { + + return systemd_get_property(G_BUS_TYPE_SYSTEM, + DBUS_SYSTEMD_DEST, + DBUS_SYSTEMD_ADDRESS, + DBUS_INTERFACE_DBUS_PROPERTIES, + "Get", + iface, + property, + variant); +} + +int systemd_get_unit_property(const char *unit, + const char *property, + GVariant **variant) { + + _cleanup_free_ char *systemd_unit_obj_path; + + systemd_unit_obj_path = get_systemd_unit_obj_path(unit); + + return systemd_get_property(G_BUS_TYPE_SYSTEM, + DBUS_SYSTEMD_DEST, + systemd_unit_obj_path, + DBUS_INTERFACE_DBUS_PROPERTIES, + "Get", + DBUS_INTERFACE_SYSTEMD_UNIT, + property, + variant); +} + +int systemd_get_service_property(const char *unit, + const char *property, + GVariant **variant) { + + _cleanup_free_ char *systemd_unit_obj_path; + + systemd_unit_obj_path = get_systemd_unit_obj_path(unit); + + return systemd_get_property(G_BUS_TYPE_SYSTEM, + DBUS_SYSTEMD_DEST, + systemd_unit_obj_path, + DBUS_INTERFACE_DBUS_PROPERTIES, + "Get", + DBUS_INTERFACE_SYSTEMD_SERVICE, + property, + variant); +} + +typedef unsigned int uint; +typedef long long int64; +typedef unsigned long long uint64; + +#define g_variant_type_int32 G_VARIANT_TYPE_INT32 +#define g_variant_type_int64 G_VARIANT_TYPE_INT64 +#define g_variant_type_uint32 G_VARIANT_TYPE_UINT32 +#define g_variant_type_uint64 G_VARIANT_TYPE_UINT64 +#define g_variant_type_string G_VARIANT_TYPE_STRING + +#define g_variant_get_function_int32(v) g_variant_get_int32(v) +#define g_variant_get_function_int64(v) g_variant_get_int64(v) +#define g_variant_get_function_uint32(v) g_variant_get_uint32(v) +#define g_variant_get_function_uint64(v) g_variant_get_uint64(v) +#define g_variant_get_function_string(v) g_variant_dup_string(v, NULL) + +#define DEFINE_SYSTEMD_GET_PROPERTY(iface, type, value) \ + int systemd_get_##iface##_property_as_##type( \ + const char* target, \ + const char* property, \ + value* result) { \ + \ + GVariant *var; \ + GVariant *inner; \ + int r; \ + \ + r = systemd_get_##iface##_property(target, property, &var); \ + \ + if (r < 0) { \ + fprintf(stderr, "Failed to get property:\n target: %s\n property: %s\n", \ + target, property); \ + return r; \ + } \ + \ + g_assert(g_variant_is_of_type(var, G_VARIANT_TYPE("(v)"))); \ + g_variant_get(var, "(v)", &inner); \ + g_assert(g_variant_is_of_type(inner, g_variant_type_##type)); \ + *result = g_variant_get_function_##type(inner); \ + g_variant_unref(var); \ + \ + return 0; \ + } + + +DEFINE_SYSTEMD_GET_PROPERTY(manager, int32, int) +DEFINE_SYSTEMD_GET_PROPERTY(manager, uint32, uint) +DEFINE_SYSTEMD_GET_PROPERTY(manager, int64, long long) +DEFINE_SYSTEMD_GET_PROPERTY(manager, uint64, unsigned long long) +DEFINE_SYSTEMD_GET_PROPERTY(manager, string, char*) +DEFINE_SYSTEMD_GET_PROPERTY(unit, int32, int) +DEFINE_SYSTEMD_GET_PROPERTY(unit, uint32, uint) +DEFINE_SYSTEMD_GET_PROPERTY(unit, int64, long long) +DEFINE_SYSTEMD_GET_PROPERTY(unit, uint64, unsigned long long) +DEFINE_SYSTEMD_GET_PROPERTY(unit, string, char*) +DEFINE_SYSTEMD_GET_PROPERTY(service, int32, int) +DEFINE_SYSTEMD_GET_PROPERTY(service, uint32, uint) +DEFINE_SYSTEMD_GET_PROPERTY(service, int64, long long) +DEFINE_SYSTEMD_GET_PROPERTY(service, uint64, unsigned long long) +DEFINE_SYSTEMD_GET_PROPERTY(service, string, char*) diff --git a/src/shared/systemd.h b/src/shared/systemd.h new file mode 100644 index 0000000..aa29e1c --- /dev/null +++ b/src/shared/systemd.h @@ -0,0 +1,67 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <dbus/dbus.h> +#include <gio/gio.h> + +enum SystemdUnitType { + SYSTEMD_UNIT_SERVICE, + SYSTEMD_UNIT_SOCKET, + SYSTEMD_UNIT_DEVICE, + SYSTEMD_UNIT_MOUNT, + SYSTEMD_UNIT_AUTOMOUNT, + SYSTEMD_UNIT_SWAP, + SYSTEMD_UNIT_TARGET, + SYSTEMD_UNIT_PATH, + SYSTEMD_UNIT_TIMER, + SYSTEMD_UNIT_SNAPSHOT, + SYSTEMD_UNIT_SLICE, + SYSTEMD_UNIT_SCOPE, + _SYSTEMD_UNIT_TYPE_MAX, + _SYSTEMD_UNIT_TYPE_INVALID = -1 +}; + +#define DBUS_SYSTEMD_DEST "org.freedesktop.systemd1" +#define DBUS_SYSTEMD_ADDRESS "/org/freedesktop/systemd1" +#define DBUS_INTERFACE_SYSTEMD_MANAGER DBUS_SYSTEMD_DEST ".Manager" +#define DBUS_INTERFACE_SYSTEMD_UNIT DBUS_SYSTEMD_DEST ".Unit" +#define DBUS_INTERFACE_SYSTEMD_SERVICE DBUS_SYSTEMD_DEST ".Service" +#define DBUS_INTERFACE_SYSTEMD_TARGET DBUS_SYSTEMD_DEST ".Target" + +int systemd_get_unit_property(const char *unit, const char *property, GVariant **variant); +int systemd_get_service_property(const char* unit, const char* property, GVariant **variant); + +int systemd_get_manager_property_as_int32(const char *iface, const char *property, int *result); +int systemd_get_manager_property_as_uint32(const char *iface, const char *property, unsigned int *result); +int systemd_get_manager_property_as_int64(const char *iface, const char *property, long long *result); +int systemd_get_manager_property_as_uint64(const char *iface, const char *property, unsigned long long *result); +int systemd_get_manager_property_as_string(const char *iface, const char *property, char **result); +int systemd_get_unit_property_as_int32(const char *unit, const char *property, int *result); +int systemd_get_unit_property_as_uint32(const char *unit, const char *property, unsigned int *result); +int systemd_get_unit_property_as_int64(const char *unit, const char *property, long long *result); +int systemd_get_unit_property_as_uint64(const char *unit, const char *property, unsigned long long *result); +int systemd_get_unit_property_as_string(const char *unit, const char *property, char **result); +int systemd_get_service_property_as_int32(const char *unit, const char *property, int *result); +int systemd_get_service_property_as_uint32(const char *unit, const char *property, unsigned int *result); +int systemd_get_service_property_as_int64(const char *unit, const char *property, long long *result); +int systemd_get_service_property_as_uint64(const char *unit, const char *property, unsigned long long *result); +int systemd_get_service_property_as_string(const char *unit, const char *property, char **result); diff --git a/src/shared/util.c b/src/shared/util.c new file mode 100644 index 0000000..2d98f1a --- /dev/null +++ b/src/shared/util.c @@ -0,0 +1,382 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <stddef.h> +#include <assert.h> +#include <errno.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/wait.h> +#include <sys/stat.h> + +#include "fileio.h" +#include "util.h" + +/* In old kernel, this symbol maybe NOT */ +#ifndef TASK_COMM_LEN +#define TASK_COMM_LEN 16 +#endif + +bool streq_ptr(const char *a, const char *b) { + + /* Like streq(), but tries to make sense of NULL pointers */ + + if (a && b) + return streq(a, b); + + if (!a && !b) + return true; + + return false; +} + +char *truncate_nl(char *s) { + assert(s); + + s[strcspn(s, NEWLINE)] = 0; + + return s; +} + +char *strnappend(const char *s, const char *suffix, size_t b) { + size_t a; + char *r; + + if (!s && !suffix) + return strdup(""); + + if (!s) + return strndup(suffix, b); + + if (!suffix) + return strdup(s); + + assert(s); + assert(suffix); + + a = strlen(s); + if (b > ((size_t) -1) - a) + return NULL; + + r = new(char, a+b+1); + if (!r) + return NULL; + + memcpy(r, s, a); + memcpy(r+a, suffix, b); + r[a+b] = 0; + + return r; +} + +char *strappend(const char *s, const char *suffix) { + return strnappend(s, suffix, suffix ? strlen(suffix) : 0); +} + +char *strstrip(char *s) { + char *e; + + /* Drops trailing whitespace. Modifies the string in + * place. Returns pointer to first non-space character */ + + s += strspn(s, WHITESPACE); + + for (e = strchr(s, 0); e > s; e --) + if (!strchr(WHITESPACE, e[-1])) + break; + + *e = 0; + + return s; +} + +char *file_in_same_dir(const char *path, const char *filename) { + char *e, *r; + size_t k; + + assert(path); + assert(filename); + + /* This removes the last component of path and appends + * filename, unless the latter is absolute anyway or the + * former isn't */ + + if (path_is_absolute(filename)) + return strdup(filename); + + if (!(e = strrchr(path, '/'))) + return strdup(filename); + + k = strlen(filename); + if (!(r = new(char, e-path+1+k+1))) + return NULL; + + memcpy(r, path, e-path+1); + memcpy(r+(e-path)+1, filename, k+1); + + return r; +} + +bool nulstr_contains(const char*nulstr, const char *needle) { + const char *i; + + if (!nulstr) + return false; + + NULSTR_FOREACH(i, nulstr) + if (streq(i, needle)) + return true; + + return false; +} + +bool path_is_absolute(const char *p) { + return p[0] == '/'; +} + +char *path_kill_slashes(char *path) { + char *f, *t; + bool slash = false; + + /* Removes redundant inner and trailing slashes. Modifies the + * passed string in-place. + * + * ///foo///bar/ becomes /foo/bar + */ + + for (f = path, t = path; *f; f++) { + + if (*f == '/') { + slash = true; + continue; + } + + if (slash) { + slash = false; + *(t++) = '/'; + } + + *(t++) = *f; + } + + /* Special rule, if we are talking of the root directory, a + trailing slash is good */ + + if (t == path && slash) + *(t++) = '/'; + + *t = 0; + return path; +} + +char* endswith(const char *s, const char *postfix) { + size_t sl, pl; + + assert(s); + assert(postfix); + + sl = strlen(s); + pl = strlen(postfix); + + if (pl == 0) + return (char*) s + sl; + + if (sl < pl) + return NULL; + + if (memcmp(s + sl - pl, postfix, pl) != 0) + return NULL; + + return (char*) s + sl - pl; +} + +int parse_boolean(const char *v) { + assert(v); + + if (streq(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || strcaseeq(v, "on")) + return 1; + else if (streq(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || strcaseeq(v, "off")) + return 0; + + return -EINVAL; +} + +/* Split a string into words. */ +char *split(const char *c, size_t *l, const char *separator, char **state) { + char *current; + + current = *state ? *state : (char*) c; + + if (!*current || *c == 0) + return NULL; + + current += strspn(current, separator); + *l = strcspn(current, separator); + *state = current+*l; + + return (char*) current; +} + +bool is_number(const char *s, int l) { + int i; + + for (i = 0; i < l; i++) + if (!isdigit(s[i])) + return false; + + return true; +} + +int pid_of(const char *pname) { + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *de; + int r; + + dir = opendir("/proc"); + if (!dir) { + fprintf(stderr, "Failed to open dir: %s", "/proc"); + return -errno; + } + + FOREACH_DIRENT(de, dir, return -errno) { + _cleanup_free_ char *path = NULL; + _cleanup_free_ char *comm = NULL; + + if (de->d_type != DT_DIR) + continue; + + if (!is_number(de->d_name, strlen(de->d_name))) + continue; + + r = asprintf(&path, "/proc/%s/comm", de->d_name); + if (r < 0) + return -ENOMEM; + + r = read_one_line_file(path, &comm); + if (r < 0) + continue; + + if (strneq(pname, comm, TASK_COMM_LEN-1)) + return atoi(de->d_name); + } + + return 0; +} + +int do_copy(const char *src, const char *dst, const char *option) { + pid_t pid; + int status; + + pid = fork(); + if (pid == 0) { /* child */ + execl("/bin/cp", + "/bin/cp", src, dst, option, (char *)0); + _exit(1); + } + else if (pid < 0) + return -errno; + /* TODO */ + /* Child wait status should be checked. */ + wait(&status); + return 0; +} + +int do_mkdir_one(const char *path, mode_t mode) { + int r; + + assert(path); + + r = mkdir(path, mode); + if (r < 0) { + fprintf(stderr, "cannot create directory '%s': %m\n", path); + return r; + } + + return 0; +} + +int do_mkdir(const char *path, mode_t mode) { + size_t s, l; + int p; + int r; + + assert(path); + + l = strlen(path); + + for (p = 0, s = 0; p < l; p += s+1) { + _cleanup_free_ char *d = new0(char, p+s+1); + + s = strcspn(path+p, "/"); + if (!s) + continue; + + r = snprintf(d, p+s+1, "%s", path); + if (r < 0) + return r; + + r = access(d, W_OK); + if (r == 0) + continue; + else if (r < 0 && errno != ENOENT) { + fprintf(stderr, + "cannot create directory '%s': %m\n", d); + return r; + } + + r = do_mkdir_one(d, mode); + if (r < 0) + return r; + } + + return 0; +} + +int rmdir_recursive(const char *path) { + _cleanup_closedir_ DIR *d = NULL; + struct dirent *de; + int r; + + assert(path); + + d = opendir(path); + if (!d) + return -errno; + + FOREACH_DIRENT(de, d, return -errno) { + _cleanup_free_ char *p = NULL; + + r = asprintf(&p, "%s/%s", path, de->d_name); + if (r < 0) + return -ENOMEM; + + if (de->d_type == DT_DIR) { + r = rmdir_recursive(p); + if (r < 0) + return r; + } else { + r = unlink(p); + if (r < 0) + return r; + } + } + + return rmdir(path); +} diff --git a/src/shared/util.h b/src/shared/util.h new file mode 100644 index 0000000..4340874 --- /dev/null +++ b/src/shared/util.h @@ -0,0 +1,109 @@ +/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ + +/* + * system-plugin-common + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the License); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <dirent.h> + +#include "macro.h" + +#define WHITESPACE " \t\n\r" +#define NEWLINE "\n\r" +#define QUOTES "\"\'" +#define COMMENTS "#;" + +static inline void freep(void *p) { + free(*(void**) p); +} + +static inline void fclosep(FILE **f) { + if (*f) + fclose(*f); +} + +static inline void closedirp(DIR **d) { + if (*d) + closedir(*d); +} + +static inline const char *startswith(const char *s, const char *prefix) { + if (strncmp(s, prefix, strlen(prefix)) == 0) + return s + strlen(prefix); + return NULL; +} + +#define _cleanup_free_ _cleanup_(freep) +#define _cleanup_fclose_ _cleanup_(fclosep) +#define _cleanup_closedir_ _cleanup_(closedirp) + +#define streq(a,b) (strcmp((a),(b)) == 0) +#define strneq(a, b, n) (strncmp((a), (b), (n)) == 0) +#define strcaseeq(a,b) (strcasecmp((a),(b)) == 0) +#define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0) + +#define new(t, n) ((t*) malloc(sizeof(t) * (n))) +#define new0(t, n) ((t*) calloc((n), sizeof(t))) +#define malloc0(n) (calloc((n), 1)) + +#define NULSTR_FOREACH(i, l) \ + for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1) + +bool streq_ptr(const char *a, const char *b) _pure_; +int parse_boolean(const char *v) _pure_; +char *truncate_nl(char *s); +char *strnappend(const char *s, const char *suffix, size_t b); +char *strappend(const char *s, const char *suffix); +char *strstrip(char *s); +char *file_in_same_dir(const char *path, const char *filename); +bool nulstr_contains(const char*nulstr, const char *needle); +bool path_is_absolute(const char *p); +char *path_kill_slashes(char *path); +char* endswith(const char *s, const char *postfix); + +char *split(const char *c, size_t *l, const char *separator, char **state); + +#define FOREACH_WORD(word, length, s, state) \ + for ((state) = NULL, (word) = split((s), &(length), WHITESPACE, &(state)); (word); (word) = split((s), &(length), WHITESPACE, &(state))) + +#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \ + for ((state) = NULL, (word) = split((s), &(length), (separator), &(state)); (word); (word) = split((s), &(length), (separator), &(state))) + +#define FOREACH_DIRENT(de, d, on_error) \ + for (errno = 0, de = readdir(d);; errno = 0, de = readdir(d)) \ + if (!de) { \ + if (errno > 0) { \ + on_error; \ + } \ + break; \ + } else if (streq(de->d_name, ".") || \ + streq(de->d_name, "..")) \ + continue; \ + else + +bool is_number(const char *s, int l); +int pid_of(const char *pname); +int do_copy(const char *src, const char *dst, const char *option); +int do_mkdir_one(const char *path, mode_t mode); +int do_mkdir(const char *path, mode_t mode); +int rmdir_recursive(const char *path); diff --git a/sysctl.d/50-tizen-default.conf.in b/sysctl.d/50-tizen-default.conf.in new file mode 100644 index 0000000..4225340 --- /dev/null +++ b/sysctl.d/50-tizen-default.conf.in @@ -0,0 +1,12 @@ +# See sysctl.d(5) and core(5) for for details. + +# This specifies an upper limit on the number of inotify instances +# that can be created per real user ID. +fs.inotify.max_user_instances=1024 + +# In hundredths of a second, this is how often pdflush wakes up to +# write data to disk. +vm.dirty_writeback_centisecs=@DIRTY_WRITEBACK_CENTISECS@ + +# config overcommit handling mode +vm.overcommit_memory = 1 diff --git a/units/check-mount.service b/units/check-mount.service new file mode 100644 index 0000000..9eede2a --- /dev/null +++ b/units/check-mount.service @@ -0,0 +1,14 @@ +[Unit] +Description=Check Mount +ConditionPathIsMountPoint=!/opt/usr +After=tizen-boot.target starter.service +Requires=tizen-boot.target +Before=tizen-system.target + +[Service] +Type=oneshot +ExecStart=/bin/sh -c 'while [ "z`/bin/grep /opt/usr /proc/mounts`" == "z" ]; do /bin/sleep 0.5; done' +ExecStartPost=/bin/sleep 3 + +[Install] +WantedBy=tizen-system.target diff --git a/units/cleanup-storage.service b/units/cleanup-storage.service new file mode 100644 index 0000000..426a02d --- /dev/null +++ b/units/cleanup-storage.service @@ -0,0 +1,10 @@ +[Unit] +Description=Cleanup Storage +DefaultDependencies=no + +[Service] +Type=oneshot +ExecStart=/usr/bin/cleanup-storage.sh + +[Install] +WantedBy=basic.target diff --git a/units/cleanup-storage.timer b/units/cleanup-storage.timer new file mode 100644 index 0000000..c94c753 --- /dev/null +++ b/units/cleanup-storage.timer @@ -0,0 +1,5 @@ +[Unit] +Description=Timer for cleanup-storage + +[Timer] +OnCalendar=*-*-* 05:00:00 diff --git a/units/ghost.service b/units/ghost.service new file mode 100644 index 0000000..af5f376 --- /dev/null +++ b/units/ghost.service @@ -0,0 +1,13 @@ +[Unit] +Description=ghost process +DefaultDependencies=no +Requires=dbus.socket +After=dbus.socket + +[Service] +ExecStart=/usr/bin/ghost +StandardOutput=journal+console +StandardError=inherit + +[Install] +WantedBy=multi-user.target diff --git a/units/init-conf.service b/units/init-conf.service new file mode 100644 index 0000000..b62d0d6 --- /dev/null +++ b/units/init-conf.service @@ -0,0 +1,14 @@ +[Unit] +Description=Run init.%H.conf +DefaultDependencies=no +After=local-fs.target +Conflicts=shutdown.target +Before=sysinit.target shutdown.target +ConditionFileNotEmpty=/etc/init.%H.conf + +[Service] +Type=oneshot +ExecStart=/bin/bash -c '/etc/init.%H.conf' + +[Install] +WantedBy=sysinit.target diff --git a/units/systemd-udevd-kill.service b/units/systemd-udevd-kill.service new file mode 100644 index 0000000..609d0f4 --- /dev/null +++ b/units/systemd-udevd-kill.service @@ -0,0 +1,8 @@ +[Unit] +Description=Stop systemd-udevd service + +[Service] +Type=oneshot +ExecStart=/usr/bin/systemctl stop systemd-udevd.service +ExecStartPost=/usr/bin/systemctl stop systemd-udevd-control.socket +ExecStartPost=/usr/bin/systemctl stop systemd-udevd-kernel.socket diff --git a/units/systemd-udevd-kill.timer b/units/systemd-udevd-kill.timer new file mode 100644 index 0000000..85624e7 --- /dev/null +++ b/units/systemd-udevd-kill.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Stop systemd-udevd 30s After Completed Startup +DefaultDependencies=no +Conflicts=shutdown.target +After=default.target +Before=shutdown.target + +[Timer] +OnActiveSec=30s diff --git a/units/tizen-boot.target b/units/tizen-boot.target new file mode 100644 index 0000000..1533be5 --- /dev/null +++ b/units/tizen-boot.target @@ -0,0 +1,6 @@ +[Unit] +Description=Tizen Boot +Requires=basic.target +Conflicts=rescue.service rescue.target +After=basic.target rescue.service rescue.target +Before=multi-user.target diff --git a/units/tizen-fstrim-user.service b/units/tizen-fstrim-user.service new file mode 100644 index 0000000..a0cfe33 --- /dev/null +++ b/units/tizen-fstrim-user.service @@ -0,0 +1,9 @@ +[Unit] +Description=Discard unused blocks on user partition +Requires=opt-usr.mount + +[Service] +Type=oneshot +ExecStart=/usr/bin/tizen-fstrim-on-charge.sh /opt/usr +StandardOutput=journal +StandardError=inherit diff --git a/units/tizen-fstrim-user.timer.m4 b/units/tizen-fstrim-user.timer.m4 new file mode 100644 index 0000000..8ebabf3 --- /dev/null +++ b/units/tizen-fstrim-user.timer.m4 @@ -0,0 +1,8 @@ +[Unit] +Description=Timer for tizen-fstrim + +[Timer] +m4_ifdef(`WITH_FREQUENT_FSTRIM', +`OnBootSec=30 +OnUnitActiveSec=3h', +`OnCalendar=*-*-* 06:00:00') diff --git a/units/tizen-generate-env.service b/units/tizen-generate-env.service new file mode 100644 index 0000000..ae5bc98 --- /dev/null +++ b/units/tizen-generate-env.service @@ -0,0 +1,12 @@ +[Unit] +Description=Generate environment from /etc/profile.d +DefaultDependencies=no +After=opt.mount +Before=basic.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/env -i sh -c 'source /etc/profile; env | /bin/egrep -v "^(HOME|PWD|SHLVL|_)=" > /run/tizen-mobile-env' + +[Install] +WantedBy=basic.target diff --git a/units/tizen-init-check.service.in b/units/tizen-init-check.service.in new file mode 100644 index 0000000..31ec3ca --- /dev/null +++ b/units/tizen-init-check.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Tizen Initialized check +DefaultDependencies=no +After=opt.mount +Before=tizen-init-done.service tizen-initial-boot-done.service +ConditionPathExists=@INITAILBOOT_DONE@ +ConditionPathExists=!@INITIALIZE_DONE@ +RefuseManualStart=yes + +[Service] +ExecStart=/usr/bin/systemctl start tizen-init.target diff --git a/units/tizen-init-done.service.in b/units/tizen-init-done.service.in new file mode 100644 index 0000000..df4c5c1 --- /dev/null +++ b/units/tizen-init-done.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Tizen initialized flag done +After=default.target +ConditionPathExists=!@INITIALIZE_DONE@ +RefuseManualStart=yes + +[Service] +ExecStart=/bin/touch @INITIALIZE_DONE@ + +[Install] +WantedBy=tizen-init.target diff --git a/units/tizen-init.target b/units/tizen-init.target new file mode 100644 index 0000000..8c7ce15 --- /dev/null +++ b/units/tizen-init.target @@ -0,0 +1,5 @@ +[Unit] +Description=Tizen Initialization +Conflicts=emergency.service emergency.target +Wants=local-fs.target swap.target +After=local-fs.target swap.target emergency.service emergency.target diff --git a/units/tizen-initial-boot-done.service.in b/units/tizen-initial-boot-done.service.in new file mode 100644 index 0000000..7e8ae55 --- /dev/null +++ b/units/tizen-initial-boot-done.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=Tizen initial boot flag generate +After=default.target +ConditionPathExists=!@INITAILBOOT_DONE@ +RefuseManualStart=yes + +[Service] +ExecStart=/bin/touch @INITAILBOOT_DONE@ + +[Install] +WantedBy=default.target diff --git a/units/tizen-journal-flush.service b/units/tizen-journal-flush.service new file mode 100644 index 0000000..9a2d2ee --- /dev/null +++ b/units/tizen-journal-flush.service @@ -0,0 +1,11 @@ +# This file is copied from systemd to modify. + +[Unit] +Description=Trigger Flushing of Journal to Persistent Storage +Documentation=man:systemd-journald.service(8) man:journald.conf(5) +Requires=systemd-journald.service +After=systemd-journald.service default.target + +[Service] +ExecStart=/usr/bin/systemctl kill --kill-who=main --signal=SIGUSR1 systemd-journald.service +Type=oneshot diff --git a/units/tizen-readahead-collect-stop.service b/units/tizen-readahead-collect-stop.service new file mode 100644 index 0000000..9d4aeaa --- /dev/null +++ b/units/tizen-readahead-collect-stop.service @@ -0,0 +1,14 @@ +[Unit] +Description=Stop Read-Ahead Data Collection +DefaultDependencies=no +Conflicts=shutdown.target +After=tizen-readahead-collect.service boot-animation.service +Before=shutdown.target tizen-system.target +ConditionVirtualization=no + +[Service] +Type=oneshot +ExecStart=/usr/bin/systemd-notify --readahead=done + +[Install] +Also=tizen-readahead-collect.service diff --git a/units/tizen-readahead-collect.service.in b/units/tizen-readahead-collect.service.in new file mode 100644 index 0000000..8b0c5c3 --- /dev/null +++ b/units/tizen-readahead-collect.service.in @@ -0,0 +1,20 @@ +[Unit] +Description=Collect Read-Ahead Data +DefaultDependencies=no +Wants=tizen-readahead-collect-stop.service +Conflicts=shutdown.target +After=smack.service smack-default-labeling.service tizen-readahead-replay.service +Before=sysinit.target shutdown.target +ConditionPathExists=!/run/systemd/readahead/cancel +ConditionPathExists=!/run/systemd/readahead/done +ConditionPathExists=!@READAHEAD_DIR@/.readahead +ConditionVirtualization=no + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead collect --savedir=@READAHEAD_DIR@ +RemainAfterExit=yes +StandardOutput=null + +[Install] +WantedBy=tizen-init.target diff --git a/units/tizen-readahead-replay.service.in b/units/tizen-readahead-replay.service.in new file mode 100644 index 0000000..22f00dd --- /dev/null +++ b/units/tizen-readahead-replay.service.in @@ -0,0 +1,19 @@ +[Unit] +Description=Replay Read-Ahead Data +DefaultDependencies=no +Conflicts=shutdown.target +After=smack.service smack-default-labeling.service +Before=sysinit.target shutdown.target +ConditionPathExists=!/run/systemd/readahead/noreplay +ConditionPathExists=@READAHEAD_DIR@/.readahead +ConditionVirtualization=no + +[Service] +Type=notify +ExecStart=@rootlibexecdir@/systemd-readahead replay --savedir=@READAHEAD_DIR@ +RemainAfterExit=yes +StandardOutput=null +OOMScoreAdjust=1000 + +[Install] +WantedBy=graphical.target diff --git a/units/tizen-runtime.target b/units/tizen-runtime.target new file mode 100644 index 0000000..b1bc216 --- /dev/null +++ b/units/tizen-runtime.target @@ -0,0 +1,6 @@ +[Unit] +Description=Tizen Runtime +Requires=basic.target tizen-boot.target tizen-system.target +Conflicts=rescue.service rescue.target +After=basic.target tizen-boot.target tizen-system.target rescue.service rescue.target +Before=multi-user.target diff --git a/units/tizen-system.target b/units/tizen-system.target new file mode 100644 index 0000000..4240819 --- /dev/null +++ b/units/tizen-system.target @@ -0,0 +1,6 @@ +[Unit] +Description=Tizen System +Requires=basic.target tizen-boot.target +Conflicts=rescue.service rescue.target +After=basic.target tizen-boot.target rescue.service rescue.target +Before=multi-user.target diff --git a/units/wm_ready.service b/units/wm_ready.service new file mode 100644 index 0000000..e3f260b --- /dev/null +++ b/units/wm_ready.service @@ -0,0 +1,12 @@ +[Unit] +Description=waiting for window mananger +After=xorg.service +Before=tizen-boot.target + +[Service] +Type=oneshot +ExecStart=/bin/sh -c 'while [ ! -e /tmp/.wm_ready ]; do sleep 0.1 ; done' +TimeoutSec=10s + +[Install] +WantedBy=tizen-boot.target |