@@ -32,6 +32,7 @@ use crate::whois::WhoIsInfo;
3232use std:: collections:: HashMap ;
3333use std:: error:: Error ;
3434use std:: sync:: atomic:: AtomicBool ;
35+ use std:: sync:: Weak ;
3536use std:: sync:: { Arc , Mutex , RwLock } ;
3637use tokio:: sync:: mpsc;
3738use tokio:: task:: JoinHandle ;
@@ -43,6 +44,7 @@ pub const DEFAULT_MAX_LOG_AGE_MS: u64 = DEFAULT_MAX_LOG_AGE * 1000;
4344pub const MAX_LOG_AGE_VALUE_MIN : u64 = 3600 ;
4445pub const MAX_LOG_AGE_VALUE_MAX : u64 = 365 * 24 * 60 * 60 * 10 ;
4546pub const MIN_FREE_DISK_SPACE : u64 = 1024 * 1024 * 8 ;
47+ pub const DB_FILE_NAME : & str = "smartdns.db" ;
4648
4749#[ derive( Clone ) ]
4850pub struct OverviewData {
@@ -68,14 +70,16 @@ pub struct MetricsData {
6870
6971#[ derive( Clone ) ]
7072pub 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
7578impl 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
116120impl 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 ( ) ;
0 commit comments