Skip to content

Commit

Permalink
Merge remote-tracking branch 'gh/next'
Browse files Browse the repository at this point in the history
  • Loading branch information
Sage Weil committed Jul 19, 2013
2 parents c4d4f34 + 053659d commit 23cde45
Show file tree
Hide file tree
Showing 63 changed files with 1,102 additions and 641 deletions.
15 changes: 15 additions & 0 deletions PendingReleaseNotes
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,18 @@ v0.67
* The output of 'ceph status --format=json' or 'ceph -s --format=json'
has changed to return status information in a more structured and
usable format.

* The 'ceph pg dump_stuck [threshold]' command used to require a
--threshold or -t prefix to the threshold argument, but now does
not.

* Many more ceph commands now output formatted information; select
with '--format=<format>', where <format> can be 'json', 'json-pretty',
'xml', or 'xml-pretty'.

* ceph-rest-api, a wrapper around ceph_rest_api.py, can be used to start
up a test single-threaded HTTP server that provides access to cluster
information and administration in very similar ways to the ceph
commandline tool. ceph_rest_api.py can be used as a WSGI application
for deployment in a more-capable web server. See ceph-rest-api.8
for more.
22 changes: 13 additions & 9 deletions qa/workunits/cephtool/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,8 @@ if ! grep "$mymsg" /tmp/$$; then
fi
kill $wpid

ceph mds cluster_down --no-log-to-stderr 2>&1 | grep "marked mdsmap DOWN"
expect_false ceph mds cluster_down
ceph mds cluster_up --no-log-to-stderr 2>&1 | grep "unmarked mdsmap DOWN"
expect_false ceph mds cluster_up
ceph mds cluster_down
ceph mds cluster_up

ceph mds compat rm_incompat 4
ceph mds compat rm_incompat 4
Expand Down Expand Up @@ -167,9 +165,20 @@ ceph osd getmaxosd | grep 'max_osd = 10'
ceph osd setmaxosd $save
ceph osd getmaxosd | grep "max_osd = $save"

for id in `ceph osd ls` ; do
ceph tell osd.$id version
done

id=`ceph osd create`
ceph osd lost $id --yes-i-really-mean-it
ceph osd rm $id

uuid=`uuidgen`
id=`ceph osd create $uuid`
id2=`ceph osd create $uuid`
[ "$id" = "$id2" ]
ceph osd rm $id

ceph osd ls
ceph osd lspools | grep data
ceph osd map data foo | grep 'pool.*data.*object.*foo.*pg.*up.*acting'
Expand All @@ -191,11 +200,6 @@ ceph osd pool delete data3 data3 --yes-i-really-really-mean-it

ceph osd stat | grep up,

for id in `ceph osd ls` ; do
ceph tell osd.$id version
done


ceph pg debug unfound_objects_exist
ceph pg debug degraded_pgs_exist
ceph pg deep-scrub 0.0
Expand Down
3 changes: 3 additions & 0 deletions src/auth/cephx/CephxKeyServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,9 @@ class KeyServer : public KeyStore {
map<EntityName, EntityAuth>::const_iterator b = data.secrets_begin();
return (b != data.secrets_end());
}
int get_num_secrets() {
return data.secrets.size();
}

/*void add_rotating_secret(uint32_t service_id, ExpiringCryptoKey& key) {
Mutex::Locker l(lock);
Expand Down
159 changes: 78 additions & 81 deletions src/ceph-disk
Original file line number Diff line number Diff line change
Expand Up @@ -198,69 +198,95 @@ def maybe_mkdir(*a, **kw):
raise


# a device "name" is something like
# sdb
# cciss!c0d1
def get_dev_name(path):
"""
get device name from path. e.g., /dev/sda -> sdas, /dev/cciss/c0d1 -> cciss!c0d1
"""
assert path.startswith('/dev/')
base = path[5:]
return base.replace('/', '!')

# a device "path" is something like
# /dev/sdb
# /dev/cciss/c0d1
def get_dev_path(name):
"""
get a path (/dev/...) from a name (cciss!c0d1)
"""
return '/dev/' + name.replace('!', '/')

def get_dev_relpath(name):
"""
get a relative path to /dev from a name (cciss!c0d1)
"""
return name.replace('!', '/')


def get_partition_dev(dev, pnum):
"""
get the device name for a partition
assume that partitions are named like the base dev, with a number, and optionally
some intervening characters (like 'p'). e.g.,
sda 1 -> sda1
cciss/c0d1 1 -> cciss!c0d1p1
"""
name = get_dev_name(os.path.realpath(dev))
partname = None
for f in os.listdir(os.path.join('/sys/block', name)):
if f.startswith(name) and f.endswith(str(pnum)):
# we want the shortest name that starts with the base name and ends with the partition number
if not partname or len(f) < len(partname):
partname = f
if partname:
return get_dev_path(partname)
else:
raise Error('partition %d for %s does not appear to exist' % (pnum, dev))

def list_all_partitions():
"""
Return a list of devices and partitions
"""
dev_part_list = {}
for name in os.listdir('/dev/disk/by-path'):
target = os.readlink(os.path.join('/dev/disk/by-path', name))
dev = target.split('/')[-1]
#print "name %s target %s dev %s" % (name, target, dev)
(baser) = re.search('(.*)-part\d+$', name)
if baser is not None:
basename = baser.group(1)
#print 'basename %s' % basename
base = os.readlink(os.path.join('/dev/disk/by-path', basename)).split('/')[-1]
if base not in dev_part_list:
dev_part_list[base] = []
dev_part_list[base].append(dev)
else:
if dev not in dev_part_list:
dev_part_list[dev] = []
for name in os.listdir('/sys/block'):
if not os.path.exists(os.path.join('/sys/block', name, 'device')):
continue
dev_part_list[name] = list_partitions(name)
return dev_part_list


def list_partitions(disk):
def list_partitions(basename):
"""
Return a list of partitions on the given device
Return a list of partitions on the given device name
"""
disk = os.path.realpath(disk)
assert not is_partition(disk)
assert disk.startswith('/dev/')
base = disk.split('/')[-1]
partitions = []
for name in os.listdir(os.path.join('/sys/block', base)):
if name.startswith(base):
partitions.append('/dev/' + name)
for name in os.listdir(os.path.join('/sys/block', basename)):
if name.startswith(basename):
partitions.append(name)
return partitions


def is_partition(dev):
"""
Check whether a given device is a partition or a full disk.
Check whether a given device path is a partition or a full disk.
"""
dev = os.path.realpath(dev)
if not stat.S_ISBLK(os.lstat(dev).st_mode):
raise Error('not a block device', dev)

# we can't tell just from the name of the device if it is a
# partition or not. look in the by-path dir and see if the
# referring symlink ends in -partNNN.
name = dev.split('/')[-1]
for name in os.listdir('/dev/disk/by-path'):
target = os.readlink(os.path.join('/dev/disk/by-path', name))
cdev = target.split('/')[-1]
if '/dev/' + cdev != dev:
continue
(baser) = re.search('(.*)-part\d+$', name)
if baser is not None:
name = get_dev_name(dev)
if os.path.exists(os.path.join('/sys/block', name)):
return False

# make sure it is a partition of something else
for basename in os.listdir('/sys/block'):
if os.path.exists(os.path.join('/sys/block', basename, name)):
return True
else:
return False

# hrm, don't know...
return False
raise Error('not a disk or partition', dev)


def is_mounted(dev):
Expand Down Expand Up @@ -288,7 +314,7 @@ def is_held(dev):
"""
assert os.path.exists(dev)
dev = os.path.realpath(dev)
base = dev.split('/')[-1]
base = get_dev_name(dev)

# full disk?
directory = '/sys/block/{base}/holders'.format(base=base)
Expand Down Expand Up @@ -320,7 +346,9 @@ def verify_not_in_use(dev):
if holders:
raise Error('Device is in use by a device-mapper mapping (dm-crypt?)' % dev, ','.join(holders))
else:
for partition in list_partitions(dev):
basename = get_dev_name(os.path.realpath(dev))
for partname in list_partitions(basename):
partition = get_dev_path(partname)
if is_mounted(partition):
raise Error('Device is mounted', partition)
holders = is_held(partition)
Expand Down Expand Up @@ -762,16 +790,6 @@ def zap(dev):
raise Error(e)


def get_udev_version():
version = _check_output(
args=[
'udevadm',
'--version',
],
)
return int(version)


def prepare_journal_dev(
data,
journal,
Expand Down Expand Up @@ -840,30 +858,9 @@ def prepare_journal_dev(
],
)

if get_udev_version() >= 172:
journal_symlink = '/dev/disk/by-partuuid/{journal_uuid}'.format(
journal_uuid=journal_uuid,
)
else:
# udev prior to version 172 doesn't create by-partuuid directory
# use by-path symlink instead. This is the third symlink returned
# by udevadm when queried.
LOG.debug('Using alternate persistant name for journal symlink')
symlinks = _check_output(
args=[
'udevadm',
'info',
'--query=symlink',
'--name={name}'.format(name=os.path.basename(journal)),
],
)
journal_symlink = None
for udev_line in symlinks.split():
if 'by-path' in udev_line:
journal_symlink = '/dev/{symlink}-part{num}'.format(symlink=str(udev_line), num=num)
break
if not journal_symlink:
raise Error('Unable to get device by path from udev')
journal_symlink = '/dev/disk/by-partuuid/{journal_uuid}'.format(
journal_uuid=journal_uuid,
)

journal_dmcrypt = None
if journal_dm_keypath:
Expand Down Expand Up @@ -1042,7 +1039,7 @@ def prepare_dev(
except subprocess.CalledProcessError as e:
raise Error(e)

rawdev = '{data}1'.format(data=data)
rawdev = get_partition_dev(data, 1)

dev = None
if osd_dm_keypath:
Expand Down Expand Up @@ -2009,7 +2006,7 @@ def is_suppressed(path):
try:
if not disk.startswith('/dev/') or not stat.S_ISBLK(os.lstat(path).st_mode):
return False
base = disk.split('/')[-1]
base = get_dev_name(disk)
while len(base):
if os.path.exists(SUPPRESS_PREFIX + base):
return True
Expand All @@ -2023,7 +2020,7 @@ def set_suppress(path):
raise Error('does not exist', path)
if not stat.S_ISBLK(os.lstat(path).st_mode):
raise Error('not a block device', path)
base = disk.split('/')[-1]
base = get_dev_name(disk)

with file(SUPPRESS_PREFIX + base, 'w') as f:
pass
Expand All @@ -2036,7 +2033,7 @@ def unset_suppress(path):
if not stat.S_ISBLK(os.lstat(path).st_mode):
raise Error('not a block device', path)
assert disk.startswith('/dev/')
base = disk.split('/')[-1]
base = get_dev_name(disk)

fn = SUPPRESS_PREFIX + base
if not os.path.exists(fn):
Expand Down
13 changes: 9 additions & 4 deletions src/ceph.in
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,6 @@ def parse_cmdargs(args=None, target=''):

parser.add_argument('-f', '--format', choices=['json', 'json-pretty',
'xml', 'xml-pretty', 'plain'], dest='output_format')
# for pg dump_stuck
parser.add_argument('--threshold', type=int, help='number of seconds for a pg to be considered stuck for pg dump_stuck')

# returns a Namespace with the parsed args, and a list of all extras
parsed_args, extras = parser.parse_known_args(args)
Expand Down Expand Up @@ -683,8 +681,6 @@ def main():
compat = True
if parsed_args.output_format:
childargs.extend(['--format', parsed_args.output_format])
if parsed_args.threshold:
childargs.extend(['--threshold', parsed_args.threshold])
ret, outbuf, outs = send_command(cluster_handle, target, childargs,
inbuf)
elif ret:
Expand All @@ -699,6 +695,15 @@ def main():
ret, outbuf, outs = new_style_command(parsed_args, childargs, target,
sigdict, inbuf, verbose)

# debug tool: send any successful command *again* to
# verify that it is idempotent.
if not ret and 'CEPH_CLI_TEST_DUP_COMMAND' in os.environ:
ret, outbuf, outs = new_style_command(parsed_args, childargs, target,
sigdict, inbuf, verbose)
if ret < 0:
ret = -ret
print >> sys.stderr, prefix + 'Second attempt of previously successful command failed with {0}: {1}'.format(errno.errorcode[ret], outs)

if ret < 0:
ret = -ret
print >> sys.stderr, prefix + 'Error {0}: {1}'.format(errno.errorcode[ret], outs)
Expand Down
3 changes: 2 additions & 1 deletion src/ceph_mon.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ int obtain_monmap(MonitorDBStore &store, bufferlist &bl)
}
}

if (store.exists("mon_sync", "in_sync")) {
if (store.exists("mon_sync", "in_sync")
|| store.exists("mon_sync", "force_sync")) {
dout(10) << __func__ << " detected aborted sync" << dendl;
if (store.exists("mon_sync", "latest_monmap")) {
int err = store.get("mon_sync", "latest_monmap", bl);
Expand Down
2 changes: 1 addition & 1 deletion src/client/Client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1882,7 +1882,7 @@ void Client::handle_mds_map(MMDSMap* m)
int newstate = mdsmap->get_state(p->first);
if (!mdsmap->is_up(p->first) ||
mdsmap->get_inst(p->first) != p->second->inst) {
messenger->mark_down(p->second->inst.addr);
messenger->mark_down(p->second->con);
if (mdsmap->is_up(p->first))
p->second->inst = mdsmap->get_inst(p->first);
} else if (oldstate == newstate)
Expand Down
Loading

0 comments on commit 23cde45

Please sign in to comment.