Summary: | akonadi server does not work with afs homes | ||
---|---|---|---|
Product: | [Frameworks and Libraries] Akonadi | Reporter: | Andrej Filipcic <andrej.filipcic> |
Component: | server | Assignee: | Volker Krause <vkrause> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | andrej.filipcic, ComputerDruid, cordlandwehr, davidben, dirk.heinrichs, faure, hephooey_dev, Martin.Vala, rdieter, stijn, TAGeorgiou, tokoe, tuju |
Priority: | NOR | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Platform: | Compiled Sources | ||
OS: | Linux | ||
Latest Commit: | Version Fixed In: |
Description
Andrej Filipcic
2008-12-29 00:29:41 UTC
Also note that firefox nor opensync does not work as they try to make pipes into home dir too. I saw this today on some afs-homed workstations. Firefox DOES work on these workstations however... a /tmp/kde-username location as an option would be much appreciated. i had problem with AFS too,so i did mkdir -p /tmp/kde-$USER/akonadi ln -s /tmp/kde-$USER/akonadi/ $HOME/.local/share/ and it worked. But i don't like this solution. i did it also because i had timeout error when i started clean KDE4 (i cleaned my $HOME/.kde4) so my solution was to put mkdir -p /tmp/kde-$USER/akonadi ln -s /tmp/kde-$USER/akonadi/ $HOME/.local/share/ in to /etc/kde/startup/agent-startup.sh (I use gentoo linux) i had problem with AFS too,so i did mkdir -p /tmp/kde-$USER/akonadi ln -s /tmp/kde-$USER/akonadi/ $HOME/.local/share/ and it worked. But i don't like this solution. i did it also because i had timeout error when i started clean KDE4 (i cleaned my $HOME/.kde4) so my solution was to put mkdir -p /tmp/kde-$USER/akonadi ln -s /tmp/kde-$USER/akonadi/ $HOME/.local/share/ in to /etc/kde/startup/agent-startup.sh (I use gentoo linux) Hej, in the current version of Akonadi server you can specify a custom socket path by entering [Connection] SocketDirectory=/tmp/akonadi-myuser/ into $HOME/.config/akonadi/akonadiserverrc Could it be set up somehow to be globally configured? I would imagine most deployments of AFS apply to all users (for instance, MIT's Athena system). We would certainly prefer a solution which did not involve customizing a configuration file separately per-user. What if the string was a template and accepted $USER somewhere? Or perhaps the underlying code could automatically fallback to /tmp/akonadi-$USER when creating the local socket fails. Can a solution similar to kde's ~/.kde/socket-<hostname> => /tmp/ksocket-<username> symlink be used in akonadi too? Same bug as bug 182292 I suppose? My suggestion on how to fix it is there: https://bugs.kde.org/show_bug.cgi?id=182292#c6 *** This bug has been confirmed by popular vote. *** Yes the lnusertemp solution (make symlink if possible, otherwise mkdir) as used by $KDEHOME/ksocket-$HOSTNAME would be better than a configurable path. No configuration needed, it would just work out of the box for all users. Reopening this one, which IMHO makes 203460 unnecessary. *** Bug 250107 has been marked as a duplicate of this bug. *** commit e4affdfc2922efc10b647939fd4e068c02e256eb branch master Author: Tobias Koenig <tokoe@kde.org> Date: Mon Dec 6 19:56:07 2010 +0100 Use symlink to /tmp as socket directory by default This patch is based on the one written by Ansgar Burchardt to use a socket directory linked to /tmp/<username>-akonadi.<random> instead of the hard-coded one from ~/.local/share/akonadi. With this patch Akonadi will start on systems with $HOME on AFS without any further configuration needed. BUG: 179006 diff --git a/server/src/utils.cpp b/server/src/utils.cpp index 37949db..4575292 100644 --- a/server/src/utils.cpp +++ b/server/src/utils.cpp @@ -22,9 +22,21 @@ #include "libs/xdgbasedirs_p.h" +#include <QtCore/QDebug> #include <QtCore/QDir> #include <QtCore/QFileInfo> #include <QtCore/QSettings> +#include <QtNetwork/QHostInfo> + +#include <cerrno> +#include <cstdlib> +#include <pwd.h> +#include <sys/types.h> +#include <unistd.h> + +static QString akonadiSocketDirectory(); +static bool checkSocketDirectory( const QString &path ); +static bool createSocketDirectory( const QString &link, const QString &tmpl ); using namespace Akonadi; @@ -33,7 +45,16 @@ QString Utils::preferredSocketDirectory( const QString &defaultDirectory ) const QString serverConfigFile = XdgBaseDirs::akonadiServerConfigFile( XdgBaseDirs::ReadWrite ); const QSettings serverSettings( serverConfigFile, QSettings::IniFormat ); - QString socketDir = serverSettings.value( QLatin1String( "Connection/SocketDirectory" ), defaultDirectory ).toString(); + QString socketDir = defaultDirectory; + if ( !serverSettings.contains( QLatin1String( "Connection/SocketDirectory" ) ) ) { + // if no socket directory is defined, use the symlinked from /tmp + socketDir = akonadiSocketDirectory(); + + if ( socketDir.isEmpty() ) // if that does not work, fall back on default + socketDir = defaultDirectory; + } else { + socketDir = serverSettings.value( QLatin1String( "Connection/SocketDirectory" ), defaultDirectory ).toString(); + } const QString userName = QString::fromLocal8Bit( qgetenv( "USER" ) ); if ( socketDir.contains( QLatin1String( "$USER" ) ) && !userName.isEmpty() ) @@ -50,3 +71,74 @@ QString Utils::preferredSocketDirectory( const QString &defaultDirectory ) return socketDir; } + +QString akonadiSocketDirectory() +{ + const QString hostname = QHostInfo::localHostName(); + + if ( hostname.isEmpty() ) { + qCritical() << "QHostInfo::localHostName() failed"; + return QString(); + } + + const uid_t uid = getuid(); + const struct passwd *pw_ent = getpwuid( uid ); + if ( !pw_ent ) { + qCritical() << "Could not get passwd entry for user id" << uid; + return QString(); + } + + const QString link = XdgBaseDirs::saveDir( "data", QLatin1String( "akonadi" ) ) + QLatin1Char( '/' ) + QLatin1String( "socket-" ) + hostname; + const QString tmpl = QLatin1String( "akonadi-" ) + QLatin1String( pw_ent->pw_name ) + QLatin1String( ".XXXXXX" ); + + if ( checkSocketDirectory( link ) ) + return link; + + if ( createSocketDirectory( link, tmpl ) ) + return link; + + qCritical() << "Could not create socket directory for Akonadi."; + return QString(); +} + +static bool checkSocketDirectory( const QString &path ) +{ + QFileInfo info( path ); + + if ( !info.exists() ) + return false; + + if ( info.isSymLink() ) + info = QFileInfo( info.symLinkTarget() ); + + if ( !info.isDir() ) + return false; + + if ( info.ownerId() != getuid() ) + return false; + + return true; +} + +static bool createSocketDirectory( const QString &link, const QString &tmpl ) +{ + QString directory = QString::fromLatin1( "%1%2%3" ).arg( QDir::tempPath() ).arg( QDir::separator() ).arg( tmpl ); + + QByteArray directoryString = directory.toLocal8Bit().data(); + + if ( !mkdtemp( directoryString.data() ) ) { + qCritical() << "Creating socket directory with template" << directoryString << "failed:" << strerror( errno ); + return false; + } + + directory = QString::fromLocal8Bit( directoryString ); + + QFile::remove( link ); + + if ( !QFile::link( directory, link ) ) { + qCritical() << "Creating symlink from" << directory << "to" << link << "failed"; + return false; + } + + return true; +} This change in git will cause trouble with old akonadi config files where the socket has been set to $HOME/.local/share/akonadi/db_misc/mysql.socket, akonadi will crash with the error message like: Last driver error: "QMYSQL: Unable to connect" Last database error: "Can't connect to local MySQL server through socket '/home/luran/.local/share/akonadi/db_misc/mysql.socket' (2)" Unable to open database "Can't connect to local MySQL server through socket '/home/luran/.local/share/akonadi/db_misc/mysql.socket' (2) QMYSQL: Unable to connect" And multiple mysqld will be started. There should be some announcement beside the commit log, or some code to fix the path automatically. (In reply to comment #13) > This change in git will cause trouble with old akonadi config files where the > socket has been set to $HOME/.local/share/akonadi/db_misc/mysql.socket, > akonadi will crash with the error message like: This has been fixed in the meantime. |