Skip to content

Commit 0cfa5d6

Browse files
committed
webui: fix config option tail space issue, add some init log and fix memory leak when exit.
1 parent 55a4b36 commit 0cfa5d6

File tree

16 files changed

+293
-98
lines changed

16 files changed

+293
-98
lines changed

etc/smartdns/smartdns.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -443,7 +443,7 @@ log-level info
443443
# plugin smartdns_ui.so
444444
# smartdns-ui.www-root /usr/share/smartdns/wwwroot
445445
# smartdns-ui.ip http://0.0.0.0:6080
446-
# smartdns-ui.ip https://0.0.0.0:6080
446+
# smartdns-ui.ip https://[::]:6080
447447
# smartdns-ui.token-expire 600
448448
# smartdns-ui.max-query-log-age 86400
449449
# smartdns-ui.enable-terminal yes

package/openwrt/files/etc/init.d/smartdns

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ load_service()
871871

872872
conf_append "plugin" "smartdns_ui.so"
873873
conf_append "smartdns-ui.www-root" "/usr/share/smartdns/wwwroot"
874-
conf_append "smartdns-ui.ip" "http://0.0.0.0:$ui_port"
874+
conf_append "smartdns-ui.ip" "http://[::]:$ui_port"
875875
conf_append "data-dir" "$ui_data_dir"
876876
conf_append "smartdns-ui.max-query-log-age" "$ui_log_max_age_s"
877877
}

plugin/smartdns-ui/src/data_server.rs

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::whois::WhoIsInfo;
3232
use std::collections::HashMap;
3333
use std::error::Error;
3434
use std::sync::atomic::AtomicBool;
35+
use std::sync::Weak;
3536
use std::sync::{Arc, Mutex, RwLock};
3637
use tokio::sync::mpsc;
3738
use tokio::task::JoinHandle;
@@ -43,6 +44,7 @@ pub const DEFAULT_MAX_LOG_AGE_MS: u64 = DEFAULT_MAX_LOG_AGE * 1000;
4344
pub const MAX_LOG_AGE_VALUE_MIN: u64 = 3600;
4445
pub const MAX_LOG_AGE_VALUE_MAX: u64 = 365 * 24 * 60 * 60 * 10;
4546
pub const MIN_FREE_DISK_SPACE: u64 = 1024 * 1024 * 8;
47+
pub const DB_FILE_NAME: &str = "smartdns.db";
4648

4749
#[derive(Clone)]
4850
pub struct OverviewData {
@@ -68,14 +70,16 @@ pub struct MetricsData {
6870

6971
#[derive(Clone)]
7072
pub struct DataServerConfig {
71-
pub data_root: String,
73+
pub db_file: String,
74+
pub data_path: String,
7275
pub max_log_age_ms: u64,
7376
}
7477

7578
impl DataServerConfig {
7679
pub fn new() -> Self {
7780
DataServerConfig {
78-
data_root: Plugin::dns_conf_data_dir() + "/smartdns.db",
81+
data_path: Plugin::dns_conf_data_dir(),
82+
db_file: Plugin::dns_conf_data_dir() + "/" + DB_FILE_NAME,
7983
max_log_age_ms: DEFAULT_MAX_LOG_AGE_MS,
8084
}
8185
}
@@ -110,7 +114,7 @@ pub struct DataServerControl {
110114
server_thread: Mutex<Option<JoinHandle<()>>>,
111115
is_init: Mutex<bool>,
112116
is_run: Mutex<bool>,
113-
plugin: Mutex<Option<Arc<SmartdnsPlugin>>>,
117+
plugin: Mutex<Weak<SmartdnsPlugin>>,
114118
}
115119

116120
impl DataServerControl {
@@ -120,7 +124,7 @@ impl DataServerControl {
120124
server_thread: Mutex::new(None),
121125
is_init: Mutex::new(false),
122126
is_run: Mutex::new(false),
123-
plugin: Mutex::new(None),
127+
plugin: Mutex::new(Weak::new()),
124128
}
125129
}
126130

@@ -129,12 +133,19 @@ impl DataServerControl {
129133
}
130134

131135
pub fn set_plugin(&self, plugin: Arc<SmartdnsPlugin>) {
132-
*self.plugin.lock().unwrap() = Some(plugin);
136+
*self.plugin.lock().unwrap() = Arc::downgrade(&plugin);
133137
}
134138

135-
pub fn get_plugin(&self) -> Arc<SmartdnsPlugin> {
136-
let plugin = self.plugin.lock().unwrap();
137-
Arc::clone(&plugin.as_ref().unwrap())
139+
pub fn get_plugin(&self) -> Result<Arc<SmartdnsPlugin>, Box<dyn Error>> {
140+
let plugin = match self.plugin.lock() {
141+
Ok(plugin) => plugin,
142+
Err(_) => return Err("Failed to lock plugin mutex".into()),
143+
};
144+
145+
if let Some(plugin) = plugin.upgrade() {
146+
return Ok(plugin);
147+
}
148+
Err("Plugin is not set".into())
138149
}
139150

140151
pub fn init_db(&self, conf: &DataServerConfig) -> Result<(), Box<dyn Error>> {
@@ -155,8 +166,9 @@ impl DataServerControl {
155166
return Err("data server not init".into());
156167
}
157168

158-
self.data_server.set_plugin(self.get_plugin());
159-
let rt = self.get_plugin().get_runtime();
169+
let plugin = self.get_plugin()?;
170+
self.data_server.set_plugin(plugin.clone());
171+
let rt = plugin.get_runtime();
160172

161173
let server_thread = rt.spawn(async move {
162174
let ret = DataServer::data_server_loop(inner_clone).await;
@@ -181,7 +193,18 @@ impl DataServerControl {
181193
self.data_server.stop_data_server();
182194
let _server_thread = self.server_thread.lock().unwrap().take();
183195
if let Some(server_thread) = _server_thread {
184-
let rt = self.get_plugin().get_runtime();
196+
let plugin = self.get_plugin();
197+
if plugin.is_err() {
198+
dns_log!(
199+
LogLevel::ERROR,
200+
"get plugin error: {}",
201+
plugin.err().unwrap()
202+
);
203+
return;
204+
}
205+
206+
let plugin = plugin.unwrap();
207+
let rt = plugin.get_runtime();
185208
tokio::task::block_in_place(|| {
186209
if let Err(e) = rt.block_on(server_thread) {
187210
dns_log!(LogLevel::ERROR, "http server stop error: {}", e);
@@ -233,7 +256,7 @@ pub struct DataServer {
233256
disable_handle_request: AtomicBool,
234257
stat: Arc<DataStats>,
235258
server_log: ServerLog,
236-
plugin: Mutex<Option<Arc<SmartdnsPlugin>>>,
259+
plugin: Mutex<Weak<SmartdnsPlugin>>,
237260
whois: whois::WhoIs,
238261
startup_timestamp: u64,
239262
recv_in_batch: Mutex<bool>,
@@ -252,7 +275,7 @@ impl DataServer {
252275
db: db.clone(),
253276
stat: DataStats::new(db, conf.clone()),
254277
server_log: ServerLog::new(),
255-
plugin: Mutex::new(None),
278+
plugin: Mutex::new(Weak::new()),
256279
whois: whois::WhoIs::new(),
257280
startup_timestamp: get_utc_time_ms(),
258281
disable_handle_request: AtomicBool::new(false),
@@ -284,8 +307,17 @@ impl DataServer {
284307

285308
smartdns::smartdns_enable_update_neighbour(true);
286309

287-
dns_log!(LogLevel::INFO, "open db: {}", conf_clone.data_root);
288-
let ret = self.db.open(&conf_clone.data_root);
310+
if utils::is_dir_writable(&conf_clone.data_path) == false {
311+
return Err(format!(
312+
"data path '{}' is not exist or writable.",
313+
conf_clone.data_path
314+
)
315+
.into());
316+
}
317+
318+
conf_clone.db_file = conf_clone.data_path.clone() + "/" + DB_FILE_NAME;
319+
dns_log!(LogLevel::INFO, "open db: {}", conf_clone.db_file);
320+
let ret = self.db.open(&conf_clone.db_file);
289321
if let Err(e) = ret {
290322
return Err(e);
291323
}
@@ -299,12 +331,19 @@ impl DataServer {
299331
}
300332

301333
pub fn set_plugin(&self, plugin: Arc<SmartdnsPlugin>) {
302-
*self.plugin.lock().unwrap() = Some(plugin);
334+
*self.plugin.lock().unwrap() = Arc::downgrade(&plugin);
303335
}
304336

305-
pub fn get_plugin(&self) -> Arc<SmartdnsPlugin> {
306-
let plugin = self.plugin.lock().unwrap();
307-
Arc::clone(&plugin.as_ref().unwrap())
337+
pub fn get_plugin(&self) -> Result<Arc<SmartdnsPlugin>, Box<dyn Error>> {
338+
let plugin = match self.plugin.lock() {
339+
Ok(plugin) => plugin,
340+
Err(_) => return Err("Failed to lock plugin mutex".into()),
341+
};
342+
343+
if let Some(plugin) = plugin.upgrade() {
344+
return Ok(plugin);
345+
}
346+
Err("Plugin is not set".into())
308347
}
309348

310349
pub fn get_data_server_config(&self) -> DataServerConfig {
@@ -445,7 +484,7 @@ impl DataServer {
445484
}
446485

447486
pub fn get_free_disk_space(&self) -> u64 {
448-
utils::get_free_disk_space(&self.get_data_server_config().data_root)
487+
utils::get_free_disk_space(&self.get_data_server_config().db_file)
449488
}
450489

451490
pub fn get_overview(&self) -> Result<OverviewData, Box<dyn Error + Send>> {
@@ -705,7 +744,15 @@ impl DataServer {
705744

706745
fn stop_data_server(&self) {
707746
if let Some(tx) = self.notify_tx.as_ref().cloned() {
708-
let rt = self.get_plugin().get_runtime();
747+
let plugin = match self.get_plugin() {
748+
Ok(plugin) => plugin,
749+
Err(e) => {
750+
dns_log!(LogLevel::ERROR, "get plugin error: {}", e);
751+
return;
752+
}
753+
};
754+
755+
let rt = plugin.get_runtime();
709756
tokio::task::block_in_place(|| {
710757
let _ = rt.block_on(async {
711758
let _ = tx.send(()).await;
@@ -722,7 +769,7 @@ impl DataServer {
722769
F: FnOnce() -> R + Send + 'static,
723770
R: Send + 'static,
724771
{
725-
let rt = this.get_plugin().get_runtime();
772+
let rt = this.get_plugin().unwrap().get_runtime();
726773

727774
let ret = rt.spawn_blocking(move || -> R {
728775
return func();

plugin/smartdns-ui/src/data_stats.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,6 @@ impl DataStats {
249249
pub fn init(self: &Arc<Self>) -> Result<(), Box<dyn Error>> {
250250
dns_log!(LogLevel::DEBUG, "init data stats");
251251
self.load_status_data()?;
252-
dns_log!(LogLevel::DEBUG, "init data stats complete");
253252
Ok(())
254253
}
255254

0 commit comments

Comments
 (0)