|
@@ -1,91 +0,0 @@
|
|
|
---- mpd-0.18.5.orig/src/db/SimpleDatabasePlugin.cxx 2013-11-22 00:33:30.000000000 +0100
|
|
|
-+++ mpd-0.18.5/src/db/SimpleDatabasePlugin.cxx 2013-11-30 19:17:55.000000000 +0100
|
|
|
-@@ -35,6 +35,9 @@
|
|
|
-
|
|
|
- #include <sys/types.h>
|
|
|
- #include <errno.h>
|
|
|
-+#include <sys/mount.h>
|
|
|
-+#include <mntent.h>
|
|
|
-+#include <string.h>
|
|
|
-
|
|
|
- static constexpr Domain simple_db_domain("simple_db");
|
|
|
-
|
|
|
-@@ -95,8 +98,8 @@ SimpleDatabase::Check(Error &error) cons
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-- /* Check if we can write to the directory */
|
|
|
-- if (!CheckAccess(dirPath, X_OK | W_OK)) {
|
|
|
-+ /* Check if we can change into the directory */
|
|
|
-+ if (!CheckAccess(dirPath, X_OK)) {
|
|
|
- const int e = errno;
|
|
|
- const std::string dirPath_utf8 = dirPath.ToUTF8();
|
|
|
- error.FormatErrno(e, "Can't create db file in \"%s\"",
|
|
|
-@@ -122,9 +125,9 @@ SimpleDatabase::Check(Error &error) cons
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
-- /* And check that we can write to it */
|
|
|
-- if (!CheckAccess(path, R_OK | W_OK)) {
|
|
|
-- error.FormatErrno("Can't open db file \"%s\" for reading/writing",
|
|
|
-+ /* And check that we can read it */
|
|
|
-+ if (!CheckAccess(path, R_OK)) {
|
|
|
-+ error.FormatErrno("Can't open db file \"%s\" for reading",
|
|
|
- path_utf8.c_str());
|
|
|
- return false;
|
|
|
- }
|
|
|
-@@ -281,6 +284,10 @@ SimpleDatabase::GetStats(const DatabaseS
|
|
|
- bool
|
|
|
- SimpleDatabase::Save(Error &error)
|
|
|
- {
|
|
|
-+ struct mntent *mnt;
|
|
|
-+ int remount;
|
|
|
-+ FILE *f;
|
|
|
-+
|
|
|
- db_lock();
|
|
|
-
|
|
|
- LogDebug(simple_db_domain, "removing empty directories from DB");
|
|
|
-@@ -293,6 +300,26 @@ SimpleDatabase::Save(Error &error)
|
|
|
-
|
|
|
- LogDebug(simple_db_domain, "writing DB");
|
|
|
-
|
|
|
-+ remount = 0;
|
|
|
-+ /* check if /data is mounted read-only */
|
|
|
-+ if ((f = setmntent("/proc/mounts", "r")) == NULL)
|
|
|
-+ error.Format(simple_db_domain, "Checking /proc/mounts failed");
|
|
|
-+
|
|
|
-+ while ((mnt = getmntent(f)) != NULL) {
|
|
|
-+ if (strcmp(mnt->mnt_dir, "/data") == 0 &&
|
|
|
-+ hasmntopt(mnt, MNTOPT_RO) != NULL) {
|
|
|
-+ remount = 1;
|
|
|
-+ }
|
|
|
-+ }
|
|
|
-+ endmntent(f);
|
|
|
-+
|
|
|
-+ if (remount) {
|
|
|
-+ if (mount("","/data",0,MS_REMOUNT,0)<0) {
|
|
|
-+ error.Format(simple_db_domain, "Remounting /data rw failed");
|
|
|
-+ }
|
|
|
-+ LogDebug(simple_db_domain, "Mounted /data successfully in read-write mode");
|
|
|
-+ }
|
|
|
-+
|
|
|
- FILE *fp = FOpen(path, FOpenMode::WriteText);
|
|
|
- if (!fp) {
|
|
|
- error.FormatErrno("unable to write to db file \"%s\"",
|
|
|
-@@ -310,6 +337,16 @@ SimpleDatabase::Save(Error &error)
|
|
|
-
|
|
|
- fclose(fp);
|
|
|
-
|
|
|
-+ if (remount) {
|
|
|
-+ sync();
|
|
|
-+ if (mount("","/data",0,MS_REMOUNT|MS_RDONLY,0)<0) {
|
|
|
-+ error.Format(simple_db_domain, "Remounting /data ro failed");
|
|
|
-+ }
|
|
|
-+ LogDebug(simple_db_domain, "Mounted /data successfully in read-only mode");
|
|
|
-+ }
|
|
|
-+
|
|
|
-+ LogDebug(simple_db_domain, "Successfully written database");
|
|
|
-+
|
|
|
- struct stat st;
|
|
|
- if (StatFile(path, st))
|
|
|
- mtime = st.st_mtime;
|