Lines 39-44
Link Here
|
39 |
#include "gpt.h" |
39 |
#include "gpt.h" |
40 |
#include "ldm.h" |
40 |
#include "ldm.h" |
41 |
|
41 |
|
|
|
42 |
#define DM_UUID_PREFIX "LDM-" |
43 |
|
42 |
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-" \ |
44 |
#define UUID_FMT "%02x%02x%02x%02x-%02x%02x-%02x%02x-" \ |
43 |
"%02x%02x-%02x%02x%02x%02x%02x%02x" |
45 |
"%02x%02x-%02x%02x%02x%02x%02x%02x" |
44 |
#define UUID_VALS(uuid) (uuid)[0], (uuid)[1], (uuid)[2], (uuid)[3], \ |
46 |
#define UUID_VALS(uuid) (uuid)[0], (uuid)[1], (uuid)[2], (uuid)[3], \ |
Lines 234-239
Link Here
|
234 |
return etype; |
236 |
return etype; |
235 |
} |
237 |
} |
236 |
|
238 |
|
|
|
239 |
/* We catch log messages generated by device mapper with errno != 0 and store |
240 |
* them here */ |
241 |
static int _dm_err_last_level = 0; |
242 |
static const char *_dm_err_last_file = NULL; |
243 |
static int _dm_err_last_line = 0; |
244 |
static int _dm_err_last_errno = 0; |
245 |
static char *_dm_err_last_msg = NULL; |
246 |
|
247 |
static void |
248 |
_dm_log_fn(const int level, const char * const file, const int line, |
249 |
const int dm_errno, const char *f, ...) |
250 |
{ |
251 |
if (dm_errno == 0) return; |
252 |
|
253 |
_dm_err_last_level = level; |
254 |
_dm_err_last_file = file; |
255 |
_dm_err_last_line = line; |
256 |
|
257 |
/* device-mapper doesn't set dm_errno usefully (it only seems to use |
258 |
* EUNCLASSIFIED), so we capture errno directly and cross our fingers */ |
259 |
_dm_err_last_errno = errno; |
260 |
|
261 |
if (_dm_err_last_msg) { |
262 |
free(_dm_err_last_msg); |
263 |
_dm_err_last_msg = NULL; |
264 |
} |
265 |
|
266 |
va_list ap; |
267 |
va_start(ap, f); |
268 |
if (vasprintf(&_dm_err_last_msg, f, ap) == -1) { |
269 |
g_error("vasprintf"); |
270 |
} |
271 |
va_end(ap); |
272 |
} |
273 |
|
237 |
/* Macros for exporting object properties */ |
274 |
/* Macros for exporting object properties */ |
238 |
|
275 |
|
239 |
#define EXPORT_PROP_STRING(object, klass, property) \ |
276 |
#define EXPORT_PROP_STRING(object, klass, property) \ |
Lines 267-281
Link Here
|
267 |
|
304 |
|
268 |
/* LDM */ |
305 |
/* LDM */ |
269 |
|
306 |
|
270 |
#define LDM_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ |
|
|
271 |
((obj), LDM_TYPE, LDMPrivate)) |
272 |
|
273 |
struct _LDMPrivate |
307 |
struct _LDMPrivate |
274 |
{ |
308 |
{ |
275 |
GArray *disk_groups; |
309 |
GArray *disk_groups; |
276 |
}; |
310 |
}; |
277 |
|
311 |
|
278 |
G_DEFINE_TYPE(LDM, ldm, G_TYPE_OBJECT) |
312 |
G_DEFINE_TYPE_WITH_PRIVATE(LDM, ldm, G_TYPE_OBJECT) |
279 |
|
313 |
|
280 |
static void |
314 |
static void |
281 |
ldm_dispose(GObject * const object) |
315 |
ldm_dispose(GObject * const object) |
Lines 285-297
Link Here
|
285 |
if (ldm->priv->disk_groups) { |
319 |
if (ldm->priv->disk_groups) { |
286 |
g_array_unref(ldm->priv->disk_groups); ldm->priv->disk_groups = NULL; |
320 |
g_array_unref(ldm->priv->disk_groups); ldm->priv->disk_groups = NULL; |
287 |
} |
321 |
} |
|
|
322 |
|
323 |
/* Restore default logging function. */ |
324 |
dm_log_with_errno_init(NULL); |
288 |
} |
325 |
} |
289 |
|
326 |
|
290 |
static void |
327 |
static void |
291 |
ldm_init(LDM * const o) |
328 |
ldm_init(LDM * const o) |
292 |
{ |
329 |
{ |
293 |
o->priv = LDM_GET_PRIVATE(o); |
330 |
o->priv = ldm_get_instance_private(o); |
294 |
bzero(o->priv, sizeof(*o->priv)); |
331 |
bzero(o->priv, sizeof(*o->priv)); |
|
|
332 |
|
333 |
/* Provide our logging function. */ |
334 |
dm_log_with_errno_init(_dm_log_fn); |
335 |
dm_set_name_mangling_mode(DM_STRING_MANGLING_AUTO); |
336 |
dm_set_uuid_prefix(DM_UUID_PREFIX); |
295 |
} |
337 |
} |
296 |
|
338 |
|
297 |
static void |
339 |
static void |
Lines 300-313
Link Here
|
300 |
GObjectClass *object_class = G_OBJECT_CLASS(klass); |
342 |
GObjectClass *object_class = G_OBJECT_CLASS(klass); |
301 |
object_class->dispose = ldm_dispose; |
343 |
object_class->dispose = ldm_dispose; |
302 |
|
344 |
|
303 |
g_type_class_add_private(klass, sizeof(LDMPrivate)); |
|
|
304 |
} |
345 |
} |
305 |
|
346 |
|
306 |
/* LDMDiskGroup */ |
347 |
/* LDMDiskGroup */ |
307 |
|
348 |
|
308 |
#define LDM_DISK_GROUP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ |
|
|
309 |
((obj), LDM_TYPE_DISK_GROUP, LDMDiskGroupPrivate)) |
310 |
|
311 |
struct _LDMDiskGroupPrivate |
349 |
struct _LDMDiskGroupPrivate |
312 |
{ |
350 |
{ |
313 |
uuid_t guid; |
351 |
uuid_t guid; |
Lines 326-332
Link Here
|
326 |
GArray *comps; |
364 |
GArray *comps; |
327 |
}; |
365 |
}; |
328 |
|
366 |
|
329 |
G_DEFINE_TYPE(LDMDiskGroup, ldm_disk_group, G_TYPE_OBJECT) |
367 |
G_DEFINE_TYPE_WITH_PRIVATE(LDMDiskGroup, ldm_disk_group, G_TYPE_OBJECT) |
330 |
|
368 |
|
331 |
enum { |
369 |
enum { |
332 |
PROP_LDM_DISK_GROUP_PROP0, |
370 |
PROP_LDM_DISK_GROUP_PROP0, |
Lines 396-402
Link Here
|
396 |
object_class->finalize = ldm_disk_group_finalize; |
434 |
object_class->finalize = ldm_disk_group_finalize; |
397 |
object_class->get_property = ldm_disk_group_get_property; |
435 |
object_class->get_property = ldm_disk_group_get_property; |
398 |
|
436 |
|
399 |
g_type_class_add_private(klass, sizeof(LDMDiskGroupPrivate)); |
|
|
400 |
|
437 |
|
401 |
/** |
438 |
/** |
402 |
* LDMDiskGroup:guid: |
439 |
* LDMDiskGroup:guid: |
Lines 431-437
Link Here
|
431 |
static void |
468 |
static void |
432 |
ldm_disk_group_init(LDMDiskGroup * const o) |
469 |
ldm_disk_group_init(LDMDiskGroup * const o) |
433 |
{ |
470 |
{ |
434 |
o->priv = LDM_DISK_GROUP_GET_PRIVATE(o); |
471 |
o->priv = ldm_disk_group_get_instance_private(o); |
435 |
bzero(o->priv, sizeof(*o->priv)); |
472 |
bzero(o->priv, sizeof(*o->priv)); |
436 |
} |
473 |
} |
437 |
|
474 |
|
Lines 457-465
Link Here
|
457 |
|
494 |
|
458 |
/* LDMVolume */ |
495 |
/* LDMVolume */ |
459 |
|
496 |
|
460 |
#define LDM_VOLUME_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ |
|
|
461 |
((obj), LDM_TYPE_VOLUME, LDMVolumePrivate)) |
462 |
|
463 |
typedef enum { |
497 |
typedef enum { |
464 |
_VOLUME_TYPE_GEN = 0x3, |
498 |
_VOLUME_TYPE_GEN = 0x3, |
465 |
_VOLUME_TYPE_RAID5 = 0x4 |
499 |
_VOLUME_TYPE_RAID5 = 0x4 |
Lines 469-474
Link Here
|
469 |
{ |
503 |
{ |
470 |
guint32 id; |
504 |
guint32 id; |
471 |
gchar *name; |
505 |
gchar *name; |
|
|
506 |
uuid_t guid; |
472 |
gchar *dgname; |
507 |
gchar *dgname; |
473 |
|
508 |
|
474 |
guint64 size; |
509 |
guint64 size; |
Lines 491-501
Link Here
|
491 |
guint32 _n_comps_i; |
526 |
guint32 _n_comps_i; |
492 |
}; |
527 |
}; |
493 |
|
528 |
|
494 |
G_DEFINE_TYPE(LDMVolume, ldm_volume, G_TYPE_OBJECT) |
529 |
G_DEFINE_TYPE_WITH_PRIVATE(LDMVolume, ldm_volume, G_TYPE_OBJECT) |
495 |
|
530 |
|
496 |
enum { |
531 |
enum { |
497 |
PROP_LDM_VOLUME_PROP0, |
532 |
PROP_LDM_VOLUME_PROP0, |
498 |
PROP_LDM_VOLUME_NAME, |
533 |
PROP_LDM_VOLUME_NAME, |
|
|
534 |
PROP_LDM_VOLUME_GUID, |
499 |
PROP_LDM_VOLUME_TYPE, |
535 |
PROP_LDM_VOLUME_TYPE, |
500 |
PROP_LDM_VOLUME_SIZE, |
536 |
PROP_LDM_VOLUME_SIZE, |
501 |
PROP_LDM_VOLUME_PART_TYPE, |
537 |
PROP_LDM_VOLUME_PART_TYPE, |
Lines 514-519
Link Here
|
514 |
case PROP_LDM_VOLUME_NAME: |
550 |
case PROP_LDM_VOLUME_NAME: |
515 |
g_value_set_string(value, priv->name); break; |
551 |
g_value_set_string(value, priv->name); break; |
516 |
|
552 |
|
|
|
553 |
case PROP_LDM_VOLUME_GUID: |
554 |
{ |
555 |
char guid_str[37]; |
556 |
uuid_unparse(priv->guid, guid_str); |
557 |
g_value_set_string(value, guid_str); |
558 |
} |
559 |
break; |
560 |
|
517 |
case PROP_LDM_VOLUME_TYPE: |
561 |
case PROP_LDM_VOLUME_TYPE: |
518 |
g_value_set_enum(value, priv->type); break; |
562 |
g_value_set_enum(value, priv->type); break; |
519 |
|
563 |
|
Lines 535-540
Link Here
|
535 |
} |
579 |
} |
536 |
|
580 |
|
537 |
EXPORT_PROP_STRING(volume, LDMVolume, name) |
581 |
EXPORT_PROP_STRING(volume, LDMVolume, name) |
|
|
582 |
EXPORT_PROP_GUID(volume, LDMVolume) |
538 |
EXPORT_PROP_SCALAR(volume, LDMVolume, size, guint64) |
583 |
EXPORT_PROP_SCALAR(volume, LDMVolume, size, guint64) |
539 |
EXPORT_PROP_SCALAR(volume, LDMVolume, part_type, guint8) |
584 |
EXPORT_PROP_SCALAR(volume, LDMVolume, part_type, guint8) |
540 |
EXPORT_PROP_STRING(volume, LDMVolume, hint) |
585 |
EXPORT_PROP_STRING(volume, LDMVolume, hint) |
Lines 577-583
Link Here
|
577 |
object_class->finalize = ldm_volume_finalize; |
622 |
object_class->finalize = ldm_volume_finalize; |
578 |
object_class->get_property = ldm_volume_get_property; |
623 |
object_class->get_property = ldm_volume_get_property; |
579 |
|
624 |
|
580 |
g_type_class_add_private(klass, sizeof(LDMVolumePrivate)); |
|
|
581 |
|
625 |
|
582 |
/** |
626 |
/** |
583 |
* LDMVolume:name: |
627 |
* LDMVolume:name: |
Lines 594-599
Link Here
|
594 |
); |
638 |
); |
595 |
|
639 |
|
596 |
/** |
640 |
/** |
|
|
641 |
* LDMVolume:guid: |
642 |
* |
643 |
* The GUID of the volume. |
644 |
*/ |
645 |
g_object_class_install_property( |
646 |
object_class, |
647 |
PROP_LDM_VOLUME_GUID, |
648 |
g_param_spec_string( |
649 |
"guid", "GUID", "The GUID of the volume", |
650 |
NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS |
651 |
) |
652 |
); |
653 |
|
654 |
/** |
597 |
* LDMVolume:type: |
655 |
* LDMVolume:type: |
598 |
* |
656 |
* |
599 |
* The volume type: simple, spanned, striped, mirrored or raid5. |
657 |
* The volume type: simple, spanned, striped, mirrored or raid5. |
Lines 677-683
Link Here
|
677 |
static void |
735 |
static void |
678 |
ldm_volume_init(LDMVolume * const o) |
736 |
ldm_volume_init(LDMVolume * const o) |
679 |
{ |
737 |
{ |
680 |
o->priv = LDM_VOLUME_GET_PRIVATE(o); |
738 |
o->priv = ldm_volume_get_instance_private(o); |
681 |
bzero(o->priv, sizeof(*o->priv)); |
739 |
bzero(o->priv, sizeof(*o->priv)); |
682 |
|
740 |
|
683 |
/* We don't have a trivial way to initialize this array to the correct size |
741 |
/* We don't have a trivial way to initialize this array to the correct size |
Lines 717-725
Link Here
|
717 |
|
775 |
|
718 |
/* LDMPartition */ |
776 |
/* LDMPartition */ |
719 |
|
777 |
|
720 |
#define LDM_PARTITION_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ |
|
|
721 |
((obj), LDM_TYPE_PARTITION, LDMPartitionPrivate)) |
722 |
|
723 |
struct _LDMPartitionPrivate |
778 |
struct _LDMPartitionPrivate |
724 |
{ |
779 |
{ |
725 |
guint32 id; |
780 |
guint32 id; |
Lines 735-741
Link Here
|
735 |
LDMDisk *disk; |
790 |
LDMDisk *disk; |
736 |
}; |
791 |
}; |
737 |
|
792 |
|
738 |
G_DEFINE_TYPE(LDMPartition, ldm_partition, G_TYPE_OBJECT) |
793 |
G_DEFINE_TYPE_WITH_PRIVATE(LDMPartition, ldm_partition, G_TYPE_OBJECT) |
739 |
|
794 |
|
740 |
enum { |
795 |
enum { |
741 |
PROP_LDM_PARTITION_PROP0, |
796 |
PROP_LDM_PARTITION_PROP0, |
Lines 796-802
Link Here
|
796 |
object_class->finalize = ldm_partition_finalize; |
851 |
object_class->finalize = ldm_partition_finalize; |
797 |
object_class->get_property = ldm_partition_get_property; |
852 |
object_class->get_property = ldm_partition_get_property; |
798 |
|
853 |
|
799 |
g_type_class_add_private(klass, sizeof(LDMPartitionPrivate)); |
|
|
800 |
|
854 |
|
801 |
/** |
855 |
/** |
802 |
* LDMPartition:name: |
856 |
* LDMPartition:name: |
Lines 846-860
Link Here
|
846 |
static void |
900 |
static void |
847 |
ldm_partition_init(LDMPartition * const o) |
901 |
ldm_partition_init(LDMPartition * const o) |
848 |
{ |
902 |
{ |
849 |
o->priv = LDM_PARTITION_GET_PRIVATE(o); |
903 |
o->priv = ldm_partition_get_instance_private(o); |
850 |
bzero(o->priv, sizeof(*o->priv)); |
904 |
bzero(o->priv, sizeof(*o->priv)); |
851 |
} |
905 |
} |
852 |
|
906 |
|
853 |
/* LDMDisk */ |
907 |
/* LDMDisk */ |
854 |
|
908 |
|
855 |
#define LDM_DISK_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE \ |
|
|
856 |
((obj), LDM_TYPE_DISK, LDMDiskPrivate)) |
857 |
|
858 |
struct _LDMDiskPrivate |
909 |
struct _LDMDiskPrivate |
859 |
{ |
910 |
{ |
860 |
guint32 id; |
911 |
guint32 id; |
Lines 870-876
Link Here
|
870 |
gchar *device; // NULL until device is found |
921 |
gchar *device; // NULL until device is found |
871 |
}; |
922 |
}; |
872 |
|
923 |
|
873 |
G_DEFINE_TYPE(LDMDisk, ldm_disk, G_TYPE_OBJECT) |
924 |
G_DEFINE_TYPE_WITH_PRIVATE(LDMDisk, ldm_disk, G_TYPE_OBJECT) |
874 |
|
925 |
|
875 |
enum { |
926 |
enum { |
876 |
PROP_LDM_DISK_PROP0, |
927 |
PROP_LDM_DISK_PROP0, |
Lines 948-954
Link Here
|
948 |
object_class->finalize = ldm_disk_finalize; |
999 |
object_class->finalize = ldm_disk_finalize; |
949 |
object_class->get_property = ldm_disk_get_property; |
1000 |
object_class->get_property = ldm_disk_get_property; |
950 |
|
1001 |
|
951 |
g_type_class_add_private(klass, sizeof(LDMDiskPrivate)); |
|
|
952 |
|
1002 |
|
953 |
/** |
1003 |
/** |
954 |
* LDMDisk:name: |
1004 |
* LDMDisk:name: |
Lines 1062-1068
Link Here
|
1062 |
static void |
1112 |
static void |
1063 |
ldm_disk_init(LDMDisk * const o) |
1113 |
ldm_disk_init(LDMDisk * const o) |
1064 |
{ |
1114 |
{ |
1065 |
o->priv = LDM_DISK_GET_PRIVATE(o); |
1115 |
o->priv = ldm_disk_get_instance_private(o); |
1066 |
bzero(o->priv, sizeof(*o->priv)); |
1116 |
bzero(o->priv, sizeof(*o->priv)); |
1067 |
} |
1117 |
} |
1068 |
|
1118 |
|
Lines 1514-1521
Link Here
|
1514 |
|
1564 |
|
1515 |
vol->part_type = *((uint8_t *)vblk); vblk++; |
1565 |
vol->part_type = *((uint8_t *)vblk); vblk++; |
1516 |
|
1566 |
|
1517 |
/* Volume id */ |
1567 |
/* Volume GUID */ |
1518 |
vblk += 16; |
1568 |
memcpy(&vol->guid, vblk, 16); vblk += 16; |
1519 |
|
1569 |
|
1520 |
if (flags & 0x08) vol->id1 = _parse_var_string(&vblk); |
1570 |
if (flags & 0x08) vol->id1 = _parse_var_string(&vblk); |
1521 |
if (flags & 0x20) vol->id2 = _parse_var_string(&vblk); |
1571 |
if (flags & 0x20) vol->id2 = _parse_var_string(&vblk); |
Lines 2354-2359
Link Here
|
2354 |
} |
2404 |
} |
2355 |
|
2405 |
|
2356 |
static GString * |
2406 |
static GString * |
|
|
2407 |
_dm_part_name(const LDMPartitionPrivate * const part) |
2408 |
{ |
2409 |
const LDMDiskPrivate * const disk = part->disk->priv; |
2410 |
|
2411 |
GString * name = g_string_new(""); |
2412 |
g_string_printf(name, "ldm_part_%s_%s", disk->dgname, part->name); |
2413 |
|
2414 |
return name; |
2415 |
} |
2416 |
|
2417 |
static GString * |
2418 |
_dm_part_uuid(const LDMPartitionPrivate * const part) |
2419 |
{ |
2420 |
const LDMDiskPrivate * const disk = part->disk->priv; |
2421 |
|
2422 |
char ldm_disk_guid[37]; |
2423 |
uuid_unparse_lower(disk->guid, ldm_disk_guid); |
2424 |
|
2425 |
GString * dm_uuid = g_string_new(""); |
2426 |
g_string_printf(dm_uuid, "%s%s-%s", |
2427 |
DM_UUID_PREFIX, part->name, ldm_disk_guid); |
2428 |
|
2429 |
return dm_uuid; |
2430 |
} |
2431 |
|
2432 |
static GString * |
2357 |
_dm_vol_name(const LDMVolumePrivate * const vol) |
2433 |
_dm_vol_name(const LDMVolumePrivate * const vol) |
2358 |
{ |
2434 |
{ |
2359 |
GString * r = g_string_new(""); |
2435 |
GString * r = g_string_new(""); |
Lines 2361-2373
Link Here
|
2361 |
return r; |
2437 |
return r; |
2362 |
} |
2438 |
} |
2363 |
|
2439 |
|
2364 |
/* We catch log messages generated by device mapper with errno != 0 and store |
2440 |
static GString * |
2365 |
* them here */ |
2441 |
_dm_vol_uuid(const LDMVolumePrivate * const vol) |
2366 |
static int _dm_err_last_level = 0; |
2442 |
{ |
2367 |
static const char *_dm_err_last_file = NULL; |
2443 |
char ldm_vol_uuid[37]; |
2368 |
static int _dm_err_last_line = 0; |
2444 |
uuid_unparse_lower(vol->guid, ldm_vol_uuid); |
2369 |
static int _dm_err_last_errno = 0; |
2445 |
|
2370 |
static char *_dm_err_last_msg = NULL; |
2446 |
GString * dm_uuid = g_string_new(""); |
|
|
2447 |
g_string_printf(dm_uuid, "%s%s-%s", |
2448 |
DM_UUID_PREFIX, vol->name, ldm_vol_uuid); |
2449 |
|
2450 |
return dm_uuid; |
2451 |
} |
2371 |
|
2452 |
|
2372 |
struct dm_target { |
2453 |
struct dm_target { |
2373 |
guint64 start; |
2454 |
guint64 start; |
Lines 2377-2383
Link Here
|
2377 |
}; |
2458 |
}; |
2378 |
|
2459 |
|
2379 |
static struct dm_tree * |
2460 |
static struct dm_tree * |
2380 |
_get_device_tree(GError **err) |
2461 |
_dm_get_device_tree(GError **err) |
2381 |
{ |
2462 |
{ |
2382 |
struct dm_tree *tree; |
2463 |
struct dm_tree *tree; |
2383 |
tree = dm_tree_create(); |
2464 |
tree = dm_tree_create(); |
Lines 2432-2476
Link Here
|
2432 |
return NULL; |
2513 |
return NULL; |
2433 |
} |
2514 |
} |
2434 |
|
2515 |
|
2435 |
static struct dm_tree_node * |
2516 |
/* Returns TRUE if device with specified UUID is found or FALSE otherwise. |
2436 |
_walk_tree(const struct dm_tree * const tree, |
2517 |
* |
2437 |
const struct dm_tree_node * const node, |
2518 |
* Found device node is returned if dm_node is not NULL. In this case dm_tree |
2438 |
const char * const search) |
2519 |
* MUST not be NULL as well. And the caller is responsible to free device tree |
|
|
2520 |
* by calling dm_tree_free function. |
2521 |
*/ |
2522 |
gboolean |
2523 |
_dm_find_tree_node_by_uuid(const gchar * const uuid, |
2524 |
struct dm_tree_node ** dm_node, |
2525 |
struct dm_tree ** dm_tree, |
2526 |
GError ** const err) |
2439 |
{ |
2527 |
{ |
2440 |
void *handle = NULL; |
2528 |
gboolean r = FALSE; |
2441 |
struct dm_tree_node *child; |
|
|
2442 |
for (;;) { |
2443 |
child = dm_tree_next_child(&handle, node, 0); |
2444 |
if (!child) return NULL; |
2445 |
|
2446 |
const char * const name = dm_tree_node_get_name(child); |
2447 |
if (!name || *name == '\0') continue; |
2448 |
|
2529 |
|
2449 |
if (g_strcmp0(search, name) == 0) return child; |
2530 |
if (dm_node) { |
|
|
2531 |
g_assert(dm_tree != NULL); |
2532 |
*dm_node = NULL; |
2533 |
} |
2534 |
if (dm_tree) *dm_tree = NULL; |
2535 |
|
2536 |
struct dm_tree *tree = _dm_get_device_tree(err); |
2537 |
if (tree) { |
2538 |
struct dm_tree_node *node = dm_tree_find_node_by_uuid(tree, uuid); |
2539 |
if (node) r = TRUE; |
2540 |
|
2541 |
if (dm_tree) |
2542 |
*dm_tree = tree; |
2543 |
else |
2544 |
dm_tree_free(tree); |
2450 |
|
2545 |
|
2451 |
if (dm_tree_node_num_children(child, 0) > 0) { |
2546 |
if (dm_node) *dm_node = node; |
2452 |
struct dm_tree_node * const r_search = |
|
|
2453 |
_walk_tree(tree, child, search); |
2454 |
if (r_search) return r_search; |
2455 |
} |
2456 |
} |
2547 |
} |
|
|
2548 |
|
2549 |
return r; |
2457 |
} |
2550 |
} |
2458 |
|
2551 |
|
2459 |
static struct dm_tree_node * |
2552 |
gchar * |
2460 |
_find_device_tree_node(struct dm_tree * const tree, |
2553 |
_dm_get_device(const gchar * const uuid, GError ** const err) |
2461 |
const char * const name) |
|
|
2462 |
{ |
2554 |
{ |
2463 |
const struct dm_tree_node * const root = dm_tree_find_node(tree, 0, 0); |
2555 |
GString *r = NULL; |
2464 |
return _walk_tree(tree, root, name); |
2556 |
|
|
|
2557 |
struct dm_tree_node *node = NULL; |
2558 |
struct dm_tree *tree = NULL; |
2559 |
struct dm_task *task = NULL; |
2560 |
|
2561 |
if (_dm_find_tree_node_by_uuid(uuid, &node, &tree, err)) { |
2562 |
const struct dm_info *info = dm_tree_node_get_info(node); |
2563 |
|
2564 |
task = dm_task_create(DM_DEVICE_INFO); |
2565 |
if (!task) { |
2566 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2567 |
"dm_task_create: %s", _dm_err_last_msg); |
2568 |
goto error; |
2569 |
} |
2570 |
|
2571 |
if (!dm_task_set_major(task, info->major)) { |
2572 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2573 |
"DM_DEVICE_INFO: dm_task_set_major(%d) failed: %s", |
2574 |
info->major, _dm_err_last_msg); |
2575 |
goto error; |
2576 |
} |
2577 |
|
2578 |
if (!dm_task_set_minor(task, info->minor)) { |
2579 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2580 |
"DM_DEVICE_INFO: dm_task_set_major(%d) failed: %s", |
2581 |
info->minor, _dm_err_last_msg); |
2582 |
goto error; |
2583 |
} |
2584 |
|
2585 |
if (!dm_task_run(task)) { |
2586 |
g_set_error_literal(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2587 |
_dm_err_last_msg); |
2588 |
goto error; |
2589 |
} |
2590 |
|
2591 |
const char *dir = dm_dir(); |
2592 |
char *mangled_name = dm_task_get_name_mangled(task); |
2593 |
r = g_string_new(""); |
2594 |
g_string_printf(r, "%s/%s", dir, mangled_name); |
2595 |
dm_free(mangled_name); |
2596 |
} |
2597 |
|
2598 |
error: |
2599 |
if (tree) dm_tree_free(tree); |
2600 |
if (task) dm_task_destroy(task); |
2601 |
|
2602 |
/* Really FALSE here - don't free but return the character data. */ |
2603 |
return r ? g_string_free(r, FALSE) : NULL; |
2465 |
} |
2604 |
} |
2466 |
|
2605 |
|
2467 |
gboolean |
2606 |
gboolean |
2468 |
_dm_create(const gchar * const name, uint32_t udev_cookie, |
2607 |
_dm_create(const gchar * const name, const gchar * const uuid, |
2469 |
const guint n_targets, const struct dm_target * const targets, |
2608 |
uint32_t udev_cookie, const guint n_targets, |
2470 |
GError ** const err) |
2609 |
const struct dm_target * const targets, |
|
|
2610 |
GString **mangled_name, GError ** const err) |
2471 |
{ |
2611 |
{ |
2472 |
gboolean r = TRUE; |
2612 |
gboolean r = TRUE; |
2473 |
|
2613 |
|
|
|
2614 |
if (mangled_name) *mangled_name = NULL; |
2615 |
|
2474 |
struct dm_task * const task = dm_task_create(DM_DEVICE_CREATE); |
2616 |
struct dm_task * const task = dm_task_create(DM_DEVICE_CREATE); |
2475 |
if (!task) { |
2617 |
if (!task) { |
2476 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2618 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
Lines 2486-2491
Link Here
|
2486 |
r = FALSE; goto out; |
2628 |
r = FALSE; goto out; |
2487 |
} |
2629 |
} |
2488 |
|
2630 |
|
|
|
2631 |
if (!dm_task_set_uuid(task, uuid)) { |
2632 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
2633 |
"DM_DEVICE_CREATE: dm_task_set_uuid(%s) failed: %s", |
2634 |
uuid, _dm_err_last_msg); |
2635 |
r = FALSE; goto out; |
2636 |
} |
2637 |
|
2489 |
for (guint i = 0; i < n_targets; i++) { |
2638 |
for (guint i = 0; i < n_targets; i++) { |
2490 |
const struct dm_target * const target = &targets[i]; |
2639 |
const struct dm_target * const target = &targets[i]; |
2491 |
|
2640 |
|
Lines 2515-2520
Link Here
|
2515 |
r = FALSE; goto out; |
2664 |
r = FALSE; goto out; |
2516 |
} |
2665 |
} |
2517 |
|
2666 |
|
|
|
2667 |
if (mangled_name) { |
2668 |
char *tmp = dm_task_get_name_mangled(task); |
2669 |
*mangled_name = g_string_new(tmp); |
2670 |
dm_free(tmp); |
2671 |
} |
2672 |
|
2518 |
out: |
2673 |
out: |
2519 |
dm_task_destroy(task); |
2674 |
dm_task_destroy(task); |
2520 |
return r; |
2675 |
return r; |
Lines 2588-2624
Link Here
|
2588 |
g_string_printf(target.params, "%s %" PRIu64, |
2743 |
g_string_printf(target.params, "%s %" PRIu64, |
2589 |
disk->device, disk->data_start + part->start); |
2744 |
disk->device, disk->data_start + part->start); |
2590 |
|
2745 |
|
2591 |
/* Ensure we sanitise table names */ |
2746 |
GString *name = _dm_part_name(part); |
2592 |
char * dgname_esc = |
2747 |
GString *uuid = _dm_part_uuid(part); |
2593 |
g_uri_escape_string(disk->dgname, |
2748 |
GString *mangled_name = NULL; |
2594 |
G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, |
2749 |
|
2595 |
FALSE); |
2750 |
if (!_dm_create(name->str, uuid->str, cookie, 1, &target, |
2596 |
char * partname_esc = |
2751 |
&mangled_name, err)) { |
2597 |
g_uri_escape_string(part->name, |
2752 |
mangled_name = NULL; |
2598 |
G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT, |
|
|
2599 |
FALSE); |
2600 |
|
2601 |
GString *name = g_string_new(""); |
2602 |
g_string_printf(name, "ldm_part_%s_%s", dgname_esc, partname_esc); |
2603 |
g_free(dgname_esc); |
2604 |
g_free(partname_esc); |
2605 |
|
2606 |
if (!_dm_create(name->str, cookie, 1, &target, err)) { |
2607 |
g_string_free(name, TRUE); |
2608 |
name = NULL; |
2609 |
} |
2753 |
} |
2610 |
|
2754 |
|
|
|
2755 |
g_string_free(name, TRUE); |
2756 |
g_string_free(uuid, TRUE); |
2611 |
g_string_free(target.params, TRUE); |
2757 |
g_string_free(target.params, TRUE); |
2612 |
return name; |
2758 |
|
|
|
2759 |
return mangled_name; |
2760 |
} |
2761 |
|
2762 |
gint |
2763 |
_cmp_component_vol_offset(gconstpointer a, gconstpointer b) |
2764 |
{ |
2765 |
const LDMPartition * const ao = LDM_PARTITION(*(LDMPartition **)a); |
2766 |
const LDMPartition * const bo = LDM_PARTITION(*(LDMPartition **)b); |
2767 |
|
2768 |
return ao->priv->vol_offset - bo->priv->vol_offset; |
2613 |
} |
2769 |
} |
2614 |
|
2770 |
|
2615 |
static GString * |
2771 |
static GString * |
2616 |
_dm_create_spanned(const LDMVolumePrivate * const vol, GError ** const err) |
2772 |
_dm_create_spanned(const LDMVolumePrivate * const vol, GError ** const err) |
2617 |
{ |
2773 |
{ |
2618 |
static GString *name = NULL; |
2774 |
GString *name = NULL; |
2619 |
guint i = 0; |
2775 |
guint i = 0; |
2620 |
struct dm_target *targets = g_malloc(sizeof(*targets) * vol->parts->len); |
2776 |
struct dm_target *targets = g_malloc(sizeof(*targets) * vol->parts->len); |
2621 |
|
2777 |
|
|
|
2778 |
g_array_sort(vol->parts, _cmp_component_vol_offset); |
2779 |
|
2622 |
uint64_t pos = 0; |
2780 |
uint64_t pos = 0; |
2623 |
for (; i < vol->parts->len; i++) { |
2781 |
for (; i < vol->parts->len; i++) { |
2624 |
const LDMPartition * const part_o = |
2782 |
const LDMPartition * const part_o = |
Lines 2661-2672
Link Here
|
2661 |
} |
2819 |
} |
2662 |
|
2820 |
|
2663 |
name = _dm_vol_name(vol); |
2821 |
name = _dm_vol_name(vol); |
|
|
2822 |
GString *uuid = _dm_vol_uuid(vol); |
2664 |
|
2823 |
|
2665 |
if (!_dm_create(name->str, cookie, vol->parts->len, targets, err)) { |
2824 |
if (!_dm_create(name->str, uuid->str, cookie, vol->parts->len, targets, |
|
|
2825 |
NULL, err)) { |
2666 |
g_string_free(name, TRUE); |
2826 |
g_string_free(name, TRUE); |
2667 |
name = NULL; |
2827 |
name = NULL; |
2668 |
} |
2828 |
} |
2669 |
|
2829 |
|
|
|
2830 |
g_string_free(uuid, TRUE); |
2670 |
dm_udev_wait(cookie); |
2831 |
dm_udev_wait(cookie); |
2671 |
|
2832 |
|
2672 |
out: |
2833 |
out: |
Lines 2682-2688
Link Here
|
2682 |
static GString * |
2843 |
static GString * |
2683 |
_dm_create_striped(const LDMVolumePrivate * const vol, GError ** const err) |
2844 |
_dm_create_striped(const LDMVolumePrivate * const vol, GError ** const err) |
2684 |
{ |
2845 |
{ |
2685 |
static GString *name = NULL; |
2846 |
GString *name = NULL; |
2686 |
struct dm_target target; |
2847 |
struct dm_target target; |
2687 |
|
2848 |
|
2688 |
target.start = 0; |
2849 |
target.start = 0; |
Lines 2718-2729
Link Here
|
2718 |
} |
2879 |
} |
2719 |
|
2880 |
|
2720 |
name = _dm_vol_name(vol); |
2881 |
name = _dm_vol_name(vol); |
|
|
2882 |
GString *uuid = _dm_vol_uuid(vol); |
2721 |
|
2883 |
|
2722 |
if (!_dm_create(name->str, cookie, 1, &target, err)) { |
2884 |
if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) { |
2723 |
g_string_free(name, TRUE); |
2885 |
g_string_free(name, TRUE); |
2724 |
name = NULL; |
2886 |
name = NULL; |
2725 |
} |
2887 |
} |
2726 |
|
2888 |
|
|
|
2889 |
g_string_free(uuid, TRUE); |
2727 |
dm_udev_wait(cookie); |
2890 |
dm_udev_wait(cookie); |
2728 |
|
2891 |
|
2729 |
out: |
2892 |
out: |
Lines 2754-2759
Link Here
|
2754 |
goto out; |
2917 |
goto out; |
2755 |
} |
2918 |
} |
2756 |
|
2919 |
|
|
|
2920 |
const char *dir = dm_dir(); |
2921 |
|
2757 |
int found = 0; |
2922 |
int found = 0; |
2758 |
for (guint i = 0; i < vol->parts->len; i++) { |
2923 |
for (guint i = 0; i < vol->parts->len; i++) { |
2759 |
const LDMPartition * const part_o = |
2924 |
const LDMPartition * const part_o = |
Lines 2774-2780
Link Here
|
2774 |
|
2939 |
|
2775 |
found++; |
2940 |
found++; |
2776 |
g_array_append_val(devices, chunk); |
2941 |
g_array_append_val(devices, chunk); |
2777 |
g_string_append_printf(target.params, " - /dev/mapper/%s", chunk->str); |
2942 |
g_string_append_printf(target.params, " - %s/%s", dir, chunk->str); |
2778 |
} |
2943 |
} |
2779 |
|
2944 |
|
2780 |
if (found == 0) { |
2945 |
if (found == 0) { |
Lines 2792-2803
Link Here
|
2792 |
} |
2957 |
} |
2793 |
|
2958 |
|
2794 |
name = _dm_vol_name(vol); |
2959 |
name = _dm_vol_name(vol); |
|
|
2960 |
GString *uuid = _dm_vol_uuid(vol); |
2795 |
|
2961 |
|
2796 |
if (!_dm_create(name->str, cookie, 1, &target, err)) { |
2962 |
if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) { |
2797 |
g_string_free(name, TRUE); |
2963 |
g_string_free(name, TRUE); |
2798 |
name = NULL; |
2964 |
name = NULL; |
2799 |
} |
2965 |
} |
2800 |
|
2966 |
|
|
|
2967 |
g_string_free(uuid, TRUE); |
2801 |
dm_udev_wait(cookie); |
2968 |
dm_udev_wait(cookie); |
2802 |
|
2969 |
|
2803 |
g_array_unref(devices); devices = NULL; |
2970 |
g_array_unref(devices); devices = NULL; |
Lines 2816-2821
Link Here
|
2816 |
} |
2983 |
} |
2817 |
|
2984 |
|
2818 |
g_string_free(target.params, TRUE); |
2985 |
g_string_free(target.params, TRUE); |
|
|
2986 |
|
2819 |
return name; |
2987 |
return name; |
2820 |
} |
2988 |
} |
2821 |
|
2989 |
|
Lines 2823-2828
Link Here
|
2823 |
_dm_create_raid5(const LDMVolumePrivate * const vol, GError ** const err) |
2991 |
_dm_create_raid5(const LDMVolumePrivate * const vol, GError ** const err) |
2824 |
{ |
2992 |
{ |
2825 |
GString *name = NULL; |
2993 |
GString *name = NULL; |
|
|
2994 |
GString *uuid = NULL; |
2826 |
struct dm_target target; |
2995 |
struct dm_target target; |
2827 |
|
2996 |
|
2828 |
target.start = 0; |
2997 |
target.start = 0; |
Lines 2842-2847
Link Here
|
2842 |
goto out; |
3011 |
goto out; |
2843 |
} |
3012 |
} |
2844 |
|
3013 |
|
|
|
3014 |
const char *dir = dm_dir(); |
3015 |
|
2845 |
guint n_found = 0; |
3016 |
guint n_found = 0; |
2846 |
for (guint i = 0; i < vol->parts->len; i++) { |
3017 |
for (guint i = 0; i < vol->parts->len; i++) { |
2847 |
const LDMPartition * const part_o = |
3018 |
const LDMPartition * const part_o = |
Lines 2862-2868
Link Here
|
2862 |
|
3033 |
|
2863 |
n_found++; |
3034 |
n_found++; |
2864 |
g_array_append_val(devices, chunk); |
3035 |
g_array_append_val(devices, chunk); |
2865 |
g_string_append_printf(target.params, " - /dev/mapper/%s", chunk->str); |
3036 |
g_string_append_printf(target.params, " - %s/%s", dir, chunk->str); |
2866 |
} |
3037 |
} |
2867 |
|
3038 |
|
2868 |
if (n_found < vol->parts->len - 1) { |
3039 |
if (n_found < vol->parts->len - 1) { |
Lines 2880-2891
Link Here
|
2880 |
} |
3051 |
} |
2881 |
|
3052 |
|
2882 |
name = _dm_vol_name(vol); |
3053 |
name = _dm_vol_name(vol); |
|
|
3054 |
uuid = _dm_vol_uuid(vol); |
2883 |
|
3055 |
|
2884 |
if (!_dm_create(name->str, cookie, 1, &target, err)) { |
3056 |
if (!_dm_create(name->str, uuid->str, cookie, 1, &target, NULL, err)) { |
2885 |
g_string_free(name, TRUE); name = NULL; |
3057 |
g_string_free(name, TRUE); name = NULL; |
|
|
3058 |
g_string_free(uuid, TRUE); |
2886 |
goto out; |
3059 |
goto out; |
2887 |
} |
3060 |
} |
2888 |
|
3061 |
|
|
|
3062 |
g_string_free(uuid, TRUE); |
2889 |
dm_udev_wait(cookie); |
3063 |
dm_udev_wait(cookie); |
2890 |
|
3064 |
|
2891 |
g_array_unref(devices); devices = NULL; |
3065 |
g_array_unref(devices); devices = NULL; |
Lines 2904-2968
Link Here
|
2904 |
} |
3078 |
} |
2905 |
|
3079 |
|
2906 |
g_string_free(target.params, TRUE); |
3080 |
g_string_free(target.params, TRUE); |
|
|
3081 |
|
2907 |
return name; |
3082 |
return name; |
2908 |
} |
3083 |
} |
2909 |
|
3084 |
|
2910 |
static void |
3085 |
GString * |
2911 |
_dm_log_fn(const int level, const char * const file, const int line, |
3086 |
ldm_volume_dm_get_name(const LDMVolume * const o) |
2912 |
const int dm_errno, const char *f, ...) |
|
|
2913 |
{ |
3087 |
{ |
2914 |
if (dm_errno == 0) return; |
3088 |
return _dm_vol_name(o->priv); |
2915 |
|
3089 |
} |
2916 |
_dm_err_last_level = level; |
|
|
2917 |
_dm_err_last_file = file; |
2918 |
_dm_err_last_line = line; |
2919 |
|
2920 |
/* device-mapper doesn't set dm_errno usefully (it only seems to use |
2921 |
* EUNCLASSIFIED), so we capture errno directly and cross our fingers */ |
2922 |
_dm_err_last_errno = errno; |
2923 |
|
3090 |
|
2924 |
if (_dm_err_last_msg) { |
3091 |
gchar * |
2925 |
free(_dm_err_last_msg); |
3092 |
ldm_partition_dm_get_device(const LDMPartition * const o, GError ** const err) |
2926 |
_dm_err_last_msg = NULL; |
3093 |
{ |
2927 |
} |
3094 |
GString *uuid = _dm_part_uuid(o->priv); |
|
|
3095 |
gchar* r = _dm_get_device(uuid->str, err); |
3096 |
g_string_free(uuid, TRUE); |
2928 |
|
3097 |
|
2929 |
va_list ap; |
3098 |
return r; |
2930 |
va_start(ap, f); |
|
|
2931 |
if (vasprintf(&_dm_err_last_msg, f, ap) == -1) { |
2932 |
g_error("vasprintf"); |
2933 |
} |
2934 |
va_end(ap); |
2935 |
} |
3099 |
} |
2936 |
|
3100 |
|
2937 |
GString * |
3101 |
gchar * |
2938 |
ldm_volume_dm_get_name(const LDMVolume * const o) |
3102 |
ldm_volume_dm_get_device(const LDMVolume * const o, GError ** const err) |
2939 |
{ |
3103 |
{ |
2940 |
return _dm_vol_name(o->priv); |
3104 |
GString *uuid = _dm_vol_uuid(o->priv); |
|
|
3105 |
gchar* r = _dm_get_device(uuid->str, err); |
3106 |
g_string_free(uuid, TRUE); |
3107 |
|
3108 |
return r; |
2941 |
} |
3109 |
} |
2942 |
|
3110 |
|
2943 |
gboolean |
3111 |
gboolean |
2944 |
ldm_volume_dm_create(const LDMVolume * const o, GString **created, |
3112 |
ldm_volume_dm_create(const LDMVolume * const o, GString **created, |
2945 |
GError ** const err) |
3113 |
GError ** const err) |
2946 |
{ |
3114 |
{ |
2947 |
const LDMVolumePrivate * const vol = o->priv; |
3115 |
if (created) *created = NULL; |
2948 |
|
3116 |
|
2949 |
/* We should really store the previous logging function and restore it |
3117 |
const LDMVolumePrivate * const vol = o->priv; |
2950 |
* afterwards, but the API doesn't allow this. */ |
|
|
2951 |
dm_log_with_errno_init(_dm_log_fn); |
2952 |
|
3118 |
|
2953 |
/* Check if the device already exists */ |
3119 |
/* Check if the device already exists */ |
2954 |
struct dm_tree *tree = _get_device_tree(err); |
3120 |
GString *uuid = _dm_vol_uuid(vol); |
2955 |
if (!tree) return FALSE; |
3121 |
if (_dm_find_tree_node_by_uuid(uuid->str, NULL, NULL, err)) { |
2956 |
|
3122 |
g_string_free(uuid, TRUE); |
2957 |
GString *name = _dm_vol_name(vol); |
|
|
2958 |
struct dm_tree_node *node = _find_device_tree_node(tree, name->str); |
2959 |
if (node) { |
2960 |
dm_tree_free(tree); tree = NULL; |
2961 |
return TRUE; |
3123 |
return TRUE; |
2962 |
} |
3124 |
} |
2963 |
dm_tree_free(tree); tree = NULL; |
3125 |
g_string_free(uuid, TRUE); |
2964 |
g_string_free(name, TRUE); |
|
|
2965 |
|
3126 |
|
|
|
3127 |
GString *name = NULL; |
2966 |
switch (vol->type) { |
3128 |
switch (vol->type) { |
2967 |
case LDM_VOLUME_TYPE_SIMPLE: |
3129 |
case LDM_VOLUME_TYPE_SIMPLE: |
2968 |
case LDM_VOLUME_TYPE_SPANNED: |
3130 |
case LDM_VOLUME_TYPE_SPANNED: |
Lines 2986-3023
Link Here
|
2986 |
g_error("Unexpected volume type: %u", vol->type); |
3148 |
g_error("Unexpected volume type: %u", vol->type); |
2987 |
} |
3149 |
} |
2988 |
|
3150 |
|
2989 |
dm_log_with_errno_init(NULL); |
3151 |
gboolean r = name != NULL; |
|
|
3152 |
|
3153 |
if (created) |
3154 |
*created = name; |
3155 |
else if (name) |
3156 |
g_string_free(name, TRUE); |
2990 |
|
3157 |
|
2991 |
if (created && name) *created = name; |
3158 |
return r; |
2992 |
return name == NULL ? FALSE : TRUE; |
|
|
2993 |
} |
3159 |
} |
2994 |
|
3160 |
|
2995 |
gboolean |
3161 |
gboolean |
2996 |
ldm_volume_dm_remove(const LDMVolume * const o, GString **removed, |
3162 |
ldm_volume_dm_remove(const LDMVolume * const o, GString **removed, |
2997 |
GError ** const err) |
3163 |
GError ** const err) |
2998 |
{ |
3164 |
{ |
|
|
3165 |
if (removed) *removed = NULL; |
3166 |
|
2999 |
const LDMVolumePrivate * const vol = o->priv; |
3167 |
const LDMVolumePrivate * const vol = o->priv; |
3000 |
|
3168 |
|
3001 |
/* We should really store the previous logging function and restore it |
3169 |
gboolean r = FALSE; |
3002 |
* afterwards, but the API doesn't allow this. */ |
|
|
3003 |
dm_log_with_errno_init(_dm_log_fn); |
3004 |
|
3170 |
|
3005 |
struct dm_tree *tree = _get_device_tree(err); |
3171 |
struct dm_tree *tree = NULL; |
3006 |
if (!tree) return FALSE; |
3172 |
struct dm_tree_node *node = NULL; |
3007 |
|
3173 |
|
3008 |
gboolean r = FALSE; |
3174 |
GString *uuid = _dm_vol_uuid(vol); |
|
|
3175 |
gboolean found = _dm_find_tree_node_by_uuid(uuid->str, &node, &tree, err); |
3176 |
g_string_free(uuid, TRUE); |
3009 |
|
3177 |
|
3010 |
GString *name = _dm_vol_name(vol); |
3178 |
GString *name = NULL; |
3011 |
struct dm_tree_node *node = _find_device_tree_node(tree, name->str); |
3179 |
if (found) { |
3012 |
if (node) { |
|
|
3013 |
uint32_t cookie; |
3180 |
uint32_t cookie; |
3014 |
if (!dm_udev_create_cookie(&cookie)) { |
3181 |
if (!dm_udev_create_cookie(&cookie)) { |
3015 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
3182 |
g_set_error(err, LDM_ERROR, LDM_ERROR_EXTERNAL, |
3016 |
"dm_udev_create_cookie: %s", _dm_err_last_msg); |
3183 |
"dm_udev_create_cookie: %s", _dm_err_last_msg); |
3017 |
g_string_free(name, TRUE); name = NULL; |
|
|
3018 |
goto out; |
3184 |
goto out; |
3019 |
} |
3185 |
} |
3020 |
|
3186 |
|
|
|
3187 |
name = _dm_vol_name(vol); |
3021 |
if (!_dm_remove(name->str, cookie, err)) { |
3188 |
if (!_dm_remove(name->str, cookie, err)) { |
3022 |
g_string_free(name, TRUE); name = NULL; |
3189 |
g_string_free(name, TRUE); name = NULL; |
3023 |
goto out; |
3190 |
goto out; |
Lines 3032-3048
Link Here
|
3032 |
} |
3199 |
} |
3033 |
|
3200 |
|
3034 |
dm_udev_wait(cookie); |
3201 |
dm_udev_wait(cookie); |
3035 |
} else { |
|
|
3036 |
g_string_free(name, TRUE); name = NULL; |
3037 |
} |
3202 |
} |
3038 |
|
3203 |
|
3039 |
r = TRUE; |
3204 |
r = TRUE; |
3040 |
|
3205 |
|
3041 |
out: |
3206 |
out: |
3042 |
dm_tree_free(tree); |
3207 |
if (tree) dm_tree_free(tree); |
3043 |
if (removed && name) *removed = name; |
|
|
3044 |
|
3208 |
|
3045 |
dm_log_with_errno_init(NULL); |
3209 |
if (removed) |
|
|
3210 |
*removed = name; |
3211 |
else if (name) |
3212 |
g_string_free(name, TRUE); |
3046 |
|
3213 |
|
3047 |
return r; |
3214 |
return r; |
3048 |
} |
3215 |
} |