@@ -235,9 +235,10 @@ pub(crate) async fn mirror_root_inode(
235235 needs_license ( & ctx, LicensedFeature :: Mirroring ) ?;
236236 fail_on_pre_shutdown ( & ctx) ?;
237237
238+ let offline_timeout = ctx. info . user_config . node_offline_timeout . as_secs ( ) ;
238239 let meta_root = ctx
239240 . db
240- . read_tx ( |tx| {
241+ . read_tx ( move |tx| {
241242 let node_uid = match db:: misc:: get_meta_root ( tx) ? {
242243 MetaRoot :: Normal ( _, node_uid) => node_uid,
243244 MetaRoot :: Mirrored ( _) => bail ! ( "Root inode is already mirrored" ) ,
@@ -267,7 +268,33 @@ pub(crate) async fn mirror_root_inode(
267268 } ) ?;
268269
269270 if clients > 0 {
270- bail ! ( "This operation requires that all clients are disconnected/unmounted, but still has {clients} clients mounted." ) ;
271+ bail ! (
272+ "This operation requires that all clients are disconnected/unmounted. \
273+ {clients} clients are still mounted."
274+ ) ;
275+ }
276+
277+ let mut server_stmt = tx. prepare ( sql ! (
278+ "SELECT COUNT(*) FROM nodes
279+ WHERE node_type = ?1 AND UNIXEPOCH('now') - UNIXEPOCH(last_contact) < ?2
280+ AND node_uid != ?3"
281+ ) ) ?;
282+
283+ let metas = server_stmt. query_row (
284+ params ! [ NodeType :: Meta . sql_variant( ) , offline_timeout, node_uid] ,
285+ |row| row. get :: < _ , i64 > ( 0 ) ,
286+ ) ?;
287+ let storages = server_stmt. query_row (
288+ params ! [ NodeType :: Storage . sql_variant( ) , offline_timeout, node_uid] ,
289+ |row| row. get :: < _ , i64 > ( 0 ) ,
290+ ) ?;
291+
292+ if metas > 0 || storages > 0 {
293+ bail ! (
294+ "This operation requires that all nodes except the root meta node are shut \
295+ down. {metas} meta nodes (excluding the root meta node) and {storages} storage nodes have \
296+ communicated during the last {offline_timeout}s."
297+ ) ;
271298 }
272299
273300 Ok ( node_uid)
0 commit comments