Hi guys, I'd love some thoughts on this. Of course, finding the right place to put the osl_syncFile took a fair while, but then to discover that the dp_manager was bootstrapping all that UCB-ness just to create and delete a file, twice on startup each time ... we certainly can't be doing an fsync on startup on old file-systems it'd be a killer, and just look like an ultra-slow start.
Anyhow - hopefully this will save someone some theoretical data, or at least give a new idea of where to look for data-loss :-) I also tend to loathe these 'vnd.expand' URLs. I wish we had a simple low-level API for them we could use everywhere, that had the more complex (?) configmgr-ness hooked into it at run-time. Anyhow - hopefully this didn't break some ultra-complicated expansion use-case. Thoughts appreciated, Michael. -- michael.me...@suse.com <><, Pseudo Engineer, itinerant idiot
>From d3192948fe968fc4d6a8ec0e6fda232f265b3c4c Mon Sep 17 00:00:00 2001 From: Michael Meeks <michael.me...@suse.com> Date: Fri, 9 Mar 2012 17:02:32 +0000 Subject: [PATCH] fdo#40607 - osl_syncFile having written, and avoid doing that on start --- desktop/source/deployment/manager/dp_manager.cxx | 64 +++++++++++----------- ucb/source/ucp/file/shell.cxx | 4 ++ 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx index 4f6f6c04..0efa4c0 100644 --- a/desktop/source/deployment/manager/dp_manager.cxx +++ b/desktop/source/deployment/manager/dp_manager.cxx @@ -311,6 +311,36 @@ void PackageManagerImpl::initRegistryBackends() m_xComponentContext ) ); } +// this overcomes previous rumours that the sal API is misleading +// as to whether a directory is truly read-only or not +static bool isMacroURLWriteable( const OUString &rMacro ) +{ + if (rMacro.getLength() < (sal_Int32)sizeof ("vnd.sun.star.expand:")) + return true; + rtl::OUString aURL( rMacro.copy( sizeof ("vnd.sun.star.expand:") - 1 ) ); + ::rtl::Bootstrap::expandMacros( aURL ); + + bool bError; + sal_uInt64 nWritten = 0; + ::osl::File aFile( aURL ); + + bError = aFile.open( osl_File_OpenFlag_Read | + osl_File_OpenFlag_Write | + osl_File_OpenFlag_Create ) != ::osl::FileBase::E_None; + if (!bError) + bError = aFile.write( "1", 1, nWritten ) != ::osl::FileBase::E_None; + if (aFile.close() != ::osl::FileBase::E_None) + bError = true; + if (osl::File::remove( aURL ) != ::osl::FileBase::E_None) + bError = true; + + OSL_TRACE ("local url '%s' -> '%s' %s readonly\n", + rtl::OUStringToOString( rMacro, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ).getStr(), + bError ? "is" : "is not"); + return bError; +} + //______________________________________________________________________________ Reference<deployment::XPackageManager> PackageManagerImpl::create( Reference<XComponentContext> const & xComponentContext, @@ -406,39 +436,9 @@ Reference<deployment::XPackageManager> PackageManagerImpl::create( Reference<XCommandEnvironment> xCmdEnv; try { - //There is no stampURL for the bundled folder + // There is no stampURL for the bundled folder if (!stampURL.isEmpty()) - { -#define CURRENT_STAMP "1" - try { - //The osl file API does not allow to find out if one can write - //into a folder. Therefore we try to write a file. Then we delete - //it, so that it does not hinder uninstallation of OOo - // probe writing: - ::ucbhelper::Content ucbStamp( stampURL, xCmdEnv ); - ::rtl::OString stamp( - RTL_CONSTASCII_STRINGPARAM(CURRENT_STAMP) ); - Reference<io::XInputStream> xData( - ::xmlscript::createInputStream( - ::rtl::ByteSequence( - reinterpret_cast<sal_Int8 const *>(stamp.getStr()), - stamp.getLength() ) ) ); - ucbStamp.writeStream( xData, true /* replace existing */ ); - that->m_readOnly = false; - erase_path( stampURL, xCmdEnv ); - } - catch (const RuntimeException &) { - try { - erase_path( stampURL, xCmdEnv ); - } catch (...) - { - } - throw; - } - catch (const Exception &) { - that->m_readOnly = true; - } - } + that->m_readOnly = !isMacroURLWriteable( stampURL ); if (!that->m_readOnly && !logFile.isEmpty()) { diff --git a/ucb/source/ucp/file/shell.cxx b/ucb/source/ucp/file/shell.cxx index 725820d..86236f0 100644 --- a/ucb/source/ucp/file/shell.cxx +++ b/ucb/source/ucp/file/shell.cxx @@ -1909,6 +1909,10 @@ shell::write( sal_Int32 CommandId, } } while( nReadBytes == nRequestedBytes ); + aFile.sync(); // fsync / flush it to disk. + OSL_TRACE( "fsync'd file '%s'\n", + rtl::OUStringToOString( aUnqPath, RTL_TEXTENCODING_UTF8 ).getStr() ); + err = aFile.close(); if( err != osl::FileBase::E_None ) { -- 1.7.9
_______________________________________________ LibreOffice mailing list LibreOffice@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice