This repository was archived by the owner on Feb 12, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmanual-non-destructive-rescan-v1_3_0.patch
233 lines (217 loc) · 7.36 KB
/
manual-non-destructive-rescan-v1_3_0.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
You can see the original patch in the following page:
https://sourceforge.net/p/minidlna/patches/172/
diff --git a/minidlna.c b/minidlna.c
index b2769ae..2c50f16 100644
--- a/minidlna.c
+++ b/minidlna.c
@@ -211,6 +211,17 @@ sigusr1(int sig)
memset(&clients, '\0', sizeof(clients));
}
+static void
+sigusr2(int sig)
+{
+ signal(sig, sigusr2);
+ DPRINTF(E_WARN, L_GENERAL, "received signal %d, manual rescan\n", sig);
+
+ if (!GETFLAG(SCANNING_MASK) &&
+ !GETFLAG(RESCAN_MASK))
+ SETFLAG(RESCAN_MASK);
+}
+
static void
sighup(int sig)
{
@@ -915,6 +926,10 @@ init(int argc, char **argv)
if (system(buf) != 0)
DPRINTF(E_FATAL, L_GENERAL, "Failed to clean old file cache %s. EXITING\n", db_path);
break;
+ case 'U':
+ pid = process_check_if_running(pidfilename);
+ printf("Manual rescan for " SERVER_NAME " %s\n", (pid > 0 && !kill(pid, SIGUSR2)) ? "sent" : "failed");
+ exit(0);
case 'u':
if (i+1 != argc)
{
@@ -974,9 +989,9 @@ init(int argc, char **argv)
"\t\t[-t notify_interval] [-P pid_filename]\n"
"\t\t[-s serial] [-m model_number]\n"
#ifdef __linux__
- "\t\t[-w url] [-r] [-R] [-L] [-S] [-V] [-h]\n"
+ "\t\t[-w url] [-r] [-R] [-U] [-L] [-S] [-V] [-h]\n"
#else
- "\t\t[-w url] [-r] [-R] [-L] [-V] [-h]\n"
+ "\t\t[-w url] [-r] [-R] [-U] [-L] [-V] [-h]\n"
#endif
"\nNotes:\n\tNotify interval is in seconds. Default is 895 seconds.\n"
"\tDefault pid file is %s.\n"
@@ -984,7 +999,8 @@ init(int argc, char **argv)
"\t-w sets the presentation url. Default is http address on port 80\n"
"\t-v enables verbose output\n"
"\t-h displays this text\n"
- "\t-r forces a rescan\n"
+ "\t-r forces a rescan on startup\n"
+ "\t-U forces a rescan while " SERVER_NAME " is running. Use after -P\n"
"\t-R forces a rebuild\n"
"\t-L do not create playlists\n"
#if defined(__linux__) || defined(__APPLE__)
@@ -1026,7 +1042,7 @@ init(int argc, char **argv)
DPRINTF(E_FATAL, L_GENERAL, "Failed to open log file '%s/" LOGFILE_NAME "': %s\n",
log_path, strerror(errno));
- if (process_check_if_running(pidfilename) < 0)
+ if (process_check_if_running(pidfilename) > 0)
DPRINTF(E_FATAL, L_GENERAL, SERVER_NAME " is already running. EXITING.\n");
set_startup_time();
@@ -1051,6 +1067,7 @@ init(int argc, char **argv)
if (signal(SIGUSR2, SIG_IGN) == SIG_ERR)
DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGUSR2");
signal(SIGUSR1, &sigusr1);
+ signal(SIGUSR2, &sigusr2);
sa.sa_handler = process_handle_child_termination;
if (sigaction(SIGCHLD, &sa, NULL))
DPRINTF(E_FATAL, L_GENERAL, "Failed to set %s handler. EXITING.\n", "SIGCHLD");
@@ -1274,6 +1291,7 @@ main(int argc, char **argv)
if (GETFLAG(SCANNING_MASK) && kill(scanner_pid, 0) != 0) {
CLEARFLAG(SCANNING_MASK);
+ CLEARFLAG(RESCAN_MASK);
if (_get_dbtime() != lastdbtime)
updateID++;
#ifdef HAVE_KQUEUE
@@ -1281,6 +1299,13 @@ main(int argc, char **argv)
kqueue_monitor_start();
#endif /* HAVE_KQUEUE */
}
+ if (GETFLAG(RESCAN_MASK) && !GETFLAG(SCANNING_MASK))
+ {
+ if (GETFLAG(MONITOR_MASK))
+ DPRINTF(E_WARN, L_GENERAL, "Waiting for inotify to finish.\n");
+ else
+ check_db(db, -1, &scanner_pid);
+ }
event_module.process(timeout);
if (quitting)
diff --git a/monitor.c b/monitor.c
index 9e56bc7..237e738 100644
--- a/monitor.c
+++ b/monitor.c
@@ -683,6 +683,12 @@ start_inotify(void)
buffer[BUF_LEN-1] = '\0';
}
+ if (GETFLAG(RESCAN_MASK))
+ {
+ DPRINTF(E_WARN, L_INOTIFY, "Ignoring inotify during rescan.\n");
+ continue;
+ }
+
i = 0;
while( !quitting && i < length )
{
@@ -698,15 +704,18 @@ start_inotify(void)
snprintf(path_buf, sizeof(path_buf), "%s/%s", get_path_from_wd(event->wd), event->name);
if ( event->mask & IN_ISDIR && (event->mask & (IN_CREATE|IN_MOVED_TO)) )
{
+ SETFLAG(MONITOR_MASK);
DPRINTF(E_DEBUG, L_INOTIFY, "The directory %s was %s.\n",
path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created"));
monitor_insert_directory(pollfds[0].fd, esc_name, path_buf);
+ CLEARFLAG(MONITOR_MASK);
}
else if ( (event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO|IN_CREATE)) &&
(lstat(path_buf, &st) == 0) )
{
if( (event->mask & (IN_MOVED_TO|IN_CREATE)) && (S_ISLNK(st.st_mode) || st.st_nlink > 1) )
{
+ SETFLAG(MONITOR_MASK);
DPRINTF(E_DEBUG, L_INOTIFY, "The %s link %s was %s.\n",
(S_ISLNK(st.st_mode) ? "symbolic" : "hard"),
path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "created"));
@@ -714,20 +723,24 @@ start_inotify(void)
monitor_insert_directory(pollfds[0].fd, esc_name, path_buf);
else
monitor_insert_file(esc_name, path_buf);
+ CLEARFLAG(MONITOR_MASK);
}
else if( event->mask & (IN_CLOSE_WRITE|IN_MOVED_TO) && st.st_size > 0 )
{
if( (event->mask & IN_MOVED_TO) ||
(sql_get_int_field(db, "SELECT TIMESTAMP from DETAILS where PATH = '%q'", path_buf) != st.st_mtime) )
{
+ SETFLAG(MONITOR_MASK);
DPRINTF(E_DEBUG, L_INOTIFY, "The file %s was %s.\n",
path_buf, (event->mask & IN_MOVED_TO ? "moved here" : "changed"));
monitor_insert_file(esc_name, path_buf);
+ CLEARFLAG(MONITOR_MASK);
}
}
}
else if ( event->mask & (IN_DELETE|IN_MOVED_FROM) )
{
+ SETFLAG(MONITOR_MASK);
DPRINTF(E_DEBUG, L_INOTIFY, "The %s %s was %s.\n",
(event->mask & IN_ISDIR ? "directory" : "file"),
path_buf, (event->mask & IN_MOVED_FROM ? "moved away" : "deleted"));
@@ -735,6 +748,7 @@ start_inotify(void)
monitor_remove_directory(pollfds[0].fd, path_buf);
else
monitor_remove_file(path_buf);
+ CLEARFLAG(MONITOR_MASK);
}
free(esc_name);
}
diff --git a/process.c b/process.c
index abb777b..2cb8046 100644
--- a/process.c
+++ b/process.c
@@ -179,7 +179,7 @@ process_check_if_running(const char *fname)
{
char buffer[64];
int pidfile;
- pid_t pid;
+ pid_t pid = 0;
if(!fname || *fname == '\0')
return -1;
@@ -193,17 +193,13 @@ process_check_if_running(const char *fname)
{
if( (pid = atol(buffer)) > 0)
{
- if(!kill(pid, 0))
- {
- close(pidfile);
- return -2;
- }
+ pid = !kill(pid, 0) ? pid : -2;
}
}
close(pidfile);
- return 0;
+ return (int) pid;
}
void
diff --git a/upnpglobalvars.c b/upnpglobalvars.c
index 1625bdb..c6e699e 100644
--- a/upnpglobalvars.c
+++ b/upnpglobalvars.c
@@ -58,7 +58,7 @@
time_t startup_time = 0;
struct runtime_vars_s runtime_vars;
-uint32_t runtime_flags = INOTIFY_MASK | TIVO_BONJOUR_MASK | SUBTITLES_MASK;
+volatile uint32_t runtime_flags = INOTIFY_MASK | TIVO_BONJOUR_MASK | SUBTITLES_MASK;
const char *pidfilename = "/var/run/minidlna/minidlna.pid";
diff --git a/upnpglobalvars.h b/upnpglobalvars.h
index 92596e7..8546ffc 100644
--- a/upnpglobalvars.h
+++ b/upnpglobalvars.h
@@ -187,7 +187,7 @@ extern time_t startup_time;
extern struct runtime_vars_s runtime_vars;
/* runtime boolean flags */
-extern uint32_t runtime_flags;
+extern volatile uint32_t runtime_flags;
#define INOTIFY_MASK 0x0001
#define TIVO_MASK 0x0002
#define DLNA_STRICT_MASK 0x0004
@@ -204,6 +204,7 @@ extern uint32_t runtime_flags;
#define RESCAN_MASK 0x0200
#define SUBTITLES_MASK 0x0400
#define FORCE_ALPHASORT_MASK 0x0800
+#define MONITOR_MASK 0x1000
#define SETFLAG(mask) runtime_flags |= mask
#define GETFLAG(mask) (runtime_flags & mask)