From 3bd0ac0ab011c4cdf0121f0d9732938d085fb8bf Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 4 Mar 2013 16:38:57 -0800 Subject: [PATCH] ceph-disk-prepare: verify device is not mounted before using Make sure the data and/or journal device(s) are not in use (mounted) before using them. Make room for additional "in-use" checks in the future. Closes: #3256 Signed-off-by: Sage Weil --- src/ceph-disk-prepare | 51 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/src/ceph-disk-prepare b/src/ceph-disk-prepare index 3dd7e2950c236..ef39a009b5c45 100755 --- a/src/ceph-disk-prepare +++ b/src/ceph-disk-prepare @@ -4,6 +4,7 @@ import argparse import logging import os import os.path +import re import subprocess import stat import sys @@ -70,6 +71,24 @@ 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): """ @@ -84,6 +103,29 @@ def is_partition(dev): 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 verify_not_in_use(dev): + assert os.path.exists(dev) + if is_partition(dev): + if is_mounted(dev): + raise PrepareError('Device is mounted', dev) + else: + for p in list_partitions(dev): + if is_mounted(p): + raise PrepareError('Device is mounted', p) def write_one_line(parent, name, text): """ @@ -373,6 +415,9 @@ def prepare_journal_dev( journal_dm_keypath, ): + if os.path.exists(journal): + verify_not_in_use(journal) + if is_partition(journal): log.debug('Journal %s is a partition', journal) log.warning('OSD will not be hot-swappable if journal is not the same device as the osd data') @@ -860,8 +905,12 @@ def main(): ) journal_size = int(journal_size) - # colocate journal with data? + # in use? dmode = os.stat(args.data).st_mode + if stat.S_ISBLK(dmode): + verify_not_in_use(args.data) + + # colocate journal with data? 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 -- 2.39.5