logcatd: introduce logcatd executable
logcatd is the same as logcat, except that the -L flag, if supplied,
runs once, then the command re-runs itself without the -L flag with
the same argument set. By introducing a logcatd daemon executable
we can solve the problem of the longish reads from pstore that
sometimes occur when the system is excessively busy, starving this
background cgroup daemon as we absorb the delay in a backgrounded
init "service", rather than in a forgrounded init "exec". This would
not have been efficiently possible without the introduction of
liblogcat.
There are no doubt many flags that make no sense to run twice with,
and without, the -L flag. In the general sense we expect the caller
to perform the correct set of operations and not pick these nonsense
operations. logcatd is only supplied on engineering and debug builds
for logpersist, and is only an automated aid to triage.
Test: gTest logcat-unit-tests
Test: manual confirm logpersist functions as expected, required reboot
Bug: 28788401
Bug: 30041146
Bug: 30612424
Bug: 35326290
Change-Id: I53ba31970749daf37eef42636f039f485932416f
2017-04-03 18:30:20 +02:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2017 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* 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 <signal.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2018-06-16 00:16:20 +02:00
|
|
|
#include "logcat.h"
|
logcatd: introduce logcatd executable
logcatd is the same as logcat, except that the -L flag, if supplied,
runs once, then the command re-runs itself without the -L flag with
the same argument set. By introducing a logcatd daemon executable
we can solve the problem of the longish reads from pstore that
sometimes occur when the system is excessively busy, starving this
background cgroup daemon as we absorb the delay in a backgrounded
init "service", rather than in a forgrounded init "exec". This would
not have been efficiently possible without the introduction of
liblogcat.
There are no doubt many flags that make no sense to run twice with,
and without, the -L flag. In the general sense we expect the caller
to perform the correct set of operations and not pick these nonsense
operations. logcatd is only supplied on engineering and debug builds
for logpersist, and is only an automated aid to triage.
Test: gTest logcat-unit-tests
Test: manual confirm logpersist functions as expected, required reboot
Bug: 28788401
Bug: 30041146
Bug: 30612424
Bug: 35326290
Change-Id: I53ba31970749daf37eef42636f039f485932416f
2017-04-03 18:30:20 +02:00
|
|
|
|
|
|
|
int main(int argc, char** argv, char** envp) {
|
|
|
|
android_logcat_context ctx = create_android_logcat();
|
|
|
|
if (!ctx) return -1;
|
|
|
|
|
|
|
|
signal(SIGPIPE, exit);
|
|
|
|
|
|
|
|
// Save and detect presence of -L or --last flag
|
|
|
|
std::vector<std::string> args;
|
|
|
|
bool last = false;
|
|
|
|
for (int i = 0; i < argc; ++i) {
|
|
|
|
if (!argv[i]) continue;
|
|
|
|
args.push_back(std::string(argv[i]));
|
|
|
|
if (!strcmp(argv[i], "-L") || !strcmp(argv[i], "--last")) last = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Generate argv from saved content
|
|
|
|
std::vector<const char*> argv_hold;
|
|
|
|
for (auto& str : args) argv_hold.push_back(str.c_str());
|
|
|
|
argv_hold.push_back(nullptr);
|
|
|
|
|
|
|
|
int ret = 0;
|
|
|
|
if (last) {
|
|
|
|
// Run logcat command with -L flag
|
|
|
|
ret = android_logcat_run_command(ctx, -1, -1, argv_hold.size() - 1,
|
|
|
|
(char* const*)&argv_hold[0], envp);
|
|
|
|
// Remove -L and --last flags from argument list
|
|
|
|
for (std::vector<const char*>::iterator it = argv_hold.begin();
|
|
|
|
it != argv_hold.end();) {
|
|
|
|
if (!*it || (strcmp(*it, "-L") && strcmp(*it, "--last"))) {
|
|
|
|
++it;
|
|
|
|
} else {
|
|
|
|
it = argv_hold.erase(it);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// fall through to re-run the command regardless of the arguments
|
|
|
|
// passed in. For instance, we expect -h to report help stutter.
|
|
|
|
}
|
|
|
|
|
|
|
|
// Run logcat command without -L flag
|
|
|
|
int retval = android_logcat_run_command(ctx, -1, -1, argv_hold.size() - 1,
|
|
|
|
(char* const*)&argv_hold[0], envp);
|
|
|
|
if (!ret) ret = retval;
|
|
|
|
retval = android_logcat_destroy(&ctx);
|
|
|
|
if (!ret) ret = retval;
|
|
|
|
return ret;
|
|
|
|
}
|