Changeset View
Changeset View
Standalone View
Standalone View
src/server/storage/dbconfigmysql.cpp
Show All 36 Lines | |||||
37 | using namespace Akonadi; | 37 | using namespace Akonadi; | ||
38 | using namespace Akonadi::Server; | 38 | using namespace Akonadi::Server; | ||
39 | 39 | | |||
40 | #define MYSQL_MIN_MAJOR 5 | 40 | #define MYSQL_MIN_MAJOR 5 | ||
41 | #define MYSQL_MIN_MINOR 1 | 41 | #define MYSQL_MIN_MINOR 1 | ||
42 | 42 | | |||
43 | #define MYSQL_VERSION_CHECK(major, minor, patch) ((major << 16) | (minor << 8) | patch) | 43 | #define MYSQL_VERSION_CHECK(major, minor, patch) ((major << 16) | (minor << 8) | patch) | ||
44 | 44 | | |||
45 | static const QString s_mysqlSocketFileName = QStringLiteral("mysql.socket"); | ||||
46 | | ||||
45 | DbConfigMysql::DbConfigMysql() | 47 | DbConfigMysql::DbConfigMysql() | ||
46 | : mInternalServer(true) | 48 | : mInternalServer(true) | ||
47 | , mDatabaseProcess(nullptr) | 49 | , mDatabaseProcess(nullptr) | ||
48 | { | 50 | { | ||
49 | } | 51 | } | ||
50 | 52 | | |||
51 | QString DbConfigMysql::driverName() const | 53 | QString DbConfigMysql::driverName() const | ||
52 | { | 54 | { | ||
Show All 28 Lines | |||||
81 | { | 83 | { | ||
82 | // determine default settings depending on the driver | 84 | // determine default settings depending on the driver | ||
83 | QString defaultHostName; | 85 | QString defaultHostName; | ||
84 | QString defaultOptions; | 86 | QString defaultOptions; | ||
85 | QString defaultServerPath; | 87 | QString defaultServerPath; | ||
86 | QString defaultCleanShutdownCommand; | 88 | QString defaultCleanShutdownCommand; | ||
87 | 89 | | |||
88 | #ifndef Q_OS_WIN | 90 | #ifndef Q_OS_WIN | ||
89 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc"))); | 91 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc")), | ||
92 | s_mysqlSocketFileName.length()); | ||||
90 | #endif | 93 | #endif | ||
91 | 94 | | |||
92 | const bool defaultInternalServer = true; | 95 | const bool defaultInternalServer = true; | ||
93 | #ifdef MYSQLD_EXECUTABLE | 96 | #ifdef MYSQLD_EXECUTABLE | ||
94 | if (QFile::exists(QStringLiteral(MYSQLD_EXECUTABLE))) { | 97 | if (QFile::exists(QStringLiteral(MYSQLD_EXECUTABLE))) { | ||
95 | defaultServerPath = QStringLiteral(MYSQLD_EXECUTABLE); | 98 | defaultServerPath = QStringLiteral(MYSQLD_EXECUTABLE); | ||
96 | } | 99 | } | ||
97 | #endif | 100 | #endif | ||
98 | if (defaultServerPath.isEmpty()) { | 101 | if (defaultServerPath.isEmpty()) { | ||
99 | defaultServerPath = findExecutable(QStringLiteral("mysqld")); | 102 | defaultServerPath = findExecutable(QStringLiteral("mysqld")); | ||
100 | } | 103 | } | ||
101 | 104 | | |||
102 | const QString mysqladminPath = findExecutable(QStringLiteral("mysqladmin")); | 105 | const QString mysqladminPath = findExecutable(QStringLiteral("mysqladmin")); | ||
103 | if (!mysqladminPath.isEmpty()) { | 106 | if (!mysqladminPath.isEmpty()) { | ||
104 | #ifndef Q_OS_WIN | 107 | #ifndef Q_OS_WIN | ||
105 | defaultCleanShutdownCommand = QStringLiteral("%1 --defaults-file=%2/mysql.conf --socket=%3/mysql.socket shutdown") | 108 | defaultCleanShutdownCommand = QStringLiteral("%1 --defaults-file=%2/mysql.conf --socket=%3/%4 shutdown") | ||
106 | .arg(mysqladminPath, StandardDirs::saveDir("data"), socketDirectory); | 109 | .arg(mysqladminPath, StandardDirs::saveDir("data"), socketDirectory, s_mysqlSocketFileName); | ||
107 | #else | 110 | #else | ||
108 | defaultCleanShutdownCommand = QString::fromLatin1("%1 shutdown --shared-memory").arg(mysqladminPath); | 111 | defaultCleanShutdownCommand = QString::fromLatin1("%1 shutdown --shared-memory").arg(mysqladminPath); | ||
109 | #endif | 112 | #endif | ||
110 | } | 113 | } | ||
111 | 114 | | |||
112 | mMysqlInstallDbPath = findExecutable(QStringLiteral("mysql_install_db")); | 115 | mMysqlInstallDbPath = findExecutable(QStringLiteral("mysql_install_db")); | ||
113 | qCDebug(AKONADISERVER_LOG) << "Found mysql_install_db: " << mMysqlInstallDbPath; | 116 | qCDebug(AKONADISERVER_LOG) << "Found mysql_install_db: " << mMysqlInstallDbPath; | ||
114 | 117 | | |||
115 | mMysqlCheckPath = findExecutable(QStringLiteral("mysqlcheck")); | 118 | mMysqlCheckPath = findExecutable(QStringLiteral("mysqlcheck")); | ||
116 | qCDebug(AKONADISERVER_LOG) << "Found mysqlcheck: " << mMysqlCheckPath; | 119 | qCDebug(AKONADISERVER_LOG) << "Found mysqlcheck: " << mMysqlCheckPath; | ||
117 | 120 | | |||
118 | mInternalServer = settings.value(QStringLiteral("QMYSQL/StartServer"), defaultInternalServer).toBool(); | 121 | mInternalServer = settings.value(QStringLiteral("QMYSQL/StartServer"), defaultInternalServer).toBool(); | ||
119 | #ifndef Q_OS_WIN | 122 | #ifndef Q_OS_WIN | ||
120 | if (mInternalServer) { | 123 | if (mInternalServer) { | ||
121 | defaultOptions = QStringLiteral("UNIX_SOCKET=%1/mysql.socket").arg(socketDirectory); | 124 | defaultOptions = QStringLiteral("UNIX_SOCKET=%1/%2").arg(socketDirectory, s_mysqlSocketFileName); | ||
122 | } | 125 | } | ||
123 | #endif | 126 | #endif | ||
124 | 127 | | |||
125 | // read settings for current driver | 128 | // read settings for current driver | ||
126 | settings.beginGroup(driverName()); | 129 | settings.beginGroup(driverName()); | ||
127 | mDatabaseName = settings.value(QStringLiteral("Name"), defaultDatabaseName()).toString(); | 130 | mDatabaseName = settings.value(QStringLiteral("Name"), defaultDatabaseName()).toString(); | ||
128 | mHostName = settings.value(QStringLiteral("Host"), defaultHostName).toString(); | 131 | mHostName = settings.value(QStringLiteral("Host"), defaultHostName).toString(); | ||
129 | mUserName = settings.value(QStringLiteral("User")).toString(); | 132 | mUserName = settings.value(QStringLiteral("User")).toString(); | ||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Line(s) | |||||
195 | 198 | | |||
196 | bool DbConfigMysql::startInternalServer() | 199 | bool DbConfigMysql::startInternalServer() | ||
197 | { | 200 | { | ||
198 | bool success = true; | 201 | bool success = true; | ||
199 | 202 | | |||
200 | const QString akDir = StandardDirs::saveDir("data"); | 203 | const QString akDir = StandardDirs::saveDir("data"); | ||
201 | const QString dataDir = StandardDirs::saveDir("data", QStringLiteral("db_data")); | 204 | const QString dataDir = StandardDirs::saveDir("data", QStringLiteral("db_data")); | ||
202 | #ifndef Q_OS_WIN | 205 | #ifndef Q_OS_WIN | ||
203 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc"))); | 206 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc")), | ||
204 | const QString socketFile = QStringLiteral("%1/mysql.socket").arg(socketDirectory); | 207 | s_mysqlSocketFileName.length()); | ||
208 | const QString socketFile = QStringLiteral("%1/%2").arg(socketDirectory, s_mysqlSocketFileName); | ||||
205 | const QString pidFileName = QStringLiteral("%1/mysql.pid").arg(socketDirectory); | 209 | const QString pidFileName = QStringLiteral("%1/mysql.pid").arg(socketDirectory); | ||
206 | #endif | 210 | #endif | ||
207 | 211 | | |||
208 | // generate config file | 212 | // generate config file | ||
209 | const QString globalConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-global.conf")); | 213 | const QString globalConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-global.conf")); | ||
210 | const QString localConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-local.conf")); | 214 | const QString localConfig = StandardDirs::locateResourceFile("config", QStringLiteral("mysql-local.conf")); | ||
211 | const QString actualConfig = StandardDirs::saveDir("data") + QLatin1String("/mysql.conf"); | 215 | const QString actualConfig = StandardDirs::saveDir("data") + QLatin1String("/mysql.conf"); | ||
212 | if (globalConfig.isEmpty()) { | 216 | if (globalConfig.isEmpty()) { | ||
▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Line(s) | 297 | #ifndef Q_OS_WIN | |||
297 | } | 301 | } | ||
298 | 302 | | |||
299 | // the socket path must not exceed 103 characters, so check for max dir length right away | 303 | // the socket path must not exceed 103 characters, so check for max dir length right away | ||
300 | if (socketDirectory.length() >= 90) { | 304 | if (socketDirectory.length() >= 90) { | ||
301 | qCCritical(AKONADISERVER_LOG) << "MySQL cannot deal with a socket path this long. Path was: " << socketDirectory; | 305 | qCCritical(AKONADISERVER_LOG) << "MySQL cannot deal with a socket path this long. Path was: " << socketDirectory; | ||
302 | return false; | 306 | return false; | ||
303 | } | 307 | } | ||
304 | 308 | | |||
305 | // If mysql.socket file exists, check if also the server process is still running, | 309 | // If mysql socket file exists, check if also the server process is still running, | ||
306 | // else we can safely remove the socket file (cleanup after a system crash, etc.) | 310 | // else we can safely remove the socket file (cleanup after a system crash, etc.) | ||
307 | QFile pidFile(pidFileName); | 311 | QFile pidFile(pidFileName); | ||
308 | if (QFile::exists(socketFile) && pidFile.open(QIODevice::ReadOnly)) { | 312 | if (QFile::exists(socketFile) && pidFile.open(QIODevice::ReadOnly)) { | ||
309 | qCDebug(AKONADISERVER_LOG) << "Found a mysqld pid file, checking whether the server is still running..."; | 313 | qCDebug(AKONADISERVER_LOG) << "Found a mysqld pid file, checking whether the server is still running..."; | ||
310 | QByteArray pid = pidFile.readLine().trimmed(); | 314 | QByteArray pid = pidFile.readLine().trimmed(); | ||
311 | QFile proc(QString::fromLatin1("/proc/" + pid + "/stat")); | 315 | QFile proc(QString::fromLatin1("/proc/" + pid + "/stat")); | ||
312 | // Check whether the process with the PID from pidfile still exists and whether | 316 | // Check whether the process with the PID from pidfile still exists and whether | ||
313 | // it's actually still mysqld or, whether the PID has been recycled in the meanwhile. | 317 | // it's actually still mysqld or, whether the PID has been recycled in the meanwhile. | ||
Show All 29 Lines | |||||
343 | #ifndef Q_OS_WIN | 347 | #ifndef Q_OS_WIN | ||
344 | arguments << QStringLiteral("--socket=%1").arg(socketFile); | 348 | arguments << QStringLiteral("--socket=%1").arg(socketFile); | ||
345 | arguments << QStringLiteral("--pid-file=%1").arg(pidFileName); | 349 | arguments << QStringLiteral("--pid-file=%1").arg(pidFileName); | ||
346 | #else | 350 | #else | ||
347 | arguments << QString::fromLatin1("--shared-memory"); | 351 | arguments << QString::fromLatin1("--shared-memory"); | ||
348 | #endif | 352 | #endif | ||
349 | 353 | | |||
350 | #ifndef Q_OS_WIN | 354 | #ifndef Q_OS_WIN | ||
351 | // If mysql.socket file does not exists, then we must start the server, | 355 | // If mysql socket file does not exists, then we must start the server, | ||
352 | // otherwise we reconnect to it | 356 | // otherwise we reconnect to it | ||
353 | if (!QFile::exists(socketFile)) { | 357 | if (!QFile::exists(socketFile)) { | ||
354 | // move mysql error log file out of the way | 358 | // move mysql error log file out of the way | ||
355 | const QFileInfo errorLog(dataDir + QDir::separator() + QLatin1String("mysql.err")); | 359 | const QFileInfo errorLog(dataDir + QDir::separator() + QLatin1String("mysql.err")); | ||
356 | if (errorLog.exists()) { | 360 | if (errorLog.exists()) { | ||
357 | QFile logFile(errorLog.absoluteFilePath()); | 361 | QFile logFile(errorLog.absoluteFilePath()); | ||
358 | QFile oldLogFile(dataDir + QDir::separator() + QLatin1String("mysql.err.old")); | 362 | QFile oldLogFile(dataDir + QDir::separator() + QLatin1String("mysql.err.old")); | ||
359 | if (logFile.open(QFile::ReadOnly) && oldLogFile.open(QFile::Append)) { | 363 | if (logFile.open(QFile::ReadOnly) && oldLogFile.open(QFile::Append)) { | ||
Show All 38 Lines | |||||
398 | connect(mDatabaseProcess, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &DbConfigMysql::processFinished); | 402 | connect(mDatabaseProcess, QOverload<int,QProcess::ExitStatus>::of(&QProcess::finished), this, &DbConfigMysql::processFinished); | ||
399 | 403 | | |||
400 | // wait until mysqld has created the socket file (workaround for QTBUG-47475 in Qt5.5.0) | 404 | // wait until mysqld has created the socket file (workaround for QTBUG-47475 in Qt5.5.0) | ||
401 | int counter = 50; // avoid an endless loop in case mysqld terminated | 405 | int counter = 50; // avoid an endless loop in case mysqld terminated | ||
402 | while ((counter-- > 0) && !QFileInfo::exists(socketFile)) { | 406 | while ((counter-- > 0) && !QFileInfo::exists(socketFile)) { | ||
403 | QThread::msleep(100); | 407 | QThread::msleep(100); | ||
404 | } | 408 | } | ||
405 | } else { | 409 | } else { | ||
406 | qCDebug(AKONADISERVER_LOG) << "Found mysql.socket file, reconnecting to the database"; | 410 | qCDebug(AKONADISERVER_LOG) << "Found " << qPrintable(s_mysqlSocketFileName) << " file, reconnecting to the database"; | ||
407 | } | 411 | } | ||
408 | #endif | 412 | #endif | ||
409 | 413 | | |||
410 | const QLatin1String initCon("initConnection"); | 414 | const QLatin1String initCon("initConnection"); | ||
411 | { | 415 | { | ||
412 | QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QMYSQL"), initCon); | 416 | QSqlDatabase db = QSqlDatabase::addDatabase(QStringLiteral("QMYSQL"), initCon); | ||
413 | apply(db); | 417 | apply(db); | ||
414 | 418 | | |||
Show All 22 Lines | |||||
437 | } | 441 | } | ||
438 | 442 | | |||
439 | if (opened) { | 443 | if (opened) { | ||
440 | if (!mMysqlCheckPath.isEmpty()) { | 444 | if (!mMysqlCheckPath.isEmpty()) { | ||
441 | execute(mMysqlCheckPath, { QStringLiteral("--defaults-file=%1/mysql.conf").arg(akDir), | 445 | execute(mMysqlCheckPath, { QStringLiteral("--defaults-file=%1/mysql.conf").arg(akDir), | ||
442 | QStringLiteral("--check-upgrade"), | 446 | QStringLiteral("--check-upgrade"), | ||
443 | QStringLiteral("--auto-repair"), | 447 | QStringLiteral("--auto-repair"), | ||
444 | #ifndef Q_OS_WIN | 448 | #ifndef Q_OS_WIN | ||
445 | QStringLiteral("--socket=%1/mysql.socket").arg(socketDirectory), | 449 | QStringLiteral("--socket=%1/%2").arg(socketDirectory, s_mysqlSocketFileName), | ||
446 | #endif | 450 | #endif | ||
447 | mDatabaseName | 451 | mDatabaseName | ||
448 | }); | 452 | }); | ||
449 | } | 453 | } | ||
450 | 454 | | |||
451 | // Verify MySQL version | 455 | // Verify MySQL version | ||
452 | { | 456 | { | ||
453 | QSqlQuery query(db); | 457 | QSqlQuery query(db); | ||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Line(s) | 512 | { | |||
509 | Q_UNUSED(exitCode); | 513 | Q_UNUSED(exitCode); | ||
510 | Q_UNUSED(exitStatus); | 514 | Q_UNUSED(exitStatus); | ||
511 | 515 | | |||
512 | qCCritical(AKONADISERVER_LOG) << "database server stopped unexpectedly"; | 516 | qCCritical(AKONADISERVER_LOG) << "database server stopped unexpectedly"; | ||
513 | 517 | | |||
514 | #ifndef Q_OS_WIN | 518 | #ifndef Q_OS_WIN | ||
515 | // when the server stopped unexpectedly, make sure to remove the stale socket file since otherwise | 519 | // when the server stopped unexpectedly, make sure to remove the stale socket file since otherwise | ||
516 | // it can not be started again | 520 | // it can not be started again | ||
517 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc"))); | 521 | const QString socketDirectory = Utils::preferredSocketDirectory(StandardDirs::saveDir("data", QStringLiteral("db_misc")), | ||
518 | const QString socketFile = QStringLiteral("%1/mysql.socket").arg(socketDirectory); | 522 | s_mysqlSocketFileName.length()); | ||
523 | const QString socketFile = QStringLiteral("%1/%2").arg(socketDirectory, s_mysqlSocketFileName); | ||||
519 | QFile::remove(socketFile); | 524 | QFile::remove(socketFile); | ||
520 | #endif | 525 | #endif | ||
521 | 526 | | |||
522 | QCoreApplication::quit(); | 527 | QCoreApplication::quit(); | ||
523 | } | 528 | } | ||
524 | 529 | | |||
525 | void DbConfigMysql::stopInternalServer() | 530 | void DbConfigMysql::stopInternalServer() | ||
526 | { | 531 | { | ||
▲ Show 20 Lines • Show All 102 Lines • Show Last 20 Lines |