Skip to content

Commit eabf79e

Browse files
committed
core/command: allow qs log to retrieve logs of dead instances
If no live instances are found matching the current config, the youngest dead instance will be used instead.
1 parent 0662c37 commit eabf79e

File tree

3 files changed

+28
-16
lines changed

3 files changed

+28
-16
lines changed

src/core/paths.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ void QsPaths::createLock() {
262262
}
263263
}
264264

265-
bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
265+
bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info, bool allowDead) {
266266
auto file = QFile(QDir(path).filePath("instance.lock"));
267267
if (!file.open(QFile::ReadOnly)) return false;
268268

@@ -275,10 +275,12 @@ bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
275275
};
276276

277277
fcntl(file.handle(), F_GETLK, &lock); // NOLINT
278-
if (lock.l_type == F_UNLCK) return false;
278+
auto isLocked = lock.l_type != F_UNLCK;
279+
280+
if (!isLocked && !allowDead) return false;
279281

280282
if (info) {
281-
info->pid = lock.l_pid;
283+
info->pid = isLocked ? lock.l_pid : -1;
282284

283285
auto stream = QDataStream(&file);
284286
stream >> info->instance;
@@ -287,7 +289,7 @@ bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
287289
return true;
288290
}
289291

290-
QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path) {
292+
QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path, bool fallbackDead) {
291293
qCDebug(logPaths) << "Collecting instances from" << path;
292294
auto instances = QVector<InstanceLockInfo>();
293295
auto dir = QDir(path);
@@ -296,13 +298,18 @@ QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path) {
296298
for (auto& entry: dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
297299
auto path = dir.filePath(entry);
298300

299-
if (QsPaths::checkLock(path, &info)) {
300-
qCDebug(logPaths).nospace() << "Found live instance " << info.instance.instanceId << " (pid "
301+
if (QsPaths::checkLock(path, &info, fallbackDead)) {
302+
if (fallbackDead && info.pid != -1) {
303+
fallbackDead = false;
304+
instances.clear();
305+
}
306+
307+
qCDebug(logPaths).nospace() << "Found instance " << info.instance.instanceId << " (pid "
301308
<< info.pid << ") at " << path;
302309

303310
instances.push_back(info);
304311
} else {
305-
qCDebug(logPaths) << "Skipped dead instance at" << path;
312+
qCDebug(logPaths) << "Skipped potential instance at" << path;
306313
}
307314
}
308315

src/core/paths.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@ class QsPaths {
2020
static QDir crashDir(const QString& id);
2121
static QString basePath(const QString& id);
2222
static QString ipcPath(const QString& id);
23-
static bool checkLock(const QString& path, InstanceLockInfo* info = nullptr);
24-
static QVector<InstanceLockInfo> collectInstances(const QString& path);
23+
static bool
24+
checkLock(const QString& path, InstanceLockInfo* info = nullptr, bool allowDead = false);
25+
static QVector<InstanceLockInfo> collectInstances(const QString& path, bool fallbackDead = false);
2526

2627
QDir* cacheDir();
2728
QDir* baseRunDir();

src/launch/command.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,21 +109,21 @@ void sortInstances(QVector<InstanceLockInfo>& list, bool newestFirst) {
109109
});
110110
};
111111

112-
int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
112+
int selectInstance(CommandState& cmd, InstanceLockInfo* instance, bool deadFallback = false) {
113113
auto* basePath = QsPaths::instance()->baseRunDir();
114114
if (!basePath) return -1;
115115

116116
QString path;
117117

118118
if (cmd.instance.pid != -1) {
119119
path = QDir(basePath->filePath("by-pid")).filePath(QString::number(cmd.instance.pid));
120-
if (!QsPaths::checkLock(path, instance)) {
120+
if (!QsPaths::checkLock(path, instance, deadFallback)) {
121121
qCInfo(logBare) << "No instance found for pid" << cmd.instance.pid;
122122
return -1;
123123
}
124124
} else if (!cmd.instance.id->isEmpty()) {
125125
path = basePath->filePath("by-pid");
126-
auto instances = QsPaths::collectInstances(path);
126+
auto instances = QsPaths::collectInstances(path, deadFallback);
127127

128128
instances.removeIf([&](const InstanceLockInfo& info) {
129129
return !info.instance.instanceId.startsWith(*cmd.instance.id);
@@ -136,7 +136,8 @@ int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
136136
qCInfo(logBare) << "More than one instance starts with" << *cmd.instance.id;
137137

138138
for (auto& instance: instances) {
139-
qCInfo(logBare).noquote() << " -" << instance.instance.instanceId;
139+
qCInfo(logBare).noquote() << " -" << instance.instance.instanceId
140+
<< (instance.pid == -1 ? " (dead)" : "");
140141
}
141142

142143
return -1;
@@ -153,8 +154,11 @@ int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
153154

154155
path = QDir(basePath->filePath("by-path")).filePath(pathId);
155156

156-
auto instances = QsPaths::collectInstances(path);
157-
sortInstances(instances, cmd.config.newest);
157+
auto instances = QsPaths::collectInstances(path, deadFallback);
158+
sortInstances(
159+
instances,
160+
cmd.config.newest || (!instances.empty() && instances.first().pid == -1)
161+
);
158162

159163
if (instances.isEmpty()) {
160164
qCInfo(logBare) << "No running instances for" << configFilePath;
@@ -172,7 +176,7 @@ int readLogFile(CommandState& cmd) {
172176

173177
if (path.isEmpty()) {
174178
InstanceLockInfo instance;
175-
auto r = selectInstance(cmd, &instance);
179+
auto r = selectInstance(cmd, &instance, true);
176180
if (r != 0) return r;
177181

178182
path = QDir(QsPaths::basePath(instance.instance.instanceId)).filePath("log.qslog");

0 commit comments

Comments
 (0)