1 /*
2 * Permission is hereby granted, free of charge, to any person obtaining a copy
3 * of this software and associated documentation files (the "Software"), to
4 * deal in the Software without restriction, including without limitation the
5 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
6 * sell copies of the Software, and to permit persons to whom the Software is
7 * furnished to do so, subject to the following conditions:
8 *
9 * The above copyright notice and this permission notice shall be included in
10 * all copies or substantial portions of the Software.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
16 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
17 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
18 * DEALINGS IN THE SOFTWARE.
19 *
20 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
21 * Use is subject to license terms.
22 */
23
24 #include <sys/stat.h>
25 #include <sys/types.h>
26 #include <strings.h>
27 #include <unistd.h>
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <errno.h>
32 #include <pthread.h>
33
34 #include "xenfsimage_plugin.h"
35 #include "fsimage_priv.h"
36
37 static pthread_mutex_t fsi_lock = PTHREAD_MUTEX_INITIALIZER;
38
fsi_open_fsimage(const char * path,uint64_t off,const char * options)39 fsi_t *fsi_open_fsimage(const char *path, uint64_t off, const char *options)
40 {
41 fsi_t *fsi = NULL;
42 int fd;
43 int err;
44
45 if ((fd = open(path, O_RDONLY)) == -1)
46 goto fail;
47
48 if ((fsi = malloc(sizeof(*fsi))) == NULL)
49 goto fail;
50
51 fsi->f_fd = fd;
52 fsi->f_off = off;
53 fsi->f_data = NULL;
54 fsi->f_bootstring = NULL;
55
56 pthread_mutex_lock(&fsi_lock);
57 err = find_plugin(fsi, path, options);
58 pthread_mutex_unlock(&fsi_lock);
59 if (err != 0)
60 goto fail;
61
62 return (fsi);
63
64 fail:
65 err = errno;
66 if (fd != -1)
67 (void) close(fd);
68 free(fsi);
69 errno = err;
70 return (NULL);
71 }
72
fsi_close_fsimage(fsi_t * fsi)73 void fsi_close_fsimage(fsi_t *fsi)
74 {
75 pthread_mutex_lock(&fsi_lock);
76 fsi->f_plugin->fp_ops->fpo_umount(fsi);
77 (void) close(fsi->f_fd);
78 free(fsi);
79 pthread_mutex_unlock(&fsi_lock);
80 }
81
fsi_file_exists(fsi_t * fsi,const char * path)82 int fsi_file_exists(fsi_t *fsi, const char *path)
83 {
84 fsi_file_t *ffi;
85
86 if ((ffi = fsi_open_file(fsi, path)) == NULL)
87 return (0);
88
89 fsi_close_file(ffi);
90 return (1);
91 }
92
fsi_open_file(fsi_t * fsi,const char * path)93 fsi_file_t *fsi_open_file(fsi_t *fsi, const char *path)
94 {
95 fsi_plugin_ops_t *ops;
96 fsi_file_t *ffi;
97
98 pthread_mutex_lock(&fsi_lock);
99 ops = fsi->f_plugin->fp_ops;
100 ffi = ops->fpo_open(fsi, path);
101 pthread_mutex_unlock(&fsi_lock);
102
103 return (ffi);
104 }
105
fsi_close_file(fsi_file_t * ffi)106 int fsi_close_file(fsi_file_t *ffi)
107 {
108 fsi_plugin_ops_t *ops;
109 int err;
110
111 pthread_mutex_lock(&fsi_lock);
112 ops = ffi->ff_fsi->f_plugin->fp_ops;
113 err = ops->fpo_close(ffi);
114 pthread_mutex_unlock(&fsi_lock);
115
116 return (err);
117 }
118
fsi_read_file(fsi_file_t * ffi,void * buf,size_t nbytes)119 ssize_t fsi_read_file(fsi_file_t *ffi, void *buf, size_t nbytes)
120 {
121 fsi_plugin_ops_t *ops;
122 ssize_t ret;
123
124 pthread_mutex_lock(&fsi_lock);
125 ops = ffi->ff_fsi->f_plugin->fp_ops;
126 ret = ops->fpo_read(ffi, buf, nbytes);
127 pthread_mutex_unlock(&fsi_lock);
128
129 return (ret);
130 }
131
fsi_pread_file(fsi_file_t * ffi,void * buf,size_t nbytes,uint64_t off)132 ssize_t fsi_pread_file(fsi_file_t *ffi, void *buf, size_t nbytes, uint64_t off)
133 {
134 fsi_plugin_ops_t *ops;
135 ssize_t ret;
136
137 pthread_mutex_lock(&fsi_lock);
138 ops = ffi->ff_fsi->f_plugin->fp_ops;
139 ret = ops->fpo_pread(ffi, buf, nbytes, off);
140 pthread_mutex_unlock(&fsi_lock);
141
142 return (ret);
143 }
144
145 char *
fsi_bootstring_alloc(fsi_t * fsi,size_t len)146 fsi_bootstring_alloc(fsi_t *fsi, size_t len)
147 {
148 fsi->f_bootstring = malloc(len);
149 if (fsi->f_bootstring == NULL)
150 return (NULL);
151
152 bzero(fsi->f_bootstring, len);
153 return (fsi->f_bootstring);
154 }
155
156 void
fsi_bootstring_free(fsi_t * fsi)157 fsi_bootstring_free(fsi_t *fsi)
158 {
159 if (fsi->f_bootstring != NULL) {
160 free(fsi->f_bootstring);
161 fsi->f_bootstring = NULL;
162 }
163 }
164
165 char *
fsi_fs_bootstring(fsi_t * fsi)166 fsi_fs_bootstring(fsi_t *fsi)
167 {
168 return (fsi->f_bootstring);
169 }
170