Merge "liblog: event log tags cache miss call logd for update"
This commit is contained in:
commit
364bf6db00
1 changed files with 79 additions and 7 deletions
|
|
@ -227,19 +227,30 @@ int EventTagMap::find(MapString&& tag) const {
|
|||
// successful return, it will be pointing to the last character in the
|
||||
// tag line (i.e. the character before the start of the next line).
|
||||
//
|
||||
// lineNum = 0 removes verbose comments and requires us to cache the
|
||||
// content rather than make direct raw references since the content
|
||||
// will disappear after the call. A non-zero lineNum means we own the
|
||||
// data and it will outlive the call.
|
||||
//
|
||||
// Returns 0 on success, nonzero on failure.
|
||||
static int scanTagLine(EventTagMap* map, char** pData, int lineNum) {
|
||||
char* cp;
|
||||
unsigned long val = strtoul(*pData, &cp, 10);
|
||||
if (cp == *pData) {
|
||||
fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n", lineNum);
|
||||
if (lineNum) {
|
||||
fprintf(stderr, OUT_TAG ": malformed tag number on line %d\n",
|
||||
lineNum);
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t tagIndex = val;
|
||||
if (tagIndex != val) {
|
||||
fprintf(stderr, OUT_TAG ": tag number too large on line %d\n", lineNum);
|
||||
if (lineNum) {
|
||||
fprintf(stderr, OUT_TAG ": tag number too large on line %d\n",
|
||||
lineNum);
|
||||
}
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -248,7 +259,10 @@ static int scanTagLine(EventTagMap* map, char** pData, int lineNum) {
|
|||
}
|
||||
|
||||
if (*cp == '\n') {
|
||||
fprintf(stderr, OUT_TAG ": missing tag string on line %d\n", lineNum);
|
||||
if (lineNum) {
|
||||
fprintf(stderr, OUT_TAG ": missing tag string on line %d\n",
|
||||
lineNum);
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -259,7 +273,10 @@ static int scanTagLine(EventTagMap* map, char** pData, int lineNum) {
|
|||
size_t tagLen = cp - tag;
|
||||
|
||||
if (!isspace(*cp)) {
|
||||
fprintf(stderr, OUT_TAG ": invalid tag chars on line %d\n", lineNum);
|
||||
if (lineNum) {
|
||||
fprintf(stderr, OUT_TAG ": invalid tag chars on line %d\n",
|
||||
lineNum);
|
||||
}
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -293,9 +310,18 @@ static int scanTagLine(EventTagMap* map, char** pData, int lineNum) {
|
|||
#endif
|
||||
*pData = cp;
|
||||
|
||||
if (map->emplaceUnique(tagIndex, TagFmt(std::make_pair(
|
||||
MapString(tag, tagLen), MapString(fmt, fmtLen))), verbose)) {
|
||||
return 0;
|
||||
if (lineNum) {
|
||||
if (map->emplaceUnique(tagIndex, TagFmt(std::make_pair(
|
||||
MapString(tag, tagLen), MapString(fmt, fmtLen))), verbose)) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
// cache
|
||||
if (map->emplaceUnique(tagIndex, TagFmt(std::make_pair(
|
||||
MapString(std::string(tag, tagLen)),
|
||||
MapString(std::string(fmt, fmtLen)))))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
errno = EMLINK;
|
||||
return -1;
|
||||
|
|
@ -455,12 +481,55 @@ LIBLOG_ABI_PUBLIC void android_closeEventTagMap(EventTagMap* map) {
|
|||
if (map) delete map;
|
||||
}
|
||||
|
||||
// Cache miss, go to logd to acquire a public reference.
|
||||
// Because we lack access to a SHARED PUBLIC /dev/event-log-tags file map?
|
||||
static const TagFmt* __getEventTag(EventTagMap* map, unsigned int tag) {
|
||||
// call event tag service to arrange for a new tag
|
||||
char *buf = NULL;
|
||||
// Can not use android::base::StringPrintf, asprintf + free instead.
|
||||
static const char command_template[] = "getEventTag id=%u";
|
||||
int ret = asprintf(&buf, command_template, tag);
|
||||
if (ret > 0) {
|
||||
// Add some buffer margin for an estimate of the full return content.
|
||||
char *cp;
|
||||
size_t size = ret - strlen(command_template) +
|
||||
strlen("65535\n4294967295\t?\t\t\t?\t# uid=32767\n\n\f?success?");
|
||||
if (size > (size_t)ret) {
|
||||
cp = static_cast<char*>(realloc(buf, size));
|
||||
if (cp) {
|
||||
buf = cp;
|
||||
} else {
|
||||
size = ret;
|
||||
}
|
||||
} else {
|
||||
size = ret;
|
||||
}
|
||||
// Ask event log tag service for an existing entry
|
||||
if (__send_log_msg(buf, size) >= 0) {
|
||||
buf[size - 1] = '\0';
|
||||
unsigned long val = strtoul(buf, &cp, 10); // return size
|
||||
if ((buf != cp) && (val > 0) && (*cp == '\n')) { // truncation OK
|
||||
++cp;
|
||||
if (!scanTagLine(map, &cp, 0)) {
|
||||
free(buf);
|
||||
return map->find(tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Look up an entry in the map.
|
||||
LIBLOG_ABI_PUBLIC const char* android_lookupEventTag_len(const EventTagMap* map,
|
||||
size_t *len,
|
||||
unsigned int tag) {
|
||||
if (len) *len = 0;
|
||||
const TagFmt* str = map->find(tag);
|
||||
if (!str) {
|
||||
str = __getEventTag(const_cast<EventTagMap*>(map), tag);
|
||||
}
|
||||
if (!str) return NULL;
|
||||
if (len) *len = str->first.length();
|
||||
return str->first.data();
|
||||
|
|
@ -471,6 +540,9 @@ LIBLOG_ABI_PUBLIC const char* android_lookupEventFormat_len(
|
|||
const EventTagMap* map, size_t *len, unsigned int tag) {
|
||||
if (len) *len = 0;
|
||||
const TagFmt* str = map->find(tag);
|
||||
if (!str) {
|
||||
str = __getEventTag(const_cast<EventTagMap*>(map), tag);
|
||||
}
|
||||
if (!str) return NULL;
|
||||
if (len) *len = str->second.length();
|
||||
return str->second.data();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue