mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
Refactoring.
This commit is contained in:
parent
74b27447c1
commit
d1d9800ef1
@ -4,27 +4,48 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "log.h"
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
#include "dev_manager.h"
|
#include "dev_manager.h"
|
||||||
|
|
||||||
/* FIXME Temporary */
|
|
||||||
#include "vgcache.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
|
#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
|
||||||
|
|
||||||
|
static int _activation = 1;
|
||||||
|
|
||||||
|
void set_activation(int activation)
|
||||||
|
{
|
||||||
|
if (activation == _activation)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_activation = activation;
|
||||||
|
if (_activation)
|
||||||
|
log_verbose("Activation enabled. Device-mapper kernel "
|
||||||
|
"driver will be used.");
|
||||||
|
else
|
||||||
|
log_verbose("Activation disabled. No device-mapper "
|
||||||
|
"interaction will be attempted.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int activation()
|
||||||
|
{
|
||||||
|
return _activation;
|
||||||
|
}
|
||||||
|
|
||||||
int library_version(char *version, size_t size)
|
int library_version(char *version, size_t size)
|
||||||
{
|
{
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!dm_get_library_version(version, size))
|
if (!dm_get_library_version(version, size))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
@ -35,6 +56,9 @@ int driver_version(char *version, size_t size)
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
log_very_verbose("Getting driver version");
|
log_very_verbose("Getting driver version");
|
||||||
if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
|
if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
|
||||||
stack;
|
stack;
|
||||||
@ -63,6 +87,9 @@ int lv_info(struct logical_volume *lv, struct dm_info *info)
|
|||||||
int r;
|
int r;
|
||||||
struct dev_manager *dm;
|
struct dev_manager *dm;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
@ -83,6 +110,9 @@ int lv_snapshot_percent(struct logical_volume *lv, float *percent)
|
|||||||
int r;
|
int r;
|
||||||
struct dev_manager *dm;
|
struct dev_manager *dm;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!(dm = dev_manager_create(lv->vg->name))) {
|
if (!(dm = dev_manager_create(lv->vg->name))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
@ -182,6 +212,9 @@ int lvs_in_vg_activated(struct volume_group *vg)
|
|||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = list_item(lvh, struct lv_list)->lv;
|
lv = list_item(lvh, struct lv_list)->lv;
|
||||||
count += (_lv_active(lv) == 1);
|
count += (_lv_active(lv) == 1);
|
||||||
@ -196,6 +229,9 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
|||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 0;
|
||||||
|
|
||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = list_item(lvh, struct lv_list)->lv;
|
lv = list_item(lvh, struct lv_list)->lv;
|
||||||
count += (_lv_open_count(lv) == 1);
|
count += (_lv_open_count(lv) == 1);
|
||||||
@ -204,44 +240,21 @@ int lvs_in_vg_opened(struct volume_group *vg)
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct logical_volume *_lv_from_lvid(struct cmd_context *cmd,
|
|
||||||
const char *lvid_s)
|
|
||||||
{
|
|
||||||
struct lv_list *lvl;
|
|
||||||
struct volume_group *vg;
|
|
||||||
union lvid *lvid;
|
|
||||||
|
|
||||||
lvid = (union lvid *) lvid_s;
|
|
||||||
|
|
||||||
log_very_verbose("Finding volume group for uuid %s", lvid_s);
|
|
||||||
if (!(vg = vg_read_by_vgid(cmd, lvid->id[0].uuid))) {
|
|
||||||
log_error("Volume group for uuid not found: %s", lvid_s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
log_verbose("Found volume group \"%s\"", vg->name);
|
|
||||||
if (vg->status & EXPORTED_VG) {
|
|
||||||
log_error("Volume group \"%s\" is exported", vg->name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(lvl = find_lv_in_vg_by_lvid(vg, lvid))) {
|
|
||||||
log_very_verbose("Can't find logical volume id %s", lvid_s);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lvl->lv;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These return success if the device is not active */
|
/* These return success if the device is not active */
|
||||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
|
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
|
||||||
{
|
{
|
||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(lv = _lv_from_lvid(cmd, lvid_s)))
|
if (!activation())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
if (!activation())
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
_skip("Suspending '%s'.", lv->name);
|
_skip("Suspending '%s'.", lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
@ -263,7 +276,10 @@ int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
|
|||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(lv = _lv_from_lvid(cmd, lvid_s)))
|
if (!activation())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
@ -287,7 +303,10 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
|
|||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(lv = _lv_from_lvid(cmd, lvid_s)))
|
if (!activation())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
@ -311,7 +330,10 @@ int lv_activate(struct cmd_context *cmd, const char *lvid_s)
|
|||||||
struct logical_volume *lv;
|
struct logical_volume *lv;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
|
|
||||||
if (!(lv = _lv_from_lvid(cmd, lvid_s)))
|
if (!activation())
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(lv = lv_from_lvid(cmd, lvid_s)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (test_mode()) {
|
if (test_mode()) {
|
||||||
|
@ -7,8 +7,12 @@
|
|||||||
#ifndef LVM_ACTIVATE_H
|
#ifndef LVM_ACTIVATE_H
|
||||||
#define LVM_ACTIVATE_H
|
#define LVM_ACTIVATE_H
|
||||||
|
|
||||||
|
#include "metadata.h"
|
||||||
#include <libdevmapper.h>
|
#include <libdevmapper.h>
|
||||||
|
|
||||||
|
void set_activation(int activation);
|
||||||
|
int activation();
|
||||||
|
|
||||||
int driver_version(char *version, size_t size);
|
int driver_version(char *version, size_t size);
|
||||||
int library_version(char *version, size_t size);
|
int library_version(char *version, size_t size);
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "dev_manager.h"
|
#include "dev_manager.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "log.h"
|
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
|
||||||
@ -577,7 +577,7 @@ static int _resume(struct dev_layer *dl)
|
|||||||
* Emit a target for a given segment.
|
* Emit a target for a given segment.
|
||||||
* FIXME: tidy this function.
|
* FIXME: tidy this function.
|
||||||
*/
|
*/
|
||||||
static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
|
static int _emit_target(struct dm_task *dmt, struct lv_segment *seg)
|
||||||
{
|
{
|
||||||
char params[1024];
|
char params[1024];
|
||||||
uint64_t esize = seg->lv->vg->extent_size;
|
uint64_t esize = seg->lv->vg->extent_size;
|
||||||
@ -638,11 +638,11 @@ static int _populate_vanilla(struct dev_manager *dm,
|
|||||||
struct dm_task *dmt, struct dev_layer *dl)
|
struct dm_task *dmt, struct dev_layer *dl)
|
||||||
{
|
{
|
||||||
struct list *segh;
|
struct list *segh;
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
struct logical_volume *lv = dl->lv;
|
struct logical_volume *lv = dl->lv;
|
||||||
|
|
||||||
list_iterate(segh, &lv->segments) {
|
list_iterate(segh, &lv->segments) {
|
||||||
seg = list_item(segh, struct stripe_segment);
|
seg = list_item(segh, struct lv_segment);
|
||||||
if (!_emit_target(dmt, seg)) {
|
if (!_emit_target(dmt, seg)) {
|
||||||
log_error("Unable to build table for '%s'", lv->name);
|
log_error("Unable to build table for '%s'", lv->name);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4,20 +4,16 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
#include "log.h"
|
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "lvm-file.h"
|
#include "lvm-file.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include <libdevmapper.h>
|
#include <libdevmapper.h>
|
||||||
|
|
||||||
static int _mk_dir(struct volume_group *vg)
|
static int _mk_dir(struct volume_group *vg)
|
||||||
|
475
lib/commands/toolcontext.c
Normal file
475
lib/commands/toolcontext.c
Normal file
@ -0,0 +1,475 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "toolcontext.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "metadata.h"
|
||||||
|
#include "defaults.h"
|
||||||
|
#include "lvm-string.h"
|
||||||
|
#include "activate.h"
|
||||||
|
#include "filter.h"
|
||||||
|
#include "filter-composite.h"
|
||||||
|
#include "filter-persistent.h"
|
||||||
|
#include "filter-regex.h"
|
||||||
|
#include "label.h"
|
||||||
|
#include "lvm-file.h"
|
||||||
|
#include "format-text.h"
|
||||||
|
#include "sharedlib.h"
|
||||||
|
|
||||||
|
#ifdef LVM1_INTERNAL
|
||||||
|
#include "format1.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static FILE *_log;
|
||||||
|
|
||||||
|
static int _get_env_vars(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
const char *e;
|
||||||
|
|
||||||
|
/* Set to "" to avoid using any system directory */
|
||||||
|
if ((e = getenv("LVM_SYSTEM_DIR"))) {
|
||||||
|
if (lvm_snprintf(cmd->sys_dir, sizeof(cmd->sys_dir),
|
||||||
|
"%s", e) < 0) {
|
||||||
|
log_error("LVM_SYSTEM_DIR environment variable "
|
||||||
|
"is too long.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _init_logging(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
char *open_mode = "a";
|
||||||
|
time_t t;
|
||||||
|
|
||||||
|
const char *log_file;
|
||||||
|
|
||||||
|
/* Syslog */
|
||||||
|
cmd->default_settings.syslog =
|
||||||
|
find_config_int(cmd->cf->root, "log/syslog", '/', DEFAULT_SYSLOG);
|
||||||
|
if (cmd->default_settings.syslog != 1)
|
||||||
|
fin_syslog();
|
||||||
|
|
||||||
|
if (cmd->default_settings.syslog > 1)
|
||||||
|
init_syslog(cmd->default_settings.syslog);
|
||||||
|
|
||||||
|
/* Debug level for log file output */
|
||||||
|
cmd->default_settings.debug =
|
||||||
|
find_config_int(cmd->cf->root, "log/level", '/', DEFAULT_LOGLEVEL);
|
||||||
|
init_debug(cmd->default_settings.debug);
|
||||||
|
|
||||||
|
/* Verbose level for tty output */
|
||||||
|
cmd->default_settings.verbose =
|
||||||
|
find_config_int(cmd->cf->root, "log/verbose", '/', DEFAULT_VERBOSE);
|
||||||
|
init_verbose(cmd->default_settings.verbose);
|
||||||
|
|
||||||
|
/* Log message formatting */
|
||||||
|
init_indent(find_config_int(cmd->cf->root, "log/indent", '/',
|
||||||
|
DEFAULT_INDENT));
|
||||||
|
|
||||||
|
cmd->default_settings.msg_prefix = find_config_str(cmd->cf->root,
|
||||||
|
"log/prefix", '/',
|
||||||
|
DEFAULT_MSG_PREFIX);
|
||||||
|
init_msg_prefix(cmd->default_settings.msg_prefix);
|
||||||
|
|
||||||
|
cmd->default_settings.cmd_name = find_config_int(cmd->cf->root,
|
||||||
|
"log/command_names",
|
||||||
|
'/', DEFAULT_CMD_NAME);
|
||||||
|
init_cmd_name(cmd->default_settings.cmd_name);
|
||||||
|
|
||||||
|
/* Test mode */
|
||||||
|
cmd->default_settings.test =
|
||||||
|
find_config_int(cmd->cf->root, "global/test", '/', 0);
|
||||||
|
|
||||||
|
/* Settings for logging to file */
|
||||||
|
if (find_config_int(cmd->cf->root, "log/overwrite", '/',
|
||||||
|
DEFAULT_OVERWRITE))
|
||||||
|
open_mode = "w";
|
||||||
|
|
||||||
|
log_file = find_config_str(cmd->cf->root, "log/file", '/', 0);
|
||||||
|
if (log_file) {
|
||||||
|
/* set up the logging */
|
||||||
|
if (!(_log = fopen(log_file, open_mode)))
|
||||||
|
log_error("Couldn't open log file %s", log_file);
|
||||||
|
else
|
||||||
|
init_log(_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
t = time(NULL);
|
||||||
|
log_verbose("Logging initialised at %s", ctime(&t));
|
||||||
|
|
||||||
|
/* Tell device-mapper about our logging */
|
||||||
|
dm_log_init(print_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _process_config(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
mode_t old_umask;
|
||||||
|
|
||||||
|
/* umask */
|
||||||
|
cmd->default_settings.umask = find_config_int(cmd->cf->root,
|
||||||
|
"global/umask", '/',
|
||||||
|
DEFAULT_UMASK);
|
||||||
|
|
||||||
|
if ((old_umask = umask((mode_t) cmd->default_settings.umask)) !=
|
||||||
|
(mode_t) cmd->default_settings.umask)
|
||||||
|
log_verbose("Set umask to %04o", cmd->default_settings.umask);
|
||||||
|
|
||||||
|
/* dev dir */
|
||||||
|
if (lvm_snprintf(cmd->dev_dir, sizeof(cmd->dev_dir), "%s/",
|
||||||
|
find_config_str(cmd->cf->root, "devices/dir",
|
||||||
|
'/', DEFAULT_DEV_DIR)) < 0) {
|
||||||
|
log_error("Device directory given in config file too long");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dm_set_dev_dir(cmd->dev_dir);
|
||||||
|
|
||||||
|
/* proc dir */
|
||||||
|
if (lvm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
|
||||||
|
find_config_str(cmd->cf->root, "global/proc",
|
||||||
|
'/', DEFAULT_PROC_DIR)) < 0) {
|
||||||
|
log_error("Device directory given in config file too long");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* activation? */
|
||||||
|
cmd->default_settings.activation = find_config_int(cmd->cf->root,
|
||||||
|
"global/activation",
|
||||||
|
'/',
|
||||||
|
DEFAULT_ACTIVATION);
|
||||||
|
set_activation(cmd->default_settings.activation);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find and read config file */
|
||||||
|
static int _init_config(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct stat info;
|
||||||
|
char config_file[PATH_MAX] = "";
|
||||||
|
|
||||||
|
if (!(cmd->cf = create_config_tree())) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No config file if LVM_SYSTEM_DIR is empty */
|
||||||
|
if (!*cmd->sys_dir)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (lvm_snprintf(config_file, sizeof(config_file),
|
||||||
|
"%s/lvm.conf", cmd->sys_dir) < 0) {
|
||||||
|
log_error("LVM_SYSTEM_DIR was too long");
|
||||||
|
destroy_config_tree(cmd->cf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is there a config file? */
|
||||||
|
if (stat(config_file, &info) == -1) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
return 1;
|
||||||
|
log_sys_error("stat", config_file);
|
||||||
|
destroy_config_tree(cmd->cf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!read_config_file(cmd->cf, config_file)) {
|
||||||
|
log_error("Failed to load config file %s", config_file);
|
||||||
|
destroy_config_tree(cmd->cf);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_dev_cache(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct config_node *cn;
|
||||||
|
struct config_value *cv;
|
||||||
|
|
||||||
|
if (!dev_cache_init()) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(cn = find_config_node(cmd->cf->root, "devices/scan", '/'))) {
|
||||||
|
if (!dev_cache_add_dir("/dev")) {
|
||||||
|
log_error("Failed to add /dev to internal "
|
||||||
|
"device cache");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
log_verbose("device/scan not in config file: "
|
||||||
|
"Defaulting to /dev");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
|
if (cv->type != CFG_STRING) {
|
||||||
|
log_error("Invalid string in config file: "
|
||||||
|
"devices/scan");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dev_cache_add_dir(cv->v.str)) {
|
||||||
|
log_error("Failed to add %s to internal device cache",
|
||||||
|
cv->v.str);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
struct config_node *cn;
|
||||||
|
struct dev_filter *f1, *f2, *f3;
|
||||||
|
|
||||||
|
if (!(f2 = lvm_type_filter_create(cmd->proc_dir)))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!(cn = find_config_node(cmd->cf->root, "devices/filter", '/'))) {
|
||||||
|
log_debug("devices/filter not found in config file: no regex "
|
||||||
|
"filter installed");
|
||||||
|
return f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(f1 = regex_filter_create(cn->v))) {
|
||||||
|
log_error("Failed to create regex device filter");
|
||||||
|
return f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(f3 = composite_filter_create(2, f1, f2))) {
|
||||||
|
log_error("Failed to create composite device filter");
|
||||||
|
return f2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return f3;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_filters(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
const char *lvm_cache;
|
||||||
|
struct dev_filter *f3, *f4;
|
||||||
|
struct stat st;
|
||||||
|
char cache_file[PATH_MAX];
|
||||||
|
|
||||||
|
cmd->dump_filter = 0;
|
||||||
|
|
||||||
|
if (!(f3 = _init_filter_components(cmd)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (lvm_snprintf(cache_file, sizeof(cache_file),
|
||||||
|
"%s/.cache", cmd->sys_dir) < 0) {
|
||||||
|
log_error("Persistent cache filename too long ('%s/.cache').",
|
||||||
|
cmd->sys_dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_cache =
|
||||||
|
find_config_str(cmd->cf->root, "devices/cache", '/', cache_file);
|
||||||
|
if (!(f4 = persistent_filter_create(f3, lvm_cache))) {
|
||||||
|
log_error("Failed to create persistent device filter");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Should we ever dump persistent filter state? */
|
||||||
|
if (find_config_int(cmd->cf->root, "devices/write_cache_state", '/', 1))
|
||||||
|
cmd->dump_filter = 1;
|
||||||
|
|
||||||
|
if (!*cmd->sys_dir)
|
||||||
|
cmd->dump_filter = 0;
|
||||||
|
|
||||||
|
if (!stat(lvm_cache, &st) && !persistent_filter_load(f4))
|
||||||
|
log_verbose("Failed to load existing device cache from %s",
|
||||||
|
lvm_cache);
|
||||||
|
|
||||||
|
cmd->filter = f4;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _init_formats(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
const char *format;
|
||||||
|
|
||||||
|
struct format_type *fmt;
|
||||||
|
struct list *fmth;
|
||||||
|
struct config_node *cn;
|
||||||
|
struct config_value *cv;
|
||||||
|
|
||||||
|
struct format_type *(*init_format_fn) (struct cmd_context * cmd);
|
||||||
|
|
||||||
|
void *lib;
|
||||||
|
|
||||||
|
label_init();
|
||||||
|
|
||||||
|
#ifdef LVM1_INTERNAL
|
||||||
|
if (!(fmt = init_lvm1_format(cmd)))
|
||||||
|
return 0;
|
||||||
|
fmt->library = NULL;
|
||||||
|
list_add(&cmd->formats, &fmt->list);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Load any formats in shared libs */
|
||||||
|
if ((cn = find_config_node(cmd->cf->root, "global/format_libraries",
|
||||||
|
'/'))) {
|
||||||
|
for (cv = cn->v; cv; cv = cv->next) {
|
||||||
|
if (cv->type != CFG_STRING) {
|
||||||
|
log_error("Invalid string in config file: "
|
||||||
|
"global/format_libraries");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (!(lib = load_shared_library(cmd->cf, cv->v.str,
|
||||||
|
"format"))) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(init_format_fn = dlsym(lib, "init_format"))) {
|
||||||
|
log_error("Shared library %s does not contain "
|
||||||
|
"format functions", cv->v.str);
|
||||||
|
dlclose(lib);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fmt = init_format_fn(cmd)))
|
||||||
|
return 0;
|
||||||
|
fmt->library = lib;
|
||||||
|
list_add(&cmd->formats, &fmt->list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(fmt = create_text_format(cmd)))
|
||||||
|
return 0;
|
||||||
|
fmt->library = NULL;
|
||||||
|
list_add(&cmd->formats, &fmt->list);
|
||||||
|
|
||||||
|
cmd->fmt_backup = fmt;
|
||||||
|
|
||||||
|
format = find_config_str(cmd->cf->root, "global/format", '/',
|
||||||
|
DEFAULT_FORMAT);
|
||||||
|
|
||||||
|
list_iterate(fmth, &cmd->formats) {
|
||||||
|
fmt = list_item(fmth, struct format_type);
|
||||||
|
if (!strcasecmp(fmt->name, format) ||
|
||||||
|
(fmt->alias && !strcasecmp(fmt->alias, format))) {
|
||||||
|
cmd->default_settings.fmt = fmt;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log_error("_init_formats: Default format (%s) not found", format);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entry point */
|
||||||
|
struct cmd_context *create_toolcontext(struct arg *the_args)
|
||||||
|
{
|
||||||
|
struct cmd_context *cmd;
|
||||||
|
|
||||||
|
if (!setlocale(LC_ALL, ""))
|
||||||
|
log_error("setlocale failed");
|
||||||
|
|
||||||
|
init_syslog(DEFAULT_LOG_FACILITY);
|
||||||
|
|
||||||
|
if (!(cmd = dbg_malloc(sizeof(*cmd)))) {
|
||||||
|
log_error("Failed to allocate command context");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
memset(cmd, 0, sizeof(*cmd));
|
||||||
|
cmd->args = the_args;
|
||||||
|
list_init(&cmd->formats);
|
||||||
|
|
||||||
|
strcpy(cmd->sys_dir, DEFAULT_SYS_DIR);
|
||||||
|
|
||||||
|
if (!_get_env_vars(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
/* Create system directory if it doesn't already exist */
|
||||||
|
if (*cmd->sys_dir && !create_dir(cmd->sys_dir))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!_init_config(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
_init_logging(cmd);
|
||||||
|
|
||||||
|
if (!_process_config(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!_init_dev_cache(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!_init_filters(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(cmd->mem = pool_create(4 * 1024))) {
|
||||||
|
log_error("Command memory pool creation failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_init_formats(cmd))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
cmd->current_settings = cmd->default_settings;
|
||||||
|
|
||||||
|
return cmd;
|
||||||
|
|
||||||
|
error:
|
||||||
|
dbg_free(cmd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_formats(struct list *formats)
|
||||||
|
{
|
||||||
|
struct list *fmtl, *tmp;
|
||||||
|
struct format_type *fmt;
|
||||||
|
void *lib;
|
||||||
|
|
||||||
|
list_iterate_safe(fmtl, tmp, formats) {
|
||||||
|
fmt = list_item(fmtl, struct format_type);
|
||||||
|
list_del(&fmt->list);
|
||||||
|
lib = fmt->library;
|
||||||
|
fmt->ops->destroy(fmt);
|
||||||
|
if (lib)
|
||||||
|
dlclose(lib);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy_toolcontext(struct cmd_context *cmd)
|
||||||
|
{
|
||||||
|
if (cmd->dump_filter)
|
||||||
|
persistent_filter_dump(cmd->filter);
|
||||||
|
|
||||||
|
cache_destroy();
|
||||||
|
label_exit();
|
||||||
|
destroy_formats(&cmd->formats);
|
||||||
|
cmd->filter->destroy(cmd->filter);
|
||||||
|
pool_destroy(cmd->mem);
|
||||||
|
dev_cache_exit();
|
||||||
|
destroy_config_tree(cmd->cf);
|
||||||
|
dbg_free(cmd);
|
||||||
|
|
||||||
|
dump_memory();
|
||||||
|
fin_log();
|
||||||
|
fin_syslog();
|
||||||
|
|
||||||
|
if (_log)
|
||||||
|
fclose(_log);
|
||||||
|
|
||||||
|
}
|
@ -13,25 +13,57 @@
|
|||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Config options that can be changed while commands are processed
|
||||||
|
*/
|
||||||
|
struct config_info {
|
||||||
|
int debug;
|
||||||
|
int verbose;
|
||||||
|
int test;
|
||||||
|
int syslog;
|
||||||
|
int activation;
|
||||||
|
const char *msg_prefix;
|
||||||
|
int cmd_name; /* Show command name? */
|
||||||
|
|
||||||
|
int archive; /* should we archive ? */
|
||||||
|
int backup; /* should we backup ? */
|
||||||
|
|
||||||
|
struct format_type *fmt;
|
||||||
|
|
||||||
|
mode_t umask;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* FIXME Split into tool & library contexts */
|
||||||
/* command-instance-related variables needed by library */
|
/* command-instance-related variables needed by library */
|
||||||
struct cmd_context {
|
struct cmd_context {
|
||||||
/* format handler allocates all objects from here */
|
/* format handler allocates all objects from here */
|
||||||
struct pool *mem;
|
struct pool *mem;
|
||||||
|
|
||||||
struct format_type *fmt; /* Current format to use by default */
|
struct format_type *fmt; /* Current format to use by default */
|
||||||
|
struct format_type *fmt_backup; /* Format to use for backups */
|
||||||
|
|
||||||
/* FIXME Move into dynamic list */
|
struct list formats; /* Available formats */
|
||||||
struct format_type *fmt1; /* Format1 */
|
|
||||||
struct format_type *fmtt; /* Format_text */
|
|
||||||
|
|
||||||
char *cmd_line;
|
char *cmd_line;
|
||||||
char *dev_dir;
|
|
||||||
struct dev_filter *filter;
|
|
||||||
struct config_file *cf;
|
|
||||||
|
|
||||||
struct command *command;
|
struct command *command;
|
||||||
struct uuid_map *um;
|
|
||||||
struct arg *args;
|
struct arg *args;
|
||||||
|
|
||||||
|
struct dev_filter *filter;
|
||||||
|
int dump_filter; /* Dump filter when exiting? */
|
||||||
|
|
||||||
|
struct config_tree *cf;
|
||||||
|
struct config_info default_settings;
|
||||||
|
struct config_info current_settings;
|
||||||
|
|
||||||
|
char sys_dir[PATH_MAX];
|
||||||
|
char dev_dir[PATH_MAX];
|
||||||
|
char proc_dir[PATH_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct cmd_context *create_toolcontext(struct arg *the_args);
|
||||||
|
void destroy_toolcontext(struct cmd_context *cmd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,18 +4,18 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include "lib.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "crc.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "device.h"
|
||||||
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
#include <asm/page.h>
|
||||||
#include <errno.h>
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#include "pool.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
TOK_INT,
|
TOK_INT,
|
||||||
@ -32,10 +32,10 @@ enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct parser {
|
struct parser {
|
||||||
const char *fb, *fe; /* file limits */
|
char *fb, *fe; /* file limits */
|
||||||
|
|
||||||
int t; /* token limits and type */
|
int t; /* token limits and type */
|
||||||
const char *tb, *te;
|
char *tb, *te;
|
||||||
|
|
||||||
int fd; /* descriptor for file being parsed */
|
int fd; /* descriptor for file being parsed */
|
||||||
int line; /* line number we are on */
|
int line; /* line number we are on */
|
||||||
@ -44,8 +44,10 @@ struct parser {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct cs {
|
struct cs {
|
||||||
struct config_file cf;
|
struct config_tree cf;
|
||||||
struct pool *mem;
|
struct pool *mem;
|
||||||
|
time_t timestamp;
|
||||||
|
char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void _get_token(struct parser *p);
|
static void _get_token(struct parser *p);
|
||||||
@ -81,7 +83,7 @@ static int _tok_match(const char *str, const char *b, const char *e)
|
|||||||
/*
|
/*
|
||||||
* public interface
|
* public interface
|
||||||
*/
|
*/
|
||||||
struct config_file *create_config_file(void)
|
struct config_tree *create_config_tree(void)
|
||||||
{
|
{
|
||||||
struct cs *c;
|
struct cs *c;
|
||||||
struct pool *mem = pool_create(10 * 1024);
|
struct pool *mem = pool_create(10 * 1024);
|
||||||
@ -99,20 +101,24 @@ struct config_file *create_config_file(void)
|
|||||||
|
|
||||||
c->mem = mem;
|
c->mem = mem;
|
||||||
c->cf.root = (struct config_node *) NULL;
|
c->cf.root = (struct config_node *) NULL;
|
||||||
|
c->timestamp = 0;
|
||||||
|
c->filename = NULL;
|
||||||
return &c->cf;
|
return &c->cf;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_config_file(struct config_file *cf)
|
void destroy_config_tree(struct config_tree *cf)
|
||||||
{
|
{
|
||||||
pool_destroy(((struct cs *) cf)->mem);
|
pool_destroy(((struct cs *) cf)->mem);
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_config(struct config_file *cf, const char *file)
|
int read_config_fd(struct config_tree *cf, int fd, const char *file,
|
||||||
|
off_t offset, uint32_t size, off_t offset2, uint32_t size2,
|
||||||
|
checksum_fn_t checksum_fn, uint32_t checksum)
|
||||||
{
|
{
|
||||||
struct cs *c = (struct cs *) cf;
|
struct cs *c = (struct cs *) cf;
|
||||||
struct parser *p;
|
struct parser *p;
|
||||||
struct stat info;
|
off_t mmap_offset;
|
||||||
int r = 1, fd;
|
int r = 0;
|
||||||
|
|
||||||
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
|
if (!(p = pool_alloc(c->mem, sizeof(*p)))) {
|
||||||
stack;
|
stack;
|
||||||
@ -120,12 +126,93 @@ int read_config(struct config_file *cf, const char *file)
|
|||||||
}
|
}
|
||||||
p->mem = c->mem;
|
p->mem = c->mem;
|
||||||
|
|
||||||
|
if (size2) {
|
||||||
|
/* FIXME Attempt adjacent mmaps MAP_FIXED into malloced space
|
||||||
|
* one PAGE_SIZE larger than required...
|
||||||
|
*/
|
||||||
|
if (!(p->fb = dbg_malloc(size + size2))) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (lseek(fd, offset, SEEK_SET) < 0) {
|
||||||
|
log_sys_error("lseek", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (raw_read(fd, p->fb, size) != size) {
|
||||||
|
log_error("Circular read from %s failed", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (lseek(fd, offset2, SEEK_SET) < 0) {
|
||||||
|
log_sys_error("lseek", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (raw_read(fd, p->fb + size, size2) != size2) {
|
||||||
|
log_error("Circular read from %s failed", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mmap_offset = offset % PAGE_SIZE;
|
||||||
/* memory map the file */
|
/* memory map the file */
|
||||||
if (stat(file, &info) || S_ISDIR(info.st_mode)) {
|
p->fb = mmap((caddr_t) 0, size + mmap_offset, PROT_READ,
|
||||||
|
MAP_PRIVATE, fd, offset - mmap_offset);
|
||||||
|
if (p->fb == (caddr_t) (-1)) {
|
||||||
|
log_sys_error("mmap", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->fb = p->fb + mmap_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (checksum_fn && checksum !=
|
||||||
|
(checksum_fn(checksum_fn(INITIAL_CRC, p->fb, size),
|
||||||
|
p->fb + size, size2))) {
|
||||||
|
log_error("%s: Checksum error", file);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->fe = p->fb + size + size2;
|
||||||
|
|
||||||
|
/* parse */
|
||||||
|
p->tb = p->te = p->fb;
|
||||||
|
p->line = 1;
|
||||||
|
_get_token(p);
|
||||||
|
if (!(cf->root = _file(p))) {
|
||||||
|
stack;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = 1;
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (size2)
|
||||||
|
dbg_free(p->fb);
|
||||||
|
else {
|
||||||
|
/* unmap the file */
|
||||||
|
if (munmap((char *) (p->fb - mmap_offset), size)) {
|
||||||
|
log_sys_error("munmap", file);
|
||||||
|
r = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_config_file(struct config_tree *cf, const char *file)
|
||||||
|
{
|
||||||
|
struct cs *c = (struct cs *) cf;
|
||||||
|
struct stat info;
|
||||||
|
int r = 1, fd;
|
||||||
|
|
||||||
|
if (stat(file, &info)) {
|
||||||
log_sys_error("stat", file);
|
log_sys_error("stat", file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!S_ISREG(info.st_mode)) {
|
||||||
|
log_error("%s is not a regular file", file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (info.st_size == 0) {
|
if (info.st_size == 0) {
|
||||||
log_verbose("%s is empty", file);
|
log_verbose("%s is empty", file);
|
||||||
return 1;
|
return 1;
|
||||||
@ -136,30 +223,75 @@ int read_config(struct config_file *cf, const char *file)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p->fb = mmap((caddr_t) 0, info.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
r = read_config_fd(cf, fd, file, 0, info.st_size, 0, 0,
|
||||||
if (p->fb == (caddr_t) (-1)) {
|
(checksum_fn_t) NULL, 0);
|
||||||
log_sys_error("mmap", file);
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
c->timestamp = info.st_mtime;
|
||||||
|
c->filename = pool_strdup(c->mem, file);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns 1 if config file reloaded
|
||||||
|
*/
|
||||||
|
int reload_config_file(struct config_tree **cf)
|
||||||
|
{
|
||||||
|
struct config_tree *new_cf;
|
||||||
|
struct cs *c = (struct cs *) *cf;
|
||||||
|
struct cs *new_cs;
|
||||||
|
struct stat info;
|
||||||
|
int r, fd;
|
||||||
|
|
||||||
|
if (stat(c->filename, &info) == -1) {
|
||||||
|
if (errno == ENOENT)
|
||||||
|
return 1;
|
||||||
|
log_sys_error("stat", c->filename);
|
||||||
|
log_error("Failed to reload configuration file");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
p->fe = p->fb + info.st_size;
|
|
||||||
|
|
||||||
/* parse */
|
if (!S_ISREG(info.st_mode)) {
|
||||||
p->tb = p->te = p->fb;
|
log_error("Configuration file %s is not a regular file",
|
||||||
p->line = 1;
|
c->filename);
|
||||||
_get_token(p);
|
return 0;
|
||||||
if (!(cf->root = _file(p))) {
|
|
||||||
stack;
|
|
||||||
r = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* unmap the file */
|
/* Unchanged? */
|
||||||
if (munmap((char *) p->fb, info.st_size)) {
|
if (c->timestamp == info.st_mtime)
|
||||||
log_sys_error("munmap", file);
|
return 0;
|
||||||
r = 0;
|
|
||||||
|
log_verbose("Detected config file change: Reloading %s", c->filename);
|
||||||
|
|
||||||
|
if (info.st_size == 0) {
|
||||||
|
log_verbose("Config file reload: %s is empty", c->filename);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((fd = open(c->filename, O_RDONLY)) < 0) {
|
||||||
|
log_sys_error("open", c->filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(new_cf = create_config_tree())) {
|
||||||
|
log_error("Allocation of new config_tree failed");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = read_config_fd(new_cf, fd, c->filename, 0, info.st_size, 0, 0,
|
||||||
|
(checksum_fn_t) NULL, 0);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
if (r) {
|
||||||
|
new_cs = (struct cs *) new_cf;
|
||||||
|
new_cs->filename = pool_strdup(new_cs->mem, c->filename);
|
||||||
|
new_cs->timestamp = info.st_mtime;
|
||||||
|
destroy_config_tree(*cf);
|
||||||
|
*cf = new_cf;
|
||||||
|
}
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +315,8 @@ static void _write_value(FILE * fp, struct config_value *v)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log_err("Unknown value type");
|
log_error("_write_value: Unknown value type: %d", v->type);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,7 +363,7 @@ static int _write_config(struct config_node *n, FILE * fp, int level)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write_config(struct config_file *cf, const char *file)
|
int write_config_file(struct config_tree *cf, const char *file)
|
||||||
{
|
{
|
||||||
int r = 1;
|
int r = 1;
|
||||||
FILE *fp = fopen(file, "w");
|
FILE *fp = fopen(file, "w");
|
||||||
@ -332,9 +465,8 @@ static struct config_value *_value(struct parser *p)
|
|||||||
match(TOK_COMMA);
|
match(TOK_COMMA);
|
||||||
}
|
}
|
||||||
match(TOK_ARRAY_E);
|
match(TOK_ARRAY_E);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Special case an empty array.
|
* Special case for an empty array.
|
||||||
*/
|
*/
|
||||||
if (!h) {
|
if (!h) {
|
||||||
if (!(h = _create_value(p)))
|
if (!(h = _create_value(p)))
|
||||||
@ -342,6 +474,7 @@ static struct config_value *_value(struct parser *p)
|
|||||||
|
|
||||||
h->type = CFG_EMPTY_ARRAY;
|
h->type = CFG_EMPTY_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
h = _type(p);
|
h = _type(p);
|
||||||
|
|
||||||
@ -352,6 +485,7 @@ static struct config_value *_type(struct parser *p)
|
|||||||
{
|
{
|
||||||
/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */
|
/* [0-9]+ | [0-9]*\.[0-9]* | ".*" */
|
||||||
struct config_value *v = _create_value(p);
|
struct config_value *v = _create_value(p);
|
||||||
|
|
||||||
if (!v)
|
if (!v)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@ -403,7 +537,7 @@ static void _get_token(struct parser *p)
|
|||||||
{
|
{
|
||||||
p->tb = p->te;
|
p->tb = p->te;
|
||||||
_eat_space(p);
|
_eat_space(p);
|
||||||
if (p->tb == p->fe) {
|
if (p->tb == p->fe || !*p->tb) {
|
||||||
p->t = TOK_EOF;
|
p->t = TOK_EOF;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -444,13 +578,14 @@ static void _get_token(struct parser *p)
|
|||||||
case '"':
|
case '"':
|
||||||
p->t = TOK_STRING;
|
p->t = TOK_STRING;
|
||||||
p->te++;
|
p->te++;
|
||||||
while ((p->te != p->fe) && (*p->te != '"')) {
|
while ((p->te != p->fe) && (*p->te) && (*p->te != '"')) {
|
||||||
if ((*p->te == '\\') && (p->te + 1 != p->fe))
|
if ((*p->te == '\\') && (p->te + 1 != p->fe) &&
|
||||||
|
*(p->te + 1))
|
||||||
p->te++;
|
p->te++;
|
||||||
p->te++;
|
p->te++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p->te != p->fe)
|
if ((p->te != p->fe) && (*p->te))
|
||||||
p->te++;
|
p->te++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -467,7 +602,7 @@ static void _get_token(struct parser *p)
|
|||||||
case '8':
|
case '8':
|
||||||
case '9':
|
case '9':
|
||||||
p->te++;
|
p->te++;
|
||||||
while (p->te != p->fe) {
|
while ((p->te != p->fe) && (*p->te)) {
|
||||||
if (*p->te == '.') {
|
if (*p->te == '.') {
|
||||||
if (p->t == TOK_FLOAT)
|
if (p->t == TOK_FLOAT)
|
||||||
break;
|
break;
|
||||||
@ -480,7 +615,7 @@ static void _get_token(struct parser *p)
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
p->t = TOK_IDENTIFIER;
|
p->t = TOK_IDENTIFIER;
|
||||||
while ((p->te != p->fe) && !isspace(*p->te) &&
|
while ((p->te != p->fe) && (*p->te) && !isspace(*p->te) &&
|
||||||
(*p->te != '#') && (*p->te != '='))
|
(*p->te != '#') && (*p->te != '='))
|
||||||
p->te++;
|
p->te++;
|
||||||
break;
|
break;
|
||||||
@ -489,15 +624,15 @@ static void _get_token(struct parser *p)
|
|||||||
|
|
||||||
static void _eat_space(struct parser *p)
|
static void _eat_space(struct parser *p)
|
||||||
{
|
{
|
||||||
while (p->tb != p->fe) {
|
while ((p->tb != p->fe) && (*p->tb)) {
|
||||||
if (*p->te == '#') {
|
if (*p->te == '#') {
|
||||||
while ((p->te != p->fe) && (*p->te != '\n'))
|
while ((p->te != p->fe) && (*p->te) && (*p->te != '\n'))
|
||||||
p->te++;
|
p->te++;
|
||||||
p->line++;
|
p->line++;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (isspace(*p->te)) {
|
else if (isspace(*p->te)) {
|
||||||
while ((p->te != p->fe) && isspace(*p->te)) {
|
while ((p->te != p->fe) && (*p->te) && isspace(*p->te)) {
|
||||||
if (*p->te == '\n')
|
if (*p->te == '\n')
|
||||||
p->line++;
|
p->line++;
|
||||||
p->te++;
|
p->te++;
|
||||||
@ -715,4 +850,3 @@ int get_config_str(struct config_node *cn, const char *path,
|
|||||||
*result = n->v->v.str;
|
*result = n->v->v.str;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define _LVM_CONFIG_H
|
#define _LVM_CONFIG_H
|
||||||
|
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CFG_STRING,
|
CFG_STRING,
|
||||||
@ -32,15 +33,22 @@ struct config_node {
|
|||||||
struct config_value *v;
|
struct config_value *v;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_file {
|
struct config_tree {
|
||||||
struct config_node *root;
|
struct config_node *root;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_file *create_config_file(void);
|
struct config_tree *create_config_tree(void);
|
||||||
void destroy_config_file(struct config_file *cf);
|
void destroy_config_tree(struct config_tree *cf);
|
||||||
|
|
||||||
int read_config(struct config_file *cf, const char *file);
|
typedef uint32_t (*checksum_fn_t) (uint32_t initial, void *buf, uint32_t size);
|
||||||
int write_config(struct config_file *cf, const char *file);
|
|
||||||
|
int read_config_fd(struct config_tree *cf, int fd, const char *file,
|
||||||
|
off_t offset, uint32_t size, off_t offset2, uint32_t size2,
|
||||||
|
checksum_fn_t checksum_fn, uint32_t checksum);
|
||||||
|
|
||||||
|
int read_config_file(struct config_tree *cf, const char *file);
|
||||||
|
int write_config_file(struct config_tree *cf, const char *file);
|
||||||
|
int reload_config_file(struct config_tree **cf);
|
||||||
|
|
||||||
struct config_node *find_config_node(struct config_node *cn,
|
struct config_node *find_config_node(struct config_node *cn,
|
||||||
const char *path, char seperator);
|
const char *path, char seperator);
|
||||||
@ -61,8 +69,6 @@ float find_config_float(struct config_node *cn, const char *path,
|
|||||||
int find_config_bool(struct config_node *cn, const char *path,
|
int find_config_bool(struct config_node *cn, const char *path,
|
||||||
char sep, int fail);
|
char sep, int fail);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int get_config_uint32(struct config_node *cn, const char *path,
|
int get_config_uint32(struct config_node *cn, const char *path,
|
||||||
char sep, uint32_t *result);
|
char sep, uint32_t *result);
|
||||||
|
|
||||||
@ -73,4 +79,3 @@ int get_config_str(struct config_node *cn, const char *path,
|
|||||||
char sep, char **result);
|
char sep, char **result);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -7,9 +7,6 @@
|
|||||||
#ifndef _LVM_DEFAULTS_H
|
#ifndef _LVM_DEFAULTS_H
|
||||||
#define _LVM_DEFAULTS_H
|
#define _LVM_DEFAULTS_H
|
||||||
|
|
||||||
|
|
||||||
#define DEFAULT_SYS_DIR "/etc/lvm"
|
|
||||||
|
|
||||||
#define DEFAULT_ARCHIVE_ENABLED 1
|
#define DEFAULT_ARCHIVE_ENABLED 1
|
||||||
#define DEFAULT_BACKUP_ENABLED 1
|
#define DEFAULT_BACKUP_ENABLED 1
|
||||||
|
|
||||||
@ -19,22 +16,42 @@
|
|||||||
#define DEFAULT_ARCHIVE_DAYS 30
|
#define DEFAULT_ARCHIVE_DAYS 30
|
||||||
#define DEFAULT_ARCHIVE_NUMBER 10
|
#define DEFAULT_ARCHIVE_NUMBER 10
|
||||||
|
|
||||||
|
#define DEFAULT_SYS_DIR "/etc/lvm"
|
||||||
#define DEFAULT_DEV_DIR "/dev"
|
#define DEFAULT_DEV_DIR "/dev"
|
||||||
#define DEFAULT_PROC_DIR "/proc"
|
#define DEFAULT_PROC_DIR "/proc"
|
||||||
|
|
||||||
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
|
#define DEFAULT_LOCK_DIR "/var/lock/lvm"
|
||||||
|
#define DEFAULT_LOCKING_LIB "lvm2_locking.so"
|
||||||
|
|
||||||
#define DEFAULT_UMASK 0077
|
#define DEFAULT_UMASK 0077
|
||||||
|
|
||||||
|
#ifdef LVM1_SUPPORT
|
||||||
#define DEFAULT_FORMAT "lvm1"
|
#define DEFAULT_FORMAT "lvm1"
|
||||||
|
#else
|
||||||
|
#define DEFAULT_FORMAT "lvm2"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_PVMETADATASIZE 255
|
||||||
|
#define DEFAULT_PVMETADATACOPIES 1
|
||||||
|
#define DEFAULT_LABELSECTOR 1
|
||||||
|
|
||||||
#define DEFAULT_MSG_PREFIX " "
|
#define DEFAULT_MSG_PREFIX " "
|
||||||
|
|
||||||
#define DEFAULT_CMD_NAME 0
|
#define DEFAULT_CMD_NAME 0
|
||||||
|
#define DEFAULT_OVERWRITE 0
|
||||||
|
|
||||||
|
#ifndef DEFAULT_LOG_FACILITY
|
||||||
|
#define DEFAULT_LOG_FACILITY LOG_USER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define DEFAULT_SYSLOG 1
|
||||||
|
#define DEFAULT_VERBOSE 0
|
||||||
|
#define DEFAULT_LOGLEVEL 0
|
||||||
|
#define DEFAULT_INDENT 1
|
||||||
|
|
||||||
|
#define DEFAULT_ACTIVATION 1
|
||||||
|
|
||||||
#ifdef READLINE_SUPPORT
|
#ifdef READLINE_SUPPORT
|
||||||
#define DEFAULT_MAX_HISTORY 100
|
#define DEFAULT_MAX_HISTORY 100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* _LVM_DEFAULTS_H */
|
#endif /* _LVM_DEFAULTS_H */
|
||||||
|
@ -4,10 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "bitset.h"
|
#include "bitset.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
/* FIXME: calculate this. */
|
/* FIXME: calculate this. */
|
||||||
#define INT_SHIFT 5
|
#define INT_SHIFT 5
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
|
|
||||||
typedef uint32_t *bitset_t;
|
typedef uint32_t *bitset_t;
|
||||||
|
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "btree.h"
|
#include "btree.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
uint32_t key;
|
uint32_t key;
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dbg_malloc.h"
|
#include "lib.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
struct hash_node {
|
struct hash_node {
|
||||||
struct hash_node *next;
|
struct hash_node *next;
|
||||||
@ -60,10 +59,10 @@ static struct hash_node *_create_node(const char *str)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned _hash(const char *str)
|
static unsigned _hash(const char *str, int len)
|
||||||
{
|
{
|
||||||
unsigned long int h = 0, g;
|
unsigned long int h = 0, g;
|
||||||
while (*str) {
|
while (*str && len--) {
|
||||||
h <<= 4;
|
h <<= 4;
|
||||||
h += _nums[(int) *str++];
|
h += _nums[(int) *str++];
|
||||||
g = h & ((unsigned long) 0xf << 16u);
|
g = h & ((unsigned long) 0xf << 16u);
|
||||||
@ -126,18 +125,30 @@ void hash_destroy(struct hash_table *t)
|
|||||||
dbg_free(t);
|
dbg_free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct hash_node **_find(struct hash_table *t, const char *key)
|
static inline struct hash_node **_find_fixed(struct hash_table *t,
|
||||||
|
const char *key, uint32_t len)
|
||||||
{
|
{
|
||||||
unsigned h = _hash(key) & (t->num_slots - 1);
|
unsigned h = _hash(key, len) & (t->num_slots - 1);
|
||||||
struct hash_node **c;
|
struct hash_node **c;
|
||||||
|
|
||||||
for (c = &t->slots[h]; *c; c = &((*c)->next))
|
for (c = &t->slots[h]; *c; c = &((*c)->next))
|
||||||
if (!strcmp(key, (*c)->key))
|
if (!strncmp(key, (*c)->key, len))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct hash_node **_find(struct hash_table *t, const char *key)
|
||||||
|
{
|
||||||
|
return _find_fixed(t, key, strlen(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len)
|
||||||
|
{
|
||||||
|
struct hash_node **c = _find_fixed(t, key, len);
|
||||||
|
return *c ? (*c)->data : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void *hash_lookup(struct hash_table *t, const char *key)
|
void *hash_lookup(struct hash_table *t, const char *key)
|
||||||
{
|
{
|
||||||
struct hash_node **c = _find(t, key);
|
struct hash_node **c = _find(t, key);
|
||||||
@ -227,6 +238,6 @@ struct hash_node *hash_get_first(struct hash_table *t)
|
|||||||
|
|
||||||
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
|
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
|
||||||
{
|
{
|
||||||
unsigned int h = _hash(n->key) & (t->num_slots - 1);
|
unsigned int h = _hash(n->key, strlen(n->key)) & (t->num_slots - 1);
|
||||||
return n->next ? n->next : _next_slot(t, h + 1);
|
return n->next ? n->next : _next_slot(t, h + 1);
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@
|
|||||||
#ifndef _LVM_HASH_H
|
#ifndef _LVM_HASH_H
|
||||||
#define _LVM_HASH_H
|
#define _LVM_HASH_H
|
||||||
|
|
||||||
|
#include "lvm-types.h"
|
||||||
|
|
||||||
struct hash_table;
|
struct hash_table;
|
||||||
struct hash_node;
|
struct hash_node;
|
||||||
|
|
||||||
@ -17,6 +19,7 @@ void hash_destroy(struct hash_table *t);
|
|||||||
void hash_wipe(struct hash_table *t);
|
void hash_wipe(struct hash_table *t);
|
||||||
|
|
||||||
void *hash_lookup(struct hash_table *t, const char *key);
|
void *hash_lookup(struct hash_table *t, const char *key);
|
||||||
|
void *hash_lookup_fixed(struct hash_table *t, const char *key, uint32_t len);
|
||||||
int hash_insert(struct hash_table *t, const char *key, void *data);
|
int hash_insert(struct hash_table *t, const char *key, void *data);
|
||||||
void hash_remove(struct hash_table *t, const char *key);
|
void hash_remove(struct hash_table *t, const char *key);
|
||||||
|
|
||||||
|
@ -4,17 +4,14 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "dev-cache.h"
|
#include "dev-cache.h"
|
||||||
#include "log.h"
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "lvm-types.h"
|
#include "lvm-types.h"
|
||||||
#include "btree.h"
|
#include "btree.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -63,6 +60,8 @@ static struct device *_create_dev(dev_t d)
|
|||||||
list_init(&dev->aliases);
|
list_init(&dev->aliases);
|
||||||
dev->dev = d;
|
dev->dev = d;
|
||||||
dev->fd = -1;
|
dev->fd = -1;
|
||||||
|
dev->flags = 0;
|
||||||
|
memset(dev->pvid, 0, sizeof(dev->pvid));
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,6 +228,21 @@ static void _full_scan(void)
|
|||||||
_cache.has_scanned = 1;
|
_cache.has_scanned = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int dev_cache_has_scanned(void)
|
||||||
|
{
|
||||||
|
return _cache.has_scanned;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dev_cache_scan(int do_scan)
|
||||||
|
{
|
||||||
|
if (!do_scan)
|
||||||
|
_cache.has_scanned = 1;
|
||||||
|
else {
|
||||||
|
_cache.has_scanned = 0;
|
||||||
|
_full_scan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int dev_cache_init(void)
|
int dev_cache_init(void)
|
||||||
{
|
{
|
||||||
_cache.names = NULL;
|
_cache.names = NULL;
|
||||||
|
@ -27,6 +27,10 @@ struct dev_filter {
|
|||||||
int dev_cache_init(void);
|
int dev_cache_init(void);
|
||||||
void dev_cache_exit(void);
|
void dev_cache_exit(void);
|
||||||
|
|
||||||
|
/* Trigger(1) or avoid(0) a scan */
|
||||||
|
void dev_cache_scan(int do_scan);
|
||||||
|
int dev_cache_has_scanned(void);
|
||||||
|
|
||||||
int dev_cache_add_dir(const char *path);
|
int dev_cache_add_dir(const char *path);
|
||||||
struct device *dev_cache_get(const char *name, struct dev_filter *f);
|
struct device *dev_cache_get(const char *name, struct dev_filter *f);
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "lvm-types.h"
|
#include "lvm-types.h"
|
||||||
#include "log.h"
|
#include "metadata.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -62,7 +62,6 @@ int dev_get_sectsize(struct device *dev, uint32_t * size)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void _flush(int fd)
|
static void _flush(int fd)
|
||||||
{
|
{
|
||||||
ioctl(fd, BLKFLSBUF, 0);
|
ioctl(fd, BLKFLSBUF, 0);
|
||||||
@ -96,6 +95,7 @@ int dev_open(struct device *dev, int flags)
|
|||||||
if ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev)) {
|
if ((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev)) {
|
||||||
log_error("%s: fstat failed: Has device name changed?", name);
|
log_error("%s: fstat failed: Has device name changed?", name);
|
||||||
dev_close(dev);
|
dev_close(dev);
|
||||||
|
dev->fd = -1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_flush(dev->fd);
|
_flush(dev->fd);
|
||||||
@ -126,7 +126,7 @@ int dev_close(struct device *dev)
|
|||||||
/*
|
/*
|
||||||
* FIXME: factor common code out.
|
* FIXME: factor common code out.
|
||||||
*/
|
*/
|
||||||
int _read(int fd, void *buf, size_t count)
|
int raw_read(int fd, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
@ -162,12 +162,12 @@ int64_t dev_read(struct device * dev, uint64_t offset,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _read(fd, buffer, len);
|
return raw_read(fd, buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
int _write(int fd, const void *buf, size_t count)
|
int _write(int fd, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t n = 0;
|
ssize_t n = 0;
|
||||||
int tot = 0;
|
int tot = 0;
|
||||||
|
|
||||||
/* Skip all writes */
|
/* Skip all writes */
|
||||||
@ -214,24 +214,34 @@ int dev_zero(struct device *dev, uint64_t offset, int64_t len)
|
|||||||
{
|
{
|
||||||
int64_t r, s;
|
int64_t r, s;
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
const char *name = dev_name(dev);
|
int already_open;
|
||||||
int fd = dev->fd;
|
|
||||||
|
|
||||||
if (fd < 0) {
|
already_open = dev_is_open(dev);
|
||||||
log_error("Attempt to zero part of an unopened device %s",
|
|
||||||
name);
|
if (!already_open && !dev_open(dev, O_RDWR)) {
|
||||||
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lseek(fd, offset, SEEK_SET) < 0) {
|
if (lseek(dev->fd, offset, SEEK_SET) < 0) {
|
||||||
log_sys_error("lseek", name);
|
log_sys_error("lseek", dev_name(dev));
|
||||||
|
if (!already_open && !dev_close(dev))
|
||||||
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((offset % SECTOR_SIZE) || (len % SECTOR_SIZE))
|
||||||
|
log_debug("Wiping %s at %" PRIu64 " length %" PRId64,
|
||||||
|
dev_name(dev), offset, len);
|
||||||
|
else
|
||||||
|
log_debug("Wiping %s at sector %" PRIu64 " length %" PRId64
|
||||||
|
" sectors", dev_name(dev), offset >> SECTOR_SHIFT,
|
||||||
|
len >> SECTOR_SHIFT);
|
||||||
|
|
||||||
memset(buffer, 0, sizeof(buffer));
|
memset(buffer, 0, sizeof(buffer));
|
||||||
while (1) {
|
while (1) {
|
||||||
s = len > sizeof(buffer) ? sizeof(buffer) : len;
|
s = len > sizeof(buffer) ? sizeof(buffer) : len;
|
||||||
r = _write(fd, buffer, s);
|
r = _write(dev->fd, buffer, s);
|
||||||
|
|
||||||
if (r <= 0)
|
if (r <= 0)
|
||||||
break;
|
break;
|
||||||
@ -245,6 +255,9 @@ int dev_zero(struct device *dev, uint64_t offset, int64_t len)
|
|||||||
|
|
||||||
dev->flags |= DEV_ACCESSED_W;
|
dev->flags |= DEV_ACCESSED_W;
|
||||||
|
|
||||||
|
if (!already_open && !dev_close(dev))
|
||||||
|
stack;
|
||||||
|
|
||||||
/* FIXME: Always display error */
|
/* FIXME: Always display error */
|
||||||
return (len == 0);
|
return (len == 0);
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
* MA 02111-1307, USA
|
* MA 02111-1307, USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#if 0
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
@ -24,9 +25,12 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <string.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#include <linux/major.h>
|
||||||
|
#include <linux/genhd.h>
|
||||||
|
|
||||||
#include "dbg_malloc.h"
|
#include "dbg_malloc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
@ -34,11 +38,6 @@
|
|||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
|
||||||
#include <linux/fs.h>
|
|
||||||
#include <linux/major.h>
|
|
||||||
#include <linux/genhd.h>
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
int _get_partition_type(struct dev_filter *filter, struct device *d);
|
int _get_partition_type(struct dev_filter *filter, struct device *d);
|
||||||
|
|
||||||
#define MINOR_PART(dm, d) (MINOR((d)->dev) % dev_max_partitions(dm, (d)->dev))
|
#define MINOR_PART(dm, d) (MINOR((d)->dev) % dev_max_partitions(dm, (d)->dev))
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "lvm-types.h"
|
#include "lvm-types.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
|
#define DEV_ACCESSED_W 0x00000001 /* Device written to? */
|
||||||
|
|
||||||
@ -23,6 +24,8 @@ struct device {
|
|||||||
/* private */
|
/* private */
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
|
|
||||||
|
char pvid[ID_LEN + 1];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct device_list {
|
struct device_list {
|
||||||
@ -30,6 +33,12 @@ struct device_list {
|
|||||||
struct device *dev;
|
struct device *dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct device_area {
|
||||||
|
struct device *dev;
|
||||||
|
uint64_t start; /* Bytes */
|
||||||
|
uint64_t size; /* Bytes */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All io should use these routines.
|
* All io should use these routines.
|
||||||
*/
|
*/
|
||||||
@ -39,14 +48,21 @@ int dev_get_sectsize(struct device *dev, uint32_t *size);
|
|||||||
int dev_open(struct device *dev, int flags);
|
int dev_open(struct device *dev, int flags);
|
||||||
int dev_close(struct device *dev);
|
int dev_close(struct device *dev);
|
||||||
|
|
||||||
|
static inline int dev_fd(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw_read(int fd, void *buf, size_t count);
|
||||||
|
|
||||||
int64_t dev_read(struct device *dev,
|
int64_t dev_read(struct device *dev,
|
||||||
uint64_t offset, int64_t len, void *buffer);
|
uint64_t offset, int64_t len, void *buffer);
|
||||||
int64_t dev_write(struct device *dev,
|
int64_t dev_write(struct device *dev,
|
||||||
uint64_t offset, int64_t len, void *buffer);
|
uint64_t offset, int64_t len, void *buffer);
|
||||||
int dev_zero(struct device *dev, uint64_t offset, int64_t len);
|
int dev_zero(struct device *dev, uint64_t offset, int64_t len);
|
||||||
|
|
||||||
|
static inline const char *dev_name(struct device *dev)
|
||||||
static inline const char *dev_name(struct device *dev) {
|
{
|
||||||
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
|
return (dev) ? list_item(dev->aliases.n, struct str_list)->str :
|
||||||
"unknown device";
|
"unknown device";
|
||||||
}
|
}
|
||||||
@ -54,9 +70,14 @@ static inline const char *dev_name(struct device *dev) {
|
|||||||
/* Return a valid device name from the alias list; NULL otherwise */
|
/* Return a valid device name from the alias list; NULL otherwise */
|
||||||
const char *dev_name_confirmed(struct device *dev);
|
const char *dev_name_confirmed(struct device *dev);
|
||||||
|
|
||||||
static inline int is_lvm_partition(const char *name) {
|
static inline int is_lvm_partition(const char *name)
|
||||||
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
static inline int dev_is_open(struct device *dev)
|
||||||
|
{
|
||||||
|
return dev->fd >= 0 ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -18,19 +18,83 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
#include "uuid.h"
|
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#define SIZE_BUF 128
|
#define SIZE_BUF 128
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
alloc_policy_t alloc;
|
||||||
|
const char *str;
|
||||||
|
} _policies[] = {
|
||||||
|
{
|
||||||
|
ALLOC_NEXT_FREE, "next free"}, {
|
||||||
|
ALLOC_CONTIGUOUS, "contiguous"}, {
|
||||||
|
ALLOC_DEFAULT, "next free (default)"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
segment_type_t segtype;
|
||||||
|
const char *str;
|
||||||
|
} _segtypes[] = {
|
||||||
|
{
|
||||||
|
SEG_STRIPED, "striped"}, {
|
||||||
|
SEG_MIRROR, "mirror"}, {
|
||||||
|
SEG_SNAPSHOT, "snapshot"}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
||||||
|
static int _num_segtypes = sizeof(_segtypes) / sizeof(*_segtypes);
|
||||||
|
|
||||||
|
const char *get_alloc_string(alloc_policy_t alloc)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _num_policies; i++)
|
||||||
|
if (_policies[i].alloc == alloc)
|
||||||
|
return _policies[i].str;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *get_segtype_string(segment_type_t segtype)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _num_segtypes; i++)
|
||||||
|
if (_segtypes[i].segtype == segtype)
|
||||||
|
return _segtypes[i].str;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
alloc_policy_t get_alloc_from_string(const char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _num_policies; i++)
|
||||||
|
if (!strcmp(_policies[i].str, str))
|
||||||
|
return _policies[i].alloc;
|
||||||
|
|
||||||
|
log_error("Unrecognised allocation policy - using default");
|
||||||
|
return ALLOC_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
segment_type_t get_segtype_from_string(const char *str)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < _num_segtypes; i++)
|
||||||
|
if (!strcmp(_segtypes[i].str, str))
|
||||||
|
return _segtypes[i].segtype;
|
||||||
|
|
||||||
|
log_error("Unrecognised segment type - using default (striped)");
|
||||||
|
return SEG_STRIPED;
|
||||||
|
}
|
||||||
|
|
||||||
char *display_size(uint64_t size, size_len_t sl)
|
char *display_size(uint64_t size, size_len_t sl)
|
||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
@ -89,7 +153,8 @@ void pvdisplay_colons(struct physical_volume *pv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pvdisplay_full(struct physical_volume *pv)
|
/* FIXME Include label fields */
|
||||||
|
void pvdisplay_full(struct physical_volume *pv, void *handle)
|
||||||
{
|
{
|
||||||
char uuid[64];
|
char uuid[64];
|
||||||
char *size, *size1; /*, *size2; */
|
char *size, *size1; /*, *size2; */
|
||||||
@ -104,18 +169,6 @@ void pvdisplay_full(struct physical_volume *pv)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compat */
|
|
||||||
if(!pv->pe_size) {
|
|
||||||
size = display_size((uint64_t) pv->size / 2, SIZE_SHORT);
|
|
||||||
log_print("\"%s\" is a new physical volume of %s", dev_name(pv->dev), size);
|
|
||||||
dbg_free(size);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
set_cmd_name("");
|
|
||||||
init_msg_prefix("");
|
|
||||||
|
|
||||||
/****** FIXME Do we really need this conditional here? */
|
|
||||||
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
|
log_print("--- %sPhysical volume ---", pv->pe_size ? "" : "NEW ");
|
||||||
log_print("PV Name %s", dev_name(pv->dev));
|
log_print("PV Name %s", dev_name(pv->dev));
|
||||||
log_print("VG Name %s%s", pv->vg_name,
|
log_print("VG Name %s%s", pv->vg_name,
|
||||||
@ -126,14 +179,12 @@ void pvdisplay_full(struct physical_volume *pv)
|
|||||||
size1 = display_size((pv->size - pv->pe_count * pv->pe_size)
|
size1 = display_size((pv->size - pv->pe_count * pv->pe_size)
|
||||||
/ 2, SIZE_SHORT);
|
/ 2, SIZE_SHORT);
|
||||||
|
|
||||||
/******** FIXME display LVM on-disk data size - static for now...
|
/******** FIXME display LVM on-disk data size
|
||||||
size2 = display_size(pv->size / 2, SIZE_SHORT);
|
size2 = display_size(pv->size / 2, SIZE_SHORT);
|
||||||
********/
|
********/
|
||||||
|
|
||||||
log_print("PV Size %s [%llu secs]" " / not "
|
log_print("PV Size %s" " / not usable %s", /* [LVM: %s]", */
|
||||||
"usable %s [LVM: %s]",
|
size, size1); /* , size2); */
|
||||||
size, (uint64_t) pv->size, size1, "151 KB");
|
|
||||||
/* , size2); */
|
|
||||||
|
|
||||||
dbg_free(size1);
|
dbg_free(size1);
|
||||||
/* dbg_free(size2); */
|
/* dbg_free(size2); */
|
||||||
@ -141,12 +192,9 @@ void pvdisplay_full(struct physical_volume *pv)
|
|||||||
log_print("PV Size %s", size);
|
log_print("PV Size %s", size);
|
||||||
dbg_free(size);
|
dbg_free(size);
|
||||||
|
|
||||||
/******** FIXME anytime this *isn't* available? */
|
/* PV number not part of LVM2 design
|
||||||
log_print("PV Status available");
|
|
||||||
|
|
||||||
/*********FIXME Anything use this?
|
|
||||||
log_print("PV# %u", pv->pv_number);
|
log_print("PV# %u", pv->pv_number);
|
||||||
**********/
|
*/
|
||||||
|
|
||||||
pe_free = pv->pe_count - pv->pe_alloc_count;
|
pe_free = pv->pe_count - pv->pe_alloc_count;
|
||||||
if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
|
if (pv->pe_count && (pv->status & ALLOCATABLE_PV))
|
||||||
@ -155,18 +203,13 @@ void pvdisplay_full(struct physical_volume *pv)
|
|||||||
else
|
else
|
||||||
log_print("Allocatable NO");
|
log_print("Allocatable NO");
|
||||||
|
|
||||||
/*********FIXME Erm...where is this stored?
|
/* LV count is no longer available when displaying PV
|
||||||
log_print("Cur LV %u", vg->lv_count);
|
log_print("Cur LV %u", vg->lv_count);
|
||||||
*/
|
*/
|
||||||
log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2);
|
log_print("PE Size (KByte) %" PRIu64, pv->pe_size / 2);
|
||||||
log_print("Total PE %u", pv->pe_count);
|
log_print("Total PE %u", pv->pe_count);
|
||||||
log_print("Free PE %" PRIu64, pe_free);
|
log_print("Free PE %" PRIu64, pe_free);
|
||||||
log_print("Allocated PE %u", pv->pe_alloc_count);
|
log_print("Allocated PE %u", pv->pe_alloc_count);
|
||||||
|
|
||||||
#ifdef LVM_FUTURE
|
|
||||||
printf("Stale PE %u", pv->pe_stale);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
log_print("PV UUID %s", *uuid ? uuid : "none");
|
log_print("PV UUID %s", *uuid ? uuid : "none");
|
||||||
log_print(" ");
|
log_print(" ");
|
||||||
|
|
||||||
@ -174,7 +217,7 @@ void pvdisplay_full(struct physical_volume *pv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
|
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
struct physical_volume *pv)
|
struct physical_volume *pv, void *handle)
|
||||||
{
|
{
|
||||||
if (!pv)
|
if (!pv)
|
||||||
return 0;
|
return 0;
|
||||||
@ -190,8 +233,6 @@ int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lvdisplay_colons(struct logical_volume *lv)
|
void lvdisplay_colons(struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
int inkernel;
|
int inkernel;
|
||||||
@ -207,59 +248,21 @@ void lvdisplay_colons(struct logical_volume *lv)
|
|||||||
/* FIXME lv->lv_number, */
|
/* FIXME lv->lv_number, */
|
||||||
inkernel ? info.open_count : 0, lv->size, lv->le_count,
|
inkernel ? info.open_count : 0, lv->size, lv->le_count,
|
||||||
/* FIXME Add num allocated to struct! lv->lv_allocated_le, */
|
/* FIXME Add num allocated to struct! lv->lv_allocated_le, */
|
||||||
((lv->alloc == ALLOC_STRICT) +
|
(lv->alloc == ALLOC_CONTIGUOUS ? 2 : 0), lv->read_ahead,
|
||||||
(lv->alloc == ALLOC_CONTIGUOUS) * 2), lv->read_ahead,
|
|
||||||
inkernel ? info.major : -1, inkernel ? info.minor : -1);
|
inkernel ? info.major : -1, inkernel ? info.minor : -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
static struct {
|
void *handle)
|
||||||
alloc_policy_t alloc;
|
|
||||||
const char *str;
|
|
||||||
} _policies[] = {
|
|
||||||
{ALLOC_NEXT_FREE, "next free"},
|
|
||||||
{ALLOC_STRICT, "strict"},
|
|
||||||
{ALLOC_CONTIGUOUS, "contiguous"}
|
|
||||||
};
|
|
||||||
|
|
||||||
static int _num_policies = sizeof(_policies) / sizeof(*_policies);
|
|
||||||
|
|
||||||
const char *get_alloc_string(alloc_policy_t alloc)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < _num_policies; i++)
|
|
||||||
if (_policies[i].alloc == alloc)
|
|
||||||
return _policies[i].str;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
alloc_policy_t get_alloc_from_string(const char *str)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < _num_policies; i++)
|
|
||||||
if (!strcmp(_policies[i].str, str))
|
|
||||||
return _policies[i].alloc;
|
|
||||||
|
|
||||||
log_warn("Unknown allocation policy, defaulting to next free");
|
|
||||||
return ALLOC_NEXT_FREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|
||||||
{
|
{
|
||||||
char *size;
|
char *size;
|
||||||
struct dm_info info;
|
struct dm_info info;
|
||||||
int inkernel;
|
int inkernel, snap_active;
|
||||||
char uuid[64];
|
char uuid[64];
|
||||||
struct snapshot *snap;
|
struct snapshot *snap = NULL;
|
||||||
struct stripe_segment *seg;
|
struct list *slh, *snaplist;
|
||||||
struct list *lvseg;
|
float snap_percent; /* fused, fsize; */
|
||||||
struct logical_volume *origin;
|
|
||||||
float snap_percent;
|
|
||||||
int snap_active;
|
|
||||||
|
|
||||||
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
|
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid))) {
|
||||||
stack;
|
stack;
|
||||||
@ -268,26 +271,21 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
|
|
||||||
inkernel = lv_info(lv, &info) && info.exists;
|
inkernel = lv_info(lv, &info) && info.exists;
|
||||||
|
|
||||||
set_cmd_name("");
|
|
||||||
init_msg_prefix("");
|
|
||||||
|
|
||||||
log_print("--- Logical volume ---");
|
log_print("--- Logical volume ---");
|
||||||
|
|
||||||
log_print("LV Name %s%s/%s", lv->vg->cmd->dev_dir,
|
log_print("LV Name %s%s/%s", lv->vg->cmd->dev_dir,
|
||||||
lv->vg->name, lv->name);
|
lv->vg->name, lv->name);
|
||||||
log_print("VG Name %s", lv->vg->name);
|
log_print("VG Name %s", lv->vg->name);
|
||||||
|
|
||||||
/* Not in LVM1 format
|
|
||||||
log_print("LV UUID %s", uuid);
|
log_print("LV UUID %s", uuid);
|
||||||
**/
|
|
||||||
log_print("LV Write Access %s",
|
log_print("LV Write Access %s",
|
||||||
(lv->status & LVM_WRITE) ? "read/write" : "read only");
|
(lv->status & LVM_WRITE) ? "read/write" : "read only");
|
||||||
|
|
||||||
/* see if this LV is an origin for a snapshot */
|
if (lv_is_origin(lv)) {
|
||||||
if ((snap = find_origin(lv))) {
|
|
||||||
struct list *slh, *snaplist = find_snapshots(lv);
|
|
||||||
|
|
||||||
log_print("LV snapshot status source of");
|
log_print("LV snapshot status source of");
|
||||||
|
|
||||||
|
snaplist = find_snapshots(lv);
|
||||||
list_iterate(slh, snaplist) {
|
list_iterate(slh, snaplist) {
|
||||||
snap = list_item(slh, struct snapshot_list)->snapshot;
|
snap = list_item(slh, struct snapshot_list)->snapshot;
|
||||||
snap_active = lv_snapshot_percent(snap->cow,
|
snap_active = lv_snapshot_percent(snap->cow,
|
||||||
@ -297,13 +295,7 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
snap->cow->name,
|
snap->cow->name,
|
||||||
(snap_active > 0) ? "active" : "INACTIVE");
|
(snap_active > 0) ? "active" : "INACTIVE");
|
||||||
}
|
}
|
||||||
/* reset so we don't try to use this to display other snapshot
|
} else if ((snap = find_cow(lv))) {
|
||||||
* related information. */
|
|
||||||
snap = NULL;
|
|
||||||
snap_active = 0;
|
|
||||||
}
|
|
||||||
/* Check to see if this LV is a COW target for a snapshot */
|
|
||||||
else if ((snap = find_cow(lv))) {
|
|
||||||
snap_active = lv_snapshot_percent(lv, &snap_percent);
|
snap_active = lv_snapshot_percent(lv, &snap_percent);
|
||||||
log_print("LV snapshot status %s destination for %s%s/%s",
|
log_print("LV snapshot status %s destination for %s%s/%s",
|
||||||
(snap_active > 0) ? "active" : "INACTIVE",
|
(snap_active > 0) ? "active" : "INACTIVE",
|
||||||
@ -311,102 +303,61 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
snap->origin->name);
|
snap->origin->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (inkernel && info.suspended)
|
if (inkernel && info.suspended)
|
||||||
log_print("LV Status suspended");
|
log_print("LV Status suspended");
|
||||||
else
|
else
|
||||||
log_print("LV Status %savailable",
|
log_print("LV Status %savailable",
|
||||||
!inkernel || (snap && (snap_active < 1))
|
inkernel ? "" : "NOT ");
|
||||||
? "NOT " : "");
|
|
||||||
|
|
||||||
/********* FIXME lv_number - not sure that we're going to bother with this
|
/********* FIXME lv_number
|
||||||
log_print("LV # %u", lv->lv_number + 1);
|
log_print("LV # %u", lv->lv_number + 1);
|
||||||
************/
|
************/
|
||||||
|
|
||||||
/* LVM1 lists the number of LVs open in this field, therefore, so do we. */
|
|
||||||
log_print("# open %u", lvs_in_vg_opened(lv->vg));
|
|
||||||
|
|
||||||
/* We're not going to use this count ATM, 'cause it's not what LVM1 does
|
|
||||||
if (inkernel)
|
if (inkernel)
|
||||||
log_print("# open %u", info.open_count);
|
log_print("# open %u", info.open_count);
|
||||||
*/
|
|
||||||
/********
|
|
||||||
#ifdef LVM_FUTURE
|
|
||||||
printf("Mirror copies %u\n", lv->lv_mirror_copies);
|
|
||||||
printf("Consistency recovery ");
|
|
||||||
if (lv->lv_recovery | LV_BADBLOCK_ON)
|
|
||||||
printf("bad blocks\n");
|
|
||||||
else
|
|
||||||
printf("none\n");
|
|
||||||
printf("Schedule %u\n", lv->lv_schedule);
|
|
||||||
#endif
|
|
||||||
********/
|
|
||||||
|
|
||||||
if(snap)
|
size = display_size(snap ? snap->origin->size / 2 : lv->size / 2,
|
||||||
origin = snap->origin;
|
SIZE_SHORT);
|
||||||
else
|
|
||||||
origin = lv;
|
|
||||||
|
|
||||||
size = display_size(origin->size / 2, SIZE_SHORT);
|
|
||||||
log_print("LV Size %s", size);
|
log_print("LV Size %s", size);
|
||||||
dbg_free(size);
|
dbg_free(size);
|
||||||
|
|
||||||
log_print("Current LE %u", origin->le_count);
|
log_print("Current LE %u",
|
||||||
|
snap ? snap->origin->le_count : lv->le_count);
|
||||||
|
|
||||||
/********** FIXME allocation - is there anytime the allocated LEs will not
|
/********** FIXME allocation
|
||||||
* equal the current LEs? */
|
log_print("Allocated LE %u", lv->allocated_le);
|
||||||
log_print("Allocated LE %u", origin->le_count);
|
**********/
|
||||||
/**********/
|
|
||||||
|
|
||||||
|
|
||||||
list_iterate(lvseg, &lv->segments) {
|
|
||||||
seg = list_item(lvseg, struct stripe_segment);
|
|
||||||
if(seg->stripes > 1) {
|
|
||||||
log_print("Stripes %u", seg->stripes);
|
|
||||||
log_print("Stripe size (KByte) %u",
|
|
||||||
seg->stripe_size/2);
|
|
||||||
}
|
|
||||||
/* only want the first segment for LVM1 format output */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(snap) {
|
|
||||||
float fused, fsize;
|
|
||||||
if(snap_percent == -1)
|
|
||||||
snap_percent=100;
|
|
||||||
|
|
||||||
size = display_size(snap->chunk_size / 2, SIZE_SHORT);
|
|
||||||
log_print("snapshot chunk size %s", size);
|
|
||||||
dbg_free(size);
|
|
||||||
|
|
||||||
size = display_size(lv->size / 2, SIZE_SHORT);
|
|
||||||
sscanf(size, "%f", &fsize);
|
|
||||||
fused = fsize * ( snap_percent / 100 );
|
|
||||||
log_print("Allocated to snapshot %2.2f%% [%2.2f/%s]",
|
|
||||||
snap_percent, fused, size);
|
|
||||||
dbg_free(size);
|
|
||||||
|
|
||||||
/* FIXME: Think this'll make them wonder?? */
|
|
||||||
log_print("Allocated to COW-table %s", "00.01 KB");
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Not in LVM1 format output **
|
|
||||||
log_print("Segments %u", list_size(&lv->segments));
|
log_print("Segments %u", list_size(&lv->segments));
|
||||||
***/
|
|
||||||
|
|
||||||
/********* FIXME Stripes & stripesize for each segment
|
/********* FIXME Stripes & stripesize for each segment
|
||||||
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
|
log_print("Stripe size (KByte) %u", lv->stripesize / 2);
|
||||||
***********/
|
***********/
|
||||||
|
|
||||||
/**************
|
if (snap) {
|
||||||
#ifdef LVM_FUTURE
|
if (snap_percent == -1)
|
||||||
printf("Bad block ");
|
snap_percent = 100;
|
||||||
if (lv->lv_badblock == LV_BADBLOCK_ON)
|
|
||||||
printf("on\n");
|
size = display_size(snap->chunk_size / 2, SIZE_SHORT);
|
||||||
else
|
log_print("Snapshot chunk size %s", size);
|
||||||
printf("off\n");
|
dbg_free(size);
|
||||||
#endif
|
|
||||||
***************/
|
/*
|
||||||
|
size = display_size(lv->size / 2, SIZE_SHORT);
|
||||||
|
sscanf(size, "%f", &fsize);
|
||||||
|
fused = fsize * snap_percent / 100;
|
||||||
|
*/
|
||||||
|
log_print("Allocated to snapshot %.2f%% ", /* [%.2f/%s]", */
|
||||||
|
snap_percent); /*, fused, size); */
|
||||||
|
/* dbg_free(size); */
|
||||||
|
}
|
||||||
|
|
||||||
|
/********** FIXME Snapshot
|
||||||
|
size = ???
|
||||||
|
log_print("Allocated to COW-table %s", size);
|
||||||
|
dbg_free(size);
|
||||||
|
}
|
||||||
|
******************/
|
||||||
|
|
||||||
log_print("Allocation %s", get_alloc_string(lv->alloc));
|
log_print("Allocation %s", get_alloc_string(lv->alloc));
|
||||||
log_print("Read ahead sectors %u", lv->read_ahead);
|
log_print("Read ahead sectors %u", lv->read_ahead);
|
||||||
@ -414,16 +365,6 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
if (lv->status & FIXED_MINOR)
|
if (lv->status & FIXED_MINOR)
|
||||||
log_print("Persistent minor %d", lv->minor);
|
log_print("Persistent minor %d", lv->minor);
|
||||||
|
|
||||||
/****************
|
|
||||||
#ifdef LVM_FUTURE
|
|
||||||
printf("IO Timeout (seconds) ");
|
|
||||||
if (lv->lv_io_timeout == 0)
|
|
||||||
printf("default\n\n");
|
|
||||||
else
|
|
||||||
printf("%lu\n\n", lv->lv_io_timeout);
|
|
||||||
#endif
|
|
||||||
*************/
|
|
||||||
|
|
||||||
if (inkernel)
|
if (inkernel)
|
||||||
log_print("Block device %d:%d", info.major,
|
log_print("Block device %d:%d", info.major,
|
||||||
info.minor);
|
info.minor);
|
||||||
@ -433,15 +374,15 @@ int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _display_stripe(struct stripe_segment *seg, int s, const char *pre)
|
void _display_stripe(struct lv_segment *seg, int s, const char *pre)
|
||||||
{
|
{
|
||||||
uint32_t len = seg->len / seg->stripes;
|
uint32_t len = seg->len / seg->stripes;
|
||||||
|
|
||||||
log_print("%sphysical volume\t%s", pre,
|
log_print("%sPhysical volume\t%s", pre,
|
||||||
seg->area[s].pv ? dev_name(seg->area[s].pv->dev) : "Missing");
|
seg->area[s].pv ? dev_name(seg->area[s].pv->dev) : "Missing");
|
||||||
|
|
||||||
if (seg->area[s].pv)
|
if (seg->area[s].pv)
|
||||||
log_print("%sphysical extents\t%d to %d", pre,
|
log_print("%sPhysical extents\t%d to %d", pre,
|
||||||
seg->area[s].pe, seg->area[s].pe + len - 1);
|
seg->area[s].pe, seg->area[s].pe + len - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,29 +390,38 @@ int lvdisplay_segments(struct logical_volume *lv)
|
|||||||
{
|
{
|
||||||
int s;
|
int s;
|
||||||
struct list *segh;
|
struct list *segh;
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
|
|
||||||
log_print("--- Segments ---");
|
log_print("--- Segments ---");
|
||||||
|
|
||||||
list_iterate(segh, &lv->segments) {
|
list_iterate(segh, &lv->segments) {
|
||||||
seg = list_item(segh, struct stripe_segment);
|
seg = list_item(segh, struct lv_segment);
|
||||||
|
|
||||||
log_print("logical extent %d to %d:",
|
log_print("Logical extent %d to %d:",
|
||||||
seg->le, seg->le + seg->len - 1);
|
seg->le, seg->le + seg->len - 1);
|
||||||
|
|
||||||
|
log_print(" Type\t\t%s", get_segtype_string(seg->type));
|
||||||
|
|
||||||
|
switch (seg->type) {
|
||||||
|
case SEG_STRIPED:
|
||||||
if (seg->stripes == 1)
|
if (seg->stripes == 1)
|
||||||
_display_stripe(seg, 0, " ");
|
_display_stripe(seg, 0, " ");
|
||||||
|
|
||||||
else {
|
else {
|
||||||
log_print(" stripes\t\t%d", seg->stripes);
|
log_print(" Stripes\t\t%d", seg->stripes);
|
||||||
log_print(" stripe size\t\t%d", seg->stripe_size);
|
log_print(" Stripe size\t\t%d",
|
||||||
|
seg->stripe_size);
|
||||||
|
|
||||||
for (s = 0; s < seg->stripes; s++) {
|
for (s = 0; s < seg->stripes; s++) {
|
||||||
log_print(" stripe %d:", s);
|
log_print(" Stripe %d:", s);
|
||||||
_display_stripe(seg, s, " ");
|
_display_stripe(seg, s, " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
log_print(" ");
|
log_print(" ");
|
||||||
|
break;
|
||||||
|
case SEG_SNAPSHOT:
|
||||||
|
case SEG_MIRROR:
|
||||||
|
;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log_print(" ");
|
log_print(" ");
|
||||||
@ -486,29 +436,24 @@ void vgdisplay_extents(struct volume_group *vg)
|
|||||||
void vgdisplay_full(struct volume_group *vg)
|
void vgdisplay_full(struct volume_group *vg)
|
||||||
{
|
{
|
||||||
uint32_t access;
|
uint32_t access;
|
||||||
|
uint32_t active_pvs;
|
||||||
char *s1;
|
char *s1;
|
||||||
char uuid[64];
|
char uuid[64];
|
||||||
uint32_t active_pvs;
|
|
||||||
struct list *pvlist;
|
|
||||||
|
|
||||||
set_cmd_name("");
|
if (vg->status & PARTIAL_VG)
|
||||||
init_msg_prefix("");
|
active_pvs = list_size(&vg->pvs);
|
||||||
|
|
||||||
/* get the number of active PVs */
|
|
||||||
if(vg->status & PARTIAL_VG) {
|
|
||||||
active_pvs=0;
|
|
||||||
list_iterate(pvlist, &(vg->pvs)) {
|
|
||||||
active_pvs++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
active_pvs = vg->pv_count;
|
active_pvs = vg->pv_count;
|
||||||
|
|
||||||
log_print("--- Volume group ---");
|
log_print("--- Volume group ---");
|
||||||
log_print("VG Name %s", vg->name);
|
log_print("VG Name %s", vg->name);
|
||||||
/****** Not in LVM1 output, so we aren't outputing it here:
|
|
||||||
log_print("System ID %s", vg->system_id);
|
log_print("System ID %s", vg->system_id);
|
||||||
*******/
|
log_print("Format %s", vg->fid->fmt->name);
|
||||||
|
if (vg->fid->fmt->features & FMT_MDAS) {
|
||||||
|
log_print("Metadata Areas %d",
|
||||||
|
list_size(&vg->fid->metadata_areas));
|
||||||
|
log_print("Metadata Sequence No %d", vg->seqno);
|
||||||
|
}
|
||||||
access = vg->status & (LVM_READ | LVM_WRITE);
|
access = vg->status & (LVM_READ | LVM_WRITE);
|
||||||
log_print("VG Access %s%s%s%s",
|
log_print("VG Access %s%s%s%s",
|
||||||
access == (LVM_READ | LVM_WRITE) ? "read/write" : "",
|
access == (LVM_READ | LVM_WRITE) ? "read/write" : "",
|
||||||
@ -516,27 +461,29 @@ void vgdisplay_full(struct volume_group *vg)
|
|||||||
access == LVM_WRITE ? "write" : "",
|
access == LVM_WRITE ? "write" : "",
|
||||||
access == 0 ? "error" : "");
|
access == 0 ? "error" : "");
|
||||||
log_print("VG Status %s%sresizable",
|
log_print("VG Status %s%sresizable",
|
||||||
vg->status & EXPORTED_VG ? "exported/" : "available/",
|
vg->status & EXPORTED_VG ? "exported/" : "",
|
||||||
vg->status & RESIZEABLE_VG ? "" : "NOT ");
|
vg->status & RESIZEABLE_VG ? "" : "NOT ");
|
||||||
|
/* vg number not part of LVM2 design
|
||||||
|
log_print ("VG # %u\n", vg->vg_number);
|
||||||
|
*/
|
||||||
if (vg->status & CLUSTERED) {
|
if (vg->status & CLUSTERED) {
|
||||||
log_print("Clustered yes");
|
log_print("Clustered yes");
|
||||||
log_print("Shared %s",
|
log_print("Shared %s",
|
||||||
vg->status & SHARED ? "yes" : "no");
|
vg->status & SHARED ? "yes" : "no");
|
||||||
}
|
}
|
||||||
/****** FIXME VG # - we aren't implementing this because people should
|
|
||||||
* use the UUID for this anyway
|
|
||||||
log_print("VG # %u", vg->vg_number);
|
|
||||||
*******/
|
|
||||||
log_print("MAX LV %u", vg->max_lv);
|
log_print("MAX LV %u", vg->max_lv);
|
||||||
log_print("Cur LV %u", vg->lv_count);
|
log_print("Cur LV %u", vg->lv_count);
|
||||||
log_print("Open LV %u", lvs_in_vg_opened(vg));
|
log_print("Open LV %u", lvs_in_vg_opened(vg));
|
||||||
log_print("MAX LV Size 256 TB");
|
/****** FIXME Max LV Size
|
||||||
|
log_print ( "MAX LV Size %s",
|
||||||
|
( s1 = display_size ( LVM_LV_SIZE_MAX(vg) / 2, SIZE_SHORT)));
|
||||||
|
free ( s1);
|
||||||
|
*********/
|
||||||
log_print("Max PV %u", vg->max_pv);
|
log_print("Max PV %u", vg->max_pv);
|
||||||
log_print("Cur PV %u", vg->pv_count);
|
log_print("Cur PV %u", vg->pv_count);
|
||||||
log_print("Act PV %u", active_pvs);
|
log_print("Act PV %u", active_pvs);
|
||||||
|
|
||||||
s1 =
|
s1 = display_size((uint64_t) vg->extent_count * (vg->extent_size / 2),
|
||||||
display_size((uint64_t) vg->extent_count * (vg->extent_size / 2),
|
|
||||||
SIZE_SHORT);
|
SIZE_SHORT);
|
||||||
log_print("VG Size %s", s1);
|
log_print("VG Size %s", s1);
|
||||||
dbg_free(s1);
|
dbg_free(s1);
|
||||||
@ -554,8 +501,7 @@ void vgdisplay_full(struct volume_group *vg)
|
|||||||
vg->extent_count - vg->free_count, s1);
|
vg->extent_count - vg->free_count, s1);
|
||||||
dbg_free(s1);
|
dbg_free(s1);
|
||||||
|
|
||||||
s1 =
|
s1 = display_size((uint64_t) vg->free_count * (vg->extent_size / 2),
|
||||||
display_size((uint64_t) vg->free_count * (vg->extent_size / 2),
|
|
||||||
SIZE_SHORT);
|
SIZE_SHORT);
|
||||||
log_print("Free PE / Size %u / %s", vg->free_count, s1);
|
log_print("Free PE / Size %u / %s", vg->free_count, s1);
|
||||||
dbg_free(s1);
|
dbg_free(s1);
|
||||||
@ -580,9 +526,8 @@ void vgdisplay_short(struct volume_group *vg)
|
|||||||
{
|
{
|
||||||
char *s1, *s2, *s3;
|
char *s1, *s2, *s3;
|
||||||
s1 = display_size(vg->extent_count * vg->extent_size / 2, SIZE_SHORT);
|
s1 = display_size(vg->extent_count * vg->extent_size / 2, SIZE_SHORT);
|
||||||
s2 =
|
s2 = display_size((vg->extent_count -
|
||||||
display_size((vg->extent_count - vg->free_count) * vg->extent_size /
|
vg->free_count) * vg->extent_size / 2, SIZE_SHORT);
|
||||||
2, SIZE_SHORT);
|
|
||||||
s3 = display_size(vg->free_count * vg->extent_size / 2, SIZE_SHORT);
|
s3 = display_size(vg->free_count * vg->extent_size / 2, SIZE_SHORT);
|
||||||
log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
|
log_print("\"%s\" %-9s [%-9s used / %s free]", vg->name,
|
||||||
/********* FIXME if "open" print "/used" else print "/idle"??? ******/
|
/********* FIXME if "open" print "/used" else print "/idle"??? ******/
|
||||||
|
@ -32,12 +32,14 @@ char *display_size(uint64_t size, size_len_t sl);
|
|||||||
char *display_uuid(char *uuidstr);
|
char *display_uuid(char *uuidstr);
|
||||||
|
|
||||||
void pvdisplay_colons(struct physical_volume *pv);
|
void pvdisplay_colons(struct physical_volume *pv);
|
||||||
void pvdisplay_full(struct physical_volume *pv);
|
void pvdisplay_full(struct physical_volume *pv, void *handle);
|
||||||
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg, struct physical_volume *pv);
|
int pvdisplay_short(struct cmd_context *cmd, struct volume_group *vg,
|
||||||
|
struct physical_volume *pv, void *handle);
|
||||||
|
|
||||||
void lvdisplay_colons(struct logical_volume *lv);
|
void lvdisplay_colons(struct logical_volume *lv);
|
||||||
int lvdisplay_segments(struct logical_volume *lv);
|
int lvdisplay_segments(struct logical_volume *lv);
|
||||||
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv);
|
int lvdisplay_full(struct cmd_context *cmd, struct logical_volume *lv,
|
||||||
|
void *handle);
|
||||||
|
|
||||||
void vgdisplay_extents(struct volume_group *vg);
|
void vgdisplay_extents(struct volume_group *vg);
|
||||||
void vgdisplay_full(struct volume_group *vg);
|
void vgdisplay_full(struct volume_group *vg);
|
||||||
@ -45,14 +47,15 @@ void vgdisplay_colons(struct volume_group *vg);
|
|||||||
void vgdisplay_short(struct volume_group *vg);
|
void vgdisplay_short(struct volume_group *vg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Retrieve a text description of the allocation policy. Only
|
* Allocation policy display conversion routines.
|
||||||
* extern because it's used by lvscan.
|
|
||||||
*/
|
*/
|
||||||
const char *get_alloc_string(alloc_policy_t alloc);
|
const char *get_alloc_string(alloc_policy_t alloc);
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: put this somewhere more sensible.
|
|
||||||
*/
|
|
||||||
alloc_policy_t get_alloc_from_string(const char *str);
|
alloc_policy_t get_alloc_from_string(const char *str);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Segment type display conversion routines.
|
||||||
|
*/
|
||||||
|
segment_type_t get_segtype_from_string(const char *str);
|
||||||
|
const char *get_segtype_string(segment_type_t segtype);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "filter-composite.h"
|
#include "filter-composite.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
@ -4,14 +4,12 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dev-cache.h"
|
#include "dev-cache.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "filter-persistent.h"
|
#include "filter-persistent.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -43,10 +41,13 @@ int persistent_filter_wipe(struct dev_filter *f)
|
|||||||
struct pfilter *pf = (struct pfilter *) f->private;
|
struct pfilter *pf = (struct pfilter *) f->private;
|
||||||
|
|
||||||
hash_wipe(pf->devices);
|
hash_wipe(pf->devices);
|
||||||
|
/* Trigger complete device scan */
|
||||||
|
dev_cache_scan(1);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _read_array(struct pfilter *pf, struct config_file *cf,
|
static int _read_array(struct pfilter *pf, struct config_tree *cf,
|
||||||
const char *path, void *data)
|
const char *path, void *data)
|
||||||
{
|
{
|
||||||
struct config_node *cn;
|
struct config_node *cn;
|
||||||
@ -72,6 +73,8 @@ static int _read_array(struct pfilter *pf, struct config_file *cf,
|
|||||||
if (!hash_insert(pf->devices, cv->v.str, data))
|
if (!hash_insert(pf->devices, cv->v.str, data))
|
||||||
log_verbose("Couldn't add '%s' to filter ... ignoring",
|
log_verbose("Couldn't add '%s' to filter ... ignoring",
|
||||||
cv->v.str);
|
cv->v.str);
|
||||||
|
/* Populate dev_cache ourselves */
|
||||||
|
dev_cache_get(cv->v.str, NULL);
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -81,28 +84,33 @@ int persistent_filter_load(struct dev_filter *f)
|
|||||||
struct pfilter *pf = (struct pfilter *) f->private;
|
struct pfilter *pf = (struct pfilter *) f->private;
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
struct config_file *cf;
|
struct config_tree *cf;
|
||||||
|
|
||||||
if (!(cf = create_config_file())) {
|
if (!(cf = create_config_tree())) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!read_config(cf, pf->file)) {
|
if (!read_config_file(cf, pf->file)) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
_read_array(pf, cf, "persistent_filter_cache/valid_devices",
|
_read_array(pf, cf, "persistent_filter_cache/valid_devices",
|
||||||
PF_GOOD_DEVICE);
|
PF_GOOD_DEVICE);
|
||||||
_read_array(pf, cf, "persistent_filter_cache/invalid_devices",
|
/* We don't gain anything by holding invalid devices */
|
||||||
PF_BAD_DEVICE);
|
/* _read_array(pf, cf, "persistent_filter_cache/invalid_devices",
|
||||||
|
PF_BAD_DEVICE); */
|
||||||
|
|
||||||
if (hash_get_num_entries(pf->devices))
|
/* Did we find anything? */
|
||||||
|
if (hash_get_num_entries(pf->devices)) {
|
||||||
|
/* We populated dev_cache ourselves */
|
||||||
|
dev_cache_scan(0);
|
||||||
r = 1;
|
r = 1;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
destroy_config_file(cf);
|
destroy_config_tree(cf);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,6 +155,12 @@ int persistent_filter_dump(struct dev_filter *f)
|
|||||||
"- not writing to %s", pf->file);
|
"- not writing to %s", pf->file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (!dev_cache_has_scanned()) {
|
||||||
|
log_very_verbose("Device cache incomplete - not writing "
|
||||||
|
"to %s", pf->file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
log_very_verbose("Dumping persistent device cache to %s", pf->file);
|
log_very_verbose("Dumping persistent device cache to %s", pf->file);
|
||||||
|
|
||||||
fp = fopen(pf->file, "w");
|
fp = fopen(pf->file, "w");
|
||||||
@ -160,7 +174,8 @@ int persistent_filter_dump(struct dev_filter *f)
|
|||||||
fprintf(fp, "persistent_filter_cache {\n");
|
fprintf(fp, "persistent_filter_cache {\n");
|
||||||
|
|
||||||
_write_array(pf, fp, "valid_devices", PF_GOOD_DEVICE);
|
_write_array(pf, fp, "valid_devices", PF_GOOD_DEVICE);
|
||||||
_write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE);
|
/* We don't gain anything by remembering invalid devices */
|
||||||
|
/* _write_array(pf, fp, "invalid_devices", PF_BAD_DEVICE); */
|
||||||
|
|
||||||
fprintf(fp, "}\n");
|
fprintf(fp, "}\n");
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "filter-regex.h"
|
#include "filter-regex.h"
|
||||||
#include "matcher.h"
|
#include "matcher.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
#include "bitset.h"
|
#include "bitset.h"
|
||||||
#include "log.h"
|
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
struct rfilter {
|
struct rfilter {
|
||||||
|
@ -18,18 +18,14 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dbg_malloc.h"
|
#include "lib.h"
|
||||||
#include "log.h"
|
|
||||||
#include "dev-cache.h"
|
#include "dev-cache.h"
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
@ -43,6 +39,7 @@ typedef struct {
|
|||||||
|
|
||||||
static int _md_major = -1;
|
static int _md_major = -1;
|
||||||
|
|
||||||
|
/* FIXME Move list into config file */
|
||||||
static device_info_t device_info[] = {
|
static device_info_t device_info[] = {
|
||||||
{"ide", 16}, /* IDE disk */
|
{"ide", 16}, /* IDE disk */
|
||||||
{"sd", 16}, /* SCSI disk */
|
{"sd", 16}, /* SCSI disk */
|
||||||
|
7
lib/format1/.export.sym
Normal file
7
lib/format1/.export.sym
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
global:
|
||||||
|
init_format;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
||||||
|
|
31
lib/format1/Makefile.in
Normal file
31
lib/format1/Makefile.in
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
#
|
||||||
|
# This file is released under the LGPL.
|
||||||
|
#
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
|
||||||
|
SOURCES=\
|
||||||
|
disk-rep.c \
|
||||||
|
format1.c \
|
||||||
|
import-export.c \
|
||||||
|
import-extents.c \
|
||||||
|
layout.c \
|
||||||
|
lvm1-label.c \
|
||||||
|
vg_number.c
|
||||||
|
|
||||||
|
TARGETS=liblvm2format1.so
|
||||||
|
|
||||||
|
include ../../make.tmpl
|
||||||
|
|
||||||
|
|
||||||
|
install: libformat1.so
|
||||||
|
$(INSTALL) -D -o $(OWNER) -g $(GROUP) -m 555 $(STRIP) $< \
|
||||||
|
$(libdir)/liblvm2format1.so.$(LIB_VERSION)
|
||||||
|
$(LN_S) -f liblvm2format1.so.$(LIB_VERSION) $(libdir)/liblvm2format1.so
|
||||||
|
|
||||||
|
.PHONY: install
|
||||||
|
|
@ -4,15 +4,13 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "xlate.h"
|
#include "xlate.h"
|
||||||
#include "log.h"
|
|
||||||
#include "vgcache.h"
|
|
||||||
#include "filter.h"
|
#include "filter.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <linux/kdev_t.h>
|
#include <linux/kdev_t.h>
|
||||||
@ -116,12 +114,12 @@ static int _munge_formats(struct pv_disk *pvd)
|
|||||||
switch (pvd->version) {
|
switch (pvd->version) {
|
||||||
case 1:
|
case 1:
|
||||||
pvd->pe_start = ((pvd->pe_on_disk.base +
|
pvd->pe_start = ((pvd->pe_on_disk.base +
|
||||||
pvd->pe_on_disk.size) / SECTOR_SIZE);
|
pvd->pe_on_disk.size) >> SECTOR_SHIFT);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
pvd->version = 1;
|
pvd->version = 1;
|
||||||
pe_start = pvd->pe_start * SECTOR_SIZE;
|
pe_start = pvd->pe_start << SECTOR_SHIFT;
|
||||||
pvd->pe_on_disk.size = pe_start - pvd->pe_on_disk.base;
|
pvd->pe_on_disk.size = pe_start - pvd->pe_on_disk.base;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -132,7 +130,7 @@ static int _munge_formats(struct pv_disk *pvd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read_pvd(struct device *dev, struct pv_disk *pvd)
|
static int _read_pvd(struct device *dev, struct pv_disk *pvd)
|
||||||
{
|
{
|
||||||
if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) {
|
if (dev_read(dev, 0, sizeof(*pvd), pvd) != sizeof(*pvd)) {
|
||||||
log_very_verbose("Failed to read PV data from %s",
|
log_very_verbose("Failed to read PV data from %s",
|
||||||
@ -143,14 +141,14 @@ int read_pvd(struct device *dev, struct pv_disk *pvd)
|
|||||||
_xlate_pvd(pvd);
|
_xlate_pvd(pvd);
|
||||||
|
|
||||||
if (pvd->id[0] != 'H' || pvd->id[1] != 'M') {
|
if (pvd->id[0] != 'H' || pvd->id[1] != 'M') {
|
||||||
log_very_verbose("%s does not have a valid PV identifier",
|
log_very_verbose("%s does not have a valid LVM1 PV identifier",
|
||||||
dev_name(dev));
|
dev_name(dev));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_munge_formats(pvd)) {
|
if (!_munge_formats(pvd)) {
|
||||||
log_very_verbose("Unknown metadata version %d found on %s",
|
log_very_verbose("format1: Unknown metadata version %d "
|
||||||
pvd->version, dev_name(dev));
|
"found on %s", pvd->version, dev_name(dev));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,6 +280,7 @@ static struct disk_list *__read_disk(struct format_type *fmt,
|
|||||||
{
|
{
|
||||||
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
|
struct disk_list *dl = pool_alloc(mem, sizeof(*dl));
|
||||||
const char *name = dev_name(dev);
|
const char *name = dev_name(dev);
|
||||||
|
struct cache_info *info;
|
||||||
|
|
||||||
if (!dl) {
|
if (!dl) {
|
||||||
stack;
|
stack;
|
||||||
@ -293,11 +292,20 @@ static struct disk_list *__read_disk(struct format_type *fmt,
|
|||||||
list_init(&dl->uuids);
|
list_init(&dl->uuids);
|
||||||
list_init(&dl->lvds);
|
list_init(&dl->lvds);
|
||||||
|
|
||||||
if (!read_pvd(dev, &dl->pvd)) {
|
if (!_read_pvd(dev, &dl->pvd)) {
|
||||||
stack;
|
stack;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!(info = cache_add(fmt->labeller, dl->pvd.pv_uuid, dev,
|
||||||
|
dl->pvd.vg_name, NULL)))
|
||||||
|
stack;
|
||||||
|
else {
|
||||||
|
info->device_size = xlate32(dl->pvd.pv_size) << SECTOR_SHIFT;
|
||||||
|
list_init(&info->mdas);
|
||||||
|
info->status &= ~CACHE_INVALID;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* is it an orphan ?
|
* is it an orphan ?
|
||||||
*/
|
*/
|
||||||
@ -305,7 +313,7 @@ static struct disk_list *__read_disk(struct format_type *fmt,
|
|||||||
log_very_verbose("%s is not a member of any format1 VG", name);
|
log_very_verbose("%s is not a member of any format1 VG", name);
|
||||||
|
|
||||||
/* Update VG cache */
|
/* Update VG cache */
|
||||||
vgcache_add(dl->pvd.vg_name, NULL, dev, fmt);
|
/* vgcache_add(dl->pvd.vg_name, NULL, dev, fmt); */
|
||||||
|
|
||||||
return (vg_name) ? NULL : dl;
|
return (vg_name) ? NULL : dl;
|
||||||
}
|
}
|
||||||
@ -319,7 +327,7 @@ static struct disk_list *__read_disk(struct format_type *fmt,
|
|||||||
_munge_exported_vg(dl);
|
_munge_exported_vg(dl);
|
||||||
|
|
||||||
/* Update VG cache with what we found */
|
/* Update VG cache with what we found */
|
||||||
vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt);
|
/* vgcache_add(dl->pvd.vg_name, dl->vgd.vg_uuid, dev, fmt); */
|
||||||
|
|
||||||
if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) {
|
if (vg_name && strcmp(vg_name, dl->pvd.vg_name)) {
|
||||||
log_very_verbose("%s is not a member of the VG %s",
|
log_very_verbose("%s is not a member of the VG %s",
|
||||||
@ -407,14 +415,15 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
|
|||||||
struct dev_iter *iter;
|
struct dev_iter *iter;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct disk_list *data = NULL;
|
struct disk_list *data = NULL;
|
||||||
|
struct list *vgih;
|
||||||
struct list *pvdh, *pvdh2;
|
struct cache_vginfo *vginfo;
|
||||||
|
|
||||||
/* Fast path if we already saw this VG and cached the list of PVs */
|
/* Fast path if we already saw this VG and cached the list of PVs */
|
||||||
if ((pvdh = vgcache_find(vg_name))) {
|
if (vg_name && (vginfo = vginfo_from_vgname(vg_name)) &&
|
||||||
list_iterate(pvdh2, pvdh) {
|
vginfo->infos.n) {
|
||||||
dev = list_item(pvdh2, struct pvdev_list)->dev;
|
list_iterate(vgih, &vginfo->infos) {
|
||||||
if (!(data = read_disk(fmt, dev, mem, vg_name)))
|
dev = list_item(vgih, struct cache_info)->dev;
|
||||||
|
if (dev && !(data = read_disk(fmt, dev, mem, vg_name)))
|
||||||
break;
|
break;
|
||||||
_add_pv_to_list(head, data);
|
_add_pv_to_list(head, data);
|
||||||
}
|
}
|
||||||
@ -422,11 +431,12 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
|
|||||||
/* Did we find the whole VG? */
|
/* Did we find the whole VG? */
|
||||||
if (!vg_name || !*vg_name ||
|
if (!vg_name || !*vg_name ||
|
||||||
(data && *data->pvd.vg_name &&
|
(data && *data->pvd.vg_name &&
|
||||||
list_size(head) == data->vgd.pv_cur)) return 1;
|
list_size(head) == data->vgd.pv_cur))
|
||||||
|
return 1;
|
||||||
|
|
||||||
/* Something changed. Remove the hints. */
|
/* Failed */
|
||||||
list_init(head);
|
list_init(head);
|
||||||
vgcache_del(vg_name);
|
/* vgcache_del(vg_name); */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(iter = dev_iter_create(filter))) {
|
if (!(iter = dev_iter_create(filter))) {
|
||||||
@ -514,8 +524,7 @@ static int _write_lvs(struct disk_list *data)
|
|||||||
struct lvd_list *ll = list_item(lvh, struct lvd_list);
|
struct lvd_list *ll = list_item(lvh, struct lvd_list);
|
||||||
|
|
||||||
offset = sizeof(struct lv_disk) * ll->lvd.lv_number;
|
offset = sizeof(struct lv_disk) * ll->lvd.lv_number;
|
||||||
if (offset + sizeof(struct lv_disk) >
|
if (offset + sizeof(struct lv_disk) > data->pvd.lv_on_disk.size) {
|
||||||
data->pvd.lv_on_disk.size) {
|
|
||||||
log_error("lv_number %d too large", ll->lvd.lv_number);
|
log_error("lv_number %d too large", ll->lvd.lv_number);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -587,19 +596,19 @@ static int __write_all_pvd(struct format_type *fmt, struct disk_list *data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, fmt);
|
/* vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev, fmt); */
|
||||||
/*
|
/*
|
||||||
* Stop here for orphan pv's.
|
* Stop here for orphan pv's.
|
||||||
*/
|
*/
|
||||||
if (data->pvd.vg_name[0] == '\0') {
|
if (data->pvd.vg_name[0] == '\0') {
|
||||||
if (!test_mode())
|
/* if (!test_mode())
|
||||||
vgcache_add(data->pvd.vg_name, NULL, data->dev, fmt);
|
vgcache_add(data->pvd.vg_name, NULL, data->dev, fmt); */
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!test_mode())
|
/* if (!test_mode())
|
||||||
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev,
|
vgcache_add(data->pvd.vg_name, data->vgd.vg_uuid, data->dev,
|
||||||
fmt);
|
fmt); */
|
||||||
|
|
||||||
if (!_write_vgd(data)) {
|
if (!_write_vgd(data)) {
|
||||||
log_error("Failed to write VG data to %s", pv_name);
|
log_error("Failed to write VG data to %s", pv_name);
|
||||||
|
@ -11,21 +11,17 @@
|
|||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
|
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
|
||||||
|
|
||||||
#define MAX_PV 256
|
#define MAX_PV 256
|
||||||
#define MAX_LV 256
|
#define MAX_LV 256
|
||||||
#define MAX_VG 99
|
#define MAX_VG 99
|
||||||
|
|
||||||
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
|
#define MAX_PV_SIZE ((uint32_t) -1) /* 2TB in sectors - 1 */
|
||||||
#define MIN_PE_SIZE (8192L / SECTOR_SIZE) /* 8 KB in sectors */
|
#define MIN_PE_SIZE (8192L >> SECTOR_SHIFT) /* 8 KB in sectors */
|
||||||
#define MAX_PE_SIZE (16L * 1024L * 1024L / SECTOR_SIZE * 1024)
|
#define MAX_PE_SIZE (16L * 1024L * (1024L >> SECTOR_SHIFT) * 1024L)
|
||||||
#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */
|
#define PE_SIZE_PV_SIZE_REL 5 /* PV size must be at least 5 times PE size */
|
||||||
#define MAX_LE_TOTAL 65534 /* 2^16 - 2 */
|
#define MAX_LE_TOTAL 65534 /* 2^16 - 2 */
|
||||||
#define MAX_PE_TOTAL ((uint32_t) -2)
|
#define MAX_PE_TOTAL ((uint32_t) -2)
|
||||||
|
|
||||||
|
|
||||||
#define UNMAPPED_EXTENT 0
|
#define UNMAPPED_EXTENT 0
|
||||||
|
|
||||||
/* volume group */
|
/* volume group */
|
||||||
@ -60,11 +56,10 @@
|
|||||||
#define EXPORTED_TAG "PV_EXP" /* Identifier for exported PV */
|
#define EXPORTED_TAG "PV_EXP" /* Identifier for exported PV */
|
||||||
#define IMPORTED_TAG "PV_IMP" /* Identifier for imported PV */
|
#define IMPORTED_TAG "PV_IMP" /* Identifier for imported PV */
|
||||||
|
|
||||||
|
|
||||||
struct data_area {
|
struct data_area {
|
||||||
uint32_t base;
|
uint32_t base;
|
||||||
uint32_t size;
|
uint32_t size;
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct pv_disk {
|
struct pv_disk {
|
||||||
uint8_t id[2];
|
uint8_t id[2];
|
||||||
@ -89,7 +84,7 @@ struct pv_disk {
|
|||||||
|
|
||||||
/* only present on version == 2 pv's */
|
/* only present on version == 2 pv's */
|
||||||
uint32_t pe_start;
|
uint32_t pe_start;
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct lv_disk {
|
struct lv_disk {
|
||||||
uint8_t lv_name[NAME_LEN];
|
uint8_t lv_name[NAME_LEN];
|
||||||
@ -113,7 +108,7 @@ struct lv_disk {
|
|||||||
uint32_t lv_allocation;
|
uint32_t lv_allocation;
|
||||||
uint32_t lv_io_timeout; /* for future use */
|
uint32_t lv_io_timeout; /* for future use */
|
||||||
uint32_t lv_read_ahead;
|
uint32_t lv_read_ahead;
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct vg_disk {
|
struct vg_disk {
|
||||||
uint8_t vg_uuid[ID_LEN]; /* volume group UUID */
|
uint8_t vg_uuid[ID_LEN]; /* volume group UUID */
|
||||||
@ -133,13 +128,12 @@ struct vg_disk {
|
|||||||
uint32_t pe_total; /* total of physical extents */
|
uint32_t pe_total; /* total of physical extents */
|
||||||
uint32_t pe_allocated; /* allocated physical extents */
|
uint32_t pe_allocated; /* allocated physical extents */
|
||||||
uint32_t pvg_total; /* physical volume groups FU */
|
uint32_t pvg_total; /* physical volume groups FU */
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
struct pe_disk {
|
struct pe_disk {
|
||||||
uint16_t lv_num;
|
uint16_t lv_num;
|
||||||
uint16_t le_num;
|
uint16_t le_num;
|
||||||
};
|
} __attribute__ ((packed));
|
||||||
|
|
||||||
|
|
||||||
struct uuid_list {
|
struct uuid_list {
|
||||||
struct list list;
|
struct list list;
|
||||||
@ -163,7 +157,6 @@ struct disk_list {
|
|||||||
struct pe_disk *extents;
|
struct pe_disk *extents;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Layout constants.
|
* Layout constants.
|
||||||
*/
|
*/
|
||||||
@ -173,19 +166,17 @@ struct disk_list {
|
|||||||
#define PV_SIZE 1024UL
|
#define PV_SIZE 1024UL
|
||||||
#define VG_SIZE 4096UL
|
#define VG_SIZE 4096UL
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to calculate layout info.
|
* Functions to calculate layout info.
|
||||||
*/
|
*/
|
||||||
int calculate_layout(struct disk_list *dl);
|
int calculate_layout(struct disk_list *dl);
|
||||||
int calculate_extent_count(struct physical_volume *pv);
|
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||||
|
uint32_t max_extent_count);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Low level io routines which read/write
|
* Low level io routines which read/write
|
||||||
* disk_lists.
|
* disk_lists.
|
||||||
*/
|
*/
|
||||||
int read_pvd(struct device *dev, struct pv_disk *pvd);
|
|
||||||
|
|
||||||
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
|
struct disk_list *read_disk(struct format_type *fmt, struct device *dev,
|
||||||
struct pool *mem, const char *vg_name);
|
struct pool *mem, const char *vg_name);
|
||||||
@ -196,7 +187,6 @@ int read_pvs_in_vg(struct format_type *fmt, const char *vg_name,
|
|||||||
|
|
||||||
int write_disks(struct format_type *fmt, struct list *pvds);
|
int write_disks(struct format_type *fmt, struct list *pvds);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to translate to between disk and in
|
* Functions to translate to between disk and in
|
||||||
* core structures.
|
* core structures.
|
||||||
@ -208,27 +198,21 @@ int export_pv(struct pool *mem, struct volume_group *vg,
|
|||||||
struct pv_disk *pvd, struct physical_volume *pv);
|
struct pv_disk *pvd, struct physical_volume *pv);
|
||||||
|
|
||||||
int import_vg(struct pool *mem,
|
int import_vg(struct pool *mem,
|
||||||
struct volume_group *vg, struct disk_list *dl,
|
struct volume_group *vg, struct disk_list *dl, int partial);
|
||||||
int partial);
|
|
||||||
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
|
int export_vg(struct vg_disk *vgd, struct volume_group *vg);
|
||||||
|
|
||||||
int import_lv(struct pool *mem, struct logical_volume *lv,
|
int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd);
|
||||||
struct lv_disk *lvd);
|
|
||||||
void export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
|
||||||
struct logical_volume *lv, const char *dev_dir);
|
|
||||||
|
|
||||||
int import_extents(struct pool *mem, struct volume_group *vg,
|
int import_extents(struct pool *mem, struct volume_group *vg,
|
||||||
struct list *pvds);
|
struct list *pvds);
|
||||||
int export_extents(struct disk_list *dl, int lv_num,
|
int export_extents(struct disk_list *dl, int lv_num,
|
||||||
struct logical_volume *lv,
|
struct logical_volume *lv, struct physical_volume *pv);
|
||||||
struct physical_volume *pv);
|
|
||||||
|
|
||||||
int import_pvs(struct format_instance *fid, struct pool *mem,
|
int import_pvs(struct format_type *fmt, struct pool *mem,
|
||||||
struct volume_group *vg,
|
struct volume_group *vg,
|
||||||
struct list *pvds, struct list *results, int *count);
|
struct list *pvds, struct list *results, int *count);
|
||||||
|
|
||||||
int import_lvs(struct pool *mem, struct volume_group *vg,
|
int import_lvs(struct pool *mem, struct volume_group *vg, struct list *pvds);
|
||||||
struct list *pvds);
|
|
||||||
int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
||||||
struct physical_volume *pv, const char *dev_dir);
|
struct physical_volume *pv, const char *dev_dir);
|
||||||
|
|
||||||
@ -247,5 +231,4 @@ int get_free_vg_number(struct format_instance *fid, struct dev_filter *filter,
|
|||||||
int export_vg_number(struct format_instance *fid, struct list *pvds,
|
int export_vg_number(struct format_instance *fid, struct list *pvds,
|
||||||
const char *vg_name, struct dev_filter *filter);
|
const char *vg_name, struct dev_filter *filter);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,15 +4,17 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "limits.h"
|
#include "limits.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
|
||||||
#include "display.h"
|
#include "display.h"
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
|
#include "cache.h"
|
||||||
|
#include "lvm1-label.h"
|
||||||
|
#include "format1.h"
|
||||||
|
|
||||||
/* VG consistency checks */
|
/* VG consistency checks */
|
||||||
static int _check_vgs(struct list *pvs, int *partial)
|
static int _check_vgs(struct list *pvs, int *partial)
|
||||||
@ -113,7 +115,7 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
|||||||
if (!import_vg(mem, vg, dl, partial))
|
if (!import_vg(mem, vg, dl, partial))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (!import_pvs(fid, mem, vg, pvs, &vg->pvs, &vg->pv_count))
|
if (!import_pvs(fid->fmt, mem, vg, pvs, &vg->pvs, &vg->pv_count))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
if (!import_lvs(mem, vg, pvs))
|
if (!import_lvs(mem, vg, pvs))
|
||||||
@ -134,7 +136,8 @@ static struct volume_group *_build_vg(struct format_instance *fid,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct volume_group *_vg_read(struct format_instance *fid,
|
static struct volume_group *_vg_read(struct format_instance *fid,
|
||||||
const char *vg_name, void *mda)
|
const char *vg_name,
|
||||||
|
struct metadata_area *mda)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024 * 10);
|
struct pool *mem = pool_create(1024 * 10);
|
||||||
struct list pvs;
|
struct list pvs;
|
||||||
@ -185,8 +188,7 @@ static struct disk_list *_flatten_pv(struct pool *mem, struct volume_group *vg,
|
|||||||
if (!export_pv(mem, vg, &dl->pvd, pv) ||
|
if (!export_pv(mem, vg, &dl->pvd, pv) ||
|
||||||
!export_vg(&dl->vgd, vg) ||
|
!export_vg(&dl->vgd, vg) ||
|
||||||
!export_uuids(dl, vg) ||
|
!export_uuids(dl, vg) ||
|
||||||
!export_lvs(dl, vg, pv, dev_dir) ||
|
!export_lvs(dl, vg, pv, dev_dir) || !calculate_layout(dl)) {
|
||||||
!calculate_layout(dl)) {
|
|
||||||
stack;
|
stack;
|
||||||
pool_free(mem, dl);
|
pool_free(mem, dl);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -227,7 +229,7 @@ static int _flatten_vg(struct format_instance *fid, struct pool *mem,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
||||||
void *mdl)
|
struct metadata_area *mda)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024 * 10);
|
struct pool *mem = pool_create(1024 * 10);
|
||||||
struct list pvds;
|
struct list pvds;
|
||||||
@ -243,26 +245,28 @@ static int _vg_write(struct format_instance *fid, struct volume_group *vg,
|
|||||||
r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir,
|
r = (_flatten_vg(fid, mem, vg, &pvds, fid->fmt->cmd->dev_dir,
|
||||||
fid->fmt->cmd->filter) &&
|
fid->fmt->cmd->filter) &&
|
||||||
write_disks(fid->fmt, &pvds));
|
write_disks(fid->fmt, &pvds));
|
||||||
|
|
||||||
|
cache_update_vg(vg);
|
||||||
pool_destroy(mem);
|
pool_destroy(mem);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _pv_read(struct format_type *fmt, const char *name,
|
int _pv_read(struct format_type *fmt, const char *pv_name,
|
||||||
struct physical_volume *pv)
|
struct physical_volume *pv, struct list *mdas)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024);
|
struct pool *mem = pool_create(1024);
|
||||||
struct disk_list *dl;
|
struct disk_list *dl;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
log_very_verbose("Reading physical volume data %s from disk", name);
|
log_very_verbose("Reading physical volume data %s from disk", pv_name);
|
||||||
|
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(dev = dev_cache_get(name, fmt->cmd->filter))) {
|
if (!(dev = dev_cache_get(pv_name, fmt->cmd->filter))) {
|
||||||
stack;
|
stack;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -277,7 +281,7 @@ int _pv_read(struct format_type *fmt, const char *name,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
pv->fid = fmt->ops->create_instance(fmt, NULL, NULL);
|
pv->fmt = fmt;
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
|
|
||||||
@ -286,123 +290,45 @@ int _pv_read(struct format_type *fmt, const char *name,
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct list *_get_pvs(struct format_type *fmt, struct list *results)
|
static int _pv_setup(struct format_type *fmt,
|
||||||
|
uint64_t pe_start, uint32_t extent_count,
|
||||||
|
uint32_t extent_size,
|
||||||
|
int pvmetadatacopies,
|
||||||
|
uint64_t pvmetadatasize, struct list *mdas,
|
||||||
|
struct physical_volume *pv, struct volume_group *vg)
|
||||||
{
|
{
|
||||||
struct pool *mem = pool_create(1024 * 10);
|
char *sz;
|
||||||
struct list pvs;
|
|
||||||
uint32_t count;
|
|
||||||
|
|
||||||
if (!mem) {
|
|
||||||
stack;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_init(&pvs);
|
|
||||||
|
|
||||||
if (!read_pvs_in_vg(fmt, NULL, fmt->cmd->filter, mem, &pvs)) {
|
|
||||||
stack;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!import_pvs(NULL, fmt->cmd->mem, NULL, &pvs, results, &count)) {
|
|
||||||
stack;
|
|
||||||
goto bad;
|
|
||||||
}
|
|
||||||
|
|
||||||
pool_destroy(mem);
|
|
||||||
return results;
|
|
||||||
|
|
||||||
bad:
|
|
||||||
pool_destroy(mem);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _find_vg_name(struct list *names, const char *vg)
|
|
||||||
{
|
|
||||||
struct list *nh;
|
|
||||||
struct name_list *nl;
|
|
||||||
|
|
||||||
list_iterate(nh, names) {
|
|
||||||
nl = list_item(nh, struct name_list);
|
|
||||||
if (!strcmp(nl->name, vg))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct list *_get_vgs(struct format_type *fmt, struct list *names)
|
|
||||||
{
|
|
||||||
struct list *pvh;
|
|
||||||
struct list *pvs;
|
|
||||||
struct name_list *nl;
|
|
||||||
|
|
||||||
if (!(pvs = pool_alloc(fmt->cmd->mem, sizeof(*pvs)))) {
|
|
||||||
log_error("PV list allocation failed");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_init(pvs);
|
|
||||||
|
|
||||||
if (!_get_pvs(fmt, pvs)) {
|
|
||||||
stack;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_iterate(pvh, pvs) {
|
|
||||||
struct pv_list *pvl = list_item(pvh, struct pv_list);
|
|
||||||
|
|
||||||
if (!(*pvl->pv->vg_name) ||
|
|
||||||
_find_vg_name(names, pvl->pv->vg_name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (!(nl = pool_alloc(fmt->cmd->mem, sizeof(*nl)))) {
|
|
||||||
stack;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(nl->name = pool_strdup(fmt->cmd->mem, pvl->pv->vg_name))) {
|
|
||||||
stack;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
list_add(names, &nl->list);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (list_empty(names))
|
|
||||||
pool_free(fmt->cmd->mem, pvs);
|
|
||||||
|
|
||||||
return names;
|
|
||||||
|
|
||||||
err:
|
|
||||||
pool_free(fmt->cmd->mem, pvs);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _pv_setup(struct format_instance *fid, struct physical_volume *pv,
|
|
||||||
struct volume_group *vg)
|
|
||||||
{
|
|
||||||
/* setup operations for the PV structure */
|
|
||||||
if (pv->size > MAX_PV_SIZE)
|
if (pv->size > MAX_PV_SIZE)
|
||||||
pv->size--;
|
pv->size--;
|
||||||
if (pv->size > MAX_PV_SIZE) {
|
if (pv->size > MAX_PV_SIZE) {
|
||||||
/* FIXME Limit hardcoded */
|
log_error("Physical volumes cannot be bigger than %s",
|
||||||
log_error("Physical volumes cannot be bigger than 2TB");
|
sz = display_size(MAX_PV_SIZE / 2, SIZE_SHORT));
|
||||||
|
dbg_free(sz);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Nothing more to do if pe_size isn't known */
|
/* Nothing more to do if extent size isn't provided */
|
||||||
if (!vg)
|
if (!extent_size)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This works out pe_start and pe_count.
|
* This works out pe_start and pe_count.
|
||||||
*/
|
*/
|
||||||
if (!calculate_extent_count(pv)) {
|
if (!calculate_extent_count(pv, extent_size, extent_count)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Retain existing extent locations exactly */
|
||||||
|
/* FIXME Relax this so a non-overlapping existing pe_start can also
|
||||||
|
* be used in place of the calculated one */
|
||||||
|
if (((pe_start || extent_count) && (pe_start != pv->pe_start)) ||
|
||||||
|
(extent_count && (extent_count != pv->pe_count))) {
|
||||||
|
log_error("Metadata would overwrite physical extents");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -448,20 +374,27 @@ static int _lv_setup(struct format_instance *fid, struct logical_volume *lv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _pv_write(struct format_instance *fid, struct physical_volume *pv,
|
static int _pv_write(struct format_type *fmt, struct physical_volume *pv,
|
||||||
void *mdl)
|
struct list *mdas, int64_t sector)
|
||||||
{
|
{
|
||||||
struct pool *mem;
|
struct pool *mem;
|
||||||
struct disk_list *dl;
|
struct disk_list *dl;
|
||||||
struct list pvs;
|
struct list pvs;
|
||||||
|
struct label *label;
|
||||||
|
struct cache_info *info;
|
||||||
|
|
||||||
list_init(&pvs);
|
if (!(info = cache_add(fmt->labeller, (char *) &pv->id, pv->dev,
|
||||||
|
pv->vg_name, NULL))) {
|
||||||
if (*pv->vg_name || pv->pe_alloc_count) {
|
stack;
|
||||||
log_error("Assertion failed: can't _pv_write non-orphan PV "
|
|
||||||
"(in VG %s)", pv->vg_name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
label = info->label;
|
||||||
|
info->device_size = pv->size << SECTOR_SHIFT;
|
||||||
|
info->fmt = fmt;
|
||||||
|
|
||||||
|
list_init(&info->mdas);
|
||||||
|
|
||||||
|
list_init(&pvs);
|
||||||
|
|
||||||
/* Ensure any residual PE structure is gone */
|
/* Ensure any residual PE structure is gone */
|
||||||
pv->pe_size = pv->pe_count = 0;
|
pv->pe_size = pv->pe_count = 0;
|
||||||
@ -488,10 +421,10 @@ static int _pv_write(struct format_instance *fid, struct physical_volume *pv,
|
|||||||
dev_write in order to make other disk tools happy */
|
dev_write in order to make other disk tools happy */
|
||||||
dl->pvd.pv_on_disk.base = METADATA_BASE;
|
dl->pvd.pv_on_disk.base = METADATA_BASE;
|
||||||
dl->pvd.pv_on_disk.size = PV_SIZE;
|
dl->pvd.pv_on_disk.size = PV_SIZE;
|
||||||
dl->pvd.pe_on_disk.base = PE_ALIGN * SECTOR_SIZE;
|
dl->pvd.pe_on_disk.base = PE_ALIGN << SECTOR_SHIFT;
|
||||||
|
|
||||||
list_add(&pvs, &dl->list);
|
list_add(&pvs, &dl->list);
|
||||||
if (!write_disks(fid->fmt, &pvs)) {
|
if (!write_disks(fmt, &pvs)) {
|
||||||
stack;
|
stack;
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
}
|
||||||
@ -542,6 +475,11 @@ int _vg_setup(struct format_instance *fid, struct volume_group *vg)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct metadata_area_ops _metadata_format1_ops = {
|
||||||
|
vg_read:_vg_read,
|
||||||
|
vg_write:_vg_write,
|
||||||
|
};
|
||||||
|
|
||||||
struct format_instance *_create_instance(struct format_type *fmt,
|
struct format_instance *_create_instance(struct format_type *fmt,
|
||||||
const char *vgname, void *private)
|
const char *vgname, void *private)
|
||||||
{
|
{
|
||||||
@ -563,6 +501,7 @@ struct format_instance *_create_instance(struct format_type *fmt,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mda->ops = &_metadata_format1_ops;
|
||||||
mda->metadata_locn = NULL;
|
mda->metadata_locn = NULL;
|
||||||
list_add(&fid->metadata_areas, &mda->list);
|
list_add(&fid->metadata_areas, &mda->list);
|
||||||
|
|
||||||
@ -580,21 +519,21 @@ void _destroy(struct format_type *fmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct format_handler _format1_ops = {
|
static struct format_handler _format1_ops = {
|
||||||
get_vgs: _get_vgs,
|
|
||||||
get_pvs: _get_pvs,
|
|
||||||
pv_read:_pv_read,
|
pv_read:_pv_read,
|
||||||
pv_setup:_pv_setup,
|
pv_setup:_pv_setup,
|
||||||
pv_write:_pv_write,
|
pv_write:_pv_write,
|
||||||
lv_setup:_lv_setup,
|
lv_setup:_lv_setup,
|
||||||
vg_read: _vg_read,
|
|
||||||
vg_setup:_vg_setup,
|
vg_setup:_vg_setup,
|
||||||
vg_write: _vg_write,
|
|
||||||
create_instance:_create_instance,
|
create_instance:_create_instance,
|
||||||
destroy_instance:_destroy_instance,
|
destroy_instance:_destroy_instance,
|
||||||
destroy:_destroy,
|
destroy:_destroy,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct format_type *create_lvm1_format(struct cmd_context *cmd)
|
#ifdef LVM1_INTERNAL
|
||||||
|
struct format_type *init_lvm1_format(struct cmd_context *cmd)
|
||||||
|
#else /* Shared */
|
||||||
|
struct format_type *init_format(struct cmd_context *cmd)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
struct format_type *fmt = dbg_malloc(sizeof(*fmt));
|
||||||
|
|
||||||
@ -606,8 +545,19 @@ struct format_type *create_lvm1_format(struct cmd_context *cmd)
|
|||||||
fmt->cmd = cmd;
|
fmt->cmd = cmd;
|
||||||
fmt->ops = &_format1_ops;
|
fmt->ops = &_format1_ops;
|
||||||
fmt->name = FMT_LVM1_NAME;
|
fmt->name = FMT_LVM1_NAME;
|
||||||
|
fmt->alias = NULL;
|
||||||
fmt->features = 0;
|
fmt->features = 0;
|
||||||
fmt->private = NULL;
|
fmt->private = NULL;
|
||||||
|
|
||||||
|
if (!(fmt->labeller = lvm1_labeller_create(fmt))) {
|
||||||
|
log_error("Couldn't create lvm1 label handler.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(label_register_handler(FMT_LVM1_NAME, fmt->labeller))) {
|
||||||
|
log_error("Couldn't register lvm1 label handler.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return fmt;
|
return fmt;
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
|
|
||||||
struct format_type *create_lvm1_format(struct cmd_context *cmd);
|
#define FMT_LVM1_NAME "lvm1"
|
||||||
|
|
||||||
|
#ifdef LVM1_INTERNAL
|
||||||
|
struct format_type *init_lvm1_format(struct cmd_context *cmd);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -6,12 +6,11 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "log.h"
|
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -172,6 +171,9 @@ int export_pv(struct pool *mem, struct volume_group *vg,
|
|||||||
|
|
||||||
pvd->pv_size = pv->size;
|
pvd->pv_size = pv->size;
|
||||||
pvd->lv_cur = 0; /* this is set when exporting the lv list */
|
pvd->lv_cur = 0; /* this is set when exporting the lv list */
|
||||||
|
if (vg)
|
||||||
|
pvd->pe_size = vg->extent_size;
|
||||||
|
else
|
||||||
pvd->pe_size = pv->pe_size;
|
pvd->pe_size = pv->pe_size;
|
||||||
pvd->pe_total = pv->pe_count;
|
pvd->pe_total = pv->pe_count;
|
||||||
pvd->pe_allocated = pv->pe_alloc_count;
|
pvd->pe_allocated = pv->pe_alloc_count;
|
||||||
@ -278,6 +280,8 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lv->status |= VISIBLE_LV;
|
||||||
|
|
||||||
if (lvd->lv_status & LV_SPINDOWN)
|
if (lvd->lv_status & LV_SPINDOWN)
|
||||||
lv->status |= SPINDOWN_LV;
|
lv->status |= SPINDOWN_LV;
|
||||||
|
|
||||||
@ -296,13 +300,11 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
|||||||
if (lvd->lv_badblock)
|
if (lvd->lv_badblock)
|
||||||
lv->status |= BADBLOCK_ON;
|
lv->status |= BADBLOCK_ON;
|
||||||
|
|
||||||
if (lvd->lv_allocation & LV_STRICT)
|
/* Drop the unused LV_STRICT here */
|
||||||
lv->alloc = ALLOC_STRICT;
|
|
||||||
|
|
||||||
if (lvd->lv_allocation & LV_CONTIGUOUS)
|
if (lvd->lv_allocation & LV_CONTIGUOUS)
|
||||||
lv->alloc = ALLOC_CONTIGUOUS;
|
lv->alloc = ALLOC_CONTIGUOUS;
|
||||||
else
|
else
|
||||||
lv->alloc |= ALLOC_NEXT_FREE;
|
lv->alloc = ALLOC_NEXT_FREE;
|
||||||
|
|
||||||
lv->read_ahead = lvd->lv_read_ahead;
|
lv->read_ahead = lvd->lv_read_ahead;
|
||||||
lv->size = lvd->lv_size;
|
lv->size = lvd->lv_size;
|
||||||
@ -313,15 +315,13 @@ int import_lv(struct pool *mem, struct logical_volume *lv, struct lv_disk *lvd)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
static void _export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
||||||
struct logical_volume *lv, const char *dev_dir)
|
struct logical_volume *lv, const char *dev_dir)
|
||||||
{
|
{
|
||||||
memset(lvd, 0, sizeof(*lvd));
|
memset(lvd, 0, sizeof(*lvd));
|
||||||
snprintf(lvd->lv_name, sizeof(lvd->lv_name), "%s%s/%s",
|
snprintf(lvd->lv_name, sizeof(lvd->lv_name), "%s%s/%s",
|
||||||
dev_dir, vg->name, lv->name);
|
dev_dir, vg->name, lv->name);
|
||||||
|
|
||||||
/* FIXME: Add 'if' test */
|
|
||||||
_check_vg_name(vg->name);
|
|
||||||
strcpy(lvd->vg_name, vg->name);
|
strcpy(lvd->vg_name, vg->name);
|
||||||
|
|
||||||
if (lv->status & LVM_READ)
|
if (lv->status & LVM_READ)
|
||||||
@ -339,10 +339,9 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
lvd->lv_read_ahead = lv->read_ahead;
|
lvd->lv_read_ahead = lv->read_ahead;
|
||||||
lvd->lv_stripes = list_item(lv->segments.n,
|
lvd->lv_stripes = list_item(lv->segments.n, struct lv_segment)->stripes;
|
||||||
struct stripe_segment)->stripes;
|
|
||||||
lvd->lv_stripesize = list_item(lv->segments.n,
|
lvd->lv_stripesize = list_item(lv->segments.n,
|
||||||
struct stripe_segment)->stripe_size;
|
struct lv_segment)->stripe_size;
|
||||||
|
|
||||||
lvd->lv_size = lv->size;
|
lvd->lv_size = lv->size;
|
||||||
lvd->lv_allocated_le = lv->le_count;
|
lvd->lv_allocated_le = lv->le_count;
|
||||||
@ -350,9 +349,6 @@ void export_lv(struct lv_disk *lvd, struct volume_group *vg,
|
|||||||
if (lv->status & BADBLOCK_ON)
|
if (lv->status & BADBLOCK_ON)
|
||||||
lvd->lv_badblock = LV_BADBLOCK_ON;
|
lvd->lv_badblock = LV_BADBLOCK_ON;
|
||||||
|
|
||||||
if (lv->alloc == ALLOC_STRICT)
|
|
||||||
lvd->lv_allocation |= LV_STRICT;
|
|
||||||
|
|
||||||
if (lv->alloc == ALLOC_CONTIGUOUS)
|
if (lv->alloc == ALLOC_CONTIGUOUS)
|
||||||
lvd->lv_allocation |= LV_CONTIGUOUS;
|
lvd->lv_allocation |= LV_CONTIGUOUS;
|
||||||
}
|
}
|
||||||
@ -362,11 +358,11 @@ int export_extents(struct disk_list *dl, int lv_num,
|
|||||||
{
|
{
|
||||||
struct list *segh;
|
struct list *segh;
|
||||||
struct pe_disk *ped;
|
struct pe_disk *ped;
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
uint32_t pe, s;
|
uint32_t pe, s;
|
||||||
|
|
||||||
list_iterate(segh, &lv->segments) {
|
list_iterate(segh, &lv->segments) {
|
||||||
seg = list_item(segh, struct stripe_segment);
|
seg = list_item(segh, struct lv_segment);
|
||||||
|
|
||||||
for (s = 0; s < seg->stripes; s++) {
|
for (s = 0; s < seg->stripes; s++) {
|
||||||
if (seg->area[s].pv != pv)
|
if (seg->area[s].pv != pv)
|
||||||
@ -384,7 +380,7 @@ int export_extents(struct disk_list *dl, int lv_num,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int import_pvs(struct format_instance *fid, struct pool *mem,
|
int import_pvs(struct format_type *fmt, struct pool *mem,
|
||||||
struct volume_group *vg,
|
struct volume_group *vg,
|
||||||
struct list *pvds, struct list *results, int *count)
|
struct list *pvds, struct list *results, int *count)
|
||||||
{
|
{
|
||||||
@ -408,7 +404,7 @@ int import_pvs(struct format_instance *fid, struct pool *mem,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pvl->pv->fid = fid;
|
pvl->pv->fmt = fmt;
|
||||||
list_add(results, &pvl->list);
|
list_add(results, &pvl->list);
|
||||||
(*count)++;
|
(*count)++;
|
||||||
}
|
}
|
||||||
@ -477,6 +473,11 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
|||||||
int lv_num, len;
|
int lv_num, len;
|
||||||
struct hash_table *lvd_hash;
|
struct hash_table *lvd_hash;
|
||||||
|
|
||||||
|
if (!_check_vg_name(vg->name)) {
|
||||||
|
stack;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(lvd_hash = hash_create(32))) {
|
if (!(lvd_hash = hash_create(32))) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
@ -499,7 +500,7 @@ int export_lvs(struct disk_list *dl, struct volume_group *vg,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
export_lv(&lvdl->lvd, vg, ll->lv, dev_dir);
|
_export_lv(&lvdl->lvd, vg, ll->lv, dev_dir);
|
||||||
|
|
||||||
lv_num = lvnum_from_lvid(&ll->lv->lvid);
|
lv_num = lvnum_from_lvid(&ll->lv->lvid);
|
||||||
|
|
||||||
@ -616,7 +617,8 @@ int import_snapshots(struct pool *mem, struct volume_group *vg,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* insert the snapshot */
|
/* insert the snapshot */
|
||||||
if (!vg_add_snapshot(org, cow, 1, lvd->lv_chunk_size)) {
|
if (!vg_add_snapshot(org, cow, 1, NULL,
|
||||||
|
lvd->lv_chunk_size)) {
|
||||||
log_err("Couldn't add snapshot.");
|
log_err("Couldn't add snapshot.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "metadata.h"
|
#include "metadata.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
|
|
||||||
@ -192,9 +191,9 @@ static int _check_maps_are_complete(struct hash_table *maps)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct stripe_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
|
static struct lv_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
|
||||||
{
|
{
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
|
uint32_t len = sizeof(*seg) + (stripes * sizeof(seg->area[0]));
|
||||||
|
|
||||||
if (!(seg = pool_zalloc(mem, len))) {
|
if (!(seg = pool_zalloc(mem, len))) {
|
||||||
@ -208,12 +207,13 @@ static struct stripe_segment *_alloc_seg(struct pool *mem, uint32_t stripes)
|
|||||||
static int _read_linear(struct pool *mem, struct lv_map *lvm)
|
static int _read_linear(struct pool *mem, struct lv_map *lvm)
|
||||||
{
|
{
|
||||||
uint32_t le = 0;
|
uint32_t le = 0;
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
|
|
||||||
while (le < lvm->lv->le_count) {
|
while (le < lvm->lv->le_count) {
|
||||||
seg = _alloc_seg(mem, 1);
|
seg = _alloc_seg(mem, 1);
|
||||||
|
|
||||||
seg->lv = lvm->lv;
|
seg->lv = lvm->lv;
|
||||||
|
seg->type = SEG_STRIPED;
|
||||||
seg->le = le;
|
seg->le = le;
|
||||||
seg->len = 0;
|
seg->len = 0;
|
||||||
seg->stripe_size = 0;
|
seg->stripe_size = 0;
|
||||||
@ -238,7 +238,7 @@ static int _read_linear(struct pool *mem, struct lv_map *lvm)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _check_stripe(struct lv_map *lvm, struct stripe_segment *seg,
|
static int _check_stripe(struct lv_map *lvm, struct lv_segment *seg,
|
||||||
uint32_t base_le, uint32_t len)
|
uint32_t base_le, uint32_t len)
|
||||||
{
|
{
|
||||||
uint32_t le, st;
|
uint32_t le, st;
|
||||||
@ -260,7 +260,7 @@ static int _check_stripe(struct lv_map *lvm, struct stripe_segment *seg,
|
|||||||
static int _read_stripes(struct pool *mem, struct lv_map *lvm)
|
static int _read_stripes(struct pool *mem, struct lv_map *lvm)
|
||||||
{
|
{
|
||||||
uint32_t st, le = 0, len;
|
uint32_t st, le = 0, len;
|
||||||
struct stripe_segment *seg;
|
struct lv_segment *seg;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Work out overall striped length
|
* Work out overall striped length
|
||||||
@ -279,6 +279,7 @@ static int _read_stripes(struct pool *mem, struct lv_map *lvm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
seg->lv = lvm->lv;
|
seg->lv = lvm->lv;
|
||||||
|
seg->type = SEG_STRIPED;
|
||||||
seg->stripe_size = lvm->stripe_size;
|
seg->stripe_size = lvm->stripe_size;
|
||||||
seg->stripes = lvm->stripes;
|
seg->stripes = lvm->stripes;
|
||||||
seg->le = seg->stripes * le;
|
seg->le = seg->stripes * le;
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
#include "log.h"
|
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only works with powers of 2.
|
* Only works with powers of 2.
|
||||||
@ -36,7 +35,7 @@ static uint32_t _next_base(struct data_area *area)
|
|||||||
*/
|
*/
|
||||||
static int _adjust_pe_on_disk(struct pv_disk *pvd)
|
static int _adjust_pe_on_disk(struct pv_disk *pvd)
|
||||||
{
|
{
|
||||||
uint32_t pe_start = pvd->pe_start * SECTOR_SIZE;
|
uint32_t pe_start = pvd->pe_start << SECTOR_SHIFT;
|
||||||
|
|
||||||
if (pe_start < pvd->pe_on_disk.base + pvd->pe_on_disk.size)
|
if (pe_start < pvd->pe_on_disk.base + pvd->pe_on_disk.size)
|
||||||
return 0;
|
return 0;
|
||||||
@ -103,11 +102,10 @@ int calculate_layout(struct disk_list *dl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* It may seem strange to have a struct physical_volume in here,
|
* The number of extents that can fit on a disk is metadata format dependant.
|
||||||
* but the number of extents that can fit on a disk *is* metadata
|
|
||||||
* format dependant.
|
|
||||||
*/
|
*/
|
||||||
int calculate_extent_count(struct physical_volume *pv)
|
int calculate_extent_count(struct physical_volume *pv, uint32_t extent_size,
|
||||||
|
uint32_t max_extent_count)
|
||||||
{
|
{
|
||||||
struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
|
struct pv_disk *pvd = dbg_malloc(sizeof(*pvd));
|
||||||
uint32_t end;
|
uint32_t end;
|
||||||
@ -122,10 +120,13 @@ int calculate_extent_count(struct physical_volume *pv)
|
|||||||
* one is going to be knocked off at the start of the
|
* one is going to be knocked off at the start of the
|
||||||
* next loop.
|
* next loop.
|
||||||
*/
|
*/
|
||||||
pvd->pe_total = (pv->size / pv->pe_size);
|
if (max_extent_count)
|
||||||
|
pvd->pe_total = max_extent_count + 1;
|
||||||
|
else
|
||||||
|
pvd->pe_total = (pv->size / extent_size);
|
||||||
|
|
||||||
if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
|
if (pvd->pe_total < PE_SIZE_PV_SIZE_REL) {
|
||||||
log_error("Insufficient space for extents on %s",
|
log_error("Too few extents on %s. Try smaller extent size.",
|
||||||
dev_name(pv->dev));
|
dev_name(pv->dev));
|
||||||
dbg_free(pvd);
|
dbg_free(pvd);
|
||||||
return 0;
|
return 0;
|
||||||
@ -135,11 +136,12 @@ int calculate_extent_count(struct physical_volume *pv)
|
|||||||
pvd->pe_total--;
|
pvd->pe_total--;
|
||||||
_calc_simple_layout(pvd);
|
_calc_simple_layout(pvd);
|
||||||
end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size +
|
end = ((pvd->pe_on_disk.base + pvd->pe_on_disk.size +
|
||||||
SECTOR_SIZE - 1) / SECTOR_SIZE);
|
SECTOR_SIZE - 1) >> SECTOR_SHIFT);
|
||||||
|
|
||||||
pvd->pe_start = _round_up(end, PE_ALIGN);
|
pvd->pe_start = _round_up(end, PE_ALIGN);
|
||||||
|
|
||||||
} while ((pvd->pe_start + (pvd->pe_total * pv->pe_size)) > pv->size);
|
} while ((pvd->pe_start + (pvd->pe_total * extent_size))
|
||||||
|
> pv->size);
|
||||||
|
|
||||||
if (pvd->pe_total > MAX_PE_TOTAL) {
|
if (pvd->pe_total > MAX_PE_TOTAL) {
|
||||||
log_error("Metadata extent limit (%u) exceeded for %s - "
|
log_error("Metadata extent limit (%u) exceeded for %s - "
|
||||||
@ -151,6 +153,7 @@ int calculate_extent_count(struct physical_volume *pv)
|
|||||||
|
|
||||||
pv->pe_count = pvd->pe_total;
|
pv->pe_count = pvd->pe_total;
|
||||||
pv->pe_start = pvd->pe_start;
|
pv->pe_start = pvd->pe_start;
|
||||||
|
/* We can't set pe_size here without breaking LVM1 compatibility */
|
||||||
dbg_free(pvd);
|
dbg_free(pvd);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
106
lib/format1/lvm1-label.c
Normal file
106
lib/format1/lvm1-label.c
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "lvm1-label.h"
|
||||||
|
#include "disk-rep.h"
|
||||||
|
#include "label.h"
|
||||||
|
#include "metadata.h"
|
||||||
|
#include "xlate.h"
|
||||||
|
#include "cache.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
static void _not_supported(const char *op)
|
||||||
|
{
|
||||||
|
log_err("The '%s' operation is not supported for the lvm1 labeller.",
|
||||||
|
op);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _can_handle(struct labeller *l, char *buf, uint64_t sector)
|
||||||
|
{
|
||||||
|
struct pv_disk *pvd = (struct pv_disk *) buf;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
/* LVM1 label must always be in first sector */
|
||||||
|
if (sector)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
version = xlate16(pvd->version);
|
||||||
|
|
||||||
|
if (pvd->id[0] == 'H' && pvd->id[1] == 'M' &&
|
||||||
|
(version == 1 || version == 2))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _write(struct label *label, char *buf)
|
||||||
|
{
|
||||||
|
_not_supported("write");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _read(struct labeller *l, struct device *dev, char *buf,
|
||||||
|
struct label **label)
|
||||||
|
{
|
||||||
|
struct pv_disk *pvd = (struct pv_disk *) buf;
|
||||||
|
struct cache_info *info;
|
||||||
|
|
||||||
|
if (!(info = cache_add(l, pvd->pv_uuid, dev, pvd->vg_name, NULL)))
|
||||||
|
return 0;
|
||||||
|
*label = info->label;
|
||||||
|
|
||||||
|
info->device_size = xlate32(pvd->pv_size) << SECTOR_SHIFT;
|
||||||
|
list_init(&info->mdas);
|
||||||
|
|
||||||
|
info->status &= ~CACHE_INVALID;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _initialise_label(struct labeller *l, struct label *label)
|
||||||
|
{
|
||||||
|
strcpy(label->type, "LVM1");
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _destroy_label(struct labeller *l, struct label *label)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _destroy(struct labeller *l)
|
||||||
|
{
|
||||||
|
dbg_free(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct label_ops _lvm1_ops = {
|
||||||
|
can_handle:_can_handle,
|
||||||
|
write:_write,
|
||||||
|
read:_read,
|
||||||
|
verify:_can_handle,
|
||||||
|
initialise_label:_initialise_label,
|
||||||
|
destroy_label:_destroy_label,
|
||||||
|
destroy:_destroy
|
||||||
|
};
|
||||||
|
|
||||||
|
struct labeller *lvm1_labeller_create(struct format_type *fmt)
|
||||||
|
{
|
||||||
|
struct labeller *l;
|
||||||
|
|
||||||
|
if (!(l = dbg_malloc(sizeof(*l)))) {
|
||||||
|
log_err("Couldn't allocate labeller object.");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
l->ops = &_lvm1_ops;
|
||||||
|
l->private = (void *) fmt;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
14
lib/format1/lvm1-label.h
Normal file
14
lib/format1/lvm1-label.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_LVM1_LABEL_H
|
||||||
|
#define _LVM_LVM1_LABEL_H
|
||||||
|
|
||||||
|
#include "metadata.h"
|
||||||
|
|
||||||
|
struct labeller *lvm1_labeller_create(struct format_type *fmt);
|
||||||
|
|
||||||
|
#endif
|
@ -1,143 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
|
||||||
*
|
|
||||||
* This file is released under the LGPL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "lvm1_label.h"
|
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "disk-rep.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "label.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
static void _not_supported(const char *op)
|
|
||||||
{
|
|
||||||
log_err("The '%s' operation is not supported for the lvm1 labeller.",
|
|
||||||
op);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _can_handle(struct labeller *l, struct device *dev)
|
|
||||||
{
|
|
||||||
struct pv_disk pvd;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
if (!dev_open(dev, O_RDONLY)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = read_pvd(dev, &pvd);
|
|
||||||
|
|
||||||
if (!dev_close(dev))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _write(struct labeller *l, struct device *dev, struct label *label)
|
|
||||||
{
|
|
||||||
_not_supported("write");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _remove(struct labeller *l, struct device *dev)
|
|
||||||
{
|
|
||||||
_not_supported("remove");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct label *_to_label(struct pv_disk *pvd)
|
|
||||||
{
|
|
||||||
struct label *l;
|
|
||||||
struct lvm_label_info *info;
|
|
||||||
|
|
||||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
|
||||||
log_err("Couldn't allocate label.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(info = (struct lvm_label_info *) dbg_strdup(pvd->vg_name))) {
|
|
||||||
dbg_free(l);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(&l->id, &pvd->pv_uuid, sizeof(l->id));
|
|
||||||
strcpy(l->volume_type, "lvm");
|
|
||||||
l->version[0] = 1;
|
|
||||||
l->version[0] = 0;
|
|
||||||
l->version[0] = 0;
|
|
||||||
l->extra_info = info;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _read(struct labeller *l, struct device *dev, struct label **label)
|
|
||||||
{
|
|
||||||
struct pv_disk pvd;
|
|
||||||
int r = 0;
|
|
||||||
|
|
||||||
if (!dev_open(dev, O_RDONLY)) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = read_pvd(dev, &pvd);
|
|
||||||
|
|
||||||
if (!dev_close(dev))
|
|
||||||
stack;
|
|
||||||
|
|
||||||
if (!r) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert the disk_list into a label structure.
|
|
||||||
*/
|
|
||||||
if (!(*label = _to_label(&pvd))) {
|
|
||||||
stack;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _destroy_label(struct labeller *l, struct label *label)
|
|
||||||
{
|
|
||||||
dbg_free(label->extra_info);
|
|
||||||
dbg_free(label);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _destroy(struct labeller *l)
|
|
||||||
{
|
|
||||||
dbg_free(l);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct label_ops _lvm1_ops = {
|
|
||||||
can_handle: _can_handle,
|
|
||||||
write: _write,
|
|
||||||
remove: _remove,
|
|
||||||
read: _read,
|
|
||||||
verify: _can_handle,
|
|
||||||
destroy_label: _destroy_label,
|
|
||||||
destroy: _destroy
|
|
||||||
};
|
|
||||||
|
|
||||||
struct labeller *lvm1_labeller_create(void)
|
|
||||||
{
|
|
||||||
struct labeller *l;
|
|
||||||
|
|
||||||
if (!(l = dbg_malloc(sizeof(*l)))) {
|
|
||||||
log_err("Couldn't allocate labeller object.");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
l->ops = &_lvm1_ops;
|
|
||||||
l->private = NULL;
|
|
||||||
|
|
||||||
return l;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
|
||||||
*
|
|
||||||
* This file is released under the LGPL.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LVM_LVM1_LABEL_H
|
|
||||||
#define _LVM_LVM1_LABEL_H
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is what the 'extra_info' field of the label will point to
|
|
||||||
* if the label type is lvm1.
|
|
||||||
*/
|
|
||||||
struct lvm_label_info {
|
|
||||||
char volume_group[0];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct labeller *lvm1_labeller_create(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -4,7 +4,7 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "disk-rep.h"
|
#include "disk-rep.h"
|
||||||
|
|
||||||
|
@ -5,111 +5,72 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "locking.h"
|
|
||||||
#include "locking_types.h"
|
#include "locking_types.h"
|
||||||
#include "activate.h"
|
|
||||||
#include "config.h"
|
|
||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include "lvm-file.h"
|
#include "sharedlib.h"
|
||||||
#include "lvm-string.h"
|
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/file.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
static void *locking_module = NULL;
|
static void *_locking_lib = NULL;
|
||||||
static void (*end_fn) (void) = NULL;
|
static void (*_end_fn) (void) = NULL;
|
||||||
static int (*lock_fn) (struct cmd_context * cmd, const char *resource,
|
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
|
||||||
int flags) = NULL;
|
int flags) = NULL;
|
||||||
static int (*init_fn) (int type, struct config_file * cf) = NULL;
|
static int (*_init_fn) (int type, struct config_tree * cf) = NULL;
|
||||||
|
|
||||||
static int lock_resource(struct cmd_context *cmd, const char *resource,
|
static int _lock_resource(struct cmd_context *cmd, const char *resource,
|
||||||
int flags)
|
int flags)
|
||||||
{
|
{
|
||||||
if (lock_fn)
|
if (_lock_fn)
|
||||||
return lock_fn(cmd, resource, flags);
|
return _lock_fn(cmd, resource, flags);
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fin_external_locking(void)
|
static void _fin_external_locking(void)
|
||||||
{
|
{
|
||||||
if (end_fn)
|
if (_end_fn)
|
||||||
end_fn();
|
_end_fn();
|
||||||
|
|
||||||
dlclose(locking_module);
|
dlclose(_locking_lib);
|
||||||
|
|
||||||
locking_module = NULL;
|
_locking_lib = NULL;
|
||||||
end_fn = NULL;
|
_init_fn = NULL;
|
||||||
lock_fn = NULL;
|
_end_fn = NULL;
|
||||||
|
_lock_fn = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_external_locking(struct locking_type *locking, struct config_file *cf)
|
int init_external_locking(struct locking_type *locking, struct config_tree *cf)
|
||||||
{
|
{
|
||||||
char _lock_lib[PATH_MAX];
|
const char *libname;
|
||||||
|
|
||||||
if (locking_module) {
|
if (_locking_lib) {
|
||||||
log_error("External locking already initialised");
|
log_error("External locking already initialised");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
locking->lock_resource = lock_resource;
|
|
||||||
locking->fin_locking = fin_external_locking;
|
|
||||||
|
|
||||||
/* Get locking module name from config file */
|
locking->lock_resource = _lock_resource;
|
||||||
strncpy(_lock_lib, find_config_str(cf->root, "global/locking_library",
|
locking->fin_locking = _fin_external_locking;
|
||||||
'/', "lvm2_locking.so"),
|
|
||||||
sizeof(_lock_lib));
|
|
||||||
|
|
||||||
/* If there is a module_dir in the config file then
|
libname = find_config_str(cf->root, "global/locking_library", '/',
|
||||||
look for the locking module in there first and then
|
DEFAULT_LOCKING_LIB);
|
||||||
using the normal dlopen(3) mechanism of looking
|
|
||||||
down LD_LIBRARY_PATH and /lib, /usr/lib.
|
|
||||||
If course, if the library name starts with a slash then
|
|
||||||
just use the name... */
|
|
||||||
if (_lock_lib[0] != '/') {
|
|
||||||
struct stat st;
|
|
||||||
char _lock_lib1[PATH_MAX];
|
|
||||||
|
|
||||||
lvm_snprintf(_lock_lib1, sizeof(_lock_lib1),
|
if (!(_locking_lib = load_shared_library(cf, libname, "locking"))) {
|
||||||
"%s/%s",
|
stack;
|
||||||
find_config_str(cf->root, "global/module_dir",
|
|
||||||
'/', "RUBBISH"), _lock_lib);
|
|
||||||
|
|
||||||
/* Does it exist ? */
|
|
||||||
if (stat(_lock_lib1, &st) == 0) {
|
|
||||||
strcpy(_lock_lib, _lock_lib1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log_very_verbose("Opening locking library %s", _lock_lib);
|
|
||||||
|
|
||||||
locking_module = dlopen(_lock_lib, RTLD_LAZY);
|
|
||||||
if (!locking_module) {
|
|
||||||
log_error("Unable to open external locking module %s",
|
|
||||||
_lock_lib);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the functions we need */
|
/* Get the functions we need */
|
||||||
init_fn = dlsym(locking_module, "init_locking");
|
if (!(_init_fn = dlsym(_locking_lib, "init_locking")) ||
|
||||||
lock_fn = dlsym(locking_module, "lock_resource");
|
!(_lock_fn = dlsym(_locking_lib, "lock_resource")) ||
|
||||||
end_fn = dlsym(locking_module, "end_locking");
|
!(_end_fn = dlsym(_locking_lib, "end_locking"))) {
|
||||||
|
|
||||||
/* Are they all there ? */
|
|
||||||
if (!end_fn || !init_fn || !lock_fn) {
|
|
||||||
log_error("Shared library %s does not contain locking "
|
log_error("Shared library %s does not contain locking "
|
||||||
"functions", _lock_lib);
|
"functions", libname);
|
||||||
dlclose(locking_module);
|
dlclose(_locking_lib);
|
||||||
|
_locking_lib = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
log_verbose("Opened external locking module %s", _lock_lib);
|
log_verbose("Loaded external locking library %s", libname);
|
||||||
return init_fn(2, cf);
|
return _init_fn(2, cf);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "locking.h"
|
#include "locking.h"
|
||||||
#include "locking_types.h"
|
#include "locking_types.h"
|
||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
@ -13,11 +13,9 @@
|
|||||||
#include "defaults.h"
|
#include "defaults.h"
|
||||||
#include "lvm-file.h"
|
#include "lvm-file.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
@ -117,13 +115,16 @@ static int _lock_file(const char *file, int flags)
|
|||||||
|
|
||||||
struct lock_list *ll;
|
struct lock_list *ll;
|
||||||
struct stat buf1, buf2;
|
struct stat buf1, buf2;
|
||||||
|
char state;
|
||||||
|
|
||||||
switch (flags & LCK_TYPE_MASK) {
|
switch (flags & LCK_TYPE_MASK) {
|
||||||
case LCK_READ:
|
case LCK_READ:
|
||||||
operation = LOCK_SH;
|
operation = LOCK_SH;
|
||||||
|
state = 'R';
|
||||||
break;
|
break;
|
||||||
case LCK_WRITE:
|
case LCK_WRITE:
|
||||||
operation = LOCK_EX;
|
operation = LOCK_EX;
|
||||||
|
state = 'W';
|
||||||
break;
|
break;
|
||||||
case LCK_UNLOCK:
|
case LCK_UNLOCK:
|
||||||
return _release_lock(file);
|
return _release_lock(file);
|
||||||
@ -142,7 +143,8 @@ static int _lock_file(const char *file, int flags)
|
|||||||
|
|
||||||
ll->lf = -1;
|
ll->lf = -1;
|
||||||
|
|
||||||
log_very_verbose("Locking %s", ll->res);
|
log_very_verbose("Locking %s %c%c", ll->res, state,
|
||||||
|
flags & LCK_NONBLOCK ? ' ' : 'B');
|
||||||
do {
|
do {
|
||||||
if (ll->lf > -1)
|
if (ll->lf > -1)
|
||||||
close(ll->lf);
|
close(ll->lf);
|
||||||
@ -197,10 +199,6 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
|||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case LCK_LV:
|
case LCK_LV:
|
||||||
/* Skip if driver isn't loaded */
|
|
||||||
/* FIXME Use /proc/misc instead? */
|
|
||||||
if (!driver_version(NULL, 0))
|
|
||||||
return 1;
|
|
||||||
switch (flags & LCK_TYPE_MASK) {
|
switch (flags & LCK_TYPE_MASK) {
|
||||||
case LCK_UNLOCK:
|
case LCK_UNLOCK:
|
||||||
if (!lv_resume_if_active(cmd, resource))
|
if (!lv_resume_if_active(cmd, resource))
|
||||||
@ -231,7 +229,7 @@ int file_lock_resource(struct cmd_context *cmd, const char *resource, int flags)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_file_locking(struct locking_type *locking, struct config_file *cf)
|
int init_file_locking(struct locking_type *locking, struct config_tree *cf)
|
||||||
{
|
{
|
||||||
locking->lock_resource = file_lock_resource;
|
locking->lock_resource = file_lock_resource;
|
||||||
locking->fin_locking = fin_file_locking;
|
locking->fin_locking = fin_file_locking;
|
||||||
|
@ -5,13 +5,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "locking.h"
|
#include "locking.h"
|
||||||
#include "locking_types.h"
|
#include "locking_types.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "activate.h"
|
#include "activate.h"
|
||||||
#include "toolcontext.h"
|
#include "toolcontext.h"
|
||||||
#include "defaults.h"
|
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -72,7 +71,7 @@ static inline void _update_lock_count(int flags)
|
|||||||
/*
|
/*
|
||||||
* Select a locking type
|
* Select a locking type
|
||||||
*/
|
*/
|
||||||
int init_locking(int type, struct config_file *cf)
|
int init_locking(int type, struct config_tree *cf)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0:
|
case 0:
|
||||||
@ -122,9 +121,12 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname)
|
|||||||
struct stat info;
|
struct stat info;
|
||||||
char path[PATH_MAX];
|
char path[PATH_MAX];
|
||||||
|
|
||||||
if (lvm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s",
|
/* We'll allow operations on orphans */
|
||||||
find_config_str(cmd->cf->root, "global/proc", '/',
|
if (!*vgname)
|
||||||
DEFAULT_PROC_DIR), vgname) < 0) {
|
return 1;
|
||||||
|
|
||||||
|
if (lvm_snprintf(path, sizeof(path), "%s/lvm/VGs/%s", cmd->proc_dir,
|
||||||
|
vgname) < 0) {
|
||||||
log_error("LVM1 proc VG pathname too long for %s", vgname);
|
log_error("LVM1 proc VG pathname too long for %s", vgname);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
int init_locking(int type, struct config_file *cf);
|
int init_locking(int type, struct config_tree *cf);
|
||||||
void fin_locking(void);
|
void fin_locking(void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -24,9 +24,9 @@ struct locking_type {
|
|||||||
/*
|
/*
|
||||||
* Locking types
|
* Locking types
|
||||||
*/
|
*/
|
||||||
int init_no_locking(struct locking_type *locking, struct config_file *cf);
|
int init_no_locking(struct locking_type *locking, struct config_tree *cf);
|
||||||
|
|
||||||
int init_file_locking(struct locking_type *locking, struct config_file *cf);
|
int init_file_locking(struct locking_type *locking, struct config_tree *cf);
|
||||||
|
|
||||||
int init_external_locking(struct locking_type *locking, struct config_file *cf);
|
int init_external_locking(struct locking_type *locking, struct config_tree *cf);
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "locking.h"
|
#include "locking.h"
|
||||||
#include "locking_types.h"
|
#include "locking_types.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
@ -51,7 +51,7 @@ static int _no_lock_resource(struct cmd_context *cmd, const char *resource,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int init_no_locking(struct locking_type *locking, struct config_file *cf)
|
int init_no_locking(struct locking_type *locking, struct config_tree *cf)
|
||||||
{
|
{
|
||||||
locking->lock_resource = _no_lock_resource;
|
locking->lock_resource = _no_lock_resource;
|
||||||
locking->fin_locking = _no_fin_locking;
|
locking->fin_locking = _no_fin_locking;
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
@ -57,9 +58,9 @@ void init_verbose(int level)
|
|||||||
|
|
||||||
void init_test(int level)
|
void init_test(int level)
|
||||||
{
|
{
|
||||||
|
if (!_test && level)
|
||||||
|
log_print("Test mode: Metadata will NOT be updated.");
|
||||||
_test = level;
|
_test = level;
|
||||||
if (_test)
|
|
||||||
log_print("Test mode. Metadata will NOT be updated.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_partial(int level)
|
void init_partial(int level)
|
||||||
|
@ -28,8 +28,8 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h> /* FILE */
|
||||||
#include <string.h>
|
#include <string.h> /* strerror() */
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#define _LOG_DEBUG 7
|
#define _LOG_DEBUG 7
|
||||||
@ -91,8 +91,3 @@ void print_log(int level, const char *file, int line, const char *format, ...)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Local variables:
|
|
||||||
* c-file-style: "linux"
|
|
||||||
* End:
|
|
||||||
*/
|
|
||||||
|
28
lib/misc/crc.c
Normal file
28
lib/misc/crc.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "lvm-types.h"
|
||||||
|
|
||||||
|
/* Calculate an endian-independent CRC of supplied buffer */
|
||||||
|
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size)
|
||||||
|
{
|
||||||
|
static const uint32_t crctab[] = {
|
||||||
|
0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
|
||||||
|
0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
|
||||||
|
0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
|
||||||
|
0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
|
||||||
|
};
|
||||||
|
uint32_t i, crc = initial;
|
||||||
|
uint8_t *data = (uint8_t *) buf;
|
||||||
|
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
crc ^= *data++;
|
||||||
|
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
||||||
|
crc = (crc >> 4) ^ crctab[crc & 0xf];
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
16
lib/misc/crc.h
Normal file
16
lib/misc/crc.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _LVM_CRC_H
|
||||||
|
#define _LVM_CRC_H
|
||||||
|
|
||||||
|
#include "lvm-types.h"
|
||||||
|
|
||||||
|
#define INITIAL_CRC 0xf597a6cf
|
||||||
|
|
||||||
|
uint32_t calc_crc(uint32_t initial, void *buf, uint32_t size);
|
||||||
|
|
||||||
|
#endif
|
18
lib/misc/lib.h
Normal file
18
lib/misc/lib.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file must be included first by every source file.
|
||||||
|
*/
|
||||||
|
#ifndef _LVM_LIB_H
|
||||||
|
#define _LVM_LIB_H
|
||||||
|
|
||||||
|
#define _REENTRANT
|
||||||
|
|
||||||
|
#include "log.h"
|
||||||
|
#include "dbg_malloc.h"
|
||||||
|
|
||||||
|
#endif
|
@ -4,14 +4,11 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "log.h"
|
#include "lib.h"
|
||||||
#include "lvm-file.h"
|
#include "lvm-file.h"
|
||||||
#include "lvm-string.h"
|
#include "lvm-string.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/file.h>
|
#include <sys/file.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
39
lib/misc/sharedlib.c
Normal file
39
lib/misc/sharedlib.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "lvm-string.h"
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dlfcn.h>
|
||||||
|
|
||||||
|
void *load_shared_library(struct config_tree *cf, const char *libname,
|
||||||
|
const char *desc)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
struct stat info;
|
||||||
|
const char *lib_dir;
|
||||||
|
void *library;
|
||||||
|
|
||||||
|
/* If libname doesn't begin with '/' then use lib_dir/libname,
|
||||||
|
* if present */
|
||||||
|
if (libname[0] == '/' ||
|
||||||
|
!(lib_dir = find_config_str(cf->root, "global/library_dir",
|
||||||
|
'/', 0)) ||
|
||||||
|
(lvm_snprintf(path, sizeof(path), "%s/%s", lib_dir,
|
||||||
|
libname) == -1) || stat(path, &info) == -1)
|
||||||
|
strncpy(path, libname, sizeof(path));
|
||||||
|
|
||||||
|
log_very_verbose("Opening shared %s library %s", desc, path);
|
||||||
|
|
||||||
|
if (!(library = dlopen(path, RTLD_LAZY)))
|
||||||
|
log_error("Unable to open external %s library %s", desc, path);
|
||||||
|
|
||||||
|
return library;
|
||||||
|
}
|
11
lib/misc/sharedlib.h
Normal file
11
lib/misc/sharedlib.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 Sistina Software (UK) Limited.
|
||||||
|
*
|
||||||
|
* This file is released under the LGPL.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
void *load_shared_library(struct config_tree *cf, const char *libname,
|
||||||
|
const char *what);
|
@ -4,14 +4,11 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
|
#include "lvm-types.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
struct memblock {
|
struct memblock {
|
||||||
struct memblock *prev, *next; /* All allocated blocks are linked */
|
struct memblock *prev, *next; /* All allocated blocks are linked */
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "dbg_malloc.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
@ -4,13 +4,9 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include "lib.h"
|
||||||
#include <string.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "dbg_malloc.h"
|
#include "lvm-types.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
struct chunk {
|
struct chunk {
|
||||||
char *begin, *end;
|
char *begin, *end;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||||
*
|
*
|
||||||
* This file is released under the LGPL.
|
* This file is released under the GPL.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
#include <asm/byteorder.h>
|
#include <asm/byteorder.h>
|
||||||
|
|
||||||
#define xlate16(x) __cpu_to_le16((x));
|
#define xlate16(x) __cpu_to_le16((x))
|
||||||
#define xlate32(x) __cpu_to_le32((x));
|
#define xlate32(x) __cpu_to_le32((x))
|
||||||
#define xlate64(x) __cpu_to_le64((x));
|
#define xlate64(x) __cpu_to_le64((x))
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,14 +4,12 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "matcher.h"
|
#include "matcher.h"
|
||||||
#include "parse_rx.h"
|
#include "parse_rx.h"
|
||||||
#include "log.h"
|
|
||||||
#include "ttree.h"
|
#include "ttree.h"
|
||||||
#include "bitset.h"
|
#include "bitset.h"
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
struct dfa_state {
|
struct dfa_state {
|
||||||
@ -330,8 +328,8 @@ struct matcher *matcher_create(struct pool *mem, const char **patterns, int num)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct dfa_state *
|
static inline struct dfa_state *_step_matcher(unsigned char c,
|
||||||
_step_matcher(unsigned char c, struct dfa_state *cs, int *r)
|
struct dfa_state *cs, int *r)
|
||||||
{
|
{
|
||||||
if (!(cs = cs->lookup[c]))
|
if (!(cs = cs->lookup[c]))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4,13 +4,9 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "parse_rx.h"
|
#include "parse_rx.h"
|
||||||
#include "bitset.h"
|
#include "bitset.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
struct parse_sp { /* scratch pad for the parsing process */
|
struct parse_sp { /* scratch pad for the parsing process */
|
||||||
struct pool *mem;
|
struct pool *mem;
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "ttree.h"
|
#include "ttree.h"
|
||||||
#include "pool.h"
|
#include "pool.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
unsigned k;
|
unsigned k;
|
||||||
|
@ -4,10 +4,9 @@
|
|||||||
* This file is released under the LGPL.
|
* This file is released under the LGPL.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "lib.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user