1 // Copyright (C) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::fs::File;
15 use std::io::Write;
16 
17 use ipc::IpcResult;
18 
19 use crate::manage::events::TaskManagerEvent;
20 use crate::service::RequestServiceStub;
21 
22 const HELP_MSG: &str = "usage:\n\
23                          -h                    help text for the tool\n\
24                          -t [taskid]           without taskid: display all task summary info; \
25                          taskid: display one task detail info\n";
26 impl RequestServiceStub {
27     // Ignores all the file error.
dump(&self, mut file: File, args: Vec<String>) -> IpcResult<()>28     pub(crate) fn dump(&self, mut file: File, args: Vec<String>) -> IpcResult<()> {
29         info!("Service dump");
30 
31         let len = args.len();
32         if len == 0 || args[0] == "-h" {
33             let _ = file.write(HELP_MSG.as_bytes());
34             return Ok(());
35         }
36 
37         if args[0] != "-t" {
38             let _ = file.write("invalid args".as_bytes());
39             return Ok(());
40         }
41 
42         match len {
43             1 => self.dump_all_task_info(file),
44             2 => {
45                 let task_id = args[1].parse::<u32>();
46                 match task_id {
47                     Ok(id) => self.dump_one_task_info(file, id),
48                     Err(_) => {
49                         let _ = file.write("-t accept a number".as_bytes());
50                     }
51                 }
52             }
53             _ => {
54                 let _ = file.write("too many args, -t accept no arg or one arg".as_bytes());
55             }
56         }
57         Ok(())
58     }
59 
dump_all_task_info(&self, mut file: File)60     fn dump_all_task_info(&self, mut file: File) {
61         info!("Service dump all task info");
62 
63         let (event, rx) = TaskManagerEvent::dump_all();
64         if !self.task_manager.lock().unwrap().send_event(event) {
65             return;
66         }
67 
68         let infos = match rx.get() {
69             Some(infos) => infos,
70             None => {
71                 error!("Service dump: receives infos failed");
72                 return;
73             }
74         };
75         let len = infos.vec.len();
76         let _ = file.write(format!("task num: {}\n", len).as_bytes());
77         if len > 0 {
78             let _ = file.write(
79                 format!(
80                     "{:<20}{:<12}{:<12}{:<12}\n",
81                     "id", "action", "state", "reason"
82                 )
83                 .as_bytes(),
84             );
85             for info in infos.vec.iter() {
86                 let _ = file.write(
87                     format!(
88                         "{:<20}{:<12}{:<12}{:<12}\n",
89                         info.task_id, info.action.repr, info.state.repr, info.reason.repr
90                     )
91                     .as_bytes(),
92                 );
93             }
94         }
95     }
96 
dump_one_task_info(&self, mut file: File, task_id: u32)97     fn dump_one_task_info(&self, mut file: File, task_id: u32) {
98         info!("Service dump one task info");
99 
100         let (event, rx) = TaskManagerEvent::dump_one(task_id);
101         if !self.task_manager.lock().unwrap().send_event(event) {
102             return;
103         }
104         let task = match rx.get() {
105             Some(task) => task,
106             None => {
107                 error!("Service dump: receives task failed");
108                 return;
109             }
110         };
111 
112         if let Some(task) = task {
113             let _ = file.write(
114                 format!(
115                     "{:<20}{:<12}{:<12}{:<12}\n",
116                     "id", "action", "state", "reason"
117                 )
118                 .as_bytes(),
119             );
120             let _ = file.write(
121                 format!(
122                     "{:<20}{:<12}{:<12}{:<12}\n",
123                     task.task_id,
124                     task.action.repr,
125                     task.state.repr,
126                     task.reason.repr
127                 )
128                 .as_bytes(),
129             );
130         } else {
131             let _ = file.write(format!("invalid task id {}", task_id).as_bytes());
132         }
133     }
134 }
135