diff options
author | Tim Deegan <Tim.Deegan@xensource.com> | 2006-11-09 14:09:53 +0000 |
---|---|---|
committer | Tim Deegan <Tim.Deegan@xensource.com> | 2006-11-09 14:09:53 +0000 |
commit | cddc1d5a09b0ee520e31d9f56dfb4a20f6fb3ba1 (patch) | |
tree | 40779970f5ad69d7f5cea225844c430e48812b8c /tools/libfsimage/common | |
parent | 21b5e9be6acce19ff8aa22e55a0ddc69d7b19750 (diff) | |
download | xen-cddc1d5a09b0ee520e31d9f56dfb4a20f6fb3ba1.tar.gz xen-cddc1d5a09b0ee520e31d9f56dfb4a20f6fb3ba1.tar.bz2 xen-cddc1d5a09b0ee520e31d9f56dfb4a20f6fb3ba1.zip |
Add libfsimage, a C library for reading files from filesystem images.
Initial support is provided for Solaris UFS, ext2 (both using libext2fs
and not), and reiserfs.
Signed-off-by: John Levon <john.levon@sun.com>
Diffstat (limited to 'tools/libfsimage/common')
-rw-r--r-- | tools/libfsimage/common/Makefile | 46 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage.c | 140 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage.h | 52 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage_grub.c | 277 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage_grub.h | 92 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage_plugin.c | 214 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage_plugin.h | 65 | ||||
-rw-r--r-- | tools/libfsimage/common/fsimage_priv.h | 62 | ||||
-rw-r--r-- | tools/libfsimage/common/mapfile-GNU | 37 | ||||
-rw-r--r-- | tools/libfsimage/common/mapfile-SunOS | 35 |
10 files changed, 1020 insertions, 0 deletions
diff --git a/tools/libfsimage/common/Makefile b/tools/libfsimage/common/Makefile new file mode 100644 index 0000000000..98c43d5858 --- /dev/null +++ b/tools/libfsimage/common/Makefile @@ -0,0 +1,46 @@ +XEN_ROOT = ../../.. +include $(XEN_ROOT)/tools/Rules.mk + +MAJOR = 1.0 +MINOR = 0 + +CFLAGS += -Werror -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -Wp,-MD,.$(@F).d +DEPS = .*.d + +LDFLAGS-$(CONFIG_SunOS) = -Wl,-M -Wl,mapfile-SunOS +LDFLAGS-$(CONFIG_Linux) = -Wl,mapfile-GNU +LDFLAGS = $(LDFLAGS-y) + +LIB_SRCS-y = fsimage.c fsimage_plugin.c fsimage_grub.c + +PIC_OBJS := $(patsubst %.c,%.opic,$(LIB_SRCS-y)) + +LIB = libfsimage.so libfsimage.so.$(MAJOR) libfsimage.so.$(MAJOR).$(MINOR) + +.PHONY: all +all: $(LIB) + +.PHONY: install +install: all + [ -d $(DESTDIR)/usr/$(LIBDIR) ] || $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR) + [ -d $(DESTDIR)/usr/include ] || $(INSTALL_DIR) $(DESTDIR)/usr/include + $(INSTALL_PROG) libfsimage.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR) + ln -sf libfsimage.so.$(MAJOR).$(MINOR) $(DESTDIR)/usr/$(LIBDIR)/libfsimage.so.$(MAJOR) + ln -sf libfsimage.so.$(MAJOR) $(DESTDIR)/usr/$(LIBDIR)/libfsimage.so + $(INSTALL_DATA) fsimage.h $(DESTDIR)/usr/include + $(INSTALL_DATA) fsimage_plugin.h $(DESTDIR)/usr/include + $(INSTALL_DATA) fsimage_grub.h $(DESTDIR)/usr/include + +clean distclean: + rm -f $(PIC_OBJS) $(LIB) + +libfsimage.so: libfsimage.so.$(MAJOR) + ln -sf $< $@ +libfsimage.so.$(MAJOR): libfsimage.so.$(MAJOR).$(MINOR) + ln -sf $< $@ + +libfsimage.so.$(MAJOR).$(MINOR): $(PIC_OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) -Wl,$(SONAME_LDFLAG) -Wl,libfsimage.so.$(MAJOR) $(SHLIB_CFLAGS) -o $@ $^ -lpthread + +-include $(DEPS) + diff --git a/tools/libfsimage/common/fsimage.c b/tools/libfsimage/common/fsimage.c new file mode 100644 index 0000000000..f77d73b815 --- /dev/null +++ b/tools/libfsimage/common/fsimage.c @@ -0,0 +1,140 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <sys/stat.h> +#include <sys/types.h> +#include <strings.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <fcntl.h> +#include <errno.h> +#include <pthread.h> + +#include "fsimage_plugin.h" +#include "fsimage_priv.h" + +static pthread_mutex_t fsi_lock = PTHREAD_MUTEX_INITIALIZER; + +fsi_t *fsi_open_fsimage(const char *path, uint64_t off) +{ + fsi_t *fsi = NULL; + int fd; + int err; + + if ((fd = open(path, O_RDONLY)) == -1) + goto fail; + + if ((fsi = malloc(sizeof(*fsi))) == NULL) + goto fail; + + fsi->f_fd = fd; + fsi->f_off = off; + fsi->f_data = NULL; + + pthread_mutex_lock(&fsi_lock); + err = find_plugin(fsi, path); + pthread_mutex_unlock(&fsi_lock); + if (err != 0) + goto fail; + + return (fsi); + +fail: + err = errno; + if (fd != -1) + (void) close(fd); + free(fsi); + errno = err; + return (NULL); +} + +void fsi_close_fsimage(fsi_t *fsi) +{ + pthread_mutex_lock(&fsi_lock); + fsip_fs_free(fsi); + pthread_mutex_unlock(&fsi_lock); +} + +int fsi_file_exists(fsi_t *fsi, const char *path) +{ + fsi_file_t *ffi; + + if ((ffi = fsi_open_file(fsi, path)) == NULL) + return (0); + + fsi_close_file(ffi); + return (1); +} + +fsi_file_t *fsi_open_file(fsi_t *fsi, const char *path) +{ + fsi_plugin_ops_t *ops; + fsi_file_t *ffi; + + pthread_mutex_lock(&fsi_lock); + ops = fsi->f_plugin->fp_ops; + ffi = ops->fpo_open(fsi, path); + pthread_mutex_unlock(&fsi_lock); + + return (ffi); +} + +int fsi_close_file(fsi_file_t *ffi) +{ + fsi_plugin_ops_t *ops; + int err; + + pthread_mutex_lock(&fsi_lock); + ops = ffi->ff_fsi->f_plugin->fp_ops; + err = ops->fpo_close(ffi); + pthread_mutex_unlock(&fsi_lock); + + return (err); +} + +ssize_t fsi_read_file(fsi_file_t *ffi, void *buf, size_t nbytes) +{ + fsi_plugin_ops_t *ops; + ssize_t ret; + + pthread_mutex_lock(&fsi_lock); + ops = ffi->ff_fsi->f_plugin->fp_ops; + ret = ops->fpo_read(ffi, buf, nbytes); + pthread_mutex_unlock(&fsi_lock); + + return (ret); +} + +ssize_t fsi_pread_file(fsi_file_t *ffi, void *buf, size_t nbytes, uint64_t off) +{ + fsi_plugin_ops_t *ops; + ssize_t ret; + + pthread_mutex_lock(&fsi_lock); + ops = ffi->ff_fsi->f_plugin->fp_ops; + ret = ops->fpo_pread(ffi, buf, nbytes, off); + pthread_mutex_unlock(&fsi_lock); + + return (ret); +} diff --git a/tools/libfsimage/common/fsimage.h b/tools/libfsimage/common/fsimage.h new file mode 100644 index 0000000000..28165ef29d --- /dev/null +++ b/tools/libfsimage/common/fsimage.h @@ -0,0 +1,52 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FSIMAGE_H +#define _FSIMAGE_H + +#ifdef __cplusplus +extern C { +#endif + +#include <sys/types.h> +#include <stdint.h> +#include <unistd.h> + +typedef struct fsi fsi_t; +typedef struct fsi_file fsi_file_t; + +fsi_t *fsi_open_fsimage(const char *, uint64_t); +void fsi_close_fsimage(fsi_t *); + +int fsi_file_exists(fsi_t *, const char *); +fsi_file_t *fsi_open_file(fsi_t *, const char *); +int fsi_close_file(fsi_file_t *); + +ssize_t fsi_read_file(fsi_file_t *, void *, size_t); +ssize_t fsi_pread_file(fsi_file_t *, void *, size_t, uint64_t); + +#ifdef __cplusplus +}; +#endif + +#endif /* _FSIMAGE_H */ diff --git a/tools/libfsimage/common/fsimage_grub.c b/tools/libfsimage/common/fsimage_grub.c new file mode 100644 index 0000000000..6f3f290634 --- /dev/null +++ b/tools/libfsimage/common/fsimage_grub.c @@ -0,0 +1,277 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef __sun__ +#define _XOPEN_SOURCE 500 +#endif +#include <stdlib.h> +#include <strings.h> +#include <errno.h> + +#include "fsimage_grub.h" +#include "fsimage_priv.h" + +static char *disk_read_junk; + +typedef struct fsig_data { + char fd_buf[FSYS_BUFLEN]; +} fsig_data_t; + +typedef struct fsig_file_data { + char ffd_buf[FSYS_BUFLEN]; + uint64_t ffd_curpos; + uint64_t ffd_filepos; + uint64_t ffd_filemax; + int ffd_int1; + int ffd_int2; + int ffd_errnum; +} fsig_file_data_t; + +fsi_file_t * +fsig_file_alloc(fsi_t *fsi) +{ + fsi_file_t *ffi; + fsig_file_data_t *data = malloc(sizeof (fsig_file_data_t)); + + if (data == NULL) + return (NULL); + + bzero(data, sizeof (fsig_file_data_t)); + bcopy(fsig_fs_buf(fsi), data->ffd_buf, FSYS_BUFLEN); + + if ((ffi = fsip_file_alloc(fsi, data)) == NULL) { + free(data); + return (NULL); + } + + return (ffi); +} + +void * +fsig_fs_buf(fsi_t *fsi) +{ + fsig_data_t *data = fsip_fs_data(fsi); + return ((void *)data->fd_buf); +} + +void * +fsig_file_buf(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return ((void *)data->ffd_buf); +} + +uint64_t * +fsig_filepos(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return (&data->ffd_filepos); +} + +uint64_t * +fsig_filemax(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return (&data->ffd_filemax); +} + +int * +fsig_int1(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return (&data->ffd_int1); +} + +int * +fsig_int2(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return (&data->ffd_int2); +} + +int * +fsig_errnum(fsi_file_t *ffi) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + return (&data->ffd_errnum); +} + +char ** +fsig_disk_read_junk(void) +{ + return (&disk_read_junk); +} + +int +fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset, + unsigned int bufsize, char *buf) +{ + uint64_t off = ffi->ff_fsi->f_off + ((uint64_t)(sector * 512)) + offset; + ssize_t bytes_read = 0; + + while (bufsize) { + ssize_t ret = pread(ffi->ff_fsi->f_fd, buf + bytes_read, + bufsize, (off_t)off); + if (ret == -1) + return (0); + if (ret == 0) + return (0); + + bytes_read += ret; + bufsize -= ret; + } + + return (1); +} + +int +fsig_substring(const char *s1, const char *s2) +{ + while (*s1 == *s2) { + if (*s1 == '\0') + return (0); + s1++; + s2++; + } + + if (*s1 == '\0') + return (-1); + + return (1); +} + +static int +fsig_mount(fsi_t *fsi, const char *path) +{ + fsig_plugin_ops_t *ops = fsi->f_plugin->fp_data; + fsi_file_t *ffi; + fsi->f_data = malloc(sizeof (fsig_data_t)); + + if (fsi->f_data == NULL) + return (-1); + + if ((ffi = fsig_file_alloc(fsi)) == NULL) { + free(fsi->f_data); + fsi->f_data = NULL; + return (-1); + } + + bzero(fsi->f_data, sizeof (fsig_data_t)); + + if (!ops->fpo_mount(ffi)) { + fsip_file_free(ffi); + free(fsi->f_data); + fsi->f_data = NULL; + return (-1); + } + + bcopy(fsig_file_buf(ffi), fsig_fs_buf(fsi), FSYS_BUFLEN); + fsip_file_free(ffi); + return (0); +} + +static int +fsig_umount(fsi_t *fsi) +{ + fsip_fs_free(fsi); + return (0); +} + +static fsi_file_t * +fsig_open(fsi_t *fsi, const char *name) +{ + fsig_plugin_ops_t *ops = fsi->f_plugin->fp_data; + char *path = strdup(name); + fsi_file_t *ffi = NULL; + + if (path == NULL || (ffi = fsig_file_alloc(fsi)) == NULL) + goto out; + + if (ops->fpo_dir(ffi, path) == 0) { + fsip_file_free(ffi); + ffi = NULL; + errno = ENOENT; + } + +out: + free(path); + return (ffi); +} + +static ssize_t +fsig_pread(fsi_file_t *ffi, void *buf, size_t nbytes, uint64_t off) +{ + fsig_plugin_ops_t *ops = ffi->ff_fsi->f_plugin->fp_data; + fsig_file_data_t *data = fsip_file_data(ffi); + + data->ffd_filepos = off; + + if (data->ffd_filepos >= data->ffd_filemax) + return (0); + + /* FIXME: check */ + if (data->ffd_filepos + nbytes > data->ffd_filemax) + nbytes = data->ffd_filemax - data->ffd_filepos; + + errnum = 0; + return (ops->fpo_read(ffi, buf, nbytes)); +} + +static ssize_t +fsig_read(fsi_file_t *ffi, void *buf, size_t nbytes) +{ + fsig_file_data_t *data = fsip_file_data(ffi); + ssize_t ret; + + ret = fsig_pread(ffi, buf, nbytes, data->ffd_curpos); + data->ffd_curpos = data->ffd_filepos; + return (ret); +} + +static int +fsig_close(fsi_file_t *ffi) +{ + fsip_file_free(ffi); + return (0); +} + +static fsi_plugin_ops_t fsig_grub_ops = { + .fpo_version = FSIMAGE_PLUGIN_VERSION, + .fpo_mount = fsig_mount, + .fpo_umount = fsig_umount, + .fpo_open = fsig_open, + .fpo_read = fsig_read, + .fpo_pread = fsig_pread, + .fpo_close = fsig_close +}; + +fsi_plugin_ops_t * +fsig_init(fsi_plugin_t *plugin, fsig_plugin_ops_t *ops) +{ + if (ops->fpo_version > FSIMAGE_PLUGIN_VERSION) + return (NULL); + + plugin->fp_data = ops; + + return (&fsig_grub_ops); +} diff --git a/tools/libfsimage/common/fsimage_grub.h b/tools/libfsimage/common/fsimage_grub.h new file mode 100644 index 0000000000..38db2a219c --- /dev/null +++ b/tools/libfsimage/common/fsimage_grub.h @@ -0,0 +1,92 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FSIMAGE_GRUB_H +#define _FSIMAGE_GRUB_H + +#ifdef __cplusplus +extern C { +#endif + +#include <sys/types.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> + +#include "fsimage.h" +#include "fsimage_plugin.h" + +typedef struct fsig_plugin_ops { + int fpo_version; + int (*fpo_mount)(fsi_file_t *); + int (*fpo_dir)(fsi_file_t *, char *); + int (*fpo_read)(fsi_file_t *, char *, int); +} fsig_plugin_ops_t; + +#define STAGE1_5 +#define FSYS_BUFLEN 0x8000 +#define SECTOR_BITS 9 +#define SECTOR_SIZE 0x200 + +#define FSYS_BUF (fsig_file_buf(ffi)) +#define filepos (*fsig_filepos(ffi)) +#define filemax (*fsig_filemax(ffi)) +#define devread fsig_devread +#define substring fsig_substring +#define errnum (*fsig_errnum(ffi)) +#define disk_read_func (*fsig_disk_read_junk()) +#define disk_read_hook (*fsig_disk_read_junk()) +#define print_possibilities 0 + +#define grub_memset memset +#define grub_memmove memmove + +extern char **fsig_disk_read_junk(void); + +#define ERR_FSYS_CORRUPT 1 +#define ERR_SYMLINK_LOOP 1 +#define ERR_FILELENGTH 1 +#define ERR_BAD_FILETYPE 1 +#define ERR_BAD_FILETYPE 1 +#define ERR_FILE_NOT_FOUND 1 + +fsi_plugin_ops_t *fsig_init(fsi_plugin_t *, fsig_plugin_ops_t *); + +int fsig_devread(fsi_file_t *, unsigned int, unsigned int, unsigned int, char *); +int fsig_substring(const char *, const char *); + +void *fsig_fs_buf(fsi_t *); + +fsi_file_t *fsig_file_alloc(fsi_t *); +void *fsig_file_buf(fsi_file_t *); +uint64_t *fsig_filepos(fsi_file_t *); +uint64_t *fsig_filemax(fsi_file_t *); +int *fsig_int1(fsi_file_t *); +int *fsig_int2(fsi_file_t *); +int *fsig_errnum(fsi_file_t *); + +#ifdef __cplusplus +}; +#endif + +#endif /* _FSIMAGE_GRUB_H */ diff --git a/tools/libfsimage/common/fsimage_plugin.c b/tools/libfsimage/common/fsimage_plugin.c new file mode 100644 index 0000000000..71099ba2ff --- /dev/null +++ b/tools/libfsimage/common/fsimage_plugin.c @@ -0,0 +1,214 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#include <stdlib.h> +#include <stdio.h> +#include <strings.h> +#include <string.h> +#include <dirent.h> +#include <dlfcn.h> +#include <errno.h> + +#include "fsimage_plugin.h" +#include "fsimage_priv.h" + +static fsi_plugin_t *plugins; + +void +fsip_fs_set_data(fsi_t *fsi, void *data) +{ + fsi->f_data = data; +} + +void +fsip_fs_free(fsi_t *fsi) +{ + free(fsi->f_data); + free(fsi); +} + +fsi_file_t * +fsip_file_alloc(fsi_t *fsi, void *data) +{ + fsi_file_t *ffi = malloc(sizeof (fsi_file_t)); + if (ffi == NULL) + return (NULL); + + bzero(ffi, sizeof (fsi_file_t)); + + ffi->ff_fsi = fsi; + ffi->ff_data = data; + return (ffi); +} + +void +fsip_file_free(fsi_file_t *ffi) +{ + free(ffi->ff_data); + free(ffi); +} + +fsi_t * +fsip_fs(fsi_file_t *ffi) +{ + return (ffi->ff_fsi); +} + +uint64_t +fsip_fs_offset(fsi_t *fsi) +{ + return (fsi->f_off); +} + +void * +fsip_fs_data(fsi_t *fsi) +{ + return (fsi->f_data); +} + +void * +fsip_file_data(fsi_file_t *ffi) +{ + return (ffi->ff_data); +} + +static int init_plugin(const char *lib) +{ + fsi_plugin_init_t init; + fsi_plugin_t *fp = malloc(sizeof (fsi_plugin_t)); + + if (fp == NULL) + return (-1); + + bzero(fp, sizeof (fsi_plugin_t)); + + if ((fp->fp_dlh = dlopen(lib, RTLD_LAZY | RTLD_LOCAL)) == NULL) { + free(fp); + return (0); + } + + init = dlsym(fp->fp_dlh, "fsi_init_plugin"); + + if (init == NULL) + goto fail; + + fp->fp_ops = init(FSIMAGE_PLUGIN_VERSION, fp, &fp->fp_name); + if (fp->fp_ops == NULL || + fp->fp_ops->fpo_version > FSIMAGE_PLUGIN_VERSION) + goto fail; + + fp->fp_next = plugins; + plugins = fp; + + return (0); +fail: + (void) dlclose(fp->fp_dlh); + free(fp); + return (-1); +} + +static int load_plugins(void) +{ + const char *fsdir = getenv("FSIMAGE_FSDIR"); + const char *isadir = ""; + struct dirent *dp = NULL; + struct dirent *dpp; + DIR *dir = NULL; + char *tmp = NULL; + size_t name_max; + int err; + int ret = -1; + +#ifdef __sun__ + if (fsdir == NULL) + fsdir = "/usr/lib/fs"; + + if (sizeof(void *) == 8) + isadir = "64/"; +#else + if (fsdir == NULL) { + if (sizeof(void *) == 8) + fsdir = "/usr/lib64/fs"; + else + fsdir = "/usr/lib/fs"; + } +#endif + + if ((name_max = pathconf(fsdir, _PC_NAME_MAX)) == -1) + goto fail; + + if ((tmp = malloc(name_max + 1)) == NULL) + goto fail; + + if ((dp = malloc(sizeof (struct dirent) + name_max + 1)) == NULL) + goto fail; + + if ((dir = opendir(fsdir)) == NULL) + goto fail; + + bzero(dp, sizeof (struct dirent) + name_max + 1); + + while (readdir_r(dir, dp, &dpp) == 0 && dpp != NULL) { + if (strcmp(dpp->d_name, ".") == 0) + continue; + if (strcmp(dpp->d_name, "..") == 0) + continue; + + (void) snprintf(tmp, name_max, "%s/%s/%sfsimage.so", fsdir, + dpp->d_name, isadir); + + if (init_plugin(tmp) != 0) + goto fail; + } + + ret = 0; + +fail: + err = errno; + if (dir != NULL) + (void) closedir(dir); + free(tmp); + free(dp); + errno = err; + return (ret); +} + +int find_plugin(fsi_t *fsi, const char *path) +{ + fsi_plugin_t *fp; + int ret = 0; + + if (plugins == NULL && (ret = load_plugins()) != 0) + goto out; + + for (fp = plugins; fp != NULL; fp = fp->fp_next) { + fsi->f_plugin = fp; + if (fp->fp_ops->fpo_mount(fsi, path) == 0) + goto out; + } + + ret = -1; + errno = ENOTSUP; +out: + return (ret); +} diff --git a/tools/libfsimage/common/fsimage_plugin.h b/tools/libfsimage/common/fsimage_plugin.h new file mode 100644 index 0000000000..4592e08be7 --- /dev/null +++ b/tools/libfsimage/common/fsimage_plugin.h @@ -0,0 +1,65 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FSIMAGE_PLUGIN_H +#define _FSIMAGE_PLUGIN_H + +#ifdef __cplusplus +extern C { +#endif + +#include <sys/types.h> + +#include "fsimage.h" + +#define FSIMAGE_PLUGIN_VERSION 1 + +typedef struct fsi_plugin fsi_plugin_t; + +typedef struct fsi_plugin_ops { + int fpo_version; + int (*fpo_mount)(fsi_t *, const char *); + int (*fpo_umount)(fsi_t *); + fsi_file_t *(*fpo_open)(fsi_t *, const char *); + ssize_t (*fpo_read)(fsi_file_t *, void *, size_t); + ssize_t (*fpo_pread)(fsi_file_t *, void *, size_t, uint64_t); + int (*fpo_close)(fsi_file_t *); +} fsi_plugin_ops_t; + +typedef fsi_plugin_ops_t * + (*fsi_plugin_init_t)(int, fsi_plugin_t *, const char **); + +void fsip_fs_set_data(fsi_t *, void *); +void fsip_fs_free(fsi_t *); +fsi_file_t *fsip_file_alloc(fsi_t *, void *); +void fsip_file_free(fsi_file_t *); +fsi_t * fsip_fs(fsi_file_t *ffi); +uint64_t fsip_fs_offset(fsi_t *fsi); +void *fsip_fs_data(fsi_t *); +void *fsip_file_data(fsi_file_t *); + +#ifdef __cplusplus +}; +#endif + +#endif /* _FSIMAGE_PLUGIN_H */ diff --git a/tools/libfsimage/common/fsimage_priv.h b/tools/libfsimage/common/fsimage_priv.h new file mode 100644 index 0000000000..cf0dfe6612 --- /dev/null +++ b/tools/libfsimage/common/fsimage_priv.h @@ -0,0 +1,62 @@ +/* + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _FSIMAGE_PRIV_H +#define _FSIMAGE_PRIV_H + +#ifdef __cplusplus +extern C { +#endif + +#include <sys/types.h> + +#include "fsimage.h" +#include "fsimage_plugin.h" + +struct fsi_plugin { + const char *fp_name; + void *fp_dlh; + fsi_plugin_ops_t *fp_ops; + struct fsi_plugin *fp_next; + void *fp_data; +}; + +struct fsi { + int f_fd; + uint64_t f_off; + void *f_data; + fsi_plugin_t *f_plugin; +}; + +struct fsi_file { + fsi_t *ff_fsi; + void *ff_data; +}; + +int find_plugin(fsi_t *, const char *); + +#ifdef __cplusplus +}; +#endif + +#endif /* _FSIMAGE_PRIV_H */ diff --git a/tools/libfsimage/common/mapfile-GNU b/tools/libfsimage/common/mapfile-GNU new file mode 100644 index 0000000000..f15060cba4 --- /dev/null +++ b/tools/libfsimage/common/mapfile-GNU @@ -0,0 +1,37 @@ +VERSION { + libfsimage.so.1.1 { + global: + fsi_open_fsimage; + fsi_close_fsimage; + fsi_file_exists; + fsi_open_file; + fsi_close_file; + fsi_read_file; + fsi_pread_file; + + fsip_fs_set_data; + fsip_fs_free; + fsip_file_alloc; + fsip_file_free; + fsip_fs; + fsip_fs_offset; + fsip_fs_data; + fsip_file_data; + + fsig_init; + fsig_devread; + fsig_substring; + fsig_fs_buf; + fsig_file_alloc; + fsig_file_buf; + fsig_filepos; + fsig_filemax; + fsig_int1; + fsig_int2; + fsig_errnum; + fsig_disk_read_junk; + + local: + *; + }; +} diff --git a/tools/libfsimage/common/mapfile-SunOS b/tools/libfsimage/common/mapfile-SunOS new file mode 100644 index 0000000000..1ea38bed04 --- /dev/null +++ b/tools/libfsimage/common/mapfile-SunOS @@ -0,0 +1,35 @@ +libfsimage.so.1.1 { + global: + fsi_open_fsimage; + fsi_close_fsimage; + fsi_file_exists; + fsi_open_file; + fsi_close_file; + fsi_read_file; + fsi_pread_file; + + fsip_fs_set_data; + fsip_fs_free; + fsip_file_alloc; + fsip_file_free; + fsip_fs; + fsip_fs_data; + fsip_fs_offset; + fsip_file_data; + + fsig_init; + fsig_devread; + fsig_substring; + fsig_fs_buf; + fsig_file_alloc; + fsig_file_buf; + fsig_filepos; + fsig_filemax; + fsig_int1; + fsig_int2; + fsig_errnum; + fsig_disk_read_junk; + + local: + *; +}; |