Commit d1f0c171 authored by Christian Kandeler's avatar Christian Kandeler
Browse files

Maemo: Fix UTFS server readiness detection.

parent cd57457a
......@@ -557,6 +557,7 @@ void MaemoDeployStep::handleMounted()
void MaemoDeployStep::handleUnmounted()
{
m_mounter->resetMountSpecifications();
if (m_stopped) {
m_canStart = true;
return;
......@@ -574,7 +575,7 @@ void MaemoDeployStep::handleUnmounted()
} else {
#ifdef Q_OS_WIN
bool drivesToMount[26];
for (int i = 0; i < sizeof drivesToMount / drivesToMount[0]; ++i)
for (int i = 0; i < sizeof drivesToMount / sizeof drivesToMount[0]; ++i)
drivesToMount[i] = false;
for (int i = 0; i < m_filesToCopy.count(); ++i) {
const QString localDir = QFileInfo(m_filesToCopy.at(i).localFilePath)
......
......@@ -36,7 +36,7 @@
#include <coreplugin/ssh/sshconnection.h>
#include <coreplugin/ssh/sshremoteprocess.h>
#include <QtCore/QProcess>
#include <QtCore/QTimer>
using namespace Core;
......@@ -45,12 +45,19 @@ namespace Internal {
MaemoRemoteMounter::MaemoRemoteMounter(QObject *parent,
const MaemoToolChain *toolchain)
: QObject(parent), m_toolChain(toolchain), m_uploadJobId(SftpInvalidJob),
: QObject(parent), m_toolChain(toolchain),
m_utfsServerTimer(new QTimer(this)), m_uploadJobId(SftpInvalidJob),
m_stop(false)
{
m_utfsServerTimer->setSingleShot(true);
connect(m_utfsServerTimer, SIGNAL(timeout()), this,
SLOT(handleUtfsServerTimeout()));
}
MaemoRemoteMounter::~MaemoRemoteMounter() {}
MaemoRemoteMounter::~MaemoRemoteMounter()
{
killAllUtfsServers();
}
void MaemoRemoteMounter::setConnection(const Core::SshConnection::Ptr &connection)
{
......@@ -72,7 +79,8 @@ bool MaemoRemoteMounter::addMountSpecification(const MaemoMountSpecification &mo
void MaemoRemoteMounter::mount()
{
m_stop = false;
Q_ASSERT(m_utfsServers.isEmpty());
Q_ASSERT(m_startedUtfsServers.isEmpty());
Q_ASSERT(m_readyUtfsServers.isEmpty());
if (m_mountSpecs.isEmpty())
emit mounted();
......@@ -126,13 +134,7 @@ void MaemoRemoteMounter::handleUnmountProcessFinished(int exitStatus)
"Impossible SshRemoteProcess exit status.");
}
foreach (const ProcPtr &utfsServer, m_utfsServers) {
utfsServer->terminate();
utfsServer->waitForFinished(1000);
utfsServer->kill();
}
m_mountSpecs.clear();
m_utfsServers.clear();
killAllUtfsServers();
if (errorMsg.isEmpty()) {
emit reportProgress(tr("Finished unmounting."));
......@@ -274,6 +276,7 @@ void MaemoRemoteMounter::handleUtfsClientsFinished(int exitStatus)
void MaemoRemoteMounter::startUtfsServers()
{
emit reportProgress(tr("Starting UTFS servers..."));
m_utfsServerTimer->start(30000);
for (int i = 0; i < m_mountSpecs.count(); ++i) {
const MountInfo &mountInfo = m_mountSpecs.at(i);
const MaemoMountSpecification &mountSpec = mountInfo.mountSpec;
......@@ -281,29 +284,97 @@ void MaemoRemoteMounter::startUtfsServers()
const QString port = QString::number(mountInfo.remotePort);
const QString localSecretOpt = QLatin1String("-l");
const QString remoteSecretOpt = QLatin1String("-r");
const QStringList utfsServerArgs = QStringList()
<< QLatin1String("--detach") << localSecretOpt << port
<< remoteSecretOpt << port << QLatin1String("-c")
const QStringList utfsServerArgs = QStringList() << localSecretOpt
<< port << remoteSecretOpt << port << QLatin1String("-c")
<< (m_connection->connectionParameters().host + QLatin1Char(':') + port)
<< mountSpec.localDir;
connect(utfsServerProc.data(), SIGNAL(readyReadStandardError()), this,
SLOT(handleUtfsServerStderr()));
connect(utfsServerProc.data(),
SIGNAL(finished(int,QProcess::ExitStatus)), this,
SLOT(handleUtfsServerFinished(int,QProcess::ExitStatus)));
connect(utfsServerProc.data(), SIGNAL(error(QProcess::ProcessError)),
this, SLOT(handleUtfsServerError(QProcess::ProcessError)));
m_startedUtfsServers << utfsServerProc;
utfsServerProc->start(utfsServer(), utfsServerArgs);
if (!utfsServerProc->waitForStarted()
|| !utfsServerProc->waitForFinished(5000)) {
const QByteArray &errorOutput
= utfsServerProc->readAllStandardError();
QString errorMsg = tr("Could not start UTFS server: %1")
.arg(utfsServerProc->errorString());
if (!errorOutput.isEmpty()) {
errorMsg += tr("\nstderr output was: '%1'")
.arg(QString::fromLocal8Bit(errorOutput));
}
}
void MaemoRemoteMounter::handleUtfsServerStderr()
{
if (m_stop)
return;
for (int i = 0; i < m_startedUtfsServers.count(); ++i) {
UtfsServerInfo &info = m_startedUtfsServers[i];
if (info.proc.data() == sender()) {
info.output += info.proc->readAllStandardError();
if (info.output.contains("utfs server is ready")) {
m_readyUtfsServers << info;
m_startedUtfsServers.removeAt(i);
if (m_startedUtfsServers.isEmpty()) {
m_utfsServerTimer->stop();
emit mounted();
}
return;
}
break;
}
}
for (int i = 0; i < m_readyUtfsServers.count(); ++i) {
UtfsServerInfo &info = m_readyUtfsServers[i];
if (info.proc.data() == sender()) {
const QByteArray &output = info.proc->readAllStandardError();
qWarning("%s: %s", Q_FUNC_INFO, output.data());
info.output += output;
}
}
}
void MaemoRemoteMounter::handleUtfsServerError(QProcess::ProcessError procError)
{
if (procError != QProcess::FailedToStart)
return;
for (int i = 0; i < m_startedUtfsServers.count(); ++i) {
const UtfsServerInfo info = m_startedUtfsServers.at(i);
if (info.proc.data() == sender()) {
QString errorString = info.proc->errorString();
if (!info.output.isEmpty()) {
errorString += tr("\nstderr was: %1")
.arg(QString::fromLocal8Bit(info.output));
}
emit error(errorMsg);
killAllUtfsServers();
m_utfsServerTimer->stop();
emit error(tr("Could not start UTFS server: %1").arg(errorString));
return;
}
m_utfsServers << utfsServerProc;
}
emit mounted();
qWarning("%s: Process failed to start", Q_FUNC_INFO);
}
void MaemoRemoteMounter::handleUtfsServerFinished(int exitCode,
QProcess::ExitStatus exitStatus)
{
if (exitStatus == QProcess::NormalExit && exitCode == 0)
return;
for (int i = 0; i < m_startedUtfsServers.count(); ++i) {
const UtfsServerInfo info = m_startedUtfsServers.at(i);
if (info.proc.data() == sender()) {
QString errorString = info.proc->errorString();
if (!info.output.isEmpty()) {
errorString += tr("\nstderr was: %1")
.arg(QString::fromLocal8Bit(info.output));
}
killAllUtfsServers();
m_utfsServerTimer->stop();
emit error(tr("UTFS server finished unexpectedly: %1").arg(errorString));
return;
}
}
}
void MaemoRemoteMounter::handleUtfsClientStderr(const QByteArray &output)
......@@ -327,5 +398,32 @@ QString MaemoRemoteMounter::utfsServer() const
return m_toolChain->maddeRoot() + QLatin1String("/madlib/utfs-server");
}
void MaemoRemoteMounter::killAllUtfsServers()
{
foreach (const UtfsServerInfo &info, m_startedUtfsServers)
killUtfsServer(info.proc.data());
m_startedUtfsServers.clear();
foreach (const UtfsServerInfo &info, m_readyUtfsServers)
killUtfsServer(info.proc.data());
m_readyUtfsServers.clear();
}
void MaemoRemoteMounter::killUtfsServer(QProcess *proc)
{
disconnect(proc, 0, this, 0);
proc->terminate();
proc->waitForFinished(1000);
proc->kill();
}
void MaemoRemoteMounter::handleUtfsServerTimeout()
{
if (m_stop)
return;
killAllUtfsServers();
emit error(tr("Timeout waiting for UTFS servers to connect."));
}
} // namespace Internal
} // namespace Qt4ProjectManager
......@@ -37,10 +37,11 @@
#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QProcess>
#include <QtCore/QSharedPointer>
#include <QtCore/QString>
QT_FORWARD_DECLARE_CLASS(QProcess);
QT_FORWARD_DECLARE_CLASS(QTimer);
namespace Core {
class SftpChannel;
......@@ -61,6 +62,7 @@ public:
void setPortList(const MaemoPortList &portList) { m_portList = portList; }
bool addMountSpecification(const MaemoMountSpecification &mountSpec,
bool mountAsRoot);
void resetMountSpecifications() { m_mountSpecs.clear(); }
void mount();
void unmount();
void stop();
......@@ -81,16 +83,24 @@ private slots:
void handleUtfsClientsFinished(int exitStatus);
void handleUnmountProcessFinished(int exitStatus);
void handleUtfsClientStderr(const QByteArray &output);
void handleUtfsServerStderr();
void handleUtfsServerError(QProcess::ProcessError error);
void handleUtfsServerFinished(int exitCode,
QProcess::ExitStatus exitStatus);
void handleUmountStderr(const QByteArray &output);
void handleUtfsServerTimeout();
private:
void deployUtfsClient();
void startUtfsClients();
void startUtfsServers();
void killUtfsServer(QProcess *proc);
void killAllUtfsServers();
QString utfsClientOnDevice() const;
QString utfsServer() const;
const MaemoToolChain * const m_toolChain;
QTimer * const m_utfsServerTimer;
struct MountInfo {
MountInfo(const MaemoMountSpecification &m, int port, bool root)
......@@ -108,7 +118,14 @@ private:
Core::SftpJobId m_uploadJobId;
typedef QSharedPointer<QProcess> ProcPtr;
QList<ProcPtr> m_utfsServers;
struct UtfsServerInfo {
UtfsServerInfo(const ProcPtr &p) : proc(p) {}
ProcPtr proc;
QByteArray output;
};
QList<UtfsServerInfo> m_startedUtfsServers;
QList<UtfsServerInfo> m_readyUtfsServers;
bool m_stop;
QByteArray m_utfsClientStderr;
QByteArray m_umountStderr;
......
......@@ -187,6 +187,7 @@ void MaemoSshRunner::handleUnmounted()
case InitialUnmount: {
if (m_stop)
return;
m_mounter->resetMountSpecifications();
MaemoPortList portList = m_devConfig.freePorts();
if (m_debugging && !m_runConfig->useRemoteGdb())
portList.getNext(); // One has already been used for gdbserver.
......@@ -214,6 +215,7 @@ void MaemoSshRunner::handleUnmounted()
break;
case ShutdownUnmount:
Q_ASSERT(m_shuttingDown);
m_mounter->resetMountSpecifications();
m_shuttingDown = false;
if (m_exitStatus == SshRemoteProcess::ExitedNormally) {
emit remoteProcessFinished(m_runner->exitCode());
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment