Add vendor_dlkm partition.

Test: define vendor_dlkm for CF.
Bug: 156020364

Change-Id: I459059e1c20df7a285a377b8b3bbc8decc60b124
diff --git a/tools/fs_config/Android.mk b/tools/fs_config/Android.mk
index 64fabe6..60b51b6 100644
--- a/tools/fs_config/Android.mk
+++ b/tools/fs_config/Android.mk
@@ -27,11 +27,12 @@
 system_android_filesystem_config := system/core/include/private/android_filesystem_config.h
 system_capability_header := bionic/libc/kernel/uapi/linux/capability.h
 
-# List of supported vendor, oem, odm, product and system_ext Partitions
+# List of supported vendor, oem, odm, vendor_dlkm, product and system_ext Partitions
 fs_config_generate_extra_partition_list := $(strip \
   $(if $(BOARD_USES_VENDORIMAGE)$(BOARD_VENDORIMAGE_FILE_SYSTEM_TYPE),vendor) \
   $(if $(BOARD_USES_OEMIMAGE)$(BOARD_OEMIMAGE_FILE_SYSTEM_TYPE),oem) \
   $(if $(BOARD_USES_ODMIMAGE)$(BOARD_ODMIMAGE_FILE_SYSTEM_TYPE),odm) \
+  $(if $(BOARD_USES_VENDOR_DLKMIMAGE)$(BOARD_VENDOR_DLKMIMAGE_FILE_SYSTEM_TYPE),vendor_dlkm) \
   $(if $(BOARD_PRODUCTIMAGE_FILE_SYSTEM_TYPE),product) \
   $(if $(BOARD_SYSTEM_EXTIMAGE_FILE_SYSTEM_TYPE),system_ext) \
 )
@@ -282,6 +283,57 @@
 
 endif
 
+ifneq ($(filter vendor_dlkm,$(fs_config_generate_extra_partition_list)),)
+##################################
+# Generate the vendor_dlkm/etc/fs_config_dirs binary file for the target
+# Add fs_config_dirs or fs_config_dirs_vendor_dlkm to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_dirs_vendor_dlkm
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_dirs
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
+	@mkdir -p $(dir $@)
+	$< fsconfig \
+	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
+	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
+	   --partition vendor_dlkm \
+	   --dirs \
+	   --out_file $@ \
+	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
+
+##################################
+# Generate the vendor_dlkm/etc/fs_config_files binary file for the target
+# Add fs_config_files of fs_config_files_vendor_dlkm to PRODUCT_PACKAGES in
+# the device make file to enable
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := fs_config_files_vendor_dlkm
+LOCAL_MODULE_CLASS := ETC
+LOCAL_INSTALLED_MODULE_STEM := fs_config_files
+LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_DLKM)/etc
+include $(BUILD_SYSTEM)/base_rules.mk
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_FS_HDR := $(system_android_filesystem_config)
+$(LOCAL_BUILT_MODULE): PRIVATE_ANDROID_CAP_HDR := $(system_capability_header)
+$(LOCAL_BUILT_MODULE): PRIVATE_TARGET_FS_CONFIG_GEN := $(TARGET_FS_CONFIG_GEN)
+$(LOCAL_BUILT_MODULE): $(LOCAL_PATH)/fs_config_generator.py $(TARGET_FS_CONFIG_GEN) $(system_android_filesystem_config) $(system_capability_header)
+	@mkdir -p $(dir $@)
+	$< fsconfig \
+	   --aid-header $(PRIVATE_ANDROID_FS_HDR) \
+	   --capability-header $(PRIVATE_ANDROID_CAP_HDR) \
+	   --partition vendor_dlkm \
+	   --files \
+	   --out_file $@ \
+	   $(or $(PRIVATE_TARGET_FS_CONFIG_GEN),/dev/null)
+
+endif
+
 ifneq ($(filter product,$(fs_config_generate_extra_partition_list)),)
 ##################################
 # Generate the product/etc/fs_config_dirs binary file for the target
diff --git a/tools/releasetools/add_img_to_target_files.py b/tools/releasetools/add_img_to_target_files.py
index 723fe94..284c89a 100644
--- a/tools/releasetools/add_img_to_target_files.py
+++ b/tools/releasetools/add_img_to_target_files.py
@@ -281,6 +281,22 @@
   return img.name
 
 
+def AddVendorDlkm(output_zip):
+  """Turn the contents of VENDOR_DLKM into an vendor_dlkm image and store it in output_zip."""
+
+  img = OutputFile(output_zip, OPTIONS.input_tmp, "IMAGES", "vendor_dlkm.img")
+  if os.path.exists(img.name):
+    logger.info("vendor_dlkm.img already exists; no need to rebuild...")
+    return img.name
+
+  block_list = OutputFile(
+      output_zip, OPTIONS.input_tmp, "IMAGES", "vendor_dlkm.map")
+  CreateImage(
+      OPTIONS.input_tmp, OPTIONS.info_dict, "vendor_dlkm", img,
+      block_list=block_list)
+  return img.name
+
+
 def AddDtbo(output_zip):
   """Adds the DTBO image.
 
@@ -736,7 +752,7 @@
   has_boot = OPTIONS.info_dict.get("no_boot") != "true"
   has_vendor_boot = OPTIONS.info_dict.get("vendor_boot") == "true"
 
-  # {vendor,odm,product,system_ext}.img are unlike system.img or
+  # {vendor,odm,product,system_ext,vendor_dlkm}.img are unlike system.img or
   # system_other.img. Because it could be built from source, or dropped into
   # target_files.zip as a prebuilt blob. We consider either of them as
   # {vendor,product,system_ext}.img being available, which could be
@@ -749,6 +765,13 @@
               OPTIONS.info_dict.get("building_odm_image") == "true") or
              os.path.exists(
                  os.path.join(OPTIONS.input_tmp, "IMAGES", "odm.img")))
+  has_vendor_dlkm = ((os.path.isdir(os.path.join(OPTIONS.input_tmp,
+                                                 "VENDOR_DLKM")) and
+                      OPTIONS.info_dict.get("building_vendor_dlkm_image")
+                      == "true") or
+                     os.path.exists(
+                         os.path.join(OPTIONS.input_tmp, "IMAGES",
+                                      "vendor_dlkm.img")))
   has_product = ((os.path.isdir(os.path.join(OPTIONS.input_tmp, "PRODUCT")) and
                   OPTIONS.info_dict.get("building_product_image") == "true") or
                  os.path.exists(
@@ -874,6 +897,10 @@
     banner("odm")
     partitions['odm'] = AddOdm(output_zip)
 
+  if has_vendor_dlkm:
+    banner("vendor_dlkm")
+    partitions['vendor_dlkm'] = AddVendorDlkm(output_zip)
+
   if has_system_other:
     banner("system_other")
     AddSystemOther(output_zip)
diff --git a/tools/releasetools/build_image.py b/tools/releasetools/build_image.py
index 7567346..dbfb485 100755
--- a/tools/releasetools/build_image.py
+++ b/tools/releasetools/build_image.py
@@ -708,6 +708,29 @@
       d["extfs_rsv_pct"] = "0"
     copy_prop("odm_reserved_size", "partition_reserved_size")
     copy_prop("odm_selinux_fc", "selinux_fc")
+  elif mount_point == "vendor_dlkm":
+    copy_prop("avb_vendor_dlkm_hashtree_enable", "avb_hashtree_enable")
+    copy_prop("avb_vendor_dlkm_add_hashtree_footer_args",
+              "avb_add_hashtree_footer_args")
+    copy_prop("avb_vendor_dlkm_key_path", "avb_key_path")
+    copy_prop("avb_vendor_dlkm_algorithm", "avb_algorithm")
+    copy_prop("avb_vendor_dlkm_salt", "avb_salt")
+    copy_prop("vendor_dlkm_fs_type", "fs_type")
+    copy_prop("vendor_dlkm_size", "partition_size")
+    if not copy_prop("vendor_dlkm_journal_size", "journal_size"):
+      d["journal_size"] = "0"
+    copy_prop("vendor_dlkm_verity_block_device", "verity_block_device")
+    copy_prop("ext4_share_dup_blocks", "ext4_share_dup_blocks")
+    copy_prop("vendor_dlkm_squashfs_compressor", "squashfs_compressor")
+    copy_prop("vendor_dlkm_squashfs_compressor_opt", "squashfs_compressor_opt")
+    copy_prop("vendor_dlkm_squashfs_block_size", "squashfs_block_size")
+    copy_prop("vendor_dlkm_squashfs_disable_4k_align", "squashfs_disable_4k_align")
+    copy_prop("vendor_dlkm_base_fs_file", "base_fs_file")
+    copy_prop("vendor_dlkm_extfs_inode_count", "extfs_inode_count")
+    if not copy_prop("vendor_dlkm_extfs_rsv_pct", "extfs_rsv_pct"):
+      d["extfs_rsv_pct"] = "0"
+    copy_prop("vendor_dlkm_reserved_size", "partition_reserved_size")
+    copy_prop("vendor_dlkm_selinux_fc", "selinux_fc")
   elif mount_point == "oem":
     copy_prop("fs_type", "fs_type")
     copy_prop("oem_size", "partition_size")
@@ -752,6 +775,8 @@
     copy_prop("partition_size", "vendor_size")
   elif mount_point == "odm":
     copy_prop("partition_size", "odm_size")
+  elif mount_point == "vendor_dlkm":
+    copy_prop("partition_size", "vendor_dlkm_size")
   elif mount_point == "product":
     copy_prop("partition_size", "product_size")
   elif mount_point == "system_ext":
@@ -791,6 +816,8 @@
       mount_point = "vendor"
     elif image_filename == "odm.img":
       mount_point = "odm"
+    elif image_filename == "vendor_dlkm.img":
+      mount_point = "vendor_dlkm"
     elif image_filename == "oem.img":
       mount_point = "oem"
     elif image_filename == "product.img":
diff --git a/tools/releasetools/check_target_files_vintf.py b/tools/releasetools/check_target_files_vintf.py
index 95d09cc..79005df 100755
--- a/tools/releasetools/check_target_files_vintf.py
+++ b/tools/releasetools/check_target_files_vintf.py
@@ -46,6 +46,7 @@
     '/product': ('PRODUCT', 'SYSTEM/product'),
     '/odm': ('ODM', 'VENDOR/odm', 'SYSTEM/vendor/odm'),
     '/system_ext': ('SYSTEM_EXT', 'SYSTEM/system_ext'),
+    # vendor_dlkm does not have VINTF files.
 }
 
 UNZIP_PATTERN = ['META/*', '*/build.prop']
diff --git a/tools/releasetools/common.py b/tools/releasetools/common.py
index 8bbc35e..a26f9e4 100644
--- a/tools/releasetools/common.py
+++ b/tools/releasetools/common.py
@@ -110,13 +110,20 @@
 # that system_other is not in the list because we don't want to include its
 # descriptor into vbmeta.img.
 AVB_PARTITIONS = ('boot', 'dtbo', 'odm', 'product', 'recovery', 'system',
-                  'system_ext', 'vendor', 'vendor_boot')
+                  'system_ext', 'vendor', 'vendor_boot', 'vendor_dlkm')
 
 # Chained VBMeta partitions.
 AVB_VBMETA_PARTITIONS = ('vbmeta_system', 'vbmeta_vendor')
 
 # Partitions that should have their care_map added to META/care_map.pb
-PARTITIONS_WITH_CARE_MAP = ('system', 'vendor', 'product', 'system_ext', 'odm')
+PARTITIONS_WITH_CARE_MAP = (
+    'system',
+    'vendor',
+    'product',
+    'system_ext',
+    'odm',
+    'vendor_dlkm',
+)
 
 
 class ErrorCode(object):
@@ -655,7 +662,8 @@
         input_file, "META", "root_filesystem_config.txt")
 
     # Redirect {partition}_base_fs_file for each of the named partitions.
-    for part_name in ["system", "vendor", "system_ext", "product", "odm"]:
+    for part_name in ["system", "vendor", "system_ext", "product", "odm",
+                      "vendor_dlkm"]:
       key_name = part_name + "_base_fs_file"
       if key_name not in d:
         continue
diff --git a/tools/releasetools/merge_target_files.py b/tools/releasetools/merge_target_files.py
index ed42b20..ad991ca 100755
--- a/tools/releasetools/merge_target_files.py
+++ b/tools/releasetools/merge_target_files.py
@@ -197,6 +197,7 @@
     'PREBUILT_IMAGES/*',
     'RADIO/*',
     'VENDOR/*',
+    'VENDOR_DLKM/*',
 )
 
 # VENDOR_EXTRACT_SPECIAL_ITEM_LIST is a list of items to extract from the
@@ -223,6 +224,7 @@
     'SYSTEM/',
     'SYSTEM_OTHER/',
     'VENDOR/',
+    'VENDOR_DLKM/',
 )
 
 
diff --git a/tools/releasetools/ota_from_target_files.py b/tools/releasetools/ota_from_target_files.py
index 7fb0a77..f114f63 100755
--- a/tools/releasetools/ota_from_target_files.py
+++ b/tools/releasetools/ota_from_target_files.py
@@ -277,7 +277,8 @@
 UNZIP_PATTERN = ['IMAGES/*', 'META/*', 'OTA/*', 'RADIO/*']
 # Files to be unzipped for target diffing purpose.
 TARGET_DIFFING_UNZIP_PATTERN = ['BOOT', 'RECOVERY', 'SYSTEM/*', 'VENDOR/*',
-                                'PRODUCT/*', 'SYSTEM_EXT/*', 'ODM/*']
+                                'PRODUCT/*', 'SYSTEM_EXT/*', 'ODM/*',
+                                'VENDOR_DLKM/*']
 RETROFIT_DAP_UNZIP_PATTERN = ['OTA/super_*.img', AB_PARTITIONS]
 
 # Images to be excluded from secondary payload. We essentially only keep
@@ -285,7 +286,7 @@
 SECONDARY_PAYLOAD_SKIPPED_IMAGES = [
     'boot', 'dtbo', 'modem', 'odm', 'product', 'radio', 'recovery',
     'system_ext', 'vbmeta', 'vbmeta_system', 'vbmeta_vendor', 'vendor',
-    'vendor_boot']
+    'vendor_boot', 'vendor_dlkm']
 
 
 class PayloadSigner(object):
@@ -668,7 +669,8 @@
     assert blockimgdiff_version >= 3
 
   block_diff_dict = collections.OrderedDict()
-  partition_names = ["system", "vendor", "product", "odm", "system_ext"]
+  partition_names = ["system", "vendor", "product", "odm", "system_ext",
+                     "vendor_dlkm"]
   for partition in partition_names:
     if not HasPartition(target_zip, partition):
       continue