• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2021 Huawei Technologies Co., Ltd. All rights reserved.
4  */
5 
6 #include <linux/blackbox.h>
7 #include <linux/kernel.h>
8 #include <linux/delay.h>
9 #include <linux/reboot.h>
10 #include <linux/syscalls.h>
11 #include <linux/rtc.h>
12 #include <linux/time.h>
13 #include <linux/vmalloc.h>
14 #include <linux/blackbox_common.h>
15 
sys_reset(void)16 void sys_reset(void)
17 {
18 	bbox_print_info("reset the system now!\n");
19 	emergency_restart();
20 	bbox_print_info("reset the system failed!\n");
21 }
22 
change_own_mode(char * path,int uid,int gid,int mode)23 void change_own_mode(char *path, int uid, int gid, int mode)
24 {
25 	mm_segment_t old_fs;
26 	int ret = -1;
27 
28 	if (unlikely(!path || uid == -1 || gid == -1)) {
29 		bbox_print_err("path or uid or gid error.\n");
30 		return;
31 	}
32 
33 	old_fs = get_fs();
34 	set_fs(KERNEL_DS);
35 	ret = sys_chown(path, uid, gid);
36 	if (ret != 0) {
37 		bbox_print_err("sys_chown [%s] failed, ret: %d\n", path, ret);
38 		goto __out;
39 	}
40 
41 	ret = sys_chmod(path, mode);
42 	if (ret != 0) {
43 		bbox_print_err("sys_chmod [%s] failed, ret: %d\n", path, ret);
44 		goto __out;
45 	}
46 
47 __out:
48 	set_fs(old_fs);
49 }
50 
full_write_file(const char * pfile_path,char * buf,size_t buf_size,bool is_append)51 int full_write_file(const char *pfile_path, char *buf,
52 		size_t buf_size, bool is_append)
53 {
54 	mm_segment_t old_fs;
55 	long total_to_write = (long)buf_size;
56 	long total_write = 0;
57 	long write_this_time;
58 	char *ptemp = buf;
59 	int fd = -1;
60 
61 	if (unlikely(!pfile_path || !buf)) {
62 		bbox_print_err("fd or buf is NULL!\n");
63 		return -EINVAL;
64 	}
65 
66 	old_fs = get_fs();
67 	set_fs(KERNEL_DS);
68 	fd = sys_open(pfile_path, O_CREAT | O_RDWR |
69 		(is_append ? O_APPEND : O_TRUNC), 0);
70 	if (fd < 0) {
71 		bbox_print_err("Create file [%s] failed! ret: %d\n", pfile_path, fd);
72 		goto __out;
73 	}
74 
75 	while (total_to_write > 0) {
76 		write_this_time = ksys_write(fd, ptemp, total_to_write);
77 		if (write_this_time < 0) {
78 			bbox_print_err("%s\n", "Failed to write file!\n");
79 			break;
80 		}
81 		ptemp += write_this_time;
82 		total_to_write -= write_this_time;
83 		total_write += write_this_time;
84 	}
85 
86 __out:
87 	if (fd >= 0) {
88 		ksys_sync();
89 		ksys_close(fd);
90 	}
91 	set_fs(old_fs);
92 
93 	return total_write == (long)buf_size ? 0 : -1;
94 }
95 
create_new_dir(char * path)96 static int create_new_dir(char *path)
97 {
98 	int ret;
99 	mm_segment_t old_fs;
100 
101 	if (unlikely(!path)) {
102 		bbox_print_err("path is NULL!\n");
103 		return -EINVAL;
104 	}
105 
106 	old_fs = get_fs();
107 	set_fs(KERNEL_DS);
108 	ret = sys_access(path, 0);
109 	if (ret != 0) {
110 		ret = sys_mkdir(path, BBOX_DIR_LIMIT);
111 		if (ret < 0) {
112 			bbox_print_err("Create dir [%s] failed! ret: %d\n", path, ret);
113 			set_fs(old_fs);
114 			return -EINVAL;
115 		}
116 		change_own_mode(path, AID_ROOT, AID_SYSTEM, BBOX_DIR_LIMIT);
117 	}
118 	set_fs(old_fs);
119 
120 	return 0;
121 }
122 
create_log_dir(const char * path)123 int create_log_dir(const char *path)
124 {
125 	char *cur_path = NULL;
126 	int index = 0;
127 
128 	if (unlikely(!path)) {
129 		bbox_print_err("path is NULL!\n");
130 		return -EINVAL;
131 	}
132 
133 	if (*path != '/')
134 		return -EINVAL;
135 	cur_path = vmalloc(PATH_MAX_LEN + 1);
136 	if (!cur_path) {
137 		bbox_print_err("vmalloc failed!\n");
138 		return -ENOMEM;
139 	}
140 	memset(cur_path, 0, PATH_MAX_LEN + 1);
141 	cur_path[index++] = *path++;
142 	while (*path != '\0') {
143 		if (*path == '/')
144 			create_new_dir(cur_path);
145 		cur_path[index] = *path;
146 		path++;
147 		index++;
148 	}
149 	create_new_dir(cur_path);
150 	vfree(cur_path);
151 
152 	return 0;
153 }
154 
get_timestamp(char * buf,size_t buf_size)155 void get_timestamp(char *buf, size_t buf_size)
156 {
157 	struct rtc_time tm;
158 	struct timespec64 tv;
159 
160 	if (unlikely(!buf || buf_size == 0)) {
161 		bbox_print_err("buf: %p, buf_size: %u\n", buf, (unsigned int)buf_size);
162 		return;
163 	}
164 
165 	memset(buf, 0, buf_size);
166 	memset(&tm, 0, sizeof(tm));
167 
168 	memset(&tv, 0, sizeof(tv));
169 	ktime_get_real_ts64(&tv);
170 	tv.tv_sec -= (long)sys_tz.tz_minuteswest * SECONDS_PER_MINUTE;
171 	rtc_time64_to_tm(tv.tv_sec, &tm);
172 
173 	(void)scnprintf(buf, buf_size, TIMESTAMP_FORMAT,
174 			tm.tm_year + YEAR_BASE, tm.tm_mon + 1, tm.tm_mday,
175 			tm.tm_hour, tm.tm_min, tm.tm_sec, get_ticks());
176 	buf[buf_size - 1] = '\0';
177 }
178 
get_ticks(void)179 unsigned long long get_ticks(void)
180 {
181 	/* use only one int value to save time: */
182 
183 	struct timespec64 uptime;
184 
185 	ktime_get_ts64(&uptime);
186 
187 	ktime_get_boottime_ts64(&uptime);
188 
189 	return (u64)uptime.tv_sec;
190 }
191