mirror of
https://github.com/ceph/ceph
synced 2025-03-11 02:39:05 +00:00
Merge branch 'wip-prepare'
Reviewed-by: Josh Durgin <josh.durgin@inktank.com> Reviewed-by: Alexandre Marangone <alexandre.marangone@inktank.com> Tested-by: Tamil Muthamizhan <tamil.muthamizhan@inktank.com>
This commit is contained in:
commit
8184b68c37
@ -4,6 +4,7 @@ import argparse
|
||||
import logging
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
import stat
|
||||
import sys
|
||||
@ -70,28 +71,82 @@ class UnmountError(PrepareError):
|
||||
Unmounting filesystem failed
|
||||
"""
|
||||
|
||||
def list_partitions(disk):
|
||||
"""
|
||||
Return a list of partitions on the given device
|
||||
"""
|
||||
disk = os.path.realpath(disk)
|
||||
assert not is_partition(disk)
|
||||
assert disk.startswith('/dev/')
|
||||
base = disk[5:]
|
||||
ls = []
|
||||
with file('/proc/partitions', 'rb') as f:
|
||||
for line in f.read().split('\n')[2:]:
|
||||
fields = re.split('\s+', line)
|
||||
if len(fields) < 5:
|
||||
continue
|
||||
(_, major, minor, blocks, name) = fields
|
||||
if name != base and name.startswith(base):
|
||||
ls.append('/dev/' + name)
|
||||
return ls
|
||||
|
||||
def is_partition(dev):
|
||||
"""
|
||||
Check whether a given device is a partition or a full disk.
|
||||
"""
|
||||
# resolve symlink(s)
|
||||
max = 10
|
||||
while stat.S_ISLNK(os.lstat(dev).st_mode):
|
||||
dev = os.readlink(dev)
|
||||
max -= 1
|
||||
if max == 0:
|
||||
raise PrepareError('%s is a rats nest of symlinks' % dev)
|
||||
dev = os.path.realpath(dev)
|
||||
if not stat.S_ISBLK(os.lstat(dev).st_mode):
|
||||
raise PrepareError('not a block device', dev)
|
||||
|
||||
# if the device ends in a number, it is a partition (e.g., /dev/sda3)
|
||||
|
||||
# ugh i have no internet.. how do you do a python regex?
|
||||
if dev.endswith('0') or dev.endswith('1') or dev.endswith('2') or dev.endswith('3') or dev.endswith('4') or dev.endswith('4') or dev.endswith('6') or dev.endswith('7') or dev.endswith('8') or dev.endswith('9'):
|
||||
if dev[-1].isdigit():
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_mounted(dev):
|
||||
"""
|
||||
Check if the given device is mounted.
|
||||
"""
|
||||
dev = os.path.realpath(dev)
|
||||
with file('/proc/mounts') as f:
|
||||
for line in f.read().split('\n'):
|
||||
d = line.split(' ')[0]
|
||||
if os.path.exists(d):
|
||||
d = os.path.realpath(d)
|
||||
if dev == d:
|
||||
return True
|
||||
return False
|
||||
|
||||
def is_held(dev):
|
||||
"""
|
||||
Check if a device is held by another device (e.g., a dm-crypt mapping)
|
||||
"""
|
||||
assert os.path.exists(dev)
|
||||
dev = os.path.realpath(dev)
|
||||
base = dev[5:]
|
||||
disk = base
|
||||
while disk[-1].isdigit():
|
||||
disk = disk[:-1]
|
||||
dir = '/sys/block/{disk}/{base}/holders'.format(disk=disk, base=base)
|
||||
if not os.path.exists(dir):
|
||||
return []
|
||||
return os.listdir(dir)
|
||||
|
||||
def verify_not_in_use(dev):
|
||||
assert os.path.exists(dev)
|
||||
if is_partition(dev):
|
||||
if is_mounted(dev):
|
||||
raise PrepareError('Device is mounted', dev)
|
||||
holders = is_held(dev)
|
||||
if holders:
|
||||
raise PrepareError('Device is in use by a device-mapper mapping (dm-crypt?)' % dev, ','.join(holders))
|
||||
else:
|
||||
for p in list_partitions(dev):
|
||||
if is_mounted(p):
|
||||
raise PrepareError('Device is mounted', p)
|
||||
holders = is_held(p)
|
||||
if holders:
|
||||
raise PrepareError('Device %s is in use by a device-mapper mapping (dm-crypt?)' % p, ','.join(holders))
|
||||
|
||||
def write_one_line(parent, name, text):
|
||||
"""
|
||||
@ -804,12 +859,18 @@ def main():
|
||||
if not os.path.exists(args.data):
|
||||
raise PrepareError('data path does not exist', args.data)
|
||||
|
||||
# FIXME: verify disk/partitions is not in use
|
||||
# in use?
|
||||
dmode = os.stat(args.data).st_mode
|
||||
if stat.S_ISBLK(dmode):
|
||||
verify_not_in_use(args.data)
|
||||
|
||||
if args.journal and os.path.exists(args.journal):
|
||||
jmode = os.stat(args.journal).st_mode
|
||||
if stat.S_ISBLK(jmode):
|
||||
verify_not_in_use(args.journal)
|
||||
|
||||
if args.zap_disk is not None:
|
||||
if not os.path.exists(args.data):
|
||||
raise PrepareError('does not exist', args.data)
|
||||
mode = os.stat(args.data).st_mode
|
||||
if stat.S_ISBLK(mode) and not is_partition(args.data):
|
||||
if stat.S_ISBLK(dmode) and not is_partition(args.data):
|
||||
zap(args.data)
|
||||
else:
|
||||
raise PrepareError('not full block device; cannot zap', args.data)
|
||||
@ -869,7 +930,6 @@ def main():
|
||||
journal_size = int(journal_size)
|
||||
|
||||
# colocate journal with data?
|
||||
dmode = os.stat(args.data).st_mode
|
||||
if stat.S_ISBLK(dmode) and not is_partition(args.data) and args.journal is None and args.journal_file is None:
|
||||
log.info('Will colocate journal with data on %s', args.data)
|
||||
args.journal = args.data
|
||||
|
Loading…
Reference in New Issue
Block a user