Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disk I/O error when device is locked #262

Open
Dave005 opened this issue May 6, 2014 · 23 comments
Open

Disk I/O error when device is locked #262

Dave005 opened this issue May 6, 2014 · 23 comments

Comments

@Dave005
Copy link

Dave005 commented May 6, 2014

Hi,

i get the following error if i write to the database when the device is locked:
Unknown error calling sqlite3_step (10: disk I/O error)

i works fine if the app is in running in the background without locking the device.

I'v tried to set the file protection to none with the following code:

currentDB = [FMDatabase databaseWithPath: pathToDatabase];
[[NSFileManager defaultManager] setAttributes:[NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey] ofItemAtPath: pathToDatabase error:&error];

but it will still raise the same error.

Is there something i'm missing ?

@purdyk
Copy link

purdyk commented Jun 24, 2014

I'm also seeing this problem. On a very limited set of devices, I am unable to write to my database when the device is locked in background mode.

@purdyk
Copy link

purdyk commented Jun 24, 2014

I have tracked down this issue. You'll need to set your fileprotection when you open the database.
Add the following flag to the open call for the database:

SQLITE_OPEN_FILEPROTECTION_NONE

in your case,

currentDB = [FMDatabase databaseWithPath:pathToDatabase];
[currentDB openWithFlags:SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_FILEPROTECTION_NONE];

@Dave005
Copy link
Author

Dave005 commented Jun 24, 2014

thanks, i tried setting the file protection at the db file.
I will try ist with your flags !

@ccgus
Copy link
Owner

ccgus commented Jun 25, 2014

Well this is interesting, I've not encountered these flags before. Here's a relevant post from an apple mailing list: http://lists.apple.com/archives/cocoa-dev/2012/Aug/msg00527.html

@rodmaz
Copy link

rodmaz commented Sep 10, 2014

This still does not work in our tests. Even setting SQLITE_OPEN_FILEPROTECTION_NONE makes the file protected. Seems like a bug in SQLite as these flags and implementation was done by Apple.

    [self.dbQueue inDatabase:^(FMDatabase *db) {
        if ( ![db openWithFlags:(SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE | SQLITE_OPEN_FILEPROTECTION_NONE )] )
        {
            DDLogError(@"could not open local data storage database.");
        }
        else
        {
            NSError *fileAttributesError = nil;
            NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[db databasePath] error:&fileAttributesError];
            DDLogVerbose(@"opened local database; %@; file attributes: %@", dbPathURL, fileAttributes);
        }
...

fileAttributes are:

{
    NSFileCreationDate = "2014-09-10 00:45:24 +0000";
    NSFileExtensionHidden = 0;
    NSFileGroupOwnerAccountID = 501;
    NSFileGroupOwnerAccountName = mobile;
    NSFileModificationDate = "2014-09-10 00:45:24 +0000";
    NSFileOwnerAccountID = 501;
    NSFileOwnerAccountName = mobile;
    NSFilePosixPermissions = 420;
    NSFileProtectionKey = NSFileProtectionComplete;
    NSFileReferenceCount = 1;
    NSFileSize = 0;
    NSFileSystemFileNumber = 16846;
    NSFileSystemNumber = 16777219;
    NSFileType = NSFileTypeRegular;
}

@rodmaz
Copy link

rodmaz commented Sep 10, 2014

I can confirm this is an SQLite implementation bug at least on iOS 7.2.1 and iOS 8 (GM).

@purdyk
Copy link

purdyk commented Sep 10, 2014

We're not having any issues on iOS 7.0 - 8.0 using the following to initially open the database:

_database =
    [FMDatabaseQueue databaseQueueWithPath:dbPath
        flags:SQLITE_OPEN_READWRITE |
            SQLITE_OPEN_CREATE |
            SQLITE_OPEN_FILEPROTECTION_NONE];

It looks from your snippet that you're database has already been opened with the default flags.

@rodmaz
Copy link

rodmaz commented Sep 15, 2014

We are having issues when the app runs in background and the device is locked, even though the protection is none.
Also the bug only occurs in INSERTs.

<Warning>: Unknown error calling sqlite3_step (14: unable to open database file) eu
<Warning>: DB Query: INSERT INTO test (testColumn) VALUES (:testColumn)
<Warning>: Unknown error finalizing or resetting statement (14: unable to open database file)
<Warning>: DB Query: INSERT INTO test (testColumn) VALUES (:testColumn)

SELECTs work just fine.

@Moncter
Copy link

Moncter commented Oct 13, 2014

If has passcode and device is locked,write to the database(file) will get disk I/O error.
For some device you can modify open flag(SQLITE_OPEN_FILEPROTECTION_NONE) to solve the problem.But this method is invalid in some other device.Then you can modify the upper directory FileProtection attribute, for example:

[[NSFileManager defaultManager] setAttributes:[NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey] ofItemAtPath:[NSHomeDirectory() stringByAppendingFormat:@"/Documents"] error:NULL];

@javiergonzper
Copy link

@rodmaz I am having the same problem:

 <Warning>: Unknown error calling sqlite3_step (14: unable to open database file) eu
 <Warning>: DB Query: UPDATE control_songs_played SET songs_played = ? WHERE cloud_type = ?
 <Warning>: Unknown error finalizing or resetting statement (14: unable to open database file)

I tried to open the FMDatabaseQueue with:

 sharedDatabase = [[FMDatabaseQueue alloc] initWithPath:dbPath flags:SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE|SQLITE_OPEN_FILEPROTECTION_NONE];

And the problem still there.

I also tried to change the attribures of the folder that contains the SQLite file as said @Moncter that is Documents like in the example.

Any new idea?

@rodmaz
Copy link

rodmaz commented Nov 18, 2014

The problem I had was that the DB was created somewhere else with invalid arguments.
Make sure the DB file is not there before you call databaseQueueWithPath.
Let me know if this does not help.

@javiergonzper
Copy link

Finally my problem was that I can not access to any file on the Sandbox. After a few minutes with the device locked I can not access to the Database but also I can not access to any file on my Sandbox so the problem was there.
I was making many calls to files that does not exist on the Sandbox finally I found the problem using Instruments.

Thanks for your help anyway @rodmaz

@Marviszhao
Copy link

@javiergonzper my problem was similar with yours ,I also can
not access to any file on my Sandbox after device was locked with passcode.did you solved your problem? Thanks.

1904bf8e-af63-4d09-b807-1e9779634186

@javiergonzper
Copy link

Hey @Marviszhao yes.
To fix it you have to give this attibute for any file that you add on your sandbox:

NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey];
if (![[NSFileManager defaultManager] setAttributes:fileAttributes ofItemAtPath:filePath error:nil]) {
    // Deal with the error
}

@Marviszhao
Copy link

@javiergonzper thanks for you advance, I set all file with that attibute and finally it worked!

@hamza1307
Copy link

hi , it work for me but i only can read from the database i can't write .does enyone have this problems ? plz help me i dont know what to do :( thank u

@Marviszhao
Copy link

@hamza1307 did you open database with @purdyk said
_database =
[FMDatabaseQueue databaseQueueWithPath:dbPath
flags:SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_FILEPROTECTION_NONE];

@pateljigar1111
Copy link

thank you very much

@nemesis
Copy link
Contributor

nemesis commented Nov 10, 2015

If used with SQLCipher, SQLITE_OPEN_FILEPROTECTION_NONE seems to be missing. Any idea on why is that?
screen shot 2015-11-10 at 9 52 25 pm

@lqdncel
Copy link

lqdncel commented Nov 13, 2015

Hi,

I got the following error if i write to the database when the device is locked,and my device system is iOS9.1
error message list:
Unknown error calling sqlite3_step (10: disk I/O error)
DB Query: begin exclusive transaction
Unknown error finalizing or resetting statement (10: disk I/O error)

i works fine if the app is in running in the background without locking the device.

I'v tried to set the file protection to none with the following code:

[[NSFileManager defaultManager] setAttributes:[NSDictionary dictionaryWithObject:NSFileProtectionNone forKey:NSFileProtectionKey] ofItemAtPath:document error:NULL];

_dataQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath flags:SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_FILEPROTECTION_NONE];

but it will still raise the same error.And I remember before iOS9.1 system, there have not been Appear this error.

Is there something i'm missing ?

@nemesis
Copy link
Contributor

nemesis commented Nov 13, 2015

@lqdncel not sure that setting NSFileProtectionKey should actually set it. The documentation lists a handful of properties which can be changed by using setAttributes:ofItemAtPath:error but NSFileProtectionKey isn't listed there.

@smking1122
Copy link

has everybody fix this issue?
@nemesis , @lqdncel ,
I use the SQLCipher too, and I set the NSFileProtectionKey to the db file. Also set the _dataQueue = [FMDatabaseQueue databaseQueueWithPath:dbPath flags:SQLITE_OPEN_READWRITE |
SQLITE_OPEN_CREATE |
SQLITE_OPEN_FILEPROTECTION_NONE];

But unfortunately, this issue also exist.
Wait for some guy's help? thx. Also appreciated if you can send me the solution to 274019799@qq.com.

@HEYRIX
Copy link

HEYRIX commented May 24, 2016

Yes it is。I'm find the answer...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests