patch-src_db_SimpleDatabasePlugin_cxx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. --- mpd-0.18.5.orig/src/db/SimpleDatabasePlugin.cxx 2013-11-22 00:33:30.000000000 +0100
  2. +++ mpd-0.18.5/src/db/SimpleDatabasePlugin.cxx 2013-11-30 19:17:55.000000000 +0100
  3. @@ -35,6 +35,9 @@
  4. #include <sys/types.h>
  5. #include <errno.h>
  6. +#include <sys/mount.h>
  7. +#include <mntent.h>
  8. +#include <string.h>
  9. static constexpr Domain simple_db_domain("simple_db");
  10. @@ -95,8 +98,8 @@ SimpleDatabase::Check(Error &error) cons
  11. return false;
  12. }
  13. - /* Check if we can write to the directory */
  14. - if (!CheckAccess(dirPath, X_OK | W_OK)) {
  15. + /* Check if we can change into the directory */
  16. + if (!CheckAccess(dirPath, X_OK)) {
  17. const int e = errno;
  18. const std::string dirPath_utf8 = dirPath.ToUTF8();
  19. error.FormatErrno(e, "Can't create db file in \"%s\"",
  20. @@ -122,9 +125,9 @@ SimpleDatabase::Check(Error &error) cons
  21. return false;
  22. }
  23. - /* And check that we can write to it */
  24. - if (!CheckAccess(path, R_OK | W_OK)) {
  25. - error.FormatErrno("Can't open db file \"%s\" for reading/writing",
  26. + /* And check that we can read it */
  27. + if (!CheckAccess(path, R_OK)) {
  28. + error.FormatErrno("Can't open db file \"%s\" for reading",
  29. path_utf8.c_str());
  30. return false;
  31. }
  32. @@ -281,6 +284,10 @@ SimpleDatabase::GetStats(const DatabaseS
  33. bool
  34. SimpleDatabase::Save(Error &error)
  35. {
  36. + struct mntent *mnt;
  37. + int remount;
  38. + FILE *f;
  39. +
  40. db_lock();
  41. LogDebug(simple_db_domain, "removing empty directories from DB");
  42. @@ -293,6 +300,26 @@ SimpleDatabase::Save(Error &error)
  43. LogDebug(simple_db_domain, "writing DB");
  44. + remount = 0;
  45. + /* check if /data is mounted read-only */
  46. + if ((f = setmntent("/proc/mounts", "r")) == NULL)
  47. + error.Format(simple_db_domain, "Checking /proc/mounts failed");
  48. +
  49. + while ((mnt = getmntent(f)) != NULL) {
  50. + if (strcmp(mnt->mnt_dir, "/data") == 0 &&
  51. + hasmntopt(mnt, MNTOPT_RO) != NULL) {
  52. + remount = 1;
  53. + }
  54. + }
  55. + endmntent(f);
  56. +
  57. + if (remount) {
  58. + if (mount("","/data",0,MS_REMOUNT,0)<0) {
  59. + error.Format(simple_db_domain, "Remounting /data rw failed");
  60. + }
  61. + LogDebug(simple_db_domain, "Mounted /data successfully in read-write mode");
  62. + }
  63. +
  64. FILE *fp = FOpen(path, FOpenMode::WriteText);
  65. if (!fp) {
  66. error.FormatErrno("unable to write to db file \"%s\"",
  67. @@ -310,6 +337,16 @@ SimpleDatabase::Save(Error &error)
  68. fclose(fp);
  69. + if (remount) {
  70. + sync();
  71. + if (mount("","/data",0,MS_REMOUNT|MS_RDONLY,0)<0) {
  72. + error.Format(simple_db_domain, "Remounting /data ro failed");
  73. + }
  74. + LogDebug(simple_db_domain, "Mounted /data successfully in read-only mode");
  75. + }
  76. +
  77. + LogDebug(simple_db_domain, "Successfully written database");
  78. +
  79. struct stat st;
  80. if (StatFile(path, st))
  81. mtime = st.st_mtime;