Exemplo n.º 1
0
    def mkfile(self, filename, nbytes):
        """
        Create a non-sparse file of that size. Deletes and replaces existing file.

        To allow efficient execution, fallocate will be tried first. This includes
        ``os.posix_fallocate`` on Python 3.3+ (unix) and the ``fallocate`` command
        in the popular ``util-linux{,-ng}`` package.

        A dd fallback will be tried too. When size < 64M, perform single-pass dd.
        Otherwise do two-pass dd.
        """

        if not isinstance(nbytes, int):
            nbytes = int(nbytes)

        if nbytes < 0:
            raise ValueError(nbytes)

        if os.path.isfile(filename):
            os.remove(filename)

        # os.posix_fallocate
        if sys.version_info >= (3, 3):
            # Probable errors:
            #  - OSError: Seen on Cygwin, libc notimpl?
            #  - AttributeError: What if someone runs this under...
            with open(filename, 'w') as f:
                try:
                    os.posix_fallocate(f.fileno(), 0, nbytes)
                    return 0
                except:
                    # Not confident with this thing, just keep trying...
                    pass

        # fallocate command
        fn_sh = shellutil.quote((filename,))
        ret = shellutil.run(u"umask 0077 && fallocate -l {0} {1}".format(nbytes, fn_sh))
        if ret == 0:
            return ret

        logger.info("fallocate unsuccessful, falling back to dd")

        # dd fallback
        dd_maxbs = 64 * 1024 ** 2
        dd_cmd = "umask 0077 && dd if=/dev/zero bs={0} count={1} conv=notrunc of={2}"

        blocks = int(nbytes / dd_maxbs)
        if blocks > 0:
            ret = shellutil.run(dd_cmd.format(dd_maxbs, blocks, fn_sh)) << 8

        remains = int(nbytes % dd_maxbs)
        if remains > 0:
            ret += shellutil.run(dd_cmd.format(remains, 1, fn_sh))

        if ret == 0:
            logger.info("dd successful")
        else:
            logger.error("dd unsuccessful")

        return ret
Exemplo n.º 2
0
    def mkfile(self, filename, nbytes):
        """
        Create a non-sparse file of that size. Deletes and replaces existing file.

        To allow efficient execution, fallocate will be tried first. This includes
        ``os.posix_fallocate`` on Python 3.3+ (unix) and the ``fallocate`` command
        in the popular ``util-linux{,-ng}`` package.

        A dd fallback will be tried too. When size < 64M, perform single-pass dd.
        Otherwise do two-pass dd.
        """

        if not isinstance(nbytes, int):
            nbytes = int(nbytes)

        if nbytes < 0:
            raise ValueError(nbytes)

        if os.path.isfile(filename):
            os.remove(filename)

        # os.posix_fallocate
        if sys.version_info >= (3, 3):
            # Probable errors:
            #  - OSError: Seen on Cygwin, libc notimpl?
            #  - AttributeError: What if someone runs this under...
            with open(filename, 'w') as f:
                try:
                    os.posix_fallocate(f.fileno(), 0, nbytes)
                    return 0
                except:
                    # Not confident with this thing, just keep trying...
                    pass

        # fallocate command
        fn_sh = shellutil.quote((filename, ))
        ret = shellutil.run(u"umask 0077 && fallocate -l {0} {1}".format(
            nbytes, fn_sh))
        if ret != 127:  # 127 = command not found
            return ret

        # dd fallback
        dd_maxbs = 64 * 1024**2
        dd_cmd = "umask 0077 && dd if=/dev/zero bs={0} count={1} conv=notrunc of={2}"

        blocks = int(nbytes / dd_maxbs)
        if blocks > 0:
            ret = shellutil.run(dd_cmd.format(dd_maxbs, fn_sh, blocks)) << 8

        remains = int(nbytes % dd_maxbs)
        if remains > 0:
            ret += shellutil.run(dd_cmd.format(remains, fn_sh, 1))

        return ret
Exemplo n.º 3
0
 def test_shellquote(self):
     self.assertEqual("\'foo\'", shellutil.quote("foo"))
     self.assertEqual("\'foo bar\'", shellutil.quote("foo bar"))
     self.assertEqual("'foo'\\''bar'", shellutil.quote("foo\'bar"))
Exemplo n.º 4
0
    def mkfile(self, filename, nbytes):
        """
        Create a non-sparse file of that size. Deletes and replaces existing
        file.

        To allow efficient execution, fallocate will be tried first. This
        includes
        ``os.posix_fallocate`` on Python 3.3+ (unix) and the ``fallocate``
        command
        in the popular ``util-linux{,-ng}`` package.

        A dd fallback will be tried too. When size < 64M, perform
        single-pass dd.
        Otherwise do two-pass dd.
        """

        if not isinstance(nbytes, int):
            nbytes = int(nbytes)

        if nbytes <= 0:
            raise ResourceDiskError("Invalid swap size [{0}]".format(nbytes))

        if os.path.isfile(filename):
            os.remove(filename)

        # If file system is xfs, use dd right away as we have been reported that
        # swap enabling fails in xfs fs when disk space is allocated with
        # fallocate
        ret = 0
        fn_sh = shellutil.quote((filename, ))
        if self.fs not in ['xfs', 'ext4']:
            # os.posix_fallocate
            if sys.version_info >= (3, 3):
                # Probable errors:
                #  - OSError: Seen on Cygwin, libc notimpl?
                #  - AttributeError: What if someone runs this under...
                fd = None

                try:
                    fd = os.open(filename,
                                 os.O_CREAT | os.O_WRONLY | os.O_EXCL,
                                 stat.S_IRUSR | stat.S_IWUSR)
                    os.posix_fallocate(fd, 0, nbytes)  # pylint: disable=no-member
                    return 0
                except BaseException:
                    # Not confident with this thing, just keep trying...
                    pass
                finally:
                    if fd is not None:
                        os.close(fd)

            # fallocate command
            ret = shellutil.run(u"umask 0077 && fallocate -l {0} {1}".format(
                nbytes, fn_sh))
            if ret == 0:
                return ret

            logger.info("fallocate unsuccessful, falling back to dd")

        # dd fallback
        dd_maxbs = 64 * 1024**2
        dd_cmd = "umask 0077 && dd if=/dev/zero bs={0} count={1} " \
                 "conv=notrunc of={2}"

        blocks = int(nbytes / dd_maxbs)
        if blocks > 0:
            ret = shellutil.run(dd_cmd.format(dd_maxbs, blocks, fn_sh)) << 8

        remains = int(nbytes % dd_maxbs)
        if remains > 0:
            ret += shellutil.run(dd_cmd.format(remains, 1, fn_sh))

        if ret == 0:
            logger.info("dd successful")
        else:
            logger.error("dd unsuccessful")

        return ret
Exemplo n.º 5
0
 def test_shellquote(self):
     self.assertEqual("\'foo\'", shellutil.quote("foo"))
     self.assertEqual("\'foo bar\'", shellutil.quote("foo bar"))
     self.assertEqual("'foo'\\''bar'", shellutil.quote("foo\'bar"))
Exemplo n.º 6
0
    def mkfile(self, filename, nbytes):
        """
        Create a non-sparse file of that size. Deletes and replaces existing
        file.

        To allow efficient execution, fallocate will be tried first. This
        includes
        ``os.posix_fallocate`` on Python 3.3+ (unix) and the ``fallocate``
        command
        in the popular ``util-linux{,-ng}`` package.

        A dd fallback will be tried too. When size < 64M, perform
        single-pass dd.
        Otherwise do two-pass dd.
        """

        if not isinstance(nbytes, int):
            nbytes = int(nbytes)

        if nbytes <= 0:
            raise ResourceDiskError("Invalid swap size [{0}]".format(nbytes))

        if os.path.isfile(filename):
            os.remove(filename)

        # If file system is xfs, use dd right away as we have been reported that
        # swap enabling fails in xfs fs when disk space is allocated with fallocate
        ret = 0
        fn_sh = shellutil.quote((filename,))
        if self.fs != 'xfs':
            # os.posix_fallocate
            if sys.version_info >= (3, 3):
                # Probable errors:
                #  - OSError: Seen on Cygwin, libc notimpl?
                #  - AttributeError: What if someone runs this under...
                fd = None

                try:
                    fd = os.open(filename, os.O_CREAT | os.O_WRONLY | os.O_EXCL, stat.S_IRUSR | stat.S_IWUSR)
                    os.posix_fallocate(fd, 0, nbytes)
                    return 0
                except:
                    # Not confident with this thing, just keep trying...
                    pass
                finally:
                    if fd is not None:
                        os.close(fd)

            # fallocate command
            ret = shellutil.run(
                u"umask 0077 && fallocate -l {0} {1}".format(nbytes, fn_sh))
            if ret == 0:
                return ret

            logger.info("fallocate unsuccessful, falling back to dd")

        # dd fallback
        dd_maxbs = 64 * 1024 ** 2
        dd_cmd = "umask 0077 && dd if=/dev/zero bs={0} count={1} " \
                 "conv=notrunc of={2}"

        blocks = int(nbytes / dd_maxbs)
        if blocks > 0:
            ret = shellutil.run(dd_cmd.format(dd_maxbs, blocks, fn_sh)) << 8

        remains = int(nbytes % dd_maxbs)
        if remains > 0:
            ret += shellutil.run(dd_cmd.format(remains, 1, fn_sh))

        if ret == 0:
            logger.info("dd successful")
        else:
            logger.error("dd unsuccessful")

        return ret