summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAidan MacDonald <amachronic@protonmail.com>2022-06-01 02:00:30 +0100
committerAidan MacDonald <amachronic@protonmail.com>2022-12-03 07:29:42 -0500
commit8f582c90de487c5a29cb61f41a715630cb143d45 (patch)
treee5421113a175a1760e5d9676568f2638eb05c032
parentf033fd390eaf23be3e94cc503c92f065660b4d72 (diff)
downloadrockbox-8f582c90de487c5a29cb61f41a715630cb143d45.tar.gz
rockbox-8f582c90de487c5a29cb61f41a715630cb143d45.zip
tagcache: add a setting for customizing the database path
Add a new setting, database path: /path/to/folder to change where the database files are stored, which allows it to be shared by multiple builds when using multiboot. This avoids the need to maintain a separate copy of the database for each build. This setting can only be set from the config file; it has no menu option yet (due to lack of a GUI to pick the directory). Change-Id: Ide7b3ccdd84abb62b52f900421bd3d101773e093
-rw-r--r--apps/settings.h1
-rw-r--r--apps/settings_list.c2
-rw-r--r--apps/tagcache.c99
-rw-r--r--manual/appendix/config_file_options.tex1
4 files changed, 71 insertions, 32 deletions
diff --git a/apps/settings.h b/apps/settings.h
index 9c5bf0470f..df82ae3687 100644
--- a/apps/settings.h
+++ b/apps/settings.h
@@ -585,6 +585,7 @@ struct user_settings
585 unsigned char autoresume_paths[MAX_PATHNAME+1]; /* colon-separated list */ 585 unsigned char autoresume_paths[MAX_PATHNAME+1]; /* colon-separated list */
586 bool runtimedb; /* runtime database active? */ 586 bool runtimedb; /* runtime database active? */
587 unsigned char tagcache_scan_paths[MAX_PATHNAME+1]; 587 unsigned char tagcache_scan_paths[MAX_PATHNAME+1];
588 unsigned char tagcache_db_path[MAX_PATHNAME+1];
588#endif /* HAVE_TAGCACHE */ 589#endif /* HAVE_TAGCACHE */
589 590
590#if LCD_DEPTH > 1 591#if LCD_DEPTH > 1
diff --git a/apps/settings_list.c b/apps/settings_list.c
index 8aa476a133..eaa3b17e0c 100644
--- a/apps/settings_list.c
+++ b/apps/settings_list.c
@@ -1544,6 +1544,8 @@ const struct settings_list settings[] = {
1544 "gather runtime data", NULL), 1544 "gather runtime data", NULL),
1545 TEXT_SETTING(0, tagcache_scan_paths, "database scan paths", 1545 TEXT_SETTING(0, tagcache_scan_paths, "database scan paths",
1546 DEFAULT_TAGCACHE_SCAN_PATHS, NULL, NULL), 1546 DEFAULT_TAGCACHE_SCAN_PATHS, NULL, NULL),
1547 TEXT_SETTING(0, tagcache_db_path, "database path",
1548 ROCKBOX_DIR, NULL, NULL),
1547#endif 1549#endif
1548 1550
1549 /* replay gain */ 1551 /* replay gain */
diff --git a/apps/tagcache.c b/apps/tagcache.c
index c638665def..228b7cb751 100644
--- a/apps/tagcache.c
+++ b/apps/tagcache.c
@@ -84,6 +84,7 @@
84#include "structec.h" 84#include "structec.h"
85#include "debug.h" 85#include "debug.h"
86#include "dircache.h" 86#include "dircache.h"
87#include "errno.h"
87 88
88#ifndef __PCTOOL__ 89#ifndef __PCTOOL__
89#include "lang.h" 90#include "lang.h"
@@ -124,19 +125,19 @@
124#define TAGCACHE_COMMAND_QUEUE_COMMIT_DELAY HZ*2 125#define TAGCACHE_COMMAND_QUEUE_COMMIT_DELAY HZ*2
125 126
126/* Temporary database containing new tags to be committed to the main db. */ 127/* Temporary database containing new tags to be committed to the main db. */
127#define TAGCACHE_FILE_TEMP ROCKBOX_DIR "/database_tmp.tcd" 128#define TAGCACHE_FILE_TEMP "database_tmp.tcd"
128 129
129/* The main database master index and numeric data. */ 130/* The main database master index and numeric data. */
130#define TAGCACHE_FILE_MASTER ROCKBOX_DIR "/database_idx.tcd" 131#define TAGCACHE_FILE_MASTER "database_idx.tcd"
131 132
132/* The main database string data. */ 133/* The main database string data. */
133#define TAGCACHE_FILE_INDEX ROCKBOX_DIR "/database_%d.tcd" 134#define TAGCACHE_FILE_INDEX "database_%d.tcd"
134 135
135/* ASCII dumpfile of the DB contents. */ 136/* ASCII dumpfile of the DB contents. */
136#define TAGCACHE_FILE_CHANGELOG ROCKBOX_DIR "/database_changelog.txt" 137#define TAGCACHE_FILE_CHANGELOG "database_changelog.txt"
137 138
138/* Serialized DB. */ 139/* Serialized DB. */
139#define TAGCACHE_STATEFILE ROCKBOX_DIR "/database_state.tcd" 140#define TAGCACHE_STATEFILE "database_state.tcd"
140 141
141/* Flags */ 142/* Flags */
142#define FLAG_DELETED 0x0001 /* Entry has been removed from db */ 143#define FLAG_DELETED 0x0001 /* Entry has been removed from db */
@@ -474,6 +475,33 @@ static ssize_t ecwrite_index_entry(int fd, struct index_entry *buf)
474 return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ); 475 return ecwrite(fd, buf, 1, index_entry_ec, tc_stat.econ);
475} 476}
476 477
478/*
479 * open_db_fd and remove_db_file are noinline to minimize stack usage
480 */
481static int NO_INLINE open_db_fd(const char* filename, int mode)
482{
483 char buf[MAX_PATH];
484
485 if(mode & O_CREAT)
486 {
487 if (mkdir(global_settings.tagcache_db_path) < 0 && errno != EEXIST)
488 return -1;
489 }
490
491 return open_pathfmt(buf, sizeof(buf), mode, "%s/%s",
492 global_settings.tagcache_db_path, filename);
493}
494
495static int NO_INLINE remove_db_file(const char* filename)
496{
497 char buf[MAX_PATH];
498
499 snprintf(buf, sizeof(buf), "%s/%s",
500 global_settings.tagcache_db_path, filename);
501
502 return remove(buf);
503}
504
477static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write) 505static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
478{ 506{
479 int fd; 507 int fd;
@@ -484,8 +512,8 @@ static int open_tag_fd(struct tagcache_header *hdr, int tag, bool write)
484 return -1; 512 return -1;
485 513
486 fd = open_pathfmt(fname, sizeof(fname), 514 fd = open_pathfmt(fname, sizeof(fname),
487 write ? O_RDWR : O_RDONLY, TAGCACHE_FILE_INDEX, tag); 515 write ? O_RDWR : O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
488 516 global_settings.tagcache_db_path, tag);
489 if (fd < 0) 517 if (fd < 0)
490 { 518 {
491 logf("tag file open failed: tag=%d write=%d file= " TAGCACHE_FILE_INDEX, 519 logf("tag file open failed: tag=%d write=%d file= " TAGCACHE_FILE_INDEX,
@@ -512,7 +540,7 @@ static int open_master_fd(struct master_header *hdr, bool write)
512 int fd; 540 int fd;
513 int rc; 541 int rc;
514 542
515 fd = open(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY); 543 fd = open_db_fd(TAGCACHE_FILE_MASTER, write ? O_RDWR : O_RDONLY);
516 if (fd < 0) 544 if (fd < 0)
517 { 545 {
518 logf("master file open failed for R/W"); 546 logf("master file open failed for R/W");
@@ -862,7 +890,8 @@ static bool open_files(struct tagcache_search *tcs, int tag)
862 { 890 {
863 char fname[MAX_PATH]; 891 char fname[MAX_PATH];
864 tcs->idxfd[tag] = open_pathfmt(fname, sizeof(fname), 892 tcs->idxfd[tag] = open_pathfmt(fname, sizeof(fname),
865 O_RDONLY, TAGCACHE_FILE_INDEX, tag); 893 O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
894 global_settings.tagcache_db_path, tag);
866 } 895 }
867 896
868 if (tcs->idxfd[tag] < 0) 897 if (tcs->idxfd[tag] < 0)
@@ -1480,13 +1509,14 @@ static void remove_files(void)
1480 tc_stat.ready = false; 1509 tc_stat.ready = false;
1481 tc_stat.ramcache = false; 1510 tc_stat.ramcache = false;
1482 tc_stat.econ = false; 1511 tc_stat.econ = false;
1483 remove(TAGCACHE_FILE_MASTER); 1512 remove_db_file(TAGCACHE_FILE_MASTER);
1484 for (i = 0; i < TAG_COUNT; i++) 1513 for (i = 0; i < TAG_COUNT; i++)
1485 { 1514 {
1486 if (TAGCACHE_IS_NUMERIC(i)) 1515 if (TAGCACHE_IS_NUMERIC(i))
1487 continue; 1516 continue;
1488 1517
1489 snprintf(buf, bufsz, TAGCACHE_FILE_INDEX, i); 1518 snprintf(buf, bufsz, "%s/" TAGCACHE_FILE_INDEX,
1519 global_settings.tagcache_db_path, i);
1490 remove(buf); 1520 remove(buf);
1491 } 1521 }
1492} 1522}
@@ -1645,7 +1675,8 @@ bool tagcache_search_add_clause(struct tagcache_search *tcs,
1645 { 1675 {
1646 char fname[MAX_PATH]; 1676 char fname[MAX_PATH];
1647 tcs->idxfd[clause->tag] = open_pathfmt(fname, sizeof(fname), O_RDONLY, 1677 tcs->idxfd[clause->tag] = open_pathfmt(fname, sizeof(fname), O_RDONLY,
1648 TAGCACHE_FILE_INDEX, clause->tag); 1678 "%s/" TAGCACHE_FILE_INDEX,
1679 global_settings.tagcache_db_path, clause->tag);
1649 } 1680 }
1650 } 1681 }
1651 1682
@@ -2793,9 +2824,13 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2793 /** 2824 /**
2794 * Creating new index file to store the tags. No need to preload 2825 * Creating new index file to store the tags. No need to preload
2795 * anything whether the index type is sorted or not. 2826 * anything whether the index type is sorted or not.
2827 *
2828 * Note: although we are creating a file under the db path, it must
2829 * already exist by this point so no mkdir is required.
2796 */ 2830 */
2797 fd = open_pathfmt(buf, bufsz, O_WRONLY | O_CREAT | O_TRUNC, 2831 fd = open_pathfmt(buf, bufsz, O_WRONLY | O_CREAT | O_TRUNC,
2798 TAGCACHE_FILE_INDEX, index_type); 2832 "%s/" TAGCACHE_FILE_INDEX,
2833 global_settings.tagcache_db_path, index_type);
2799 if (fd < 0) 2834 if (fd < 0)
2800 { 2835 {
2801 logf(TAGCACHE_FILE_INDEX " open fail", index_type); 2836 logf(TAGCACHE_FILE_INDEX " open fail", index_type);
@@ -2817,12 +2852,12 @@ static int build_index(int index_type, struct tagcache_header *h, int tmpfd)
2817 2852
2818 /* Loading the tag lookup file as "master file". */ 2853 /* Loading the tag lookup file as "master file". */
2819 logf("Loading index file"); 2854 logf("Loading index file");
2820 masterfd = open(TAGCACHE_FILE_MASTER, O_RDWR); 2855 masterfd = open_db_fd(TAGCACHE_FILE_MASTER, O_RDWR);
2821 2856
2822 if (masterfd < 0) 2857 if (masterfd < 0)
2823 { 2858 {
2824 logf("Creating new DB"); 2859 logf("Creating new DB");
2825 masterfd = open(TAGCACHE_FILE_MASTER, O_WRONLY | O_CREAT | O_TRUNC, 0666); 2860 masterfd = open_db_fd(TAGCACHE_FILE_MASTER, O_WRONLY | O_CREAT | O_TRUNC);
2826 2861
2827 if (masterfd < 0) 2862 if (masterfd < 0)
2828 { 2863 {
@@ -3149,7 +3184,7 @@ static bool commit(void)
3149 while (write_lock) 3184 while (write_lock)
3150 sleep(1); 3185 sleep(1);
3151 3186
3152 tmpfd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 3187 tmpfd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDONLY);
3153 if (tmpfd < 0) 3188 if (tmpfd < 0)
3154 { 3189 {
3155 logf("nothing to commit"); 3190 logf("nothing to commit");
@@ -3165,7 +3200,7 @@ static bool commit(void)
3165 { 3200 {
3166 logf("incorrect tmpheader"); 3201 logf("incorrect tmpheader");
3167 close(tmpfd); 3202 close(tmpfd);
3168 remove(TAGCACHE_FILE_TEMP); 3203 remove_db_file(TAGCACHE_FILE_TEMP);
3169 return false; 3204 return false;
3170 } 3205 }
3171 3206
@@ -3176,7 +3211,7 @@ static bool commit(void)
3176 tc_stat.ready = check_all_headers(); 3211 tc_stat.ready = check_all_headers();
3177 3212
3178#ifdef HAVE_EEPROM_SETTINGS 3213#ifdef HAVE_EEPROM_SETTINGS
3179 remove(TAGCACHE_STATEFILE); 3214 remove_db_file(TAGCACHE_STATEFILE);
3180#endif 3215#endif
3181 3216
3182 /* At first be sure to unload the ramcache! */ 3217 /* At first be sure to unload the ramcache! */
@@ -3268,7 +3303,7 @@ static bool commit(void)
3268 if ( (masterfd = open_master_fd(&tcmh, true)) < 0) 3303 if ( (masterfd = open_master_fd(&tcmh, true)) < 0)
3269 goto commit_error; 3304 goto commit_error;
3270 3305
3271 remove(TAGCACHE_FILE_TEMP); 3306 remove_db_file(TAGCACHE_FILE_TEMP);
3272 3307
3273 tcmh.tch.entry_count += tch.entry_count; 3308 tcmh.tch.entry_count += tch.entry_count;
3274 tcmh.tch.datasize = sizeof(struct master_header) 3309 tcmh.tch.datasize = sizeof(struct master_header)
@@ -3681,7 +3716,7 @@ bool tagcache_import_changelog(void)
3681 while (read_lock) 3716 while (read_lock)
3682 sleep(1); 3717 sleep(1);
3683 3718
3684 clfd = open(TAGCACHE_FILE_CHANGELOG, O_RDONLY); 3719 clfd = open_db_fd(TAGCACHE_FILE_CHANGELOG, O_RDONLY);
3685 if (clfd < 0) 3720 if (clfd < 0)
3686 { 3721 {
3687 logf("failure to open changelog"); 3722 logf("failure to open changelog");
@@ -3736,7 +3771,7 @@ bool tagcache_create_changelog(struct tagcache_search *tcs)
3736 return false; 3771 return false;
3737 3772
3738 /* Initialize the changelog */ 3773 /* Initialize the changelog */
3739 clfd = open(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC, 0666); 3774 clfd = open_db_fd(TAGCACHE_FILE_CHANGELOG, O_WRONLY | O_CREAT | O_TRUNC);
3740 if (clfd < 0) 3775 if (clfd < 0)
3741 { 3776 {
3742 logf("failure to open changelog"); 3777 logf("failure to open changelog");
@@ -4104,7 +4139,7 @@ static bool tagcache_dumpload(void)
4104 tcramcache.handle = 0; 4139 tcramcache.handle = 0;
4105 tcramcache.hdr = NULL; 4140 tcramcache.hdr = NULL;
4106 4141
4107 fd = open(TAGCACHE_STATEFILE, O_RDONLY); 4142 fd = open_db_fd(TAGCACHE_STATEFILE, O_RDONLY);
4108 if (fd < 0) 4143 if (fd < 0)
4109 { 4144 {
4110 logf("no tagcache statedump"); 4145 logf("no tagcache statedump");
@@ -4164,7 +4199,7 @@ static bool tagcache_dumpsave(void)
4164 if (!tc_stat.ramcache) 4199 if (!tc_stat.ramcache)
4165 return false; 4200 return false;
4166 4201
4167 fd = open(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC, 0666); 4202 fd = open_db_fd(TAGCACHE_STATEFILE, O_WRONLY | O_CREAT | O_TRUNC);
4168 if (fd < 0) 4203 if (fd < 0)
4169 { 4204 {
4170 logf("failed to create a statedump"); 4205 logf("failed to create a statedump");
@@ -4208,7 +4243,7 @@ static bool load_tagcache(void)
4208 4243
4209 tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */ 4244 tcrc_buffer_lock(); /* lock for the rest of the scan, simpler to handle */
4210 4245
4211 fd = open(TAGCACHE_FILE_MASTER, O_RDONLY); 4246 fd = open_db_fd(TAGCACHE_FILE_MASTER, O_RDONLY);
4212 if (fd < 0) 4247 if (fd < 0)
4213 { 4248 {
4214 logf("tagcache open failed"); 4249 logf("tagcache open failed");
@@ -4451,8 +4486,8 @@ static bool check_deleted_files(void)
4451 struct tagfile_entry tfe; 4486 struct tagfile_entry tfe;
4452 4487
4453 logf("reverse scan..."); 4488 logf("reverse scan...");
4454 4489 fd = open_pathfmt(buf, bufsz, O_RDONLY, "%s/" TAGCACHE_FILE_INDEX,
4455 fd = open_pathfmt(buf, bufsz, O_RDONLY, TAGCACHE_FILE_INDEX, tag_filename); 4490 global_settings.tagcache_db_path, tag_filename);
4456 if (fd < 0) 4491 if (fd < 0)
4457 { 4492 {
4458 logf(TAGCACHE_FILE_INDEX " open fail", tag_filename); 4493 logf(TAGCACHE_FILE_INDEX " open fail", tag_filename);
@@ -4735,7 +4770,7 @@ void do_tagcache_build(const char *path[])
4735 4770
4736 logf("updating tagcache"); 4771 logf("updating tagcache");
4737 4772
4738 cachefd = open(TAGCACHE_FILE_TEMP, O_RDONLY); 4773 cachefd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDONLY);
4739 if (cachefd >= 0) 4774 if (cachefd >= 0)
4740 { 4775 {
4741 logf("skipping, cache already waiting for commit"); 4776 logf("skipping, cache already waiting for commit");
@@ -4743,7 +4778,7 @@ void do_tagcache_build(const char *path[])
4743 return ; 4778 return ;
4744 } 4779 }
4745 4780
4746 cachefd = open(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC, 0666); 4781 cachefd = open_db_fd(TAGCACHE_FILE_TEMP, O_RDWR | O_CREAT | O_TRUNC);
4747 if (cachefd < 0) 4782 if (cachefd < 0)
4748 { 4783 {
4749 logf("master file open failed: %s", TAGCACHE_FILE_TEMP); 4784 logf("master file open failed: %s", TAGCACHE_FILE_TEMP);
@@ -4872,7 +4907,7 @@ void tagcache_unload_ramcache(void)
4872{ 4907{
4873 tc_stat.ramcache = false; 4908 tc_stat.ramcache = false;
4874 /* Just to make sure there is no statefile present. */ 4909 /* Just to make sure there is no statefile present. */
4875 // remove(TAGCACHE_STATEFILE); 4910 // remove_db_file(TAGCACHE_STATEFILE);
4876} 4911}
4877#endif /* HAVE_TC_RAMCACHE */ 4912#endif /* HAVE_TC_RAMCACHE */
4878 4913
@@ -4897,7 +4932,7 @@ static void tagcache_thread(void)
4897 check_done = tagcache_dumpload(); 4932 check_done = tagcache_dumpload();
4898 } 4933 }
4899 4934
4900 remove(TAGCACHE_STATEFILE); 4935 remove_db_file(TAGCACHE_STATEFILE);
4901#endif /* HAVE_EEPROM_SETTINGS */ 4936#endif /* HAVE_EEPROM_SETTINGS */
4902 4937
4903 /* Allocate space for the tagcache if found on disk. */ 4938 /* Allocate space for the tagcache if found on disk. */
@@ -4930,7 +4965,7 @@ static void tagcache_thread(void)
4930 4965
4931 case Q_REBUILD: 4966 case Q_REBUILD:
4932 remove_files(); 4967 remove_files();
4933 remove(TAGCACHE_FILE_TEMP); 4968 remove_db_file(TAGCACHE_FILE_TEMP);
4934 tagcache_build(); 4969 tagcache_build();
4935 break; 4970 break;
4936 4971
@@ -5014,7 +5049,7 @@ void tagcache_shutdown(void)
5014 5049
5015void tagcache_remove_statefile(void) 5050void tagcache_remove_statefile(void)
5016{ 5051{
5017 remove(TAGCACHE_STATEFILE); 5052 remove_db_file(TAGCACHE_STATEFILE);
5018} 5053}
5019 5054
5020static int get_progress(void) 5055static int get_progress(void)
diff --git a/manual/appendix/config_file_options.tex b/manual/appendix/config_file_options.tex
index dc186e2d26..709bc9b2ff 100644
--- a/manual/appendix/config_file_options.tex
+++ b/manual/appendix/config_file_options.tex
@@ -250,6 +250,7 @@
250 keyclick repeats & on, off & N/A\\ 250 keyclick repeats & on, off & N/A\\
251 dircache & on, off & N/A\\ 251 dircache & on, off & N/A\\
252 tagcache\_ram & on, off & N/A\\ 252 tagcache\_ram & on, off & N/A\\
253 database path & path to a directory & N/A\\
253 254
254 \opt{touchpad}{ 255 \opt{touchpad}{
255 \opt{GIGABEAT_PAD}{ 256 \opt{GIGABEAT_PAD}{