精品久久久亚洲精品中文字幕_国产色综合久久天天综合观看_视频一区视频二区视频三区_大地资源网在线播放国产一区_中国日本免费不卡在线中文_国产97色在线 国产_免费av在线超碰人妻_成人三级电影大香蕉_麻豆精品视频免费在线观看_女人被男人躁爽免费视频涩爱av

購物車

解決方案

解決方案

您現(xiàn)在的位置:首頁 > 解決方案 > 行業(yè)應用 > 詳細內(nèi)容
基于兆芯平臺的OpenStack云系統(tǒng)調(diào)優(yōu)指南
發(fā)布時間:2024-07-22   點擊次數(shù):256次

  為讓使用兆芯平臺服務器的用戶能夠更快捷的構建IaaS系統(tǒng),充分發(fā)揮兆芯平臺的性能,特編寫本指南,供用戶參考。本指南并不依賴特定產(chǎn)品型號,重在指導用戶在兆芯平臺服務器上的調(diào)試方法,并且會隨著評估測試的深入和成熟度增加逐步完善。

 

  一、系統(tǒng)介紹

 

1.硬件環(huán)境:

測試用IaaS系統(tǒng)規(guī)模為46個節(jié)點,均使用兆芯平臺雙路服務器構建。其中OpenStack節(jié)點40個,Ceph分布式存儲系統(tǒng)節(jié)點6個,詳見下表。

 

節(jié)點類型

節(jié)點配置

數(shù)量

管理節(jié)點

128G DDR4內(nèi)存+120G SSD+千兆網(wǎng)絡x2

3

網(wǎng)絡節(jié)點

128G DDR4內(nèi)存+120G SSD+千兆網(wǎng)絡x3

1

塊存儲節(jié)點

128G DDR4內(nèi)存+120G SSD+千兆網(wǎng)絡x2

1

對象存儲節(jié)點

128G DDR4內(nèi)存+120G SSD+4T HDDx3+千兆網(wǎng)絡x2

1

計算節(jié)點

128G DDR4內(nèi)存+120G SSD+千兆網(wǎng)絡x2

33

監(jiān)控節(jié)點

128G DDR4內(nèi)存+120G SSD+千兆網(wǎng)絡x2

1

Ceph Mon節(jié)點

128G DDR4內(nèi)存+120G SSD+萬兆網(wǎng)絡x2

3

Ceph OSD節(jié)點

128G DDR4內(nèi)存+250G SSD+500G SSDx3+2T HDDx12+萬兆網(wǎng)絡x4

3

Rally Server

Dell E3-1220v3服務器

1

 

2.軟件環(huán)境:

軟件

版本

備注

Host OS

CentOS7.6

安裝ZX Patch v3.0.9.4

Python

v2.7.5

 

Docker

v19.03.8

 

OpenStack

Sterin

基于容器部署

Mariadb

v10.3.10

多主Golare Cluster

SQLAlchemy

v0.12.0

python module

RabbitMQ

v3.8.14

搭配Erlang v22.3.4.21

Haproxy

v1.5.18

 

KeepAlived

v1.3.5

 

Ceph

v14.2.19

 

Rally

v2.0

并發(fā)測試工具

CosBench

v0.4.2

對象存儲性能測試工具

TestPerf

v2.16.0

消息隊列性能測試工具

 

3.存儲方案

各OpenStack節(jié)點的本地磁盤只做系統(tǒng)使用。提供給用戶的存儲資源統(tǒng)一使用Ceph作為后端。即nova、glance、cinder-volume和cinder-backup以及manila全部使用Ceph做后端存儲;谡仔酒脚_的Ceph集群部署和調(diào)優(yōu)方法請參見官網(wǎng)已發(fā)布的《基于兆芯平臺部署Ceph分布式存儲系統(tǒng)的最佳實踐》。

 

部署了Swift對象存儲服務,使用本地磁盤,但沒有配置給其他組件使用。其性能也不包含本文討論范圍之內(nèi)。

 

4.組網(wǎng)方案

根據(jù)兆芯平臺服務器板載網(wǎng)卡配置情況、計劃業(yè)務規(guī)模和現(xiàn)有網(wǎng)絡環(huán)境等條件,規(guī)劃集群網(wǎng)絡如下圖所示。將邏輯上的五類網(wǎng)絡收縮成三個物理網(wǎng)絡實施部署,即管理和Tunnel網(wǎng)絡公用一個物理網(wǎng)絡、部署和存儲網(wǎng)絡公用一個物理網(wǎng)絡以及外網(wǎng)。

 

- 部署網(wǎng)絡:用于PXE boot及安裝軟件時訪問本地軟件源鏡像;

- 管理網(wǎng)絡:用于各節(jié)點之間通過API訪問以及SSH訪問;

- Tunnel網(wǎng)絡:用于各計算節(jié)上虛擬機互通以及和網(wǎng)絡節(jié)點的連接,主要承載業(yè)務的東西流量;

- 存儲網(wǎng)絡:用于訪問統(tǒng)一存儲后端;

 

基于兆芯平臺的OpenStack云系統(tǒng)調(diào)優(yōu)指南

                                                    圖1 網(wǎng)絡拓撲

 

  二、調(diào)優(yōu)策略和手段

 

1.性能指標

由于本文主要涉及IaaS平臺性能,并不包含虛擬主機的性能,因此測試和調(diào)優(yōu)工作主要在針對OpenStack關鍵組件的性能測試。我們關注的性能指標有:單個請求的完成時間、批量請求的95%完成時間和批量請求的尾端延遲。

 

2.測試方法

獲得優(yōu)化參數(shù)的流程主要是測試、分析、調(diào)優(yōu)、再測試。

 

- 測試工具

對于OpenStack組件我們使用Rally來進行批量測試,可以使用Rally中包含的測試用例也可以根據(jù)需要自定義測試用例。Rally的測試報告中會有詳細的耗時統(tǒng)計。本測試批量請求的測試規(guī)模是200并發(fā),被測計算節(jié)點十個,使用的Guest OS是Cirros。

 

對于單個請求的測試還可以使用OSprofiler。Openstack中的請求多數(shù)都需要經(jīng)過多個組件處理才可以完成,該工具主要用途是協(xié)助分析請求的處理過程,在并發(fā)測試前找出可能的耗時點,從而提前優(yōu)化。

 

對于RabbitMQ我們采用了TestPerf工具,并設計了幾種典型用例來進行性能測試。重點關注消息隊列的吞吐量和消息投遞的延遲時間。

 

- 分析方法

主要從測試結果和日志入手,優(yōu)先解決日志中的告警和報錯事件,例如瞬時高并發(fā)請求導致的服務或數(shù)據(jù)庫連接超時、數(shù)據(jù)庫查詢失敗、資源不足等問題。

 

其次是基于對源代碼的理解通過添加時間戳獲取測試中的業(yè)務流或數(shù)據(jù)流關鍵節(jié)點的耗時數(shù)據(jù),再逐個分析高耗時點的耗時原因。

 

還有一種常用方法是在標準平臺上做對標測試。在問題收斂到一定程度后仍無法解釋性能問題的原因時或者性能問題的原因可能是和硬件架構或體系結構有關時,使用該方法來驗證。

 

- 優(yōu)化手段

對于OpenStack控制層面的優(yōu)化方向主要有三個:提高并發(fā)成功率、縮短平均完成時間和降低尾部延遲。

 

使用OpenStack默認配置做并發(fā)測試會發(fā)現(xiàn),根據(jù)具體的被測功能不同,200并發(fā)的成功率差別很大,通常被測功能涉及組件越多且并發(fā)數(shù)量越大成功率越低。提高成功率的方法主要靠提升硬件性能和調(diào)整各組件的配置參數(shù)。在兆芯平臺上,硬件性能的提升除了提高關鍵硬件(內(nèi)存和網(wǎng)卡)的性能外更重要的有兩點:一是服務器系統(tǒng)要打上兆芯BSP Patch;二是系統(tǒng)部署方案開發(fā)階段就要根據(jù)兆芯平臺的NUMA 拓撲結構來考慮合理的親和設置,盡量避免產(chǎn)生跨NUMA訪問,若無法避免跨NUMA訪問,則盡量使用相鄰的node,避免跨Socket訪問。而在組件配置上則需要根據(jù)對請求的處理路徑的跟蹤,找到耗時較長的功能。由于隨并發(fā)量增加經(jīng)常會導致組件處理的Retry和Timeout,這些會進一步導致產(chǎn)生請求失敗,在無法提升組件處理效率時應適當增加Retry次數(shù)或Timeout時間來避免請求直接失敗。

 

為縮短平均完成時間,除了前面已提到增加硬件平臺性能外,就要清楚的找到各種delay請求處理的具體階段。該情況下可使用各種trace手段來梳理控制流和數(shù)據(jù)流,通過分析日志等方法統(tǒng)計各處理階段的耗時。找到關鍵耗時功能后,可調(diào)優(yōu)的手段有:

 

1、修改組件配置,增加處理線程數(shù),充分利用多核性能;

2、組件性能依賴操作系統(tǒng)配置的,考慮調(diào)整系統(tǒng)配置來優(yōu)化,相關配置優(yōu)化方法請參考對應操作系統(tǒng)提供的調(diào)優(yōu)文檔以及兆芯官方提供的其他服務器產(chǎn)品相關調(diào)優(yōu)文檔;

3、組件對同一功能經(jīng)常可以提供多種方式,修改配置,使用更高效的方式;

4、從社區(qū)查找對請求處理性能有提高的Patch,有些處理效率低的原因是實現(xiàn)方式本身就效率低,通過Patch可能有效提高處理能力。如果沒有可用Patch,只能自行開發(fā)。

5、根據(jù)Python語言特性進行優(yōu)化,避免線程阻塞;

6、優(yōu)化組件部署方案,根據(jù)并發(fā)壓力適當增加組件數(shù)量或節(jié)點數(shù)量,也可通過組件遷移均衡各節(jié)點的負載壓力;

7、更新服務器OS 內(nèi)核功能Patch,提供高內(nèi)核處理能力;

8、對于通用軟件,如消息隊列,數(shù)據(jù)庫和負載均衡等,還可以選擇升級版本或選用性能更好的同類軟件來實現(xiàn)性能的提高。

 

本文后續(xù)章節(jié)中介紹的推薦參數(shù)均根據(jù)測試成績得出。

 

請注意,測試用例不同對各參數(shù)的值影響很大,比如測試200并發(fā)創(chuàng)建虛擬機時使用的虛擬機鏡像從Cirros改為Ubuntu,那么很可能很多地方的超時時間和Retry次數(shù)都需要增加才能保證成功率100%。因此,本文中推薦值不適用于生產(chǎn)環(huán)境,僅用作調(diào)優(yōu)參考。

 

  三、OpenStack關鍵組件配置

 

1. 數(shù)據(jù)庫

OpenStack系統(tǒng)中數(shù)據(jù)庫是十分關鍵的服務。各組件都在數(shù)據(jù)庫服務中有自己的數(shù)據(jù)庫,用于保存服務、資源和用戶等相關數(shù)據(jù)。數(shù)據(jù)庫還被用作各種組件間協(xié)同的一種機制。因此,在處理各種請求的過程中或多或少都會涉及到數(shù)據(jù)庫的讀寫操作。

 

在云平臺的性能調(diào)優(yōu)過程中需要重點觀測數(shù)據(jù)庫請求響應時間。對于運行時數(shù)據(jù)庫請求響應時間過長問題通常是比較復雜的,涉及數(shù)據(jù)庫服務器/cluster、代理服務器和客戶端(即組件端),需要一一排查,查找問題源頭并做對應調(diào)整。本節(jié)主要介紹服務器端和客戶端的相關配置參數(shù),代理服務器端參考后續(xù)章節(jié)。

 

1.1 Mariadb

 

測試用系統(tǒng)中以三個Mariadb節(jié)點構建了一個多主模式的Golare Cluster,前端通過haproxy實現(xiàn)主備高可用。數(shù)據(jù)庫的調(diào)優(yōu)方法可以參考《MySQL優(yōu)化手冊》,補充一個在OpenStack云系統(tǒng)中需要特別注意的參數(shù)。

 

- max_allowed_packet

該參數(shù)用于設置MariaDB 服務器端允許接收的最大數(shù)據(jù)包大小。有時候大的插入和更新操作會因max_allowed_packet 參數(shù)設置過小導致失敗。

 

- 推薦配置:

默認值1024,單位Kbyte。在Open Stack的集群中,有超出默認值大小的包,需要適當增加大小。

修改mariadb的配置文件galera.cnf

[mysqld]

max_allowed_packet = 64M

重啟mariadb服務生效。

 

1.2 oslo_db

各組件訪問數(shù)據(jù)庫是通過調(diào)用oslo_db來實現(xiàn)的,實際部署中我們配置oslo_db+SQLAlchemy作為數(shù)據(jù)庫訪問的客戶端,因此,數(shù)據(jù)庫客戶端的相關配置參數(shù)和調(diào)優(yōu)手段可以參考SQLAlchemy的官方文檔。注意,SQLAlchemy的高版本會帶來性能提升,但不可隨意升級,需要考慮版本兼容。

 

- slave_connection

Stein版oslo_db支持配置slave_connection,并且已經(jīng)有部分組件支持按讀寫分離方式訪問數(shù)據(jù)庫,例如nova,即寫數(shù)據(jù)庫操作使用connection,讀數(shù)據(jù)庫操作使用slave_connection操作。從而改善讀操作的性能。

 

參考配置方法:

1、通過haproxy來為讀寫操作提供不同的轉(zhuǎn)發(fā)入口,如寫操作使用3306,轉(zhuǎn)發(fā)模式配置為一主兩備;讀操作使用3307,轉(zhuǎn)發(fā)方式配置為按最小連接數(shù)。

2、為支持讀寫分離的組件在其配置文件的【database】段中增加slave_connection配置。

 

注意:有些組件雖然可以配置slave_connection但其代碼事件中實際上并沒有在讀數(shù)據(jù)庫時調(diào)用slave_connection,需根據(jù)具體版本仔細確認。

 

- 連接池

和數(shù)據(jù)庫建立連接是一個相對耗時的過程,因此,提供了連接池機制,連接池中的連接可以被重復使用,以提高效率。用戶在調(diào)試過程中應關注各組件和數(shù)據(jù)庫之間的連接情況,如組件的數(shù)據(jù)庫請求響應時間和組件日志中數(shù)據(jù)庫連接相關信息等。若發(fā)現(xiàn)數(shù)據(jù)庫請求響應時間過長且經(jīng)排查后懷疑是組件端在連接數(shù)據(jù)庫上耗時過長時,可通過以下參數(shù)嘗試優(yōu)化。在本文所述測試過程中使用了默認參數(shù)設置,用戶需根據(jù)運行時情況進行調(diào)優(yōu)。連接池主要配置參數(shù)如下:

 

    min_pool_size :連接池中已連接的SQL連接數(shù)不得小于該值,默認值是1。

    max_pool_size :連接池中已連接的最大SQL連接數(shù),默認值是5,設置0時無限制。

    max_overflow :最大允許超出最大連接數(shù)的數(shù)量,默認值是50。

    pool_timeout :從連接池里獲取連接時如果無空閑的連接,且連接數(shù)已經(jīng)到達了max_pool_size+max_overflow,那么要獲取連接的進程會等待pool_timeout秒,默認值是30s,如果超過這個時間還沒有得到連接將會拋出異常。如果出現(xiàn)該異常,可以考慮增加連接池的連接數(shù)。

 

2. 消息隊列

 

2.1 Rabbitmq

測試用系統(tǒng)中以三節(jié)點構建了一個RabbitMQ Mirror Queue Cluster,所有節(jié)點均為disk節(jié)點。

 

RabbitMQ的主要性能問題是消息投遞的延遲時間,但對于cluster的組織方式,其延遲時間主要消耗在鏡像隊列之間的數(shù)據(jù)一致性保證處理上,而這種處理過程十分復雜,調(diào)優(yōu)難度很大。對于Cluster目前的調(diào)優(yōu)手段有如下幾種:

1、由于Rabbitmq基于erlang運行,而通過對比測試,高低版本性能差異較大,建議盡量使用高版本,如Rabbitmq使用3.8以上版本,erlang版本v22.3及以上(根據(jù)Rabbitmq版本具體選擇)。

2、由于Cluster的隊列鏡像數(shù)量越多,每條消息處理時在一致性上的耗時越長,因此可以根據(jù)實際情況減少鏡像隊列數(shù)量。

3、若Rabbitmq是容器化安裝,為避免CPU資源被搶占,可配置docker參數(shù),分配給Rabbitmq更多的CPU時間。

 

推薦的調(diào)優(yōu)參數(shù)如下:

 

- collect_statistics_interval

默認情況下,Rabbitmq Server默認以5s的間隔統(tǒng)計系統(tǒng)信息,周期內(nèi)publish、 delivery message等速率信息會以此為周期統(tǒng)計。

 

- 推薦配置

增加該值能夠減少Rabbitmq Server 收集大量的狀態(tài)信息而導致CPU利用率增加,參數(shù)單位為ms。

編輯RabbitMQ的配置文件rabbitmq.conf

collect_statistics_interval = 30000

重啟RabbitMQ服務生效。

 

- cpu_share

Docker 允許用戶為每個容器設置一個數(shù)字,代表容器的 CPU share,默認情況下每個容器的 share 是 1024。要注意,這個 share 是相對的,本身并不能代表任何確定的意義。當主機上有多個容器運行時,每個容器占用的 CPU 時間比例為它的 share 在總額中的比例。只有在CPU資源緊張時,設定的資源比例才可以顯現(xiàn)出來,如果CPU資源空閑,cpu_share值低的docker也能獲取到比例外的CPU資源。

 

- 推薦配置

控制節(jié)點上部署openstack 各組件的api server以及rabbitmq server,當對rabbitmq做并發(fā)測試時,可以適當提高節(jié)點上rabbitmq docker的CPU share讓其獲得更多的CPU資源。如果條件滿足的情況下,Rabbitmq Cluster 應該單獨部署在服務器集群上,不和其他服務搶占CPU資源。單獨部署的Rabbitmq Cluster有更高的并發(fā)能力。

 

配置方法:

docker update --cpu-shares 10240 rabbitmq-server

 

- ha-mode

Rabbitmq Cluster鏡像隊列可以配置鏡像隊列在多節(jié)點備份,每個隊列包含一個master節(jié)點和多個slave節(jié)點。消費者消費的操作現(xiàn)在master節(jié)點上完成,之后再slave上進行相同的操作。生產(chǎn)者發(fā)布的消息會同步到所有的節(jié)點。其他的操作通過master中轉(zhuǎn),master將操作作用于slave。鏡像隊列的配置策略:

ha-mode

ha-params

說明

all

 

集群中每個節(jié)點都有鏡像隊列

exactly

count

指定集群中鏡像隊列的個數(shù)

nodes

node names

在指定的節(jié)點列表中配置鏡像隊列

默認的ha-mode是all,三節(jié)點的集群鏡像隊列在3節(jié)點備份。定義策略的指令:

    rabbimqctl set_policy –p vhost

    pattern:正則匹配,定義的policy會根據(jù)正則表達式應用到相應的交換機或者隊列上。

    definition:配置策略的參數(shù)。

 

- 推薦配置

rabbitmqctl set_policy -p / ha-exactly '^' '{'ha-mode':'exactly', 'ha-params':2}'

集群兩隊列備份比三隊列備份應對高并發(fā)的能力更強,前者支持的并發(fā)數(shù)是后者的1.75倍。

 

- CPU綁定

RabbitMQ 運行在erlang 虛擬機中。本文環(huán)境之中使用的erlang版本支持SMP,采用多調(diào)度器多隊列的機制,即啟動erlang虛擬機時,默認會根據(jù)系統(tǒng)邏輯CPU核數(shù)啟動相同數(shù)量的調(diào)度器(可通過啟動參數(shù)+S限制),每個調(diào)度器都會從各自的運行隊列中獲取運行進程。但由于OS的線程調(diào)度機制,erlang調(diào)度器線程會在各核之間遷移,這會導致Cache Miss增加,影響性能?梢酝ㄟ^參數(shù)+sbt 來設置調(diào)度器和邏輯核綁定。Erlang支持多種綁定策略,詳見Erlang說明文檔。

 

- 推薦配置

默認配置為db,按numa node輪流綁定,盡量使用到所有node。但由于調(diào)度器多任務隊列之間存在balance機制,任務會在隊列間遷移,因此,為了更好的利用cache,在本文測試環(huán)境下上推薦將+stb 配置為nnts,即調(diào)度器線程按numa node順序進行綁定。

 

編輯RabbitMQ的配置文件rabbitmq-env.conf

RABBITMQ_SERVER_ADDITIONAL_ERL_ARGS='+sbt nnts'

重啟RabbitMQ 服務生效。

 

用戶還可根據(jù)實際環(huán)境采取其他Erlang虛擬機調(diào)優(yōu)方法配合使用(如啟用Hipe等),但具體Erlang虛擬機的參數(shù)介紹和調(diào)優(yōu)手段不在本文討論范圍。

 

- 心跳保持

Hearbeat用來檢測通信的對端是否保活;驹硎菣z測對應的socket鏈接上數(shù)據(jù)的收發(fā)是否正常,如果有一段時間沒有收發(fā)數(shù)據(jù),則向?qū)Χ税l(fā)送一個心跳檢測包,如果一段時間內(nèi)沒有回應則認為心跳超時對端可能異常crash。在負載重時組件可能無法及時處理heartbeat消息而導致Rabbitmq Server沒有在超時時間內(nèi)收到心跳檢測應答。Rabbitmq Server因組件超時未應答而關閉連接導致錯誤。適當增加組件和Rabbitmq Server的心跳超時時間以避免該錯誤。參考Cinder章節(jié)中相關介紹。

 

編輯RabbitMQ的配置文件rabbitmq.conf

heartbeat = 180

重啟RabbitMQ服務生效。

 

2.2 oslo_messaging

 

各功能組件和Rabbitmq的連接都是調(diào)用oslo_messaging來實現(xiàn)的,該庫中提供的如下幾個參數(shù)可用于優(yōu)化高負載時RPC處理性能。

 

    rpc_conn_pool_size :RPC連接池的大小,默認值是30。

    executor_thread_pool_size :執(zhí)行RPC處理的線程或協(xié)程數(shù)量,默認值是64。

    rpc_response_timeout :RPC調(diào)用響應超時時間,默認值是60s。

 

我們的測試中前兩個參數(shù)使用了默認值,rpc_response_timeout根據(jù)各組件的實際處理能力做了適當增加。

 

3. Nova

 

3.1 nova-api

 

- Workers

nova-api是一個WSGI Server,亦可叫api server,其負責接收外部發(fā)來的REST請求。API Server啟動時會根據(jù)配置文件建立一定數(shù)量的worker線程來接收請求,如果線程數(shù)量不足以滿足并發(fā)量,就會出現(xiàn)排隊,導致請求處理時間增加。因此,管理員可以根據(jù)實際的業(yè)務量來設置worker數(shù)量。對于獨占一個節(jié)點的api server,workers通?梢栽O置到等同于CPU核數(shù),但在多個api server同部署于一個節(jié)點時(如在控制節(jié)點上),物理CPU資源有限,就需要根據(jù)服務器處理能力和各api server的負載情況調(diào)整各自的workers數(shù)量。

 

對于容器方式部署的api server,還可以考慮配置容器使用的CPU和內(nèi)存資源的numa親和,盡量做到各容器的NUMA親和分開,從而減少CPU資源搶占以及更好的利用cache資源。該方法對其他以容器方式部署的服務也同樣適用。

 

在nova-api的配置文件中有幾個配置項,如:osapi_compute_workers和metadata_workers,可以根據(jù)節(jié)點服務器能力和負載情況進行調(diào)整。

 

其他組件,如glance等都有自己的api server,與nova-api類似,可以通過增加workers數(shù)量來改善請求處理性能。

 

- Patch:熱遷移性能

Nova Compute在執(zhí)行l(wèi)ive-migrate()時,子線程執(zhí)行_live_migration_operation()函數(shù)和主線程執(zhí)行_live_migration_monitor()函數(shù)都會訪問Instance Fields。如果此前未曾訪問過Instance.fields,則可能同時調(diào)用nova/objects/instance.py:class Instance. obj_load_attr()函數(shù),utils.temporary_mutation()函數(shù)的重入會導致執(zhí)行后Context.read_deleted賦值為“yes”。后續(xù)在_update_usage_from_instances()時會統(tǒng)計不必要統(tǒng)計的已經(jīng)刪除的instances,增加耗時。 Stein版本的OpenStack存在上述漏洞,后續(xù)的版本由于其他操作提前獲取過Intance.fields,從而nova-compute不需要在live-migrate時調(diào)用obj_load_attr()。Bug提交信息見鏈接:https://bugs.launchpad.net/nova/+bug/1941819?梢酝ㄟ^補丁https://github.com/openstack/nova/commit/84db8b3f3d202a234221ed265ec00a7cf32999c9 在Nova API中提前獲取Instance.fileds以避免該Bug。

 

補丁詳情參見附件A1.1

 

3.2  Nova-scheduler & nova-conductor

 

這兩個服務同樣也有workers配置參數(shù)來控制處理線程的數(shù)量,可以根據(jù)實際業(yè)務量來調(diào)整,我們的測試中設置為默認值即可滿足。Nova-conductor的workers默認值是CPU核數(shù)。Nova-scheduler的默認值是當使用filter-scheduler時是CPU核數(shù),使用其他Scheduler時默認值是1。

 

3.3 nova-computer

 

- vcpu_pin_set

限定Guest可以使用compute node上的pCPUs的范圍,給Host適當留下一些CPU以保證正常運作。解決因虛擬機高負載情況下爭搶CPU資源導致Host性能不足的問題。

 

- 推薦配置

在每個numa node上都預留一個物理CPU核供Host使用。以兩numa nodes 平臺為例,可選擇預留cpu0和cpu15供Host使用,配置方法如下:

編輯nova-compute的配置文件nova.conf

vcpu_pin_set = 1-14

重啟nova_compute服務生效。

 

- reserved_host_memory_mb

該參數(shù)用于在計算節(jié)點上預留內(nèi)存給Host系統(tǒng)使用,避免虛擬主機占用掉過多內(nèi)存,導致Host系統(tǒng)上的任務無法正常運行。

 

- 推薦配置

設置值須根據(jù)實際內(nèi)存總量、Host系統(tǒng)中運行的tasks以及預期虛擬機會占用的最大內(nèi)存量來決定,建議至少預留1024MB供系統(tǒng)使用。

編輯nova-compute的配置文件nova.conf

reserved_host_memory_mb=4096  #單位MB

重啟nova_compute服務生效。

 

- cpu_allocation_ratio

配置vCPU的可超配比例。

 

- 推薦配置

根據(jù)ZHAOXIN CPU的性能,桌面云系統(tǒng)中,單個pCPU可以虛擬2個vCPU。

編輯nova-compute的配置文件nova.conf

[DEFAULT]

cpu_allocation_ratio = 2

重啟nova_compute服務生效。

 

- block_device_allocate_retries

創(chuàng)建有block device的虛擬機時,需要從blank、image或者snaphot創(chuàng)建volume。在volume被attach到虛擬機之前,其狀態(tài)必須是“available”。block_device_allocate_retries指定nova檢查volume狀態(tài)是否“available”的次數(shù)。相關參數(shù)有block_device_allocate_retries_interval,指定檢查狀態(tài)的查詢間隔,默認值3,單位s。

 

- 推薦配置

默認值是60次。當cinder負載較重時,60次查詢之后可能volume的狀態(tài)不是“available”,適當增加查詢次數(shù),避免虛擬機創(chuàng)建失敗。

 

編輯nova-compute的配置文件nova.conf

[DEFAULT]

block_device_allocate_retries = 150

重啟nova_compute服務生效。

 

- vif_plugging_timeout

nova-compute等待Neutron VIF plugging event message arrival的超時時間。

 

- 推薦配置

默認值300,單位s。當創(chuàng)建虛擬機并發(fā)數(shù)高時,可能無法在300s內(nèi)收到該event。兆芯桌面云系統(tǒng)測試200并發(fā)創(chuàng)建虛擬機時,耗時約360s,該值可以根據(jù)系統(tǒng)的最大并發(fā)數(shù)適當調(diào)整。

 

編輯nova-compute的配置文件nova.conf

[DEFAULT]

vif_plugging_timeout = 500

重啟nova_compute服務生效。

 

- Patch:熱遷移性能

該補丁完成了兩個功能:去掉遷移過程中不必要的get_volume_connect() 函數(shù)調(diào)用,以及減少不要的Neutron訪問。該補丁能夠讓熱遷移更高效,熱遷移的無服務時間更短。補丁地址:

https://review.opendev.org/c/openstack/nova/+/795027

https://opendev.org/openstack/nova/commit/6488a5dfb293831a448596e2084f484dd0bfa916

補丁詳情參見附件A1.2

 

4. Cinder

 

4.1 cinder-api

 

- Workers

參見nova-api。不同的是Stein版中cinder-api采用httpd部署,因此,其除了可以調(diào)優(yōu)cinder支持的各種workers(如osapi_volume_workers),還可以調(diào)優(yōu)cinder-wsgi.conf中的processes和threads。類似的組件還有keystone和horizon等。

 

編輯cinder-wsgi.conf

WSGIDaemonProcess cinder-api processes=12 threads=3 user=cinder group=cinder display-name=%{GROUP} python-path=/var/lib/kolla/venv/lib/python2.7/site-packages

……

 

重啟cinder-api服務生效。

 

- rpc_response_timeout

 

Cinder-api等待RPC消息返回的超時時間

 

- 推薦配置

默認值 60,單位s。在高并發(fā)的attach_volume時,cinder-volume響應cinder-api的時間較長。如果報告rpc timeout的錯誤,可以適當調(diào)大該值。

 

編輯cinder-volume的配置文件cinder.conf

[DEFAULT]

rpc_response_timeout = 600

重啟cinder-api服務生效。

 

4.2 cinder-volume

 

- 心跳保持

和Rabbitmq之間

參考RabbitMQ章中的“心跳保持”小節(jié)。

 

Cinder的heartbeat_timeout_threshold用來設置心跳超時時間,會以1/2心跳超時時間為間隔發(fā)送心跳檢測信號。

 

- 推薦配置

cinder-volume heartbeat_timeout_threshold默認值為60,單位為s,在負載重時可能無法在及時處理heartbeat消息而導致Rabbitmq Server沒有在超時時間內(nèi)收到心跳檢測應答。Rabbitmq Server因Cinder-volume超時未應答而關閉連接,進而導致一系列錯誤。適當增加Cinder-volume和Rabbitmq Server的心跳超時時間以避免該錯誤,不建議禁用心跳檢測機制(heartbeat=0)。

 

編輯cinder-volume的配置文件cinder.conf

[oslo_messaging_rabbit]

heartbeat_timeout_threshold = 180

重啟cinder-volume服務生效。

 

服務之間

OpenStack是一個分布式系統(tǒng),由運行在不同主機上的各個服務組成來共同完成各項工作。每個服務都會定時向數(shù)據(jù)庫中更新自己的update time,服務間可通過查詢對方的update time是否超過設置的service_down_time來判斷服務是否在線。這也可以看作是一種心跳機制。

 

在高負載時,數(shù)據(jù)庫訪問可能延遲增加,同時運行上報的周期任務會因CPU資源被占用導致延遲上報,這些都有可能引發(fā)誤報service down。

 

- 推薦配置

report_interval:狀態(tài)報告間隔,即心跳間隔,默認10,單位s。

service_down_time:距離上一次心跳的最長時間,默認60,單位s。超過這個時間沒有心跳則認為服務Down。

report-interval一定要小于service_down_time。適當增加service_down_time,避免cinder-volume的周期性任務占用cpu導致沒有及時報告狀態(tài)而被誤認為Down。

編輯cinder-volume的配置文件cinder.conf

service_down_time = 120

重啟cinder_volume服務生效。

 

- rbd_exclusive_cinder_pool

 

OpenStack Ocata引入了參數(shù)rbd_exclusive_cinder_pool,如果RBD pool是Cinder獨占,則可以設置rbd_exclusive_cinder_pool=true。Cinder用查詢數(shù)據(jù)庫的方式代替輪詢后端所有volumes的方式獲取provisioned size,這會明顯減少查詢時間,同時減輕Ceph 集群和Cinder-volume 服務的負載。

 

- 推薦配置

編輯cinder-volume的配置文件cinder.conf

[DEFAULT]

Enable_backends =rbd-1

[rbd-1]

rbd_exclusive_cinder_pool = true

重啟cinder-volume服務生效。

 

- image_volume_cache_enabled

 

從Liberty版本開始,Cinder能夠使用image volume cahe,能夠提高從image創(chuàng)建volume的性能。從image第一次創(chuàng)建volume的同時會創(chuàng)建屬于快存儲Internal Tenant的cached image-volume 。后續(xù)從該image創(chuàng)建volume時從cached image-volume 克隆,不需要將image 下載到本地再傳入volume。

 

- 推薦配置

cinder_internal_tenant_project_id:指定OpenStack的項目“service”的ID

cinder_internal_tenant_user_id:指定OpenStack的用戶“cinder”的ID

image_volume_cache_max_size_gb:指定cached image-volume的最大size,設置為0,即不對其限制。

image_volume_cache_max_count:指定cached image-volume的最大數(shù)量,設置為0,即不對其限制。

編輯cinder-volume的配置文件cinder.conf

[DEFAULT]

cinder_internal_tenant_project_id = c4076a45bcac411bacf20eb4fecb50e0 

cinder_internal_tenant_user_id = 4fe8e33010fd4263be493c1c9681bec8 

[backend_defaults]

image_volume_cache_enabled=True

image_volume_cache_max_size_gb = 0

image_volume_cache_max_count = 0

重啟cinder-volume服務生效。

 

5. Neutron

 

5.1 Neutron Service

 

neutron-service是neutron組件的api server,其配置優(yōu)化參考nova-api中的介紹,可調(diào)整參數(shù)有api_workers和metadata_workers。

 

- rpc_workers

在neutron的設計架構上,核心服務和各plugin的處理是先主進程fork子進程,再在子進程中創(chuàng)建協(xié)程來運行處理程序,從而實現(xiàn)可利用到多核的并發(fā)處理。rpc_workers是用來控制為RPC處理創(chuàng)建的進程數(shù)量,默認值是api_workers的一半。由于我們的系統(tǒng)是基于容器部署,因此該值使用默認值即可。

 

5.2 Neutron DHCP Agent

 

這里的兩個補丁主要影響網(wǎng)絡節(jié)點上的neutron服務。

 

- 改善Network Port管理效率

 

Patch1

Neutron DHCP agent中用Pyroute2 的“ip route”命令替換oslo.rootwrap庫中該linux命令。該補丁讓Neutron DHCP agent創(chuàng)建和刪除port時更加高效。補丁地址:

https://opendev.org/openstack/neutron/commit/06997136097152ea67611ec56b345e5867184df5

補丁詳情參見附件A1.3。

 

Patch2

Neutron DHCP agent中用oslo.privsep庫的“dhcp_release”命令替換oslo.rootwrap庫該linux 命令。該補丁讓Neutron DHCP agent創(chuàng)建和刪除port時更加高效。補丁地址:

https://opendev.org/openstack/neutron/commit/e332054d63cfc6a2f8f65b1b9de192ae0df9ebb3

https://opendev.org/openstack/neutron/commit/2864957ca53a346418f89cc945bba5cdcf204799

補丁詳情參見附件A1.4。

 

5.3 Neuton OpenvSwitch Agent

 

- 改善Network Port處理效率

 

polling_interval

Neutron L2 Agent如果配置的是openvswitch agent,neutron-openvswitch-agent啟動后會運行一個RPC循環(huán)任務來處理端口添加、刪除、修改。通過配置項polling_interval指定RPC循環(huán)執(zhí)行的間隔。

 

- 推薦配置

默認值是2,單位s。減少該值可以使得端口狀態(tài)更新更快,特別是熱遷移過程中,減少該值可以減少遷移時間。但如果設置為0會導致neutron-openvswitch-agent占用過多的CPU資源。

編輯neutron-openvswitch-agent的配置文件ml2_conf.ini

[agent]

polling_interval = 1

重啟計算節(jié)點的neutron-openvswitch-agent服務生效。

 

Patch

Neutron openvswitch agent中用oslo.privsep庫替換oslo.rootwrap庫的“iptables”和“ipset”命令。該補丁能讓Neutron openvswitch agent處理network port時更加高效。補丁地址:

https://opendev.org/openstack/neutron/commit/6c75316ca0a7ee2f6513bb6bc0797678ef419d24

https://opendev.org/openstack/neutron/commit/5a419cbc84e26b4a3b1d0dbe5166c1ab83cc825b

補丁詳情參見附件A1.5。

 

5.4 熱遷移Down Time時間優(yōu)化

 

openstack stein版本在熱遷移的測試中,虛機遷移到目標主機后,網(wǎng)絡不能及時ping通,存在比較明顯的延時現(xiàn)象。原因是虛機遷移成功后會立刻發(fā)送RARP廣播,而此時虛機網(wǎng)卡對應的port還沒真正up。Bug信息:

https://bugs.launchpad.net/neutron/+bug/1901707

https://bugs.launchpad.net/neutron/+bug/1815989

補丁詳情參見附錄B1.1--B1.7, 涉及neutron和nova模塊:

https://review.opendev.org/c/openstack/neutron/+/790702

https://review.opendev.org/c/openstack/nova/+/767368

 

5.5 網(wǎng)絡性能優(yōu)化

 

網(wǎng)絡為了獲得穩(wěn)定的高性能,在部署虛機時,網(wǎng)卡硬中斷和對應虛機,最好限定在位于同一Cluster的CPU上,這樣可以避免不必要的cache miss,進而提升網(wǎng)絡的穩(wěn)定性和性能。

 

5.6 VXLAN 性能優(yōu)化

 

主流隧道網(wǎng)絡普遍基于UDP協(xié)議實現(xiàn),例如VXLAN,當UDP校驗和字段為零時,會導致接收端在處理VXLAN報文時不能及時進行GRO(generic receive offload)處理,進而嚴重影響網(wǎng)絡性能。該問題社區(qū)已經(jīng)修正,具體信息可以參見下面鏈接:

https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net.git/commit/?id=89e5c58fc1e2857ccdaae506fb8bc5fed57ee063

打上該補丁后,萬兆網(wǎng)卡情況下,同樣的VXLAN iperf3測試,成績可以提升2倍以上。

補丁詳情參見附錄C1.1

 

6. Keystone

 

- 并發(fā)進程數(shù)

WSGIDaemonProcess守護進程的配置參數(shù)。Processes定義了守護進程啟動的進程數(shù)。

 

- 推薦配置

默認值為1。當keystone壓力較大時,1個WSGI進程無法處理較大的并發(fā)數(shù),適當增加processes的值,大于CPU cores number的意義不大。

編輯keystone的配置文件wsgi-keystone.conf

WSGIDaemonProcess keystone-public processes=12 threads=1 user=keystone group=keystone display-name=%{GROUP} python-path=/var/lib/kolla/venv/lib/python2.7/site-packages

……

 

WSGIDaemonProcess keystone-admin processes=12 threads=1 user=keystone group=keystone display-name=%{GROUP} python-path=/var/lib/kolla/venv/lib/python2.7/site-packages

……

 

重啟keystone服務生效。

 

7. Haproxy

 

- Timeout設置

1、timeout http-request:HTTP請求的最大超時時間

2、timeout queue:當server端請求數(shù)量達到了maxconn,新到的connections會被添加到指定的queue。當requests在queue上等待超過timeout queue時,request被認為不被服務而丟棄,返回503 error給client端。

3、timeout connect :connection連接上后端服務器的超時時間。

4、timeout client :client端發(fā)送數(shù)據(jù)或者應答時,客戶端最大的非活躍時間

5、timeout server:server端最大的非活躍時間

 

- 推薦配置

編輯haproxy的配置文件haproxy.cfg,單位s表示秒,單位m表示分。

defaults

timeout http-request 100s

timeout queue 4m

timeout connect 100s

timeout client 10m

timeout server 10m。

重啟haproxy服務生效。

 

- 最大連接數(shù)

Haproxy可以配置全局的maxconn定義Haproxy同時最大的連接數(shù),也可以為后端服務配置maxconn定義該服務的最大連接數(shù),可以為前端配置maxconn定義此端口的最大連接數(shù)。系統(tǒng)的ulimit -n的值一定要大于maxconn。

 

- 推薦配置

全局的maxconn默認值為4000,應用過程中在Haproxy的控制臺觀察到全局連接數(shù)不夠,將其增加到40000。

編輯Haproxy的配置文件haproxy.cfg

global

maxconn 40000

重啟haproxy服務生效。

 

- 處理線程數(shù)

設置haproxy的負責均衡并發(fā)進程數(shù),OpenStack Stein的Haproxy 版本為1.5.18。該參數(shù)在haproxy 2.5 版本中已移除,由nbthread參數(shù)指定線程數(shù)量。

 

- 推薦配置

由于Haproxy的負載較重,推薦適當增大該參數(shù)。

編輯Haproxy的配置文件haproxy.cfg

global

nbproc 4

重啟haproxy服務生效。

 

- 權重

Haproxy后端配置參數(shù)weight可以配置server的權重,取值范圍0-256,權重越大,分給這個server的請求就越多。weight為0的server將不會被分配任何新的連接。所有server的默認值為1。

 

- 推薦配置

當多個后端的主機壓力不一致時,可以將壓力大的主機上的server的權重適當減少,從而使各主機負載均衡。

 

以3 控制節(jié)點的小集群為例:測試過程中,controller03上整體cpu使用率較高達95%+,其他兩個控制節(jié)點cpu使用率約在70%,各個控制節(jié)點keystone的 cpu使用率均較高。減少controller03上keystone server的權重,從而減少controller03的cpu壓力。

 

編輯Haproxy的配置文件keystone.cfg

listen keystone_external

    mode http

    http-request del-header X-Forwarded-Proto

    option httplog

    option forwardfor

    http-request set-header X-Forwarded-Proto https if { ssl_fc }

    bind haproxy-ip-addr:5000

    maxconn 5000

    server controller01 server-ip-addr:5000 check inter 2000 rise 2 fall 5 maxconn 3000 weight 10

    server controller02 server-ip-addr:5000 check inter 2000 rise 2 fall 5 maxconn 3000 weight 10

    server controller03 server-ip-addr:5000 check inter 2000 rise 2 fall 5 maxconn 3000 weight 9

重啟haproxy服務生效。

~~~~~~~~~~~~~~~~~~

附錄

A1.1

diff -ruN nova-bak/api/openstack/compute/migrate_server.py nova/api/openstack/compute/migrate_server.py

--- nova-bak/api/openstack/compute/migrate_server.py    2021-09-10 11:20:15.774990677 +0800

+++ nova/api/openstack/compute/migrate_server.py 2021-09-10 11:23:22.239098421 +0800

@@ -157,7 +157,9 @@

                               'conductor during pre-live-migration checks '

                               ''%(ex)s'', {'ex': ex})

             else:

-                raise exc.HTTPBadRequest(explanation=ex.format_message())

+               raise exc.HTTPBadRequest(explanation=ex.format_message())

+        except exception.OperationNotSupportedForSEV as e:

+            raise exc.HTTPConflict(explanation=e.format_message())

         except exception.InstanceIsLocked as e:

             raise exc.HTTPConflict(explanation=e.format_message())

         except exception.ComputeHostNotFound as e:

diff -ruN nova-bak/api/openstack/compute/suspend_server.py nova/api/openstack/compute/suspend_server.py

--- nova-bak/api/openstack/compute/suspend_server.py   2021-09-10 11:25:03.847439106 +0800

+++ nova/api/openstack/compute/suspend_server.py 2021-09-10 11:27:09.958950964 +0800

@@ -40,7 +40,8 @@

             self.compute_api.suspend(context, server)

         except exception.InstanceUnknownCell as e:

             raise exc.HTTPNotFound(explanation=e.format_message())

-        except exception.InstanceIsLocked as e:

+        except (exception.OperationNotSupportedForSEV,

+                exception.InstanceIsLocked) as e:

             raise exc.HTTPConflict(explanation=e.format_message())

         except exception.InstanceInvalidState as state_error:

             common.raise_http_conflict_for_instance_invalid_state(state_error,

diff -ruN nova-bak/compute/api.py nova/compute/api.py

--- nova-bak/compute/api.py   2021-09-10 11:31:55.278077457 +0800

+++ nova/compute/api.py 2021-09-10 15:32:28.131175652 +0800

@@ -215,6 +215,23 @@

         return fn(self, context, instance, *args, **kwargs)

     return _wrapped

 

+def reject_sev_instances(operation):

+    '''Decorator.  Raise OperationNotSupportedForSEV if instance has SEV

+    enabled.

+    '''

+

+    def outer(f):

+        @six.wraps(f)

+        def inner(self, context, instance, *args, **kw):

+            if hardware.get_mem_encryption_constraint(instance.flavor,

+                                                      instance.image_meta):

+                raise exception.OperationNotSupportedForSEV(

+                    instance_uuid=instance.uuid,

+                    operation=operation)

+            return f(self, context, instance, *args, **kw)

+        return inner

+    return outer

+

 

 def _diff_dict(orig, new):

     '''Return a dict describing how to change orig to new.  The keys

@@ -690,6 +707,9 @@

         '''

         image_meta = _get_image_meta_obj(image)

 

+        API._validate_flavor_image_mem_encryption(instance_type, image_meta)

+     

+

         # Only validate values of flavor/image so the return results of

         # following 'get' functions are not used.

         hardware.get_number_of_serial_ports(instance_type, image_meta)

@@ -701,6 +721,19 @@

         if validate_pci:

             pci_request.get_pci_requests_from_flavor(instance_type)

 

+    @staticmethod

+    def _validate_flavor_image_mem_encryption(instance_type, image):

+        '''Validate that the flavor and image don't make contradictory

+        requests regarding memory encryption.

+        :param instance_type: Flavor object

+        :param image: an ImageMeta object

+        :raises: nova.exception.FlavorImageConflict

+        '''

+        # This library function will raise the exception for us if

+        # necessary; if not, we can ignore the result returned.

+        hardware.get_mem_encryption_constraint(instance_type, image)

+

+

     def _get_image_defined_bdms(self, instance_type, image_meta,

                                 root_device_name):

         image_properties = image_meta.get('properties', {})

@@ -3915,6 +3948,7 @@

         return self.compute_rpcapi.get_instance_diagnostics(context,

                                                             instance=instance)

 

+    @reject_sev_instances(instance_actions.SUSPEND)

     @check_instance_lock

     @check_instance_cell

     @check_instance_state(vm_state=[vm_states.ACTIVE])

@@ -4699,6 +4733,7 @@

                                                      diff=diff)

         return _metadata

 

+    @reject_sev_instances(instance_actions.SUSPEND)

     @check_instance_lock

     @check_instance_cell

     @check_instance_state(vm_state=[vm_states.ACTIVE, vm_states.PAUSED])

diff -ruN nova-bak/exception.py nova/exception.py

--- nova-bak/exception.py        2021-09-10 11:35:25.491284738 +0800

+++ nova/exception.py     2021-09-10 11:36:09.799787563 +0800

@@ -536,6 +536,10 @@

     msg_fmt = _('Unable to migrate instance (%(instance_id)s) '

                 'to current host (%(host)s).')

 

+class OperationNotSupportedForSEV(NovaException):

+    msg_fmt = _('Operation '%(operation)s' not supported for SEV-enabled '

+                'instance (%(instance_uuid)s).')

+    code = 409

 

 class InvalidHypervisorType(Invalid):

     msg_fmt = _('The supplied hypervisor type of is invalid.')

diff -ruN nova-bak/objects/image_meta.py nova/objects/image_meta.py

--- nova-bak/objects/image_meta.py 2021-09-10 15:16:30.530628464 +0800

+++ nova/objects/image_meta.py      2021-09-10 15:19:26.999151245 +0800

@@ -177,6 +177,9 @@

         super(ImageMetaProps, self).obj_make_compatible(primitive,

                                                         target_version)

         target_version = versionutils.convert_version_to_tuple(target_version)

+       

+        if target_version < (1, 24):

+            primitive.pop('hw_mem_encryption', None)

         if target_version < (1, 21):

             primitive.pop('hw_time_hpet', None)

         if target_version < (1, 20):

@@ -298,6 +301,11 @@

         # is not practical to enumerate them all. So we use a free

         # form string

         'hw_machine_type': fields.StringField(),

+       

+        # boolean indicating that the guest needs to be booted with

+        # encrypted memory

+        'hw_mem_encryption': fields.FlexibleBooleanField(),

+

 

         # One of the magic strings 'small', 'any', 'large'

         # or an explicit page size in KB (eg 4, 2048, ...)

diff -ruN nova-bak/scheduler/utils.py nova/scheduler/utils.py

--- nova-bak/scheduler/utils.py 2021-09-10 15:19:58.172561042 +0800

+++ nova/scheduler/utils.py      2021-09-10 15:35:05.630393147 +0800

@@ -35,7 +35,7 @@

 from nova.objects import instance as obj_instance

 from nova import rpc

 from nova.scheduler.filters import utils as filters_utils

-

+import nova.virt.hardware as hw

 

 LOG = logging.getLogger(__name__)

 

@@ -61,6 +61,27 @@

         # Default to the configured limit but _limit can be

         # set to None to indicate 'no limit'.

         self._limit = CONF.scheduler.max_placement_results

+        image = (request_spec.image if 'image' in request_spec

+                 else objects.ImageMeta(properties=objects.ImageMetaProps()))

+        self._translate_memory_encryption(request_spec.flavor, image)

+

+    def _translate_memory_encryption(self, flavor, image):

+        '''When the hw:mem_encryption extra spec or the hw_mem_encryption

+        image property are requested, translate into a request for

+        resources:MEM_ENCRYPTION_CONTEXT=1 which requires a slot on a

+        host which can support encryption of the guest memory.

+        '''

+        # NOTE(aspiers): In theory this could raise FlavorImageConflict,

+        # but we already check it in the API layer, so that should never

+        # happen.

+        if not hw.get_mem_encryption_constraint(flavor, image):

+            # No memory encryption required, so no further action required.

+            return

+

+        self._add_resource(None, orc.MEM_ENCRYPTION_CONTEXT, 1)

+        LOG.debug('Added %s=1 to requested resources',

+                  orc.MEM_ENCRYPTION_CONTEXT)

+

 

     def __str__(self):

         return ', '.join(sorted(

diff -ruN nova-bak/virt/hardware.py nova/virt/hardware.py

--- nova-bak/virt/hardware.py  2022-02-23 10:45:42.320988102 +0800

+++ nova/virt/hardware.py        2021-09-10 14:05:25.145572630 +0800

@@ -1140,6 +1140,67 @@

 

     return flavor_policy, image_policy

 

+def get_mem_encryption_constraint(flavor, image_meta, machine_type=None):

+    '''Return a boolean indicating whether encryption of guest memory was

+    requested, either via the hw:mem_encryption extra spec or the

+    hw_mem_encryption image property (or both).

+    Also watch out for contradictory requests between the flavor and

+    image regarding memory encryption, and raise an exception where

+    encountered.  These conflicts can arise in two different ways:

+        1) the flavor requests memory encryption but the image

+           explicitly requests *not* to have memory encryption, or

+           vice-versa

+        2) the flavor and/or image request memory encryption, but the

+           image is missing hw_firmware_type=uefi

+        3) the flavor and/or image request memory encryption, but the

+           machine type is set to a value which does not contain 'q35'

+    This can be called from the libvirt driver on the compute node, in

+    which case the driver should pass the result of

+    nova.virt.libvirt.utils.get_machine_type() as the machine_type

+    parameter, or from the API layer, in which case get_machine_type()

+    cannot be called since it relies on being run from the compute

+    node in order to retrieve CONF.libvirt.hw_machine_type.

+    :param instance_type: Flavor object

+    :param image: an ImageMeta object

+    :param machine_type: a string representing the machine type (optional)

+    :raises: nova.exception.FlavorImageConflict

+    :raises: nova.exception.InvalidMachineType

+    :returns: boolean indicating whether encryption of guest memory

+    was requested

+    '''

+

+    flavor_mem_enc_str, image_mem_enc = _get_flavor_image_meta(

+        'mem_encryption', flavor, image_meta)

+

+    flavor_mem_enc = None

+    if flavor_mem_enc_str is not None:

+        flavor_mem_enc = strutils.bool_from_string(flavor_mem_enc_str)

+

+    # Image property is a FlexibleBooleanField, so coercion to a

+    # boolean is handled automatically

+

+    if not flavor_mem_enc and not image_mem_enc:

+        return False

+

+    _check_for_mem_encryption_requirement_conflicts(

+        flavor_mem_enc_str, flavor_mem_enc, image_mem_enc, flavor, image_meta)

+

+    # If we get this far, either the extra spec or image property explicitly

+    # specified a requirement regarding memory encryption, and if both did,

+    # they are asking for the same thing.

+    requesters = []

+    if flavor_mem_enc:

+        requesters.append('hw:mem_encryption extra spec in %s flavor' %

+                          flavor.name)

+    if image_mem_enc:

+        requesters.append('hw_mem_encryption property of image %s' %

+                          image_meta.name)

+

+    _check_mem_encryption_uses_uefi_image(requesters, image_meta)

+    _check_mem_encryption_machine_type(image_meta, machine_type)

+

+    LOG.debug('Memory encryption requested by %s', ' and '.join(requesters))

+    return True

 

 def _get_numa_pagesize_constraint(flavor, image_meta):

     '''Return the requested memory page size

A1.2

diff -ruN nova-bak/compute/manager.py nova/compute/manager.py

--- nova-bak/compute/manager.py  2021-07-07 14:40:15.570807168 +0800

+++ nova/compute/manager.py        2021-10-18 19:02:37.931655551 +0800

@@ -7013,7 +7013,8 @@

                                         migrate_data)

 

         # Detaching volumes.

-        connector = self.driver.get_volume_connector(instance)

+        connector = None

+        #connector = self.driver.get_volume_connector(instance)

         for bdm in source_bdms:

             if bdm.is_volume:

                 # Detaching volumes is a call to an external API that can fail.

@@ -7033,6 +7034,8 @@

                         # remove the volume connection without detaching from

                         # hypervisor because the instance is not running

                         # anymore on the current host

+                        if connector is None:

+                            connector = self.driver.get_volume_connector(instance)

                         self.volume_api.terminate_connection(ctxt,

                                                              bdm.volume_id,

                                                              connector)

@@ -7056,8 +7059,10 @@

 

         # Releasing vlan.

         # (not necessary in current implementation?)

-

-        network_info = self.network_api.get_instance_nw_info(ctxt, instance)

+       

+        #changed by Fiona

+        #network_info = self.network_api.get_instance_nw_info(ctxt, instance)

+        network_info = instance.get_network_info()

 

         self._notify_about_instance_usage(ctxt, instance,

                                           'live_migration._post.start',

A1.3

diff -ruN neutron-bak/agent/l3/router_info.py neutron-iproute/agent/l3/router_info.py

--- neutron-bak/agent/l3/router_info.py    2020-12-14 18:00:23.683687327 +0800

+++ neutron-iproute/agent/l3/router_info.py     2022-02-23 15:18:15.650669589 +0800

@@ -748,8 +748,10 @@

         for ip_version in (lib_constants.IP_VERSION_4,

                            lib_constants.IP_VERSION_6):

             gateway = device.route.get_gateway(ip_version=ip_version)

-            if gateway and gateway.get('gateway'):

-                current_gateways.add(gateway.get('gateway'))

+#            if gateway and gateway.get('gateway'):

+#                current_gateways.add(gateway.get('gateway'))

+            if gateway and gateway.get('via'):

+                current_gateways.add(gateway.get('via'))

         for ip in current_gateways - set(gateway_ips):

             device.route.delete_gateway(ip)

         for ip in gateway_ips:

diff -ruN neutron-bak/agent/linux/ip_lib.py neutron-iproute/agent/linux/ip_lib.py

--- neutron-bak/agent/linux/ip_lib.py 2020-12-14 18:03:47.951878754 +0800

+++ neutron-iproute/agent/linux/ip_lib.py 2022-02-23 15:19:03.981457532 +0800

@@ -48,6 +48,8 @@

                   'main': 254,

                   'local': 255}

 

+IP_RULE_TABLES_NAMES = {v: k for k, v in IP_RULE_TABLES.items()}

+

 # Rule indexes: pyroute2.netlink.rtnl

 # Rule names: https://www.systutorials.com/docs/linux/man/8-ip-rule/

 # NOTE(ralonsoh): 'masquerade' type is printed as 'nat' in 'ip rule' command

@@ -592,14 +594,18 @@

     def _dev_args(self):

         return ['dev', self.name] if self.name else []

 

-    def add_gateway(self, gateway, metric=None, table=None):

-        ip_version = common_utils.get_ip_version(gateway)

-        args = ['replace', 'default', 'via', gateway]

-        if metric:

-            args += ['metric', metric]

-        args += self._dev_args()

-        args += self._table_args(table)

-        self._as_root([ip_version], tuple(args))

+#    def add_gateway(self, gateway, metric=None, table=None):

+#        ip_version = common_utils.get_ip_version(gateway)

+#        args = ['replace', 'default', 'via', gateway]

+#        if metric:

+#            args += ['metric', metric]

+#        args += self._dev_args()

+#        args += self._table_args(table)

+#        self._as_root([ip_version], tuple(args))

+

+    def add_gateway(self, gateway, metric=None, table=None, scope='global'):

+        self.add_route(None, via=gateway, table=table, metric=metric,

+                       scope=scope)

 

     def _run_as_root_detect_device_not_found(self, options, args):

         try:

@@ -618,41 +624,16 @@

         args += self._table_args(table)

         self._run_as_root_detect_device_not_found([ip_version], args)

 

-    def _parse_routes(self, ip_version, output, **kwargs):

-        for line in output.splitlines():

-            parts = line.split()

-

-            # Format of line is: '|default [] ...'

-            route = {k: v for k, v in zip(parts[1::2], parts[2::2])}

-            route['cidr'] = parts[0]

-            # Avoids having to explicitly pass around the IP version

-            if route['cidr'] == 'default':

-                route['cidr'] = constants.IP_ANY[ip_version]

-

-            # ip route drops things like scope and dev from the output if it

-            # was specified as a filter.  This allows us to add them back.

-            if self.name:

-                route['dev'] = self.name

-            if self._table:

-                route['table'] = self._table

-            # Callers add any filters they use as kwargs

-            route.update(kwargs)

-

-            yield route

-

-    def list_routes(self, ip_version, **kwargs):

-        args = ['list']

-        args += self._dev_args()

-        args += self._table_args()

-        for k, v in kwargs.items():

-            args += [k, v]

-

-        output = self._run([ip_version], tuple(args))

-        return [r for r in self._parse_routes(ip_version, output, **kwargs)]

+    def list_routes(self, ip_version, scope=None, via=None, table=None,

+                    **kwargs):

+        table = table or self._table

+        return list_ip_routes(self._parent.namespace, ip_version, scope=scope,

+                              via=via, table=table, device=self.name, **kwargs)

 

     def list_onlink_routes(self, ip_version):

         routes = self.list_routes(ip_version, scope='link')

-        return [r for r in routes if 'src' not in r]

+#        return [r for r in routes if 'src' not in r]

+        return [r for r in routes if not r['source_prefix']]

 

     def add_onlink_route(self, cidr):

         self.add_route(cidr, scope='link')

@@ -660,34 +641,12 @@

     def delete_onlink_route(self, cidr):

         self.delete_route(cidr, scope='link')

 

-    def get_gateway(self, scope=None, filters=None, ip_version=None):

-        options = [ip_version] if ip_version else []

-

-        args = ['list']

-        args += self._dev_args()

-        args += self._table_args()

-        if filters:

-            args += filters

-

-        retval = None

-

-        if scope:

-            args += ['scope', scope]

-

-        route_list_lines = self._run(options, tuple(args)).split('\n')

-        default_route_line = next((x.strip() for x in

-                                   route_list_lines if

-                                   x.strip().startswith('default')), None)

-        if default_route_line:

-            retval = dict()

-            gateway = DEFAULT_GW_PATTERN.search(default_route_line)

-            if gateway:

-                retval.update(gateway=gateway.group(1))

-            metric = METRIC_PATTERN.search(default_route_line)

-            if metric:

-                retval.update(metric=int(metric.group(1)))

-

-        return retval

+    def get_gateway(self, scope=None, table=None,

+                    ip_version=constants.IP_VERSION_4):

+        routes = self.list_routes(ip_version, scope=scope, table=table)

+        for route in routes:

+            if route['via'] and route['cidr'] in constants.IP_ANY.values():

+                return route

 

     def flush(self, ip_version, table=None, **kwargs):

         args = ['flush']

@@ -696,16 +655,11 @@

             args += [k, v]

         self._as_root([ip_version], tuple(args))

 

-    def add_route(self, cidr, via=None, table=None, **kwargs):

-        ip_version = common_utils.get_ip_version(cidr)

-        args = ['replace', cidr]

-        if via:

-            args += ['via', via]

-        args += self._dev_args()

-        args += self._table_args(table)

-        for k, v in kwargs.items():

-            args += [k, v]

-        self._run_as_root_detect_device_not_found([ip_version], args)

+    def add_route(self, cidr, via=None, table=None, metric=None, scope=None,

+                  **kwargs):

+        table = table or self._table

+        add_ip_route(self._parent.namespace, cidr, device=self.name, via=via,

+                     table=table, metric=metric, scope=scope, **kwargs)

 

     def delete_route(self, cidr, via=None, table=None, **kwargs):

         ip_version = common_utils.get_ip_version(cidr)

@@ -1455,3 +1409,53 @@

                 retval[device['vxlan_link_index']]['name'])

 

     return list(retval.values())

+

+def add_ip_route(namespace, cidr, device=None, via=None, table=None,

+                 metric=None, scope=None, **kwargs):

+    '''Add an IP route'''

+    if table:

+        table = IP_RULE_TABLES.get(table, table)

+    ip_version = common_utils.get_ip_version(cidr or via)

+    privileged.add_ip_route(namespace, cidr, ip_version,

+                            device=device, via=via, table=table,

+                            metric=metric, scope=scope, **kwargs)

+

+

+def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,

+                   device=None, **kwargs):

+    '''List IP routes'''

+    def get_device(index, devices):

+        for device in (d for d in devices if d['index'] == index):

+            return get_attr(device, 'IFLA_IFNAME')

+

+    table = table if table else 'main'

+    table = IP_RULE_TABLES.get(table, table)

+    routes = privileged.list_ip_routes(namespace, ip_version, device=device,

+                                       table=table, **kwargs)

+    devices = privileged.get_link_devices(namespace)

+    ret = []

+    for route in routes:

+        cidr = get_attr(route, 'RTA_DST')

+        if cidr:

+            cidr = '%s/%s' % (cidr, route['dst_len'])

+        else:

+            cidr = constants.IP_ANY[ip_version]

+        table = int(get_attr(route, 'RTA_TABLE'))

+        value = {

+            'table': IP_RULE_TABLES_NAMES.get(table, table),

+            'source_prefix': get_attr(route, 'RTA_PREFSRC'),

+            'cidr': cidr,

+            'scope': IP_ADDRESS_SCOPE[int(route['scope'])],

+            'device': get_device(int(get_attr(route, 'RTA_OIF')), devices),

+            'via': get_attr(route, 'RTA_GATEWAY'),

+            'priority': get_attr(route, 'RTA_PRIORITY'),

+        }

+

+        ret.append(value)

+

+    if scope:

+        ret = [route for route in ret if route['scope'] == scope]

+    if via:

+        ret = [route for route in ret if route['via'] == via]

+

+    return ret

diff -ruN neutron-bak/cmd/sanity/checks.py neutron-iproute/cmd/sanity/checks.py

--- neutron-bak/cmd/sanity/checks.py       2022-02-23 11:33:16.934132708 +0800

+++ neutron-iproute/cmd/sanity/checks.py        2022-02-23 15:20:10.562018672 +0800

@@ -36,6 +36,7 @@

 from neutron.common import utils as common_utils

 from neutron.plugins.ml2.drivers.openvswitch.agent.common \

     import constants as ovs_const

+from neutron.privileged.agent.linux import dhcp as priv_dhcp

 

 LOG = logging.getLogger(__name__)

 

@@ -230,8 +231,8 @@

 

 

 def dhcp_release6_supported():

-    return runtime_checks.dhcp_release6_supported()

-

+#    return runtime_checks.dhcp_release6_supported()

+     return priv_dhcp.dhcp_release6_supported()

 

 def bridge_firewalling_enabled():

     for proto in ('arp', 'ip', 'ip6'):

@@ -363,7 +364,8 @@

 

             default_gw = gw_dev.route.get_gateway(ip_version=6)

             if default_gw:

-                default_gw = default_gw['gateway']

+#                default_gw = default_gw['gateway']

+                default_gw = default_gw['via']

 

     return expected_default_gw == default_gw

 

diff -ruN neutron-bak/privileged/agent/linux/ip_lib.py neutron-iproute/privileged/agent/linux/ip_lib.py

--- neutron-bak/privileged/agent/linux/ip_lib.py 2020-12-14 18:26:08.339307939 +0800

+++ neutron-iproute/privileged/agent/linux/ip_lib.py 2022-02-23 15:20:39.477439105 +0800

@@ -634,3 +634,50 @@

         if e.errno == errno.ENOENT:

             raise NetworkNamespaceNotFound(netns_name=namespace)

         raise

+

+@privileged.default.entrypoint

+@lockutils.synchronized('privileged-ip-lib')

+def add_ip_route(namespace, cidr, ip_version, device=None, via=None,

+                 table=None, metric=None, scope=None, **kwargs):

+    '''Add an IP route'''

+    try:

+        with get_iproute(namespace) as ip:

+            family = _IP_VERSION_FAMILY_MAP[ip_version]

+            if not scope:

+                scope = 'global' if via else 'link'

+            scope = _get_scope_name(scope)

+            if cidr:

+                kwargs['dst'] = cidr

+            if via:

+                kwargs['gateway'] = via

+            if table:

+                kwargs['table'] = int(table)

+            if device:

+                kwargs['oif'] = get_link_id(device, namespace)

+            if metric:

+                kwargs['priority'] = int(metric)

+            ip.route('replace', family=family, scope=scope, proto='static',

+                     **kwargs)

+    except OSError as e:

+        if e.errno == errno.ENOENT:

+            raise NetworkNamespaceNotFound(netns_name=namespace)

+        raise

+

+

+@privileged.default.entrypoint

+@lockutils.synchronized('privileged-ip-lib')

+def list_ip_routes(namespace, ip_version, device=None, table=None, **kwargs):

+    '''List IP routes'''

+    try:

+        with get_iproute(namespace) as ip:

+            family = _IP_VERSION_FAMILY_MAP[ip_version]

+            if table:

+                kwargs['table'] = table

+            if device:

+                kwargs['oif'] = get_link_id(device, namespace)

+            return make_serializable(ip.route('show', family=family, **kwargs))

+    except OSError as e:

+        if e.errno == errno.ENOENT:

+            raise NetworkNamespaceNotFound(netns_name=namespace)

+        raise

+

A1.4

diff -ruN neutron-bak/agent/linux/dhcp.py neutron-dhcprelease/agent/linux/dhcp.py

--- neutron-bak/agent/linux/dhcp.py 2020-12-15 09:59:29.966957908 +0800

+++ neutron-dhcprelease/agent/linux/dhcp.py  2022-02-23 15:10:14.169101010 +0800

@@ -25,6 +25,7 @@

 from neutron_lib import constants

 from neutron_lib import exceptions

 from neutron_lib.utils import file as file_utils

+from oslo_concurrency import processutils

 from oslo_log import log as logging

 from oslo_utils import excutils

 from oslo_utils import fileutils

@@ -41,6 +42,7 @@

 from neutron.common import ipv6_utils

 from neutron.common import utils as common_utils

 from neutron.ipam import utils as ipam_utils

+from neutron.privileged.agent.linux import dhcp as priv_dhcp

 

 LOG = logging.getLogger(__name__)

 

@@ -476,7 +478,8 @@

 

     def _is_dhcp_release6_supported(self):

         if self._IS_DHCP_RELEASE6_SUPPORTED is None:

-            self._IS_DHCP_RELEASE6_SUPPORTED = checks.dhcp_release6_supported()

+            self._IS_DHCP_RELEASE6_SUPPORTED = (

+                priv_dhcp.dhcp_release6_supported())

             if not self._IS_DHCP_RELEASE6_SUPPORTED:

                 LOG.warning('dhcp_release6 is not present on this system, '

                             'will not call it again.')

@@ -485,24 +488,28 @@

     def _release_lease(self, mac_address, ip, ip_version, client_id=None,

                        server_id=None, iaid=None):

         '''Release a DHCP lease.'''

-        if ip_version == constants.IP_VERSION_6:

-            if not self._is_dhcp_release6_supported():

-                return

-            cmd = ['dhcp_release6', '--iface', self.interface_name,

-                   '--ip', ip, '--client-id', client_id,

-                   '--server-id', server_id, '--iaid', iaid]

-        else:

-            cmd = ['dhcp_release', self.interface_name, ip, mac_address]

-            if client_id:

-                cmd.append(client_id)

-        ip_wrapper = ip_lib.IPWrapper(namespace=self.network.namespace)

         try:

-            ip_wrapper.netns.execute(cmd, run_as_root=True)

-        except RuntimeError as e:

+            if ip_version == constants.IP_VERSION_6:

+                if not self._is_dhcp_release6_supported():

+                    return

+

+                params = {'interface_name': self.interface_name,

+                          'ip_address': ip, 'client_id': client_id,

+                          'server_id': server_id, 'iaid': iaid,

+                          'namespace': self.network.namespace}

+                priv_dhcp.dhcp_release6(**params)

+            else:

+                params = {'interface_name': self.interface_name,

+                          'ip_address': ip, 'mac_address': mac_address,

+                          'client_id': client_id,

+                          'namespace': self.network.namespace}

+#                LOG.info('Rock_DEBUG: DHCP release construct params %(params)s.', {'params': params})

+                priv_dhcp.dhcp_release(**params)

+        except (processutils.ProcessExecutionError, OSError) as e:

             # when failed to release single lease there's

             # no need to propagate error further

-            LOG.warning('DHCP release failed for %(cmd)s. '

-                        'Reason: %(e)s', {'cmd': cmd, 'e': e})

+            LOG.warning('DHCP release failed for params %(params)s. '

+                        'Reason: %(e)s', {'params': params, 'e': e})

 

     def _output_config_files(self):

         self._output_hosts_file()

diff -ruN neutron-bak/cmd/sanity/checks.py neutron-dhcprelease/cmd/sanity/checks.py

--- neutron-bak/cmd/sanity/checks.py       2022-02-23 11:33:16.934132708 +0800

+++ neutron-dhcprelease/cmd/sanity/checks.py 2022-02-23 15:11:07.536446402 +0800

@@ -36,6 +36,7 @@

 from neutron.common import utils as common_utils

 from neutron.plugins.ml2.drivers.openvswitch.agent.common \

     import constants as ovs_const

+from neutron.privileged.agent.linux import dhcp as priv_dhcp

 

 LOG = logging.getLogger(__name__)

 

@@ -230,8 +231,8 @@

 

 

 def dhcp_release6_supported():

-    return runtime_checks.dhcp_release6_supported()

-

+#    return runtime_checks.dhcp_release6_supported()

+     return priv_dhcp.dhcp_release6_supported()

 

 def bridge_firewalling_enabled():

     for proto in ('arp', 'ip', 'ip6'):

@@ -363,7 +364,8 @@

 

             default_gw = gw_dev.route.get_gateway(ip_version=6)

             if default_gw:

-                default_gw = default_gw['gateway']

+#                default_gw = default_gw['gateway']

+                default_gw = default_gw['via']

 

     return expected_default_gw == default_gw

 

diff -ruN neutron-bak/privileged/__init__.py neutron-dhcprelease/privileged/__init__.py

--- neutron-bak/privileged/__init__.py        2020-04-23 14:45:14.000000000 +0800

+++ neutron-dhcprelease/privileged/__init__.py 2022-02-23 15:10:29.209584186 +0800

@@ -27,3 +27,11 @@

                   caps.CAP_DAC_OVERRIDE,

                   caps.CAP_DAC_READ_SEARCH],

 )

+

+dhcp_release_cmd = priv_context.PrivContext(

+    __name__,

+    cfg_section='privsep_dhcp_release',

+    pypath=__name__ + '.dhcp_release_cmd',

+    capabilities=[caps.CAP_SYS_ADMIN,

+                  caps.CAP_NET_ADMIN]

+)

A1.5

diff -ruN neutron-bak/agent/linux/ipset_manager.py neutron/agent/linux/ipset_manager.py

--- neutron-bak/agent/linux/ipset_manager.py  2022-02-16 15:11:40.419016919 +0800

+++ neutron/agent/linux/ipset_manager.py        2022-02-16 15:17:02.328133786 +0800

@@ -146,7 +146,7 @@

             cmd_ns.extend(['ip', 'netns', 'exec', self.namespace])

         cmd_ns.extend(cmd)

         self.execute(cmd_ns, run_as_root=True, process_input=input,

-                     check_exit_code=fail_on_errors)

+                     check_exit_code=fail_on_errors, privsep_exec=True)

 

     def _get_new_set_ips(self, set_name, expected_ips):

         new_member_ips = (set(expected_ips) -

diff -ruN neutron-bak/agent/linux/iptables_manager.py neutron/agent/linux/iptables_manager.py

--- neutron-bak/agent/linux/iptables_manager.py      2022-02-16 15:05:53.853147520 +0800

+++ neutron/agent/linux/iptables_manager.py   2021-07-07 14:59:16.000000000 +0800

@@ -475,12 +475,15 @@

         args = ['iptables-save', '-t', table]

         if self.namespace:

             args = ['ip', 'netns', 'exec', self.namespace] + args

-        return self.execute(args, run_as_root=True).split('\n')

+        #return self.execute(args, run_as_root=True).split('\n')

+        return self.execute(args, run_as_root=True,

+                            privsep_exec=True).split('\n')

 

     def _get_version(self):

         # Output example is 'iptables v1.6.2'

         args = ['iptables', '--version']

-        version = str(self.execute(args, run_as_root=True).split()[1][1:])

+        #version = str(self.execute(args, run_as_root=True).split()[1][1:])

+        version = str(self.execute(args, run_as_root=True, privsep_exec=True).split()[1][1:])

         LOG.debug('IPTables version installed: %s', version)

         return version

 

@@ -505,8 +508,10 @@

             args += ['-w', self.xlock_wait_time, '-W', XLOCK_WAIT_INTERVAL]

         try:

             kwargs = {} if lock else {'log_fail_as_error': False}

+            #self.execute(args, process_input='\n'.join(commands),

+            #             run_as_root=True, **kwargs)

             self.execute(args, process_input='\n'.join(commands),

-                         run_as_root=True, **kwargs)

+                         run_as_root=True, privsep_exec=True, **kwargs)

         except RuntimeError as error:

             return error

 

@@ -568,7 +573,8 @@

             if self.namespace:

                 args = ['ip', 'netns', 'exec', self.namespace] + args

             try:

-                save_output = self.execute(args, run_as_root=True)

+                #save_output = self.execute(args, run_as_root=True)

+                save_output = self.execute(args, run_as_root=True, privsep_exec=True)

             except RuntimeError:

                 # We could be racing with a cron job deleting namespaces.

                 # It is useless to try to apply iptables rules over and

@@ -769,7 +775,8 @@

                 args.append('-Z')

             if self.namespace:

                 args = ['ip', 'netns', 'exec', self.namespace] + args

-            current_table = self.execute(args, run_as_root=True)

+            #current_table = self.execute(args, run_as_root=True)

+            current_table = self.execute(args, run_as_root=True, privsep_exec=True)

             current_lines = current_table.split('\n')

 

             for line in current_lines[2:]:

diff -ruN neutron-bak/agent/linux/utils.py neutron/agent/linux/utils.py

--- neutron-bak/agent/linux/utils.py 2022-02-16 15:06:03.133090388 +0800

+++ neutron/agent/linux/utils.py       2021-07-08 09:34:12.000000000 +0800

@@ -38,6 +38,7 @@

 from neutron.agent.linux import xenapi_root_helper

 from neutron.common import utils

 from neutron.conf.agent import common as config

+from neutron.privileged.agent.linux import utils as priv_utils

 from neutron import wsgi

 

 

@@ -85,13 +86,24 @@

     if run_as_root:

         cmd = shlex.split(config.get_root_helper(cfg.CONF)) + cmd

     LOG.debug('Running command: %s', cmd)

-    obj = utils.subprocess_popen(cmd, shell=False,

-                                 stdin=subprocess.PIPE,

-                                 stdout=subprocess.PIPE,

-                                 stderr=subprocess.PIPE)

+    #obj = utils.subprocess_popen(cmd, shell=False,

+    #                             stdin=subprocess.PIPE,

+    #                             stdout=subprocess.PIPE,

+    #                             stderr=subprocess.PIPE)

+    obj = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,

+                           stdout=subprocess.PIPE, stderr=subprocess.PIPE)

 

     return obj, cmd

 

+def _execute_process(cmd, _process_input, addl_env, run_as_root):

+    obj, cmd = create_process(cmd, run_as_root=run_as_root, addl_env=addl_env)

+    _stdout, _stderr = obj.communicate(_process_input)

+    returncode = obj.returncode

+    obj.stdin.close()

+    _stdout = helpers.safe_decode_utf8(_stdout)

+    _stderr = helpers.safe_decode_utf8(_stderr)

+    return _stdout, _stderr, returncode

+

 

 def execute_rootwrap_daemon(cmd, process_input, addl_env):

     cmd = list(map(str, addl_env_args(addl_env) + cmd))

@@ -103,31 +115,45 @@

     LOG.debug('Running command (rootwrap daemon): %s', cmd)

     client = RootwrapDaemonHelper.get_client()

     try:

-        return client.execute(cmd, process_input)

+        #return client.execute(cmd, process_input)

+        returncode, __stdout, _stderr =  client.execute(cmd, process_input)

     except Exception:

         with excutils.save_and_reraise_exception():

             LOG.error('Rootwrap error running command: %s', cmd)

+    _stdout = helpers.safe_decode_utf8(_stdout)

+    _stderr = helpers.safe_decode_utf8(_stderr)

+    return _stdout, _stderr, returncode

 

 

 def execute(cmd, process_input=None, addl_env=None,

             check_exit_code=True, return_stderr=False, log_fail_as_error=True,

-            extra_ok_codes=None, run_as_root=False):

+            extra_ok_codes=None, run_as_root=False, privsep_exec=False):

     try:

         if process_input is not None:

             _process_input = encodeutils.to_utf8(process_input)

         else:

             _process_input = None

-        if run_as_root and cfg.CONF.AGENT.root_helper_daemon:

-            returncode, _stdout, _stderr = (

-                execute_rootwrap_daemon(cmd, process_input, addl_env))

+        #if run_as_root and cfg.CONF.AGENT.root_helper_daemon:

+        #    returncode, _stdout, _stderr = (

+        #        execute_rootwrap_daemon(cmd, process_input, addl_env))

+        #else:

+        #    obj, cmd = create_process(cmd, run_as_root=run_as_root,

+        #                              addl_env=addl_env)

+        #    _stdout, _stderr = obj.communicate(_process_input)

+        #    returncode = obj.returncode

+        #    obj.stdin.close()

+        #_stdout = helpers.safe_decode_utf8(_stdout)

+        #_stderr = helpers.safe_decode_utf8(_stderr)

+

+        if run_as_root and privsep_exec:

+            _stdout, _stderr, returncode = priv_utils.execute_process(

+                cmd, _process_input, addl_env)

+        elif run_as_root and cfg.CONF.AGENT.root_helper_daemon:

+            _stdout, _stderr, returncode = execute_rootwarp_daemon(

+                cmd, process_input, addl_env)

         else:

-            obj, cmd = create_process(cmd, run_as_root=run_as_root,

-                                      addl_env=addl_env)

-            _stdout, _stderr = obj.communicate(_process_input)

-            returncode = obj.returncode

-            obj.stdin.close()

-        _stdout = helpers.safe_decode_utf8(_stdout)

-        _stderr = helpers.safe_decode_utf8(_stderr)

+            _stdout, _stderr, returncode = _execute_process(

+                cmd, _process_input, addl_env, run_as_root)

 

         extra_ok_codes = extra_ok_codes or []

         if returncode and returncode not in extra_ok_codes:

diff -ruN neutron-bak/cmd/ipset_cleanup.py neutron/cmd/ipset_cleanup.py

--- neutron-bak/cmd/ipset_cleanup.py      2022-02-16 15:18:00.727786180 +0800

+++ neutron/cmd/ipset_cleanup.py   2021-07-07 15:00:03.000000000 +0800

@@ -38,7 +38,8 @@

 def remove_iptables_reference(ipset):

     # Remove any iptables reference to this IPset

     cmd = ['iptables-save'] if 'IPv4' in ipset else ['ip6tables-save']

-    iptables_save = utils.execute(cmd, run_as_root=True)

+    #iptables_save = utils.execute(cmd, run_as_root=True)

+    iptables_save = utils.execute(cmd, run_as_root=True, privsep_exec=True)

 

     if ipset in iptables_save:

         cmd = ['iptables'] if 'IPv4' in ipset else ['ip6tables']

@@ -50,7 +51,8 @@

                 params = rule.split()

                 params[0] = '-D'

                 try:

-                    utils.execute(cmd + params, run_as_root=True)

+                    #utils.execute(cmd + params, run_as_root=True)

+                    utils.execute(cmd + params, run_as_root=True, privsep_exec=True)

                 except Exception:

                     LOG.exception('Error, unable to remove iptables rule '

                                   'for IPset: %s', ipset)

@@ -65,7 +67,8 @@

     LOG.info('Destroying IPset: %s', ipset)

     cmd = ['ipset', 'destroy', ipset]

     try:

-        utils.execute(cmd, run_as_root=True)

+        #utils.execute(cmd, run_as_root=True)

+        utils.execute(cmd, run_as_root=True, privsep_exec=True)

     except Exception:

         LOG.exception('Error, unable to destroy IPset: %s', ipset)

 

@@ -75,7 +78,8 @@

     LOG.info('Destroying IPsets with prefix: %s', conf.prefix)

 

     cmd = ['ipset', '-L', '-n']

-    ipsets = utils.execute(cmd, run_as_root=True)

+    #ipsets = utils.execute(cmd, run_as_root=True)

+    ipsets = utils.execute(cmd, run_as_root=True, privsep_exec=True)

     for ipset in ipsets.split('\n'):

         if conf.allsets or ipset.startswith(conf.prefix):

             destroy_ipset(conf, ipset)

diff -ruN neutron-bak/privileged/agent/linux/utils.py neutron/privileged/agent/linux/utils.py

--- neutron-bak/privileged/agent/linux/utils.py  1970-01-01 08:00:00.000000000 +0800

+++ neutron/privileged/agent/linux/utils.py        2021-07-07 14:58:21.000000000 +0800

@@ -0,0 +1,82 @@

+# Copyright 2020 Red Hat, Inc.

+#

+#    Licensed under the Apache License, Version 2.0 (the 'License'); you may

+#    not use this file except in compliance with the License. You may obtain

+#    a copy of the License at

+#

+#         http://www.apache.org/licenses/LICENSE-2.0

+#

+#    Unless required by applicable law or agreed to in writing, software

+#    distributed under the License is distributed on an 'AS IS' BASIS, WITHOUT

+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the

+#    License for the specific language governing permissions and limitations

+#    under the License.

+

+import os

+import re

+

+from eventlet.green import subprocess

+from neutron_lib.utils import helpers

+from oslo_concurrency import processutils

+from oslo_utils import fileutils

+

+from neutron import privileged

+

+

+NETSTAT_PIDS_REGEX = re.compile(r'.* (?P\d{2,6})/.*')

+

+

+@privileged.default.entrypoint

+def find_listen_pids_namespace(namespace):

+    return _find_listen_pids_namespace(namespace)

+

+

+def _find_listen_pids_namespace(namespace):

+    '''Retrieve a list of pids of listening processes within the given netns

+    This method is implemented separately to allow unit testing.

+    '''

+    pids = set()

+    cmd = ['ip', 'netns', 'exec', namespace, 'netstat', '-nlp']

+    output = processutils.execute(*cmd)

+    for line in output[0].splitlines():

+        m = NETSTAT_PIDS_REGEX.match(line)

+        if m:

+            pids.add(m.group('pid'))

+    return list(pids)

+

+

+@privileged.default.entrypoint

+def delete_if_exists(path, remove=os.unlink):

+    fileutils.delete_if_exists(path, remove=remove)

+

+

+@privileged.default.entrypoint

+def execute_process(cmd, _process_input, addl_env):

+    obj, cmd = _create_process(cmd, addl_env=addl_env)

+    _stdout, _stderr = obj.communicate(_process_input)

+    returncode = obj.returncode

+    obj.stdin.close()

+    _stdout = helpers.safe_decode_utf8(_stdout)

+    _stderr = helpers.safe_decode_utf8(_stderr)

+    return _stdout, _stderr, returncode

+

+

+def _addl_env_args(addl_env):

+    '''Build arguments for adding additional environment vars with env'''

+

+    # NOTE (twilson) If using rootwrap, an EnvFilter should be set up for the

+    # command instead of a CommandFilter.

+    if addl_env is None:

+        return []

+    return ['env'] + ['%s=%s' % pair for pair in addl_env.items()]

+

+

+def _create_process(cmd, addl_env=None):

+    '''Create a process object for the given command.

+    The return value will be a tuple of the process object and the

+    list of command arguments used to create it.

+    '''

+    cmd = list(map(str, _addl_env_args(addl_env) + list(cmd)))

+    obj = subprocess.Popen(cmd, shell=False, stdin=subprocess.PIPE,

+                           stdout=subprocess.PIPE, stderr=subprocess.PIPE)

+    return obj, cmd

B1.1

--- neutron-bak/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py  2022-08-02 17:02:51.213224245 +0800

+++ neutron/plugins/ml2/drivers/openvswitch/agent/ovs_neutron_agent.py 2022-08-02 17:02:09.181883012 +0800

@@ -161,8 +161,8 @@

         self.enable_distributed_routing = agent_conf.enable_distributed_routing

         self.arp_responder_enabled = agent_conf.arp_responder and self.l2_pop

 

-        host = self.conf.host

-        self.agent_id = 'ovs-agent-%s' % host

+        self.host = self.conf.host

+        self.agent_id = 'ovs-agent-%s' % self.host

 

         self.enable_tunneling = bool(self.tunnel_types)

 

@@ -245,7 +245,7 @@

             self.phys_ofports,

             self.patch_int_ofport,

             self.patch_tun_ofport,

-            host,

+            self.host,

             self.enable_tunneling,

             self.enable_distributed_routing,

             self.arp_responder_enabled)

@@ -289,7 +289,7 @@

         #                  or which are used by specific extensions.

         self.agent_state = {

             'binary': 'neutron-openvswitch-agent',

-            'host': host,

+            'host': self.host,

             'topic': n_const.L2_AGENT_TOPIC,

             'configurations': {'bridge_mappings': self.bridge_mappings,

                                c_const.RP_BANDWIDTHS: self.rp_bandwidths,

@@ -1671,6 +1671,7 @@

         skipped_devices = []

         need_binding_devices = []

         binding_no_activated_devices = set()

+        migrating_devices = set()

         agent_restarted = self.iter_num == 0

         devices_details_list = (

             self.plugin_rpc.get_devices_details_list_and_failed_devices(

@@ -1696,6 +1697,12 @@

                 skipped_devices.append(device)

                 continue

 

+            migrating_to = details.get('migrating_to')

+            if migrating_to and migrating_to != self.host:

+                LOG.info('Port %(device)s is being migrated to host %(host)s.',

+                         {'device': device, 'host': migrating_to})

+                migrating_devices.add(device)

+

             if 'port_id' in details:

                 LOG.info('Port %(device)s updated. Details: %(details)s',

                          {'device': device, 'details': details})

@@ -1729,7 +1736,7 @@

                 if (port and port.ofport != -1):

                     self.port_dead(port)

         return (skipped_devices, binding_no_activated_devices,

-                need_binding_devices, failed_devices)

+                need_binding_devices, failed_devices, migrating_devices)

 

     def _update_port_network(self, port_id, network_id):

         self._clean_network_ports(port_id)

@@ -1821,10 +1828,12 @@

         need_binding_devices = []

         skipped_devices = set()

         binding_no_activated_devices = set()

+        migrating_devices = set()

         start = time.time()

         if devices_added_updated:

             (skipped_devices, binding_no_activated_devices,

-             need_binding_devices, failed_devices['added']) = (

+             need_binding_devices, failed_devices['added'],

+                migrating_devices) = (

                 self.treat_devices_added_or_updated(

                     devices_added_updated, provisioning_needed))

             LOG.debug('process_network_ports - iteration:%(iter_num)d - '

@@ -1847,7 +1856,7 @@

         # TODO(salv-orlando): Optimize avoiding applying filters

         # unnecessarily, (eg: when there are no IP address changes)

         added_ports = (port_info.get('added', set()) - skipped_devices -

-                       binding_no_activated_devices)

+                       binding_no_activated_devices - migrating_devices)

         self._add_port_tag_info(need_binding_devices)

         self.sg_agent.setup_port_filters(added_ports,

                                          port_info.get('updated', set()))

B1.2

--- neutron-bak/conf/common.py     2022-08-02 17:07:18.239265163 +0800

+++ neutron/conf/common.py 2021-09-08 17:08:59.000000000 +0800

@@ -166,6 +166,24 @@

                help=_('Type of the nova endpoint to use.  This endpoint will'

                       ' be looked up in the keystone catalog and should be'

                       ' one of public, internal or admin.')),

+    cfg.BoolOpt('live_migration_events', default=True,

+                help=_('When this option is enabled, during the live '

+                       'migration, the OVS agent will only send the '

+                       ''vif-plugged-event' when the destination host '

+                       'interface is bound. This option also disables any '

+                       'other agent (like DHCP) to send to Nova this event '

+                       'when the port is provisioned.'

+                       'This option can be enabled if Nova patch '

+                       'https://review.opendev.org/c/openstack/nova/+/767368 '

+                       'is in place.'

+                       'This option is temporary and will be removed in Y and '

+                       'the behavior will be 'True'.'),

+                deprecated_for_removal=True,

+                deprecated_reason=(

+                    'In Y the Nova patch '

+                    'https://review.opendev.org/c/openstack/nova/+/767368 '

+                    'will be in the code even when running a Nova server in '

+                    'X.')),

 ]

B1.3

--- neutron-bak/agent/rpc.py   2021-08-25 15:29:11.000000000 +0800

+++ neutron/agent/rpc.py 2021-09-15 16:34:09.000000000 +0800

@@ -25,8 +25,10 @@

 from neutron_lib import constants

 from neutron_lib.plugins import utils

 from neutron_lib import rpc as lib_rpc

+from oslo_config import cfg

 from oslo_log import log as logging

 import oslo_messaging

+from oslo_serialization import jsonutils

 from oslo_utils import uuidutils

 

 from neutron.agent import resource_cache

@@ -323,8 +325,10 @@

         binding = utils.get_port_binding_by_status_and_host(

             port_obj.bindings, constants.ACTIVE, raise_if_not_found=True,

             port_id=port_obj.id)

-        if (port_obj.device_owner.startswith(

-                constants.DEVICE_OWNER_COMPUTE_PREFIX) and

+        migrating_to = migrating_to_host(port_obj.bindings)

+        if (not (migrating_to and cfg.CONF.nova.live_migration_events) and

+                port_obj.device_owner.startswith(

+                    constants.DEVICE_OWNER_COMPUTE_PREFIX) and

                 binding[pb_ext.HOST] != host):

             LOG.debug('Device %s has no active binding in this host',

                       port_obj)

@@ -357,7 +361,8 @@

             'qos_policy_id': port_obj.qos_policy_id,

             'network_qos_policy_id': net_qos_policy_id,

             'profile': binding.profile,

-            'security_groups': list(port_obj.security_group_ids)

+            'security_groups': list(port_obj.security_group_ids),

+            'migrating_to': migrating_to,

         }

         LOG.debug('Returning: %s', entry)

         return entry

@@ -365,3 +370,40 @@

     def get_devices_details_list(self, context, devices, agent_id, host=None):

         return [self.get_device_details(context, device, agent_id, host)

                 for device in devices]

+

+# TODO(ralonsoh): move this method to neutron_lib.plugins.utils

+def migrating_to_host(bindings, host=None):

+    '''Return the host the port is being migrated.

+

+    If the host is passed, the port binding profile with the 'migrating_to',

+    that contains the host the port is being migrated, is compared to this

+    value. If no value is passed, this method will return if the port is

+    being migrated ('migrating_to' is present in any port binding profile).

+

+    The function returns None or the matching host.

+    '''

+    #LOG.info('LiveDebug: enter migrating_to_host  001')

+    for binding in (binding for binding in bindings if

+                    binding[pb_ext.STATUS] == constants.ACTIVE):

+        profile = binding.get('profile')

+        if not profile:

+            continue

+       '''

+        profile = (jsonutils.loads(profile) if isinstance(profile, str) else

+                   profile)

+        migrating_to = profile.get('migrating_to')

+       '''

+        # add by michael

+        if isinstance(profile, str):

+            migrating_to = jsonutils.loads(profile).get('migrating_to')

+            #LOG.info('LiveDebug: migrating_to_host 001  migrating_to: %s', migrating_to)

+        else:

+            migrating_to = profile.get('migrating_to')

+            #LOG.info('LiveDebug: migrating_to_host 002  migrating_to: %s', migrating_to)

+

+        if migrating_to:

+            if not host:  # Just know if the port is being migrated.

+                return migrating_to

+            if migrating_to == host:

+                return migrating_to

+    return None

B1.4

--- neutron-bak/db/provisioning_blocks.py        2021-08-25 15:43:47.000000000 +0800

+++ neutron/db/provisioning_blocks.py     2021-09-03 09:32:41.000000000 +0800

@@ -137,8 +137,7 @@

             context, standard_attr_id=standard_attr_id):

         LOG.debug('Provisioning complete for %(otype)s %(oid)s triggered by '

                   'entity %(entity)s.', log_dict)

-        registry.notify(object_type, PROVISIONING_COMPLETE,

-                        'neutron.db.provisioning_blocks',

+        registry.notify(object_type, PROVISIONING_COMPLETE, entity,

                         context=context, object_id=object_id)

 

B1.5

--- neutron-bak/notifiers/nova.py     2021-08-25 16:02:33.000000000 +0800

+++ neutron/notifiers/nova.py  2021-09-03 09:32:41.000000000 +0800

@@ -13,6 +13,8 @@

 #    License for the specific language governing permissions and limitations

 #    under the License.

 

+import contextlib

+

 from keystoneauth1 import loading as ks_loading

 from neutron_lib.callbacks import events

 from neutron_lib.callbacks import registry

@@ -66,6 +68,16 @@

             if ext.name == 'server_external_events']

         self.batch_notifier = batch_notifier.BatchNotifier(

             cfg.CONF.send_events_interval, self.send_events)

+        self._enabled = True

+

+    @contextlib.contextmanager

+    def context_enabled(self, enabled):

+        stored_enabled = self._enabled

+        try:

+            self._enabled = enabled

+            yield

+        finally:

+            self._enabled = stored_enabled

 

     def _get_nova_client(self):

         global_id = common_context.generate_request_id()

@@ -163,6 +175,10 @@

                 return self._get_network_changed_event(port)

 

     def _can_notify(self, port):

+        if not self._enabled:

+            LOG.debug('Nova notifier disabled')

+            return False

+

         if not port.id:

             LOG.warning('Port ID not set! Nova will not be notified of '

                         'port status change.')

B1.6

--- nova-bak/compute/manager.py  2022-08-02 16:27:45.943428128 +0800

+++ nova/compute/manager.py        2021-09-03 09:35:24.529858458 +0800

@@ -6637,12 +6637,12 @@

         LOG.error(msg, msg_args)

 

     @staticmethod

-    def _get_neutron_events_for_live_migration(instance):

+    def _get_neutron_events_for_live_migration(instance, migration):

         # We don't generate events if CONF.vif_plugging_timeout=0

         # meaning that the operator disabled using them.

-        if CONF.vif_plugging_timeout and utils.is_neutron():

-            return [('network-vif-plugged', vif['id'])

-                    for vif in instance.get_network_info()]

+        if CONF.vif_plugging_timeout:

+            return (instance.get_network_info()

+                    .get_live_migration_plug_time_events())

         else:

             return []

 

@@ -6695,7 +6695,8 @@

             '''

             pass

 

-        events = self._get_neutron_events_for_live_migration(instance)

+        events = self._get_neutron_events_for_live_migration(

+            instance, migration)

         try:

             if ('block_migration' in migrate_data and

                     migrate_data.block_migration):

B1.7

--- nova-bak/network/model.py        2022-08-02 16:27:47.490437859 +0800

+++ nova/network/model.py     2021-09-03 09:35:24.532858440 +0800

@@ -469,6 +469,14 @@

         return (self.is_hybrid_plug_enabled() and not

                 migration.is_same_host())

 

+    @property

+    def has_live_migration_plug_time_event(self):

+        '''Returns whether this VIF's network-vif-plugged external event will

+        be sent by Neutron at 'plugtime' - in other words, as soon as neutron

+        completes configuring the network backend.

+        '''

+        return self.is_hybrid_plug_enabled()

+

     def is_hybrid_plug_enabled(self):

         return self['details'].get(VIF_DETAILS_OVS_HYBRID_PLUG, False)

 

@@ -527,20 +535,26 @@

         return jsonutils.dumps(self)

 

     def get_bind_time_events(self, migration):

-        '''Returns whether any of our VIFs have 'bind-time' events. See

-        has_bind_time_event() docstring for more details.

+        '''Returns a list of external events for any VIFs that have

+        'bind-time' events during cold migration.

         '''

         return [('network-vif-plugged', vif['id'])

                 for vif in self if vif.has_bind_time_event(migration)]

 

+    def get_live_migration_plug_time_events(self):

+        '''Returns a list of external events for any VIFs that have

+        'plug-time' events during live migration.

+        '''

+        return [('network-vif-plugged', vif['id'])

+                for vif in self if vif.has_live_migration_plug_time_event]

+

     def get_plug_time_events(self, migration):

-        '''Complementary to get_bind_time_events(), any event that does not

-        fall in that category is a plug-time event.

+        '''Returns a list of external events for any VIFs that have

+        'plug-time' events during cold migration.

         '''

         return [('network-vif-plugged', vif['id'])

                 for vif in self if not vif.has_bind_time_event(migration)]

 

-

 class NetworkInfoAsyncWrapper(NetworkInfo):

     '''Wrapper around NetworkInfo that allows retrieving NetworkInfo

     in an async manner.

C1.1

--- linux-3.10.0-1062.18.1.el7.orig/net/ipv4/udp_offload.c     2020-02-12 21:45:22.000000000 +0800

+++ linux-3.10.0-1062.18.1.el7/net/ipv4/udp_offload.c   2022-08-17 15:56:27.540557289 +0800

@@ -261,7 +261,7 @@ struct sk_buff **udp_gro_receive(struct

      struct sock *sk;

 

      if (NAPI_GRO_CB(skb)->encap_mark ||

-         (skb->ip_summed != CHECKSUM_PARTIAL &&

+         (uh->check && skb->ip_summed != CHECKSUM_PARTIAL &&

           NAPI_GRO_CB(skb)->csum_cnt == 0 &&

           !NAPI_GRO_CB(skb)->csum_valid))

             goto out;

 

分享到:

返回列表
北京集特智能科技有限公司 All Copy Right 2005-2010@ 2015 All rights reserved. 備案號:京ICP備20018443號-1 后臺管理
在線咨詢
91热99| 中文字幕第2页不卡| 日日干夜夜操视频| 日本女人喷水| 色哺乳xxxxxhd| 小芳爸爸全文阅读下载| 亚洲欧美视频一区| 男男抽搐高潮呻吟avgaytv| 嫩模杨晨晨性色av| 免费性生活大片| 女生羞羞网站| 高辣h文乱乳h文hhh教官| 校花和老教授肉嗯h| 亚洲产国偷v产偷v自拍小说| 哭着浣肠h排泄抱着| 浪荡超短裙长腿教师h| 欧美男男gaygay巨大粗小说| 4747520视频| 麻豆传媒在线观看| 欧美日韩草逼| 女绳奴被紧缚调教影视| 日韩美女伦理| 女同啊灬啊用力灬嗯灬gl小说| 国内精品福利| 黄色片a级片| 拔萝卜视频免费看| 国产调教在线播放| 日韩一级一片| 太深了办公室裙揉捏| 国语对白做爰xxxⅹ性69视频| 离婚后我带女儿走向人生巅峰大结局| 少妇又爽又黄又色| 黑人爱爱视频| 双腿绑在调教台上调教h| 久久精品九九精av| 天天干天天爱天天射| 中文字幕2020| 激情网址在线观看| 国产女s调教男m免费网站| 鲤鱼乡bl好大进不去| 谍战剧《惊弦》在线观看免费高清| porno+hd+777| 免费看美女被靠到爽的视频| 日本残虐sm一区二区三区| 男生和女生操软件| 午夜精品久久一牛影视| xxxxx睡觉性xxxx| 飞魔幻小说| gogogo高清在线播放免费观看如果奔跑是| 阿sa做爰床戏呻吟免费| 快快啊用力添别停| 免费看美女被靠到爽的视频| 亚洲黄页| 比基尼派对电影完整版在线观看| 国产精品久久久久久婷婷动漫| 动漫同人高h啪啪爽文| 啊用力嗯轻一点小柔| 葬礼揸fit人| 张津瑜吕知樾视频| 亚洲精品久久久蜜臀下载官网| 久久久久久久久久久久久久久| 古代闺房调教h揉公玉玥| 亚洲h动漫| 黑人非洲大屁bdxxxxx| www.xvideos.com| а√8天堂中文官网资源| 中文字幕第2页不卡| 肉耽快穿文h快穿宿主受| 欧美激情性做爰免费视频| 乱lun合集之交换| 风骚小保姆(高h)| 黑人教练与娇妻h系列最新章节| 秘书激情办公室在线观看| 片山萌美有几部r级| 古代闺房调教h揉公玉玥| 无码中文av有码中文av| 久久爱黑人激情av摘花| 少妇巨大乳挤奶水免费| 亚洲 欧美 综合 另类 中字| 久久久久久黄色片| 亚洲小视频在线| 《性/生活》未删减版电影| 小受夹震蛋玩到失禁play| 亚洲青涩| 一区二区三区午夜视频| 我想看免费的毛片| 国产精品视频123| 宝贝腿张大点就不疼了男女| 黄淑珍| 国产精品中文| 无内裤全透明柔术视频| 钶钶钶钶钶钶钶免费下载在线观看| 嗯用力别停受不了h| 欧美写真视频一区| 国产自产才c区| chinese妇色videos| 在教室轮流澡到高潮h| 高潮激烈的呻吟声视频| 绑在公厕让男人来c你| 刑警娇妻h全肉禁乱免费| 调教(高h,1v1校园| 亚洲青涩| 91色琪琪电影亚洲精品久久| 91色琪琪电影亚洲精品久久| 天美星空mv高清免费| 女女女女女女女hd在线看| 少妇一级淫片aaaaaaaaa| 国产v日产∨综合v精品视频| 国产人久久人人人人爽按摩| 国产剧情av巨作| 性高湖久久久久久久久免费| 骚虎网| 午夜激情免费看| 一男一女曰批| 女女女女女女女hd在线看| 大尺度人体私拍国模| 国产亚洲成aⅴ人片在线观看麻豆| 女攻男受调教爽哭n四爱| 亚洲第一天堂在线观看| 天堂√8| 国产福利片在线| 都市激情自拍偷拍| 动漫xxxxxxxxx| 国产精品剧情一区二区在线观看| 蜜桃成人在线视频| 亚洲男女啪啪| 免费看足疗店按摩毛片| gogogo高清在线播放免费观看如果奔跑是| 2009年美版线人| 嘘魏承泽笔趣阁无弹窗最新章节| 三级网站久久| 欧美色性视频| 用力挺进新婚白嫩少妇| 温柔陷阱 不止是颗菜| 我和丰满老女人性销魂| 道道道电影国语版免费观看1080| 陈圆圆裸体一级无删减| 嗯 啊 快点 还要 爽| 九色国产在线观看| 女s羞辱女m视频ⅴk| 九九热精品视频在线| 欧美天天干| 啊轻点灬大粗嗯太深了| bnb免费电影| 亚洲视频在线观看| 小受夹震蛋玩到失禁play| 中文在线一区二区三区| 女女女女女女女hd在线看| 极品名器天生奶水1v1高h| 欧美色xxx| 久久久久一区二区三区四区| 男人躁女人过程无遮挡网站| free色老太bbw性hd| 小sao货cao的你舒服吗视频| 日韩在线观看网址| 双性精跪趴灌满h室友4p| 无内裤全透明柔术视频| free性暴力vⅰdeos糟蹋| 日韩免费精品| 娇妻尝试两根一起进3p视频| 日韩有码网站| 欧美激情性做爰免费视频| 日本黄色性片| 韩国free性video极品| 日韩亚洲在线视频| 我和丰满老女人性销魂| 女仆乖乖掀裙子让主人玩小说| 九九热精品视频在线| 欧美肥妇b| 校花张开腿让我c| 欧美13一16sexvideos| 色噜噜综合网| 国产人久久人人人人爽按摩| 欧美色图校园春色| 91精品无人区麻豆| 抱着娇小稚嫩小身体做h阅读| 睫毛膏4电影| 大尺度人体私拍国模| 国产视频一区二区在线播放| 黄黄网站在线观看| 亚洲精品播放| 国产日韩在线免费观看| 成人毛片在线观看| 大j8黑人征服绿帽| 黑人教练与娇妻h系列最新章节| 女尊女攻高h巨辣h文| 韩国在线一区| 不用播放器看的av| 好姑娘韩剧8全集免费高清观看| 欧美日韩亚洲系列| 男人扒开女人桶到爽中国的人| 靠比漫画| 国产精品久久福利| 亚洲自拍色| 宝贝你好骚| 一级毛片免费试看| 国产成人高清| 男男激情网站| 国产无套一区二区三区久久| 秘书激情办公室在线观看| videossex性糟蹋月经| 中文在线一区二区三区| 高潮激烈的呻吟声视频| 女人下面肥肥的好吗| 坐在男人嘴上让他添汁水横流| 99热久草| 亚洲高清乱码午夜电影网| 小婕子的第一次太紧了r电| 织田真子在线视频| 欧美性生交大片免费视频| 欧美激情999| 快穿妲己高h荡肉呻吟np| 便器调教(肉体狂乱)高h文| 操奶子视频| 男人插女人动态视频| 好姑娘完整版在线观看免费高清| 亚洲欧美视频一区| 日本xxx68hd老师| 少妇系列欲海娇妻| 色妞视频| 福利视频不卡| 日日夜夜免费精品视频| 亚洲精品久久久蜜桃动漫| 天堂社区在线观看| 亚洲最新在线观看| 一级毛片免费试看| 快穿np双性被各种男人啪h| 古代闺房调教h揉公玉玥| 学园痴女姐姐| 老鸭窝网站| 亚洲二页| h视频网站在线观看| 啊灬啊灬啊灬啊灬高潮了在线| 又大又黄又粗| 少妇巨大乳挤奶水免费| 国产又大又猛又爽又黄的视频| 和闺蜜互换老会睡高h| 神马在线午夜理伦片免费观看| 双乳被一左一右吃着的丫鬟文| 斗破斗罗大合集| 中文在线一区二区三区| 砼和混凝土的区别| 亚洲人毛耸耸少妇xxx| 道道道电影国语版免费观看1080| 亚洲男人天堂av在线| 少妇又紧又粗又爽的视频| 麻豆传媒在线观看| 成年人性生活免费看| 青青青爽久久午夜综合久久午夜| 极品粉嫩国产48尤物在线播放| 扒开我的腿用黄瓜折磨我渺渺| 99热国产在线观看| 警花系列乱肉辣文小说| sq调教室虐调教h打开腿玩具| 外国一级黄色| 偷拍视频一区二区| 午夜91| 都市激情自拍偷拍| 国产激情一区| 蜜桃视频在线观看免费视频| 啊灬啊灬啊灬啊灬高潮了在线| 欧美一级黄色大片| 乳色吐息动漫| 国产精品农村妇女bbw| 亚洲成人午夜av| 嫩模杨晨晨性色av| 一级日本片| av簧片在线观看| 女学生 打屁股 鞭打 网站| 国产调教在线播放| 娇妻在领导粗大胯下呻视频| 视频黄页在线观看| 动漫美女羞羞视频网站| hitomi超乳田中瞳一区二区| 双男黄色小说| 嗯啊别揉了高潮了h| 《朋友夫妇交换》3| 免费观看全黄做爰大片美国电影| 羞羞视频入口| free hd 农民工 xxxx中国| av网站资源| 男女插插小说| 边做边流奶水少妇| 黄色av网站免费观看| 女女高h黄车gl| 国产亚洲成aⅴ人片在线观看麻豆| 赵刚林风苏柔小说免费阅读全文下载| 日韩色高清| 女生张开腿男生捅| 高辣h文乱乳h文浪荡校花小说| 公主被两个师傅调教的小说| 超碰爱| 快穿np双性被各种男人啪h| 潘金莲丰满大乳人体欣赏| 小舞的玉足伸进我的裆部| 91免费污| 岳的乱系列50部分| 国产456| 国产精品久久久亚洲一区| 国产精品女同磨豆腐磨出水了| 韩国电影三级强睡女老板| 国产一区二区三区四区五区密私| 国产成人影院在线观看| 亚洲 小说区 图片区| 亚洲一区二区 在线| 娇妻在领导粗大胯下呻视频| 久草精品视频在线播放| 一道本伊人| 婷婷丁香综合| 另类绿帽羞辱调教| 成年人的天堂| 娇妻玩4p被3个男子伺候的简介| 羞辱拘束放置调教小说视频| 另类月经大全系列| 双性精跪趴灌满h室友4p| 免费少妇荡乳情欲视频的软件| 国产东北对白精品久久不能平复| 韩国理伦三级做爰在线| 成年人三级网站| 娇妻玩4p被3个男子伺候的简介| 夜夜综合网| 动漫美女羞羞视频网站| 最新日韩av| 500短篇又肉又黄合集| 美女裸胸照片| 俄罗斯三级做爰视频| 主人~别揉了~尿了~啊哈装满了| 免费看黄色视屏| 黄色污在线观看| 国产精品v欧美精品v日韩| 好吊妞午夜免费视频| 国产男女猛烈无遮挡| 坐在男人嘴上让他添汁水横流| 99久久99久久免费精品蜜臀| 不让穿乳罩随时揉h护士| 色五月视频| 亚洲啊啊啊啊啊| 隔壁主妇欲求不满 日本| 国产亚洲欧美精品永久| 男男抽搐高潮呻吟avgaytv| 3 d试机号码开机号码| 国产又黄又粗视频| 美女被艹在线观看| 触手 侵犯 调教 无尽| 女人脱了内裤露出屁股打| 强制憋尿play黄文尿奴| 亚洲欧美日韩图片| 少妇偷乱公400| 免费激情视频在线观看| 一区二区中文字幕日本韩国| 美丽姑娘电视剧免费高清观看| 余罪第一季24集完整版| 内裤奇缘-正文畸情~13| 国产区av| 一级做a爰片性色毛片视频停止| 小孩包皮是怎么样的图片| 每晚都被他添的喷水| av簧片在线观看| 张津瑜国内精品www在线| 张津瑜国内精品www在线| 农村艳妇疯狂做爰肥水不流外田| 久久精品人人做人人综合老师| 大坤巴塞嘴里| 勾人引诱(高h)| 91精品啪在线观看国产商店| 顾时夜肉多荤文高h| 夜晚天天看视频| 女尊女攻高h巨辣h文| 2021毛片| 性高湖久久久久久久久免费| 亚洲自拍一| 有没有免费的黄色网址| 亚洲乱码在线| 色碰碰| 欧美一区二区三区国产| 国产成人高清| 被强行侵犯高h| 绫川ふみ授乳奶水| 欧美猛交xxx| 啊~嗯~我下水好多水小说| 影音先锋久草在线| 免费在线观看成人网| 2009年美版线人| 国产福利高清在线| 天赐的声音第五季免费观看完整版| av网站免费在线播放| 男人用嘴添女人私密视频| 国产女s调教男m免费网站| 特黄特色片| 张津瑜国内精品www在线| 双腿绑在调教台上调教h| 99re66热这里只有精品3直播| 男男抽搐高潮呻吟avgaytv| 乳峰高耸玉腿丰腴小说| 日韩成人毛片在线| 一区二区三区三区| 乳色吐息1一2集无删减| 国产盗摄xxxx视频xxxx| 浪荡超短裙长腿教师h| 中文字幕在线视频不卡| 中文字幕在线观看电视剧的网站| 俄罗斯三级做爰视频| 亚洲精品视频免费在线| 少妇网站在线观看| 成年人的天堂| 公主被两个师傅调教的小说| 波多野毛片| 日日躁夜躁aaaaxxxx| 原声舌吻呻吟声| 教练c我好爽1v1h文| 欧美裸体tickling免费| 老鸭窝网站| 国产精品呻吟| 国产福利啪啪| 日本护士撒尿mmm视频| 高h文1v1| 一区二区三区三区| 小舞的玉足伸进我的裆部| 高潮h玩具play失禁调教小说| 男男公厕np壮汉受高h| 女女同性一区二区三区免费观看| 嘘魏承泽笔趣阁无弹窗最新章节| 少妇巨大乳挤奶水免费| 国产青草视频| 影院一区二区三区| 视频黄页在线观看| 日本特黄特色大片免费老年人高潮| 少妇一夜爽免费看| 成年大片| 国产又大又猛又爽又黄的视频| 日韩激情视频在线播放| 欧州一区二区三区| 解开她的扣子伸进她的胸罩| 抱着娇妻让粗黑人人玩3p| www.欧美色图.com| 特片网久久| 国产一级毛片潘金莲| 男人用嘴添女人私密视频| 国产欧美精品va在线观看| 国产青草视频| 太深了办公室裙揉捏| 少妇按摩做爰2免费观看| 杨过胯下黄蓉雪臀耸动娇喘| 宣宣电影网站| 亚洲情图| 泽村玲子在线中文字幕| 女s羞辱女m视频ⅴk| dasd521—黑人寄宿ntr| 男淦女| 公交强行挺进她h嗯啊漫画| 日本护士做爰视频| 我爱av网| 三上悠亚作品在线观看| 福利视频不卡| 日本一二三区电影| 东宫禁脔(h调教)随我心| 双性老师的丰满大乳奶水小说章节| a中文字幕| 不忠大尺度做爰未删减版观看| 成人动态| 一本到在线| 天堂素人在线| 强h辣文肉各种姿势h| 长泽梓在线视频| 互换娇妻爽文100系列视频| 国产又粗又硬又爽又黄的视频| 超能一家人电影免费喜剧电影在线观看| 亚洲精品国产精品乱码| 色域在线| 国产成人亚洲欧洲在线观看| y111111国产精品久久婷婷| 好男人视频在线观看| 蜜汁网站| 天赐的声音第五季免费观看完整版| 狄仁杰之飞头罗刹 电影| 国产片成人动作片| 美国一级簧片| 午夜免费男女高潮啪啪| 荡公乱妇中文字幕hd| 高潮丨vk全部脱| 日本巨乳女优排名| 久久国产精品免费专区| 强q瑜伽课被cao哭高h| 激情欧美一区二区三区免费看| 爱情综合症小说| www.madouav.com| 星辰视频免费高清在线观看动漫| 皇帝狠狠进入太子h双性| 性生活黄色一级片| 美女图片大全免费观看| 日日躁夜躁aaaaxxxx| 扒开双腿猛进入赵丽颖| 挨c的女侠全文阅读| 日本r级电影在线播放| 美国禁片4级| 久久社区视频| 魔鬼女大兵国语版| 91色琪琪电影亚洲精品久久| 欧美男男gaygay巨大粗小说| 欧美日韩一区二区三区四区五区六区| 日日夜精品欧洲日日噜噜| 久久天天综合| 午夜在线观看福利| 长泽梓在线视频| 91色琪琪电影亚洲精品久久| 午夜久久久久久久久久一区二区| 男女尻逼小说| 亚洲图片 小说 欧美 激情| 性瘾折磨憋尿高辣np高h男男| 农村艳妇疯狂做爰肥水不流外田| 丰满女人又大又爽又丰满| 热の综合热の国产| 综合网国产| 777一区二区三区| 疯狂欧美牲乱大交777| 在线观看的av网址| 91九色国产蝌蚪| 强制中出し~大桥未久4| 神马在线午夜理伦片免费观看| feet9job恋足| 亚洲小视频在线| 欧美性生交大片免费视频| 国产69精品一区二区亚洲孕妇| 性折磨bdsm欧美激烈另类| 欧美操片在线观看| 国产精品一区饥渴老女人| 噼里啪啦在线| 4个大学生按摩做爰按摩| 性xxxx17学生老师hd| 欧美人与禽zoz0善交视频| 少妇巨大乳挤奶水免费| ipx系列| 19p亚洲| 全黄h全肉禁乱同性| а√8天堂中文官网资源| 朱大海与秀华媳妇朱晓军| 欧美成人性做爰男人添l| 大坤巴塞嘴里| 王多鱼在线观看全程免费| 91久久蜜臀精品的社区功能| 青楼的特殊调教h男宠| 国产69精品一区二区亚洲孕妇| 欧美一级视频免费| 立花里子美腿女教师av在线| 又粗又猛又爽又黄| 好吊视频一区二区三| 快穿妲己高h荡肉呻吟np| 欧美极品少妇xxxx亚洲精品| 女攻男受爽到失禁h文| 强q瑜伽课被cao哭高h| 高h刺激短篇合集3p| 小妖精好紧好爽再浪一点| 快快啊用力添别停| xxxxx睡觉性xxxx| 高潮h玩具play失禁调教小说| 天天操夜夜夜操| 精品国产乱码久久久久久软件影片| 女同啊灬啊用力灬嗯灬gl小说| 当你沉睡时韩剧免费观看完整版| 日本人吃胸玩乳30分钟| 性瘾折磨憋尿高辣np高h男男| 精品国产欧美一区二区| 91freepron高潮合集| 第80章教室激情| 少妇荡乳情欲办公室麻豆av| 三国污文全文肉高h后宫| bnb免费电影| 后进极品美女圆润翘臀视频| 久久精品免费观看| 触手 侵犯 调教 无尽| 伊人天堂av| 高圆圆的特级毛片| 一区二区三区三区| 日日夜精品欧洲日日噜噜| 韩国理伦三级做爰在线| 都市激情刺激肉伦小说| 活着就是恶心| 国产在线观看| 日本xxx68hd老师| 少妇和小伙子舌吻| 司机调教贱奴总裁bl| 大学生初尝滋味电影| 美丽姑娘电视剧免费高清观看| 久热精品国产| 美女下部隐私无遮内裤| 农村女人的一级毛片| 捆绑c黑袜军警gay视频| 国产片成人动作片| 中文在线一区二区三区| 健身房被下媚药玩到高潮小说| 电视剧:一级黄色片| 黄色软件直接看| 男性性器被各种虐玩sm| 婚礼被惩罚调教高h| 娇妻梦颖| 五月 婷婷| 不忠大尺度做爰未删减版观看| 国产极品白嫩| 又粗又猛又爽又黄| 男女看片黄全部免费| 日本亲与子乱ay中文| 哦┅┅快┅┅用力啊┅少妇奶水| 三上悠亚338中文在线观看| 久久超碰精品| 亚洲国产精品影院| 小受夹震蛋玩到失禁play| 娇妻尝试两根一起进3p视频| 少妇被技师按摩高潮在线观看| 在线天堂亚洲| 用力哦我要喷了| 欧美999| 国产最新永久地址发布页| 六月婷婷综合| 男性性器被各种虐玩sm| 国产女s调教男m免费网站| 色999国产精品| 少妇一级淫片aaaaaaaaa| 古代性色禁片在线播放| 国产精品第56页| 黄色三级电影在线观看| 97av在线| 色噜噜综合网| 校花和老教授肉嗯h| 樱桃视频h| 少妇做爰免费视频播放| 色爱综合网欧美| 91色琪琪电影亚洲精品久久| 乡下邻居寡妇教我做爰电影| 殴美一级毛片| 快穿之胸大喂奶h更新时间| 亚洲人成人7777在线播放| 国产精品伦理久久久久久| 91久久久久久亚洲精品禁果| 一区二区中文字幕日本韩国| 揉我胸啊嗯~出水了电影| 漂亮妈妈电视剧全集| aaa级吃奶摸下免费视频| 少妇愉情理伦片法国4级| 尤物99av写真在线| 黄色片a级片| 日韩在线观看网址| 《性呻吟》电影在线观看| 又粗又猛又爽又黄| 十四女胸发育裸体欣赏| 欧美色xxx| 丰满女人又大又爽又丰满| 朝桐光视频在线观看| 国产精品永久免费自在线观看| 青楼的特殊调教h男宠| 里莱的穴| 在线中文字幕一区二区| 护士裸体献身取精| 国产精品视频观看| 国产区av| 宝贝乖~张开腿我轻点高视频| 亚洲国产播放| 成人久久久久| 太深了办公室裙揉捏| 男人天堂手机在线视频| 午夜久久久久久久久久一区二区| 日本欧美色图| 叶玉卿早期三点裸乳照| 中文日韩欧美| 小芳爸爸全文阅读下载| 快穿妲己高h荡肉呻吟np| 亚洲精品久久久蜜桃动漫| 名器紧致h拔不出来| 又大又黄又粗| 《忠贞2022》电影完整版| 想被男人操| 黄色污在线观看| 香蕉国产999| 女人精69xxxⅹxx视频| 美女图片大全免费观看| www.欧美激情| 印度一级黄色录像| 俺去久久| 精品一区二区三区网站| 乡村女教师乱淫交片| 偷偷久久| 啊~嗯~我下水好多水小说| 啊灬啊灬啊灬啊灬高潮了在线| 别太深肚子里有孩子| 一级淫片试看120分钟| 早川濑里奈av片在线观看| 女人十八毛片水真多| 艾秋老大的处罚md0103| 秘书激情办公室在线观看| 亚州综合| 温柔陷阱 不止是颗菜| 二级特黄绝大片免费视频大片| 国产gay男男gaygaygv网站| 亚洲xxxb撒尿| 一区二区三区午夜视频| 古代闺房调教h揉公玉玥| 免费看美女被靠到爽的视频| 偷拍女厕厕露p撒尿八个少| 无遮无挡动态图| 密桃av| 佐山爱av作品| 北条麻妃影音先锋| 中文黄色字幕| 欧美性电影在线观看| 强行撕衣强行糟蹋三级香港| 欧美精品国产| 黄色污在线观看| 快穿np双性被各种男人啪h| 青青青爽久久午夜综合久久午夜| 金鳞岂是池全文无删减txt下载| 色哺乳xxxxxhd| 久久精品色视频| 深夜十八款禁止视频app| 我和娇妻小黄三人行| 男男抽搐高潮呻吟avgaytv| 国产精品右手影院| 扒开双腿猛进入赵丽颖| 夜夜操导航| 啊轻点灬太粗嗯一路向阳| 全黄h全肉禁乱同性| 看久久毛片| 亚洲国产欧美一区二区三区丁香婷| 葬礼揸fit人| 被壮汉肉晕了h| 啊啊啊啊啊啊高h| 男人天堂手机在线视频| 中文字幕二区在线| 性折磨bdsm欧美激烈另类| 亚洲狼人精品一区二区三区| 狠狠色丁香久久一区| 公交车上被强入| 天天操天天天| 韩日视频一区二区| 女生扒开尿口让男生捅爽| 男性性器被各种虐玩sm| 双性精跪趴灌满h室友4p| 夜晚天天看视频| 双男黄色小说| 中文字幕第一区| 漂亮姑娘视频在线观看免费高清版电视剧| 我和三个男人玩4p故事| 耽美高h肉文| 交h调教粉嫩h文医生| 国产亚洲欧美精品永久| 精品国产一级蜜臀久久免费软件| 亚洲国产一区二| 夜夜综合网| 男男gaygays亚洲男同| 色狠狠一区二区三区香蕉| 欧美一级黄色大片| 当你沉睡时韩剧免费观看完整版| 双性老师的丰满大乳奶水小说章节| 久久超碰精品| 中文字幕第2页不卡| 男女18免费网站视频| 极品粉嫩国产48尤物在线播放| av片一区二区三区| 国产女s调教男m免费网站| 清冷双性美人短篇合集| 变态教授的调教h| 女警察高清一级毛片国产| 被老板抱进办公室揉我胸视频| 五月婷婷俺也去| 成人黄色电影视频| 91密桃| 俺来也俺也啪www桃花岛色| 夜晚天天看视频| 变态教授的调教h| xxx在线免费观看| 国产三级精品三级在线观看四季网| 在人间女主采薇小说免费阅读| 国产激情一区| 我被迫穿白丝女仆接受调教| 我被迫穿白丝女仆接受调教| 又黄又湿又爽| 国产精品伦理久久久久久| 美女下部隐私无遮内裤| 甜蜜之家狗儿和娘全文免费阅读| 一区二区中文字幕日本韩国| 娇妻借种的呻吟1~29小说全文| 国产v日产∨综合v精品视频| 久久免费看少妇高清激情| 女女之间**vk| 健身房教练c弄我了什么后果| 国产最新永久地址发布页| 手慢慢伸进内裤里揉搓| 女生张开腿男生捅| 女女同性一区二区三区免费观看| 青青手机在线视频| 男人扒开女人桶到爽中国的人| 国产成人看片| 对白刺激国语子与伦| 国产性猛交96| 看黄色录象| 激情久久一区| 国产又大又猛又爽又黄的视频| 国产成人高清| a级毛片蜜桃成熟时2在线播放| videossex性糟蹋月经| 人人天天色| japenese国产打屁股实践| 比基尼派对电影完整版在线观看| 兽皇系列av在线| 国产成人午夜高潮毛片| 深夜十八款禁止视频app| 欧美黄色片在线| 娇柔娇喘1v1| tickling中国美女—vk| 情趣用品试用员| 女s羞辱女m视频ⅴk| 高h办公室肉辣秘书hnp| 天堂av在线中文在线| bnb免费电影| 91色琪琪电影亚洲精品久久| h视频网站在线观看| 紧缚女社长被调教成奴| 朝桐光视频在线观看| 被公侵犯中文字幕| 密桃av| 强制憋尿play黄文尿奴| 天天躁夜夜躁天干天干2022| 女人下面肥肥的好吗| 吴家丽三级裸体| 老湿机69福利视频在线观看| 男女尻逼小说| 一本中文字幕| 国产亚洲婷婷| 日日夜夜免费精品视频| 中文字幕在线视频不卡| 国产麻豆精品传媒av国产下载| 快穿娱乐圈名器取液h| 帅哥和美女打扑克| 国产女s调教男m免费网站| 《忠贞2022》电影完整版| 我被迫穿白丝女仆接受调教| 白妇少洁第19章欲海浮沉下| 公交强行挺进她h嗯啊漫画| 国产一区二区三区四区五区密私| 第80章教室激情| 和两个男人玩3p真舒服| 嗯~啊~快点闺蜜和我| 欧美黄色片在线| 亚洲乱码国产乱码精品精竹爆| 日本特黄特色大片免费老年人高潮| 亚洲图片 小说 欧美 激情| 高清一级黄色片| 公主调教侍女百合h| 在线观看的av网址| 隔壁主妇欲求不满 日本| 海角社区乱90精品| 龙攻两根×人类受h| 二区三区在线观看| 上课呢别进去摸好舒服同桌| 女人精69xxxⅹxx视频| 久久久亚洲精品石原莉奈| 靠比漫画| 狠狠色丁香久久一区| 苏杏和国防四大校草小说苏家有女第15章| 阿娇张开双腿冠希13分钟| 老扒和三个儿媳妇| 将军含紧一点h边做边走视频| 久久久亚洲精品石原莉奈| 国产欧美精品va在线观看| 三级a在线观看| 黄色免费日本| 亚洲最新在线观看| 被强行侵犯高h| 女生扒开尿口让男生捅爽| 顾时夜肉多荤文高h| 天天干天天操天天舔| 国产精品中文| 精品少妇的一区二区三区四区| 免费在线黄色av| 互换娇妻的呻吟声越来越大| 紧缚女社长被调教成奴| 日韩一级一片| 国产又爽又黄网站| 久久精品三| 色爱综合网欧美| chinese性旺盛的老妇| 被迫戴上情趣玩具高h1v1| 日韩第五页| 欧美男男gaygay巨大粗小说| 热の综合热の国产| 亚洲欧美日韩综合网| 国产精品免费视频网站| 国产片成人动作片| 精品区在线观看| 亚洲第一色片| 国产片成人动作片| 一级电影免费在线观看| 欧美成人日韩| 夫妻日b视频| 边做边流奶水少妇| 欧美裸体tickling免费| 三级视频国产| 啊啊啊啊啊啊高h| 日韩美女伦理| 艹丝袜| 草逼欧美| 风间由美三级电影| 谍战剧《惊弦》在线观看| 狄仁杰之飞头罗刹 电影| 欧美成人性做爰男人添l| 噼里啪啦免费高清视频| 天天干天天操天天舔| 李兵沈思正值十月天气笔趣阁| 青青青爽久久午夜综合久久午夜| 亚洲国际精品久久久久婷婷老年p| 亚洲成色www.777999| 千金s被当做m调教的小说| 互换娇妻爽文100系列视频| 调教(高h,1v1,粗口调教)文| 情趣店被粗暴h| 同性疯狂做爰小说| 精品国产乱码久久久久久88av| 张津瑜吕知樾视频| 和闺蜜互换老会睡高h| 日韩福利视频在线观看| 海角社区乱90精品| 久草影音| 健身房被下媚药玩到高潮小说| 国产精品美女高潮无套久久| 狠狠色丁香久久一区| 国产精品女同磨豆腐磨出水了| 成人一级黄色| 国产日韩在线免费观看| 裸体bbb大全| 男人天堂手机在线视频| 都市激情自拍偷拍| 红猫大本营点击在线观看的| 古代闺房调教h揉公玉玥| 亚洲一区二区三区毛片| 阮梅被狂揉下部羞羞漫画| 在线一区二区三区四区| 快穿之胸大喂奶h更新时间| 小受夹震蛋玩到失禁play| 人一性一交一欲一色一情一伦| 动漫同人高h啪啪爽文| free性暴力vⅰdeos糟蹋| 边做边流奶水少妇| 百合短篇合集(高h,扶她)| 色999国产精品| 无人区在线观看免费观看完整版高清电视剧| 午夜久久久久久久久久一区二区| 勾人引诱(高h)| 动漫裸体啪啪h| 公交强行挺进她h嗯啊漫画| 健身房教练c弄我了什么后果| 当你沉睡时韩剧免费观看完整版| 九色电影| 古代性色禁片在线播放| 中文字幕2020| 精品区在线观看| 精品国产黄色片| 离婚后我带女儿走向人生巅峰大结局| 六月婷婷综合| 高h办公室肉辣秘书hnp| 皇上撞着太子妃的深处暮暮| 温柔陷阱 不止是颗菜| 亚洲国际精品久久久久婷婷老年p| 亚洲一区二区三区毛片| 体育生被强到爽哭高h| 欧美人与禽zoz0善交视频| 立花里子美腿女教师av在线| www.sao66| 女人被迫戴上乳环跪着叫主人| 国产一区二区三区四区五区密私| 成年人性生活免费看| 男男激情网站| 高潮激烈的呻吟声视频| 国产边打电话边做对白刺激| 精品少妇一二三区| 三级黄色生活片| 女攻男受爽到失禁h文| 3 d试机号码开机号码| 色狠狠一区二区三区香蕉| 欧美孕妇孕交xxⅹ孕妇交| 国产福利啪啪| 扒开腿挺进湿润的花苞h| free hd 农民工 xxxx中国| 欧美成人精品高清视频在线观看| 亚洲人网| 看羞羞视频免费| 女生扒开尿口让男生捅爽| 相泽南番号大全| 赵刚林风苏柔小说免费阅读全文下载| 风骚小保姆(高h)| 三上悠亚338中文在线观看| 亚洲无线视频| 成人av网站在线| 91啪国自产| 亚洲自拍色| 性开放永久免费视频| 五月婷综合| 尤物99av写真在线| 秋霞午夜片| 激情久久一区| 91蝌蚪色| 国模私拍丝袜成人福利| 91视频安卓版| 成人毛片在线观看| 受被卖给攻当禁脔调教| 激情五月在线| 透逼软件| 午夜一级黄色片| 成人三级a做爰视频哪里看| 色域在线| 免费看美女被靠到爽的视频| 日本乱欲| 欧美日韩亚洲系列| 成人午夜激情av| 国产欧美一区二区精品老汉影院| 精品国产欧美一区二区| 原神18av黄漫网站神里绫华| 男人躁女人过程无遮挡网站| 日本人xxxxxx免费泡妞| 少妇按摩做爰2免费观看| 野外被三个男人躁一夜漫画| 高官交换性伴侣小说| 顺丰快递电话号码附近| 隔壁主妇欲求不满 日本| 日本高h视频| 欧美又大又硬又粗bbbbb影院| 国产日韩在线免费观看| av手机看片| xxxooo极品高清hd| 欧美俄猛男同志男男巨大做爰| 慈禧秘密生活电影| 亚洲电影免费| 韩剧大尺度床戏做爰吻胸| 国产乱子经典视频在线观看| 美女扣逼逼| 日本黄色播放器| freexxⅹ性中国hd露脸| 人一性一交一欲一色一情一伦| free hd xxxx moviesles| 区一区二在线| 秀婷| 拔萝卜视频免费看高清| 在教室轮流澡到高潮h| dasd521—黑人寄宿ntr| 调教明星为肉奴小说| 校霸撅着屁股被学霸c烂h| 99re这里只有精品首页| 啊轻点灬太粗嗯一路向阳| 天堂√中文在线| 娇妻玩4p被3个男子伺候的简介| 贾平凹 暂坐免费阅读| 久久久一二区| 男人天堂手机在线视频| 天堂社区在线观看| 中文字幕日韩亚洲| 醉地视频| 五月激情六月| 久久无精品国产99久久果冻传媒| 亚洲精品久久久蜜臀下载官网| 男人捅女人30分钟视频| 女人做爰高潮免费播放| 体育生被强到爽哭高h| 美女脱衣诱惑| av作品在线| 欧美黄色片在线| bestialitysex| 国产欧美一区二区精品老汉影院| 女尊榨精h男产乳| 醉地视频| 精品国产欧美一区二区| 国产91毛片| 中国女明星全光裸体无遮挡| a级毛片蜜桃成熟时2在线播放| 中文字幕2020| 美丽姑娘免费观看版电视剧| 皇上撞着太子妃的深处暮暮| 免费观看全黄做爰大片美国电影| 久久精品色视频| 午夜激情视频在线播放| 儿媳玥玥| 极品粉嫩国产48尤物在线播放| 相泽南番号大全| 热の综合热の国产| 国产亚洲成aⅴ人片在线观看麻豆| 男性性器被各种虐玩sm| 日本性高潮视频| 不忠大尺度做爰未删减版观看| 91精品无人区麻豆| 国产在线首页| 亚洲少妇喷水| 日本做受视频| 少妇网站在线观看| 朱大海与秀华媳妇朱晓军| 强行撕衣强行糟蹋三级香港| 偷拍视频一区二区| 韩剧大尺度床戏做爰吻胸| 国产最新网址| 欧美色图校园春色| 2024黄色片| 99热国产在线观看| 宝贝乖~张开腿我轻点高视频| 人人夜夜精品网| 亚洲国产高潮在线观看| 年轻的朋友在线观看完整版| 福利视频不卡| 黄色上床软件| 蜜桃成人在线视频| 国产91毛片| 我和三个男人玩4p故事| 91无限看次数破解版小孩| 福利小视频在线观看| 租借女友第3季免费观看动漫| 五月激情六月| 52avaⅴ我爱haose免费视频| 日韩成人av免费| 99re66热这里只有精品3直播| 韩国av片永久免费| 国模小丫大尺度啪啪人体| 同桌又粗又长好进去了舒服| 91九色国产蝌蚪| 千金被肉h高h| 2020av视频| 婚礼被惩罚调教高h| 天赐的声音第五季免费观看完整版| 黄色app网站在线观看| 国产ai换脸一区二区三区| 木下凛凛子亚洲一区二区| gogogo高清在线播放免费观看如果奔跑是| 青青青爽久久午夜综合久久午夜| 91视频国产区| 大妹子影视剧在线观看全集免费高清| 国产精品18久久久久久vr| 少妇一夜爽免费看| 日本黄色播放器| 江湖血泪录全文免费阅读小说| 捆绑c黑袜军警gay视频| 裸体bbb大全| 欧美一级视频免费| 再深点灬舒服灬再快点视频| 绑在公厕让男人来c你| 飞魔幻小说| 国产精品美女高潮无套久久| 久热精品国产| 娇妻玩4p被3个男子伺候的简介| 大尺度人体私拍国模| 国产亚洲成aⅴ人片在线观看麻豆| 高h文1v1| 赵勇苏媚小说全集目录| yy4080午夜| 女人叫床视频| 啊轻点灬大粗嗯太深了| 撕开校花奶罩揉她娇乳动漫| 性开放永久免费视频| 小妖精撅臀含着真紧h| 火车卧铺上摸双乳| 在教室轮流澡到高潮h| 亚洲无人区小视频| 涩涩涩网| 快穿娱乐圈名器取液h| 漂亮妈妈电视剧全集| 欧美黑人男男gay同性xx| 又亲下面又吃奶的口述| 一级电影免费在线观看| 2024黄色片| 久久国产精品免费专区| 免费在线播放黄色片| 激情网激情五月| 欧美a区| 公主被两个师傅调教的小说| 出轨黑人| 丝瓜视频无限| 国产a v一区二区三区| 国产男女猛烈无遮挡| 97成人精品视频在线观看| 91精品播放| 深夜十八款禁止视频app| 国产自产才c区| 年轻的朋友在线观看完整版| 顾时夜肉多荤文高h| 外出8分钟床戏未删减| 好大好硬好深好爽想3p要| 少妇3p小说| 日本韩国欧美中文字幕| **激情毛片九色一区| 嗯啊别揉了高潮了h| 国产a v一区二区三区| 我和岳疯狂做爰| free hd 农民工 xxxx中国| 国产亚洲婷婷| 被男人边做边狠狠打屁股| 伊人99在线| 3d动漫精品啪啪一区二区| 国产全肉乱妇杂乱视频在线观看| 印度一级黄色录像| 国产全肉乱妇杂乱视频在线观看| 一级淫片试看120分钟| 99re这里只有精品首页| 蜜桃肉汁小说| 女人精69xxxⅹxx视频| 国产自在现线2019| 高潮激烈的呻吟声视频| 欧美激情性做爰免费视频| 狠狠色丁香久久一区| 啊轻点灬太粗嗯一路向阳| 91视频国产区| 神马在线午夜理伦片免费观看| 娇柔娇喘1v1| 天美星空mv高清免费| 中文字幕第80页| 亚洲一区二区av在线| 500短篇又肉又黄合集| 国产gay男男gaygaygv网站| 国产精品一区饥渴老女人| 国产女s调教男m免费网站| 女攻男受爽到失禁h文| 国产美女极度色诱视频www| 亚洲男人天堂av在线| 999伊人| 国产精品1000部| 嗯~啊~快点闺蜜和我| 肉耽快穿文h快穿宿主受| 国产精品久久久777777换脸| 欧美深夜视频| 国产精品久久久亚洲一区| 亚洲图片 小说 欧美 激情| 国产精品永久免费自在线观看| 国产精品中文字幕在线播放| 《艳女伦交》未删减版电影| 区一区二在线| 欧美天天干| 女女高h黄车gl| 巨肉1v1宫交h囚禁| 男人扒开女人桶到爽中国的人| 99精品国产aⅴ| 一级淫片aaa| 天堂√中文在线| 巨大黑人极品videos精品| 红猫大本营点击在线观看的| 男男play呻吟动漫网站| 少妇被技师按摩高潮在线观看| 91亚洲国产成人精品一区二三| 星空无限传媒有限公司官网入口| 五月婷综合| 性视频一级| 美女无遮无挡直播免费软件| 谍战片惊弦免费观看| 抱着娇小稚嫩小身体做h阅读| 国内一区二区视频| 女女同性一区二区三区免费观看| 亚洲欧美第一页| naruto xxxxhd hentai| 扶她futa粗大做到怀孕| 女同啊灬啊用力灬嗯灬gl小说| 国产一级毛片潘金莲| 黄色草莓视频下载| 电视剧玉楼春免费观看全集| 啊啊啊再深点| 无码中文av有码中文av| 强制中出し~大桥未久4| 国产区视频在线观看| 《性/生活》未删减版电影| 欧美13一16sexvideos| 扒开内衣狂揉美女的胸视频| 黄av在线免费| 欧美一区二区三区国产| 国产在线一区二区三区| 午夜精品久久一牛影视| 巨肉1v1宫交h囚禁| 成 人 黄 色有声 小说免费| 久久福利一区| 安野由美中文一区二区| 语文老师的玉足让我好爽| 娇妻借种的呻吟1~29小说全文| 国产成人在线一区| 波多野吉衣一区| 高清一级黄色片| free性中国色老太hd| 福利小视频在线观看| 国产色片在线| 双性精跪趴灌满h室友4p| 离婚后她不装了by暮色酒歌| 美女爆吸乳羞羞免费网站妖精| 韩国理伦三级做爰在线| 男人影院av| 美国一级簧片| 婷婷成人av| 女尊榨精h男产乳| h视频网站在线观看| 扒开双腿猛进入赵丽颖| 殴美一级毛片| xxxxxxxx黄色片| 嗯好大好深| 52avaⅴ我爱haose免费视频| 一女三男做爰3p自述| 男性性器被各种虐玩sm| 亚洲 小说区 图片区| 中文日韩欧美| 绑在公厕让男人来c你| 噼里啪啦免费高清视频| 黄色免费试看| 91成人在线观看喷潮蘑菇| 女体拷问所**室av| 无尽怪物美女触手3d| 健身房教练c弄我了什么后果| 国模精品视频一区二区| 亚洲劲爆av| 免费在线观看成人网| 陈圆圆裸体一级无删减| 木下凛凛子亚洲一区二区| 啊别那么深小心肚子里的孩子| 69国产精品成人96视频色| xxx在线免费观看| 色即是空6| 国产ai换脸一区二区三区| 三国污文全文肉高h后宫| 体育生被强到爽哭高h| 中文字幕二区在线| 女女高h黄车gl| chinese妇色videos| 亚洲欧美日韩综合网| 成人短视频app怎么下载| √天堂资源8在线官网| 扶着美女总裁翘臀挺进深处| 三级黄色生活片| 女仆乖乖掀裙子让主人玩小说| 国产精品久久av一区二区三区| 嗯 啊 快点 还要 爽| 久久久高清视频| 年轻的朋友在线观看完整版| 李兵沈思正值十月天气笔趣阁| 大坤巴塞嘴里| 国产一区二区三区四区五区密私| 日韩激情视频在线播放| 二区三区在线观看| 亚洲一区二区av在线| 健身房教练c弄我了什么后果| 国产第5页| naruto xxxxhd hentai| 亚洲精品天天| 日韩av网站在线| 闺蜜教我帮男人囗交| 97色伦在线| 浴室play高肉r18| 印度一级黄色录像| 公交强行挺进她h嗯啊漫画| 亚洲人成人7777在线播放| 五十女人一级毛片| 日韩第五页| 黄色免费片| sq调教室虐调教h打开腿玩具| 调教女友小静1—31| 王多鱼在线观看全程免费| 男男抽搐高潮呻吟avgaytv| 东北警察故事免费观看高清| 欧美日韩亚洲系列| 日韩av中文字幕在线| 美国黄色一级大片| 精品在线视频观看| 女女之间**vk| 伊人插插| 添老女人囗交做爰| 欧美写真视频一区| 啊用力嗯轻一点小柔| 中文字幕 国产精品| 国产亚洲婷婷| 浪荡受双性震动捧h男男| 秋霞片| 国产又黄又粗视频| 欧美猛交xxx| 少妇又紧又粗又爽的视频| 91成人在线观看喷潮蘑菇| 野外被三个男人躁一夜漫画| 小芳爸爸全文阅读下载| 秘书激情办公室在线观看| 好湿好紧好大好硬| 欧美性生交大片免费视频| 偷拍美女隐私| 女m大学露出调教日记| 总裁含着乳鼓鼓涨奶水小说| 小受夹震蛋玩到失禁play| 朱大海与秀华媳妇朱晓军| 性农村老女人裸体| 交资源www在线观看| 无码中文av有码中文av| 国产最新永久地址发布页| 激情网激情五月| 女尊女攻高h巨辣h文| 国产成人高清| sq调教室虐调教h打开腿玩具| 中文字幕日韩亚洲| 青青在线播放| 久久天天综合| 夜晚天天看视频| 十四女胸发育裸体欣赏| 91色琪琪电影亚洲精品久久| 女人裸体又黄图| 啦啦啦免费高清在线观看| 女m大学露出调教日记| 白洁 笔趣阁| 日本一区二区小视频| 有码在线| 无删减大尺度短剧在线观看| 成人久久久久久久久| 快穿妲己高h荡肉呻吟np| 旧里番艳美1~2集无修在线观看| 婷婷成人av| 中文字幕日韩亚洲| 日麻批| 久久精品女人毛片水多| 刑警娇妻h全肉禁乱免费| 862| 啊轻点灬太粗嗯太深小蓝视频| eeusswww电影天堂国产| 揉我胸啊嗯~出水了电影| 国产又黄又粗视频| 春意影院在线| 清冷双性美人短篇合集| 成人精品福利| 护士裸体献身取精| 千金被肉h高h| 王爷握住她的双乳耸动| 都市激情自拍偷拍| 女同桌用手揉我的jiji| 三国污文全文肉高h后宫| 欧美国产日韩在线视频| 国产又黄又粗视频| 好吊视频一区二区三| 男女尻逼小说| 国产91毛片| www.xvideos.com| 日韩精品中文字幕一区二区三区| 风骚小保姆(高h)| 女攻男受调教爽哭n四爱| www.欧美激情| 嗯 啊 快点 还要 爽| 国产精品中文字幕在线播放| 哭着浣肠h排泄抱着| 少妇做爰免费视频播放| 日本人dh亚洲人ⅹxx| 帅哥和美女打扑克| 日韩一卡在线| 不让穿乳罩随时揉h护士| 精品国产一级蜜臀久久免费软件| www亚洲免费| 神马在线午夜理伦片免费观看| 女仆狂揉下部羞羞漫画| 高h野外调教暗卫| 国产一区二区三区四区五区密私| avhd101高清在线迷片麻豆| 美女被艹在线观看| 亚洲欧洲自拍偷拍视频| 天天操天天天| xxxxzz| gogogo高清在线播放免费观看如果奔跑是| 九色porny自拍视频在线观看| 小舞被脱脱内内打扑克3d动漫| 电视剧:一级黄色片| 亚洲欧美第一页| 原神18av黄漫网站神里绫华| 印度裸体做爰av肉| 成人性生交大片免费7| 国产破处av| 亚洲欧洲一区二区三区| 亚洲一区二区小说| 离婚后她不装了by暮色酒歌| 欧洲美女av| 李兵沈思正值十月天气笔趣阁| 和闺蜜互换老会睡高h| 孙小萌闫辰的全文免费阅读| 公主被两个师傅调教的小说| 婷婷去我也去| 国产gay男男gaygaygv网站| 《欲妇艳谭》| 女s羞辱女m视频ⅴk| 国产东北对白精品久久不能平复| 斗罗大陆黄化小说| 国产剧情av巨作| asian东北少妇pics| 蜜臀久久99精品久久久| 嗯啊巨大h女皇h| 丝瓜草莓黄瓜视频app| 交资源www在线观看| xxxxxxxx黄色片| 东北大坑番外篇| 夜夜综合网| 麻豆久久久| 美女被狂揉下部羞羞69| 色多多免费观看| 欧美日韩亚洲系列| 低头吸她的蜜汁要了一夜| 想被男人操| 成年人性生活免费看| 亚洲一区二区三区毛片| 国产精品调教奴变态| 动漫xxxxxxxxx| 乱lun合集之交换| 91色琪琪电影亚洲精品久久| 九色porny自拍视频在线观看| 亚洲系列在线观看| 苏杏和国防四大校草小说苏家有女第15章| 亚洲 小说区 图片区| 精品少妇一二三区| 《欲妇艳谭》| 99国产精品电影| 青青手机在线视频| 天才俱乐部笔趣阁| 女女同性一区二区三区免费观看| 日本一本区| 亚洲欧美日韩图片| 一道本伊人| 五月婷婷欧美激情| 被公侵犯中文字幕| 亚洲产国偷v产偷v自拍小说| av优选在线观看| 疯狂欧美牲乱大交777| 特级大胆西西4444www| 亚洲a欧美| 国模小丫大尺度啪啪人体| 亚洲欧美第一页| 欧美另类一区二区| 我要干成人网| 久久久久一区二区三区四区| 国产 欧美 在线| 清冷双性美人短篇合集| asian正版国内肉体pics| 欧美另类一区二区| 在人间女主采薇小说免费阅读| 亚洲性生活大片| 强制中出し~大桥未久4| 被老板抱进办公室揉我胸视频| 亚洲人成人7777在线播放| 91九色欧美| 极品粉嫩国产48尤物在线播放| 《色诱女教师》在线| 我的性放荡日记高h| 国产视频黄| 高辣h文乱乳h文浪荡校花小说| 调教h囚禁h强制h禁脔h| 日韩激情视频在线播放| 天堂影院二区| 4747520视频| 五月 婷婷| 韩国av片永久免费| 亚洲成色www.777999| 不用播放器看的av| 小sao货水真多把你cao烂视频| 大尺度肉爽文小说| 欧美偷拍中文字幕| 国产又粗又硬又爽又黄的视频| 日本一区二区小视频| 亚洲一区二区中文字幕在线观看| 乡下邻居寡妇教我做爰电影| 激情网激情五月| 91天天射| 人人揉人人揉人人揉人人揉97| 大尺度肉爽文小说| 少妇按摩做爰2免费观看| 国产欧美精品va在线观看| 日本黄色性片| 印度裸体做爰av肉| 精品国产乱码久久久久久软件影片| 国产女s调教男m免费网站| 极品粉嫩国产48尤物在线播放| 神马在线午夜理伦片免费观看| 午夜激情视频在线播放| 北条麻妃影音先锋| 亚洲国产欧美一区二区三区丁香婷| 在线观看不卡视频| gogogo高清在线播放免费观看如果奔跑是| 黄色三级电影在线观看| 少妇巨大乳挤奶水免费| 少妇白浆视频| 亚洲乱码国产乱码精品精竹爆| 国产人久久人人人人爽按摩| 后进极品美女圆润翘臀视频| 在线少妇| 猛烈顶弄h禁欲老师h春潮| 李采潭电影大全免费观看| 女同桌用手揉我的jiji| 91免费污| 少妇叫床让我使劲| 国产又大又猛又爽又黄的视频| 蜜桃av综合网| 国产盗摄xxxx视频xxxx| 美丽姑娘免费观看版电视剧| 五月婷婷欧美激情| 日韩三级在线观看视频| 年轻的朋友在线观看完整版| 3 d试机号码开机号码| 日日夜精品欧洲日日噜噜| 杨过胯下黄蓉雪臀耸动娇喘| 夜玩亲女裸睡的小妍h上架感言| 攵女yin欲h文| 老司机午夜免费视频| 女尊女攻高h巨辣h文| 超能一家人电影免费喜剧电影在线观看| 贾平凹 暂坐免费阅读| 性开放永久免费视频| 高h不许穿内裤glfuta| 原神人物裸体| 视频黄页在线观看| 《肮脏的交易》未删版| 《艳女伦交》未删减版电影| 娇妻在领导粗大胯下呻视频| 美女叫床声音| 强壮公弄得我次次高潮hd小趴菜| 高潮h揉灌np| 青楼的特殊调教h男宠| 12男学生小裸体无遮挡| 中文字幕在线观看电视剧的网站| 特黄色片| 孙小萌闫辰的全文免费阅读| 调教(高h,1v1校园| 可不可以日剧| 噼里啪啦在线| 奶水h圆房~h嗯啊高h文n| 嗯~啊~快点闺蜜和我| japan18xxxxhdvideos| 欧美猛交xxx| 亚洲第一天堂在线观看| 男男抽搐高潮呻吟avgaytv| 女学生 打屁股 鞭打 网站| 国产v日产∨综合v精品视频| 他的礼物小说免费阅读全文| 国产高清精品在线| 免费看黄色视屏| 午夜激情视频在线播放| 国产日产一区二区三区久久久久久| 国产激情图片| 99久久毛片| 绑在公厕让男人来c你| 吴家丽三级裸体| 女人做爰高潮免费播放| 欧美肥妇b| 美女免费视频观看网站| bbw大肥臀| 天美星空mv高清免费| 动漫美女羞羞视频网站| 欧美日韩一区二区三区四区五区六区| 欧美偷拍中文字幕| 日女人麻批| 亚洲精品播放| 日本韩国欧美中文字幕| 扶她futa粗大做到怀孕| 视频黄页在线观看| 好湿好紧好大好硬| 嗯 啊 快点 还要 爽| 扒开双腿猛进入赵丽颖| 嗯嗯使劲快点娇妻满足我的绿帽欲| 强壮公弄得我次次高潮hd小趴菜| bbw大肥臀| bestialitysex| 国产一级毛片潘金莲| 色欧美精品| asian东北少妇pics| 女女同性一区二区三区免费观看| 国产激情一区| 小sao货cao的你舒服吗视频| 12男学生小裸体无遮挡| 西方世界电影免费播放| 原声舌吻呻吟声| 超能一家人电影免费喜剧电影在线观看| 黄色污在线观看| 原神18av黄漫网站神里绫华| 日韩福利| naruto xxxxhd hentai| 亚洲最大的黄色网址| 东北警察故事免费观看高清| 开发娇妻之穿着暴露小说| 抱着娇妻让粗黑人人玩3p| 最爽乱淫岳合集小说| 我和岳疯狂做爰| 日韩色高清| 开发娇妻之穿着暴露小说| 日韩激情视频在线播放| 日本xxx68hd老师| 久久无精品国产99久久果冻传媒| 国产v日产∨综合v精品视频| 久久久亚洲精品石原莉奈| 久久四色| 午夜免费男女高潮啪啪| 激情欧美一区二区三区免费看| 动漫裸体啪啪h| 慈禧秘密生活电影| 交换一乱一性一爱| 国内自拍在线| 日本乱欲| 北京富婆泄欲对白| 国产一区二区三区四区五区密私| 中文在线天堂资源| 免费少妇荡乳情欲视频的软件| caopor91| 小芳爸爸全文阅读下载| 十四女胸发育裸体欣赏| 手机在线观看av片| 高辣h文乱乳h文hhh教官|