Skip to content

Commit db05675

Browse files
lauxinwlijinxia
authored andcommitted
tools: acrn-crashlog: New apis to replace losetup and fdisk
This patch adds new apis to replace commands losetup and fdisk. Main changes include: 1. impletement apis to operate loop devices directly. 2. impletement apis to get partition information from image file. Signed-off-by: Liu, Xinwu <xinwu.liu@intel.com> Acked-by: Chen Gang <gang.c.chen@intel.com>
1 parent c01e675 commit db05675

File tree

2 files changed

+235
-2
lines changed

2 files changed

+235
-2
lines changed

tools/acrn-crashlog/acrnprobe/Makefile

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ MINOR_VERSION=0
33

44
VERSION_H = $(BUILDDIR)/include/acrnprobe/version.h
55

6-
LIBS = -lpthread -lxml2 -lcrypto -lrt $(EXTRA_LIBS)
6+
LIBS = -lpthread -lxml2 -lcrypto -lrt -lblkid $(EXTRA_LIBS)
77
INCLUDE += -I $(CURDIR)/include -I /usr/include/libxml2
88
INCLUDE += -I $(BUILDDIR)/include/acrnprobe
99
CFLAGS += $(INCLUDE)
@@ -36,7 +36,8 @@ $(BUILDDIR)/acrnprobe/bin/acrnprobe: $(BUILDDIR)/acrnprobe/obj/main.o \
3636
$(BUILDDIR)/acrnprobe/obj/property.o \
3737
$(BUILDDIR)/acrnprobe/obj/probeutils.o \
3838
$(BUILDDIR)/acrnprobe/obj/history.o \
39-
$(BUILDDIR)/acrnprobe/obj/android_events.o
39+
$(BUILDDIR)/acrnprobe/obj/android_events.o \
40+
$(BUILDDIR)/acrnprobe/obj/loop.o
4041
$(CC) -o $@ $^ $(LDFLAGS)
4142

4243
.PHONY: clean

tools/acrn-crashlog/acrnprobe/loop.c

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* Copyright (C) 2018 Intel Corporation
3+
* SPDX-License-Identifier: BSD-3-Clause
4+
*/
5+
6+
#include <stdio.h>
7+
#include <fcntl.h>
8+
#include <linux/loop.h>
9+
#include <sys/stat.h>
10+
#include <sys/ioctl.h>
11+
#include <stdlib.h>
12+
#include <unistd.h>
13+
#include <string.h>
14+
#include <errno.h>
15+
#include <blkid/blkid.h>
16+
#include <ext2fs/ext2fs.h>
17+
#include "log_sys.h"
18+
19+
#define DEV_LOOP_CTL "/dev/loop-control"
20+
21+
static int get_par_startaddr_from_img(const char *img,
22+
const char *target_parname,
23+
unsigned long long *start)
24+
{
25+
blkid_probe pr;
26+
blkid_partlist ls;
27+
blkid_partition par;
28+
int i;
29+
int nparts;
30+
const char *par_name;
31+
unsigned int sector_size;
32+
unsigned long long par_start;
33+
34+
if (!img || !target_parname || !start)
35+
return -1;
36+
37+
pr = blkid_new_probe_from_filename(img);
38+
if (!pr) {
39+
LOGE("blkid new probe failed\n");
40+
return -1;
41+
}
42+
ls = blkid_probe_get_partitions(pr);
43+
if (!ls) {
44+
LOGE("blkid get partitions failed\n");
45+
goto err;
46+
}
47+
nparts = blkid_partlist_numof_partitions(ls);
48+
if (nparts <= 0) {
49+
LOGE("(%d) partitions in (%s)??\n", nparts, img);
50+
goto err;
51+
}
52+
53+
for (i = 0; i < nparts; i++) {
54+
par = blkid_partlist_get_partition(ls, i);
55+
par_name = blkid_partition_get_name(par);
56+
if (!par_name) {
57+
LOGW("A partition in (%s) don't have name??\n", img);
58+
continue;
59+
}
60+
if (!strcmp(par_name, target_parname))
61+
goto found;
62+
}
63+
LOGE("no partition of (%s) is named %s\n", img, target_parname);
64+
err:
65+
blkid_free_probe(pr);
66+
return -1;
67+
found:
68+
sector_size = blkid_probe_get_sectorsize(pr);
69+
par_start = (unsigned long long)blkid_partition_get_start(par);
70+
*start = par_start * sector_size;
71+
blkid_free_probe(pr);
72+
return 0;
73+
}
74+
75+
int loopdev_num_get_free(void)
76+
{
77+
int loopctlfd;
78+
int devnr;
79+
80+
loopctlfd = open(DEV_LOOP_CTL, O_RDONLY);
81+
if (loopctlfd == -1) {
82+
LOGE("failed to open %s, error (%s)\n", DEV_LOOP_CTL,
83+
strerror(errno));
84+
return -errno;
85+
}
86+
87+
devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE);
88+
if (devnr == -1) {
89+
LOGE("failed to get free loopdev, error (%s)\n",
90+
strerror(errno));
91+
close(loopctlfd);
92+
return -errno;
93+
}
94+
95+
close(loopctlfd);
96+
return devnr;
97+
}
98+
99+
static int loopdev_set_status(const char *loopdev,
100+
const struct loop_info64 *info)
101+
{
102+
int loopfd;
103+
int res;
104+
105+
if (!loopdev || !info)
106+
return -EINVAL;
107+
108+
loopfd = open(loopdev, O_RDWR);
109+
if (loopfd == -1) {
110+
LOGE("failed to open (%s), error(%s)\n", loopdev,
111+
strerror(errno));
112+
return -errno;
113+
}
114+
115+
res = ioctl(loopfd, LOOP_SET_STATUS64, info);
116+
if (res == -1) {
117+
LOGE("failed to set info to (%s), error(%s)\n", loopdev,
118+
strerror(errno));
119+
close(loopfd);
120+
return -errno;
121+
}
122+
123+
close(loopfd);
124+
return 0;
125+
}
126+
127+
static int loopdev_set_img(const char *loopdev, const char *img_path)
128+
{
129+
int loopfd;
130+
int imgfd;
131+
int res;
132+
133+
if (!loopdev || !img_path)
134+
return -EINVAL;
135+
136+
loopfd = open(loopdev, O_WRONLY);
137+
if (loopfd == -1) {
138+
LOGE("failed to open %s, error (%s)\n", loopdev,
139+
strerror(errno));
140+
return -errno;
141+
}
142+
143+
imgfd = open(img_path, O_RDONLY);
144+
if (imgfd == -1) {
145+
LOGE("failed to open %s, error (%s)\n", img_path,
146+
strerror(errno));
147+
close(loopfd);
148+
return -errno;
149+
}
150+
151+
res = ioctl(loopfd, LOOP_SET_FD, imgfd);
152+
if (res == -1) {
153+
LOGE("failed to set (%s) to (%s), error (%s)\n", img_path,
154+
loopdev, strerror(errno));
155+
close(loopfd);
156+
close(imgfd);
157+
return -errno;
158+
}
159+
160+
close(loopfd);
161+
close(imgfd);
162+
return 0;
163+
}
164+
165+
int loopdev_set_img_par(const char *loopdev, const char *img_path,
166+
const char *parname)
167+
{
168+
struct loop_info64 info;
169+
unsigned long long par_start;
170+
int res;
171+
172+
if (!loopdev || !img_path || !parname)
173+
return -1;
174+
175+
res = get_par_startaddr_from_img(img_path, parname, &par_start);
176+
if (res == -1) {
177+
LOGE("failed to get data par startaddr\n");
178+
return -1;
179+
}
180+
181+
res = loopdev_set_img(loopdev, img_path);
182+
if (res) {
183+
LOGE("failed to set img (%s) to (%s), error (%s)\n",
184+
img_path, loopdev, strerror(-res));
185+
return -1;
186+
}
187+
188+
memset(&info, 0, sizeof(info));
189+
info.lo_offset = par_start;
190+
191+
res = loopdev_set_status(loopdev, &info);
192+
if (res < 0) {
193+
LOGE("failed to set loopdev, error (%s)\n", strerror(-res));
194+
return -1;
195+
}
196+
return 0;
197+
}
198+
199+
int loopdev_check_parname(const char *loopdev, const char *parname)
200+
{
201+
struct ext2_super_block super;
202+
int fd;
203+
const int skiprate = 512;
204+
loff_t sk = 0;
205+
206+
if (!loopdev || !parname)
207+
return -ENOENT;
208+
209+
/* quickly find super block */
210+
fd = open(loopdev, O_RDONLY);
211+
if (fd == -1) {
212+
LOGE("failed to open (%s), error(%s)\n", loopdev,
213+
strerror(errno));
214+
return -errno;
215+
}
216+
for (; lseek64(fd, sk, SEEK_SET) != -1 &&
217+
read(fd, &super, 512) == 512; sk += skiprate) {
218+
if (super.s_magic != EXT2_SUPER_MAGIC)
219+
continue;
220+
221+
LOGD("find super block at +%ld\n", sk);
222+
/* only look into the primary super block */
223+
if (super.s_volume_name[0]) {
224+
close(fd);
225+
return !strcmp(super.s_volume_name, parname);
226+
}
227+
break;
228+
}
229+
230+
close(fd);
231+
return 0;
232+
}

0 commit comments

Comments
 (0)