diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-09-29 09:59:18 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2017-11-14 15:54:56 +0000 |
commit | 772863355a0cf57a49e93608790dfd17c8fd82da (patch) | |
tree | 5bece011b9465288e23c941563a3c887c5536c98 /src/corelib/io/qlockfile.cpp | |
parent | 68cad0ef99b071cf03b8477d828f732485fca16b (diff) |
QLockFile/Unix: save the boot and machine IDs in the lock file too
This allows us to make sure that the PID we read is from the same boot
as we are right now running. The collision could happen on embedded
systems where the boot sequence is fixed, so all the same processes
would have the exact same PIDs after reboot as they did before.
[ChangeLog][QtCore][QLockFile] QLockFile can now properly conclude that
a lock file from a previous boot of the same device is stale and can be
removed. This is implemented only for Linux and Apple operating systems.
Task-number: QTBUG-63425
Change-Id: I0b48fc8e90304e0dacc3fffd14e8e3a197211788
Reviewed-by: Kai Koehne <kai.koehne@qt.io>
Diffstat (limited to 'src/corelib/io/qlockfile.cpp')
-rw-r--r-- | src/corelib/io/qlockfile.cpp | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/src/corelib/io/qlockfile.cpp b/src/corelib/io/qlockfile.cpp index 129cf01b63..aa84ce6bc1 100644 --- a/src/corelib/io/qlockfile.cpp +++ b/src/corelib/io/qlockfile.cpp @@ -56,6 +56,8 @@ struct LockFileInfo qint64 pid; QString appname; QString hostname; + QByteArray hostid; + QByteArray bootid; }; } @@ -331,13 +333,15 @@ QByteArray QLockFilePrivate::lockFileContents() const // Use operator% from the fast builder to avoid multiple memory allocations. return QByteArray::number(QCoreApplication::applicationPid()) % '\n' % processNameByPid(QCoreApplication::applicationPid()).toUtf8() % '\n' - % machineName().toUtf8() % '\n'; + % machineName().toUtf8() % '\n' + % QSysInfo::machineUniqueId() % '\n' + % QSysInfo::bootUniqueId() % '\n'; } static bool getLockInfo_helper(const QString &fileName, LockFileInfo *info) { QFile reader(fileName); - if (!reader.open(QIODevice::ReadOnly)) + if (!reader.open(QIODevice::ReadOnly | QIODevice::Text)) return false; QByteArray pidLine = reader.readLine(); @@ -349,9 +353,17 @@ static bool getLockInfo_helper(const QString &fileName, LockFileInfo *info) QByteArray hostNameLine = reader.readLine(); hostNameLine.chop(1); + // prior to Qt 5.10, only the lines above were recorded + QByteArray hostId = reader.readLine(); + hostId.chop(1); + QByteArray bootId = reader.readLine(); + bootId.chop(1); + bool ok; info->appname = QString::fromUtf8(appNameLine); info->hostname = QString::fromUtf8(hostNameLine); + info->hostid = hostId; + info->bootid = bootId; info->pid = pidLine.toLongLong(&ok); return ok && info->pid > 0; } @@ -360,7 +372,20 @@ bool QLockFilePrivate::isApparentlyStale() const { LockFileInfo info; if (getLockInfo_helper(fileName, &info)) { - if (info.hostname.isEmpty() || info.hostname == machineName()) { + bool sameHost = info.hostname.isEmpty() || info.hostname == machineName(); + if (!info.hostid.isEmpty()) { + // Override with the host ID, if we know it. + QByteArray ourHostId = QSysInfo::machineUniqueId(); + if (!ourHostId.isEmpty()) + sameHost = (ourHostId == info.hostid); + } + + if (sameHost) { + if (!info.bootid.isEmpty()) { + // If we've rebooted, then the lock is definitely stale. + if (info.bootid != QSysInfo::bootUniqueId()) + return true; + } if (!isProcessRunning(info.pid, info.appname)) return true; } |