From a09e35fbd4e3b45b220dca8331d576c2635d8095 Mon Sep 17 00:00:00 2001 From: Artem Bityutskiy Date: Thu, 8 Nov 2012 17:26:04 +0200 Subject: [PATCH] bmaptool: distinguish between block devices and regular file Teach bmaptool to distinguish between block devices and regular files and use the specialized version of 'BmapCopy' in case of block devices. The specialized version will be implemented in the 'BmapBdevCopy' class, which is just a copy of the base class so far. Change-Id: I444f121893dfd5d637a08300191c7a5dbc082d4e Signed-off-by: Artem Bityutskiy --- bmaptool | 34 +++++++++++++++++++++++++++++++--- bmaptools/BmapCopy.py | 8 ++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/bmaptool b/bmaptool index 1745d38..96660e5 100755 --- a/bmaptool +++ b/bmaptool @@ -37,6 +37,8 @@ VERSION = "0.1.1" import argparse import sys +import os +import stat import time import logging from bmaptools import BmapCreate, BmapCopy, BmapHelpers @@ -44,8 +46,34 @@ from bmaptools import BmapCreate, BmapCopy, BmapHelpers def copy_command(args, log): """ Copy an image to a block device or a regular file using bmap. """ + # Try to open the destination file. If it does not exist, a new regular + # file will be created. If it exists and it is a regular file - it'll be + # truncated. If this is a block device, it'll just be opened. try: - writer = BmapCopy.BmapCopy(args.image, args.dest, args.bmap) + dest_file = open(args.dest, 'w+') + except IOError as err: + log.error("cannot open destination file '%s': %s" \ + % (args.dest, err)) + raise SystemExit(1) + + dest_file.close() + + # Check whether the destination file is a block device + try: + is_block_device = stat.S_ISBLK(os.stat(args.dest).st_mode) + except OSError as err: + log.error("cannot access destination file '%s': %s" \ + % (args.bdev, err.strerror)) + raise SystemExit(1) + + try: + if is_block_device: + # For block devices, use the specialized class + destination_type = "block device" + writer = BmapCopy.BmapBdevCopy(args.image, args.dest, args.bmap) + else: + destination_type = "file" + writer = BmapCopy.BmapCopy(args.image, args.dest, args.bmap) except BmapCopy.Error as err: log.error(str(err)) raise SystemExit(1) @@ -61,8 +89,8 @@ def copy_command(args, log): writer.bmap_image_size_human, writer.bmap_mapped_cnt, writer.bmap_mapped_size_human, writer.bmap_mapped_percent)) - log.info("copying the image to '%s' using bmap file '%s'" \ - % (args.dest, args.bmap)) + log.info("copying the image to %s '%s' using bmap file '%s'" \ + % (destination_type, args.dest, args.bmap)) try: try: diff --git a/bmaptools/BmapCopy.py b/bmaptools/BmapCopy.py index ebf2766..07d1579 100644 --- a/bmaptools/BmapCopy.py +++ b/bmaptools/BmapCopy.py @@ -469,3 +469,11 @@ class BmapCopy: except OSError as err: raise Error("cannot synchronize block device '%s': %s " \ % (self._bdev_path, err.strerror)) + +class BmapBdevCopy(BmapCopy): + """ This class is a specialized version of 'BmapCopy' which copies the + image to a block device. Unlike the base 'BmapCopy' class, this class does + various optimizations specific to block devices, e.g., switchint to the + 'noop' I/O scheduler. """ + + pass -- 2.7.4