Ejemplo n.º 1
0
def main(args=None):
    '''Print file system statistics to sys.stdout'''

    if args is None:
        args = sys.argv[1:]

    options = parse_args(args)
    setup_logging(options)

    ctrlfile = assert_fs_owner(options.mountpoint, mountpoint=True)

    # Use a decent sized buffer, otherwise the statistics have to be
    # calculated thee(!) times because we need to invoce getxattr
    # three times.
    buf = llfuse.getxattr(ctrlfile, 's3qlstat', size_guess=256)

    (entries, blocks, inodes, fs_size, dedup_size,
     compr_size, db_size, cache_used, cache_dirty) = struct.unpack('QQQQQQQQQ', buf)
    p_dedup = dedup_size * 100 / fs_size if fs_size else 0
    p_compr_1 = compr_size * 100 / fs_size if fs_size else 0
    p_compr_2 = compr_size * 100 / dedup_size if dedup_size else 0
    print ('Directory entries:    %d' % entries,
           'Inodes:               %d' % inodes,
           'Data blocks:          %d' % blocks,
           'Total data size:      %s' % pretty_print_size(fs_size),
           'After de-duplication: %s (%.2f%% of total)'
             % (pretty_print_size(dedup_size), p_dedup),
           'After compression:    %s (%.2f%% of total, %.2f%% of de-duplicated)'
             % (pretty_print_size(compr_size), p_compr_1, p_compr_2),
           'Database size:        %s (uncompressed)' % pretty_print_size(db_size),
           'Cache usage:          %s (dirty: %s)' % (pretty_print_size(cache_used),
                                                     pretty_print_size(cache_dirty)),
           sep='\n')
Ejemplo n.º 2
0
def blocking_umount(mountpoint):
    '''Invoke fusermount and wait for daemon to terminate.'''

    with open('/dev/null', 'wb') as devnull:
        if subprocess.call(['fuser', '-m', mountpoint], stdout=devnull,
                           stderr=devnull) == 0:
            raise MountInUseError(mountpoint)

    ctrlfile = os.path.join(mountpoint, CTRL_NAME)

    log.debug('Flushing cache...')
    llfuse.setxattr(ctrlfile, 's3ql_flushcache!', b'dummy')

    # Get pid
    log.debug('Trying to get pid')
    pid = parse_literal(llfuse.getxattr(ctrlfile, 's3ql_pid?'), int)
    log.debug('PID is %d', pid)

    # Get command line to make race conditions less-likely
    cmdline = get_cmdline(pid)

    # Unmount
    log.debug('Unmounting...')

    if os.getuid() == 0 or platform.system() == 'Darwin':
        # MacOS X always uses umount rather than fusermount
        umount_cmd = ['umount', mountpoint]
    else:
        umount_cmd = ['fusermount', '-u', mountpoint]

    if subprocess.call(umount_cmd) != 0:
        raise UmountSubError(mountpoint)

    # Wait for daemon
    log.debug('Uploading metadata...')
    step = 0.1
    while True:
        try:
            os.kill(pid, 0)
        except OSError:
            log.debug('Kill failed, assuming daemon has quit.')
            break

        # Check that the process did not terminate and the PID
        # was reused by a different process
        cmdline2 = get_cmdline(pid)
        if cmdline2 is None:
            log.debug('Reading cmdline failed, assuming daemon has quit.')
            break
        elif cmdline2 == cmdline:
            log.debug('PID still alive and commandline unchanged.')
        else:
            log.debug('PID still alive, but cmdline changed')
            break

        # Process still exists, we wait
        log.debug('Daemon seems to be alive, waiting...')
        time.sleep(step)
        if step < 1:
            step += 0.1
Ejemplo n.º 3
0
def main(args=None):
    '''Print file system statistics to sys.stdout'''

    if args is None:
        args = sys.argv[1:]

    options = parse_args(args)
    setup_logging(options)

    ctrlfile = assert_fs_owner(options.mountpoint, mountpoint=True)

    # Use a decent sized buffer, otherwise the statistics have to be
    # calculated thee(!) times because we need to invoce getxattr
    # three times.
    buf = llfuse.getxattr(ctrlfile, 's3qlstat', size_guess=256)

    (entries, blocks, inodes, fs_size, dedup_size, compr_size,
     db_size) = struct.unpack('QQQQQQQ', buf)
    p_dedup = dedup_size * 100 / fs_size if fs_size else 0
    p_compr_1 = compr_size * 100 / fs_size if fs_size else 0
    p_compr_2 = compr_size * 100 / dedup_size if dedup_size else 0
    mb = 1024**2
    print(
        'Directory entries:    %d' % entries,
        'Inodes:               %d' % inodes,
        'Data blocks:          %d' % blocks,
        'Total data size:      %.2f MiB' % (fs_size / mb),
        'After de-duplication: %.2f MiB (%.2f%% of total)' %
        (dedup_size / mb, p_dedup),
        'After compression:    %.2f MiB (%.2f%% of total, %.2f%% of de-duplicated)'
        % (compr_size / mb, p_compr_1, p_compr_2),
        'Database size:        %.2f MiB (uncompressed)' % (db_size / mb),
        '(some values do not take into account not-yet-uploaded dirty blocks in cache)',
        sep='\n')
Ejemplo n.º 4
0
def main(args=None):
    '''Print file system statistics to sys.stdout'''

    if args is None:
        args = sys.argv[1:]

    options = parse_args(args)
    setup_logging(options)

    ctrlfile = assert_fs_owner(options.mountpoint, mountpoint=True)

    # Use a decent sized buffer, otherwise the statistics have to be
    # calculated thee(!) times because we need to invoce getxattr
    # three times.
    buf = llfuse.getxattr(ctrlfile, 's3qlstat', size_guess=256)

    (entries, blocks, inodes, fs_size, dedup_size,
     compr_size, db_size) = struct.unpack('QQQQQQQ', buf)
    p_dedup = dedup_size * 100 / fs_size if fs_size else 0
    p_compr_1 = compr_size * 100 / fs_size if fs_size else 0
    p_compr_2 = compr_size * 100 / dedup_size if dedup_size else 0
    mb = 1024 ** 2
    print ('Directory entries:    %d' % entries,
           'Inodes:               %d' % inodes,
           'Data blocks:          %d' % blocks,
           'Total data size:      %.2f MiB' % (fs_size / mb),
           'After de-duplication: %.2f MiB (%.2f%% of total)'
             % (dedup_size / mb, p_dedup),
           'After compression:    %.2f MiB (%.2f%% of total, %.2f%% of de-duplicated)'
             % (compr_size / mb, p_compr_1, p_compr_2),
           'Database size:        %.2f MiB (uncompressed)' % (db_size / mb),
           '(some values do not take into account not-yet-uploaded dirty blocks in cache)',
           sep='\n')
Ejemplo n.º 5
0
def main(args=None):
    '''Print file system statistics to sys.stdout'''

    if args is None:
        args = sys.argv[1:]

    options = parse_args(args)
    setup_logging(options)

    ctrlfile = assert_fs_owner(options.mountpoint, mountpoint=True)

    # Use a decent sized buffer, otherwise the statistics have to be
    # calculated thee(!) times because we need to invoce getxattr
    # three times.
    buf = llfuse.getxattr(ctrlfile, 's3qlstat', size_guess=256)

    (entries, blocks, inodes, fs_size, dedup_size,
     compr_size, db_size, cache_used, cache_dirty) = struct.unpack('QQQQQQQQQ', buf)
    p_dedup = dedup_size * 100 / fs_size if fs_size else 0
    p_compr_1 = compr_size * 100 / fs_size if fs_size else 0
    p_compr_2 = compr_size * 100 / dedup_size if dedup_size else 0
    print ('Directory entries:    %d' % entries,
           'Inodes:               %d' % inodes,
           'Data blocks:          %d' % blocks,
           'Total data size:      %s' % pretty_print_size(fs_size),
           'After de-duplication: %s (%.2f%% of total)'
             % (pretty_print_size(dedup_size), p_dedup),
           'After compression:    %s (%.2f%% of total, %.2f%% of de-duplicated)'
             % (pretty_print_size(compr_size), p_compr_1, p_compr_2),
           'Database size:        %s (uncompressed)' % pretty_print_size(db_size),
           'Cache usage:          %s (dirty: %s)' % (pretty_print_size(cache_used),
                                                     pretty_print_size(cache_dirty)),
           sep='\n')
Ejemplo n.º 6
0
def main(args=None):
    '''Print file system statistics to sys.stdout'''

    if args is None:
        args = sys.argv[1:]

    options = parse_args(args)
    setup_logging(options)
    mountpoint = options.mountpoint

    # Check if it's a mount point
    if not posixpath.ismount(mountpoint):
        raise QuietError('%s is not a mount point' % mountpoint)

    # Check if it's an S3QL mountpoint
    ctrlfile = os.path.join(mountpoint, CTRL_NAME)
    if not (CTRL_NAME not in llfuse.listdir(mountpoint)
            and os.path.exists(ctrlfile)):
        raise QuietError('%s is not a mount point' % mountpoint)

    if os.stat(ctrlfile).st_uid != os.geteuid() and os.geteuid() != 0:
        raise QuietError('Only root and the mounting user may run s3qlstat.')

    # Use a decent sized buffer, otherwise the statistics have to be
    # calculated thee(!) times because we need to invoce getxattr
    # three times.
    buf = llfuse.getxattr(ctrlfile, b's3qlstat', size_guess=256)

    (entries, blocks, inodes, fs_size, dedup_size,
     compr_size, db_size) = struct.unpack('QQQQQQQ', buf)
    p_dedup = dedup_size * 100 / fs_size if fs_size else 0
    p_compr_1 = compr_size * 100 / fs_size if fs_size else 0
    p_compr_2 = compr_size * 100 / dedup_size if dedup_size else 0
    mb = 1024 ** 2
    print ('Directory entries:    %d' % entries,
           'Inodes:               %d' % inodes,
           'Data blocks:          %d' % blocks,
           'Total data size:      %.2f MiB' % (fs_size / mb),
           'After de-duplication: %.2f MiB (%.2f%% of total)'
             % (dedup_size / mb, p_dedup),
           'After compression:    %.2f MiB (%.2f%% of total, %.2f%% of de-duplicated)'
             % (compr_size / mb, p_compr_1, p_compr_2),
           'Database size:        %.2f MiB (uncompressed)' % (db_size / mb),
           '(some values do not take into account not-yet-uploaded dirty blocks in cache)',
           sep='\n')
Ejemplo n.º 7
0
def _getxattr_helper(path, name):
    try:
        value = llfuse.getxattr(path, name)
    except OSError as exc:
        errno = exc.errno
        value = None

    if not hasattr(os, 'getxattr'):
        return value

    try:
        value2 = os.getxattr(path, name)
    except OSError as exc:
        assert exc.errno == errno
    else:
        assert value2 is not None
        assert value2 == value

    return value
Ejemplo n.º 8
0
def _getxattr_helper(path, name):
    try:
        value = llfuse.getxattr(path, name)
    except OSError as exc:
        errno = exc.errno
        value = None

    if not hasattr(os, 'getxattr'):
        return value

    try:
        value2 = os.getxattr(path, name)
    except OSError as exc:
        assert exc.errno == errno
    else:
        assert value2 is not None
        assert value2 == value

    return value
Ejemplo n.º 9
0
def blocking_umount(mountpoint):
    '''Invoke fusermount and wait for daemon to terminate.'''

    with open('/dev/null', 'wb') as devnull:
        if subprocess.call(['fuser', '-m', mountpoint],
                           stdout=devnull,
                           stderr=devnull) == 0:
            raise MountInUseError(mountpoint)

    ctrlfile = os.path.join(mountpoint, CTRL_NAME)

    log.debug('Flushing cache...')
    llfuse.setxattr(ctrlfile, 's3ql_flushcache!', b'dummy')

    # Get pid
    log.debug('Trying to get pid')
    pid = parse_literal(llfuse.getxattr(ctrlfile, 's3ql_pid?'), int)
    log.debug('PID is %d', pid)

    # Get command line to make race conditions less-likely
    cmdline = get_cmdline(pid)

    # Unmount
    log.debug('Unmounting...')

    if os.getuid() == 0 or platform.system() == 'Darwin':
        # MacOS X always uses umount rather than fusermount
        umount_cmd = ['umount', mountpoint]
    else:
        umount_cmd = ['fusermount', '-u', mountpoint]

    if subprocess.call(umount_cmd) != 0:
        raise UmountSubError(mountpoint)

    # Wait for daemon
    log.debug('Uploading metadata...')
    step = 0.1
    while True:
        try:
            os.kill(pid, 0)
        except OSError:
            log.debug('Kill failed, assuming daemon has quit.')
            break

        # Check that the process did not terminate and the PID
        # was reused by a different process
        cmdline2 = get_cmdline(pid)
        if cmdline2 is None:
            log.debug('Reading cmdline failed, assuming daemon has quit.')
            break
        elif cmdline2 == cmdline:
            log.debug('PID still alive and commandline unchanged.')
        else:
            log.debug('PID still alive, but cmdline changed')
            break

        # Process still exists, we wait
        log.debug('Daemon seems to be alive, waiting...')
        time.sleep(step)
        if step < 1:
            step += 0.1
Ejemplo n.º 10
0
def blocking_umount(mountpoint):
    '''Invoke fusermount and wait for daemon to terminate.'''

    devnull = open('/dev/null', 'wb')
    if subprocess.call(
        ['fuser', '-m', mountpoint], stdout=devnull, stderr=devnull
    ) == 0:
        raise MountInUseError(mountpoint)

    ctrlfile = os.path.join(mountpoint, CTRL_NAME)

    log.debug('Flushing cache...')
    llfuse.setxattr(ctrlfile, b's3ql_flushcache!', b'dummy')

    # Get pid
    log.debug('Trying to get pid')
    pid = int(llfuse.getxattr(ctrlfile, b's3ql_pid?'))
    log.debug('PID is %d', pid)

    # Get command line to make race conditions less-likely
    with open('/proc/%d/cmdline' % pid, 'r') as fh:
        cmdline = fh.readline()
    log.debug('cmdline is %r', cmdline)

    # Unmount
    log.debug('Unmounting...')
    # This seems to be necessary to prevent weird busy errors
    time.sleep(3)

    if os.getuid() == 0:
        umount_cmd = ['umount', mountpoint]
    else:
        umount_cmd = ['fusermount', '-u', mountpoint]

    if subprocess.call(umount_cmd) != 0:
        raise UmountError(mountpoint)

    # Wait for daemon
    log.debug('Uploading metadata...')
    step = 0.5
    while True:
        try:
            os.kill(pid, 0)
        except OSError:
            log.debug('Kill failed, assuming daemon has quit.')
            break

        # Check that the process did not terminate and the PID
        # was reused by a different process
        try:
            with open('/proc/%d/cmdline' % pid, 'r') as fh:
                if fh.readline() != cmdline:
                    log.debug('PID still alive, but cmdline changed')
                    # PID must have been reused, original process terminated
                    break
                else:
                    log.debug('PID still alive and commandline unchanged.')
        except OSError:
            # Process must have exited by now
            log.debug('Reading cmdline failed, assuming daemon has quit.')
            break

        # Process still exists, we wait
        log.debug('Daemon seems to be alive, waiting...')
        time.sleep(step)
        if step < 10:
            step *= 2