1 /*
2 * Copyright (C) 2018-2022 Intel Corporation.
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
6 #include "log_sys.h"
7 #include "fsutils.h"
8 #include "strutils.h"
9 #include "vmrecord.h"
10 #include <stdlib.h>
11
vmrecord_last(struct vmrecord_t * vmrecord,const char * vm_name,size_t nlen,char * vmkey,size_t ksize)12 int vmrecord_last(struct vmrecord_t *vmrecord, const char *vm_name,
13 size_t nlen, char *vmkey, size_t ksize)
14 {
15 int res;
16 char *p;
17 char *key;
18
19 if (!vmrecord || !vm_name || !nlen || !vmkey || !ksize)
20 return -1;
21
22 key = malloc(nlen + 2);
23 if (!key)
24 return -1;
25
26 memcpy(key, vm_name, nlen);
27 key[nlen] = ' ';
28 key[nlen + 1] = '\0';
29
30 pthread_mutex_lock(&vmrecord->mtx);
31 res = file_read_key_value_r(vmkey, ksize, vmrecord->path, key,
32 nlen + 1);
33 pthread_mutex_unlock(&vmrecord->mtx);
34 free(key);
35 if (res < 0) {
36 LOGE("failed to search %s, %s\n", vmrecord->path,
37 strerror(errno));
38 return -1;
39 }
40 p = strchr(vmkey, ' ');
41 if (p)
42 *p = 0;
43
44 return 0;
45 }
46
47 /* This function must be called with holding vmrecord mutex */
vmrecord_mark(struct vmrecord_t * vmrecord,const char * vmkey,size_t klen,enum vmrecord_mark_t type)48 int vmrecord_mark(struct vmrecord_t *vmrecord, const char *vmkey,
49 size_t klen, enum vmrecord_mark_t type)
50 {
51 size_t len;
52 char *line;
53 char *tag;
54
55 if (!vmrecord || !vmrecord->recos || !vmkey || !klen)
56 return -1;
57
58 line = get_line(vmkey, klen, vmrecord->recos->begin,
59 vmrecord->recos->size, vmrecord->recos->begin, &len);
60 if (!line)
61 return -1;
62
63 tag = line + len - VMRECORD_TAG_LEN;
64
65 if (type == SUCCESS)
66 memcpy(tag, VMRECORD_TAG_SUCCESS, VMRECORD_TAG_LEN);
67 else if (type == NOT_FOUND)
68 memcpy(tag, VMRECORD_TAG_NOT_FOUND, VMRECORD_TAG_LEN);
69 else if (type == MISS_LOG)
70 memcpy(tag, VMRECORD_TAG_MISS_LOG, VMRECORD_TAG_LEN);
71 else if (type == WAITING_SYNC)
72 memcpy(tag, VMRECORD_TAG_WAITING_SYNC, VMRECORD_TAG_LEN);
73 else if (type == ON_GOING)
74 memcpy(tag, VMRECORD_TAG_ON_GOING, VMRECORD_TAG_LEN);
75 else if (type == NO_RESRC)
76 memcpy(tag, VMRECORD_TAG_NO_RESOURCE, VMRECORD_TAG_LEN);
77 else
78 return -1;
79
80 return 0;
81
82 }
83
vmrecord_open_mark(struct vmrecord_t * vmrecord,const char * vmkey,size_t klen,enum vmrecord_mark_t type)84 int vmrecord_open_mark(struct vmrecord_t *vmrecord, const char *vmkey,
85 size_t klen, enum vmrecord_mark_t type)
86 {
87 int ret;
88
89 if (!vmrecord || !vmkey || !klen)
90 return -1;
91
92 pthread_mutex_lock(&vmrecord->mtx);
93 vmrecord->recos = mmap_file(vmrecord->path);
94 if (!vmrecord->recos) {
95 LOGE("failed to mmap %s, %s\n", vmrecord->path,
96 strerror(errno));
97 ret = -1;
98 goto unlock;
99 }
100 if (!vmrecord->recos->size ||
101 mm_count_lines(vmrecord->recos) < VMRECORD_HEAD_LINES) {
102 LOGE("(%s) invalid\n", vmrecord->path);
103 ret = -1;
104 goto out;
105 }
106
107 ret = vmrecord_mark(vmrecord, vmkey, klen, type);
108 out:
109 unmap_file(vmrecord->recos);
110 unlock:
111 pthread_mutex_unlock(&vmrecord->mtx);
112 return ret;
113 }
114
vmrecord_gen_ifnot_exists(struct vmrecord_t * vmrecord)115 int vmrecord_gen_ifnot_exists(struct vmrecord_t *vmrecord)
116 {
117 const char * const head =
118 "/* DONT EDIT!\n"
119 " * This file records VM id synced or about to be synched,\n"
120 " * the tag:\n"
121 " * \"<==\" indicates event waiting to sync.\n"
122 " * \"NOT_FOUND\" indicates event not found in User VM.\n"
123 " * \"MISS_LOGS\" indicates event miss logs in User VM.\n"
124 " * \"ON_GOING\" indicates event is under syncing.\n"
125 " * \"NO_RESORC\" indicates no enough resources in Service VM.\n"
126 " */\n\n";
127
128 if (!vmrecord) {
129 LOGE("vmrecord was not initialized\n");
130 return -1;
131 }
132
133 pthread_mutex_lock(&vmrecord->mtx);
134 if (!file_exists(vmrecord->path)) {
135 if (overwrite_file(vmrecord->path, head) < 0) {
136 pthread_mutex_unlock(&vmrecord->mtx);
137 LOGE("failed to create file (%s), %s\n",
138 vmrecord->path, strerror(errno));
139 return -1;
140 }
141 }
142 pthread_mutex_unlock(&vmrecord->mtx);
143 return 0;
144 }
145
vmrecord_new(struct vmrecord_t * vmrecord,const char * vm_name,const char * key)146 int vmrecord_new(struct vmrecord_t *vmrecord, const char *vm_name,
147 const char *key)
148 {
149 char log_new[64];
150 int nlen;
151
152 if (!vmrecord || !vm_name || !key)
153 return -1;
154
155 nlen = snprintf(log_new, sizeof(log_new), "%s %s %s\n",
156 vm_name, key, VMRECORD_TAG_WAITING_SYNC);
157 if (s_not_expect(nlen, sizeof(log_new))) {
158 LOGE("failed to construct record, key (%s)\n", key);
159 return -1;
160 }
161
162 pthread_mutex_lock(&vmrecord->mtx);
163 if (append_file(vmrecord->path, log_new, strnlen(log_new, 64)) < 0) {
164 pthread_mutex_unlock(&vmrecord->mtx);
165 LOGE("failed to append file (%s), %s\n", vmrecord->path,
166 strerror(errno));
167 return -1;
168 }
169 pthread_mutex_unlock(&vmrecord->mtx);
170 return 0;
171 }
172