1 /*
2 * Copyright 2018 Google, Inc
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <sys/cdefs.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <stdio.h>
23 #include <unistd.h>
24
25 #include <cutils/sockets.h>
26 #include <liblmkd_utils.h>
27 #include <processgroup/processgroup.h>
28
lmkd_connect()29 int lmkd_connect() {
30 return socket_local_client("lmkd",
31 ANDROID_SOCKET_NAMESPACE_RESERVED,
32 SOCK_SEQPACKET | SOCK_CLOEXEC);
33 }
34
lmkd_register_proc(int sock,struct lmk_procprio * params)35 int lmkd_register_proc(int sock, struct lmk_procprio *params) {
36 LMKD_CTRL_PACKET packet;
37 size_t size;
38 int ret;
39
40 size = lmkd_pack_set_procprio(packet, params);
41 ret = TEMP_FAILURE_RETRY(write(sock, packet, size));
42
43 return (ret < 0) ? -1 : 0;
44 }
45
lmkd_register_procs(int sock,struct lmk_procs_prio * params,const int proc_count)46 int lmkd_register_procs(int sock, struct lmk_procs_prio* params, const int proc_count) {
47 LMKD_CTRL_PACKET packet;
48 size_t size;
49 int ret;
50
51 size = lmkd_pack_set_procs_prio(packet, params, proc_count);
52 ret = TEMP_FAILURE_RETRY(write(sock, packet, size));
53
54 return (ret < 0) ? -1 : 0;
55 }
56
lmkd_unregister_proc(int sock,struct lmk_procremove * params)57 int lmkd_unregister_proc(int sock, struct lmk_procremove *params) {
58 LMKD_CTRL_PACKET packet;
59 size_t size;
60 int ret;
61
62 size = lmkd_pack_set_procremove(packet, params);
63 ret = TEMP_FAILURE_RETRY(write(sock, packet, size));
64
65 return (ret < 0) ? -1 : 0;
66 }
67
lmkd_update_props(int sock)68 enum update_props_result lmkd_update_props(int sock) {
69 LMKD_CTRL_PACKET packet;
70 int size;
71
72 size = lmkd_pack_set_update_props(packet);
73 if (TEMP_FAILURE_RETRY(write(sock, packet, size)) < 0) {
74 return UPDATE_PROPS_SEND_ERR;
75 }
76
77 size = TEMP_FAILURE_RETRY(read(sock, packet, CTRL_PACKET_MAX_SIZE));
78 if (size < 0) {
79 return UPDATE_PROPS_RECV_ERR;
80 }
81
82 if (size != 2 * sizeof(int) || lmkd_pack_get_cmd(packet) != LMK_UPDATE_PROPS) {
83 return UPDATE_PROPS_FORMAT_ERR;
84 }
85
86 struct lmk_update_props_reply params;
87 lmkd_pack_get_update_props_repl(packet, ¶ms);
88
89 return params.result == 0 ? UPDATE_PROPS_SUCCESS : UPDATE_PROPS_FAIL;
90 }
91
lmkd_notify_boot_completed(int sock)92 enum boot_completed_notification_result lmkd_notify_boot_completed(int sock) {
93 LMKD_CTRL_PACKET packet;
94 int size;
95
96 size = lmkd_pack_set_boot_completed_notif(packet);
97 if (TEMP_FAILURE_RETRY(write(sock, packet, size)) < 0) {
98 return BOOT_COMPLETED_NOTIF_SEND_ERR;
99 }
100
101 size = TEMP_FAILURE_RETRY(read(sock, packet, CTRL_PACKET_MAX_SIZE));
102 if (size < 0) {
103 return BOOT_COMPLETED_NOTIF_RECV_ERR;
104 }
105
106 if (size != 2 * sizeof(int) || lmkd_pack_get_cmd(packet) != LMK_BOOT_COMPLETED) {
107 return BOOT_COMPLETED_NOTIF_FORMAT_ERR;
108 }
109
110 struct lmk_boot_completed_notif_reply params;
111 lmkd_pack_get_boot_completed_notif_repl(packet, ¶ms);
112
113 enum boot_completed_notification_result res;
114 switch (params.result) {
115 case -1:
116 res = BOOT_COMPLETED_NOTIF_FAILS;
117 break;
118 case 0:
119 res = BOOT_COMPLETED_NOTIF_SUCCESS;
120 break;
121 case 1:
122 res = BOOT_COMPLETED_NOTIF_ALREADY_HANDLED;
123 break;
124 default:
125 /* This should never be reached */
126 res = BOOT_COMPLETED_NOTIF_FAILS;
127 }
128
129 return res;
130 }
131
lmkd_get_kill_count(int sock,struct lmk_getkillcnt * params)132 int lmkd_get_kill_count(int sock, struct lmk_getkillcnt* params) {
133 LMKD_CTRL_PACKET packet;
134 int size;
135
136 size = lmkd_pack_set_getkillcnt(packet, params);
137 if (TEMP_FAILURE_RETRY(write(sock, packet, size)) < 0) {
138 return (int)GET_KILL_COUNT_SEND_ERR;
139 }
140
141 size = TEMP_FAILURE_RETRY(read(sock, packet, CTRL_PACKET_MAX_SIZE));
142 if (size < 0) {
143 return (int)GET_KILL_COUNT_RECV_ERR;
144 }
145
146 if (size != 2 * sizeof(int) || lmkd_pack_get_cmd(packet) != LMK_GETKILLCNT) {
147 return (int)GET_KILL_COUNT_FORMAT_ERR;
148 }
149
150 return packet[1];
151 }
152
create_memcg(uid_t uid,pid_t pid)153 int create_memcg(uid_t uid, pid_t pid) {
154 return createProcessGroup(uid, pid, true) == 0 ? 0 : -1;
155 }
156
157