mirror of
https://github.com/projectacrn/acrn-hypervisor.git
synced 2025-06-28 00:06:55 +00:00
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>
This commit is contained in:
parent
c01e675582
commit
db05675f38
@ -3,7 +3,7 @@ MINOR_VERSION=0
|
|||||||
|
|
||||||
VERSION_H = $(BUILDDIR)/include/acrnprobe/version.h
|
VERSION_H = $(BUILDDIR)/include/acrnprobe/version.h
|
||||||
|
|
||||||
LIBS = -lpthread -lxml2 -lcrypto -lrt $(EXTRA_LIBS)
|
LIBS = -lpthread -lxml2 -lcrypto -lrt -lblkid $(EXTRA_LIBS)
|
||||||
INCLUDE += -I $(CURDIR)/include -I /usr/include/libxml2
|
INCLUDE += -I $(CURDIR)/include -I /usr/include/libxml2
|
||||||
INCLUDE += -I $(BUILDDIR)/include/acrnprobe
|
INCLUDE += -I $(BUILDDIR)/include/acrnprobe
|
||||||
CFLAGS += $(INCLUDE)
|
CFLAGS += $(INCLUDE)
|
||||||
@ -36,7 +36,8 @@ $(BUILDDIR)/acrnprobe/bin/acrnprobe: $(BUILDDIR)/acrnprobe/obj/main.o \
|
|||||||
$(BUILDDIR)/acrnprobe/obj/property.o \
|
$(BUILDDIR)/acrnprobe/obj/property.o \
|
||||||
$(BUILDDIR)/acrnprobe/obj/probeutils.o \
|
$(BUILDDIR)/acrnprobe/obj/probeutils.o \
|
||||||
$(BUILDDIR)/acrnprobe/obj/history.o \
|
$(BUILDDIR)/acrnprobe/obj/history.o \
|
||||||
$(BUILDDIR)/acrnprobe/obj/android_events.o
|
$(BUILDDIR)/acrnprobe/obj/android_events.o \
|
||||||
|
$(BUILDDIR)/acrnprobe/obj/loop.o
|
||||||
$(CC) -o $@ $^ $(LDFLAGS)
|
$(CC) -o $@ $^ $(LDFLAGS)
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
232
tools/acrn-crashlog/acrnprobe/loop.c
Normal file
232
tools/acrn-crashlog/acrnprobe/loop.c
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 Intel Corporation
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <linux/loop.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <blkid/blkid.h>
|
||||||
|
#include <ext2fs/ext2fs.h>
|
||||||
|
#include "log_sys.h"
|
||||||
|
|
||||||
|
#define DEV_LOOP_CTL "/dev/loop-control"
|
||||||
|
|
||||||
|
static int get_par_startaddr_from_img(const char *img,
|
||||||
|
const char *target_parname,
|
||||||
|
unsigned long long *start)
|
||||||
|
{
|
||||||
|
blkid_probe pr;
|
||||||
|
blkid_partlist ls;
|
||||||
|
blkid_partition par;
|
||||||
|
int i;
|
||||||
|
int nparts;
|
||||||
|
const char *par_name;
|
||||||
|
unsigned int sector_size;
|
||||||
|
unsigned long long par_start;
|
||||||
|
|
||||||
|
if (!img || !target_parname || !start)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pr = blkid_new_probe_from_filename(img);
|
||||||
|
if (!pr) {
|
||||||
|
LOGE("blkid new probe failed\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ls = blkid_probe_get_partitions(pr);
|
||||||
|
if (!ls) {
|
||||||
|
LOGE("blkid get partitions failed\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
nparts = blkid_partlist_numof_partitions(ls);
|
||||||
|
if (nparts <= 0) {
|
||||||
|
LOGE("(%d) partitions in (%s)??\n", nparts, img);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < nparts; i++) {
|
||||||
|
par = blkid_partlist_get_partition(ls, i);
|
||||||
|
par_name = blkid_partition_get_name(par);
|
||||||
|
if (!par_name) {
|
||||||
|
LOGW("A partition in (%s) don't have name??\n", img);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(par_name, target_parname))
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
LOGE("no partition of (%s) is named %s\n", img, target_parname);
|
||||||
|
err:
|
||||||
|
blkid_free_probe(pr);
|
||||||
|
return -1;
|
||||||
|
found:
|
||||||
|
sector_size = blkid_probe_get_sectorsize(pr);
|
||||||
|
par_start = (unsigned long long)blkid_partition_get_start(par);
|
||||||
|
*start = par_start * sector_size;
|
||||||
|
blkid_free_probe(pr);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loopdev_num_get_free(void)
|
||||||
|
{
|
||||||
|
int loopctlfd;
|
||||||
|
int devnr;
|
||||||
|
|
||||||
|
loopctlfd = open(DEV_LOOP_CTL, O_RDONLY);
|
||||||
|
if (loopctlfd == -1) {
|
||||||
|
LOGE("failed to open %s, error (%s)\n", DEV_LOOP_CTL,
|
||||||
|
strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
devnr = ioctl(loopctlfd, LOOP_CTL_GET_FREE);
|
||||||
|
if (devnr == -1) {
|
||||||
|
LOGE("failed to get free loopdev, error (%s)\n",
|
||||||
|
strerror(errno));
|
||||||
|
close(loopctlfd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(loopctlfd);
|
||||||
|
return devnr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loopdev_set_status(const char *loopdev,
|
||||||
|
const struct loop_info64 *info)
|
||||||
|
{
|
||||||
|
int loopfd;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!loopdev || !info)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
loopfd = open(loopdev, O_RDWR);
|
||||||
|
if (loopfd == -1) {
|
||||||
|
LOGE("failed to open (%s), error(%s)\n", loopdev,
|
||||||
|
strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ioctl(loopfd, LOOP_SET_STATUS64, info);
|
||||||
|
if (res == -1) {
|
||||||
|
LOGE("failed to set info to (%s), error(%s)\n", loopdev,
|
||||||
|
strerror(errno));
|
||||||
|
close(loopfd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(loopfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int loopdev_set_img(const char *loopdev, const char *img_path)
|
||||||
|
{
|
||||||
|
int loopfd;
|
||||||
|
int imgfd;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!loopdev || !img_path)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
loopfd = open(loopdev, O_WRONLY);
|
||||||
|
if (loopfd == -1) {
|
||||||
|
LOGE("failed to open %s, error (%s)\n", loopdev,
|
||||||
|
strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
imgfd = open(img_path, O_RDONLY);
|
||||||
|
if (imgfd == -1) {
|
||||||
|
LOGE("failed to open %s, error (%s)\n", img_path,
|
||||||
|
strerror(errno));
|
||||||
|
close(loopfd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = ioctl(loopfd, LOOP_SET_FD, imgfd);
|
||||||
|
if (res == -1) {
|
||||||
|
LOGE("failed to set (%s) to (%s), error (%s)\n", img_path,
|
||||||
|
loopdev, strerror(errno));
|
||||||
|
close(loopfd);
|
||||||
|
close(imgfd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(loopfd);
|
||||||
|
close(imgfd);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loopdev_set_img_par(const char *loopdev, const char *img_path,
|
||||||
|
const char *parname)
|
||||||
|
{
|
||||||
|
struct loop_info64 info;
|
||||||
|
unsigned long long par_start;
|
||||||
|
int res;
|
||||||
|
|
||||||
|
if (!loopdev || !img_path || !parname)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
res = get_par_startaddr_from_img(img_path, parname, &par_start);
|
||||||
|
if (res == -1) {
|
||||||
|
LOGE("failed to get data par startaddr\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = loopdev_set_img(loopdev, img_path);
|
||||||
|
if (res) {
|
||||||
|
LOGE("failed to set img (%s) to (%s), error (%s)\n",
|
||||||
|
img_path, loopdev, strerror(-res));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&info, 0, sizeof(info));
|
||||||
|
info.lo_offset = par_start;
|
||||||
|
|
||||||
|
res = loopdev_set_status(loopdev, &info);
|
||||||
|
if (res < 0) {
|
||||||
|
LOGE("failed to set loopdev, error (%s)\n", strerror(-res));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int loopdev_check_parname(const char *loopdev, const char *parname)
|
||||||
|
{
|
||||||
|
struct ext2_super_block super;
|
||||||
|
int fd;
|
||||||
|
const int skiprate = 512;
|
||||||
|
loff_t sk = 0;
|
||||||
|
|
||||||
|
if (!loopdev || !parname)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
/* quickly find super block */
|
||||||
|
fd = open(loopdev, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
LOGE("failed to open (%s), error(%s)\n", loopdev,
|
||||||
|
strerror(errno));
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
for (; lseek64(fd, sk, SEEK_SET) != -1 &&
|
||||||
|
read(fd, &super, 512) == 512; sk += skiprate) {
|
||||||
|
if (super.s_magic != EXT2_SUPER_MAGIC)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LOGD("find super block at +%ld\n", sk);
|
||||||
|
/* only look into the primary super block */
|
||||||
|
if (super.s_volume_name[0]) {
|
||||||
|
close(fd);
|
||||||
|
return !strcmp(super.s_volume_name, parname);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user