2017-09-22 13:43:00 DXsunrise 阅读数 107

linux apache vhost

<VirtualHost *:80>
DocumentRoot "/usr/www/yltgerp_old/"
ServerName erp.yltg.com.cn
ErrorLog "logs/yltgerp_old-error_log"
CustomLog "logs/yltgerp_old-access_log
</VirtualHost>

  

posted @ 2017-09-22 13:43 懒牛拉车 阅读(...) 评论(...) 编辑 收藏
2013-11-14 11:30:47 heavendai 阅读数 1965

Apache,PHP

将php.ini中设置

short_open_tag = On

 

Windows:

在httpd.conf下加入代码:
NameVirtualHost *:80
<VirtualHost *:80>
    DocumentRoot "D:/Program Files/xampps/htdocs/autorule"
    ServerName autorule.dmy.com
</VirtualHost>
从项目路径为DocumentRoot。

重启Apache

在C:\Windows\System32\drivers\etc\host中加入:

127.0.0.1    autorule.dmy.co

用下面URL进行访问:

http://autorule.dmy.com/index.php

即可。

 

Linux同上:

修改/etc/httpd/conf/httpd.conf加入

NameVirtualHost *:80
<VirtualHost *:80>
    DocumentRoot "D:/Program Files/xampps/htdocs/autorule"
    ServerName autorule.dmy.com
</VirtualHost>

重启Apache

不用修改host

即可。

2016-11-10 14:24:00 weixin_30218397 阅读数 2

Vhost 回顾

Linux中的vhost驱动程序提供了内核virtio设备仿真。 通常,QEMU用户空间进程模拟guest的I / O访问。 Vhost将virtio仿真代码放到内核中,使QEMU用户空间脱离。 这允许设备仿真代码直接调用到内核子系统,而不是从用户空间执行系统调用。

vhost-net驱动程序模拟主机内核中的virtio-net网卡。 Vhost-net是最早的vhost设备,也是主流Linux中唯一可用的设备。 也已经开发了实验vhost-blk和vhost-scsi装置。

在Linux 3.0中,vhost代码存放在drivers / vhost /中。 所有设备使用的通用代码在drivers / vhost / vhost.c中。 这包括virtio vring访问功能,所有virtio设备需要为了与客户进行通信。 vhost-net代码存放在drivers / vhost / net.c中。

Vhost 驱动模型

vhost-net驱动程序在主机上创建一个/ dev / vhost-net字符设备。 此字符设备作为配置vhost-net实例的接口。

当使用-netdev tap启动QEMU时,vhost = on将打开/ dev / vhost-net并使用几个ioctl调用初始化vhost-net实例。 这些必须将QEMU进程与vhost-net实例关联,准备virtio功能协商,并将guest虚拟机物理内存映射传递到vhost-net驱动程序。

在初始化期间,vhost驱动程序创建一个名为vhost- $ pid的内核线程,其中$ pid是QEMU进程pid。 这个线程被称为“vhost工作线程”。 工作线程的任务是处理I / O事件并执行设备仿真。

 

 

内核Virtio仿真

Vhost不会模拟一个完整的virtio PCI适配器。 相反,它只将自己限制为virtqueue操作。 QEMU仍然用于执行virtio特性协商和实时迁移。 这意味着vhost驱动程序不是完整的virtio设备实现,它依赖于用户空间来处理控制平面,而数据平面在内核中完成。

vhost工作线程等待virtqueue kick,然后处理放在virtqueue上的缓冲区。 在vhost-net这意味着从tx virtque的数据包并且通过tap文件描述符发送它们。

文件描述符轮询也由vhost工作线程完成。 在vhost-net中,当数据包进入tap文件描述符时,工作线程被唤醒,并将其放置到rx virtqueue中,以便客户端可以接收它们。

Vhost作为用户空间接口

vhost架构的一个令人惊讶的方面是它不以任何方式绑定到KVM。 Vhost是一个用户空间接口,不依赖于KVM内核模块。这意味着其他用户空间代码(如libpcap)在理论上可以使用vhost设备,如果他们发现它们方便的高性能I / O接口。

当客户端kick主机,因为它已经将缓冲区放在一个virtqueue,需要一种方式来通知vhost工作线程有工作要做。由于vhost不依赖于KVM内核模块,它们不能直接通信。相反,vhost实例使用vhost工作线程监视活动的eventfd文件描述符进行设置。 KVM内核模块具有称为ioeventfd的功能,用于获取eventfd并将其挂接到特定的guest虚拟机I / O出口。 QEMU用户空间注册一个ioeventfd用于VIRTIO_PCI_QUEUE_NOTIFY硬件寄存器访问,它能kick virtqueue。这是当guest虚拟机kick virtqueue,vhost工作线程被KVM内核模块通知的方式。

在从vhost工作线程返回到中断客户端时,使用了类似的方法。 Vhost需要一个“call”文件描述符,写这个文件描述符是为了去kick guest。 KVM内核模块有一个称为irqfd的功能,它允许eventfd触发客户机中断。 QEMU用户空间注册一个irqfd为virtio PCI设备中断并将其交给vhost实例。这是vhost工作线程如何中断客户端。

因此,vhost实例只知道guest虚拟机内存映射,kick eventfd和call eventfd。

More detail

 
 
下面是开始探索代码的要点:
drivers / vhost / vhost.c - 常见的vhost驱动程序代码
drivers / vhost / net.c - vhost-net驱动
virt / kvm / eventfd.c - ioeventfd和irqfd
QEMU用户空间代码显示如何初始化vhost实例:
hw / vhost.c - 常见的vhost初始化代码
hw / vhost_net.c - vhost-net初始化

转载于:https://www.cnblogs.com/scottieyuyang/p/6050798.html

vhost
2012-09-23 23:52:21 cybertan 阅读数 7014
vhost的用户态程序接口定义在/usr/include/linux/vhost.h
vhost目前只支持tap network backend


vhost.h/vhost.c
------------------------------
vhost的memory write log机制
vhost使用一个bitmap记录对Guest物理内存的改变,每VHOST_LOG_PAGE(4K)字节大小的内存使用
一个bit来记录,0表示没有改变过,1表示改变过。
由于vhost_dev.log是以vhost_log_chunk_t (unsignedlong)为单位的,因此一个元素包含的位数为
VHOST_LOG_BITS (8 *sizeof(vhost_log_chunk_t)),其所能记录的内存大小为
VHOST_LOG_CHUNK (VHOST_LOG_PAGE * VHOST_LOG_BITS)

因此,对于一个大小为n的内存区域,其log所需的元素数目是 n / VHOST_LOG_CHUNK +1 

vhost_get_log_size函数用于计算所需要的logsize大小。其实在实现上,可以先计算出最大的地址,
然后直接return (max_addr / VHOST_LOG_CHUNK +1),这样就不用在中间每次都使用除法了。
------------------------------

public interface:
   vhost_dev_init 初始化vhost设备
   vhost_dev_cleanup  清除vhost设备
   vhost_dev_query    
   vhost_dev_start    启动vhost设备
   vhost_dev_stop    停止vhost设备
  
vhost_virtqueue_init函数(被vhost_dev_start调用):
1. ioctl VHOST_SET_VRING_NUM 设置vringsize
2. ioctl VHOST_SET_VRING_BASE 设置 (VirtQueue.last_avail_idx)
3. 设置vhost_virtqueue中ring相关的成员(desc,avail, used_size, used_phys, used, 
    ring_size, ring_phys,ring)
4. 调用vhost_virtqueue_set_addr设置相关地址
5. 调用ioctl VHOST_SET_VRING_KICK 设置kick fd(guest -> vhost) (VirtQueue.host_notifier.fd)
6. 调用ioctl VHOST_SET_VRING_CALL 设置call fd(vhost -> guest) (VirtQueue.guest_notifier.fd)

guest_notifier的初始化:
1.在vhost_dev_start起始处,会调用vdev->binding->set_guest_notifiers(vdev->binding_opaque,true)
   对于virtiopci设备来说,该函数就是virtio_pci_set_guest_notifiers(virtio-pci.c)
2. virtio_pci_set_guest_notifiers对每个可能的vq调用virtio_pci_set_guest_notifier
3. virtio_pci_set_guest_notifier先通过event_notifier_init初始化一个eventfd,然后调用
  qemu_set_fd_handler将该eventfd添加到qemu的selectablefd列表中,并指定其read poll处理
  函数为virtio_pci_guest_notifier_read
4.调用msix_set_mask_notifier,其中msix_mask_notifier_func设置为virtio_pci_mask_notifier
5. 对该设备的所有MSI-X入口(0- msix_entries_nr),调用msix_set_mask_notifier_for_vector
6.如果该vector没有被屏蔽,则调用dev->msix_mask_notifier(就是virtio_pci_mask_notifier)
7. 对当前的所有VirtQueue,调用virtio_pci_mask_vq
8. 调用kvm_set_irqfd,设置该VirtQueue的irqfd为guest notifier fd
9.如果设置成功,则调用qemu_set_fd_handler(event_notifier_get_fd(notifier),NULL, NULL, NULL)
   取消掉对该guest notifierfd的select。

guest_notifier的使用:
1. vhost在处理完请求,将buffer放到used ring上面之后,往call fd里面写入
2. 如果成功设置了irqfd,则kvm会直接中断guest。如果没有成功设置,则走以下的路径:
3. qemu通过select调用侦测到该事件(因为vhost的callfd就是qemu里面对应vq的guest_notifier,它
   已经被加入到selectablefd列表)
4. 调用virtio_pci_guest_notifier_read通知guest
5. guest从used ring上获取相关的数据

host_notifier的初始化:
1. 在vhost_virtqueue_init中,会调用
  vdev->binding->set_host_notifiers(vdev->binding_opaque,idx, true)
   对于virtiopci设备来说,该函数就是virtio_pci_set_host_notifier(virtio-pci.c)
2. virtio_pci_set_host_notifier调用virtio_pci_set_host_notifier_internal
3. virtio_pci_set_host_notifier_internal先通过event_notifier_init初始化一个eventfd,再调用
  kvm_set_ioeventfd_pio_word
4. kvm_set_ioeventfd_pio_word通过调用kvm_vm_ioctl(kvm_state,KVM_IOEVENTFD, &kick)来设置kick


在vhost_dev_init中,调用cpu_register_phys_memory_client注册了物理内存的客户端,三个hook函数
分别设置为vhost_client_set_memory, vhost_client_sync_dirty_bitmap, vhost_client_migration_log

CPUPhysMemoryClient结构用于在Guest物理内存变化时得到通知:
typedef struct CPUPhysMemoryClient CPUPhysMemoryClient;
struct CPUPhysMemoryClient {
    void(*set_memory)(struct CPUPhysMemoryClient *client,
                   target_phys_addr_t start_addr,
                    ram_addr_tsize,
                    ram_addr_tphys_offset);
    int(*sync_dirty_bitmap)(struct CPUPhysMemoryClient *client,
                        target_phys_addr_t start_addr,
                        target_phys_addr_t end_addr);
    int(*migration_log)(struct CPUPhysMemoryClient *client,
                     int enable);
   QLIST_ENTRY(CPUPhysMemoryClient) list;
};
set_memory在添加Guest物理内存区域(Region)的时候被调用
sync_dirty_bitmap 同步指定内存区间的dirty bitmap(sync back)
migration_log 设置启用/禁用migration log


vhost_client_set_memory函数:
1. 调用qemu_realloc使vhost_memory的区域数目增加1
2. 调用vhost_dev_unassign_memory确保当前内存区域不和已存在的其他区域有交集
3. 如果是RAM,那么调用vhost_dev_assign_memory添加该内存区域
4. 如果vhost还未启动,则直接返回
5.调用vhost_verify_ring_mappings,检查新添加的内存区域和所有的VirtQueue区域都没有交集
6. 如果禁用了memory writelog,那么调用ioctl VHOST_SET_MEM_TABLE设置内存区域之后返回
7. 如果log size变大,那么先调用vhost_dev_log_resize设置log size,再调用
  ioctl VHOST_SET_MEM_TABLE设置内存区域
8. 如果logsize变小,那么先调用ioctl VHOST_SET_MEM_TABLE设置内存区域,再调用
   vhost_dev_log_resize设置logsize


vhost_client_sync_dirty_bitmap函数(同步对应于指定内存区间的dirtybitmap):
1. 如果禁用了memory write log或者vhost没有启动,则直接返回
2. 对所有vhost_dev上面的内存区域,调用vhost_dev_sync_region
3. 对所有vhost_dev上面的vhost_virtqueue的usedring所对应的内存区域,调用vhost_dev_sync_region

-----------------------------------------------------------------------------------------------
vhost_net.h/vhost_net.c

每个虚拟网卡都对应一个vhost_net,每个vhost_net都包含一个vhost_dev
代码很简单,基本是封装了vhost_dev的相关操作,并加入一些对tap的控制,对feature的控制等。

vhost_net的启用是在命令行的-netdev tap,...中指定vhost=on选项,其初始化流程如下:
1. 根据<<qemu networkbackend的初始化>>一文,在其最后会调用net_client_types[i].init函数
  对于tap,该函数是net_init_tap
2. 在其中会检查选项中是否指定vhost=on,如果指定,则会调用vhost_net_init函数进行初始化,
  并将返回的vhost_net赋值给TAPState.vhost_net成员
3.在Guest初始化设备并改变设备状态时,会调用到virtio-net.c中的virtio_net_set_status函数,
   如果初始化设备成功(status& VIRTIO_CONFIG_S_DRIVER_OK !=0),则会调用vhost_net_start
   启动vhost_net。

没有更多推荐了,返回首页