mirror of
https://github.com/ceph/ceph
synced 2024-12-17 17:05:42 +00:00
cc9d7da5b8
Signed-off-by: Sam Lang <sam.lang@inktank.com>
299 lines
9.3 KiB
C++
299 lines
9.3 KiB
C++
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
|
|
// vim: ts=8 sw=2 smarttab
|
|
/*
|
|
* Ceph - scalable distributed file system
|
|
*
|
|
* Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
|
|
*
|
|
* This is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License version 2.1, as published by the Free Software
|
|
* Foundation. See file COPYING.
|
|
*
|
|
* Simple little program to let you:
|
|
* 1) View the layout information on a file or directory,
|
|
* 2) Modify the layout information on an empty file,
|
|
* 3) Modify the default layout on a directory
|
|
*/
|
|
|
|
#include <iostream>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/socket.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include "client/ioctl.h"
|
|
#include "common/errno.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
#define CMD_SHOW_LAYOUT 1
|
|
#define CMD_SHOW_LOC 2
|
|
#define CMD_SET_LAYOUT 3
|
|
#define CMD_MAP 4
|
|
|
|
void usage();
|
|
int init_options(int argc, char **argv, int *fd, char **path, int *cmd,
|
|
int *stripe_unit, int *stripe_count,
|
|
int *object_size, int64_t *pool, int *file_offset, bool *dir);
|
|
|
|
int main (int argc, char **argv) {
|
|
int fd = 0;
|
|
int err = 0;
|
|
char *path = 0;
|
|
int cmd = 0;
|
|
int stripe_unit = 0;
|
|
int stripe_count = 0;
|
|
int object_size = 0;
|
|
int64_t pool = 0;
|
|
int file_offset = 0;
|
|
bool dir = false;
|
|
|
|
if (init_options(argc, argv, &fd, &path, &cmd, &stripe_unit, &stripe_count,
|
|
&object_size, &pool, &file_offset, &dir)){
|
|
usage();
|
|
return 0;
|
|
}
|
|
|
|
if (CMD_SHOW_LAYOUT == cmd) {
|
|
struct ceph_ioctl_layout layout;
|
|
memset(&layout, 0, sizeof(layout));
|
|
err = ioctl(fd, CEPH_IOC_GET_LAYOUT, (unsigned long)&layout);
|
|
if (err) {
|
|
cerr << "Error getting layout: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
if (layout.stripe_unit == 0) {
|
|
cerr << "layout not specified" << endl;
|
|
} else {
|
|
cout << "layout.data_pool: " << layout.data_pool << endl;
|
|
cout << "layout.object_size: " << layout.object_size << endl;
|
|
cout << "layout.stripe_unit: " << layout.stripe_unit << endl;
|
|
cout << "layout.stripe_count: " << layout.stripe_count << endl;
|
|
}
|
|
} else if (CMD_SHOW_LOC == cmd) {
|
|
struct ceph_ioctl_dataloc location;
|
|
location.file_offset = file_offset;
|
|
err = ioctl(fd, CEPH_IOC_GET_DATALOC, (unsigned long)&location);
|
|
if (err) {
|
|
cerr << "Error getting location: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
cout << "location.file_offset: " << location.file_offset << endl;
|
|
cout << "location.object_offset:" << location.object_offset << endl;
|
|
cout << "location.object_no: " << location.object_no << endl;
|
|
cout << "location.object_size: " << location.object_size << endl;
|
|
cout << "location.object_name: " << location.object_name << endl;
|
|
cout << "location.block_offset: " << location.block_offset << endl;
|
|
cout << "location.block_size: " << location.block_size << endl;
|
|
cout << "location.osd: " << location.osd << endl;
|
|
// cout << "osd address: " << location.osd_addr << endl;
|
|
} else if (CMD_SET_LAYOUT == cmd) {
|
|
struct ceph_ioctl_layout layout;
|
|
memset(&layout, 0, sizeof(layout));
|
|
int ioctl_num = (dir ? CEPH_IOC_SET_LAYOUT_POLICY : CEPH_IOC_SET_LAYOUT);
|
|
layout.data_pool = pool;
|
|
layout.object_size = object_size;
|
|
layout.stripe_count = stripe_count;
|
|
layout.stripe_unit = stripe_unit;
|
|
layout.unused = -1; /* used to be preferred_osd */
|
|
err = ioctl(fd, ioctl_num, (unsigned long)&layout);
|
|
if (err) {
|
|
cerr << "Error setting layout: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
} else if (CMD_MAP == cmd) {
|
|
struct stat st;
|
|
err = ::fstat(fd, &st);
|
|
if (err < 0) {
|
|
cerr << "error statting file: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
|
|
struct ceph_ioctl_layout layout;
|
|
memset(&layout, 0, sizeof(layout));
|
|
err = ioctl(fd, CEPH_IOC_GET_LAYOUT, (unsigned long)&layout);
|
|
if (err) {
|
|
cerr << "Error getting layout: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
|
|
printf("%15s %24s %12s %12s %s\n",
|
|
"FILE OFFSET", "OBJECT", "OFFSET", "LENGTH", "OSD");
|
|
|
|
for (long long off = 0; off < st.st_size; off += layout.stripe_unit) {
|
|
struct ceph_ioctl_dataloc location;
|
|
location.file_offset = off;
|
|
err = ioctl(fd, CEPH_IOC_GET_DATALOC, (unsigned long)&location);
|
|
if (err) {
|
|
cerr << "Error getting location: "
|
|
<< (err == -1 ? strerror(errno) : strerror(-err)) << endl;
|
|
return 1;
|
|
}
|
|
printf("%15lld %24s %12lld %12lld %d\n",
|
|
off, location.object_name, (long long)location.object_offset,
|
|
(long long)location.block_size, (int)location.osd);
|
|
}
|
|
|
|
} else {
|
|
cerr << "unknown cmd somehow set!" << endl;
|
|
usage();
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
void usage() {
|
|
cerr << "usage: cephfs path command [options]*" << endl;
|
|
cerr << "Commands:" << endl;
|
|
cerr << " show_layout -- view the layout information on a file or dir" << endl;
|
|
cerr << " set_layout -- set the layout on an empty file,\n"
|
|
<< " or the default layout on a directory" << endl;
|
|
cerr << " show_location -- view the location information on a file" << endl;
|
|
cerr << " map -- display file objects, pgs, osds" << endl;
|
|
cerr << "Options:" << endl;
|
|
cerr << " Useful for setting layouts:" << endl;
|
|
cerr << " --stripe_unit, -u: set the size of each stripe" << endl;
|
|
cerr << " --stripe_count, -c: set the number of objects to stripe across" << endl;
|
|
cerr << " --object_size, -s: set the size of the objects to stripe across" << endl;
|
|
cerr << " --pool, -p: set the pool to use" << endl;
|
|
cerr << endl;
|
|
cerr << " Useful for getting location data:" << endl;
|
|
cerr << " --offset, -l: the offset to retrieve location data for" << endl;
|
|
cerr << endl;
|
|
}
|
|
|
|
int init_options(int argc, char **argv, int *fd, char **path, int *cmd,
|
|
int *stripe_unit, int *stripe_count,
|
|
int *object_size, int64_t *pool, int *file_offset,
|
|
bool *dir) {
|
|
// look through the options, make sure they're valid,
|
|
// and set the variables from them
|
|
int i = 3;
|
|
struct stat stat_field;
|
|
|
|
if (argc < 3) {
|
|
cerr << "not enough parameters!" << endl;
|
|
return 1;
|
|
}
|
|
|
|
*path = argv[1];
|
|
|
|
*fd = open(argv[1], O_RDONLY);
|
|
if (*fd < 0) {
|
|
cerr << "error opening path: " << strerror(*fd) << endl;
|
|
return 1;
|
|
}
|
|
|
|
if (!strcmp(argv[2], "show_layout")) {
|
|
*cmd = CMD_SHOW_LAYOUT;
|
|
if (argc > 4)
|
|
return 1;
|
|
} else if (!strcmp(argv[2], "set_layout")) {
|
|
*cmd = CMD_SET_LAYOUT;
|
|
} else if (!strcmp(argv[2], "show_location")){
|
|
*cmd = CMD_SHOW_LOC;
|
|
} else if (!strcmp(argv[2], "map")) {
|
|
*cmd = CMD_MAP;
|
|
} else {
|
|
cerr << "invalid command" << endl;
|
|
return 1;
|
|
}
|
|
|
|
// okay, fill in options
|
|
while (i < argc) {
|
|
if (i == argc-1) {
|
|
// there's an option without an associated value!
|
|
cerr << "not all options are paired with a value!" << endl;
|
|
return 1;
|
|
}
|
|
|
|
if (!strcmp(argv[i], "--stripe_unit") || argv[i][1] == 'u') {
|
|
if (*cmd != CMD_SET_LAYOUT) {
|
|
cerr << "Invalid option for command!" << endl;
|
|
return 1;
|
|
}
|
|
*stripe_unit = strtol(argv[i+1], NULL, 0);
|
|
if (!*stripe_unit) {
|
|
cerr << "invalid value for stripe unit" << endl;
|
|
return 1;
|
|
}
|
|
} else if (!strcmp(argv[i], "--stripe_count") || argv[i][1] == 'c') {
|
|
if (*cmd != CMD_SET_LAYOUT) {
|
|
cerr << "Invalid option for command!" << endl;
|
|
return 1;
|
|
}
|
|
*stripe_count = strtol(argv[i+1], NULL, 0);
|
|
if (!*stripe_count) {
|
|
cerr << "invalid value for stripe count" << endl;
|
|
return 1;
|
|
}
|
|
} else if (!strcmp(argv[i], "--object_size") || argv[i][1] == 's') {
|
|
if (*cmd != CMD_SET_LAYOUT) {
|
|
cerr << "Invalid option for command!" << endl;
|
|
return 1;
|
|
}
|
|
*object_size = strtol(argv[i+1], NULL, 0);
|
|
if (!*object_size) {
|
|
cerr << "invalid value for object size" << endl;
|
|
return 1;
|
|
}
|
|
} else if (!strcmp(argv[i], "--pool") || argv[i][1] == 'p') {
|
|
if (*cmd != CMD_SET_LAYOUT) {
|
|
cerr << "Invalid option for command!" << endl;
|
|
return 1;
|
|
}
|
|
errno = 0;
|
|
*pool= strtol(argv[i+1], NULL, 0);
|
|
if (!*pool && errno) {
|
|
cerr << "invalid value for pool" << endl;
|
|
return 1;
|
|
}
|
|
} else if (!strcmp(argv[i], "--offset") || argv[i][1] == 'l') {
|
|
if (*cmd != CMD_SHOW_LOC) {
|
|
cerr << "Invalid option for command!" << endl;
|
|
return 1;
|
|
}
|
|
errno = 0;
|
|
*file_offset = strtol(argv[i+1], NULL, 0);
|
|
if (!*file_offset && errno) {
|
|
cerr << "invalid value for offset" << endl;
|
|
return 1;
|
|
}
|
|
}
|
|
i += 2;
|
|
}
|
|
|
|
int r = fstat (*fd, &stat_field);
|
|
if (r < 0) {
|
|
int err = errno;
|
|
cerr << "error doing stat file: " << cpp_strerror(err) << endl;
|
|
return 1;
|
|
}
|
|
|
|
if (S_ISREG(stat_field.st_mode)) { // open read-write to set layout
|
|
close(*fd);
|
|
*fd = open(argv[1], O_RDWR);
|
|
if (*fd < 0) {
|
|
cerr << "error opening file" << endl;
|
|
return 1;
|
|
}
|
|
} else {
|
|
*dir = true;
|
|
}
|
|
|
|
return 0;
|
|
}
|