Merge Mainline
Signed-off-by: Tianling Shen <cnsztl@immortalwrt.org>
This commit is contained in:
commit
636a2b539b
@ -136,13 +136,6 @@ menu "Target Images"
|
||||
help
|
||||
Create an ext4 filesystem with a journal.
|
||||
|
||||
config TARGET_ROOTFS_ISO
|
||||
bool "iso"
|
||||
default n
|
||||
depends on TARGET_x86_generic
|
||||
help
|
||||
Create a bootable ISO image.
|
||||
|
||||
config TARGET_ROOTFS_JFFS2
|
||||
bool "jffs2"
|
||||
depends on USES_JFFS2
|
||||
@ -207,32 +200,32 @@ menu "Target Images"
|
||||
config GRUB_IMAGES
|
||||
bool "Build GRUB images (Linux x86 or x86_64 host only)"
|
||||
depends on TARGET_x86
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
select PACKAGE_grub2
|
||||
default y
|
||||
|
||||
config EFI_IMAGES
|
||||
bool "Build EFI GRUB images (Linux x86 or x86_64 host only)"
|
||||
config GRUB_EFI_IMAGES
|
||||
bool "Build GRUB EFI images (Linux x86 or x86_64 host only)"
|
||||
depends on TARGET_x86
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_ISO || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_ROOTFS_JFFS2 || TARGET_ROOTFS_SQUASHFS
|
||||
select PACKAGE_grub2
|
||||
select PACKAGE_grub2-efi
|
||||
select PACKAGE_kmod-fs-vfat
|
||||
default y
|
||||
|
||||
config GRUB_CONSOLE
|
||||
bool "Use Console Terminal (in addition to Serial)"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default y
|
||||
|
||||
config GRUB_SERIAL
|
||||
string "Serial port device"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
default "hvc0" if TARGET_x86_xen_domu
|
||||
default "ttyS0" if ! TARGET_x86_xen_domu
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default "ttyS0"
|
||||
|
||||
config GRUB_BAUDRATE
|
||||
int "Serial port baud rate"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default 38400 if TARGET_x86_generic
|
||||
default 115200
|
||||
|
||||
@ -243,65 +236,58 @@ menu "Target Images"
|
||||
|
||||
config GRUB_BOOTOPTS
|
||||
string "Extra kernel boot options"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
default "xencons=hvc" if TARGET_x86_xen_domu
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
help
|
||||
If you don't know, just leave it blank.
|
||||
|
||||
config GRUB_TIMEOUT
|
||||
string "Seconds to wait before booting the default entry"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default "0"
|
||||
help
|
||||
If you don't know, 5 seconds is a reasonable default.
|
||||
|
||||
config GRUB_TITLE
|
||||
string "Title for the menu entry in GRUB"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
default "OpenWrt"
|
||||
help
|
||||
This is the title of the GRUB menu entry.
|
||||
If unspecified, it defaults to OpenWrt.
|
||||
|
||||
config ISO_IMAGES
|
||||
bool "Build LiveCD image (ISO)"
|
||||
depends on TARGET_x86
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
|
||||
config QCOW2_IMAGES
|
||||
bool "Build PVE/KVM image files (QCOW2)"
|
||||
depends on TARGET_x86
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
select PACKAGE_kmod-e1000
|
||||
|
||||
config VDI_IMAGES
|
||||
bool "Build VirtualBox image files (VDI)"
|
||||
depends on TARGET_x86 || TARGET_x86_64
|
||||
select GRUB_IMAGES
|
||||
select TARGET_IMAGES_PAD
|
||||
depends on TARGET_x86
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
select PACKAGE_kmod-e1000
|
||||
|
||||
config VHDX_IMAGES
|
||||
bool "Build Hyper-V image files (VHDX)"
|
||||
depends on TARGET_x86
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
select PACKAGE_kmod-tulip
|
||||
|
||||
config VMDK_IMAGES
|
||||
bool "Build VMware image files (VMDK)"
|
||||
depends on TARGET_x86 || TARGET_x86_64
|
||||
select GRUB_IMAGES
|
||||
select TARGET_IMAGES_PAD
|
||||
depends on TARGET_x86
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
select PACKAGE_kmod-e1000
|
||||
default y
|
||||
|
||||
config VHD_IMAGES
|
||||
bool "Build Hyper-V image files (VHD)"
|
||||
depends on TARGET_x86 || TARGET_x86_64
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
select TARGET_IMAGES_PAD
|
||||
select PACKAGE_kmod-tulip
|
||||
default n
|
||||
|
||||
config QCOW2_IMAGES
|
||||
bool "Build PVE/KVM image files (QCOW2)"
|
||||
depends on TARGET_x86 || TARGET_x86_64
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
select TARGET_IMAGES_PAD
|
||||
select PACKAGE_kmod-e1000
|
||||
default n
|
||||
|
||||
config TARGET_IMAGES_PAD
|
||||
bool "Pad images to filesystem size (for JFFS2)"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
default y
|
||||
|
||||
config TARGET_IMAGES_GZIP
|
||||
bool "GZip images"
|
||||
depends on TARGET_IMAGES_PAD || TARGET_ROOTFS_EXT4FS || TARGET_x86
|
||||
depends on TARGET_ROOTFS_EXT4FS || TARGET_x86
|
||||
default y
|
||||
default n if TARGET_x86
|
||||
|
||||
@ -311,21 +297,21 @@ menu "Target Images"
|
||||
|
||||
config TARGET_KERNEL_PARTSIZE
|
||||
int "Kernel partition size (in MB)"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES || USES_BOOT_PART
|
||||
depends on USES_BOOT_PART
|
||||
default 8 if TARGET_apm821xx_sata
|
||||
default 64 if TARGET_bcm27xx
|
||||
default 16
|
||||
|
||||
config TARGET_ROOTFS_PARTSIZE
|
||||
int "Root filesystem partition size (in MB)"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES || USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_rb532 || TARGET_sunxi || TARGET_uml
|
||||
depends on USES_ROOTFS_PART || TARGET_ROOTFS_EXT4FS || TARGET_mvebu || TARGET_rb532 || TARGET_sunxi || TARGET_uml
|
||||
default 160
|
||||
help
|
||||
Select the root filesystem partition size.
|
||||
|
||||
config TARGET_ROOTFS_PARTNAME
|
||||
string "Root partition on target device"
|
||||
depends on GRUB_IMAGES || EFI_IMAGES
|
||||
depends on GRUB_IMAGES || GRUB_EFI_IMAGES
|
||||
help
|
||||
Override the root partition on the final device. If left empty,
|
||||
it will be mounted by PARTUUID which makes the kernel find the
|
||||
|
||||
@ -466,3 +466,10 @@ define Build/append-metadata
|
||||
fwtool -S "$@.ucert" "$@" ;\
|
||||
}
|
||||
endef
|
||||
|
||||
# Convert a raw image into a $1 type image.
|
||||
# E.g. | qemu-image vdi
|
||||
define Build/qemu-image
|
||||
qemu-img convert -f raw -O $1 $@ $@.new
|
||||
@mv $@.new $@
|
||||
endef
|
||||
|
||||
@ -41,6 +41,7 @@ IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$
|
||||
IMG_ROOTFS:=$(IMG_PREFIX)-rootfs
|
||||
IMG_COMBINED:=$(IMG_PREFIX)-combined
|
||||
IMG_PART_SIGNATURE:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | cut -b1-8)
|
||||
IMG_PART_DISKGUID:=$(shell echo $(SOURCE_DATE_EPOCH)$(LINUX_VERMAGIC) | $(MKHASH) md5 | sed -r 's/(.{8})(.{4})(.{4})(.{4})(.{10})../\1-\2-\3-\4-\500/')
|
||||
|
||||
MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt
|
||||
|
||||
@ -89,7 +90,6 @@ fs-types-$(CONFIG_TARGET_ROOTFS_SQUASHFS) += squashfs
|
||||
fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addprefix jffs2-,$(JFFS2_BLOCKSIZE))
|
||||
fs-types-$(CONFIG_TARGET_ROOTFS_JFFS2_NAND) += $(addprefix jffs2-nand-,$(NAND_BLOCKSIZE))
|
||||
fs-types-$(CONFIG_TARGET_ROOTFS_EXT4FS) += ext4
|
||||
fs-types-$(CONFIG_TARGET_ROOTFS_ISO) += iso
|
||||
fs-types-$(CONFIG_TARGET_ROOTFS_UBIFS) += ubifs
|
||||
fs-subtypes-$(CONFIG_TARGET_ROOTFS_JFFS2) += $(addsuffix -raw,$(addprefix jffs2-,$(JFFS2_BLOCKSIZE)))
|
||||
|
||||
|
||||
@ -90,6 +90,17 @@ get_image() { # <source> [ <command> ]
|
||||
cat "$from" 2>/dev/null | $cmd
|
||||
}
|
||||
|
||||
get_image_dd() {
|
||||
local from="$1"; shift
|
||||
|
||||
(
|
||||
exec 3>&2
|
||||
( exec 3>&2; get_image "$from" 2>&1 1>&3 | grep -v -F ' Broken pipe' ) 2>&1 1>&3 \
|
||||
| ( exec 3>&2; dd "$@" 2>&1 1>&3 | grep -v -E ' records (in|out)') 2>&1 1>&3
|
||||
exec 3>&-
|
||||
)
|
||||
}
|
||||
|
||||
get_magic_word() {
|
||||
(get_image "$@" | dd bs=2 count=1 | hexdump -v -n 2 -e '1/1 "%02x"') 2>/dev/null
|
||||
}
|
||||
@ -98,6 +109,24 @@ get_magic_long() {
|
||||
(get_image "$@" | dd bs=4 count=1 | hexdump -v -n 4 -e '1/1 "%02x"') 2>/dev/null
|
||||
}
|
||||
|
||||
get_magic_gpt() {
|
||||
(get_image "$@" | dd bs=8 count=1 skip=64) 2>/dev/null
|
||||
}
|
||||
|
||||
get_magic_vfat() {
|
||||
(get_image "$@" | dd bs=1 count=3 skip=54) 2>/dev/null
|
||||
}
|
||||
|
||||
part_magic_efi() {
|
||||
local magic=$(get_magic_gpt "$@")
|
||||
[ "$magic" = "EFI PART" ]
|
||||
}
|
||||
|
||||
part_magic_fat() {
|
||||
local magic=$(get_magic_vfat "$@")
|
||||
[ "$magic" = "FAT" ]
|
||||
}
|
||||
|
||||
export_bootdevice() {
|
||||
local cmdline uuid disk uevent line
|
||||
local MAJOR MINOR DEVNAME DEVTYPE
|
||||
@ -144,6 +173,17 @@ export_bootdevice() {
|
||||
fi
|
||||
done
|
||||
;;
|
||||
PARTUUID=????????-????-????-????-??????????02)
|
||||
uuid="${rootpart#PARTUUID=}"
|
||||
uuid="${uuid%02}00"
|
||||
for disk in $(find /dev -type b); do
|
||||
set -- $(dd if=$disk bs=1 skip=568 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
|
||||
if [ "$4$3$2$1-$6$5-$8$7-$9" = "$uuid" ]; then
|
||||
uevent="/sys/class/block/${disk##*/}/uevent"
|
||||
break
|
||||
fi
|
||||
done
|
||||
;;
|
||||
/dev/*)
|
||||
uevent="/sys/class/block/${disk##*/}/uevent"
|
||||
;;
|
||||
@ -203,17 +243,34 @@ get_partitions() { # <device> <filename>
|
||||
rm -f "/tmp/partmap.$filename"
|
||||
|
||||
local part
|
||||
for part in 1 2 3 4; do
|
||||
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
|
||||
part_magic_efi "$disk" && {
|
||||
#export_partdevice will fail when partition number is greater than 15, as
|
||||
#the partition major device number is not equal to the disk major device number
|
||||
for part in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
|
||||
set -- $(hexdump -v -n 48 -s "$((0x380 + $part * 0x80))" -e '4/4 "%08x"" "4/4 "%08x"" "4/4 "0x%08X "' "$disk")
|
||||
|
||||
local type="$(( $(hex_le32_to_cpu $1) % 256))"
|
||||
local lba="$(( $(hex_le32_to_cpu $2) ))"
|
||||
local num="$(( $(hex_le32_to_cpu $3) ))"
|
||||
local type="$1"
|
||||
local lba="$(( $(hex_le32_to_cpu $4) * 0x100000000 + $(hex_le32_to_cpu $3) ))"
|
||||
local end="$(( $(hex_le32_to_cpu $6) * 0x100000000 + $(hex_le32_to_cpu $5) ))"
|
||||
local num="$(( $end - $lba ))"
|
||||
|
||||
[ $type -gt 0 ] || continue
|
||||
[ "$type" = "00000000000000000000000000000000" ] && continue
|
||||
|
||||
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
|
||||
done
|
||||
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
|
||||
done
|
||||
} || {
|
||||
for part in 1 2 3 4; do
|
||||
set -- $(hexdump -v -n 12 -s "$((0x1B2 + $part * 16))" -e '3/4 "0x%08X "' "$disk")
|
||||
|
||||
local type="$(( $(hex_le32_to_cpu $1) % 256))"
|
||||
local lba="$(( $(hex_le32_to_cpu $2) ))"
|
||||
local num="$(( $(hex_le32_to_cpu $3) ))"
|
||||
|
||||
[ $type -gt 0 ] || continue
|
||||
|
||||
printf "%2d %5d %7d\n" $part $lba $num >> "/tmp/partmap.$filename"
|
||||
done
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
158
package/boot/grub2/Makefile
Normal file
158
package/boot/grub2/Makefile
Normal file
@ -0,0 +1,158 @@
|
||||
#
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=grub
|
||||
PKG_CPE_ID:=cpe:/a:gnu:grub2
|
||||
PKG_VERSION:=2.06~rc1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://alpha.gnu.org/gnu/grub
|
||||
PKG_HASH:=2c87f1f21e2ab50043e6cd9163c08f1b6c3a6171556bf23ff9ed65b074145484
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
PKG_BUILD_DEPENDS:=grub2/host
|
||||
|
||||
PKG_ASLR_PIE:=0
|
||||
PKG_SSP:=0
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/grub2/Default
|
||||
CATEGORY:=Boot Loaders
|
||||
SECTION:=boot
|
||||
TITLE:=GRand Unified Bootloader ($(1))
|
||||
URL:=http://www.gnu.org/software/grub/
|
||||
DEPENDS:=@TARGET_x86
|
||||
VARIANT:=$(1)
|
||||
endef
|
||||
|
||||
Package/grub2=$(call Package/grub2/Default,pc)
|
||||
Package/grub2-efi=$(call Package/grub2/Default,efi)
|
||||
|
||||
define Package/grub2-editenv
|
||||
CATEGORY:=Utilities
|
||||
SECTION:=utils
|
||||
SUBMENU:=Boot Loaders
|
||||
TITLE:=Grub2 Environment editor
|
||||
URL:=http://www.gnu.org/software/grub/
|
||||
DEPENDS:=@TARGET_x86
|
||||
VARIANT:=pc
|
||||
endef
|
||||
|
||||
define Package/grub2-editenv/description
|
||||
Edit grub2 environment files.
|
||||
endef
|
||||
|
||||
HOST_BUILD_PREFIX := $(STAGING_DIR_HOST)
|
||||
|
||||
CONFIGURE_VARS += \
|
||||
grub_build_mkfont_excuse="don't want fonts"
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--target=$(REAL_GNU_TARGET_NAME) \
|
||||
--disable-werror \
|
||||
--disable-nls \
|
||||
--disable-device-mapper \
|
||||
--disable-libzfs \
|
||||
--disable-liblzma \
|
||||
--disable-grub-mkfont \
|
||||
--with-platform=$(BUILD_VARIANT)
|
||||
|
||||
HOST_CONFIGURE_VARS += \
|
||||
grub_build_mkfont_excuse="don't want fonts"
|
||||
|
||||
HOST_CONFIGURE_ARGS += \
|
||||
--disable-grub-mkfont \
|
||||
--target=$(REAL_GNU_TARGET_NAME) \
|
||||
--sbindir="$(STAGING_DIR_HOST)/bin" \
|
||||
--disable-werror \
|
||||
--disable-libzfs \
|
||||
--disable-nls \
|
||||
--with-platform=none
|
||||
|
||||
HOST_MAKE_FLAGS += \
|
||||
TARGET_RANLIB=$(TARGET_RANLIB) \
|
||||
LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
|
||||
|
||||
TARGET_CFLAGS := $(filter-out -O2 -O3 -fno-plt,$(TARGET_CFLAGS))
|
||||
|
||||
define Host/Configure
|
||||
$(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
|
||||
$(Host/Configure/Default)
|
||||
endef
|
||||
|
||||
define Package/grub2/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-bios-setup $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(STAGING_DIR_IMAGE)/grub2
|
||||
$(CP) $(PKG_BUILD_DIR)/grub-core/boot.img $(STAGING_DIR_IMAGE)/grub2/
|
||||
$(CP) $(PKG_BUILD_DIR)/grub-core/cdboot.img $(STAGING_DIR_IMAGE)/grub2/
|
||||
sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O i386-pc \
|
||||
-c $(PKG_BUILD_DIR)/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/gpt-core.img \
|
||||
at_keyboard biosdisk boot chain configfile fat linux ls part_gpt reboot serial vga
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O i386-pc \
|
||||
-c ./files/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/generic-core.img \
|
||||
at_keyboard biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O i386-pc \
|
||||
-c ./files/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/eltorito.img \
|
||||
at_keyboard biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial test vga
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O i386-pc \
|
||||
-c ./files/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/legacy-core.img \
|
||||
biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
|
||||
endef
|
||||
|
||||
define Package/grub2-efi/install
|
||||
sed 's#msdos1#gpt1#g' ./files/grub-early.cfg >$(PKG_BUILD_DIR)/grub-early.cfg
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O $(CONFIG_ARCH)-efi \
|
||||
-c $(PKG_BUILD_DIR)/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi \
|
||||
at_keyboard boot chain configfile fat linux ls part_gpt reboot serial efi_gop efi_uga
|
||||
$(STAGING_DIR_HOST)/bin/grub-mkimage \
|
||||
-d $(PKG_BUILD_DIR)/grub-core \
|
||||
-p /boot/grub \
|
||||
-O $(CONFIG_ARCH)-efi \
|
||||
-c ./files/grub-early.cfg \
|
||||
-o $(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
|
||||
at_keyboard boot chain configfile fat iso9660 linux ls part_msdos part_gpt reboot serial test efi_gop efi_uga
|
||||
endef
|
||||
|
||||
define Package/grub2-editenv/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,grub2))
|
||||
$(eval $(call BuildPackage,grub2-efi))
|
||||
$(eval $(call BuildPackage,grub2-editenv))
|
||||
@ -1,76 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_CPE_ID:=cpe:/a:gnu:grub2
|
||||
PKG_VERSION:=2.06~rc1
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=grub-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://alpha.gnu.org/gnu/grub
|
||||
PKG_HASH:=2c87f1f21e2ab50043e6cd9163c08f1b6c3a6171556bf23ff9ed65b074145484
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_ASLR_PIE:=0
|
||||
PKG_SSP:=0
|
||||
|
||||
PKG_FLAGS:=nonshared
|
||||
|
||||
PATCH_DIR := ../patches
|
||||
HOST_PATCH_DIR := ../patches
|
||||
HOST_BUILD_DIR := $(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/grub2/Default
|
||||
CATEGORY:=Boot Loaders
|
||||
SECTION:=boot
|
||||
TITLE:=GRand Unified Bootloader
|
||||
URL:=http://www.gnu.org/software/grub/
|
||||
DEPENDS:=@TARGET_x86||TARGET_x86_64
|
||||
endef
|
||||
|
||||
HOST_BUILD_PREFIX := $(STAGING_DIR_HOST)
|
||||
|
||||
CONFIGURE_VARS += \
|
||||
grub_build_mkfont_excuse="don't want fonts"
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--target=$(REAL_GNU_TARGET_NAME) \
|
||||
--disable-werror \
|
||||
--disable-nls \
|
||||
--disable-device-mapper \
|
||||
--disable-libzfs \
|
||||
--disable-liblzma \
|
||||
--disable-grub-mkfont \
|
||||
--with-platform=none
|
||||
|
||||
HOST_CONFIGURE_VARS += \
|
||||
grub_build_mkfont_excuse="don't want fonts"
|
||||
|
||||
HOST_CONFIGURE_ARGS += \
|
||||
--disable-grub-mkfont \
|
||||
--target=$(REAL_GNU_TARGET_NAME) \
|
||||
--sbindir="$(STAGING_DIR_HOST)/bin" \
|
||||
--disable-werror \
|
||||
--disable-libzfs \
|
||||
--disable-nls
|
||||
|
||||
HOST_MAKE_FLAGS += \
|
||||
TARGET_RANLIB=$(TARGET_RANLIB) \
|
||||
LIBLZMA=$(STAGING_DIR_HOST)/lib/liblzma.a
|
||||
|
||||
TARGET_CFLAGS := $(filter-out -O2 -O3 -fno-plt,$(TARGET_CFLAGS))
|
||||
|
||||
define Host/Configure
|
||||
$(SED) 's,(RANLIB),(TARGET_RANLIB),' $(HOST_BUILD_DIR)/grub-core/Makefile.in
|
||||
$(Host/Configure/Default)
|
||||
endef
|
||||
@ -1,23 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=grub-efi
|
||||
|
||||
include ../common.mk
|
||||
|
||||
TAR_OPTIONS:= --transform 's/grub-${PKG_VERSION}/${PKG_NAME}-${PKG_VERSION}/' $(TAR_OPTIONS)
|
||||
|
||||
PKG_BUILD_DEPENDS:=grub2-efi/host
|
||||
|
||||
CONFIGURE_ARGS += --with-platform=efi
|
||||
HOST_CONFIGURE_ARGS += --with-platform=efi --program-suffix=-efi
|
||||
HOST_BUILD_DIR := $(BUILD_DIR_HOST)/$(PKG_NAME)-$(PKG_VERSION)
|
||||
|
||||
define Package/grub2-efi
|
||||
$(call Package/grub2/Default)
|
||||
HIDDEN:=1
|
||||
TITLE += (with EFI support)
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,grub2-efi))
|
||||
@ -1,33 +0,0 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=grub
|
||||
|
||||
include ../common.mk
|
||||
|
||||
PKG_BUILD_DEPENDS:=grub2/host
|
||||
|
||||
define Package/grub2
|
||||
$(call Package/grub2/Default)
|
||||
endef
|
||||
|
||||
define Package/grub2-editenv
|
||||
CATEGORY:=Utilities
|
||||
SECTION:=utils
|
||||
TITLE:=Grub2 Environment editor
|
||||
URL:=http://www.gnu.org/software/grub/
|
||||
DEPENDS:=@TARGET_x86||TARGET_x86_64
|
||||
endef
|
||||
|
||||
define Package/grub2-editenv/description
|
||||
Edit grub2 environment files.
|
||||
endef
|
||||
|
||||
define Package/grub2-editenv/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/grub-editenv $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
$(eval $(call BuildPackage,grub2))
|
||||
$(eval $(call BuildPackage,grub2-editenv))
|
||||
@ -32,7 +32,7 @@ Signed-off-by: Ismael Ripoll-Ripoll <iripoll@disca.upv.es>
|
||||
@@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
- if (key == GRUB_TERM_BACKSPACE)
|
||||
+ if (key == GRUB_TERM_BACKSPACE && cur_len)
|
||||
{
|
||||
|
||||
@ -20,7 +20,7 @@ sect=63
|
||||
cyl=$(( (KERNELSIZE + ROOTFSSIZE) * 1024 * 1024 / (head * sect * 512)))
|
||||
|
||||
# create partition table
|
||||
set $(ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE})
|
||||
set $(ptgen -o "$OUTPUT" -h $head -s $sect ${GUID:+-g} -p ${KERNELSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE} ${GUID:+-G $GUID})
|
||||
|
||||
KERNELOFFSET="$(($1 / 512))"
|
||||
KERNELSIZE="$2"
|
||||
@ -30,6 +30,12 @@ ROOTFSSIZE="$(($4 / 512))"
|
||||
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
|
||||
dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
|
||||
|
||||
make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
|
||||
if [ -n "$GUID" ]; then
|
||||
[ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$(($ROOTFSOFFSET + $ROOTFSSIZE))" conv=notrunc count="$sect"
|
||||
mkfs.fat -n kernel -C "$OUTPUT.kernel" -S 512 "$(($KERNELSIZE / 1024))"
|
||||
mcopy -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
|
||||
else
|
||||
make_ext4fs -J -L kernel -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
|
||||
fi
|
||||
dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
|
||||
rm -f "$OUTPUT.kernel"
|
||||
|
||||
@ -10,7 +10,7 @@ platform_check_image_sdcard() {
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
|
||||
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -41,7 +41,7 @@ platform_do_upgrade_sdcard() {
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
|
||||
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -52,7 +52,7 @@ platform_do_upgrade_sdcard() {
|
||||
fi
|
||||
|
||||
if [ -n "$diff" ]; then
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
|
||||
# Separate removal and addtion is necessary; otherwise, partition 1
|
||||
# will be missing if it overlaps with the old partition 2
|
||||
@ -60,12 +60,12 @@ platform_do_upgrade_sdcard() {
|
||||
partx -a - "/dev/$diskdev"
|
||||
else
|
||||
#write uboot image
|
||||
get_image "$@" | dd of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
|
||||
get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=2048 conv=fsync
|
||||
#iterate over each partition from the image and write it to the boot disk
|
||||
while read part start size; do
|
||||
if export_partdevice partdev $part; then
|
||||
echo "Writing image to /dev/$partdev..."
|
||||
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
|
||||
get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
|
||||
else
|
||||
echo "Unable to find partition $part device, skipped."
|
||||
fi
|
||||
@ -73,7 +73,7 @@ platform_do_upgrade_sdcard() {
|
||||
|
||||
#copy partition uuid
|
||||
echo "Writing new UUID to /dev/$diskdev..."
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
|
||||
@ -10,7 +10,6 @@ BOARDNAME := NVIDIA Tegra
|
||||
FEATURES := audio boot-part display ext4 fpu gpio pci pcie rootfs-part rtc squashfs usb
|
||||
CPU_TYPE := cortex-a9
|
||||
CPU_SUBTYPE := vfpv3-d16
|
||||
MAINTAINER := Tomasz Maciej Nowak <tomek_n@o2.pl>
|
||||
|
||||
KERNEL_PATCHVER := 5.4
|
||||
KERNEL_TESTING_PATCHVER := 5.10
|
||||
|
||||
@ -3,8 +3,6 @@ REQUIRE_IMAGE_METADATA=1
|
||||
platform_check_image() {
|
||||
local diskdev partdev diff
|
||||
|
||||
[ "$#" -gt 1 ] && return 1
|
||||
|
||||
export_bootdevice && export_partdevice diskdev 0 || {
|
||||
echo "Unable to determine upgrade device"
|
||||
return 1
|
||||
@ -13,7 +11,7 @@ platform_check_image() {
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
|
||||
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -53,7 +51,7 @@ platform_do_upgrade() {
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
|
||||
get_image_dd "$1" of=/tmp/image.bs count=1 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -64,7 +62,7 @@ platform_do_upgrade() {
|
||||
fi
|
||||
|
||||
if [ -n "$diff" ]; then
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
|
||||
# Separate removal and addtion is necessary; otherwise, partition 1
|
||||
# will be missing if it overlaps with the old partition 2
|
||||
@ -74,11 +72,13 @@ platform_do_upgrade() {
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo "Writing bootloader to /dev/$diskdev"
|
||||
get_image_dd "$1" of="$diskdev" bs=512 skip=1 seek=1 count=4097 conv=fsync,notrunc
|
||||
#iterate over each partition from the image and write it to the boot disk
|
||||
while read part start size; do
|
||||
if export_partdevice partdev $part; then
|
||||
echo "Writing image to /dev/$partdev..."
|
||||
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
|
||||
get_image_dd "$1" of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
|
||||
else
|
||||
echo "Unable to find partition $part device, skipped."
|
||||
fi
|
||||
@ -86,5 +86,5 @@ platform_do_upgrade() {
|
||||
|
||||
#copy partition uuid
|
||||
echo "Writing new UUID to /dev/$diskdev..."
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ define Device/compulab_trimslice
|
||||
DEVICE_MODEL := TrimSlice
|
||||
DEVICE_DTS := tegra20-trimslice
|
||||
DEVICE_PACKAGES := kmod-r8169 kmod-rt2800-usb kmod-rtc-em3027 \
|
||||
kmod-usb-storage wpad-mini
|
||||
kmod-usb-storage wpad-basic-wolfssl
|
||||
UBOOT := trimslice-mmc
|
||||
endef
|
||||
TARGET_DEVICES += compulab_trimslice
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Generic
|
||||
NAME:=Generic
|
||||
endef
|
||||
|
||||
define Profile/Generic/Description
|
||||
Generic Profile
|
||||
endef
|
||||
$(eval $(call Profile,Generic))
|
||||
@ -1,5 +1,5 @@
|
||||
ARCH:=x86_64
|
||||
BOARDNAME:=x64 64bit
|
||||
BOARDNAME:=x64_64
|
||||
DEFAULT_PACKAGES += kmod-button-hotplug kmod-e1000e kmod-e1000 kmod-igb kmod-bnx2
|
||||
|
||||
define Target/Description
|
||||
|
||||
@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
ARCH:=i386
|
||||
BOARD:=x86
|
||||
BOARDNAME:=x86
|
||||
FEATURES:=squashfs vdi vmdk pcmcia fpu
|
||||
FEATURES:=squashfs ext4 vdi vmdk pcmcia targz fpu boot-part rootfs-part
|
||||
SUBTARGETS:=64 generic zen legacy geode
|
||||
MAINTAINER:=Felix Fietkau <nbd@nbd.name>
|
||||
|
||||
@ -27,6 +27,9 @@ kmod-usb-net kmod-usb-net-asix kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8150 km
|
||||
|
||||
$(eval $(call BuildTarget))
|
||||
|
||||
$(eval $(call $(if $(CONFIG_TARGET_ROOTFS_ISO),RequireCommand,Ignore),mkisofs, \
|
||||
Please install mkisofs. \
|
||||
$(eval $(call $(if $(CONFIG_ISO_IMAGES),SetupHostCommand,Ignore),mkisofs, \
|
||||
Please install mkisofs. , \
|
||||
mkisofs -v 2>&1 , \
|
||||
genisoimage -v 2>&1 | grep genisoimage, \
|
||||
xorrisofs -v 2>&1 | grep xorriso \
|
||||
))
|
||||
|
||||
@ -1,15 +1,16 @@
|
||||
# Copyright (C) 2012-2015 OpenWrt.org
|
||||
|
||||
move_config() {
|
||||
local partdev
|
||||
local partdev parttype=ext4
|
||||
|
||||
. /lib/upgrade/common.sh
|
||||
|
||||
if export_bootdevice && export_partdevice partdev 1; then
|
||||
mkdir -p /boot
|
||||
mount -t ext4 -o rw,noatime "/dev/$partdev" /boot
|
||||
if [ -f /boot/sysupgrade.tgz ]; then
|
||||
mv -f /boot/sysupgrade.tgz /
|
||||
part_magic_fat "/dev/$partdev" && parttype=vfat
|
||||
mount -t $parttype -o rw,noatime "/dev/$partdev" /boot
|
||||
if [ -f "/boot/sysupgrade.tgz" ]; then
|
||||
mv -f "/boot/sysupgrade.tgz" /
|
||||
fi
|
||||
mount --bind /boot/boot /boot
|
||||
fi
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
upgrade_bootloader() {
|
||||
local diskdev
|
||||
|
||||
. /lib/upgrade/common.sh
|
||||
|
||||
if [ ! -f /boot/grub/upgraded ] && export_bootdevice && export_partdevice diskdev 0; then
|
||||
part_magic_efi "/dev/$diskdev" && return 0
|
||||
echo "(hd0) /dev/$diskdev" > /tmp/device.map
|
||||
/usr/sbin/grub-bios-setup \
|
||||
-m "/tmp/device.map" \
|
||||
-d "/boot/grub" \
|
||||
-r "hd0,msdos1" \
|
||||
"/dev/$diskdev" \
|
||||
&& touch /boot/grub/upgraded
|
||||
fi
|
||||
}
|
||||
|
||||
[ "$INITRAMFS" = "1" ] || boot_hook_add preinit_main upgrade_bootloader
|
||||
@ -1,3 +1,5 @@
|
||||
RAMFS_COPY_BIN='grub-bios-setup'
|
||||
|
||||
platform_check_image() {
|
||||
local diskdev partdev diff
|
||||
[ "$#" -gt 1 ] && return 1
|
||||
@ -17,8 +19,8 @@ platform_check_image() {
|
||||
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b 2>/dev/null
|
||||
echo "Extract boot sector from the image"
|
||||
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -35,15 +37,38 @@ platform_check_image() {
|
||||
}
|
||||
|
||||
platform_copy_config() {
|
||||
local partdev
|
||||
local partdev parttype=ext4
|
||||
|
||||
if export_partdevice partdev 1; then
|
||||
mount -t ext4 -o rw,noatime "/dev/$partdev" /mnt
|
||||
cp -af "$CONF_TAR" /mnt/
|
||||
part_magic_fat "/dev/$partdev" && parttype=vfat
|
||||
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
||||
cp -af "$CONF_TAR" "/mnt/"
|
||||
umount /mnt
|
||||
fi
|
||||
}
|
||||
|
||||
platform_do_bootloader_upgrade() {
|
||||
local bootpart parttable=msdos
|
||||
local diskdev="$1"
|
||||
|
||||
if export_partdevice bootpart 1; then
|
||||
mkdir -p /tmp/boot
|
||||
mount -o rw,noatime "/dev/$bootpart" /tmp/boot
|
||||
echo "(hd0) /dev/$diskdev" > /tmp/device.map
|
||||
part_magic_efi "/dev/$diskdev" && parttable=gpt
|
||||
|
||||
echo "Upgrading bootloader on /dev/$diskdev..."
|
||||
grub-bios-setup \
|
||||
-m "/tmp/device.map" \
|
||||
-d "/tmp/boot/boot/grub" \
|
||||
-r "hd0,${parttable}1" \
|
||||
"/dev/$diskdev" \
|
||||
&& touch /tmp/boot/boot/grub/upgraded
|
||||
|
||||
umount /tmp/boot
|
||||
fi
|
||||
}
|
||||
|
||||
platform_do_upgrade() {
|
||||
local diskdev partdev diff
|
||||
|
||||
@ -54,11 +79,11 @@ platform_do_upgrade() {
|
||||
|
||||
sync
|
||||
|
||||
if [ "$SAVE_PARTITIONS" = "1" ]; then
|
||||
if [ "$UPGRADE_OPT_SAVE_PARTITIONS" = "1" ]; then
|
||||
get_partitions "/dev/$diskdev" bootdisk
|
||||
|
||||
#extract the boot sector from the image
|
||||
get_image "$@" | dd of=/tmp/image.bs count=1 bs=512b
|
||||
echo "Extract boot sector from the image"
|
||||
get_image_dd "$1" of=/tmp/image.bs count=63 bs=512b
|
||||
|
||||
get_partitions /tmp/image.bs image
|
||||
|
||||
@ -69,7 +94,7 @@ platform_do_upgrade() {
|
||||
fi
|
||||
|
||||
if [ -n "$diff" ]; then
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=4096 conv=fsync
|
||||
|
||||
# Separate removal and addtion is necessary; otherwise, partition 1
|
||||
# will be missing if it overlaps with the old partition 2
|
||||
@ -83,13 +108,24 @@ platform_do_upgrade() {
|
||||
while read part start size; do
|
||||
if export_partdevice partdev $part; then
|
||||
echo "Writing image to /dev/$partdev..."
|
||||
get_image "$@" | dd of="/dev/$partdev" ibs="512" obs=1M skip="$start" count="$size" conv=fsync
|
||||
get_image_dd "$1" of="/dev/$partdev" ibs=512 obs=1M skip="$start" count="$size" conv=fsync
|
||||
else
|
||||
echo "Unable to find partition $part device, skipped."
|
||||
fi
|
||||
done < /tmp/partmap.image
|
||||
|
||||
#copy partition uuid
|
||||
echo "Writing new UUID to /dev/$diskdev..."
|
||||
get_image "$@" | dd of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
get_image_dd "$1" of="/dev/$diskdev" bs=1 skip=440 count=4 seek=440 conv=fsync
|
||||
|
||||
platform_do_bootloader_upgrade "$diskdev"
|
||||
local parttype=ext4
|
||||
part_magic_efi "/dev/$diskdev" || return 0
|
||||
|
||||
if export_partdevice partdev 1; then
|
||||
part_magic_fat "/dev/$partdev" && parttype=vfat
|
||||
mount -t $parttype -o rw,noatime "/dev/$partdev" /mnt
|
||||
set -- $(dd if="/dev/$diskdev" bs=1 skip=1168 count=16 2>/dev/null | hexdump -v -e '8/1 "%02x "" "2/1 "%02x""-"6/1 "%02x"')
|
||||
sed -i "s/\(PARTUUID=\)[a-f0-9-]\+/\1$4$3$2$1-$6$5-$8$7-$9/ig" /mnt/boot/grub/grub.cfg
|
||||
umount /mnt
|
||||
fi
|
||||
}
|
||||
|
||||
@ -139,6 +139,7 @@ CONFIG_FB_DEFERRED_IO=y
|
||||
CONFIG_FB_EFI=y
|
||||
CONFIG_FB_HYPERV=y
|
||||
# CONFIG_FB_I810 is not set
|
||||
CONFIG_FB_SIMPLE=y
|
||||
CONFIG_FB_SYS_COPYAREA=y
|
||||
CONFIG_FB_SYS_FILLRECT=y
|
||||
CONFIG_FB_SYS_FOPS=y
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2009 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Generic
|
||||
NAME:=Generic
|
||||
PACKAGES:=kmod-3c59x kmod-e100 kmod-e1000 kmod-natsemi kmod-ne2k-pci \
|
||||
kmod-pcnet32 kmod-8139too kmod-r8169 kmod-sis900 kmod-tg3 \
|
||||
kmod-via-rhine kmod-via-velocity
|
||||
endef
|
||||
|
||||
define Profile/Generic/Description
|
||||
Generic Profile
|
||||
endef
|
||||
$(eval $(call Profile,Generic))
|
||||
@ -1,4 +1,4 @@
|
||||
BOARDNAME:=x86 32bit
|
||||
BOARDNAME:=Generic
|
||||
CPU_TYPE :=pentium4
|
||||
FEATURES += audio pci pcie usb
|
||||
DEFAULT_PACKAGES += kmod-button-hotplug
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2009 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Generic
|
||||
NAME:=Generic
|
||||
PACKAGES:= \
|
||||
soloscli linux-atm br2684ctl ppp-mod-pppoa pppdump pppstats \
|
||||
hwclock flashrom tc kmod-pppoa kmod-8139cp kmod-mppe \
|
||||
kmod-usb-ohci-pci kmod-hwmon-lm90 \
|
||||
kmod-via-rhine
|
||||
endef
|
||||
|
||||
define Profile/Generic/Description
|
||||
Generic Profile for all Geode boards.
|
||||
endef
|
||||
$(eval $(call Profile,Generic))
|
||||
@ -1,19 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2009 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Geos
|
||||
NAME:=Geos
|
||||
PACKAGES:= \
|
||||
soloscli linux-atm br2684ctl ppp-mod-pppoa pppdump pppstats \
|
||||
hwclock flashrom tc kmod-pppoa kmod-8139cp kmod-mppe \
|
||||
kmod-usb-ohci-pci kmod-hwmon-lm90
|
||||
endef
|
||||
|
||||
define Profile/Geos/Description
|
||||
Traverse Technologies Geos ADSL router
|
||||
endef
|
||||
$(eval $(call Profile,Geos))
|
||||
7
target/linux/x86/image/64.mk
Normal file
7
target/linux/x86/image/64.mk
Normal file
@ -0,0 +1,7 @@
|
||||
define Device/generic
|
||||
DEVICE_TITLE := Generic x86/64
|
||||
DEVICE_PACKAGES += kmod-amazon-ena kmod-bnx2 kmod-e1000e kmod-e1000 \
|
||||
kmod-forcedeth kmod-igb kmod-ixgbe kmod-amd-xgbe kmod-r8169
|
||||
GRUB2_VARIANT := generic
|
||||
endef
|
||||
TARGET_DEVICES += generic
|
||||
@ -5,27 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/image.mk
|
||||
|
||||
export PATH=$(TARGET_PATH):/sbin
|
||||
|
||||
SUPPORTED_DEVICES :=
|
||||
|
||||
GRUB2_MODULES = biosdisk boot chain configfile ext2 linux ls part_msdos reboot serial vga
|
||||
GRUB2_MODULES_LEGACY = $(GRUB2_MODULES)
|
||||
GRUB2_MODULES_LEGACY += part_gpt search fat exfat
|
||||
GRUB2_MODULES_EFI = boot chain configfile ext2 linux ls part_msdos reboot serial part_gpt part_msdos search fat exfat ext2 efi_gop efi_uga gfxterm
|
||||
GRUB2_MODULES_ISO = biosdisk boot chain configfile iso9660 linux ls part_msdos reboot serial vga
|
||||
GRUB2_VARIANT =
|
||||
GRUB_TERMINALS =
|
||||
GRUB_SERIAL_CONFIG =
|
||||
GRUB_TERMINAL_CONFIG =
|
||||
GRUB_CONSOLE_CMDLINE =
|
||||
GRUB_ROOT = hd0,msdos1
|
||||
|
||||
USE_ATKBD = generic 64
|
||||
|
||||
ifneq ($(strip $(foreach subtarget,$(USE_ATKBD),$(CONFIG_TARGET_x86_$(subtarget)))),)
|
||||
GRUB2_MODULES += at_keyboard
|
||||
GRUB2_MODULES_ISO += at_keyboard
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_GRUB_CONSOLE),)
|
||||
GRUB_CONSOLE_CMDLINE += console=tty0
|
||||
@ -44,313 +28,136 @@ ifneq ($(GRUB_TERMINALS),)
|
||||
GRUB_TERMINAL_CONFIG := terminal_input $(GRUB_TERMINALS); terminal_output $(GRUB_TERMINALS)
|
||||
endif
|
||||
|
||||
SIGNATURE:=$(shell perl -e 'printf("%08x", rand(0xFFFFFFFF))')
|
||||
EFI_SIGNATURE:=$(strip $(shell uuidgen | sed "s/[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]$$/0002/" | tr '[a-z]' '[A-Z]'))
|
||||
ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
|
||||
ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(SIGNATURE)-02)
|
||||
ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
|
||||
GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
|
||||
GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/'))
|
||||
|
||||
GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
|
||||
GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
|
||||
|
||||
ifneq ($(CONFIG_TARGET_x86_xen_domu),)
|
||||
GRUB_ROOT = xen/xvda,msdos1
|
||||
endif
|
||||
BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
|
||||
|
||||
ifneq ($(CONFIG_GRUB_IMAGES)$(CONFIG_EFI_IMAGES),)
|
||||
|
||||
BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
|
||||
|
||||
define Image/cmdline/ext4
|
||||
root=$(ROOTPART) rootfstype=ext4 rootwait
|
||||
endef
|
||||
|
||||
define Image/cmdline/squashfs
|
||||
root=$(ROOTPART) rootfstype=squashfs rootwait
|
||||
endef
|
||||
|
||||
ifneq ($(CONFIG_EFI_IMAGES),)
|
||||
|
||||
define Image/cmdline/efi
|
||||
$(subst $(SIGNATURE)-02,$2,$(call Image/cmdline/$(1)))
|
||||
endef
|
||||
|
||||
define Image/Build/efi
|
||||
# left here because the image builder doesnt need these
|
||||
rm -rf $(KDIR)/root.grub/ || true
|
||||
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
|
||||
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
|
||||
echo '(hd0) $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img' > $(KDIR)/grub2/device.map
|
||||
sed \
|
||||
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
|
||||
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
|
||||
-e 's#@CMDLINE@#$(strip $(call Image/cmdline/efi,$(1),$(EFI_SIGNATURE)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
|
||||
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
|
||||
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
|
||||
-e 's#set root.*#search --file /boot/grub/$(SIGNATURE).cfg --set=root#g' \
|
||||
./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
|
||||
sed \
|
||||
-e 's/(hd0,msdos1)/(hd0,gpt1)/' ./grub-early.cfg > \
|
||||
$(KDIR)/root.grub/boot/grub/grub-early.cfg
|
||||
|
||||
$(CP) $(KDIR)/root.grub/boot/grub/grub.cfg $(KDIR)/root.grub/boot/grub/$(SIGNATURE).cfg
|
||||
grub-mkimage \
|
||||
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
|
||||
-o $(KDIR)/grub2/core.img \
|
||||
-O i386-pc \
|
||||
-p '(hd0,gpt1)/boot/grub' \
|
||||
-c $(KDIR)/root.grub/boot/grub/grub-early.cfg \
|
||||
$(GRUB2_MODULES_LEGACY)
|
||||
$(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/
|
||||
|
||||
# Build the efi grub version
|
||||
rm -rf $(KDIR)/grub2.efi/ || true
|
||||
$(INSTALL_DIR) $(KDIR)/grub2.efi/efi/boot/
|
||||
|
||||
# Generate the grub search root config (grub will search for the $(SIGNATURE).cfg file placed on the boot partition as grub does not support search of GPT UUID yet)
|
||||
echo "search --file /boot/grub/$(SIGNATURE).cfg --set=root" > $(KDIR)/grub2.efi/efi/boot/grub.cfg
|
||||
echo "configfile /boot/grub/grub.cfg" >> $(KDIR)/grub2.efi/efi/boot/grub.cfg
|
||||
|
||||
# Create the EFI grub binary
|
||||
grub-mkimage-efi \
|
||||
-d $(STAGING_DIR_HOST)/lib/grub/x86_64-efi \
|
||||
-o $(KDIR)/grub2.efi/efi/boot/bootx64.efi \
|
||||
-O x86_64-efi \
|
||||
-p /efi/boot \
|
||||
-c $(KDIR)/grub2.efi/efi/boot/grub.cfg \
|
||||
$(GRUB2_MODULES_EFI)
|
||||
|
||||
# Generate the EFI VFAT bootfs
|
||||
rm $(KDIR)/kernel.efi || true
|
||||
mkfs.fat -C $(KDIR)/kernel.efi -S 512 1024
|
||||
mcopy -s -i "$(KDIR)/kernel.efi" $(KDIR)/grub2.efi/* ::/
|
||||
|
||||
SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" ./gen_image_efi.sh \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
|
||||
$(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \
|
||||
1 $(KDIR)/kernel.efi \
|
||||
1 \
|
||||
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \
|
||||
define Build/combined
|
||||
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
|
||||
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
|
||||
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.boot/boot/grub/
|
||||
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img \
|
||||
$@.boot/boot/grub/core.img
|
||||
$(if $(filter $(1),efi),
|
||||
$(INSTALL_DIR) $@.boot/efi/boot
|
||||
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi $@.boot/efi/boot/
|
||||
)
|
||||
PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
|
||||
$(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \
|
||||
$@ \
|
||||
$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
|
||||
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
|
||||
256
|
||||
|
||||
# Setup legacy bios for hybrid MBR (optional)
|
||||
grub-bios-setup \
|
||||
--device-map="$(KDIR)/grub2/device.map" \
|
||||
-d "$(KDIR)/grub2" \
|
||||
-r "hd0,msdos1" \
|
||||
"$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
|
||||
# Convert the MBR partition to GPT and set EFI ROOTFS signature
|
||||
dd if=/dev/zero of="$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img" bs=512 count=34 conv=notrunc oflag=append
|
||||
sgdisk -g "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
sgdisk -t 2:EF00 "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
sgdisk -t 3:EF02 "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
sgdisk -u 4:$(EFI_SIGNATURE) "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
sgdisk -h "$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
|
||||
# Setup EFI grub
|
||||
grub-bios-setup-efi \
|
||||
--device-map="$(KDIR)/grub2/device.map" \
|
||||
-d "$(KDIR)/grub2" \
|
||||
-r "hd0,gpt1" \
|
||||
"$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img"
|
||||
endef
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_GRUB_IMAGES),)
|
||||
define Image/Build/grub2
|
||||
# left here because the image builder doesnt need these
|
||||
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
|
||||
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
|
||||
grub-mkimage \
|
||||
-p /boot/grub \
|
||||
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
|
||||
-o $(KDIR)/grub2/core.img \
|
||||
-O i386-pc \
|
||||
-c ./grub-early.cfg \
|
||||
$(GRUB2_MODULES)
|
||||
$(CP) $(STAGING_DIR_HOST)/lib/grub/i386-pc/*.img $(KDIR)/grub2/
|
||||
echo '(hd0) $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img' > $(KDIR)/grub2/device.map
|
||||
sed \
|
||||
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
|
||||
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
|
||||
-e 's#@CMDLINE@#$(strip $(call Image/cmdline/$(1)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
|
||||
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
|
||||
-e 's#@ROOT@#$(GRUB_ROOT)#g' \
|
||||
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
|
||||
./grub.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
|
||||
-$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
|
||||
PADDING="$(CONFIG_TARGET_IMAGES_PAD)" SIGNATURE="$(SIGNATURE)" PATH="$(TARGET_PATH)" $(SCRIPT_DIR)/gen_image_generic.sh \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(CONFIG_TARGET_KERNEL_PARTSIZE) $(KDIR)/root.grub \
|
||||
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(KDIR)/root.$(1) \
|
||||
256
|
||||
grub-bios-setup \
|
||||
--device-map="$(KDIR)/grub2/device.map" \
|
||||
-d "$(KDIR)/grub2" \
|
||||
-r "hd0,msdos1" \
|
||||
"$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img"
|
||||
endef
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
define Image/Build/squashfs
|
||||
dd if=/dev/zero bs=128k count=1 >> $(KDIR)/root.squashfs
|
||||
endef
|
||||
|
||||
define Image/Build/iso
|
||||
$(INSTALL_DIR) $(KDIR)/root.grub/boot/grub $(KDIR)/grub2
|
||||
$(CP) $(KDIR)/bzImage $(KDIR)/root.grub/boot/vmlinuz
|
||||
grub-mkimage \
|
||||
-p /boot/grub \
|
||||
-d $(STAGING_DIR_HOST)/lib/grub/i386-pc \
|
||||
-o $(KDIR)/grub2/eltorito.img \
|
||||
-O i386-pc \
|
||||
-c ./grub-early.cfg \
|
||||
$(GRUB2_MODULES_ISO)
|
||||
define Build/grub-config
|
||||
rm -fR $@.boot
|
||||
$(INSTALL_DIR) $@.boot/boot/grub
|
||||
sed \
|
||||
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
|
||||
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
|
||||
-e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
|
||||
-e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
|
||||
-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
|
||||
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
|
||||
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
|
||||
./grub-$(1).cfg > $@.boot/boot/grub/grub.cfg
|
||||
endef
|
||||
|
||||
define Build/grub-install
|
||||
rm -fR $@.grub2
|
||||
$(INSTALL_DIR) $@.grub2
|
||||
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/
|
||||
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img $@.grub2/core.img
|
||||
echo '(hd0) $@' > $@.grub2/device.map
|
||||
$(STAGING_DIR_HOST)/bin/grub-bios-setup \
|
||||
-m "$@.grub2/device.map" \
|
||||
-d "$@.grub2" \
|
||||
-r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \
|
||||
$@
|
||||
endef
|
||||
|
||||
define Build/iso
|
||||
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
|
||||
cat \
|
||||
$(STAGING_DIR_HOST)/lib/grub/i386-pc/cdboot.img \
|
||||
$(KDIR)/grub2/eltorito.img \
|
||||
> $(KDIR)/root.grub/boot/grub/eltorito.img
|
||||
sed \
|
||||
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
|
||||
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
|
||||
-e 's#@CMDLINE@#root=/dev/sr0 rootfstype=iso9660 rootwait $(strip $(call Image/cmdline/$(1)) $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
|
||||
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
|
||||
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
|
||||
./grub-iso.cfg > $(KDIR)/root.grub/boot/grub/grub.cfg
|
||||
-$(CP) $(STAGING_DIR_ROOT)/boot/. $(KDIR)/root.grub/boot/
|
||||
$(STAGING_DIR_IMAGE)/grub2/cdboot.img \
|
||||
$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
|
||||
> $@.boot/boot/grub/eltorito.img
|
||||
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
|
||||
$(if $(filter $(1),efi),
|
||||
mkfs.fat -C $@.boot/boot/grub/isoboot.img -S 512 1440
|
||||
mmd -i $@.boot/boot/grub/isoboot.img ::/efi ::/efi/boot
|
||||
mcopy -i $@.boot/boot/grub/isoboot.img \
|
||||
$(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
|
||||
::/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi
|
||||
)
|
||||
mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
|
||||
-o $(KDIR)/root.iso $(KDIR)/root.grub $(TARGET_DIR)
|
||||
$(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \
|
||||
-o $@ $@.boot $(TARGET_DIR)
|
||||
endef
|
||||
|
||||
ifneq ($(CONFIG_VDI_IMAGES),)
|
||||
define Image/Build/vdi
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vdi \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi
|
||||
# XXX: VBoxManage insists on setting perms to 0600
|
||||
chmod 0644 $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vdi
|
||||
endef
|
||||
define Image/Build/vdi_efi
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vdi \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi
|
||||
# XXX: VBoxManage insists on setting perms to 0600
|
||||
chmod 0644 $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vdi
|
||||
endef
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_VMDK_IMAGES),)
|
||||
define Image/Build/vmdk
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vmdk || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vmdk
|
||||
#build the ESXI VMDK with
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi.vmdk || true
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi-flat.vmdk || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic,subformat=monolithicFlat \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1)-esxi.vmdk
|
||||
endef
|
||||
define Image/Build/vmdk_efi
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vmdk || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O vmdk -o adapter_type=lsilogic \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vmdk
|
||||
endef
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_VHD_IMAGES),)
|
||||
define Image/Build/vhd
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vhdx || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -O vhdx \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).vhdx
|
||||
endef
|
||||
define Image/Build/vhd_efi
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vhdx || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -O vhdx \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).vhdx
|
||||
endef
|
||||
endif
|
||||
|
||||
ifneq ($(CONFIG_QCOW2_IMAGES),)
|
||||
define Image/Build/qcow2
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).qcow2 || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O qcow2 \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).qcow2
|
||||
endef
|
||||
define Image/Build/qcow2_efi
|
||||
rm $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).qcow2 || true
|
||||
$(STAGING_DIR_HOST)/bin/qemu-img convert -f raw -O qcow2 \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img \
|
||||
$(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).qcow2
|
||||
endef
|
||||
endif
|
||||
|
||||
define Image/Build/gzip
|
||||
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
|
||||
ifneq ($(CONFIG_GRUB_IMAGES),)
|
||||
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-combined-$(1).img
|
||||
endif
|
||||
ifneq ($(CONFIG_EFI_IMAGES),)
|
||||
gzip -f9n $(BIN_DIR)/$(IMG_PREFIX)-uefi-gpt-$(1).img
|
||||
endif
|
||||
endef
|
||||
|
||||
ifneq ($(CONFIG_TARGET_IMAGES_GZIP),)
|
||||
define Image/Build/gzip/ext4
|
||||
$(call Image/Build/gzip,ext4)
|
||||
endef
|
||||
define Image/Build/gzip/squashfs
|
||||
$(call Image/Build/gzip,squashfs)
|
||||
endef
|
||||
endif
|
||||
|
||||
define Image/BuildKernel
|
||||
$(CP) $(KDIR)/bzImage $(BIN_DIR)/$(IMG_PREFIX)-vmlinuz
|
||||
endef
|
||||
|
||||
define Image/Prepare
|
||||
$(call Image/Prepare/grub2)
|
||||
endef
|
||||
|
||||
define Image/Build/Initramfs
|
||||
$(CP) $(KDIR)/bzImage-initramfs $(BIN_DIR)/$(IMG_PREFIX)-ramfs.bzImage
|
||||
endef
|
||||
|
||||
define Image/Build
|
||||
$(call Image/Build/$(1))
|
||||
ifneq ($(1),iso)
|
||||
$(call Image/Build/grub2,$(1))
|
||||
$(call Image/Build/efi,$(1))
|
||||
ifneq ($(CONFIG_GRUB_IMAGES),)
|
||||
$(call Image/Build/vdi,$(1))
|
||||
$(call Image/Build/vmdk,$(1))
|
||||
$(call Image/Build/vhd,$(1))
|
||||
$(call Image/Build/qcow2,$(1))
|
||||
endif
|
||||
ifneq ($(CONFIG_EFI_IMAGES),)
|
||||
$(call Image/Build/vdi_efi,$(1))
|
||||
$(call Image/Build/vmdk_efi,$(1))
|
||||
$(call Image/Build/vhd_efi,$(1))
|
||||
$(call Image/Build/qcow2_efi,$(1))
|
||||
endif
|
||||
$(CP) $(KDIR)/root.$(1) $(BIN_DIR)/$(IMG_PREFIX)-rootfs-$(1).img
|
||||
DEVICE_VARS += GRUB2_VARIANT
|
||||
define Device/Default
|
||||
ARTIFACT/image.iso := grub-config iso | iso
|
||||
IMAGE/combined.img := grub-config pc | combined | grub-install | append-metadata
|
||||
IMAGE/combined.img.gz := grub-config pc | combined | grub-install | gzip | append-metadata
|
||||
IMAGE/combined.qcow2 := grub-config pc | combined | grub-install | qemu-image qcow2
|
||||
IMAGE/combined.vdi := grub-config pc | combined | grub-install | qemu-image vdi
|
||||
IMAGE/combined.vhdx := grub-config pc | combined | grub-install | qemu-image vhdx
|
||||
IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
|
||||
IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE)
|
||||
IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip
|
||||
ARTIFACT/image-efi.iso := grub-config iso | iso efi
|
||||
IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi | append-metadata
|
||||
IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata
|
||||
IMAGE/combined-efi.qcow2 := grub-config efi | combined efi | grub-install efi | qemu-image qcow2
|
||||
IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi
|
||||
IMAGE/combined-efi.vhdx := grub-config efi | combined efi | grub-install efi | qemu-image vhdx
|
||||
IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
|
||||
ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
|
||||
IMAGES-y := rootfs.img.gz
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
|
||||
else
|
||||
$(CP) $(KDIR)/root.iso $(BIN_DIR)/$(IMG_PREFIX).iso
|
||||
IMAGES-y := rootfs.img
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
|
||||
endif
|
||||
$(CP) $(KDIR)/bzImage $(BIN_DIR)/$(IMG_PREFIX)-vmlinuz
|
||||
$(call Image/Build/gzip/$(1))
|
||||
ifeq ($(CONFIG_TARGET_ROOTFS_INITRAMFS),y)
|
||||
$(call Image/Build/Initramfs)
|
||||
endif
|
||||
KERNEL := kernel-bin
|
||||
KERNEL_INSTALL := 1
|
||||
KERNEL_NAME := bzImage
|
||||
ifeq ($(CONFIG_ISO_IMAGES),y)
|
||||
ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso
|
||||
ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso
|
||||
endif
|
||||
ifeq ($(CONFIG_QCOW2_IMAGES),y)
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.qcow2
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.qcow2
|
||||
endif
|
||||
ifeq ($(CONFIG_VDI_IMAGES),y)
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi
|
||||
endif
|
||||
ifeq ($(CONFIG_VHDX_IMAGES),y)
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vhdx
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vhdx
|
||||
endif
|
||||
ifeq ($(CONFIG_VMDK_IMAGES),y)
|
||||
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk
|
||||
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk
|
||||
endif
|
||||
IMAGES := $$(IMAGES-y)
|
||||
ARTIFACTS := $$(ARTIFACTS-y)
|
||||
SUPPORTED_DEVICES :=
|
||||
endef
|
||||
|
||||
include $(SUBTARGET).mk
|
||||
|
||||
$(eval $(call BuildImage))
|
||||
|
||||
|
||||
@ -1,44 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
set -x
|
||||
[ $# == 8 -o $# == 9 ] || {
|
||||
echo "SYNTAX: $0 <file> <kernel size> <kernel directory> <efi size> <efi image> <efigrubmodule size> <rootfs size> <rootfs image> [<align>]"
|
||||
exit 1
|
||||
}
|
||||
|
||||
OUTPUT="$1"
|
||||
KERNELSIZE="$2"
|
||||
KERNELDIR="$3"
|
||||
EFISIZE="$4"
|
||||
EFIIMAGE="$5"
|
||||
EFIGRUBSIZE="$6"
|
||||
ROOTFSSIZE="$7"
|
||||
ROOTFSIMAGE="$8"
|
||||
ALIGN="$9"
|
||||
|
||||
rm -f "$OUTPUT"
|
||||
|
||||
head=16
|
||||
sect=63
|
||||
cyl=$(( ($KERNELSIZE + $EFISIZE + $EFIGRUBSIZE + $ROOTFSSIZE) * 1024 * 1024 / ($head * $sect * 512) ))
|
||||
|
||||
# create partition table
|
||||
set `ptgen -o "$OUTPUT" -h $head -s $sect -p ${KERNELSIZE}m -p ${EFISIZE}m -p ${EFIGRUBSIZE}m -p ${ROOTFSSIZE}m ${ALIGN:+-l $ALIGN} ${SIGNATURE:+-S 0x$SIGNATURE}`
|
||||
|
||||
KERNELOFFSET="$(($1 / 512))"
|
||||
KERNELSIZE="$2"
|
||||
EFIOFFSET="$(($3 / 512))"
|
||||
EFISIZE="$(($4 / 512))"
|
||||
EFIGRUBOFFSET="$(($5 / 512))"
|
||||
EFIGRUBSIZE="$(($6 / 512))"
|
||||
ROOTFSOFFSET="$(($7 / 512))"
|
||||
ROOTFSSIZE="$(($8 / 512))"
|
||||
|
||||
dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
|
||||
dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
|
||||
dd if="$EFIIMAGE" of="$OUTPUT" bs=512 seek="$EFIOFFSET" conv=notrunc
|
||||
|
||||
[ -n "$NOGRUB" ] && exit 0
|
||||
|
||||
make_ext4fs -J -l "$KERNELSIZE" "$OUTPUT.kernel" "$KERNELDIR"
|
||||
dd if="$OUTPUT.kernel" of="$OUTPUT" bs=512 seek="$KERNELOFFSET" conv=notrunc
|
||||
rm -f "$OUTPUT.kernel"
|
||||
8
target/linux/x86/image/generic.mk
Normal file
8
target/linux/x86/image/generic.mk
Normal file
@ -0,0 +1,8 @@
|
||||
define Device/generic
|
||||
DEVICE_TITLE := Generic x86
|
||||
DEVICE_PACKAGES += kmod-3c59x kmod-8139too kmod-e100 kmod-e1000 kmod-natsemi \
|
||||
kmod-ne2k-pci kmod-pcnet32 kmod-r8169 kmod-sis900 kmod-tg3 \
|
||||
kmod-via-rhine kmod-via-velocity kmod-forcedeth
|
||||
GRUB2_VARIANT := generic
|
||||
endef
|
||||
TARGET_DEVICES += generic
|
||||
14
target/linux/x86/image/geode.mk
Normal file
14
target/linux/x86/image/geode.mk
Normal file
@ -0,0 +1,14 @@
|
||||
define Device/generic
|
||||
DEVICE_TITLE := Generic x86/Geode
|
||||
DEVICE_PACKAGES += kmod-crypto-cbc kmod-crypto-hw-geode kmod-ledtrig-gpio
|
||||
GRUB2_VARIANT := legacy
|
||||
endef
|
||||
TARGET_DEVICES += generic
|
||||
|
||||
define Device/geos
|
||||
$(call Device/generic)
|
||||
DEVICE_TITLE := Traverse Technologies Geos
|
||||
DEVICE_PACKAGES += br2684ctl flashrom kmod-hwmon-lm90 kmod-mppe kmod-pppoa \
|
||||
kmod-usb-ohci-pci linux-atm ppp-mod-pppoa pppdump pppstats soloscli tc
|
||||
endef
|
||||
TARGET_DEVICES += geos
|
||||
13
target/linux/x86/image/grub-efi.cfg
Normal file
13
target/linux/x86/image/grub-efi.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
@SERIAL_CONFIG@
|
||||
@TERMINAL_CONFIG@
|
||||
|
||||
set default="0"
|
||||
set timeout="@TIMEOUT@"
|
||||
set root='(hd0,gpt1)'
|
||||
|
||||
menuentry "@TITLE@" {
|
||||
linux /boot/vmlinuz @GPT_ROOTPART@ @CMDLINE@ noinitrd
|
||||
}
|
||||
menuentry "@TITLE@ (failsafe)" {
|
||||
linux /boot/vmlinuz failsafe=true @GPT_ROOTPART@ @CMDLINE@ noinitrd
|
||||
}
|
||||
@ -3,8 +3,13 @@
|
||||
|
||||
set default="0"
|
||||
set timeout="@TIMEOUT@"
|
||||
set root='(cd)'
|
||||
|
||||
if [ "${grub_platform}" = "efi" ]; then
|
||||
set root='(cd0)'
|
||||
else
|
||||
set root='(cd)'
|
||||
fi
|
||||
|
||||
menuentry "@TITLE@" {
|
||||
linux /boot/vmlinuz @CMDLINE@ noinitrd
|
||||
linux /boot/vmlinuz root=/dev/sr0 rootfstype=iso9660 rootwait @CMDLINE@ noinitrd
|
||||
}
|
||||
|
||||
13
target/linux/x86/image/grub-pc.cfg
Normal file
13
target/linux/x86/image/grub-pc.cfg
Normal file
@ -0,0 +1,13 @@
|
||||
@SERIAL_CONFIG@
|
||||
@TERMINAL_CONFIG@
|
||||
|
||||
set default="0"
|
||||
set timeout="@TIMEOUT@"
|
||||
set root='(hd0,msdos1)'
|
||||
|
||||
menuentry "@TITLE@" {
|
||||
linux /boot/vmlinuz @ROOTPART@ @CMDLINE@ noinitrd
|
||||
}
|
||||
menuentry "@TITLE@ (failsafe)" {
|
||||
linux /boot/vmlinuz failsafe=true @ROOTPART@ @CMDLINE@ noinitrd
|
||||
}
|
||||
@ -1,13 +0,0 @@
|
||||
@SERIAL_CONFIG@
|
||||
@TERMINAL_CONFIG@
|
||||
|
||||
set default="0"
|
||||
set timeout="@TIMEOUT@"
|
||||
set root='(@ROOT@)'
|
||||
|
||||
menuentry "@TITLE@" {
|
||||
linux /boot/vmlinuz @CMDLINE@ noinitrd
|
||||
}
|
||||
menuentry "@TITLE@ (failsafe)" {
|
||||
linux /boot/vmlinuz failsafe=true @CMDLINE@ noinitrd
|
||||
}
|
||||
8
target/linux/x86/image/legacy.mk
Normal file
8
target/linux/x86/image/legacy.mk
Normal file
@ -0,0 +1,8 @@
|
||||
define Device/generic
|
||||
DEVICE_TITLE := Generic x86/legacy
|
||||
DEVICE_PACKAGES += kmod-3c59x kmod-8139too kmod-e100 kmod-e1000 \
|
||||
kmod-natsemi kmod-ne2k-pci kmod-pcnet32 kmod-r8169 kmod-sis900 \
|
||||
kmod-tg3 kmod-via-rhine kmod-via-velocity kmod-forcedeth
|
||||
GRUB2_VARIANT := legacy
|
||||
endef
|
||||
TARGET_DEVICES += generic
|
||||
5
target/linux/x86/image/zen.mk
Normal file
5
target/linux/x86/image/zen.mk
Normal file
@ -0,0 +1,5 @@
|
||||
define Device/generic
|
||||
DEVICE_TITLE := Generic Zen Architecture
|
||||
GRUB2_VARIANT := generic
|
||||
endef
|
||||
TARGET_DEVICES += generic
|
||||
@ -1,18 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2009 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Generic
|
||||
NAME:=Generic
|
||||
PACKAGES:=kmod-3c59x kmod-e100 kmod-e1000 kmod-natsemi kmod-ne2k-pci \
|
||||
kmod-pcnet32 kmod-8139too kmod-r8169 kmod-sis900 kmod-tg3 \
|
||||
kmod-via-rhine kmod-via-velocity
|
||||
endef
|
||||
|
||||
define Profile/Generic/Description
|
||||
Generic Profile
|
||||
endef
|
||||
$(eval $(call Profile,Generic))
|
||||
@ -1,4 +1,4 @@
|
||||
BOARDNAME:=Legacy x86 (i586)
|
||||
BOARDNAME:=Legacy
|
||||
|
||||
define Target/Description
|
||||
Build firmware images for legacy x86 based boards
|
||||
|
||||
@ -1,15 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2006-2015 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
define Profile/Generic
|
||||
NAME:=Generic
|
||||
endef
|
||||
|
||||
define Profile/Generic/Description
|
||||
Generic Profile
|
||||
endef
|
||||
$(eval $(call Profile,Generic))
|
||||
@ -34,7 +34,6 @@ tools-$(CONFIG_TARGET_ath79) += lzma-old squashfs
|
||||
tools-$(CONFIG_TARGET_mxs) += elftosb sdimage
|
||||
tools-$(CONFIG_TARGET_orion_generic) += wrt350nv2-builder upslug2
|
||||
tools-$(CONFIG_TARGET_tegra) += cbootimage cbootimage-configs
|
||||
tools-$(CONFIG_TARGET_x86) += qemu
|
||||
tools-$(CONFIG_USES_MINOR) += kernel2minor
|
||||
tools-$(CONFIG_USE_SPARSE) += sparse
|
||||
|
||||
@ -68,7 +67,6 @@ $(curdir)/mpfr/compile := $(curdir)/gmp/compile
|
||||
$(curdir)/mtd-utils/compile := $(curdir)/libtool/compile $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
|
||||
$(curdir)/padjffs2/compile := $(curdir)/findutils/compile
|
||||
$(curdir)/patchelf/compile := $(curdir)/libtool/compile
|
||||
$(curdir)/qemu/compile := $(curdir)/e2fsprogs/compile $(curdir)/zlib/compile
|
||||
$(curdir)/quilt/compile := $(curdir)/autoconf/compile $(curdir)/findutils/compile
|
||||
$(curdir)/sdcc/compile := $(curdir)/bison/compile
|
||||
$(curdir)/squashfs/compile := $(curdir)/lzma-old/compile
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bison
|
||||
PKG_VERSION:=3.7.1
|
||||
PKG_VERSION:=3.7.4
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@GNU/$(PKG_NAME)
|
||||
PKG_HASH:=55c215521a13982a9bee68cd42eed51a65713f96c530a739a57de4438ac1bb69
|
||||
PKG_HASH:=a3b5813f48a11e540ef26f46e4d288c0c25c7907d9879ae50e430ec49f63c010
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
--- a/lib/stdio.in.h
|
||||
+++ b/lib/stdio.in.h
|
||||
@@ -816,14 +816,6 @@ _GL_WARN_ON_USE (getline, "getline is un
|
||||
@@ -835,14 +835,6 @@ _GL_WARN_ON_USE (getline, "getline is un
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -12,6 +12,6 @@
|
||||
-_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead");
|
||||
-#endif
|
||||
-
|
||||
#if @GNULIB_OBSTACK_PRINTF@ || @GNULIB_OBSTACK_PRINTF_POSIX@
|
||||
struct obstack;
|
||||
/* Grow an obstack with formatted output. Return the number of
|
||||
#if defined _WIN32 && !defined __CYGWIN__
|
||||
# undef getw
|
||||
# define getw _getw
|
||||
|
||||
@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=expat
|
||||
PKG_CPE_ID:=cpe:/a:libexpat:expat
|
||||
PKG_VERSION:=2.2.9
|
||||
PKG_VERSION:=2.2.10
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
|
||||
PKG_HASH:=f1063084dc4302a427dabcca499c8312b3a32a29b7d2506653ecc8f950a9a237
|
||||
PKG_HASH:=b2c160f1b60e92da69de8e12333096aeb0c3bf692d41c60794de278af72135a5
|
||||
PKG_SOURCE_URL:=https://github.com/libexpat/libexpat/releases/download/R_$(subst .,_,$(PKG_VERSION))
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gmp
|
||||
PKG_VERSION:=6.2.0
|
||||
PKG_VERSION:=6.2.1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=@GNU/gmp/
|
||||
PKG_HASH:=258e6cd51b3fbdfc185c716d55f82c08aff57df0c6fbd143cf6ed561267a1526
|
||||
PKG_HASH:=fd4829912cddd12f84181c3451cc752be224643e87fac497b69edddadc49b4f2
|
||||
|
||||
HOST_FIXUP:=autoreconf
|
||||
|
||||
|
||||
@ -7,11 +7,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mpc
|
||||
PKG_VERSION:=1.2.0
|
||||
PKG_VERSION:=1.2.1
|
||||
|
||||
PKG_SOURCE_URL:=@GNU/mpc/
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_HASH:=e90f2d99553a9c19911abdb4305bf8217106a957e3994436428572c8dfe8fda6
|
||||
PKG_HASH:=17503d2c395dfcf106b622dc142683c1199431d095367c6aacba6eec30340459
|
||||
|
||||
HOST_BUILD_PARALLEL:=1
|
||||
|
||||
|
||||
@ -1,45 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2010-2012 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=qemu
|
||||
PKG_CPE_ID:=cpe:/a:qemu:qemu
|
||||
PKG_VERSION:=0.14.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE_URL:=@SAVANNAH/qemu
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_HASH:=33ceae3fbe516f2cbb151dc98d16c8ccfec74b1056674ad715e75a2f7fed45c3
|
||||
|
||||
include $(INCLUDE_DIR)/host-build.mk
|
||||
|
||||
HOST_CFLAGS += \
|
||||
-I$(STAGING_DIR_HOST)/include/e2fsprogs \
|
||||
-DAES_cbc_encrypt=QEMU_AES_cbc_encrypt \
|
||||
-DAES_decrypt=QEMU_AES_decrypt \
|
||||
-DAES_encrypt=QEMU_AES_encrypt \
|
||||
-DAES_set_decrypt_key=QEMU_AES_set_decrypt_key \
|
||||
-DAES_set_encrypt_key=QEMU_AES_set_encrypt_key
|
||||
|
||||
HOST_CONFIGURE_VARS := \
|
||||
CFLAGS="$(HOST_CFLAGS)" \
|
||||
LDFLAGS="$(HOST_LDFLAGS)"
|
||||
|
||||
HOST_CONFIGURE_ARGS := \
|
||||
--extra-cflags="$(HOST_CFLAGS)" \
|
||||
--enable-uuid
|
||||
|
||||
define Host/Compile
|
||||
$(MAKE) -C $(HOST_BUILD_DIR) qemu-img
|
||||
endef
|
||||
|
||||
define Host/Install
|
||||
$(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
|
||||
$(INSTALL_BIN) $(HOST_BUILD_DIR)/qemu-img $(STAGING_DIR_HOST)/bin
|
||||
endef
|
||||
|
||||
$(eval $(call HostBuild))
|
||||
@ -1,75 +0,0 @@
|
||||
From 6afca0fc5430db0300fe53f2b9cd7d071a3925bb Mon Sep 17 00:00:00 2001
|
||||
From: Alexander Graf <agraf@suse.de>
|
||||
Date: Wed, 25 May 2011 00:46:55 +0200
|
||||
Subject: [PATCH 01/12] vmdk: fix endianness bugs
|
||||
|
||||
The vmdk code is sloppy when handling the header descriptor during
|
||||
creation of an image. Fix all header accesses in the create path to
|
||||
either store native endianness or convert it when appropriate.
|
||||
|
||||
Reported-by: Yury Tsarev <ytsarev@novell.com>
|
||||
Signed-off-by: Alexander Graf <agraf@suse.de>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 22 ++++++++++++++--------
|
||||
1 file changed, 14 insertions(+), 8 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -716,11 +716,11 @@ static int vmdk_create(const char *filen
|
||||
return -errno;
|
||||
magic = cpu_to_be32(VMDK4_MAGIC);
|
||||
memset(&header, 0, sizeof(header));
|
||||
- header.version = cpu_to_le32(1);
|
||||
- header.flags = cpu_to_le32(3); /* ?? */
|
||||
- header.capacity = cpu_to_le64(total_size);
|
||||
- header.granularity = cpu_to_le64(128);
|
||||
- header.num_gtes_per_gte = cpu_to_le32(512);
|
||||
+ header.version = 1;
|
||||
+ header.flags = 3; /* ?? */
|
||||
+ header.capacity = total_size;
|
||||
+ header.granularity = 128;
|
||||
+ header.num_gtes_per_gte = 512;
|
||||
|
||||
grains = (total_size + header.granularity - 1) / header.granularity;
|
||||
gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
|
||||
@@ -736,6 +736,12 @@ static int vmdk_create(const char *filen
|
||||
header.granularity - 1) / header.granularity) *
|
||||
header.granularity;
|
||||
|
||||
+ /* swap endianness for all header fields */
|
||||
+ header.version = cpu_to_le32(header.version);
|
||||
+ header.flags = cpu_to_le32(header.flags);
|
||||
+ header.capacity = cpu_to_le64(header.capacity);
|
||||
+ header.granularity = cpu_to_le64(header.granularity);
|
||||
+ header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
|
||||
header.desc_offset = cpu_to_le64(header.desc_offset);
|
||||
header.desc_size = cpu_to_le64(header.desc_size);
|
||||
header.rgd_offset = cpu_to_le64(header.rgd_offset);
|
||||
@@ -759,7 +765,7 @@ static int vmdk_create(const char *filen
|
||||
goto exit;
|
||||
}
|
||||
|
||||
- ret = ftruncate(fd, header.grain_offset << 9);
|
||||
+ ret = ftruncate(fd, le64_to_cpu(header.grain_offset) << 9);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
goto exit;
|
||||
@@ -767,7 +773,7 @@ static int vmdk_create(const char *filen
|
||||
|
||||
/* write grain directory */
|
||||
lseek(fd, le64_to_cpu(header.rgd_offset) << 9, SEEK_SET);
|
||||
- for (i = 0, tmp = header.rgd_offset + gd_size;
|
||||
+ for (i = 0, tmp = le64_to_cpu(header.rgd_offset) + gd_size;
|
||||
i < gt_count; i++, tmp += gt_size) {
|
||||
ret = qemu_write_full(fd, &tmp, sizeof(tmp));
|
||||
if (ret != sizeof(tmp)) {
|
||||
@@ -778,7 +784,7 @@ static int vmdk_create(const char *filen
|
||||
|
||||
/* write backup grain directory */
|
||||
lseek(fd, le64_to_cpu(header.gd_offset) << 9, SEEK_SET);
|
||||
- for (i = 0, tmp = header.gd_offset + gd_size;
|
||||
+ for (i = 0, tmp = le64_to_cpu(header.gd_offset) + gd_size;
|
||||
i < gt_count; i++, tmp += gt_size) {
|
||||
ret = qemu_write_full(fd, &tmp, sizeof(tmp));
|
||||
if (ret != sizeof(tmp)) {
|
||||
@ -1,557 +0,0 @@
|
||||
From fcd9c52d160376184cbd25e04586aa6eef6abd61 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:28 +0800
|
||||
Subject: [PATCH 02/12] VMDK: introduce VmdkExtent
|
||||
|
||||
Introduced VmdkExtent array into BDRVVmdkState, enable holding multiple
|
||||
image extents for multiple file image support.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 348 +++++++++++++++++++++++++++++++++++++++++------------------
|
||||
1 file changed, 246 insertions(+), 102 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -60,7 +60,11 @@ typedef struct {
|
||||
|
||||
#define L2_CACHE_SIZE 16
|
||||
|
||||
-typedef struct BDRVVmdkState {
|
||||
+typedef struct VmdkExtent {
|
||||
+ BlockDriverState *file;
|
||||
+ bool flat;
|
||||
+ int64_t sectors;
|
||||
+ int64_t end_sector;
|
||||
int64_t l1_table_offset;
|
||||
int64_t l1_backup_table_offset;
|
||||
uint32_t *l1_table;
|
||||
@@ -74,7 +78,13 @@ typedef struct BDRVVmdkState {
|
||||
uint32_t l2_cache_counts[L2_CACHE_SIZE];
|
||||
|
||||
unsigned int cluster_sectors;
|
||||
+} VmdkExtent;
|
||||
+
|
||||
+typedef struct BDRVVmdkState {
|
||||
uint32_t parent_cid;
|
||||
+ int num_extents;
|
||||
+ /* Extent array with num_extents entries, ascend ordered by address */
|
||||
+ VmdkExtent *extents;
|
||||
} BDRVVmdkState;
|
||||
|
||||
typedef struct VmdkMetaData {
|
||||
@@ -105,6 +115,19 @@ static int vmdk_probe(const uint8_t *buf
|
||||
#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
|
||||
#define HEADER_SIZE 512 // first sector of 512 bytes
|
||||
|
||||
+static void vmdk_free_extents(BlockDriverState *bs)
|
||||
+{
|
||||
+ int i;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
+
|
||||
+ for (i = 0; i < s->num_extents; i++) {
|
||||
+ qemu_free(s->extents[i].l1_table);
|
||||
+ qemu_free(s->extents[i].l2_cache);
|
||||
+ qemu_free(s->extents[i].l1_backup_table);
|
||||
+ }
|
||||
+ qemu_free(s->extents);
|
||||
+}
|
||||
+
|
||||
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
|
||||
{
|
||||
char desc[DESC_SIZE];
|
||||
@@ -358,11 +381,50 @@ static int vmdk_parent_open(BlockDriverS
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Create and append extent to the extent array. Return the added VmdkExtent
|
||||
+ * address. return NULL if allocation failed. */
|
||||
+static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
|
||||
+ BlockDriverState *file, bool flat, int64_t sectors,
|
||||
+ int64_t l1_offset, int64_t l1_backup_offset,
|
||||
+ uint32_t l1_size,
|
||||
+ int l2_size, unsigned int cluster_sectors)
|
||||
+{
|
||||
+ VmdkExtent *extent;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
+
|
||||
+ s->extents = qemu_realloc(s->extents,
|
||||
+ (s->num_extents + 1) * sizeof(VmdkExtent));
|
||||
+ extent = &s->extents[s->num_extents];
|
||||
+ s->num_extents++;
|
||||
+
|
||||
+ memset(extent, 0, sizeof(VmdkExtent));
|
||||
+ extent->file = file;
|
||||
+ extent->flat = flat;
|
||||
+ extent->sectors = sectors;
|
||||
+ extent->l1_table_offset = l1_offset;
|
||||
+ extent->l1_backup_table_offset = l1_backup_offset;
|
||||
+ extent->l1_size = l1_size;
|
||||
+ extent->l1_entry_sectors = l2_size * cluster_sectors;
|
||||
+ extent->l2_size = l2_size;
|
||||
+ extent->cluster_sectors = cluster_sectors;
|
||||
+
|
||||
+ if (s->num_extents > 1) {
|
||||
+ extent->end_sector = (*(extent - 1)).end_sector + extent->sectors;
|
||||
+ } else {
|
||||
+ extent->end_sector = extent->sectors;
|
||||
+ }
|
||||
+ bs->total_sectors = extent->end_sector;
|
||||
+ return extent;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int vmdk_open(BlockDriverState *bs, int flags)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
uint32_t magic;
|
||||
- int l1_size, i;
|
||||
+ int i;
|
||||
+ uint32_t l1_size, l1_entry_sectors;
|
||||
+ VmdkExtent *extent = NULL;
|
||||
|
||||
if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
|
||||
goto fail;
|
||||
@@ -370,32 +432,34 @@ static int vmdk_open(BlockDriverState *b
|
||||
magic = be32_to_cpu(magic);
|
||||
if (magic == VMDK3_MAGIC) {
|
||||
VMDK3Header header;
|
||||
-
|
||||
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
|
||||
+ if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
|
||||
+ != sizeof(header)) {
|
||||
goto fail;
|
||||
- s->cluster_sectors = le32_to_cpu(header.granularity);
|
||||
- s->l2_size = 1 << 9;
|
||||
- s->l1_size = 1 << 6;
|
||||
- bs->total_sectors = le32_to_cpu(header.disk_sectors);
|
||||
- s->l1_table_offset = le32_to_cpu(header.l1dir_offset) << 9;
|
||||
- s->l1_backup_table_offset = 0;
|
||||
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
|
||||
+ }
|
||||
+ extent = vmdk_add_extent(bs, bs->file, false,
|
||||
+ le32_to_cpu(header.disk_sectors),
|
||||
+ le32_to_cpu(header.l1dir_offset) << 9, 0,
|
||||
+ 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
|
||||
} else if (magic == VMDK4_MAGIC) {
|
||||
VMDK4Header header;
|
||||
-
|
||||
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header)) != sizeof(header))
|
||||
+ if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
|
||||
+ != sizeof(header)) {
|
||||
goto fail;
|
||||
- bs->total_sectors = le64_to_cpu(header.capacity);
|
||||
- s->cluster_sectors = le64_to_cpu(header.granularity);
|
||||
- s->l2_size = le32_to_cpu(header.num_gtes_per_gte);
|
||||
- s->l1_entry_sectors = s->l2_size * s->cluster_sectors;
|
||||
- if (s->l1_entry_sectors <= 0)
|
||||
+ }
|
||||
+ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
|
||||
+ * le64_to_cpu(header.granularity);
|
||||
+ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||
+ / l1_entry_sectors;
|
||||
+ extent = vmdk_add_extent(bs, bs->file, false,
|
||||
+ le64_to_cpu(header.capacity),
|
||||
+ le64_to_cpu(header.gd_offset) << 9,
|
||||
+ le64_to_cpu(header.rgd_offset) << 9,
|
||||
+ l1_size,
|
||||
+ le32_to_cpu(header.num_gtes_per_gte),
|
||||
+ le64_to_cpu(header.granularity));
|
||||
+ if (extent->l1_entry_sectors <= 0) {
|
||||
goto fail;
|
||||
- s->l1_size = (bs->total_sectors + s->l1_entry_sectors - 1)
|
||||
- / s->l1_entry_sectors;
|
||||
- s->l1_table_offset = le64_to_cpu(header.rgd_offset) << 9;
|
||||
- s->l1_backup_table_offset = le64_to_cpu(header.gd_offset) << 9;
|
||||
-
|
||||
+ }
|
||||
// try to open parent images, if exist
|
||||
if (vmdk_parent_open(bs) != 0)
|
||||
goto fail;
|
||||
@@ -406,40 +470,49 @@ static int vmdk_open(BlockDriverState *b
|
||||
}
|
||||
|
||||
/* read the L1 table */
|
||||
- l1_size = s->l1_size * sizeof(uint32_t);
|
||||
- s->l1_table = qemu_malloc(l1_size);
|
||||
- if (bdrv_pread(bs->file, s->l1_table_offset, s->l1_table, l1_size) != l1_size)
|
||||
- goto fail;
|
||||
- for(i = 0; i < s->l1_size; i++) {
|
||||
- le32_to_cpus(&s->l1_table[i]);
|
||||
- }
|
||||
-
|
||||
- if (s->l1_backup_table_offset) {
|
||||
- s->l1_backup_table = qemu_malloc(l1_size);
|
||||
- if (bdrv_pread(bs->file, s->l1_backup_table_offset, s->l1_backup_table, l1_size) != l1_size)
|
||||
+ l1_size = extent->l1_size * sizeof(uint32_t);
|
||||
+ extent->l1_table = qemu_malloc(l1_size);
|
||||
+ if (bdrv_pread(bs->file,
|
||||
+ extent->l1_table_offset,
|
||||
+ extent->l1_table,
|
||||
+ l1_size)
|
||||
+ != l1_size) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ for (i = 0; i < extent->l1_size; i++) {
|
||||
+ le32_to_cpus(&extent->l1_table[i]);
|
||||
+ }
|
||||
+
|
||||
+ if (extent->l1_backup_table_offset) {
|
||||
+ extent->l1_backup_table = qemu_malloc(l1_size);
|
||||
+ if (bdrv_pread(bs->file,
|
||||
+ extent->l1_backup_table_offset,
|
||||
+ extent->l1_backup_table,
|
||||
+ l1_size)
|
||||
+ != l1_size) {
|
||||
goto fail;
|
||||
- for(i = 0; i < s->l1_size; i++) {
|
||||
- le32_to_cpus(&s->l1_backup_table[i]);
|
||||
+ }
|
||||
+ for (i = 0; i < extent->l1_size; i++) {
|
||||
+ le32_to_cpus(&extent->l1_backup_table[i]);
|
||||
}
|
||||
}
|
||||
|
||||
- s->l2_cache = qemu_malloc(s->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
|
||||
+ extent->l2_cache =
|
||||
+ qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
|
||||
return 0;
|
||||
fail:
|
||||
- qemu_free(s->l1_backup_table);
|
||||
- qemu_free(s->l1_table);
|
||||
- qemu_free(s->l2_cache);
|
||||
+ vmdk_free_extents(bs);
|
||||
return -1;
|
||||
}
|
||||
|
||||
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
|
||||
- uint64_t offset, int allocate);
|
||||
-
|
||||
-static int get_whole_cluster(BlockDriverState *bs, uint64_t cluster_offset,
|
||||
- uint64_t offset, int allocate)
|
||||
+static int get_whole_cluster(BlockDriverState *bs,
|
||||
+ VmdkExtent *extent,
|
||||
+ uint64_t cluster_offset,
|
||||
+ uint64_t offset,
|
||||
+ bool allocate)
|
||||
{
|
||||
- BDRVVmdkState *s = bs->opaque;
|
||||
- uint8_t whole_grain[s->cluster_sectors*512]; // 128 sectors * 512 bytes each = grain size 64KB
|
||||
+ /* 128 sectors * 512 bytes each = grain size 64KB */
|
||||
+ uint8_t whole_grain[extent->cluster_sectors * 512];
|
||||
|
||||
// we will be here if it's first write on non-exist grain(cluster).
|
||||
// try to read from parent image, if exist
|
||||
@@ -450,14 +523,14 @@ static int get_whole_cluster(BlockDriver
|
||||
return -1;
|
||||
|
||||
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
|
||||
- s->cluster_sectors);
|
||||
+ extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Write grain only into the active image
|
||||
- ret = bdrv_write(bs->file, cluster_offset, whole_grain,
|
||||
- s->cluster_sectors);
|
||||
+ ret = bdrv_write(extent->file, cluster_offset, whole_grain,
|
||||
+ extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
@@ -465,29 +538,39 @@ static int get_whole_cluster(BlockDriver
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int vmdk_L2update(BlockDriverState *bs, VmdkMetaData *m_data)
|
||||
+static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
|
||||
{
|
||||
- BDRVVmdkState *s = bs->opaque;
|
||||
-
|
||||
/* update L2 table */
|
||||
- if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
|
||||
- &(m_data->offset), sizeof(m_data->offset)) < 0)
|
||||
+ if (bdrv_pwrite_sync(
|
||||
+ extent->file,
|
||||
+ ((int64_t)m_data->l2_offset * 512)
|
||||
+ + (m_data->l2_index * sizeof(m_data->offset)),
|
||||
+ &(m_data->offset),
|
||||
+ sizeof(m_data->offset)
|
||||
+ ) < 0) {
|
||||
return -1;
|
||||
+ }
|
||||
/* update backup L2 table */
|
||||
- if (s->l1_backup_table_offset != 0) {
|
||||
- m_data->l2_offset = s->l1_backup_table[m_data->l1_index];
|
||||
- if (bdrv_pwrite_sync(bs->file, ((int64_t)m_data->l2_offset * 512) + (m_data->l2_index * sizeof(m_data->offset)),
|
||||
- &(m_data->offset), sizeof(m_data->offset)) < 0)
|
||||
+ if (extent->l1_backup_table_offset != 0) {
|
||||
+ m_data->l2_offset = extent->l1_backup_table[m_data->l1_index];
|
||||
+ if (bdrv_pwrite_sync(
|
||||
+ extent->file,
|
||||
+ ((int64_t)m_data->l2_offset * 512)
|
||||
+ + (m_data->l2_index * sizeof(m_data->offset)),
|
||||
+ &(m_data->offset), sizeof(m_data->offset)
|
||||
+ ) < 0) {
|
||||
return -1;
|
||||
+ }
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static uint64_t get_cluster_offset(BlockDriverState *bs, VmdkMetaData *m_data,
|
||||
- uint64_t offset, int allocate)
|
||||
+static uint64_t get_cluster_offset(BlockDriverState *bs,
|
||||
+ VmdkExtent *extent,
|
||||
+ VmdkMetaData *m_data,
|
||||
+ uint64_t offset, int allocate)
|
||||
{
|
||||
- BDRVVmdkState *s = bs->opaque;
|
||||
unsigned int l1_index, l2_offset, l2_index;
|
||||
int min_index, i, j;
|
||||
uint32_t min_count, *l2_table, tmp = 0;
|
||||
@@ -496,21 +579,23 @@ static uint64_t get_cluster_offset(Block
|
||||
if (m_data)
|
||||
m_data->valid = 0;
|
||||
|
||||
- l1_index = (offset >> 9) / s->l1_entry_sectors;
|
||||
- if (l1_index >= s->l1_size)
|
||||
+ l1_index = (offset >> 9) / extent->l1_entry_sectors;
|
||||
+ if (l1_index >= extent->l1_size) {
|
||||
return 0;
|
||||
- l2_offset = s->l1_table[l1_index];
|
||||
- if (!l2_offset)
|
||||
+ }
|
||||
+ l2_offset = extent->l1_table[l1_index];
|
||||
+ if (!l2_offset) {
|
||||
return 0;
|
||||
+ }
|
||||
for(i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
- if (l2_offset == s->l2_cache_offsets[i]) {
|
||||
+ if (l2_offset == extent->l2_cache_offsets[i]) {
|
||||
/* increment the hit count */
|
||||
- if (++s->l2_cache_counts[i] == 0xffffffff) {
|
||||
+ if (++extent->l2_cache_counts[i] == 0xffffffff) {
|
||||
for(j = 0; j < L2_CACHE_SIZE; j++) {
|
||||
- s->l2_cache_counts[j] >>= 1;
|
||||
+ extent->l2_cache_counts[j] >>= 1;
|
||||
}
|
||||
}
|
||||
- l2_table = s->l2_cache + (i * s->l2_size);
|
||||
+ l2_table = extent->l2_cache + (i * extent->l2_size);
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
@@ -518,20 +603,25 @@ static uint64_t get_cluster_offset(Block
|
||||
min_index = 0;
|
||||
min_count = 0xffffffff;
|
||||
for(i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
- if (s->l2_cache_counts[i] < min_count) {
|
||||
- min_count = s->l2_cache_counts[i];
|
||||
+ if (extent->l2_cache_counts[i] < min_count) {
|
||||
+ min_count = extent->l2_cache_counts[i];
|
||||
min_index = i;
|
||||
}
|
||||
}
|
||||
- l2_table = s->l2_cache + (min_index * s->l2_size);
|
||||
- if (bdrv_pread(bs->file, (int64_t)l2_offset * 512, l2_table, s->l2_size * sizeof(uint32_t)) !=
|
||||
- s->l2_size * sizeof(uint32_t))
|
||||
+ l2_table = extent->l2_cache + (min_index * extent->l2_size);
|
||||
+ if (bdrv_pread(
|
||||
+ extent->file,
|
||||
+ (int64_t)l2_offset * 512,
|
||||
+ l2_table,
|
||||
+ extent->l2_size * sizeof(uint32_t)
|
||||
+ ) != extent->l2_size * sizeof(uint32_t)) {
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
- s->l2_cache_offsets[min_index] = l2_offset;
|
||||
- s->l2_cache_counts[min_index] = 1;
|
||||
+ extent->l2_cache_offsets[min_index] = l2_offset;
|
||||
+ extent->l2_cache_counts[min_index] = 1;
|
||||
found:
|
||||
- l2_index = ((offset >> 9) / s->cluster_sectors) % s->l2_size;
|
||||
+ l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
|
||||
cluster_offset = le32_to_cpu(l2_table[l2_index]);
|
||||
|
||||
if (!cluster_offset) {
|
||||
@@ -539,8 +629,11 @@ static uint64_t get_cluster_offset(Block
|
||||
return 0;
|
||||
|
||||
// Avoid the L2 tables update for the images that have snapshots.
|
||||
- cluster_offset = bdrv_getlength(bs->file);
|
||||
- bdrv_truncate(bs->file, cluster_offset + (s->cluster_sectors << 9));
|
||||
+ cluster_offset = bdrv_getlength(extent->file);
|
||||
+ bdrv_truncate(
|
||||
+ extent->file,
|
||||
+ cluster_offset + (extent->cluster_sectors << 9)
|
||||
+ );
|
||||
|
||||
cluster_offset >>= 9;
|
||||
tmp = cpu_to_le32(cluster_offset);
|
||||
@@ -551,7 +644,8 @@ static uint64_t get_cluster_offset(Block
|
||||
* This problem may occur because of insufficient space on host disk
|
||||
* or inappropriate VM shutdown.
|
||||
*/
|
||||
- if (get_whole_cluster(bs, cluster_offset, offset, allocate) == -1)
|
||||
+ if (get_whole_cluster(
|
||||
+ bs, extent, cluster_offset, offset, allocate) == -1)
|
||||
return 0;
|
||||
|
||||
if (m_data) {
|
||||
@@ -566,33 +660,69 @@ static uint64_t get_cluster_offset(Block
|
||||
return cluster_offset;
|
||||
}
|
||||
|
||||
+static VmdkExtent *find_extent(BDRVVmdkState *s,
|
||||
+ int64_t sector_num, VmdkExtent *start_hint)
|
||||
+{
|
||||
+ VmdkExtent *extent = start_hint;
|
||||
+
|
||||
+ if (!extent) {
|
||||
+ extent = &s->extents[0];
|
||||
+ }
|
||||
+ while (extent < &s->extents[s->num_extents]) {
|
||||
+ if (sector_num < extent->end_sector) {
|
||||
+ return extent;
|
||||
+ }
|
||||
+ extent++;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
static int vmdk_is_allocated(BlockDriverState *bs, int64_t sector_num,
|
||||
int nb_sectors, int *pnum)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
- int index_in_cluster, n;
|
||||
- uint64_t cluster_offset;
|
||||
|
||||
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
|
||||
- index_in_cluster = sector_num % s->cluster_sectors;
|
||||
- n = s->cluster_sectors - index_in_cluster;
|
||||
+ int64_t index_in_cluster, n, ret;
|
||||
+ uint64_t offset;
|
||||
+ VmdkExtent *extent;
|
||||
+
|
||||
+ extent = find_extent(s, sector_num, NULL);
|
||||
+ if (!extent) {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (extent->flat) {
|
||||
+ n = extent->end_sector - sector_num;
|
||||
+ ret = 1;
|
||||
+ } else {
|
||||
+ offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
|
||||
+ index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
+ n = extent->cluster_sectors - index_in_cluster;
|
||||
+ ret = offset ? 1 : 0;
|
||||
+ }
|
||||
if (n > nb_sectors)
|
||||
n = nb_sectors;
|
||||
*pnum = n;
|
||||
- return (cluster_offset != 0);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
|
||||
uint8_t *buf, int nb_sectors)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
- int index_in_cluster, n, ret;
|
||||
+ int ret;
|
||||
+ uint64_t n, index_in_cluster;
|
||||
+ VmdkExtent *extent = NULL;
|
||||
uint64_t cluster_offset;
|
||||
|
||||
while (nb_sectors > 0) {
|
||||
- cluster_offset = get_cluster_offset(bs, NULL, sector_num << 9, 0);
|
||||
- index_in_cluster = sector_num % s->cluster_sectors;
|
||||
- n = s->cluster_sectors - index_in_cluster;
|
||||
+ extent = find_extent(s, sector_num, extent);
|
||||
+ if (!extent) {
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ cluster_offset = get_cluster_offset(
|
||||
+ bs, extent, NULL, sector_num << 9, 0);
|
||||
+ index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
+ n = extent->cluster_sectors - index_in_cluster;
|
||||
if (n > nb_sectors)
|
||||
n = nb_sectors;
|
||||
if (!cluster_offset) {
|
||||
@@ -621,10 +751,12 @@ static int vmdk_write(BlockDriverState *
|
||||
const uint8_t *buf, int nb_sectors)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
- VmdkMetaData m_data;
|
||||
- int index_in_cluster, n;
|
||||
+ VmdkExtent *extent = NULL;
|
||||
+ int n;
|
||||
+ int64_t index_in_cluster;
|
||||
uint64_t cluster_offset;
|
||||
static int cid_update = 0;
|
||||
+ VmdkMetaData m_data;
|
||||
|
||||
if (sector_num > bs->total_sectors) {
|
||||
fprintf(stderr,
|
||||
@@ -635,20 +767,35 @@ static int vmdk_write(BlockDriverState *
|
||||
}
|
||||
|
||||
while (nb_sectors > 0) {
|
||||
- index_in_cluster = sector_num & (s->cluster_sectors - 1);
|
||||
- n = s->cluster_sectors - index_in_cluster;
|
||||
- if (n > nb_sectors)
|
||||
- n = nb_sectors;
|
||||
- cluster_offset = get_cluster_offset(bs, &m_data, sector_num << 9, 1);
|
||||
- if (!cluster_offset)
|
||||
+ extent = find_extent(s, sector_num, extent);
|
||||
+ if (!extent) {
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+ cluster_offset = get_cluster_offset(
|
||||
+ bs,
|
||||
+ extent,
|
||||
+ &m_data,
|
||||
+ sector_num << 9, 1);
|
||||
+ if (!cluster_offset) {
|
||||
return -1;
|
||||
+ }
|
||||
+ index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
+ n = extent->cluster_sectors - index_in_cluster;
|
||||
+ if (n > nb_sectors) {
|
||||
+ n = nb_sectors;
|
||||
+ }
|
||||
|
||||
- if (bdrv_pwrite(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
|
||||
+ if (bdrv_pwrite(bs->file,
|
||||
+ cluster_offset + index_in_cluster * 512,
|
||||
+ buf, n * 512)
|
||||
+ != n * 512) {
|
||||
return -1;
|
||||
+ }
|
||||
if (m_data.valid) {
|
||||
/* update L2 tables */
|
||||
- if (vmdk_L2update(bs, &m_data) == -1)
|
||||
+ if (vmdk_L2update(extent, &m_data) == -1) {
|
||||
return -1;
|
||||
+ }
|
||||
}
|
||||
nb_sectors -= n;
|
||||
sector_num += n;
|
||||
@@ -822,10 +969,7 @@ exit:
|
||||
|
||||
static void vmdk_close(BlockDriverState *bs)
|
||||
{
|
||||
- BDRVVmdkState *s = bs->opaque;
|
||||
-
|
||||
- qemu_free(s->l1_table);
|
||||
- qemu_free(s->l2_cache);
|
||||
+ vmdk_free_extents(bs);
|
||||
}
|
||||
|
||||
static int vmdk_flush(BlockDriverState *bs)
|
||||
@ -1,46 +0,0 @@
|
||||
From 66922efc83a670178b208dec2f5123ec85fb6ba3 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:29 +0800
|
||||
Subject: [PATCH 03/12] VMDK: bugfix, align offset to cluster in
|
||||
get_whole_cluster
|
||||
|
||||
In get_whole_cluster, the offset is not aligned to cluster when reading
|
||||
from backing_hd. When the first write to child is not at the cluster
|
||||
boundary, wrong address data from parent is copied to child.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 8 +++++---
|
||||
1 file changed, 5 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -514,21 +514,23 @@ static int get_whole_cluster(BlockDriver
|
||||
/* 128 sectors * 512 bytes each = grain size 64KB */
|
||||
uint8_t whole_grain[extent->cluster_sectors * 512];
|
||||
|
||||
- // we will be here if it's first write on non-exist grain(cluster).
|
||||
- // try to read from parent image, if exist
|
||||
+ /* we will be here if it's first write on non-exist grain(cluster).
|
||||
+ * try to read from parent image, if exist */
|
||||
if (bs->backing_hd) {
|
||||
int ret;
|
||||
|
||||
if (!vmdk_is_cid_valid(bs))
|
||||
return -1;
|
||||
|
||||
+ /* floor offset to cluster */
|
||||
+ offset -= offset % (extent->cluster_sectors * 512);
|
||||
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
|
||||
extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
- //Write grain only into the active image
|
||||
+ /* Write grain only into the active image */
|
||||
ret = bdrv_write(extent->file, cluster_offset, whole_grain,
|
||||
extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
@ -1,74 +0,0 @@
|
||||
From 930e57ecb64bbab75c2b71d0d1ba07451fec4567 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:30 +0800
|
||||
Subject: [PATCH 04/12] VMDK: probe for monolithicFlat images
|
||||
|
||||
Probe as the same behavior as VMware does.
|
||||
Recognize image as monolithicFlat descriptor file when the file is text
|
||||
and the first effective line (not '#' leaded comment or space line) is
|
||||
either 'version=1' or 'version=2'. No space or upper case charactors
|
||||
accepted.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 45 +++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 43 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -103,10 +103,51 @@ static int vmdk_probe(const uint8_t *buf
|
||||
return 0;
|
||||
magic = be32_to_cpu(*(uint32_t *)buf);
|
||||
if (magic == VMDK3_MAGIC ||
|
||||
- magic == VMDK4_MAGIC)
|
||||
+ magic == VMDK4_MAGIC) {
|
||||
return 100;
|
||||
- else
|
||||
+ } else {
|
||||
+ const char *p = (const char *)buf;
|
||||
+ const char *end = p + buf_size;
|
||||
+ while (p < end) {
|
||||
+ if (*p == '#') {
|
||||
+ /* skip comment line */
|
||||
+ while (p < end && *p != '\n') {
|
||||
+ p++;
|
||||
+ }
|
||||
+ p++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (*p == ' ') {
|
||||
+ while (p < end && *p == ' ') {
|
||||
+ p++;
|
||||
+ }
|
||||
+ /* skip '\r' if windows line endings used. */
|
||||
+ if (p < end && *p == '\r') {
|
||||
+ p++;
|
||||
+ }
|
||||
+ /* only accept blank lines before 'version=' line */
|
||||
+ if (p == end || *p != '\n') {
|
||||
+ return 0;
|
||||
+ }
|
||||
+ p++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (end - p >= strlen("version=X\n")) {
|
||||
+ if (strncmp("version=1\n", p, strlen("version=1\n")) == 0 ||
|
||||
+ strncmp("version=2\n", p, strlen("version=2\n")) == 0) {
|
||||
+ return 100;
|
||||
+ }
|
||||
+ }
|
||||
+ if (end - p >= strlen("version=X\r\n")) {
|
||||
+ if (strncmp("version=1\r\n", p, strlen("version=1\r\n")) == 0 ||
|
||||
+ strncmp("version=2\r\n", p, strlen("version=2\r\n")) == 0) {
|
||||
+ return 100;
|
||||
+ }
|
||||
+ }
|
||||
+ return 0;
|
||||
+ }
|
||||
return 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
#define CHECK_CID 1
|
||||
@ -1,241 +0,0 @@
|
||||
From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:31 +0800
|
||||
Subject: [PATCH 05/12] VMDK: separate vmdk_open by format version
|
||||
|
||||
Separate vmdk_open by subformats to:
|
||||
* vmdk_open_vmdk3
|
||||
* vmdk_open_vmdk4
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 178 +++++++++++++++++++++++++++++++++++++----------------------
|
||||
1 file changed, 112 insertions(+), 66 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -458,67 +458,20 @@ static VmdkExtent *vmdk_add_extent(Block
|
||||
return extent;
|
||||
}
|
||||
|
||||
-
|
||||
-static int vmdk_open(BlockDriverState *bs, int flags)
|
||||
+static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
|
||||
{
|
||||
- BDRVVmdkState *s = bs->opaque;
|
||||
- uint32_t magic;
|
||||
- int i;
|
||||
- uint32_t l1_size, l1_entry_sectors;
|
||||
- VmdkExtent *extent = NULL;
|
||||
-
|
||||
- if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic))
|
||||
- goto fail;
|
||||
-
|
||||
- magic = be32_to_cpu(magic);
|
||||
- if (magic == VMDK3_MAGIC) {
|
||||
- VMDK3Header header;
|
||||
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
|
||||
- != sizeof(header)) {
|
||||
- goto fail;
|
||||
- }
|
||||
- extent = vmdk_add_extent(bs, bs->file, false,
|
||||
- le32_to_cpu(header.disk_sectors),
|
||||
- le32_to_cpu(header.l1dir_offset) << 9, 0,
|
||||
- 1 << 6, 1 << 9, le32_to_cpu(header.granularity));
|
||||
- } else if (magic == VMDK4_MAGIC) {
|
||||
- VMDK4Header header;
|
||||
- if (bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header))
|
||||
- != sizeof(header)) {
|
||||
- goto fail;
|
||||
- }
|
||||
- l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
|
||||
- * le64_to_cpu(header.granularity);
|
||||
- l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||
- / l1_entry_sectors;
|
||||
- extent = vmdk_add_extent(bs, bs->file, false,
|
||||
- le64_to_cpu(header.capacity),
|
||||
- le64_to_cpu(header.gd_offset) << 9,
|
||||
- le64_to_cpu(header.rgd_offset) << 9,
|
||||
- l1_size,
|
||||
- le32_to_cpu(header.num_gtes_per_gte),
|
||||
- le64_to_cpu(header.granularity));
|
||||
- if (extent->l1_entry_sectors <= 0) {
|
||||
- goto fail;
|
||||
- }
|
||||
- // try to open parent images, if exist
|
||||
- if (vmdk_parent_open(bs) != 0)
|
||||
- goto fail;
|
||||
- // write the CID once after the image creation
|
||||
- s->parent_cid = vmdk_read_cid(bs,1);
|
||||
- } else {
|
||||
- goto fail;
|
||||
- }
|
||||
+ int ret;
|
||||
+ int l1_size, i;
|
||||
|
||||
/* read the L1 table */
|
||||
l1_size = extent->l1_size * sizeof(uint32_t);
|
||||
extent->l1_table = qemu_malloc(l1_size);
|
||||
- if (bdrv_pread(bs->file,
|
||||
- extent->l1_table_offset,
|
||||
- extent->l1_table,
|
||||
- l1_size)
|
||||
- != l1_size) {
|
||||
- goto fail;
|
||||
+ ret = bdrv_pread(extent->file,
|
||||
+ extent->l1_table_offset,
|
||||
+ extent->l1_table,
|
||||
+ l1_size);
|
||||
+ if (ret < 0) {
|
||||
+ goto fail_l1;
|
||||
}
|
||||
for (i = 0; i < extent->l1_size; i++) {
|
||||
le32_to_cpus(&extent->l1_table[i]);
|
||||
@@ -526,12 +479,12 @@ static int vmdk_open(BlockDriverState *b
|
||||
|
||||
if (extent->l1_backup_table_offset) {
|
||||
extent->l1_backup_table = qemu_malloc(l1_size);
|
||||
- if (bdrv_pread(bs->file,
|
||||
- extent->l1_backup_table_offset,
|
||||
- extent->l1_backup_table,
|
||||
- l1_size)
|
||||
- != l1_size) {
|
||||
- goto fail;
|
||||
+ ret = bdrv_pread(extent->file,
|
||||
+ extent->l1_backup_table_offset,
|
||||
+ extent->l1_backup_table,
|
||||
+ l1_size);
|
||||
+ if (ret < 0) {
|
||||
+ goto fail_l1b;
|
||||
}
|
||||
for (i = 0; i < extent->l1_size; i++) {
|
||||
le32_to_cpus(&extent->l1_backup_table[i]);
|
||||
@@ -541,9 +494,102 @@ static int vmdk_open(BlockDriverState *b
|
||||
extent->l2_cache =
|
||||
qemu_malloc(extent->l2_size * L2_CACHE_SIZE * sizeof(uint32_t));
|
||||
return 0;
|
||||
+ fail_l1b:
|
||||
+ qemu_free(extent->l1_backup_table);
|
||||
+ fail_l1:
|
||||
+ qemu_free(extent->l1_table);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_open_vmdk3(BlockDriverState *bs, int flags)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t magic;
|
||||
+ VMDK3Header header;
|
||||
+ VmdkExtent *extent;
|
||||
+
|
||||
+ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
|
||||
+ if (ret < 0) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ extent = vmdk_add_extent(bs,
|
||||
+ bs->file, false,
|
||||
+ le32_to_cpu(header.disk_sectors),
|
||||
+ le32_to_cpu(header.l1dir_offset) << 9,
|
||||
+ 0, 1 << 6, 1 << 9,
|
||||
+ le32_to_cpu(header.granularity));
|
||||
+ ret = vmdk_init_tables(bs, extent);
|
||||
+ if (ret) {
|
||||
+ /* vmdk_init_tables cleans up on fail, so only free allocation of
|
||||
+ * vmdk_add_extent here. */
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ return 0;
|
||||
fail:
|
||||
vmdk_free_extents(bs);
|
||||
- return -1;
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_open_vmdk4(BlockDriverState *bs, int flags)
|
||||
+{
|
||||
+ int ret;
|
||||
+ uint32_t magic;
|
||||
+ uint32_t l1_size, l1_entry_sectors;
|
||||
+ VMDK4Header header;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
+ VmdkExtent *extent;
|
||||
+
|
||||
+ ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
|
||||
+ if (ret < 0) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
|
||||
+ * le64_to_cpu(header.granularity);
|
||||
+ l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||
+ / l1_entry_sectors;
|
||||
+ extent = vmdk_add_extent(bs, bs->file, false,
|
||||
+ le64_to_cpu(header.capacity),
|
||||
+ le64_to_cpu(header.gd_offset) << 9,
|
||||
+ le64_to_cpu(header.rgd_offset) << 9,
|
||||
+ l1_size,
|
||||
+ le32_to_cpu(header.num_gtes_per_gte),
|
||||
+ le64_to_cpu(header.granularity));
|
||||
+ if (extent->l1_entry_sectors <= 0) {
|
||||
+ ret = -EINVAL;
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ /* try to open parent images, if exist */
|
||||
+ ret = vmdk_parent_open(bs);
|
||||
+ if (ret) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ s->parent_cid = vmdk_read_cid(bs, 1);
|
||||
+ ret = vmdk_init_tables(bs, extent);
|
||||
+ if (ret) {
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ return 0;
|
||||
+ fail:
|
||||
+ vmdk_free_extents(bs);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_open(BlockDriverState *bs, int flags)
|
||||
+{
|
||||
+ uint32_t magic;
|
||||
+
|
||||
+ if (bdrv_pread(bs->file, 0, &magic, sizeof(magic)) != sizeof(magic)) {
|
||||
+ return -EIO;
|
||||
+ }
|
||||
+
|
||||
+ magic = be32_to_cpu(magic);
|
||||
+ if (magic == VMDK3_MAGIC) {
|
||||
+ return vmdk_open_vmdk3(bs, flags);
|
||||
+ } else if (magic == VMDK4_MAGIC) {
|
||||
+ return vmdk_open_vmdk4(bs, flags);
|
||||
+ } else {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
}
|
||||
|
||||
static int get_whole_cluster(BlockDriverState *bs,
|
||||
@@ -630,11 +676,11 @@ static uint64_t get_cluster_offset(Block
|
||||
if (!l2_offset) {
|
||||
return 0;
|
||||
}
|
||||
- for(i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
+ for (i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
if (l2_offset == extent->l2_cache_offsets[i]) {
|
||||
/* increment the hit count */
|
||||
if (++extent->l2_cache_counts[i] == 0xffffffff) {
|
||||
- for(j = 0; j < L2_CACHE_SIZE; j++) {
|
||||
+ for (j = 0; j < L2_CACHE_SIZE; j++) {
|
||||
extent->l2_cache_counts[j] >>= 1;
|
||||
}
|
||||
}
|
||||
@@ -645,7 +691,7 @@ static uint64_t get_cluster_offset(Block
|
||||
/* not found: load a new entry in the least used one */
|
||||
min_index = 0;
|
||||
min_count = 0xffffffff;
|
||||
- for(i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
+ for (i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
if (extent->l2_cache_counts[i] < min_count) {
|
||||
min_count = extent->l2_cache_counts[i];
|
||||
min_index = i;
|
||||
@ -1,102 +0,0 @@
|
||||
From 1c1781fa1c45a7c012f7b2c4be1be372f19e3cc6 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:32 +0800
|
||||
Subject: [PATCH 06/12] VMDK: add field BDRVVmdkState.desc_offset
|
||||
|
||||
There are several occurrence of magic number 0x200 as the descriptor
|
||||
offset within mono sparse image file. This is not the case for images
|
||||
with separate descriptor file. So a field is added to BDRVVmdkState to
|
||||
hold the correct value.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 27 ++++++++++++++++++---------
|
||||
1 file changed, 18 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -81,6 +81,7 @@ typedef struct VmdkExtent {
|
||||
} VmdkExtent;
|
||||
|
||||
typedef struct BDRVVmdkState {
|
||||
+ int desc_offset;
|
||||
uint32_t parent_cid;
|
||||
int num_extents;
|
||||
/* Extent array with num_extents entries, ascend ordered by address */
|
||||
@@ -175,10 +176,11 @@ static uint32_t vmdk_read_cid(BlockDrive
|
||||
uint32_t cid;
|
||||
const char *p_name, *cid_str;
|
||||
size_t cid_str_size;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
|
||||
- /* the descriptor offset = 0x200 */
|
||||
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
|
||||
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
|
||||
return 0;
|
||||
+ }
|
||||
|
||||
if (parent) {
|
||||
cid_str = "parentCID";
|
||||
@@ -200,10 +202,12 @@ static int vmdk_write_cid(BlockDriverSta
|
||||
{
|
||||
char desc[DESC_SIZE], tmp_desc[DESC_SIZE];
|
||||
char *p_name, *tmp_str;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
|
||||
- /* the descriptor offset = 0x200 */
|
||||
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
|
||||
- return -1;
|
||||
+ memset(desc, 0, sizeof(desc));
|
||||
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
|
||||
+ return -EIO;
|
||||
+ }
|
||||
|
||||
tmp_str = strstr(desc,"parentCID");
|
||||
pstrcpy(tmp_desc, sizeof(tmp_desc), tmp_str);
|
||||
@@ -213,8 +217,9 @@ static int vmdk_write_cid(BlockDriverSta
|
||||
pstrcat(desc, sizeof(desc), tmp_desc);
|
||||
}
|
||||
|
||||
- if (bdrv_pwrite_sync(bs->file, 0x200, desc, DESC_SIZE) < 0)
|
||||
- return -1;
|
||||
+ if (bdrv_pwrite_sync(bs->file, s->desc_offset, desc, DESC_SIZE) < 0) {
|
||||
+ return -EIO;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -402,10 +407,11 @@ static int vmdk_parent_open(BlockDriverS
|
||||
{
|
||||
char *p_name;
|
||||
char desc[DESC_SIZE];
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
|
||||
- /* the descriptor offset = 0x200 */
|
||||
- if (bdrv_pread(bs->file, 0x200, desc, DESC_SIZE) != DESC_SIZE)
|
||||
+ if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
|
||||
return -1;
|
||||
+ }
|
||||
|
||||
if ((p_name = strstr(desc,"parentFileNameHint")) != NULL) {
|
||||
char *end_name;
|
||||
@@ -506,8 +512,10 @@ static int vmdk_open_vmdk3(BlockDriverSt
|
||||
int ret;
|
||||
uint32_t magic;
|
||||
VMDK3Header header;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
VmdkExtent *extent;
|
||||
|
||||
+ s->desc_offset = 0x200;
|
||||
ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
@@ -539,6 +547,7 @@ static int vmdk_open_vmdk4(BlockDriverSt
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
VmdkExtent *extent;
|
||||
|
||||
+ s->desc_offset = 0x200;
|
||||
ret = bdrv_pread(bs->file, sizeof(magic), &header, sizeof(header));
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
@ -1,35 +0,0 @@
|
||||
From 49885608e66c1e76a2b715fb36fd2f27f73e5202 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:33 +0800
|
||||
Subject: [PATCH 07/12] VMDK: flush multiple extents
|
||||
|
||||
Flush all the file that referenced by the image.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 12 +++++++++++-
|
||||
1 file changed, 11 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -1072,7 +1072,17 @@ static void vmdk_close(BlockDriverState
|
||||
|
||||
static int vmdk_flush(BlockDriverState *bs)
|
||||
{
|
||||
- return bdrv_flush(bs->file);
|
||||
+ int i, ret, err;
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
+
|
||||
+ ret = bdrv_flush(bs->file);
|
||||
+ for (i = 0; i < s->num_extents; i++) {
|
||||
+ err = bdrv_flush(s->extents[i].file);
|
||||
+ if (err < 0) {
|
||||
+ ret = err;
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
From 9d8117f00364c12cbd658de903b1ed26a30584e0 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:34 +0800
|
||||
Subject: [PATCH 08/12] VMDK: move 'static' cid_update flag to bs field
|
||||
|
||||
Cid_update is the flag for updating CID on first write after opening the
|
||||
image. This should be per image open rather than per program life cycle,
|
||||
so change it from static var of vmdk_write to a field in BDRVVmdkState.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -82,6 +82,7 @@ typedef struct VmdkExtent {
|
||||
|
||||
typedef struct BDRVVmdkState {
|
||||
int desc_offset;
|
||||
+ bool cid_updated;
|
||||
uint32_t parent_cid;
|
||||
int num_extents;
|
||||
/* Extent array with num_extents entries, ascend ordered by address */
|
||||
@@ -853,7 +854,6 @@ static int vmdk_write(BlockDriverState *
|
||||
int n;
|
||||
int64_t index_in_cluster;
|
||||
uint64_t cluster_offset;
|
||||
- static int cid_update = 0;
|
||||
VmdkMetaData m_data;
|
||||
|
||||
if (sector_num > bs->total_sectors) {
|
||||
@@ -900,9 +900,9 @@ static int vmdk_write(BlockDriverState *
|
||||
buf += n * 512;
|
||||
|
||||
// update CID on the first write every time the virtual disk is opened
|
||||
- if (!cid_update) {
|
||||
+ if (!s->cid_updated) {
|
||||
vmdk_write_cid(bs, time(NULL));
|
||||
- cid_update++;
|
||||
+ s->cid_updated = true;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -1,198 +0,0 @@
|
||||
From 9e1ddc6967e8739f4fa47fa4f6a767ebe319f6ff Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 12 Jul 2011 19:56:35 +0800
|
||||
Subject: [PATCH 09/12] VMDK: change get_cluster_offset return type
|
||||
|
||||
The return type of get_cluster_offset was an offset that use 0 to denote
|
||||
'not allocated', this will be no longer true for flat extents, as we see
|
||||
flat extent file as a single huge cluster whose offset is 0 and length
|
||||
is the whole file length.
|
||||
So now we use int return value, 0 means success and otherwise offset
|
||||
invalid.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 79 ++++++++++++++++++++++++++++++++----------------------------
|
||||
1 file changed, 42 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -665,26 +665,31 @@ static int vmdk_L2update(VmdkExtent *ext
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static uint64_t get_cluster_offset(BlockDriverState *bs,
|
||||
+static int get_cluster_offset(BlockDriverState *bs,
|
||||
VmdkExtent *extent,
|
||||
VmdkMetaData *m_data,
|
||||
- uint64_t offset, int allocate)
|
||||
+ uint64_t offset,
|
||||
+ int allocate,
|
||||
+ uint64_t *cluster_offset)
|
||||
{
|
||||
unsigned int l1_index, l2_offset, l2_index;
|
||||
int min_index, i, j;
|
||||
uint32_t min_count, *l2_table, tmp = 0;
|
||||
- uint64_t cluster_offset;
|
||||
|
||||
if (m_data)
|
||||
m_data->valid = 0;
|
||||
+ if (extent->flat) {
|
||||
+ *cluster_offset = 0;
|
||||
+ return 0;
|
||||
+ }
|
||||
|
||||
l1_index = (offset >> 9) / extent->l1_entry_sectors;
|
||||
if (l1_index >= extent->l1_size) {
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
l2_offset = extent->l1_table[l1_index];
|
||||
if (!l2_offset) {
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
for (i = 0; i < L2_CACHE_SIZE; i++) {
|
||||
if (l2_offset == extent->l2_cache_offsets[i]) {
|
||||
@@ -714,28 +719,29 @@ static uint64_t get_cluster_offset(Block
|
||||
l2_table,
|
||||
extent->l2_size * sizeof(uint32_t)
|
||||
) != extent->l2_size * sizeof(uint32_t)) {
|
||||
- return 0;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
extent->l2_cache_offsets[min_index] = l2_offset;
|
||||
extent->l2_cache_counts[min_index] = 1;
|
||||
found:
|
||||
l2_index = ((offset >> 9) / extent->cluster_sectors) % extent->l2_size;
|
||||
- cluster_offset = le32_to_cpu(l2_table[l2_index]);
|
||||
+ *cluster_offset = le32_to_cpu(l2_table[l2_index]);
|
||||
|
||||
- if (!cluster_offset) {
|
||||
- if (!allocate)
|
||||
- return 0;
|
||||
+ if (!*cluster_offset) {
|
||||
+ if (!allocate) {
|
||||
+ return -1;
|
||||
+ }
|
||||
|
||||
// Avoid the L2 tables update for the images that have snapshots.
|
||||
- cluster_offset = bdrv_getlength(extent->file);
|
||||
+ *cluster_offset = bdrv_getlength(extent->file);
|
||||
bdrv_truncate(
|
||||
extent->file,
|
||||
- cluster_offset + (extent->cluster_sectors << 9)
|
||||
+ *cluster_offset + (extent->cluster_sectors << 9)
|
||||
);
|
||||
|
||||
- cluster_offset >>= 9;
|
||||
- tmp = cpu_to_le32(cluster_offset);
|
||||
+ *cluster_offset >>= 9;
|
||||
+ tmp = cpu_to_le32(*cluster_offset);
|
||||
l2_table[l2_index] = tmp;
|
||||
|
||||
/* First of all we write grain itself, to avoid race condition
|
||||
@@ -744,8 +750,8 @@ static uint64_t get_cluster_offset(Block
|
||||
* or inappropriate VM shutdown.
|
||||
*/
|
||||
if (get_whole_cluster(
|
||||
- bs, extent, cluster_offset, offset, allocate) == -1)
|
||||
- return 0;
|
||||
+ bs, extent, *cluster_offset, offset, allocate) == -1)
|
||||
+ return -1;
|
||||
|
||||
if (m_data) {
|
||||
m_data->offset = tmp;
|
||||
@@ -755,8 +761,8 @@ static uint64_t get_cluster_offset(Block
|
||||
m_data->valid = 1;
|
||||
}
|
||||
}
|
||||
- cluster_offset <<= 9;
|
||||
- return cluster_offset;
|
||||
+ *cluster_offset <<= 9;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static VmdkExtent *find_extent(BDRVVmdkState *s,
|
||||
@@ -780,7 +786,6 @@ static int vmdk_is_allocated(BlockDriver
|
||||
int nb_sectors, int *pnum)
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
-
|
||||
int64_t index_in_cluster, n, ret;
|
||||
uint64_t offset;
|
||||
VmdkExtent *extent;
|
||||
@@ -789,15 +794,13 @@ static int vmdk_is_allocated(BlockDriver
|
||||
if (!extent) {
|
||||
return 0;
|
||||
}
|
||||
- if (extent->flat) {
|
||||
- n = extent->end_sector - sector_num;
|
||||
- ret = 1;
|
||||
- } else {
|
||||
- offset = get_cluster_offset(bs, extent, NULL, sector_num * 512, 0);
|
||||
- index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
- n = extent->cluster_sectors - index_in_cluster;
|
||||
- ret = offset ? 1 : 0;
|
||||
- }
|
||||
+ ret = get_cluster_offset(bs, extent, NULL,
|
||||
+ sector_num * 512, 0, &offset);
|
||||
+ /* get_cluster_offset returning 0 means success */
|
||||
+ ret = !ret;
|
||||
+
|
||||
+ index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
+ n = extent->cluster_sectors - index_in_cluster;
|
||||
if (n > nb_sectors)
|
||||
n = nb_sectors;
|
||||
*pnum = n;
|
||||
@@ -818,14 +821,15 @@ static int vmdk_read(BlockDriverState *b
|
||||
if (!extent) {
|
||||
return -EIO;
|
||||
}
|
||||
- cluster_offset = get_cluster_offset(
|
||||
- bs, extent, NULL, sector_num << 9, 0);
|
||||
+ ret = get_cluster_offset(
|
||||
+ bs, extent, NULL,
|
||||
+ sector_num << 9, 0, &cluster_offset);
|
||||
index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
n = extent->cluster_sectors - index_in_cluster;
|
||||
if (n > nb_sectors)
|
||||
n = nb_sectors;
|
||||
- if (!cluster_offset) {
|
||||
- // try to read from parent image, if exist
|
||||
+ if (ret) {
|
||||
+ /* if not allocated, try to read from parent image, if exist */
|
||||
if (bs->backing_hd) {
|
||||
if (!vmdk_is_cid_valid(bs))
|
||||
return -1;
|
||||
@@ -851,7 +855,7 @@ static int vmdk_write(BlockDriverState *
|
||||
{
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
VmdkExtent *extent = NULL;
|
||||
- int n;
|
||||
+ int n, ret;
|
||||
int64_t index_in_cluster;
|
||||
uint64_t cluster_offset;
|
||||
VmdkMetaData m_data;
|
||||
@@ -869,13 +873,14 @@ static int vmdk_write(BlockDriverState *
|
||||
if (!extent) {
|
||||
return -EIO;
|
||||
}
|
||||
- cluster_offset = get_cluster_offset(
|
||||
+ ret = get_cluster_offset(
|
||||
bs,
|
||||
extent,
|
||||
&m_data,
|
||||
- sector_num << 9, 1);
|
||||
- if (!cluster_offset) {
|
||||
- return -1;
|
||||
+ sector_num << 9, 1,
|
||||
+ &cluster_offset);
|
||||
+ if (ret) {
|
||||
+ return -EINVAL;
|
||||
}
|
||||
index_in_cluster = sector_num % extent->cluster_sectors;
|
||||
n = extent->cluster_sectors - index_in_cluster;
|
||||
@ -1,257 +0,0 @@
|
||||
From e6b783a12f7ff491a1a2147d9fe55b4535aa046e Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 19 Jul 2011 08:38:22 +0800
|
||||
Subject: [PATCH 10/12] VMDK: open/read/write for monolithicFlat image
|
||||
|
||||
Parse vmdk decriptor file and open mono flat image.
|
||||
Read/write the flat extent.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||
1 file changed, 158 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -65,6 +65,7 @@ typedef struct VmdkExtent {
|
||||
bool flat;
|
||||
int64_t sectors;
|
||||
int64_t end_sector;
|
||||
+ int64_t flat_start_offset;
|
||||
int64_t l1_table_offset;
|
||||
int64_t l1_backup_table_offset;
|
||||
uint32_t *l1_table;
|
||||
@@ -407,9 +408,10 @@ fail:
|
||||
static int vmdk_parent_open(BlockDriverState *bs)
|
||||
{
|
||||
char *p_name;
|
||||
- char desc[DESC_SIZE];
|
||||
+ char desc[DESC_SIZE + 1];
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
|
||||
+ desc[DESC_SIZE] = '\0';
|
||||
if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
|
||||
return -1;
|
||||
}
|
||||
@@ -584,6 +586,144 @@ static int vmdk_open_vmdk4(BlockDriverSt
|
||||
return ret;
|
||||
}
|
||||
|
||||
+/* find an option value out of descriptor file */
|
||||
+static int vmdk_parse_description(const char *desc, const char *opt_name,
|
||||
+ char *buf, int buf_size)
|
||||
+{
|
||||
+ char *opt_pos, *opt_end;
|
||||
+ const char *end = desc + strlen(desc);
|
||||
+
|
||||
+ opt_pos = strstr(desc, opt_name);
|
||||
+ if (!opt_pos) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ /* Skip "=\"" following opt_name */
|
||||
+ opt_pos += strlen(opt_name) + 2;
|
||||
+ if (opt_pos >= end) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ opt_end = opt_pos;
|
||||
+ while (opt_end < end && *opt_end != '"') {
|
||||
+ opt_end++;
|
||||
+ }
|
||||
+ if (opt_end == end || buf_size < opt_end - opt_pos + 1) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ pstrcpy(buf, opt_end - opt_pos + 1, opt_pos);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
||||
+ const char *desc_file_path)
|
||||
+{
|
||||
+ int ret;
|
||||
+ char access[11];
|
||||
+ char type[11];
|
||||
+ char fname[512];
|
||||
+ const char *p = desc;
|
||||
+ int64_t sectors = 0;
|
||||
+ int64_t flat_offset;
|
||||
+
|
||||
+ while (*p) {
|
||||
+ /* parse extent line:
|
||||
+ * RW [size in sectors] FLAT "file-name.vmdk" OFFSET
|
||||
+ * or
|
||||
+ * RW [size in sectors] SPARSE "file-name.vmdk"
|
||||
+ */
|
||||
+ flat_offset = -1;
|
||||
+ ret = sscanf(p, "%10s %" SCNd64 " %10s %511s %" SCNd64,
|
||||
+ access, §ors, type, fname, &flat_offset);
|
||||
+ if (ret < 4 || strcmp(access, "RW")) {
|
||||
+ goto next_line;
|
||||
+ } else if (!strcmp(type, "FLAT")) {
|
||||
+ if (ret != 5 || flat_offset < 0) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ } else if (ret != 4) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* trim the quotation marks around */
|
||||
+ if (fname[0] == '"') {
|
||||
+ memmove(fname, fname + 1, strlen(fname));
|
||||
+ if (strlen(fname) <= 1 || fname[strlen(fname) - 1] != '"') {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ fname[strlen(fname) - 1] = '\0';
|
||||
+ }
|
||||
+ if (sectors <= 0 ||
|
||||
+ (strcmp(type, "FLAT") && strcmp(type, "SPARSE")) ||
|
||||
+ (strcmp(access, "RW"))) {
|
||||
+ goto next_line;
|
||||
+ }
|
||||
+
|
||||
+ /* save to extents array */
|
||||
+ if (!strcmp(type, "FLAT")) {
|
||||
+ /* FLAT extent */
|
||||
+ char extent_path[PATH_MAX];
|
||||
+ BlockDriverState *extent_file;
|
||||
+ VmdkExtent *extent;
|
||||
+
|
||||
+ path_combine(extent_path, sizeof(extent_path),
|
||||
+ desc_file_path, fname);
|
||||
+ ret = bdrv_file_open(&extent_file, extent_path, bs->open_flags);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ extent = vmdk_add_extent(bs, extent_file, true, sectors,
|
||||
+ 0, 0, 0, 0, sectors);
|
||||
+ extent->flat_start_offset = flat_offset;
|
||||
+ } else {
|
||||
+ /* SPARSE extent, not supported for now */
|
||||
+ fprintf(stderr,
|
||||
+ "VMDK: Not supported extent type \"%s\""".\n", type);
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
+next_line:
|
||||
+ /* move to next line */
|
||||
+ while (*p && *p != '\n') {
|
||||
+ p++;
|
||||
+ }
|
||||
+ p++;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_open_desc_file(BlockDriverState *bs, int flags)
|
||||
+{
|
||||
+ int ret;
|
||||
+ char buf[2048];
|
||||
+ char ct[128];
|
||||
+ BDRVVmdkState *s = bs->opaque;
|
||||
+
|
||||
+ ret = bdrv_pread(bs->file, 0, buf, sizeof(buf));
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+ buf[2047] = '\0';
|
||||
+ if (vmdk_parse_description(buf, "createType", ct, sizeof(ct))) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (strcmp(ct, "monolithicFlat")) {
|
||||
+ fprintf(stderr,
|
||||
+ "VMDK: Not supported image type \"%s\""".\n", ct);
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
+ s->desc_offset = 0;
|
||||
+ ret = vmdk_parse_extents(buf, bs, bs->file->filename);
|
||||
+ if (ret) {
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ /* try to open parent images, if exist */
|
||||
+ if (vmdk_parent_open(bs)) {
|
||||
+ qemu_free(s->extents);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ s->parent_cid = vmdk_read_cid(bs, 1);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int vmdk_open(BlockDriverState *bs, int flags)
|
||||
{
|
||||
uint32_t magic;
|
||||
@@ -598,7 +738,7 @@ static int vmdk_open(BlockDriverState *b
|
||||
} else if (magic == VMDK4_MAGIC) {
|
||||
return vmdk_open_vmdk4(bs, flags);
|
||||
} else {
|
||||
- return -EINVAL;
|
||||
+ return vmdk_open_desc_file(bs, flags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -679,7 +819,7 @@ static int get_cluster_offset(BlockDrive
|
||||
if (m_data)
|
||||
m_data->valid = 0;
|
||||
if (extent->flat) {
|
||||
- *cluster_offset = 0;
|
||||
+ *cluster_offset = extent->flat_start_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -832,16 +972,20 @@ static int vmdk_read(BlockDriverState *b
|
||||
/* if not allocated, try to read from parent image, if exist */
|
||||
if (bs->backing_hd) {
|
||||
if (!vmdk_is_cid_valid(bs))
|
||||
- return -1;
|
||||
+ return -EINVAL;
|
||||
ret = bdrv_read(bs->backing_hd, sector_num, buf, n);
|
||||
if (ret < 0)
|
||||
- return -1;
|
||||
+ return ret;
|
||||
} else {
|
||||
memset(buf, 0, 512 * n);
|
||||
}
|
||||
} else {
|
||||
- if(bdrv_pread(bs->file, cluster_offset + index_in_cluster * 512, buf, n * 512) != n * 512)
|
||||
- return -1;
|
||||
+ ret = bdrv_pread(extent->file,
|
||||
+ cluster_offset + index_in_cluster * 512,
|
||||
+ buf, n * 512);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
+ }
|
||||
}
|
||||
nb_sectors -= n;
|
||||
sector_num += n;
|
||||
@@ -865,7 +1009,7 @@ static int vmdk_write(BlockDriverState *
|
||||
"(VMDK) Wrong offset: sector_num=0x%" PRIx64
|
||||
" total_sectors=0x%" PRIx64 "\n",
|
||||
sector_num, bs->total_sectors);
|
||||
- return -1;
|
||||
+ return -EIO;
|
||||
}
|
||||
|
||||
while (nb_sectors > 0) {
|
||||
@@ -888,16 +1032,17 @@ static int vmdk_write(BlockDriverState *
|
||||
n = nb_sectors;
|
||||
}
|
||||
|
||||
- if (bdrv_pwrite(bs->file,
|
||||
+ ret = bdrv_pwrite(extent->file,
|
||||
cluster_offset + index_in_cluster * 512,
|
||||
- buf, n * 512)
|
||||
- != n * 512) {
|
||||
- return -1;
|
||||
+ buf,
|
||||
+ n * 512);
|
||||
+ if (ret < 0) {
|
||||
+ return ret;
|
||||
}
|
||||
if (m_data.valid) {
|
||||
/* update L2 tables */
|
||||
if (vmdk_L2update(extent, &m_data) == -1) {
|
||||
- return -1;
|
||||
+ return -EIO;
|
||||
}
|
||||
}
|
||||
nb_sectors -= n;
|
||||
@ -1,595 +0,0 @@
|
||||
From 0d0f2ba577bd05491b5954751787f8b969ca1ec3 Mon Sep 17 00:00:00 2001
|
||||
From: Fam Zheng <famcool@gmail.com>
|
||||
Date: Tue, 19 Jul 2011 08:45:23 +0800
|
||||
Subject: [PATCH 11/12] VMDK: create different subformats
|
||||
|
||||
Add create option 'format', with enums:
|
||||
monolithicSparse
|
||||
monolithicFlat
|
||||
twoGbMaxExtentSparse
|
||||
twoGbMaxExtentFlat
|
||||
Each creates a subformat image file. The default is monolithicSparse.
|
||||
|
||||
Signed-off-by: Fam Zheng <famcool@gmail.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 503 ++++++++++++++++++++++++++++++++---------------------------
|
||||
block_int.h | 1 +
|
||||
2 files changed, 275 insertions(+), 229 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -156,8 +156,9 @@ static int vmdk_probe(const uint8_t *buf
|
||||
#define CHECK_CID 1
|
||||
|
||||
#define SECTOR_SIZE 512
|
||||
-#define DESC_SIZE 20*SECTOR_SIZE // 20 sectors of 512 bytes each
|
||||
-#define HEADER_SIZE 512 // first sector of 512 bytes
|
||||
+#define DESC_SIZE (20 * SECTOR_SIZE) /* 20 sectors of 512 bytes each */
|
||||
+#define BUF_SIZE 4096
|
||||
+#define HEADER_SIZE 512 /* first sector of 512 bytes */
|
||||
|
||||
static void vmdk_free_extents(BlockDriverState *bs)
|
||||
{
|
||||
@@ -243,168 +244,6 @@ static int vmdk_is_cid_valid(BlockDriver
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int vmdk_snapshot_create(const char *filename, const char *backing_file)
|
||||
-{
|
||||
- int snp_fd, p_fd;
|
||||
- int ret;
|
||||
- uint32_t p_cid;
|
||||
- char *p_name, *gd_buf, *rgd_buf;
|
||||
- const char *real_filename, *temp_str;
|
||||
- VMDK4Header header;
|
||||
- uint32_t gde_entries, gd_size;
|
||||
- int64_t gd_offset, rgd_offset, capacity, gt_size;
|
||||
- char p_desc[DESC_SIZE], s_desc[DESC_SIZE], hdr[HEADER_SIZE];
|
||||
- static const char desc_template[] =
|
||||
- "# Disk DescriptorFile\n"
|
||||
- "version=1\n"
|
||||
- "CID=%x\n"
|
||||
- "parentCID=%x\n"
|
||||
- "createType=\"monolithicSparse\"\n"
|
||||
- "parentFileNameHint=\"%s\"\n"
|
||||
- "\n"
|
||||
- "# Extent description\n"
|
||||
- "RW %u SPARSE \"%s\"\n"
|
||||
- "\n"
|
||||
- "# The Disk Data Base \n"
|
||||
- "#DDB\n"
|
||||
- "\n";
|
||||
-
|
||||
- snp_fd = open(filename, O_RDWR | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE, 0644);
|
||||
- if (snp_fd < 0)
|
||||
- return -errno;
|
||||
- p_fd = open(backing_file, O_RDONLY | O_BINARY | O_LARGEFILE);
|
||||
- if (p_fd < 0) {
|
||||
- close(snp_fd);
|
||||
- return -errno;
|
||||
- }
|
||||
-
|
||||
- /* read the header */
|
||||
- if (lseek(p_fd, 0x0, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
- if (read(p_fd, hdr, HEADER_SIZE) != HEADER_SIZE) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- /* write the header */
|
||||
- if (lseek(snp_fd, 0x0, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
- if (write(snp_fd, hdr, HEADER_SIZE) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- memset(&header, 0, sizeof(header));
|
||||
- memcpy(&header,&hdr[4], sizeof(header)); // skip the VMDK4_MAGIC
|
||||
-
|
||||
- if (ftruncate(snp_fd, header.grain_offset << 9)) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
- /* the descriptor offset = 0x200 */
|
||||
- if (lseek(p_fd, 0x200, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
- if (read(p_fd, p_desc, DESC_SIZE) != DESC_SIZE) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- if ((p_name = strstr(p_desc,"CID")) != NULL) {
|
||||
- p_name += sizeof("CID");
|
||||
- sscanf(p_name,"%x",&p_cid);
|
||||
- }
|
||||
-
|
||||
- real_filename = filename;
|
||||
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
-
|
||||
- snprintf(s_desc, sizeof(s_desc), desc_template, p_cid, p_cid, backing_file,
|
||||
- (uint32_t)header.capacity, real_filename);
|
||||
-
|
||||
- /* write the descriptor */
|
||||
- if (lseek(snp_fd, 0x200, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
- if (write(snp_fd, s_desc, strlen(s_desc)) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- gd_offset = header.gd_offset * SECTOR_SIZE; // offset of GD table
|
||||
- rgd_offset = header.rgd_offset * SECTOR_SIZE; // offset of RGD table
|
||||
- capacity = header.capacity * SECTOR_SIZE; // Extent size
|
||||
- /*
|
||||
- * Each GDE span 32M disk, means:
|
||||
- * 512 GTE per GT, each GTE points to grain
|
||||
- */
|
||||
- gt_size = (int64_t)header.num_gtes_per_gte * header.granularity * SECTOR_SIZE;
|
||||
- if (!gt_size) {
|
||||
- ret = -EINVAL;
|
||||
- goto fail;
|
||||
- }
|
||||
- gde_entries = (uint32_t)(capacity / gt_size); // number of gde/rgde
|
||||
- gd_size = gde_entries * sizeof(uint32_t);
|
||||
-
|
||||
- /* write RGD */
|
||||
- rgd_buf = qemu_malloc(gd_size);
|
||||
- if (lseek(p_fd, rgd_offset, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_rgd;
|
||||
- }
|
||||
- if (read(p_fd, rgd_buf, gd_size) != gd_size) {
|
||||
- ret = -errno;
|
||||
- goto fail_rgd;
|
||||
- }
|
||||
- if (lseek(snp_fd, rgd_offset, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_rgd;
|
||||
- }
|
||||
- if (write(snp_fd, rgd_buf, gd_size) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_rgd;
|
||||
- }
|
||||
-
|
||||
- /* write GD */
|
||||
- gd_buf = qemu_malloc(gd_size);
|
||||
- if (lseek(p_fd, gd_offset, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_gd;
|
||||
- }
|
||||
- if (read(p_fd, gd_buf, gd_size) != gd_size) {
|
||||
- ret = -errno;
|
||||
- goto fail_gd;
|
||||
- }
|
||||
- if (lseek(snp_fd, gd_offset, SEEK_SET) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_gd;
|
||||
- }
|
||||
- if (write(snp_fd, gd_buf, gd_size) == -1) {
|
||||
- ret = -errno;
|
||||
- goto fail_gd;
|
||||
- }
|
||||
- ret = 0;
|
||||
-
|
||||
-fail_gd:
|
||||
- qemu_free(gd_buf);
|
||||
-fail_rgd:
|
||||
- qemu_free(rgd_buf);
|
||||
-fail:
|
||||
- close(p_fd);
|
||||
- close(snp_fd);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
static int vmdk_parent_open(BlockDriverState *bs)
|
||||
{
|
||||
char *p_name;
|
||||
@@ -1058,68 +897,40 @@ static int vmdk_write(BlockDriverState *
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
+
|
||||
+static int vmdk_create_extent(const char *filename, int64_t filesize, bool flat)
|
||||
{
|
||||
- int fd, i;
|
||||
+ int ret, i;
|
||||
+ int fd = 0;
|
||||
VMDK4Header header;
|
||||
uint32_t tmp, magic, grains, gd_size, gt_size, gt_count;
|
||||
- static const char desc_template[] =
|
||||
- "# Disk DescriptorFile\n"
|
||||
- "version=1\n"
|
||||
- "CID=%x\n"
|
||||
- "parentCID=ffffffff\n"
|
||||
- "createType=\"monolithicSparse\"\n"
|
||||
- "\n"
|
||||
- "# Extent description\n"
|
||||
- "RW %" PRId64 " SPARSE \"%s\"\n"
|
||||
- "\n"
|
||||
- "# The Disk Data Base \n"
|
||||
- "#DDB\n"
|
||||
- "\n"
|
||||
- "ddb.virtualHWVersion = \"%d\"\n"
|
||||
- "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
|
||||
- "ddb.geometry.heads = \"16\"\n"
|
||||
- "ddb.geometry.sectors = \"63\"\n"
|
||||
- "ddb.adapterType = \"ide\"\n";
|
||||
- char desc[1024];
|
||||
- const char *real_filename, *temp_str;
|
||||
- int64_t total_size = 0;
|
||||
- const char *backing_file = NULL;
|
||||
- int flags = 0;
|
||||
- int ret;
|
||||
|
||||
- // Read out options
|
||||
- while (options && options->name) {
|
||||
- if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
||||
- total_size = options->value.n / 512;
|
||||
- } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
||||
- backing_file = options->value.s;
|
||||
- } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
|
||||
- flags |= options->value.n ? BLOCK_FLAG_COMPAT6: 0;
|
||||
- }
|
||||
- options++;
|
||||
+ fd = open(
|
||||
+ filename,
|
||||
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
|
||||
+ 0644);
|
||||
+ if (fd < 0) {
|
||||
+ return -errno;
|
||||
}
|
||||
-
|
||||
- /* XXX: add support for backing file */
|
||||
- if (backing_file) {
|
||||
- return vmdk_snapshot_create(filename, backing_file);
|
||||
+ if (flat) {
|
||||
+ ret = ftruncate(fd, filesize);
|
||||
+ if (ret < 0) {
|
||||
+ ret = -errno;
|
||||
+ }
|
||||
+ goto exit;
|
||||
}
|
||||
-
|
||||
- fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
|
||||
- 0644);
|
||||
- if (fd < 0)
|
||||
- return -errno;
|
||||
magic = cpu_to_be32(VMDK4_MAGIC);
|
||||
memset(&header, 0, sizeof(header));
|
||||
header.version = 1;
|
||||
header.flags = 3; /* ?? */
|
||||
- header.capacity = total_size;
|
||||
+ header.capacity = filesize / 512;
|
||||
header.granularity = 128;
|
||||
header.num_gtes_per_gte = 512;
|
||||
|
||||
- grains = (total_size + header.granularity - 1) / header.granularity;
|
||||
+ grains = (filesize / 512 + header.granularity - 1) / header.granularity;
|
||||
gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
|
||||
- gt_count = (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
|
||||
+ gt_count =
|
||||
+ (grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
|
||||
gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
|
||||
|
||||
header.desc_offset = 1;
|
||||
@@ -1130,7 +941,6 @@ static int vmdk_create(const char *filen
|
||||
((header.gd_offset + gd_size + (gt_size * gt_count) +
|
||||
header.granularity - 1) / header.granularity) *
|
||||
header.granularity;
|
||||
-
|
||||
/* swap endianness for all header fields */
|
||||
header.version = cpu_to_le32(header.version);
|
||||
header.flags = cpu_to_le32(header.flags);
|
||||
@@ -1188,27 +998,255 @@ static int vmdk_create(const char *filen
|
||||
}
|
||||
}
|
||||
|
||||
- /* compose the descriptor */
|
||||
- real_filename = filename;
|
||||
- if ((temp_str = strrchr(real_filename, '\\')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
- if ((temp_str = strrchr(real_filename, '/')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
- if ((temp_str = strrchr(real_filename, ':')) != NULL)
|
||||
- real_filename = temp_str + 1;
|
||||
- snprintf(desc, sizeof(desc), desc_template, (unsigned int)time(NULL),
|
||||
- total_size, real_filename,
|
||||
- (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
- total_size / (int64_t)(63 * 16));
|
||||
+ ret = 0;
|
||||
+ exit:
|
||||
+ close(fd);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
- /* write the descriptor */
|
||||
- lseek(fd, le64_to_cpu(header.desc_offset) << 9, SEEK_SET);
|
||||
+static int filename_decompose(const char *filename, char *path, char *prefix,
|
||||
+ char *postfix, size_t buf_len)
|
||||
+{
|
||||
+ const char *p, *q;
|
||||
+
|
||||
+ if (filename == NULL || !strlen(filename)) {
|
||||
+ fprintf(stderr, "Vmdk: no filename provided.\n");
|
||||
+ return -1;
|
||||
+ }
|
||||
+ p = strrchr(filename, '/');
|
||||
+ if (p == NULL) {
|
||||
+ p = strrchr(filename, '\\');
|
||||
+ }
|
||||
+ if (p == NULL) {
|
||||
+ p = strrchr(filename, ':');
|
||||
+ }
|
||||
+ if (p != NULL) {
|
||||
+ p++;
|
||||
+ if (p - filename >= buf_len) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ pstrcpy(path, p - filename + 1, filename);
|
||||
+ } else {
|
||||
+ p = filename;
|
||||
+ path[0] = '\0';
|
||||
+ }
|
||||
+ q = strrchr(p, '.');
|
||||
+ if (q == NULL) {
|
||||
+ pstrcpy(prefix, buf_len, p);
|
||||
+ postfix[0] = '\0';
|
||||
+ } else {
|
||||
+ if (q - p >= buf_len) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ pstrcpy(prefix, q - p + 1, p);
|
||||
+ pstrcpy(postfix, buf_len, q);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int relative_path(char *dest, int dest_size,
|
||||
+ const char *base, const char *target)
|
||||
+{
|
||||
+ int i = 0;
|
||||
+ int n = 0;
|
||||
+ const char *p, *q;
|
||||
+#ifdef _WIN32
|
||||
+ const char *sep = "\\";
|
||||
+#else
|
||||
+ const char *sep = "/";
|
||||
+#endif
|
||||
+
|
||||
+ if (!(dest && base && target)) {
|
||||
+ return -1;
|
||||
+ }
|
||||
+ if (path_is_absolute(target)) {
|
||||
+ dest[dest_size - 1] = '\0';
|
||||
+ strncpy(dest, target, dest_size - 1);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ while (base[i] == target[i]) {
|
||||
+ i++;
|
||||
+ }
|
||||
+ p = &base[i];
|
||||
+ q = &target[i];
|
||||
+ while (*p) {
|
||||
+ if (*p == *sep) {
|
||||
+ n++;
|
||||
+ }
|
||||
+ p++;
|
||||
+ }
|
||||
+ dest[0] = '\0';
|
||||
+ for (; n; n--) {
|
||||
+ pstrcat(dest, dest_size, "..");
|
||||
+ pstrcat(dest, dest_size, sep);
|
||||
+ }
|
||||
+ pstrcat(dest, dest_size, q);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int vmdk_create(const char *filename, QEMUOptionParameter *options)
|
||||
+{
|
||||
+ int fd, idx = 0;
|
||||
+ char desc[BUF_SIZE];
|
||||
+ int64_t total_size = 0, filesize;
|
||||
+ const char *backing_file = NULL;
|
||||
+ const char *fmt = NULL;
|
||||
+ int flags = 0;
|
||||
+ int ret = 0;
|
||||
+ bool flat, split;
|
||||
+ char ext_desc_lines[BUF_SIZE] = "";
|
||||
+ char path[PATH_MAX], prefix[PATH_MAX], postfix[PATH_MAX];
|
||||
+ const int64_t split_size = 0x80000000; /* VMDK has constant split size */
|
||||
+ const char *desc_extent_line;
|
||||
+ char parent_desc_line[BUF_SIZE] = "";
|
||||
+ uint32_t parent_cid = 0xffffffff;
|
||||
+ const char desc_template[] =
|
||||
+ "# Disk DescriptorFile\n"
|
||||
+ "version=1\n"
|
||||
+ "CID=%x\n"
|
||||
+ "parentCID=%x\n"
|
||||
+ "createType=\"%s\"\n"
|
||||
+ "%s"
|
||||
+ "\n"
|
||||
+ "# Extent description\n"
|
||||
+ "%s"
|
||||
+ "\n"
|
||||
+ "# The Disk Data Base\n"
|
||||
+ "#DDB\n"
|
||||
+ "\n"
|
||||
+ "ddb.virtualHWVersion = \"%d\"\n"
|
||||
+ "ddb.geometry.cylinders = \"%" PRId64 "\"\n"
|
||||
+ "ddb.geometry.heads = \"16\"\n"
|
||||
+ "ddb.geometry.sectors = \"63\"\n"
|
||||
+ "ddb.adapterType = \"ide\"\n";
|
||||
+
|
||||
+ if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ /* Read out options */
|
||||
+ while (options && options->name) {
|
||||
+ if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
||||
+ total_size = options->value.n;
|
||||
+ } else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
||||
+ backing_file = options->value.s;
|
||||
+ } else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
|
||||
+ flags |= options->value.n ? BLOCK_FLAG_COMPAT6 : 0;
|
||||
+ } else if (!strcmp(options->name, BLOCK_OPT_SUBFMT)) {
|
||||
+ fmt = options->value.s;
|
||||
+ }
|
||||
+ options++;
|
||||
+ }
|
||||
+ if (!fmt) {
|
||||
+ /* Default format to monolithicSparse */
|
||||
+ fmt = "monolithicSparse";
|
||||
+ } else if (strcmp(fmt, "monolithicFlat") &&
|
||||
+ strcmp(fmt, "monolithicSparse") &&
|
||||
+ strcmp(fmt, "twoGbMaxExtentSparse") &&
|
||||
+ strcmp(fmt, "twoGbMaxExtentFlat")) {
|
||||
+ fprintf(stderr, "VMDK: Unknown subformat: %s\n", fmt);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&
|
||||
+ strcmp(fmt, "twoGbMaxExtentSparse"));
|
||||
+ flat = !(strcmp(fmt, "monolithicFlat") &&
|
||||
+ strcmp(fmt, "twoGbMaxExtentFlat"));
|
||||
+ if (flat) {
|
||||
+ desc_extent_line = "RW %lld FLAT \"%s\" 0\n";
|
||||
+ } else {
|
||||
+ desc_extent_line = "RW %lld SPARSE \"%s\"\n";
|
||||
+ }
|
||||
+ if (flat && backing_file) {
|
||||
+ /* not supporting backing file for flat image */
|
||||
+ return -ENOTSUP;
|
||||
+ }
|
||||
+ if (backing_file) {
|
||||
+ char parent_filename[PATH_MAX];
|
||||
+ BlockDriverState *bs = bdrv_new("");
|
||||
+ ret = bdrv_open(bs, backing_file, 0, NULL);
|
||||
+ if (ret != 0) {
|
||||
+ bdrv_delete(bs);
|
||||
+ return ret;
|
||||
+ }
|
||||
+ if (strcmp(bs->drv->format_name, "vmdk")) {
|
||||
+ bdrv_delete(bs);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ filesize = bdrv_getlength(bs);
|
||||
+ parent_cid = vmdk_read_cid(bs, 0);
|
||||
+ bdrv_delete(bs);
|
||||
+ relative_path(parent_filename, sizeof(parent_filename),
|
||||
+ filename, backing_file);
|
||||
+ snprintf(parent_desc_line, sizeof(parent_desc_line),
|
||||
+ "parentFileNameHint=\"%s\"", parent_filename);
|
||||
+ }
|
||||
+
|
||||
+ /* Create extents */
|
||||
+ filesize = total_size;
|
||||
+ while (filesize > 0) {
|
||||
+ char desc_line[BUF_SIZE];
|
||||
+ char ext_filename[PATH_MAX];
|
||||
+ char desc_filename[PATH_MAX];
|
||||
+ int64_t size = filesize;
|
||||
+
|
||||
+ if (split && size > split_size) {
|
||||
+ size = split_size;
|
||||
+ }
|
||||
+ if (split) {
|
||||
+ snprintf(desc_filename, sizeof(desc_filename), "%s-%c%03d%s",
|
||||
+ prefix, flat ? 'f' : 's', ++idx, postfix);
|
||||
+ } else if (flat) {
|
||||
+ snprintf(desc_filename, sizeof(desc_filename), "%s-flat%s",
|
||||
+ prefix, postfix);
|
||||
+ } else {
|
||||
+ snprintf(desc_filename, sizeof(desc_filename), "%s%s",
|
||||
+ prefix, postfix);
|
||||
+ }
|
||||
+ snprintf(ext_filename, sizeof(ext_filename), "%s%s",
|
||||
+ path, desc_filename);
|
||||
+
|
||||
+ if (vmdk_create_extent(ext_filename, size, flat)) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ filesize -= size;
|
||||
+
|
||||
+ /* Format description line */
|
||||
+ snprintf(desc_line, sizeof(desc_line),
|
||||
+ desc_extent_line, size / 512, desc_filename);
|
||||
+ pstrcat(ext_desc_lines, sizeof(ext_desc_lines), desc_line);
|
||||
+ }
|
||||
+ /* generate descriptor file */
|
||||
+ snprintf(desc, sizeof(desc), desc_template,
|
||||
+ (unsigned int)time(NULL),
|
||||
+ parent_cid,
|
||||
+ fmt,
|
||||
+ parent_desc_line,
|
||||
+ ext_desc_lines,
|
||||
+ (flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
+ total_size / (int64_t)(63 * 16 * 512));
|
||||
+ if (split || flat) {
|
||||
+ fd = open(
|
||||
+ filename,
|
||||
+ O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
|
||||
+ 0644);
|
||||
+ } else {
|
||||
+ fd = open(
|
||||
+ filename,
|
||||
+ O_WRONLY | O_BINARY | O_LARGEFILE,
|
||||
+ 0644);
|
||||
+ }
|
||||
+ if (fd < 0) {
|
||||
+ return -errno;
|
||||
+ }
|
||||
+ /* the descriptor offset = 0x200 */
|
||||
+ if (!split && !flat && 0x200 != lseek(fd, 0x200, SEEK_SET)) {
|
||||
+ ret = -errno;
|
||||
+ goto exit;
|
||||
+ }
|
||||
ret = qemu_write_full(fd, desc, strlen(desc));
|
||||
if (ret != strlen(desc)) {
|
||||
ret = -errno;
|
||||
goto exit;
|
||||
}
|
||||
-
|
||||
ret = 0;
|
||||
exit:
|
||||
close(fd);
|
||||
@@ -1252,6 +1290,13 @@ static QEMUOptionParameter vmdk_create_o
|
||||
.type = OPT_FLAG,
|
||||
.help = "VMDK version 6 image"
|
||||
},
|
||||
+ {
|
||||
+ .name = BLOCK_OPT_SUBFMT,
|
||||
+ .type = OPT_STRING,
|
||||
+ .help =
|
||||
+ "VMDK flat extent format, can be one of "
|
||||
+ "{monolithicSparse (default) | monolithicFlat | twoGbMaxExtentSparse | twoGbMaxExtentFlat} "
|
||||
+ },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
--- a/block_int.h
|
||||
+++ b/block_int.h
|
||||
@@ -39,6 +39,7 @@
|
||||
#define BLOCK_OPT_CLUSTER_SIZE "cluster_size"
|
||||
#define BLOCK_OPT_TABLE_SIZE "table_size"
|
||||
#define BLOCK_OPT_PREALLOC "preallocation"
|
||||
+#define BLOCK_OPT_SUBFMT "subformat"
|
||||
|
||||
typedef struct AIOPool {
|
||||
void (*cancel)(BlockDriverAIOCB *acb);
|
||||
@ -1,114 +0,0 @@
|
||||
From 5483df4df2729a5d1e4888a48039b1cd90438480 Mon Sep 17 00:00:00 2001
|
||||
From: Othmar Pasteka <pasteka@kabsi.at>
|
||||
Date: Wed, 30 Jan 2013 00:26:52 +0100
|
||||
Subject: [PATCH 12/12] vmdk: Allow selecting SCSI adapter in image creation
|
||||
|
||||
Introduce a new option "adapter_type" when converting to vmdk images.
|
||||
It can be one of the following: ide (default), buslogic, lsilogic
|
||||
or legacyESX (according to the vmdk spec from vmware).
|
||||
|
||||
In case of a non-ide adapter, heads is set to 255 instead of the 16.
|
||||
The latter is used for "ide".
|
||||
|
||||
Also see LP#545089
|
||||
|
||||
Signed-off-by: Othmar Pasteka <pasteka@kabsi.at>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
---
|
||||
block/vmdk.c | 31 ++++++++++++++++++++++++++++---
|
||||
block_int.h | 1 +
|
||||
2 files changed, 29 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/block/vmdk.c
|
||||
+++ b/block/vmdk.c
|
||||
@@ -1089,6 +1089,7 @@ static int vmdk_create(const char *filen
|
||||
int fd, idx = 0;
|
||||
char desc[BUF_SIZE];
|
||||
int64_t total_size = 0, filesize;
|
||||
+ const char *adapter_type = NULL;
|
||||
const char *backing_file = NULL;
|
||||
const char *fmt = NULL;
|
||||
int flags = 0;
|
||||
@@ -1100,6 +1101,7 @@ static int vmdk_create(const char *filen
|
||||
const char *desc_extent_line;
|
||||
char parent_desc_line[BUF_SIZE] = "";
|
||||
uint32_t parent_cid = 0xffffffff;
|
||||
+ uint32_t number_heads = 16;
|
||||
const char desc_template[] =
|
||||
"# Disk DescriptorFile\n"
|
||||
"version=1\n"
|
||||
@@ -1116,9 +1118,9 @@ static int vmdk_create(const char *filen
|
||||
"\n"
|
||||
"ddb.virtualHWVersion = \"%d\"\n"
|
||||
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
|
||||
- "ddb.geometry.heads = \"16\"\n"
|
||||
+ "ddb.geometry.heads = \"%d\"\n"
|
||||
"ddb.geometry.sectors = \"63\"\n"
|
||||
- "ddb.adapterType = \"ide\"\n";
|
||||
+ "ddb.adapterType = \"%s\"\n";
|
||||
|
||||
if (filename_decompose(filename, path, prefix, postfix, PATH_MAX)) {
|
||||
return -EINVAL;
|
||||
@@ -1127,6 +1129,8 @@ static int vmdk_create(const char *filen
|
||||
while (options && options->name) {
|
||||
if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
|
||||
total_size = options->value.n;
|
||||
+ } else if (!strcmp(options->name, BLOCK_OPT_ADAPTER_TYPE)) {
|
||||
+ adapter_type = options->value.s;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_BACKING_FILE)) {
|
||||
backing_file = options->value.s;
|
||||
} else if (!strcmp(options->name, BLOCK_OPT_COMPAT6)) {
|
||||
@@ -1136,6 +1140,20 @@ static int vmdk_create(const char *filen
|
||||
}
|
||||
options++;
|
||||
}
|
||||
+ if (!adapter_type) {
|
||||
+ adapter_type = "ide";
|
||||
+ } else if (strcmp(adapter_type, "ide") &&
|
||||
+ strcmp(adapter_type, "buslogic") &&
|
||||
+ strcmp(adapter_type, "lsilogic") &&
|
||||
+ strcmp(adapter_type, "legacyESX")) {
|
||||
+ fprintf(stderr, "VMDK: Unknown adapter type: '%s'.\n", adapter_type);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (strcmp(adapter_type, "ide") != 0) {
|
||||
+ /* that's the number of heads with which vmware operates when
|
||||
+ creating, exporting, etc. vmdk files with a non-ide adapter type */
|
||||
+ number_heads = 255;
|
||||
+ }
|
||||
if (!fmt) {
|
||||
/* Default format to monolithicSparse */
|
||||
fmt = "monolithicSparse";
|
||||
@@ -1222,7 +1240,8 @@ static int vmdk_create(const char *filen
|
||||
parent_desc_line,
|
||||
ext_desc_lines,
|
||||
(flags & BLOCK_FLAG_COMPAT6 ? 6 : 4),
|
||||
- total_size / (int64_t)(63 * 16 * 512));
|
||||
+ total_size / (int64_t)(63 * number_heads * 512), number_heads,
|
||||
+ adapter_type);
|
||||
if (split || flat) {
|
||||
fd = open(
|
||||
filename,
|
||||
@@ -1281,6 +1300,12 @@ static QEMUOptionParameter vmdk_create_o
|
||||
.help = "Virtual disk size"
|
||||
},
|
||||
{
|
||||
+ .name = BLOCK_OPT_ADAPTER_TYPE,
|
||||
+ .type = OPT_STRING,
|
||||
+ .help = "Virtual adapter type, can be one of "
|
||||
+ "ide (default), lsilogic, buslogic or legacyESX"
|
||||
+ },
|
||||
+ {
|
||||
.name = BLOCK_OPT_BACKING_FILE,
|
||||
.type = OPT_STRING,
|
||||
.help = "File name of a base image"
|
||||
--- a/block_int.h
|
||||
+++ b/block_int.h
|
||||
@@ -40,6 +40,7 @@
|
||||
#define BLOCK_OPT_TABLE_SIZE "table_size"
|
||||
#define BLOCK_OPT_PREALLOC "preallocation"
|
||||
#define BLOCK_OPT_SUBFMT "subformat"
|
||||
+#define BLOCK_OPT_ADAPTER_TYPE "adapter_type"
|
||||
|
||||
typedef struct AIOPool {
|
||||
void (*cancel)(BlockDriverAIOCB *acb);
|
||||
Loading…
Reference in New Issue
Block a user