diff --git a/config/Config-images.in b/config/Config-images.in index eb0aa2c84c..5d0ee990c7 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -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 diff --git a/include/image-commands.mk b/include/image-commands.mk index f21f9e3f03..022e3d4fbd 100644 --- a/include/image-commands.mk +++ b/include/image-commands.mk @@ -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 diff --git a/include/image.mk b/include/image.mk index ef0d460514..0be07714d0 100644 --- a/include/image.mk +++ b/include/image.mk @@ -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))) diff --git a/package/base-files/files/lib/upgrade/common.sh b/package/base-files/files/lib/upgrade/common.sh index 1da87b975d..d3938b9996 100755 --- a/package/base-files/files/lib/upgrade/common.sh +++ b/package/base-files/files/lib/upgrade/common.sh @@ -90,6 +90,17 @@ get_image() { # [ ] 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() { # 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 } diff --git a/package/boot/grub2/Makefile b/package/boot/grub2/Makefile new file mode 100644 index 0000000000..a57486b91d --- /dev/null +++ b/package/boot/grub2/Makefile @@ -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)) diff --git a/package/boot/grub2/common.mk b/package/boot/grub2/common.mk deleted file mode 100644 index 115648a7f9..0000000000 --- a/package/boot/grub2/common.mk +++ /dev/null @@ -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 diff --git a/target/linux/x86/image/grub-early.cfg b/package/boot/grub2/files/grub-early.cfg similarity index 100% rename from target/linux/x86/image/grub-early.cfg rename to package/boot/grub2/files/grub-early.cfg diff --git a/package/boot/grub2/grub2-efi/Makefile b/package/boot/grub2/grub2-efi/Makefile deleted file mode 100644 index 035bfc3336..0000000000 --- a/package/boot/grub2/grub2-efi/Makefile +++ /dev/null @@ -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)) diff --git a/package/boot/grub2/grub2/Makefile b/package/boot/grub2/grub2/Makefile deleted file mode 100644 index c00797662b..0000000000 --- a/package/boot/grub2/grub2/Makefile +++ /dev/null @@ -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)) diff --git a/package/boot/grub2/patches/300-CVE-2015-8370.patch b/package/boot/grub2/patches/300-CVE-2015-8370.patch index f6b8a93d39..22f6c90928 100644 --- a/package/boot/grub2/patches/300-CVE-2015-8370.patch +++ b/package/boot/grub2/patches/300-CVE-2015-8370.patch @@ -32,7 +32,7 @@ Signed-off-by: Ismael Ripoll-Ripoll @@ -172,7 +172,7 @@ grub_username_get (char buf[], unsigned break; } - + - if (key == GRUB_TERM_BACKSPACE) + if (key == GRUB_TERM_BACKSPACE && cur_len) { diff --git a/scripts/gen_image_generic.sh b/scripts/gen_image_generic.sh index 5162be11dd..9d05b6254e 100755 --- a/scripts/gen_image_generic.sh +++ b/scripts/gen_image_generic.sh @@ -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" diff --git a/target/linux/mvebu/base-files/lib/upgrade/sdcard.sh b/target/linux/mvebu/base-files/lib/upgrade/sdcard.sh index 0f6c25aebc..cd2904fffc 100644 --- a/target/linux/mvebu/base-files/lib/upgrade/sdcard.sh +++ b/target/linux/mvebu/base-files/lib/upgrade/sdcard.sh @@ -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 diff --git a/target/linux/tegra/Makefile b/target/linux/tegra/Makefile index 1dd9f99979..98c1dece16 100644 --- a/target/linux/tegra/Makefile +++ b/target/linux/tegra/Makefile @@ -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 KERNEL_PATCHVER := 5.4 KERNEL_TESTING_PATCHVER := 5.10 diff --git a/target/linux/tegra/base-files/lib/upgrade/platform.sh b/target/linux/tegra/base-files/lib/upgrade/platform.sh index 6c9b73cdc1..7e52dd9add 100644 --- a/target/linux/tegra/base-files/lib/upgrade/platform.sh +++ b/target/linux/tegra/base-files/lib/upgrade/platform.sh @@ -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 } diff --git a/target/linux/tegra/image/Makefile b/target/linux/tegra/image/Makefile index 66a4be0fce..58c2fe74f8 100644 --- a/target/linux/tegra/image/Makefile +++ b/target/linux/tegra/image/Makefile @@ -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 diff --git a/target/linux/x86/64/profiles/000-Generic.mk b/target/linux/x86/64/profiles/000-Generic.mk deleted file mode 100644 index ccd125afa2..0000000000 --- a/target/linux/x86/64/profiles/000-Generic.mk +++ /dev/null @@ -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)) diff --git a/target/linux/x86/64/target.mk b/target/linux/x86/64/target.mk index 95e32b3360..637bef1a09 100644 --- a/target/linux/x86/64/target.mk +++ b/target/linux/x86/64/target.mk @@ -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 diff --git a/target/linux/x86/Makefile b/target/linux/x86/Makefile index 8f0493a9a7..3dee13955c 100644 --- a/target/linux/x86/Makefile +++ b/target/linux/x86/Makefile @@ -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 @@ -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 \ )) diff --git a/target/linux/x86/base-files/lib/preinit/79_move_config b/target/linux/x86/base-files/lib/preinit/79_move_config index 5acec95727..52546fc0d9 100644 --- a/target/linux/x86/base-files/lib/preinit/79_move_config +++ b/target/linux/x86/base-files/lib/preinit/79_move_config @@ -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 diff --git a/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader new file mode 100644 index 0000000000..42f04d76a7 --- /dev/null +++ b/target/linux/x86/base-files/lib/preinit/81_upgrade_bootloader @@ -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 diff --git a/target/linux/x86/base-files/lib/upgrade/platform.sh b/target/linux/x86/base-files/lib/upgrade/platform.sh index 439ba8f512..9147ddcf2a 100644 --- a/target/linux/x86/base-files/lib/upgrade/platform.sh +++ b/target/linux/x86/base-files/lib/upgrade/platform.sh @@ -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 } diff --git a/target/linux/x86/generic/config-5.4 b/target/linux/x86/generic/config-5.4 index ee9482ab0a..a668d03088 100644 --- a/target/linux/x86/generic/config-5.4 +++ b/target/linux/x86/generic/config-5.4 @@ -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 diff --git a/target/linux/x86/generic/profiles/000-Generic.mk b/target/linux/x86/generic/profiles/000-Generic.mk deleted file mode 100644 index 90f989a91d..0000000000 --- a/target/linux/x86/generic/profiles/000-Generic.mk +++ /dev/null @@ -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)) diff --git a/target/linux/x86/generic/target.mk b/target/linux/x86/generic/target.mk index 70527d001d..90586f56d6 100644 --- a/target/linux/x86/generic/target.mk +++ b/target/linux/x86/generic/target.mk @@ -1,4 +1,4 @@ -BOARDNAME:=x86 32bit +BOARDNAME:=Generic CPU_TYPE :=pentium4 FEATURES += audio pci pcie usb DEFAULT_PACKAGES += kmod-button-hotplug diff --git a/target/linux/x86/geode/profiles/000-Generic.mk b/target/linux/x86/geode/profiles/000-Generic.mk deleted file mode 100644 index 58dc3c641c..0000000000 --- a/target/linux/x86/geode/profiles/000-Generic.mk +++ /dev/null @@ -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)) diff --git a/target/linux/x86/geode/profiles/100-Geos.mk b/target/linux/x86/geode/profiles/100-Geos.mk deleted file mode 100644 index 94e501edf4..0000000000 --- a/target/linux/x86/geode/profiles/100-Geos.mk +++ /dev/null @@ -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)) diff --git a/target/linux/x86/image/64.mk b/target/linux/x86/image/64.mk new file mode 100644 index 0000000000..9c9decbf79 --- /dev/null +++ b/target/linux/x86/image/64.mk @@ -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 diff --git a/target/linux/x86/image/Makefile b/target/linux/x86/image/Makefile index 05ad059bc6..6fc353b9f2 100644 --- a/target/linux/x86/image/Makefile +++ b/target/linux/x86/image/Makefile @@ -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)) + diff --git a/target/linux/x86/image/gen_image_efi.sh b/target/linux/x86/image/gen_image_efi.sh deleted file mode 100755 index 3ecb25fed9..0000000000 --- a/target/linux/x86/image/gen_image_efi.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash -set -x -[ $# == 8 -o $# == 9 ] || { - echo "SYNTAX: $0 []" - 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" diff --git a/target/linux/x86/image/generic.mk b/target/linux/x86/image/generic.mk new file mode 100644 index 0000000000..8a23afef0a --- /dev/null +++ b/target/linux/x86/image/generic.mk @@ -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 diff --git a/target/linux/x86/image/geode.mk b/target/linux/x86/image/geode.mk new file mode 100644 index 0000000000..2ed2245f7d --- /dev/null +++ b/target/linux/x86/image/geode.mk @@ -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 diff --git a/target/linux/x86/image/grub-efi.cfg b/target/linux/x86/image/grub-efi.cfg new file mode 100644 index 0000000000..14d30e88e4 --- /dev/null +++ b/target/linux/x86/image/grub-efi.cfg @@ -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 +} diff --git a/target/linux/x86/image/grub-iso.cfg b/target/linux/x86/image/grub-iso.cfg index 9c59bdf6d4..4bef492a41 100644 --- a/target/linux/x86/image/grub-iso.cfg +++ b/target/linux/x86/image/grub-iso.cfg @@ -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 } diff --git a/target/linux/x86/image/grub-pc.cfg b/target/linux/x86/image/grub-pc.cfg new file mode 100644 index 0000000000..75605bcabf --- /dev/null +++ b/target/linux/x86/image/grub-pc.cfg @@ -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 +} diff --git a/target/linux/x86/image/grub.cfg b/target/linux/x86/image/grub.cfg deleted file mode 100644 index dedfa0a636..0000000000 --- a/target/linux/x86/image/grub.cfg +++ /dev/null @@ -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 -} diff --git a/target/linux/x86/image/legacy.mk b/target/linux/x86/image/legacy.mk new file mode 100644 index 0000000000..5c13f95157 --- /dev/null +++ b/target/linux/x86/image/legacy.mk @@ -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 diff --git a/target/linux/x86/image/zen.mk b/target/linux/x86/image/zen.mk new file mode 100644 index 0000000000..b58f54e2a1 --- /dev/null +++ b/target/linux/x86/image/zen.mk @@ -0,0 +1,5 @@ +define Device/generic + DEVICE_TITLE := Generic Zen Architecture + GRUB2_VARIANT := generic +endef +TARGET_DEVICES += generic diff --git a/target/linux/x86/legacy/profiles/000-Generic.mk b/target/linux/x86/legacy/profiles/000-Generic.mk deleted file mode 100644 index 90f989a91d..0000000000 --- a/target/linux/x86/legacy/profiles/000-Generic.mk +++ /dev/null @@ -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)) diff --git a/target/linux/x86/legacy/target.mk b/target/linux/x86/legacy/target.mk index a82e49ea8f..bd0a87d67f 100644 --- a/target/linux/x86/legacy/target.mk +++ b/target/linux/x86/legacy/target.mk @@ -1,4 +1,4 @@ -BOARDNAME:=Legacy x86 (i586) +BOARDNAME:=Legacy define Target/Description Build firmware images for legacy x86 based boards diff --git a/target/linux/x86/zen/profiles/000-Generic.mk b/target/linux/x86/zen/profiles/000-Generic.mk deleted file mode 100644 index ccd125afa2..0000000000 --- a/target/linux/x86/zen/profiles/000-Generic.mk +++ /dev/null @@ -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)) diff --git a/tools/Makefile b/tools/Makefile index a897661ec9..46564cf4ac 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -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 diff --git a/tools/bison/Makefile b/tools/bison/Makefile index fde812f334..8f3043fcb8 100644 --- a/tools/bison/Makefile +++ b/tools/bison/Makefile @@ -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 diff --git a/tools/bison/patches/100-fix-gets-removal.patch b/tools/bison/patches/100-fix-gets-removal.patch index f97e8a3985..534713f180 100644 --- a/tools/bison/patches/100-fix-gets-removal.patch +++ b/tools/bison/patches/100-fix-gets-removal.patch @@ -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 diff --git a/tools/expat/Makefile b/tools/expat/Makefile index f29264ea68..cfc70b2a49 100644 --- a/tools/expat/Makefile +++ b/tools/expat/Makefile @@ -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 diff --git a/tools/gmp/Makefile b/tools/gmp/Makefile index 36d51eb711..967cf6817b 100644 --- a/tools/gmp/Makefile +++ b/tools/gmp/Makefile @@ -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 diff --git a/tools/mpc/Makefile b/tools/mpc/Makefile index 27e9a01c4b..733c14173b 100644 --- a/tools/mpc/Makefile +++ b/tools/mpc/Makefile @@ -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 diff --git a/tools/qemu/Makefile b/tools/qemu/Makefile deleted file mode 100644 index d63ab3482e..0000000000 --- a/tools/qemu/Makefile +++ /dev/null @@ -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)) diff --git a/tools/qemu/patches/0001-vmdk-fix-endianness-bugs.patch b/tools/qemu/patches/0001-vmdk-fix-endianness-bugs.patch deleted file mode 100644 index 7e1abb49bf..0000000000 --- a/tools/qemu/patches/0001-vmdk-fix-endianness-bugs.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 6afca0fc5430db0300fe53f2b9cd7d071a3925bb Mon Sep 17 00:00:00 2001 -From: Alexander Graf -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 -Signed-off-by: Alexander Graf -Signed-off-by: Kevin Wolf ---- - 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)) { diff --git a/tools/qemu/patches/0002-VMDK-introduce-VmdkExtent.patch b/tools/qemu/patches/0002-VMDK-introduce-VmdkExtent.patch deleted file mode 100644 index 054b143245..0000000000 --- a/tools/qemu/patches/0002-VMDK-introduce-VmdkExtent.patch +++ /dev/null @@ -1,557 +0,0 @@ -From fcd9c52d160376184cbd25e04586aa6eef6abd61 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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) diff --git a/tools/qemu/patches/0003-VMDK-bugfix-align-offset-to-cluster-in-get_whole_clu.patch b/tools/qemu/patches/0003-VMDK-bugfix-align-offset-to-cluster-in-get_whole_clu.patch deleted file mode 100644 index 38e6c0ae8f..0000000000 --- a/tools/qemu/patches/0003-VMDK-bugfix-align-offset-to-cluster-in-get_whole_clu.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 66922efc83a670178b208dec2f5123ec85fb6ba3 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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) { diff --git a/tools/qemu/patches/0004-VMDK-probe-for-monolithicFlat-images.patch b/tools/qemu/patches/0004-VMDK-probe-for-monolithicFlat-images.patch deleted file mode 100644 index 86451ea24d..0000000000 --- a/tools/qemu/patches/0004-VMDK-probe-for-monolithicFlat-images.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 930e57ecb64bbab75c2b71d0d1ba07451fec4567 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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 diff --git a/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch b/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch deleted file mode 100644 index 7323aa13be..0000000000 --- a/tools/qemu/patches/0005-VMDK-separate-vmdk_open-by-format-version.patch +++ /dev/null @@ -1,241 +0,0 @@ -From 97cf5df76657bab81d6b8669607f6f13215201c1 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; diff --git a/tools/qemu/patches/0006-VMDK-add-field-BDRVVmdkState.desc_offset.patch b/tools/qemu/patches/0006-VMDK-add-field-BDRVVmdkState.desc_offset.patch deleted file mode 100644 index 51bbb3b010..0000000000 --- a/tools/qemu/patches/0006-VMDK-add-field-BDRVVmdkState.desc_offset.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 1c1781fa1c45a7c012f7b2c4be1be372f19e3cc6 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; diff --git a/tools/qemu/patches/0007-VMDK-flush-multiple-extents.patch b/tools/qemu/patches/0007-VMDK-flush-multiple-extents.patch deleted file mode 100644 index b228236517..0000000000 --- a/tools/qemu/patches/0007-VMDK-flush-multiple-extents.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 49885608e66c1e76a2b715fb36fd2f27f73e5202 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; - } - - diff --git a/tools/qemu/patches/0008-VMDK-move-static-cid_update-flag-to-bs-field.patch b/tools/qemu/patches/0008-VMDK-move-static-cid_update-flag-to-bs-field.patch deleted file mode 100644 index 90a699d73b..0000000000 --- a/tools/qemu/patches/0008-VMDK-move-static-cid_update-flag-to-bs-field.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9d8117f00364c12cbd658de903b1ed26a30584e0 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; diff --git a/tools/qemu/patches/0009-VMDK-change-get_cluster_offset-return-type.patch b/tools/qemu/patches/0009-VMDK-change-get_cluster_offset-return-type.patch deleted file mode 100644 index bc6e74656e..0000000000 --- a/tools/qemu/patches/0009-VMDK-change-get_cluster_offset-return-type.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 9e1ddc6967e8739f4fa47fa4f6a767ebe319f6ff Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; diff --git a/tools/qemu/patches/0010-VMDK-open-read-write-for-monolithicFlat-image.patch b/tools/qemu/patches/0010-VMDK-open-read-write-for-monolithicFlat-image.patch deleted file mode 100644 index b05d0d37d8..0000000000 --- a/tools/qemu/patches/0010-VMDK-open-read-write-for-monolithicFlat-image.patch +++ /dev/null @@ -1,257 +0,0 @@ -From e6b783a12f7ff491a1a2147d9fe55b4535aa046e Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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; diff --git a/tools/qemu/patches/0011-VMDK-create-different-subformats.patch b/tools/qemu/patches/0011-VMDK-create-different-subformats.patch deleted file mode 100644 index 7f02772d03..0000000000 --- a/tools/qemu/patches/0011-VMDK-create-different-subformats.patch +++ /dev/null @@ -1,595 +0,0 @@ -From 0d0f2ba577bd05491b5954751787f8b969ca1ec3 Mon Sep 17 00:00:00 2001 -From: Fam Zheng -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 -Reviewed-by: Stefan Hajnoczi -Signed-off-by: Kevin Wolf ---- - 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); diff --git a/tools/qemu/patches/0012-vmdk-Allow-selecting-SCSI-adapter-in-image-creation.patch b/tools/qemu/patches/0012-vmdk-Allow-selecting-SCSI-adapter-in-image-creation.patch deleted file mode 100644 index fc3dee361e..0000000000 --- a/tools/qemu/patches/0012-vmdk-Allow-selecting-SCSI-adapter-in-image-creation.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 5483df4df2729a5d1e4888a48039b1cd90438480 Mon Sep 17 00:00:00 2001 -From: Othmar Pasteka -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 -Signed-off-by: Stefan Hajnoczi ---- - 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);