10175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn/* 21114f1806521b2a6447b7c68934e4f3c29b60cb5Mark Salyzyn * Copyright (C) 2012-2014 The Android Open Source Project 30175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 40175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License"); 50175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * you may not use this file except in compliance with the License. 60175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * You may obtain a copy of the License at 70175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 80175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * http://www.apache.org/licenses/LICENSE-2.0 90175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * 100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Unless required by applicable law or agreed to in writing, software 110175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS, 120175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * See the License for the specific language governing permissions and 140175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * limitations under the License. 150175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn */ 160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 170175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <stdlib.h> 181114f1806521b2a6447b7c68934e4f3c29b60cb5Mark Salyzyn 19317bfb923c12af688d18fc9a3580dff201b2482bMark Salyzyn#include <private/android_filesystem_config.h> 20317bfb923c12af688d18fc9a3580dff201b2482bMark Salyzyn 210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "FlushCommand.h" 22317bfb923c12af688d18fc9a3580dff201b2482bMark Salyzyn#include "LogBuffer.h" 230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "LogBufferElement.h" 241114f1806521b2a6447b7c68934e4f3c29b60cb5Mark Salyzyn#include "LogCommand.h" 250175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "LogReader.h" 261114f1806521b2a6447b7c68934e4f3c29b60cb5Mark Salyzyn#include "LogTimes.h" 27083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn#include "LogUtils.h" 280175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 290175b0747a1f55329109e84c9a1322dcb95e2848Mark SalyzynFlushCommand::FlushCommand(LogReader &reader, 300175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn bool nonBlock, 310175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn unsigned long tail, 320175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn unsigned int logMask, 33fa3716b2501ccddc8e0cd30f6343692b8deb7639Mark Salyzyn pid_t pid, 34b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn uint64_t start, 35b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn uint64_t timeout) : 367718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn mReader(reader), 377718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn mNonBlock(nonBlock), 387718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn mTail(tail), 397718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn mLogMask(logMask), 407718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn mPid(pid), 41b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn mStart(start), 42015709784537755d42ea564a558c0eae5b1d1546Mark Salyzyn mTimeout((start > 1) ? timeout : 0) { 437718778793b106498b931dd708a466cf3a6f6a0fMark Salyzyn} 440175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 450175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// runSocketCommand is called once for every open client on the 460175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// log reader socket. Here we manage and associated the reader 470175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// client tracking and log region locks LastLogTimes list of 480175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// LogTimeEntrys, and spawn a transitory per-client thread to 490175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// work at filing data to the socket. 500175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// 510175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// global LogTimeEntry::lock() is used to protect access, 520175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// reference counts are used to ensure that individual 530175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn// LogTimeEntry lifetime is managed when not protected. 540175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzynvoid FlushCommand::runSocketCommand(SocketClient *client) { 550175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry *entry = NULL; 560175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LastLogTimes × = mReader.logbuf().mTimes; 570175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 580175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry::lock(); 590175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LastLogTimes::iterator it = times.begin(); 600175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn while(it != times.end()) { 610175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn entry = (*it); 620175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (entry->mClient == client) { 63b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn if (entry->mTimeout.tv_sec || entry->mTimeout.tv_nsec) { 64b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn LogTimeEntry::unlock(); 65b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn return; 66b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn } 670175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn entry->triggerReader_Locked(); 680175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (entry->runningReader_Locked()) { 690175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry::unlock(); 700175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return; 710175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 720175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn entry->incRef_Locked(); 730175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn break; 740175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 750175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn it++; 760175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 770175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 780175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (it == times.end()) { 79c03e72cc1c155ff668df8df1caec363b07347d0dMark Salyzyn // Create LogTimeEntry in notifyNewLog() ? 800175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn if (mTail == (unsigned long) -1) { 810175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry::unlock(); 820175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn return; 830175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 84b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn entry = new LogTimeEntry(mReader, client, mNonBlock, mTail, mLogMask, 85b75cce0389748bea111ca62af623645117e12d9dMark Salyzyn mPid, mStart, mTimeout); 8698dca2d0b15f9a579efae8592dbb45059aad082eMark Salyzyn times.push_front(entry); 870175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn } 880175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 890175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn client->incRef(); 900175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 91c03e72cc1c155ff668df8df1caec363b07347d0dMark Salyzyn // release client and entry reference counts once done 920175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn entry->startReader_Locked(); 930175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn LogTimeEntry::unlock(); 940175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 950175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn 960175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzynbool FlushCommand::hasReadLogs(SocketClient *client) { 971114f1806521b2a6447b7c68934e4f3c29b60cb5Mark Salyzyn return clientHasLogCredentials(client); 980175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn} 998fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn 1008fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzynstatic bool clientHasSecurityCredentials(SocketClient *client) { 1018fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn return (client->getUid() == AID_SYSTEM) || (client->getGid() == AID_SYSTEM); 1028fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn} 1038fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn 1048fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzynbool FlushCommand::hasSecurityLogs(SocketClient *client) { 1058fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn return clientHasSecurityCredentials(client); 1068fa8896d2ed97eb274c62f0e386dabf2e2a82a45Mark Salyzyn} 107