1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

o code sync for dev-cache.c

o made copyright headers the same

o added __attribute ((format ... to print_log so we'll get better compile errors

o added iterator to the hash table
This commit is contained in:
Joe Thornber 2001-10-03 11:06:31 +00:00
parent 112cb0dc28
commit d0986f9482
15 changed files with 265 additions and 262 deletions

View File

@ -1,31 +1,7 @@
/*
* tools/lib/lvm_config.c
*
* Copyright (C) 2001 Sistina Software
*
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
*
*/
/*
* Changelog
*
* 17/04/2001 - First version [Joe Thornber]
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#include <sys/types.h>

View File

@ -1,20 +1,7 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* This file is released under the GPL.
*/
#ifndef _LVM_CONFIG_H

View File

@ -181,4 +181,29 @@ void hash_iterate(struct hash_table *t, iterate_fn f)
f(c->data);
}
void *hash_get_data(struct hash_table *t, struct hash_node *n)
{
return n->data;
}
static struct hash_node *_next_slot(struct hash_table *t, unsigned int s)
{
struct hash_node *c = 0;
int i;
for (i = s; i < t->num_slots && !c; i++)
c = t->slots[i];
return c;
}
struct hash_node *hash_get_first(struct hash_table *t)
{
return _next_slot(t, 0);
}
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n)
{
return n->next ? n->next : _next_slot(t, _hash(n->key) + 1);
}

View File

@ -8,10 +8,12 @@
#define _LVM_HASH_H
struct hash_table;
struct hash_node;
typedef void (*iterate_fn)(void *data);
struct hash_table *create_hash_table(unsigned size_hint);
void destroy_hash_table(struct hash_table *t);
struct hash_table *hash_create(unsigned size_hint);
void hash_destroy(struct hash_table *t);
char *hash_lookup(struct hash_table *t, const char *key);
void hash_insert(struct hash_table *t, const char *key, void *data);
@ -20,5 +22,9 @@ void hash_remove(struct hash_table *t, const char *key);
unsigned hash_get_num_entries(struct hash_table *t);
void hash_iterate(struct hash_table *t, iterate_fn f);
void *hash_get_data(struct hash_table *t, struct hash_node *n);
struct hash_node *hash_get_first(struct hash_table *t);
struct hash_node *hash_get_next(struct hash_table *t, struct hash_node *n);
#endif

View File

@ -32,9 +32,9 @@ struct list_head {
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_add(struct list_head * new,
struct list_head * prev,
struct list_head * next)
static __inline__ void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
@ -11,83 +11,163 @@
#include <stdlib.h>
#define DEV_PATH_LEN 256
/*
* FIXME: really need to seperate names from the devices since
* multiple names can point to the same device.
*/
struct d_internal {
struct device dev;
int count;
int rw;
FILE *fp;
struct dev_iter {
struct hash_node *current;
struct dev_filter *filter;
};
struct {
static pool *mem;
struct dir_list {
struct list_head dir_list;
char *dir[0];
};
static struct {
struct pool *mem;
struct hash_table *devices;
int has_scanned;
struct list_head dirs;
} _cache;
static inline struct d_internal *_alloc_dev()
#define _alloc(x) pool_alloc(_cache.mem, (x))
#define _free(x) pool_free(_cache.mem, (x))
/*
* return a new path for the destination of the path.
*/
static char * _follow_link(const char *path, struct stat *info)
{
return pool_alloc(_cache.mem, sizeof(struct d_internal));
char buffer[PATH_MAX + 1], *r;
int n;
n = readlink(path, buffer);
if (n <= 0)
return NULL;
buffer[n] = '\0';
if (stat(buffer, info) < 0) {
log_sys_err("stat");
return NULL;
}
return pool_strdup(_cache.mem, buffer);
}
static struct d_internal *_create_dev(const char *path)
/*
* Get rid of extra slashes in the path string.
*/
static void _collapse_slashes(char *str)
{
char *ptr;
int was_slash = 0;
for (ptr = str; *ptr; ptr++) {
if (*ptr == '/') {
if (was_slash)
continue;
was_slash = 1;
} else
was_slash = 0;
*str++ = *ptr;
}
*str = *ptr;
}
static struct device *_create_dev(const char *path)
{
/* FIXME: follow sym links */
struct stat info;
char norm[DEV_PATH_LEN];
_normalise_path(norm, path);
struct device *dev;
char *normed = _collapse_slashes(path);
if (stat(path, &info) < 0) {
if (!normed) {
stack;
return NULL;
}
if (stat(normed, &info) < 0) {
log_sys_error("stat");
return 0;
return NULL;
}
/* FIXME: lost the will to program */
if () {
if (S_ISLNK(info.st_mode)) {
char *new_path;
log_debug("%s is a symbolic link, following\n", normed);
normed = _follow_link(normed, &info);
if (!normed)
return NULL;
}
if (!S_ISBLK(info.st_mode)) {
log_debug("%s is not a block device\n", normed);
return NULL;
}
if (!(dev = _alloc(sizeof(*dev)))) {
stack;
return NULL;
}
dev->name = normed;
dev->dev = info.st_rdev;
return dev;
}
#define DEV_READ 0
#define DEV_WRITE 1
static inline struct FILE *_open_read(const char *path)
static struct device *_add(const char *dir, const char *path)
{
return fopen(path, "r");
struct device *d;
int len = strlen(dir) + strlen(path) + 2;
char *buffer = _alloc(len);
snprintf(buffer, len, "%s/%s", path);
d = dev_cache_get(path);
if (!d)
_free(buffer); /* pool_free is safe in this case */
return d;
}
static inline struct FILE *_open_write(const char *path)
static int _dir_scan(const char *dir)
{
return fopen(path, "rw");
}
int n, dirent_count;
struct dirent **dirent;
static int _check_open(struct d_internal *di, int rw)
{
/* is it already open ? */
if (dev->fp)
return 0;
if (di->fp) {
/* do we need to upgrade a read ? */
if (di->rw == DEV_READ && rw == DEV_WRITE) {
struct FILE *fp = _open_write(di->dev.path);
if (!fp)
return 0;
fclose(di->fp);
di->fp = fp;
dirent_count = scandir(dir, &dirent, NULL, alphasort);
if (dirent_count > 0) {
for (n = 0; n < dirent_count; n++) {
_add(dir, dirent[n]->d_name);
free(dirent[n]);
}
} else if (rw == DEV_READ)
di->fp = _open_read(di->dev.path);
else
di->fp = _open_write(di->dev.path);
free(dirent);
}
return di->fp ? 1 : 0;
return 1;
}
int init_dev_cache()
static void _full_scan(void)
{
struct dir_list *dl;
if (_cache.has_scanned)
return;
for (dl = _cache.dirs.next; dl != &_cache.dirs; dl = dl->next)
_dir_scan(dl.dir);
_cache.has_scanned = 1;
}
int dev_cache_init(void)
{
if (!(_cache.mem = pool_create(10 * 1024))) {
stack;
@ -104,68 +184,70 @@ int init_dev_cache()
return 1;
}
static void _close_device(void *d)
{
struct d_internal *di = (struct d_internal *) d;
if (di->fp)
fclose(di->fp);
}
void exit_dev_cache()
void dev_cache_exit(void)
{
pool_destroy(_cache.mem);
hash_iterate(_cache.devices, _close_devices);
hash_destroy(_cache.devices);
}
struct device *get_device(const char *name)
int dev_cache_add_dir(const char *path)
{
struct d_internal *di = hash_lookup(_cache.devices, name);
if (di)
di->count++;
else {
di = _create_device(name);
struct dir_list *dl;
if (di)
hash_insert(t, name, di);
if (!(dl = _alloc(sizeof(*dl) + strlen(path) + 1)))
return 0;
strcpy(dl->dir, path);
list_add(dl, _cache.directories);
return 1;
}
struct device *dev_cache_get(const char *name)
{
struct device *d = hash_lookup(_cache.devices, name);
if (!d && (d = _create_device(name)))
hash_insert(t, name, d);
return d;
}
struct dev_iter *dev_iter_create(struct dev_filter *f)
{
struct dev_iter *di = dbg_malloc(sizeof(*di));
if (!di)
return NULL;
_full_scan();
di->current = hash_get_first();
di->filter = f;
return di;
}
void dev_iter_destroy(struct dev_iter *iter)
{
dbg_free(iter);
}
static inline struct device *_iter_next(struct dev_iter *iter)
{
struct device *d = hash_get_data(_cache.devices, iter->current);
iter->current = hash_next(_cache.devices, iter->current);
return d;
}
struct device *dev_iter_get(struct dev_iter *iter)
{
while (iter->current) {
struct device *d = _iter_next(iter);
if (!iter->filter ||
iter->filter->pass_filter(iter->filter, d))
return d;
}
return di ? &di->d : 0;
return NULL;
}
void put_device(struct device *d)
{
struct d_internal *di = (struct d_internal *) d;
if (--di->count < 0)
log_error("device reference count < 0");
else if (di->count == 0)
_close_device(di);
}
ssize_t dev_read(struct device *dev, size_t offset, size_t len, void *buffer)
{
struct d_internal *di = (struct d_internal *) dev;
if (!_check_open(di, DEV_READ)) {
stack;
return -EPERM;
}
fseek(dev->fp, offset, SEEK_SET);
return fread(buffer, 1, len, dev->fp);
}
ssize_t dev_write(struct device *dev, size_t offset, size_t len, void *buffer)
{
struct d_internal *di = (struct d_internal *) dev;
if (!_check_open(di, DEV_WRITE)) {
stack;
return -EPERM;
}
fseek(dev->fp, offset, SEEK_SET);
return fwrite(buffer, 1, len, dev->fp);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2001 Sistina Software
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
@ -31,7 +31,7 @@ int dev_cache_init(void);
void dev_cache_exit(void);
int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(const char *name);
struct device *dev_cache_get(const char *name, struct dev_filter *f);
/*
@ -45,10 +45,13 @@ struct device *dev_iter_get(struct dev_iter *iter);
/*
* All io should use these routines, rather than opening the devices
* by hand. You do not have to call an open routine.
* by hand. You do not have to call an open routine. ATM all io is
* immediately flushed.
*/
__uint64_t dev_get_size(struct device *dev); /* in 512 byte sectors */
ssize_t dev_read(struct device *dev, size_t offset, size_t len, void *buffer);
ssize_t dev_write(struct device *dev, size_t offset, size_t len, void *buffer);
int dev_get_size(struct device *dev, uint64_t *size); /* in k */
int64_t dev_read(struct device *dev, uint64_t offset,
int64_t len, void *buffer);
int64_t dev_write(struct device *dev, uint64_t offset,
int64_t len, void *buffer);
#endif

View File

@ -124,9 +124,9 @@ struct dev_mgr *init_dev_manager(struct config_node *cn)
memset(dm, 0, sizeof(*dm));
dm->pool = pool;
if(cn)
if(cn)
base_dir = find_config_str(cn, "dev-mgr/base_dir", '/', 0);
if(!base_dir)
if(!base_dir)
base_dir = DEFAULT_BASE_DIR;
dm->devdir = pool_alloc(dm->pool, sizeof(char*));
@ -447,7 +447,7 @@ static int _scan_proc_dev(struct dev_mgr *dm)
i = 0;
while (line[i] == ' ' && line[i] != '\0')
i++;
/* If its not a number it may be name of section */
line_maj = atoi(((char *) (line + i)));
if (line_maj == 0) {
@ -457,7 +457,7 @@ static int _scan_proc_dev(struct dev_mgr *dm)
/* We only want block devices ... */
if (!blocksection)
continue;
/* Find the start of the device major name */
while (line[i] != ' ' && line[i] != '\0')
i++;
@ -468,13 +468,13 @@ static int _scan_proc_dev(struct dev_mgr *dm)
match, set the array member corresponding to the
major number to !0 */
for (j = 0; device_names[j] != NULL; j++) {
dev_len = strlen(device_names[j]);
if (dev_len <= strlen(line + i)) {
if (strncmp (device_names[j],
line + i,
dev_len) == 0) {
dm->valid_majors[line_maj]='1';
ret++;
break;

View File

@ -20,22 +20,19 @@
#ifndef _LVM_DEV_MANAGER_H
#define _LVM_DEV_MANAGER_H
#include <stdio.h>
#include <sys/types.h>
#include "config.h"
struct device {
char *name;
dev_t dev;
};
struct dev_manager;
struct dev_iter;
struct dev_mgr;
typedef struct _dummy_counter *dev_counter_t;
struct dev_mgr *init_dev_manager(struct config_node *cfg_node);
struct dev_manager *create_dev_manager();
void fin_dev_manager(struct dev_mgr *dm);
struct device *dev_by_name(struct dev_mgr *dm, const char *name);
struct device *dev_by_dev(struct dev_mgr *dm, dev_t d);
struct device *get_dev_by_name(struct dev_mgr *dm, const char *name);
struct device *get_dev_by_dev(struct dev_mgr *dm, dev_t d);
void put_dev(struct dev_mgr *dm, const char *name);
/* either of these trigger a full scan, the first time they're run */
dev_counter_t init_dev_scan(struct dev_mgr *dm);

View File

@ -1,22 +1,7 @@
/*
* Copyright (C) 2001 Sistina Software
*
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#include "log.h"

View File

@ -1,21 +1,7 @@
/*
* Copyright (C) 2001 Sistina Software
*
* This LVM library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This LVM library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this LVM library; if not, write to the Free
* Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#ifndef _LVM_LOG_H
@ -31,7 +17,7 @@
#define _LOG_FATAL 2
void init_log(FILE *fp);
void fin_log();
void fin_log(void);
void init_syslog(int facility);
void fin_syslog(void);
@ -43,7 +29,8 @@ void init_debug(int level);
int test_mode(void);
int debug_level(void);
void print_log(int level, const char *file, int line, const char *format, ...);
void print_log(int level, const char *file, int line, const char *format, ...)
__attribute__ (( format (printf, 4, 5) ));
#define plog(l, x...) print_log(l, __FILE__, __LINE__ , ## x)
@ -58,7 +45,7 @@ void print_log(int level, const char *file, int line, const char *format, ...);
#define stack log_debug( "stack trace" )
/*
/*
* Macros to use for messages:
*
* log_error - always print to stderr
@ -69,7 +56,6 @@ void print_log(int level, const char *file, int line, const char *format, ...);
*
* In addition, messages will be logged to file or syslog if they
* are more serious than the log level specified with -d.
*
*/
#define log_error(fmt, args...) log_err(fmt , ## args)

View File

@ -1,24 +1,7 @@
/*
* Copyright (C) 2000, 2001 Sistina Software
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* TODO:
*
* Thread safety seems to have fallen out, put lock back in.
* This file is released under the GPL.
*/
#include <assert.h>

View File

@ -1,21 +1,7 @@
/*
* Copyright (C) 2001 Sistina Software
*
* lvm is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* lvm is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GNU CC; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#ifndef _LVM_DBG_MALLOC_H

View File

@ -1,22 +1,9 @@
/*
* Copyright (C) 2001 Sistina Software
*
* LVM is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* LVM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with LVM; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
* Copyright (C) 2001 Sistina Software (UK) Limited.
*
* This file is released under the GPL.
*/
#include <stdlib.h>
#include <string.h>

View File

@ -32,9 +32,9 @@ struct list_head {
* This is only for internal list manipulation where we know
* the prev/next entries already!
*/
static __inline__ void __list_add(struct list_head * new,
struct list_head * prev,
struct list_head * next)
static __inline__ void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;