1
1
/* libparted - a library for manipulating disk partitions
2
Copyright (C) 1999-2010 Free Software Foundation, Inc.
2
Copyright (C) 1999-2012 Free Software Foundation, Inc.
4
4
This program is free software; you can redistribute it and/or modify
5
5
it under the terms of the GNU General Public License as published by
56
57
# define _(String) (String)
57
58
#endif /* ENABLE_NLS */
60
/* The __attribute__ feature is available in gcc versions 2.5 and later.
61
The __-protected variants of the attributes 'format' and 'printf' are
62
accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
63
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
64
# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
66
# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */
59
69
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
61
71
#ifndef __NR__llseek
222
232
#define SCSI_DISK5_MAJOR 69
223
233
#define SCSI_DISK6_MAJOR 70
224
234
#define SCSI_DISK7_MAJOR 71
235
#define SCSI_DISK8_MAJOR 128
236
#define SCSI_DISK9_MAJOR 129
237
#define SCSI_DISK10_MAJOR 130
238
#define SCSI_DISK11_MAJOR 131
239
#define SCSI_DISK12_MAJOR 132
240
#define SCSI_DISK13_MAJOR 133
241
#define SCSI_DISK14_MAJOR 134
242
#define SCSI_DISK15_MAJOR 135
225
243
#define COMPAQ_SMART2_MAJOR 72
226
244
#define COMPAQ_SMART2_MAJOR1 73
227
245
#define COMPAQ_SMART2_MAJOR2 74
262
280
#define SCSI_BLK_MAJOR(M) ( \
263
281
(M) == SCSI_DISK0_MAJOR \
264
282
|| (M) == SCSI_CDROM_MAJOR \
265
|| ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
283
|| ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) \
284
|| ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
267
286
/* Maximum number of partitions supported by linux. */
268
287
#define MAX_NUM_PARTS 64
551
570
_device_stat (PedDevice* dev, struct stat * dev_stat)
553
PED_ASSERT (dev != NULL, return 0);
554
PED_ASSERT (!dev->external_mode, return 0);
572
PED_ASSERT (dev != NULL);
573
PED_ASSERT (!dev->external_mode);
557
576
if (!stat (dev->path, dev_stat)) {
644
663
static int kver = -1;
646
665
struct utsname uts;
654
673
if (uname (&uts))
656
if (sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny) == 3)
658
else if (sscanf (uts.release, "%u.%u", &major, &minor) == 2)
675
int n = sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny);
676
assert (n == 2 || n == 3);
663
677
return kver = KERNEL_VERSION (major, minor, teeny);
702
716
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
703
717
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
705
PED_ASSERT (dev->open_count, return);
719
PED_ASSERT (dev->open_count);
707
721
if (_get_linux_version() < KERNEL_VERSION (2,3,0)) {
708
722
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
768
782
unsigned long size;
769
783
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
770
784
uint64_t bytes=0;
773
PED_ASSERT (dev->open_count > 0, return 0);
774
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
785
const char* test_str;
789
PED_ASSERT (dev->open_count > 0);
790
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
792
test_str = getenv ("PARTED_TEST_DEVICE_LENGTH");
794
&& xstrtoll (test_str, NULL, 10, &test_size, NULL) == LONGINT_OK)
776
797
if (_kernel_has_blkgetsize64()) {
777
798
if (ioctl(arch_specific->fd, BLKGETSIZE64, &bytes) == 0) {
954
975
if ((f = fopen (name_buf, "r")) == NULL)
957
if (fgets (buf, 255, f) == NULL)
978
if (fgets (buf, 255, f) == NULL) {
961
984
return strip_name (buf);
1238
1261
if (_device_probe_geometry (dev)) {
1239
1262
ped_exception_leave_all ();
1241
if (!_device_get_length (dev)) {
1242
ped_exception_catch ();
1243
ped_exception_leave_all ();
1244
goto error_close_dev;
1264
if (!_device_get_length (dev)) {
1265
ped_exception_catch ();
1266
ped_exception_leave_all ();
1267
goto error_close_dev;
1247
1270
/* hack to allow use of files, for testing */
1248
1271
ped_exception_catch ();
1676
1699
LinuxSpecific* arch_specific;
1678
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
1679
PED_ASSERT (dev != NULL, return 0);
1680
PED_ASSERT (!dev->external_mode, return 0);
1701
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
1702
PED_ASSERT (dev != NULL);
1703
PED_ASSERT (!dev->external_mode);
1682
1705
arch_specific = LINUX_SPECIFIC (dev);
1699
1722
LinuxSpecific* arch_specific;
1700
1723
struct blkdev_ioctl_param ioctl_param;
1702
PED_ASSERT(dev != NULL, return 0);
1703
PED_ASSERT(buffer != NULL, return 0);
1725
PED_ASSERT(dev != NULL);
1726
PED_ASSERT(buffer != NULL);
1705
1728
arch_specific = LINUX_SPECIFIC (dev);
1734
1757
PedExceptionOption ex_status;
1735
1758
void* diobuf = NULL;
1737
PED_ASSERT (dev != NULL, return 0);
1738
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
1760
PED_ASSERT (dev != NULL);
1761
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
1740
1763
if (_get_linux_version() < KERNEL_VERSION (2,6,0)) {
1741
1764
/* Kludge. This is necessary to read/write the last
1829
1852
LinuxSpecific* arch_specific;
1830
1853
struct blkdev_ioctl_param ioctl_param;
1832
PED_ASSERT(dev != NULL, return 0);
1833
PED_ASSERT(buffer != NULL, return 0);
1855
PED_ASSERT(dev != NULL);
1856
PED_ASSERT(buffer != NULL);
1835
1858
arch_specific = LINUX_SPECIFIC (dev);
2036
2059
linux_sync (PedDevice* dev)
2038
PED_ASSERT (dev != NULL, return 0);
2039
PED_ASSERT (!dev->external_mode, return 0);
2061
PED_ASSERT (dev != NULL);
2062
PED_ASSERT (!dev->external_mode);
2041
2064
if (dev->read_only)
2050
2073
linux_sync_fast (PedDevice* dev)
2052
PED_ASSERT (dev != NULL, return 0);
2053
PED_ASSERT (!dev->external_mode, return 0);
2075
PED_ASSERT (dev != NULL);
2076
PED_ASSERT (!dev->external_mode);
2055
2078
if (dev->read_only)
2107
2130
char buf [512];
2108
2131
char part_name [256];
2109
2132
char dev_name [256];
2111
2135
proc_part_file = fopen ("/proc/partitions", "r");
2112
2136
if (!proc_part_file)
2115
2139
if (fgets (buf, 256, proc_part_file) == NULL)
2118
2142
if (fgets (buf, 256, proc_part_file) == NULL)
2121
2145
while (fgets (buf, 512, proc_part_file)
2122
2146
&& sscanf (buf, "%d %d %d %255s", &major, &minor, &size,
2241
2267
_probe_proc_partitions ();
2270
static char * _GL_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
2271
zasprintf (const char *format, ...)
2275
va_start (args, format);
2276
int r = vasprintf (&resultp, format, args);
2278
return r < 0 ? NULL : resultp;
2244
2281
static char *dm_canonical_path (PedDevice *dev)
2246
2283
char* dev_name = NULL;
2270
_device_get_part_path (PedDevice* dev, int num)
2307
_device_get_part_path (PedDevice *dev, int num)
2273
2310
if (dev->type == PED_DEVICE_DM)
2274
2311
devpath = dm_canonical_path (dev);
2275
2312
else devpath = dev->path;
2276
int path_len = strlen (devpath);
2277
int result_len = path_len + 16;
2280
result = (char*) ped_malloc (result_len);
2313
size_t path_len = strlen (devpath);
2284
2316
/* Check for devfs-style /disc => /partN transformation
2285
2317
unconditionally; the system might be using udev with devfs rules,
2286
2318
and if not the test is harmless. */
2287
if (!strcmp (devpath + path_len - 5, "/disc")) {
2288
/* replace /disc with /path%d */
2289
strcpy (result, devpath);
2290
snprintf (result + path_len - 5, 16, "/part%d", num);
2291
} else if (dev->type == PED_DEVICE_DAC960
2292
|| dev->type == PED_DEVICE_CPQARRAY
2293
|| dev->type == PED_DEVICE_ATARAID
2294
|| isdigit (devpath[path_len - 1]))
2295
snprintf (result, result_len, "%sp%d", devpath, num);
2297
snprintf (result, result_len, "%s%d", devpath, num);
2298
if (dev->type == PED_DEVICE_DM)
2319
if (5 < path_len && !strcmp (devpath + path_len - 5, "/disc")) {
2320
/* replace /disc with /part%d */
2321
result = zasprintf ("%.*s/part%d",
2322
(int) (path_len - 5), devpath, num);
2324
char const *p = (dev->type == PED_DEVICE_DAC960
2325
|| dev->type == PED_DEVICE_CPQARRAY
2326
|| dev->type == PED_DEVICE_ATARAID
2327
|| isdigit (devpath[path_len - 1])
2329
result = zasprintf ("%s%s%d", devpath, p, num);
2349
2381
return _partition_is_mounted_by_dev (part_stat.st_rdev);
2384
/* If partition PART is mounted, or if we encounter an out-of-memory error
2385
while trying to determine its status, return 1. Otherwise, return 0. */
2353
2387
_partition_is_mounted (const PedPartition *part)
2357
if (!ped_partition_is_active (part))
2359
part_name = _device_get_part_path (part->disk->dev, part->num);
2389
if (!ped_partition_is_active (part))
2391
char *part_name = _device_get_part_path (part->disk->dev, part->num);
2360
2392
if (!part_name)
2362
status = _partition_is_mounted_by_path (part_name);
2394
int status = _partition_is_mounted_by_path (part_name);
2363
2395
free (part_name);
2370
_has_partitions (const PedDisk* disk)
2372
PED_ASSERT(disk != NULL, return 0);
2374
/* Some devices can't be partitioned. */
2375
if (!strcmp (disk->type->name, "loop"))
2417
2435
const char* vol_name;
2418
2436
char* dev_name;
2420
PED_ASSERT(disk != NULL, return 0);
2421
PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0,
2424
if (!_has_partitions (disk))
2438
PED_ASSERT(disk != NULL);
2439
PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
2427
2441
if (ped_disk_type_check_feature (disk->type,
2428
2442
PED_DISK_TYPE_PARTITION_NAME))
2473
2487
struct blkpg_partition linux_part;
2475
if (!_has_partitions (disk))
2478
2489
memset (&linux_part, 0, sizeof (linux_part));
2479
2490
linux_part.pno = n;
2480
2491
return _blkpg_part_command (disk->dev, &linux_part,
2488
2499
const char* vol_name;
2489
2500
char* dev_name;
2491
PED_ASSERT(disk != NULL, return 0);
2492
PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0, return 0);
2502
PED_ASSERT (disk != NULL);
2503
PED_ASSERT (disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
2494
2505
dev_name = _device_get_part_path (disk->dev, part->num);
2542
/* Read the integer from /sys/block/DEV_BASE/ENTRY and set *VAL
2543
to that value, where DEV_BASE is the last component of DEV->path.
2544
Upon success, return true. Otherwise, return false. */
2546
_sysfs_int_entry_from_dev(PedDevice const* dev, const char *entry, int *val)
2549
int r = snprintf(path, sizeof(path), "/sys/block/%s/%s",
2550
last_component(dev->path), entry);
2551
if (r < 0 || r >= sizeof(path))
2554
FILE *fp = fopen(path, "r");
2558
bool ok = fscanf(fp, "%d", val) == 1;
2531
2564
/* Read the unsigned long long from /sys/block/DEV_BASE/PART_BASE/ENTRY
2532
2565
and set *VAL to that value, where DEV_BASE is the last component of path to
2533
2566
block device corresponding to PART and PART_BASE is the sysfs name of PART.
2568
2601
unsigned long long *start,
2569
2602
unsigned long long *length)
2571
PED_ASSERT(part, return false);
2572
PED_ASSERT(start, return false);
2573
PED_ASSERT(length, return false);
2575
2608
char *dev_name = linux_partition_get_path (part);
2625
2658
static unsigned int
2626
_device_get_partition_range(PedDevice* dev)
2659
_device_get_partition_range(PedDevice const* dev)
2662
bool ok = _sysfs_int_entry_from_dev(dev, "ext_range", &range);
2633
2664
if (dev->type == PED_DEVICE_DM)
2634
2665
return MAX_NUM_PARTS;
2636
r = snprintf(path, sizeof(path), "/sys/block/%s/ext_range",
2637
last_component(dev->path));
2638
if (r < 0 || r >= sizeof(path))
2639
return MAX_NUM_PARTS;
2641
fp = fopen(path, "r");
2643
return MAX_NUM_PARTS;
2645
ok = fscanf(fp, "%d", &range) == 1;
2648
/* (range <= 0) is none sense.*/
2649
return ok && range > 0 ? range : MAX_NUM_PARTS;
2668
return MAX_NUM_PARTS;
2669
/* both 0 and 1 mean no partitions */
2670
return range > 1 ? range : 0;
2667
2688
_disk_sync_part_table (PedDisk* disk)
2669
PED_ASSERT(disk != NULL, return 0);
2670
PED_ASSERT(disk->dev != NULL, return 0);
2690
PED_ASSERT(disk != NULL);
2691
PED_ASSERT(disk->dev != NULL);
2694
unsigned int part_range = _device_get_partition_range(disk->dev);
2673
2696
int (*add_partition)(PedDisk* disk, const PedPartition *part);
2674
2697
int (*remove_partition)(PedDisk* disk, int partno);
2675
2698
bool (*get_partition_start_and_length)(PedPartition const *part,
2690
2713
/* lpn = largest partition number. */
2691
2714
if (ped_disk_get_max_supported_partition_count(disk, &lpn))
2692
lpn = PED_MIN(lpn, _device_get_partition_range(disk->dev));
2715
lpn = PED_MIN(lpn, part_range);
2694
lpn = _device_get_partition_range(disk->dev);
2696
2719
/* Its not possible to support largest_partnum < 0.
2697
2720
* largest_partnum == 0 would mean does not support partitions.
2702
2725
int *ok = calloc (lpn, sizeof *ok);
2904
2927
if (!(task = dm_task_create(DM_DEVICE_TABLE)))
2906
2929
path = _device_get_part_path (part->disk->dev, part->num);
2907
PED_ASSERT(path, return false);
2908
2932
dm_task_set_name(task, path);
2909
2933
if (!dm_task_run(task))
2945
2966
dev_name = dm_task_get_name (task);
2947
2968
if (isdigit (dev_name[strlen (dev_name) - 1])) {
2948
if (asprintf (&vol_name, "%sp%d", dev_name, part->num) == -1)
2969
if ( ! (vol_name = zasprintf ("%sp%d", dev_name, part->num)))
2950
} else if (asprintf (&vol_name, "%s%d", dev_name, part->num) == -1)
2971
} else if ( ! (vol_name = zasprintf ("%s%d", dev_name, part->num)))
2953
2974
/* Caution: dm_task_destroy frees dev_name. */
2954
2975
dm_task_destroy (task);
2957
if (asprintf (¶ms, "%d:%d %lld", arch_specific->major,
2958
arch_specific->minor, part->geom.start) == -1)
2978
if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major,
2979
arch_specific->minor, part->geom.start)))
2961
2982
task = dm_task_create (DM_DEVICE_CREATE);
3101
/* If optimal_io_size is 0 _and_ alignment_offset is 0 _and_
3102
minimum_io_size is a power of 2 then go with the device.c default */
3103
unsigned long minimum_io_size = blkid_topology_get_minimum_io_size(tp);
3104
if (blkid_topology_get_optimal_io_size(tp) == 0 &&
3105
blkid_topology_get_alignment_offset(tp) == 0 &&
3106
(minimum_io_size & (minimum_io_size - 1)) == 0)
3119
/* When PED_DEFAULT_ALIGNMENT is divisible by the *_io_size or
3120
there are no *_io_size values, use the PED_DEFAULT_ALIGNMENT
3121
If one or the other will not divide evenly, fall through to
3123
unsigned long optimal_io = blkid_topology_get_optimal_io_size(tp);
3124
unsigned long minimum_io = blkid_topology_get_minimum_io_size(tp);
3126
(!optimal_io && !minimum_io)
3127
|| (optimal_io && PED_DEFAULT_ALIGNMENT % optimal_io == 0
3128
&& minimum_io && PED_DEFAULT_ALIGNMENT % minimum_io == 0)
3129
|| (!minimum_io && optimal_io
3130
&& PED_DEFAULT_ALIGNMENT % optimal_io == 0)
3131
|| (!optimal_io && minimum_io
3132
&& PED_DEFAULT_ALIGNMENT % minimum_io == 0)
3134
/* DASD needs to use minimum alignment */
3135
if (dev->type == PED_DEVICE_DASD)
3136
return linux_get_minimum_alignment(dev);
3138
return ped_alignment_new(
3139
blkid_topology_get_alignment_offset(tp) / dev->sector_size,
3140
PED_DEFAULT_ALIGNMENT / dev->sector_size);
3109
3143
/* If optimal_io_size is 0 and we don't meet the other criteria
3110
3144
for using the device.c default, return the minimum alignment. */