xref: /onnv-gate/usr/src/lib/libparted/common/libparted/libparted.c (revision 9663:ace9a2ac3683)
1 /*
2     libparted - a library for manipulating disk partitions
3     Copyright (C) 1999, 2000, 2001, 2007 Free Software Foundation, Inc.
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 3 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #include <config.h>
20 #include "configmake.h"
21 
22 #include <parted/parted.h>
23 #include <parted/debug.h>
24 
25 #ifdef linux
26 #  include <parted/linux.h>
27 #elif defined(__BEOS__)
28 #  include <parted/beos.h>
29 #elif defined(__sun)
30 #  include <parted/solaris.h>
31 #else
32 #  include <parted/gnu.h>
33 #endif
34 
35 #if ENABLE_NLS
36 #  include <locale.h>
37 #  include <libintl.h>
38 #  define _(String) dgettext (PACKAGE, String)
39 #else
40 #  define _(String) (String)
41 #endif /* ENABLE_NLS */
42 
43 const PedArchitecture* ped_architecture;
44 
45 /* ped_malloc() debugging.  Stick the address and size of memory blocks that
46  * weren't ped_free()d in here, and an exception will be thrown when it is
47  * allocated.  That way, you can find out what, exactly, the allocated thing
48  * is, and where it is created.
49  */
50 typedef struct
51 {
52     void*	pointer;
53     size_t	size;
54 } pointer_size_type;
55 
56 /* IMHO, none of the DEBUG-related code below is useful, and the
57    ped_malloc memset code is actually quite harmful: it masked at
58    least two nasty bugs that were fixed in June of 2007.  */
59 #undef DEBUG
60 #ifdef DEBUG
61 static pointer_size_type dodgy_malloc_list[] = {
62  {0,		0},
63  {0,		0},
64  {0,		0},
65  {0,		0},
66  {0,		0},
67  {0,		0},
68  {0,		0},
69  {0,		0},
70  {0,		0},
71  {0,		0}
72 };
73 
74 static int	dodgy_memory_active[100];
75 #endif /* DEBUG */
76 
77 int
ped_set_architecture(const PedArchitecture * arch)78 ped_set_architecture (const PedArchitecture* arch)
79 {
80 	PED_ASSERT (ped_device_get_next (NULL) == NULL, return 0);
81 
82 	ped_architecture = arch;
83 	return 1;
84 }
85 
86 extern void ped_disk_aix_init ();
87 extern void ped_disk_bsd_init ();
88 extern void ped_disk_dvh_init ();
89 extern void ped_disk_gpt_init ();
90 extern void ped_disk_loop_init ();
91 extern void ped_disk_mac_init ();
92 extern void ped_disk_msdos_init ();
93 extern void ped_disk_pc98_init ();
94 extern void ped_disk_sun_init ();
95 extern void ped_disk_amiga_init ();
96 extern void ped_disk_dasd_init ();
97 
98 static void
init_disk_types()99 init_disk_types ()
100 {
101 	ped_disk_loop_init ();	/* must be last in the probe list */
102 
103 #if defined(__s390__) || defined(__s390x__)
104 	ped_disk_dasd_init();
105 #endif
106 
107 	ped_disk_sun_init ();
108 #ifdef ENABLE_PC98
109 	ped_disk_pc98_init ();
110 #endif
111 	ped_disk_msdos_init ();
112 	ped_disk_mac_init ();
113 	ped_disk_gpt_init ();
114 	ped_disk_dvh_init ();
115 	ped_disk_bsd_init ();
116 	ped_disk_amiga_init ();
117 	ped_disk_aix_init ();
118 }
119 
120 #ifdef ENABLE_FS
121 extern void ped_file_system_amiga_init (void);
122 extern void ped_file_system_xfs_init (void);
123 extern void ped_file_system_ufs_init (void);
124 extern void ped_file_system_reiserfs_init (void);
125 extern void ped_file_system_ntfs_init (void);
126 extern void ped_file_system_linux_swap_init (void);
127 extern void ped_file_system_jfs_init (void);
128 extern void ped_file_system_hfs_init (void);
129 extern void ped_file_system_fat_init (void);
130 extern void ped_file_system_ext2_init (void);
131 extern void ped_file_system_solaris_x86_init (void);
132 
133 static void
init_file_system_types()134 init_file_system_types ()
135 {
136 	ped_file_system_amiga_init ();
137 	ped_file_system_xfs_init ();
138 	ped_file_system_ufs_init ();
139 	ped_file_system_reiserfs_init ();
140 	ped_file_system_ntfs_init ();
141 	ped_file_system_linux_swap_init ();
142 	ped_file_system_jfs_init ();
143 	ped_file_system_hfs_init ();
144 	ped_file_system_fat_init ();
145 	ped_file_system_ext2_init ();
146 	ped_file_system_solaris_x86_init ();
147 }
148 #endif /* ENABLE_FS */
149 
150 extern void ped_disk_aix_done ();
151 extern void ped_disk_bsd_done ();
152 extern void ped_disk_dvh_done ();
153 extern void ped_disk_gpt_done ();
154 extern void ped_disk_loop_done ();
155 extern void ped_disk_mac_done ();
156 extern void ped_disk_msdos_done ();
157 extern void ped_disk_pc98_done ();
158 extern void ped_disk_sun_done ();
159 extern void ped_disk_amiga_done ();
160 extern void ped_disk_dasd_done ();
161 
162 static void
done_disk_types()163 done_disk_types ()
164 {
165 #if defined(__s390__) || (__s390x__)
166 	ped_disk_dasd_done ();
167 #endif
168 	ped_disk_sun_done ();
169 #ifdef ENABLE_PC98
170 	ped_disk_pc98_done ();
171 #endif
172 	ped_disk_msdos_done ();
173 	ped_disk_mac_done ();
174 	ped_disk_loop_done ();
175 	ped_disk_gpt_done ();
176 	ped_disk_dvh_done ();
177 	ped_disk_bsd_done ();
178 	ped_disk_amiga_done ();
179 	ped_disk_aix_done ();
180 }
181 
182 static void _init() __attribute__ ((constructor));
183 
184 static void
_init()185 _init()
186 {
187 #ifdef ENABLE_NLS
188 	bindtextdomain (PACKAGE, LOCALEDIR);
189 #endif
190 
191 	init_disk_types ();
192 
193 #ifdef ENABLE_FS
194 	init_file_system_types ();
195 #endif
196 
197 	/* FIXME: a better way of doing this? */
198 #ifdef linux
199 	ped_set_architecture (&ped_linux_arch);
200 #elif defined(__BEOS__)
201 	ped_set_architecture (&ped_beos_arch);
202 #elif defined (__sun)
203 	ped_set_architecture (&ped_solaris_arch);
204 #else
205 	ped_set_architecture (&ped_gnu_arch);
206 #endif
207 
208 #ifdef DEBUG
209 	memset (dodgy_memory_active, 0, sizeof (dodgy_memory_active));
210 #endif
211 }
212 
213 #ifdef ENABLE_FS
214 extern void ped_file_system_ext2_done (void);
215 extern void ped_file_system_fat_done (void);
216 extern void ped_file_system_hfs_done (void);
217 extern void ped_file_system_jfs_done (void);
218 extern void ped_file_system_linux_swap_done (void);
219 extern void ped_file_system_ntfs_done (void);
220 extern void ped_file_system_reiserfs_done (void);
221 extern void ped_file_system_ufs_done (void);
222 extern void ped_file_system_xfs_done (void);
223 extern void ped_file_system_amiga_done (void);
224 
225 static void
done_file_system_types()226 done_file_system_types ()
227 {
228 	ped_file_system_ext2_done ();
229 	ped_file_system_fat_done ();
230 	ped_file_system_hfs_done ();
231 	ped_file_system_jfs_done ();
232 	ped_file_system_linux_swap_done ();
233 	ped_file_system_ntfs_done ();
234 	ped_file_system_reiserfs_done ();
235 	ped_file_system_ufs_done ();
236 	ped_file_system_xfs_done ();
237 	ped_file_system_amiga_done ();
238 }
239 #endif /* ENABLE_FS */
240 
241 static void _done() __attribute__ ((destructor));
242 
243 static void
_done()244 _done()
245 {
246 	ped_device_free_all ();
247 
248 	done_disk_types ();
249 
250 #ifdef ENABLE_FS
251 	done_file_system_types ();
252 #endif
253 }
254 
255 const char*
ped_get_version()256 ped_get_version ()
257 {
258 	return VERSION;
259 }
260 
261 #ifdef DEBUG
262 static void
_check_dodgy_pointer(const void * ptr,size_t size,int is_malloc)263 _check_dodgy_pointer (const void* ptr, size_t size, int is_malloc)
264 {
265 	int		i;
266 
267 	for (i=0; dodgy_malloc_list[i].pointer; i++) {
268 		if (dodgy_malloc_list[i].pointer != ptr)
269  			continue;
270 		if (is_malloc && dodgy_malloc_list[i].size != size)
271 			continue;
272 		if (!is_malloc && !dodgy_memory_active[i])
273 			continue;
274 
275 
276 		if (is_malloc) {
277 			ped_exception_throw (
278 				PED_EXCEPTION_INFORMATION,
279 				PED_EXCEPTION_OK,
280 				"Dodgy malloc(%x) == %p occurred (active==%d)",
281 				size, ptr, dodgy_memory_active[i]);
282 			dodgy_memory_active[i]++;
283 		} else {
284 			ped_exception_throw (
285 				PED_EXCEPTION_INFORMATION,
286 				PED_EXCEPTION_OK,
287 				"Dodgy free(%p) occurred (active==%d)",
288 				ptr, dodgy_memory_active[i]);
289 			dodgy_memory_active[i]--;
290 		}
291 
292 		return;
293 	}
294 }
295 #endif /* DEBUG */
296 
297 void*
ped_malloc(size_t size)298 ped_malloc (size_t size)
299 {
300 	void*		mem;
301 
302 	mem = (void*) malloc (size);
303 	if (!mem) {
304 		ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL,
305 				     _("Out of memory."));
306 		return NULL;
307 	}
308 
309 #ifdef DEBUG
310 	memset (mem, 0xff, size);
311 	_check_dodgy_pointer (mem, size, 1);
312 #endif
313 
314 	return mem;
315 }
316 
317 int
ped_realloc(void ** old,size_t size)318 ped_realloc (void** old, size_t size)
319 {
320 	void*		mem;
321 
322 	mem = (void*) realloc (*old, size);
323 	if (!mem) {
324 		ped_exception_throw (PED_EXCEPTION_FATAL, PED_EXCEPTION_CANCEL,
325 				     _("Out of memory."));
326 		return 0;
327 	}
328 	*old = mem;
329 	return 1;
330 }
331 
332 
ped_calloc(size_t size)333 void* ped_calloc (size_t size)
334 {
335         void* buf = ped_malloc (size);
336 
337         memset (buf, 0, size);
338 
339         return buf;
340 }
341 
342 
343 void
ped_free(void * ptr)344 ped_free (void* ptr)
345 {
346 #ifdef DEBUG
347 	_check_dodgy_pointer (ptr, 0, 0);
348 #endif
349 
350 	free (ptr);
351 }
352