前言
在Xen 半虚拟环境下增加新的设备,首先需要将新设备进行注册,前后端设备的注册可通过3步完成。
v 对配置文件进行解析,获取虚拟设备的信息
v 根据获取的虚拟设备信息将设备写入到XenStore上
v XenBus遍历XenStore目录,将前后端设备注册到XenBus总线
备注:前后端设备既可以在XenBus初始化时加载,也可以通过Hotplug的方式加载。虚拟机启动时会初始化XenBus总线,在初始化过程中将遍历XenStore读取所有前端设备信息,然后注册前端设备到XenBus总线,后端设备则通过Hotplug方式注册到XenBus总线。
具体实现过程如下:
(二)、将设备添加到Xenstore
接上一篇博客:
5、libxl_create.c
do_domain_create(.....);
init_domain_create(......);
添加函数 ret= libxl_device_mydevice_setdefault(gc,&d_config->mydevices[i]);
该函数的定义在libxl.c中
6、libxl_create.c
domcreate_launch_dm(){
......
switch(d_config->c_info.type){
case LIBXL_DOMAIN_TYPE_HVM:
{
//****************************************添加设备mydevice*********************************************
libxl_device_mydevice_init(&d_config->mydevices[0]);
libxl__device_mydevice_add(&d_config->mydevices[0]);
libxl_device_mydevice_dispose(&d_config->mydevices[0]);
......
}
case LIBXL_DOMAIN_TYPE_PV:
{
......
for(i=0;i<d_config->num_mydevices;i++){
libxl_device_mydevice_add(gc,domid,&d_config->mydevices[i]);
}
}
}
}
7、libxl.clibxl__device_mydevice_setdefault(libxl__gc *gc,libxl_device_mydevice *mydevice){
int run_hotplug_scripts;
int rc;
run_hotplug_scripts = libxl__hotplug_settings(gc, XBT_NULL);
if (run_hotplug_scripts < 0) {
LOG(ERROR, "unable to get current hotplug scripts execution setting");
return run_hotplug_scripts;
}
rc = libxl__resolve_domid(gc, mydevice->backend_domname, &mydevice->backend_domid);
if (rc < 0) return rc;
libxl_mydevice_example_to_string(LIBXL_MYDEVICE_EXAMPLE_ZXM);
return rc;
}
static int libxl__device_from_mydevice(libxl__gc *gc, uint32_t domid,
libxl_device_mydevice *mydevice,
libxl__device *device)
{
device->backend_devid = mydevice->devid;
device->backend_domid = mydevice->backend_domid;
device->backend_kind = LIBXL__DEVICE_KIND_MYDEVICE;
device->devid = mydevice->devid;
device->domid = domid;
device->kind = LIBXL__DEVICE_KIND_MYDEVICE;
return 0;
}
int libxl_device_mydevice_add(libxl_ctx *ctx, uint32_t domid, libxl_device_mydevice *mydevice,
const libxl_asyncop_how *ao_how)
{
AO_CREATE(ctx, domid, ao_how);
int rc;
rc = libxl__device_mydevice_add(gc, domid, mydevice);
if (rc) {
LOG(ERROR, "unable to add mydevice device");
goto out;
}
out:
libxl__ao_complete(egc, ao, rc);
return AO_INPROGRESS;
}
int libxl__device_mydevice_add(libxl__gc *gc, uint32_t domid,
libxl_device_mydevice *mydevice)
{
//STATE_AO_GC(aodev->ao);
flexarray_t *front;
flexarray_t *back;
libxl__device *device;
int rc;
rc = libxl__device_mydevice_setdefault(gc, mydevice);
if (rc) goto out;
front = flexarray_make(gc, 16, 1);
//ro_front = flexarray_make(gc, 16, 1);
back = flexarray_make(gc, 16, 1);
if (mydevice->devid == -1) {
if ((mydevice->devid = libxl__device_nextid(gc, domid, "mydevice")) < 0) {
rc = ERROR_FAIL;
goto out;
}
}
GCNEW(device);
rc = libxl__device_from_mydevice(gc, domid, mydevice, device);
if ( rc != 0 ) goto out;
flexarray_append(back, "frontend-id");
flexarray_append(back, libxl__sprintf(gc, "%d", domid));
flexarray_append(back, "online");
flexarray_append(back, "1");
flexarray_append(back, "state");
flexarray_append(back, libxl__sprintf(gc, "%d", 1));
flexarray_append(back, "domain");
flexarray_append(back, libxl__domid_to_name(gc, domid));
flexarray_append(back, "example");
flexarray_append(back, libxl__strdup(gc,
libxl_mydevice_example_to_string(LIBXL_MYDEVICE_EXAMPLE_ZXM)));
flexarray_append(front, "backend-id");
flexarray_append(front, libxl__sprintf(gc, "%d", mydevice->backend_domid));
flexarray_append(front, "state");
flexarray_append(front, libxl__sprintf(gc, "%d", 1));
flexarray_append(front, "example");
flexarray_append(front, libxl__strdup(gc,
libxl_mydevice_example_to_string(LIBXL_MYDEVICE_EXAMPLE_ZXM)));
printf("write mydevice into xenstore!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1\n");
libxl__device_generic_add(gc, XBT_NULL, device,
libxl__xs_kvs_of_flexarray(gc, back, back->count),
libxl__xs_kvs_of_flexarray(gc, front, front->count),
NULL);
rc = 0;
out:
return rc;
}
至此 设备添加成功,可通过xenstore ls指令查看;
接下来是将前后端设备和驱动注册到xenbus,并实现前后端设备的通信。
【注】:所有对Xen代码的更改,都要重新编译Xen程序,在相应目录下执行make install 即可。