1
/* libparted - a library for manipulating disk partitions
2
Copyright (C) 1999-2014 Free Software Foundation, Inc.
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation; either version 3 of the License, or
7
(at your option) any later version.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
GNU General Public License for more details.
14
You should have received a copy of the GNU General Public License
15
along with this program. If not, see <http://www.gnu.org/licenses/>.
18
#define PROC_DEVICES_BUFSIZ 16384
21
#include <arch/linux.h>
22
#include <linux/blkpg.h>
23
#include <parted/parted.h>
24
#include <parted/debug.h>
25
#if defined __s390__ || defined __s390x__
26
#include <parted/fdasd.h>
39
#include <sys/ioctl.h>
41
#include <sys/types.h>
42
#include <sys/utsname.h> /* for uname() */
43
#include <scsi/scsi.h>
45
#ifdef ENABLE_DEVICE_MAPPER
46
#include <libdevmapper.h>
49
#include "../architecture.h"
56
# define _(String) dgettext (PACKAGE, String)
58
# define _(String) (String)
59
#endif /* ENABLE_NLS */
61
/* The __attribute__ feature is available in gcc versions 2.5 and later.
62
The __-protected variants of the attributes 'format' and 'printf' are
63
accepted by gcc versions 2.6.4 (effectively 2.7) and later. */
64
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
65
# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
67
# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */
70
#define STRPREFIX(a, b) (strncmp (a, b, strlen (b)) == 0)
72
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
75
#define __NR__llseek 140
78
#ifndef SCSI_IOCTL_SEND_COMMAND
79
#define SCSI_IOCTL_SEND_COMMAND 1
82
/* from <linux/hdreg.h> */
83
#define HDIO_GETGEO 0x0301 /* get device geometry */
84
#define HDIO_GET_IDENTITY 0x030d /* get IDE identification info */
86
#define RD_MODE (O_RDONLY)
87
#define WR_MODE (O_WRONLY)
88
#define RW_MODE (O_RDWR)
92
unsigned char sectors;
93
unsigned short cylinders;
97
struct ata7_sectinfo {
104
/* structure returned by HDIO_GET_IDENTITY, as per ANSI ATA2 rev.2f spec */
106
unsigned short config; /* lots of obsolete bit flags */
107
unsigned short cyls; /* "physical" cyls */
108
unsigned short reserved2; /* reserved (word 2) */
109
unsigned short heads; /* "physical" heads */
110
unsigned short track_bytes; /* unformatted bytes per track */
111
unsigned short sector_bytes; /* unformatted bytes per sector */
112
unsigned short sectors; /* "physical" sectors per track */
113
unsigned short vendor0; /* vendor unique */
114
unsigned short vendor1; /* vendor unique */
115
unsigned short vendor2; /* vendor unique */
116
unsigned char serial_no[20]; /* 0 = not_specified */
117
unsigned short buf_type;
118
unsigned short buf_size; /* 512 byte increments;
120
unsigned short ecc_bytes; /* for r/w long cmds;
122
unsigned char fw_rev[8]; /* 0 = not_specified */
123
char model[40]; /* 0 = not_specified */
124
unsigned char max_multsect; /* 0=not_implemented */
125
unsigned char vendor3; /* vendor unique */
126
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
127
unsigned char vendor4; /* vendor unique */
128
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw
130
unsigned short reserved50; /* reserved (word 50) */
131
unsigned char vendor5; /* vendor unique */
132
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
133
unsigned char vendor6; /* vendor unique */
134
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
135
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
136
unsigned short cur_cyls; /* logical cylinders */
137
unsigned short cur_heads; /* logical heads */
138
unsigned short cur_sectors; /* logical sectors per track */
139
unsigned short cur_capacity0; /* logical total sectors on drive */
140
unsigned short cur_capacity1; /* (2 words, misaligned int) */
141
unsigned char multsect; /* current multiple sector count */
142
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
143
unsigned int lba_capacity; /* total number of sectors */
144
unsigned short dma_1word; /* single-word dma info */
145
unsigned short dma_mword; /* multiple-word dma info */
146
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
147
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
148
unsigned short eide_dma_time; /* recommended mword dma cycle
150
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
151
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
152
unsigned short words69_70[2]; /* reserved words 69-70 */
153
/* HDIO_GET_IDENTITY currently returns only words 0 through 70 */
154
unsigned short words71_74[4]; /* reserved words 71-74 */
155
unsigned short queue_depth; /* */
156
unsigned short words76_79[4]; /* reserved words 76-79 */
157
unsigned short major_rev_num; /* */
158
unsigned short minor_rev_num; /* */
159
unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable
161
unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero */
162
unsigned short cfsse; /* command set-feature supported
164
unsigned short cfs_enable_1; /* command set-feature enabled */
165
unsigned short cfs_enable_2; /* command set-feature enabled */
166
unsigned short csf_default; /* command set-feature default */
167
unsigned short dma_ultra; /* */
168
unsigned short word89; /* reserved (word 89) */
169
unsigned short word90; /* reserved (word 90) */
170
unsigned short CurAPMvalues; /* current APM values */
171
unsigned short word92; /* reserved (word 92) */
172
unsigned short hw_config; /* hardware config */
173
unsigned short words94_105[12];/* reserved words 94-105 */
174
struct ata7_sectinfo ata7_sectinfo; /* ATAPI/ATA7 physical and logical
176
unsigned short words107_116[10];/* reserved words 107-116 */
177
unsigned int logical_sectsize;/* ATAPI/ATA7 logical sector size */
178
unsigned short words119_125[7];/* reserved words 119-125 */
179
unsigned short last_lun; /* reserved (word 126) */
180
unsigned short word127; /* reserved (word 127) */
181
unsigned short dlf; /* device lock function
183
* 8 security level 1:max 0:high
192
unsigned short csfo; /* current set features options
199
unsigned short words130_155[26];/* reserved vendor words 130-155 */
200
unsigned short word156;
201
unsigned short words157_159[3]; /* reserved vendor words 157-159 */
202
unsigned short words160_255[95];/* reserved words 160-255 */
205
/* from <linux/fs.h> */
206
#define BLKRRPART _IO(0x12,95) /* re-read partition table */
207
#define BLKGETSIZE _IO(0x12,96) /* return device size */
208
#define BLKFLSBUF _IO(0x12,97) /* flush buffer cache */
209
#define BLKSSZGET _IO(0x12,104) /* get block device sector size */
210
#define BLKGETLASTSECT _IO(0x12,108) /* get last sector of block device */
211
#define BLKSETLASTSECT _IO(0x12,109) /* set last sector of block device */
213
/* return device size in bytes (u64 *arg) */
214
#define BLKGETSIZE64 _IOR(0x12,114,size_t)
216
struct blkdev_ioctl_param {
218
size_t content_length;
219
char * block_contents;
222
/* from <linux/major.h> */
224
#define IDE1_MAJOR 22
225
#define IDE2_MAJOR 33
226
#define IDE3_MAJOR 34
227
#define IDE4_MAJOR 56
228
#define IDE5_MAJOR 57
229
#define SCSI_CDROM_MAJOR 11
230
#define SCSI_DISK0_MAJOR 8
231
#define SCSI_DISK1_MAJOR 65
232
#define SCSI_DISK2_MAJOR 66
233
#define SCSI_DISK3_MAJOR 67
234
#define SCSI_DISK4_MAJOR 68
235
#define SCSI_DISK5_MAJOR 69
236
#define SCSI_DISK6_MAJOR 70
237
#define SCSI_DISK7_MAJOR 71
238
#define SCSI_DISK8_MAJOR 128
239
#define SCSI_DISK9_MAJOR 129
240
#define SCSI_DISK10_MAJOR 130
241
#define SCSI_DISK11_MAJOR 131
242
#define SCSI_DISK12_MAJOR 132
243
#define SCSI_DISK13_MAJOR 133
244
#define SCSI_DISK14_MAJOR 134
245
#define SCSI_DISK15_MAJOR 135
246
#define COMPAQ_SMART2_MAJOR 72
247
#define COMPAQ_SMART2_MAJOR1 73
248
#define COMPAQ_SMART2_MAJOR2 74
249
#define COMPAQ_SMART2_MAJOR3 75
250
#define COMPAQ_SMART2_MAJOR4 76
251
#define COMPAQ_SMART2_MAJOR5 77
252
#define COMPAQ_SMART2_MAJOR6 78
253
#define COMPAQ_SMART2_MAJOR7 79
254
#define COMPAQ_SMART_MAJOR 104
255
#define COMPAQ_SMART_MAJOR1 105
256
#define COMPAQ_SMART_MAJOR2 106
257
#define COMPAQ_SMART_MAJOR3 107
258
#define COMPAQ_SMART_MAJOR4 108
259
#define COMPAQ_SMART_MAJOR5 109
260
#define COMPAQ_SMART_MAJOR6 110
261
#define COMPAQ_SMART_MAJOR7 111
262
#define DAC960_MAJOR 48
263
#define ATARAID_MAJOR 114
264
#define I2O_MAJOR1 80
265
#define I2O_MAJOR2 81
266
#define I2O_MAJOR3 82
267
#define I2O_MAJOR4 83
268
#define I2O_MAJOR5 84
269
#define I2O_MAJOR6 85
270
#define I2O_MAJOR7 86
271
#define I2O_MAJOR8 87
273
#define DASD_MAJOR 94
274
#define VIODASD_MAJOR 112
275
#define AOE_MAJOR 152
276
#define SX8_MAJOR1 160
277
#define SX8_MAJOR2 161
278
#define XVD_MAJOR 202
279
#define SDMMC_MAJOR 179
283
#define SCSI_BLK_MAJOR(M) ( \
284
(M) == SCSI_DISK0_MAJOR \
285
|| (M) == SCSI_CDROM_MAJOR \
286
|| ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) \
287
|| ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
289
/* Maximum number of partitions supported by linux. */
290
#define MAX_NUM_PARTS 64
292
static char* _device_get_part_path (PedDevice const *dev, int num);
293
static int _partition_is_mounted_by_path (const char* path);
294
static unsigned int _device_get_partition_range(PedDevice const* dev);
298
_read_fd (int fd, char **buf)
301
size_t size = PROC_DEVICES_BUFSIZ;
304
*buf = malloc (size * sizeof (char));
310
p = &(*buf) [filesize];
311
s = read (fd, p, PROC_DEVICES_BUFSIZ);
312
/* exit if there is an error or EOF is reached */
317
char *new_buf = realloc (*buf, size);
318
if (new_buf == NULL) {
319
int saved_errno = errno;
327
if (filesize == 0 && s < 0) {
332
char *new_buf = realloc (*buf, filesize + 1);
333
if (new_buf == NULL) {
334
int saved_errno = errno;
340
(*buf)[filesize] = '\0';
347
_major_type_in_devices (int major, const char* type)
356
fd = open ("/proc/devices", O_RDONLY);
360
if (_read_fd(fd, &buf) < 0) {
366
end = strchr(line, '\n');
375
if (!strncmp(line, "Block devices:", 14))
380
name = strrchr(line, ' ');
381
if (!name || strcmp(name+1, type))
384
maj = strtol(line, &name, 10);
394
end = strchr(line, '\n');
402
_is_ide_major (int major)
419
_is_cpqarray_major (int major)
421
return ((COMPAQ_SMART2_MAJOR <= major && major <= COMPAQ_SMART2_MAJOR7)
422
|| (COMPAQ_SMART_MAJOR <= major && major <= COMPAQ_SMART_MAJOR7));
426
_is_i2o_major (int major)
428
return (I2O_MAJOR1 <= major && major <= I2O_MAJOR8);
432
_is_sx8_major (int major)
434
return (SX8_MAJOR1 <= major && major <= SX8_MAJOR2);
438
_is_virtblk_major (int major)
440
return _major_type_in_devices (major, "virtblk");
443
#ifdef ENABLE_DEVICE_MAPPER
445
_dm_task_run_wait (struct dm_task *task, uint32_t cookie)
449
rc = dm_task_run (task);
450
dm_udev_wait (cookie);
456
_is_dm_major (int major)
458
return _major_type_in_devices (major, "device-mapper");
462
_dm_maptype (PedDevice *dev)
464
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
466
uint64_t start, length;
467
char *target_type = NULL;
470
const char* dev_dir = getenv ("DM_DEV_DIR");
472
if (dev_dir && *dev_dir && !dm_set_dev_dir(dev_dir))
475
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
478
if (!dm_task_set_major_minor(dmt, arch_specific->major,
479
arch_specific->minor, 0))
482
dm_task_no_open_count(dmt);
484
if (!dm_task_run(dmt))
487
dm_get_next_target(dmt, NULL, &start, &length, &target_type, ¶ms);
489
arch_specific->dmtype = strdup(target_type ? target_type : "NO-TARGET");
490
if (arch_specific->dmtype == NULL)
494
dm_task_destroy(dmt);
498
/* Return nonzero if device-mapper device, DEVPATH, is part of a dmraid
499
array. Use the heuristic of checking for the string "DMRAID-" at the
500
start of its UUID. */
502
_is_dmraid_device (const char *devpath)
506
char const *dm_name = strrchr (devpath, '/');
507
char const *dm_basename = dm_name && *(++dm_name) ? dm_name : devpath;
508
struct dm_task *task = dm_task_create (DM_DEVICE_DEPS);
512
dm_task_set_name (task, dm_basename);
513
if (!dm_task_run (task))
516
const char *dmraid_uuid = dm_task_get_uuid (task);
517
if (STRPREFIX (dmraid_uuid, "DMRAID-"))
521
dm_task_destroy (task);
525
/* We consider a dm device that is a linear mapping with a *
526
* single target that also is a dm device to be a partition */
529
_dm_is_part (const char *path)
532
struct dm_task *task = dm_task_create (DM_DEVICE_DEPS);
536
dm_task_set_name(task, path);
537
if (!dm_task_run(task))
540
struct dm_info *info = alloca (sizeof *info);
541
memset(info, '\0', sizeof *info);
542
dm_task_get_info (task, info);
546
struct dm_deps *deps = dm_task_get_deps (task);
550
if (deps->count != 1)
552
if (!_is_dm_major (major (deps->device[0])))
554
dm_task_destroy (task);
555
if (!(task = dm_task_create (DM_DEVICE_TABLE)))
557
dm_task_set_name (task, path);
558
if (!dm_task_run (task))
561
char *target_type = NULL;
563
uint64_t start, length;
565
dm_get_next_target (task, NULL, &start, &length, &target_type, ¶ms);
566
if (strcmp (target_type, "linear"))
571
dm_task_destroy(task);
580
char buf [512]; /* readdir(3) claims d_name[256] */
583
mapper_dir = opendir ("/dev/mapper");
587
/* Search the /dev/mapper directory for devices w/ the same major
588
* number that was returned from _probe_lvm_major().
590
while ((dent = readdir (mapper_dir))) {
591
if (strcmp (dent->d_name, ".") == 0 ||
592
strcmp (dent->d_name, "..") == 0)
595
snprintf (buf, sizeof (buf), "/dev/mapper/%s", dent->d_name);
597
if (stat (buf, &st) != 0)
600
if (_is_dm_major(major(st.st_rdev)) && _is_dmraid_device (buf)
601
&& !_dm_is_part(buf))
602
_ped_device_probe (buf);
604
closedir (mapper_dir);
611
_device_stat (PedDevice* dev, struct stat * dev_stat)
613
PED_ASSERT (dev != NULL);
614
PED_ASSERT (!dev->external_mode);
617
if (!stat (dev->path, dev_stat)) {
620
if (ped_exception_throw (
622
PED_EXCEPTION_RETRY_CANCEL,
623
_("Could not stat device %s - %s."),
626
!= PED_EXCEPTION_RETRY)
633
_device_probe_type (PedDevice* dev)
635
struct stat dev_stat;
638
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
640
if (!_device_stat (dev, &dev_stat))
643
if (!S_ISBLK(dev_stat.st_mode)) {
644
dev->type = PED_DEVICE_FILE;
648
arch_specific->major = dev_major = major (dev_stat.st_rdev);
649
arch_specific->minor = dev_minor = minor (dev_stat.st_rdev);
651
if (SCSI_BLK_MAJOR (dev_major) && (dev_minor % 0x10 == 0)) {
652
dev->type = PED_DEVICE_SCSI;
653
} else if (_is_ide_major (dev_major) && (dev_minor % 0x40 == 0)) {
654
dev->type = PED_DEVICE_IDE;
655
} else if (dev_major == DAC960_MAJOR && (dev_minor % 0x8 == 0)) {
656
dev->type = PED_DEVICE_DAC960;
657
} else if (dev_major == ATARAID_MAJOR && (dev_minor % 0x10 == 0)) {
658
dev->type = PED_DEVICE_ATARAID;
659
} else if (dev_major == AOE_MAJOR && (dev_minor % 0x10 == 0)) {
660
dev->type = PED_DEVICE_AOE;
661
} else if (dev_major == DASD_MAJOR && (dev_minor % 0x4 == 0)) {
662
dev->type = PED_DEVICE_DASD;
663
} else if (dev_major == VIODASD_MAJOR && (dev_minor % 0x8 == 0)) {
664
dev->type = PED_DEVICE_VIODASD;
665
} else if (_is_sx8_major(dev_major) && (dev_minor % 0x20 == 0)) {
666
dev->type = PED_DEVICE_SX8;
667
} else if (_is_i2o_major (dev_major) && (dev_minor % 0x10 == 0)) {
668
dev->type = PED_DEVICE_I2O;
669
} else if (_is_cpqarray_major (dev_major) && (dev_minor % 0x10 == 0)) {
670
dev->type = PED_DEVICE_CPQARRAY;
671
} else if (dev_major == UBD_MAJOR && (dev_minor % 0x10 == 0)) {
672
dev->type = PED_DEVICE_UBD;
673
#ifdef ENABLE_DEVICE_MAPPER
674
} else if (_is_dm_major(dev_major)) {
675
dev->type = PED_DEVICE_DM;
676
if (_dm_maptype(dev)) {
677
ped_exception_throw (
679
PED_EXCEPTION_CANCEL,
680
_("Unable to determine the dm type of %s."),
684
} else if (dev_major == XVD_MAJOR && (dev_minor % 0x10 == 0)) {
685
dev->type = PED_DEVICE_XVD;
686
} else if (dev_major == SDMMC_MAJOR && (dev_minor % 0x08 == 0)) {
687
dev->type = PED_DEVICE_SDMMC;
688
} else if (_is_virtblk_major(dev_major)) {
689
dev->type = PED_DEVICE_VIRTBLK;
690
} else if (dev_major == LOOP_MAJOR) {
691
dev->type = PED_DEVICE_LOOP;
692
} else if (dev_major == MD_MAJOR) {
693
dev->type = PED_DEVICE_MD;
695
dev->type = PED_DEVICE_UNKNOWN;
702
_get_linux_version ()
704
static int kver = -1;
716
int n = sscanf (uts.release, "%u.%u.%u", &major, &minor, &teeny);
717
assert (n == 2 || n == 3);
718
return kver = KERNEL_VERSION (major, minor, teeny);
723
get_blkid_topology (LinuxSpecific *arch_specific)
725
arch_specific->probe = blkid_new_probe ();
726
if (!arch_specific->probe)
729
if (blkid_probe_set_device(arch_specific->probe,
730
arch_specific->fd, 0, 0))
733
arch_specific->topology =
734
blkid_probe_get_topology(arch_specific->probe);
739
_device_set_sector_size (PedDevice* dev)
741
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
744
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
745
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
747
PED_ASSERT (dev->open_count);
749
if (_get_linux_version() < KERNEL_VERSION (2,3,0)) {
750
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
754
if (ioctl (arch_specific->fd, BLKSSZGET, §or_size)) {
755
ped_exception_throw (
756
PED_EXCEPTION_WARNING,
758
_("Could not determine sector size for %s: %s.\n"
759
"Using the default sector size (%lld)."),
760
dev->path, strerror (errno), PED_SECTOR_SIZE_DEFAULT);
762
dev->sector_size = (long long)sector_size;
763
dev->phys_sector_size = dev->sector_size;
767
get_blkid_topology(arch_specific);
768
if (!arch_specific->topology) {
769
dev->phys_sector_size = 0;
771
dev->phys_sector_size =
772
blkid_topology_get_physical_sector_size(
773
arch_specific->topology);
775
if (dev->phys_sector_size == 0) {
776
ped_exception_throw (
777
PED_EXCEPTION_WARNING,
779
_("Could not determine physical sector size for %s.\n"
780
"Using the logical sector size (%lld)."),
781
dev->path, dev->sector_size);
782
dev->phys_sector_size = dev->sector_size;
786
#if defined __s390__ || defined __s390x__
787
/* Return PED_SECTOR_SIZE_DEFAULT for DASDs. */
788
if (dev->type == PED_DEVICE_DASD) {
789
arch_specific->real_sector_size = dev->sector_size;
790
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
796
_kernel_has_blkgetsize64(void)
798
int version = _get_linux_version();
800
if (version >= KERNEL_VERSION (2,5,4)) return 1;
801
if (version < KERNEL_VERSION (2,5,0) &&
802
version >= KERNEL_VERSION (2,4,18)) return 1;
806
/* TODO: do a binary search if BLKGETSIZE doesn't work?! */
808
_device_get_length (PedDevice* dev)
811
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
813
const char* test_str;
817
PED_ASSERT (dev->open_count > 0);
818
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
820
test_str = getenv ("PARTED_TEST_DEVICE_LENGTH");
822
&& xstrtoll (test_str, NULL, 10, &test_size, NULL) == LONGINT_OK)
825
if (_kernel_has_blkgetsize64()) {
826
if (ioctl(arch_specific->fd, BLKGETSIZE64, &bytes) == 0) {
827
return bytes / dev->sector_size;
831
if (ioctl (arch_specific->fd, BLKGETSIZE, &size)) {
832
ped_exception_throw (
834
PED_EXCEPTION_CANCEL,
835
_("Unable to determine the size of %s (%s)."),
845
_device_probe_geometry (PedDevice* dev)
847
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
848
struct stat dev_stat;
849
struct hd_geometry geometry;
851
if (!_device_stat (dev, &dev_stat))
853
PED_ASSERT (S_ISBLK (dev_stat.st_mode));
855
_device_set_sector_size (dev);
857
dev->length = _device_get_length (dev);
861
/* The GETGEO ioctl is no longer useful (as of linux 2.6.x). We could
862
* still use it in 2.4.x, but this is contentious. Perhaps we should
864
dev->bios_geom.sectors = 63;
865
dev->bios_geom.heads = 255;
866
dev->bios_geom.cylinders
867
= dev->length / (63 * 255);
869
/* FIXME: what should we put here? (TODO: discuss on linux-kernel) */
870
if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geometry)
871
&& geometry.sectors && geometry.heads) {
872
dev->hw_geom.sectors = geometry.sectors;
873
dev->hw_geom.heads = geometry.heads;
874
dev->hw_geom.cylinders
875
= dev->length / (dev->hw_geom.heads
876
* dev->hw_geom.sectors);
878
dev->hw_geom = dev->bios_geom;
885
strip_name(char* str)
890
for (i = 0; str[i] != 0; i++) {
891
if (!isspace (str[i])
892
|| (isspace (str[i]) && !isspace (str[i+1]) && str[i+1])) {
902
init_ide (PedDevice* dev)
904
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
905
struct stat dev_stat;
906
struct hd_driveid hdi;
907
PedExceptionOption ex_status;
909
int sector_multiplier = 0;
911
if (!_device_stat (dev, &dev_stat))
914
if (!ped_device_open (dev))
917
if (ioctl (arch_specific->fd, HDIO_GET_IDENTITY, &hdi)) {
918
ex_status = ped_exception_throw (
919
PED_EXCEPTION_WARNING,
920
PED_EXCEPTION_IGNORE_CANCEL,
921
_("Could not get identity of device %s - %s"),
922
dev->path, strerror (errno));
924
case PED_EXCEPTION_CANCEL:
925
goto error_close_dev;
927
case PED_EXCEPTION_UNHANDLED:
928
ped_exception_catch ();
929
case PED_EXCEPTION_IGNORE:
930
dev->model = strdup(_("Generic IDE"));
937
/* hdi.model is not guaranteed to be NULL terminated */
938
memcpy (hdi_buf, hdi.model, 40);
940
dev->model = strip_name (hdi_buf);
942
if (!hdi.ata7_sectinfo.valid1 && hdi.ata7_sectinfo.valid2)
943
sector_multiplier = hdi.ata7_sectinfo.multiplier;
945
sector_multiplier = 1;
947
if (sector_multiplier != 1) {
948
ex_status = ped_exception_throw (
949
PED_EXCEPTION_WARNING,
950
PED_EXCEPTION_IGNORE_CANCEL,
951
_("Device %s has multiple (%d) logical sectors "
952
"per physical sector.\n"
953
"GNU Parted supports this EXPERIMENTALLY for "
954
"some special disk label/file system "
955
"combinations, e.g. GPT and ext2/3.\n"
956
"Please consult the web site for up-to-date "
958
dev->path, sector_multiplier);
961
case PED_EXCEPTION_CANCEL:
962
goto error_close_dev;
964
case PED_EXCEPTION_UNHANDLED:
965
ped_exception_catch ();
966
case PED_EXCEPTION_IGNORE:
974
/* XXX sector_size has not been set yet! */
975
/* dev->phys_sector_size = dev->sector_size
976
* sector_multiplier;*/
977
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
980
if (!_device_probe_geometry (dev))
981
goto error_close_dev;
983
ped_device_close (dev);
987
ped_device_close (dev);
992
/* This function reads the /sys entry named "file" for device "dev". */
994
read_device_sysfs_file (PedDevice *dev, const char *file)
1000
snprintf (name_buf, 127, "/sys/block/%s/device/%s",
1001
last_component (dev->path), file);
1003
if ((f = fopen (name_buf, "r")) == NULL)
1006
if (fgets (buf, 255, f) == NULL) {
1012
return strip_name (buf);
1015
/* This function sends a query to a SCSI device for vendor and product
1016
* information. It uses the deprecated SCSI_IOCTL_SEND_COMMAND to
1020
scsi_query_product_info (PedDevice* dev, char **vendor, char **product)
1022
/* The following are defined by the SCSI-2 specification. */
1023
typedef struct _scsi_inquiry_cmd
1026
uint8_t lun; /* bits 5-7 denote the LUN */
1029
uint8_t alloc_length;
1031
} __attribute__((packed)) scsi_inquiry_cmd_t;
1033
typedef struct _scsi_inquiry_data
1035
uint8_t peripheral_info;
1036
uint8_t device_info;
1037
uint8_t version_info;
1039
uint8_t additional_length;
1043
uint8_t vendor_id[8];
1044
uint8_t product_id[16];
1045
uint8_t product_revision[4];
1046
uint8_t vendor_specific[20];
1047
uint8_t _reserved3[40];
1048
} __attribute__((packed)) scsi_inquiry_data_t;
1053
unsigned int outlen;
1057
scsi_inquiry_data_t out;
1058
scsi_inquiry_cmd_t in;
1062
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1068
memset (&arg, 0x00, sizeof(struct scsi_arg));
1070
arg.outlen = sizeof(scsi_inquiry_data_t);
1071
arg.data.in.op = INQUIRY;
1072
arg.data.in.lun = dev->host << 5;
1073
arg.data.in.alloc_length = sizeof(scsi_inquiry_data_t);
1074
arg.data.in.page_code = 0;
1075
arg.data.in.reserved = 0;
1076
arg.data.in.control = 0;
1078
if (ioctl (arch_specific->fd, SCSI_IOCTL_SEND_COMMAND, &arg) < 0)
1081
memcpy (buf, arg.data.out.vendor_id, 8);
1083
*vendor = strip_name (buf);
1085
memcpy (buf, arg.data.out.product_id, 16);
1087
*product = strip_name (buf);
1092
/* This function provides the vendor and product name for a SCSI device.
1093
* It supports both the modern /sys interface and direct queries
1094
* via the deprecated ioctl, SCSI_IOCTL_SEND_COMMAND.
1097
scsi_get_product_info (PedDevice* dev, char **vendor, char **product)
1099
*vendor = read_device_sysfs_file (dev, "vendor");
1100
*product = read_device_sysfs_file (dev, "model");
1101
if (*vendor && *product)
1104
return scsi_query_product_info (dev, vendor, product);
1108
init_scsi (PedDevice* dev)
1113
uint32_t host_unique_id;
1116
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1120
if (!ped_device_open (dev))
1123
if (ioctl (arch_specific->fd, SCSI_IOCTL_GET_IDLUN, &idlun) < 0) {
1126
if (ped_exception_throw (
1127
PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL,
1128
_("Error initialising SCSI device %s - %s"),
1129
dev->path, strerror (errno))
1130
!= PED_EXCEPTION_IGNORE)
1131
goto error_close_dev;
1132
if (!_device_probe_geometry (dev))
1133
goto error_close_dev;
1134
ped_device_close (dev);
1138
dev->host = idlun.host_unique_id;
1139
dev->did = idlun.dev_id;
1141
dev->model = (char*) ped_malloc (8 + 16 + 2);
1143
goto error_close_dev;
1145
if (scsi_get_product_info (dev, &vendor, &product)) {
1146
sprintf (dev->model, "%.8s %.16s", vendor, product);
1150
strcpy (dev->model, "Generic SCSI");
1153
if (!_device_probe_geometry (dev))
1154
goto error_close_dev;
1156
ped_device_close (dev);
1160
ped_device_close (dev);
1166
init_file (PedDevice* dev)
1168
struct stat dev_stat;
1170
if (!_device_stat (dev, &dev_stat))
1172
if (!ped_device_open (dev))
1175
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
1176
char *p = getenv ("PARTED_SECTOR_SIZE");
1179
if (0 < s && s % 512 == 0)
1180
dev->sector_size = s;
1182
dev->phys_sector_size = dev->sector_size;
1184
if (S_ISBLK(dev_stat.st_mode))
1185
dev->length = _device_get_length (dev);
1187
dev->length = dev_stat.st_size / dev->sector_size;
1188
if (dev->length <= 0) {
1189
ped_exception_throw (
1190
PED_EXCEPTION_ERROR,
1191
PED_EXCEPTION_CANCEL,
1192
_("The device %s is so small that it cannot possibly "
1193
"store a file system or partition table. Perhaps "
1194
"you selected the wrong device?"),
1196
goto error_close_dev;
1199
ped_device_close (dev);
1201
dev->bios_geom.cylinders = dev->length / 4 / 32;
1202
dev->bios_geom.heads = 4;
1203
dev->bios_geom.sectors = 32;
1204
dev->hw_geom = dev->bios_geom;
1205
dev->model = strdup ("");
1210
ped_device_close (dev);
1215
#if defined __s390__ || defined __s390x__
1217
init_dasd (PedDevice* dev, const char* model_name)
1219
struct stat dev_stat;
1220
struct hd_geometry geo;
1221
dasd_information_t dasd_info;
1223
if (!_device_stat (dev, &dev_stat))
1226
if (!ped_device_open (dev))
1229
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1231
PED_ASSERT (S_ISBLK (dev_stat.st_mode));
1233
_device_set_sector_size (dev);
1234
if (!dev->sector_size)
1235
goto error_close_dev;
1237
dev->length = _device_get_length (dev);
1239
goto error_close_dev;
1241
if (!ioctl (arch_specific->fd, HDIO_GETGEO, &geo)) {
1242
dev->hw_geom.sectors = geo.sectors;
1243
dev->hw_geom.heads = geo.heads;
1244
dev->hw_geom.cylinders = dev->length
1245
/ (dev->hw_geom.heads * dev->hw_geom.sectors)
1246
/ (dev->sector_size / PED_SECTOR_SIZE_DEFAULT);
1247
dev->bios_geom = dev->hw_geom;
1249
dev->bios_geom.sectors = 12;
1250
dev->bios_geom.heads = 15;
1251
dev->bios_geom.cylinders = dev->length
1252
/ (dev->hw_geom.heads * dev->hw_geom.sectors)
1253
/ (dev->sector_size / PED_SECTOR_SIZE_DEFAULT);
1254
dev->hw_geom = dev->bios_geom;
1257
if (!ioctl(arch_specific->fd, BIODASDINFO, &dasd_info)) {
1258
arch_specific->devno = dasd_info.devno;
1260
arch_specific->devno = arch_specific->major * 256 +
1261
arch_specific->minor;
1264
dev->model = strdup (model_name);
1266
ped_device_close (dev);
1270
ped_device_close (dev);
1277
init_generic (PedDevice* dev, const char* model_name)
1279
struct stat dev_stat;
1280
PedExceptionOption ex_status;
1282
if (!_device_stat (dev, &dev_stat))
1285
if (!ped_device_open (dev))
1288
ped_exception_fetch_all ();
1289
if (_device_probe_geometry (dev)) {
1290
ped_exception_leave_all ();
1292
if (!_device_get_length (dev)) {
1293
ped_exception_catch ();
1294
ped_exception_leave_all ();
1295
goto error_close_dev;
1298
/* hack to allow use of files, for testing */
1299
ped_exception_catch ();
1300
ped_exception_leave_all ();
1302
ex_status = ped_exception_throw (
1303
PED_EXCEPTION_WARNING,
1304
PED_EXCEPTION_IGNORE_CANCEL,
1305
_("Unable to determine geometry of "
1306
"file/device %s. You should not use Parted "
1307
"unless you REALLY know what you're doing!"),
1309
switch (ex_status) {
1310
case PED_EXCEPTION_CANCEL:
1311
goto error_close_dev;
1313
case PED_EXCEPTION_UNHANDLED:
1314
ped_exception_catch ();
1315
case PED_EXCEPTION_IGNORE:
1322
/* what should we stick in here? */
1323
dev->length = dev_stat.st_size / PED_SECTOR_SIZE_DEFAULT;
1324
dev->bios_geom.cylinders = dev->length / 4 / 32;
1325
dev->bios_geom.heads = 4;
1326
dev->bios_geom.sectors = 32;
1327
dev->sector_size = PED_SECTOR_SIZE_DEFAULT;
1328
dev->phys_sector_size = PED_SECTOR_SIZE_DEFAULT;
1331
dev->model = strdup (model_name);
1333
ped_device_close (dev);
1337
ped_device_close (dev);
1343
sdmmc_get_product_info (PedDevice* dev, char **type, char **name)
1345
*type = read_device_sysfs_file (dev, "type");
1346
*name = read_device_sysfs_file (dev, "name");
1354
init_sdmmc (PedDevice* dev)
1359
if (sdmmc_get_product_info (dev, &type, &name)) {
1360
snprintf (id, sizeof(id) - 1, "%s %s", type, name);
1364
snprintf (id, sizeof(id) - 1, "%s",
1365
_("Generic SD/MMC Storage Card"));
1367
return init_generic(dev, id);
1371
linux_new (const char* path)
1374
LinuxSpecific* arch_specific;
1376
PED_ASSERT (path != NULL);
1378
dev = (PedDevice*) ped_malloc (sizeof (PedDevice));
1382
dev->path = strdup (path);
1384
goto error_free_dev;
1387
= (LinuxSpecific*) ped_malloc (sizeof (LinuxSpecific));
1388
if (!dev->arch_specific)
1389
goto error_free_path;
1390
arch_specific = LINUX_SPECIFIC (dev);
1391
arch_specific->dmtype = NULL;
1393
arch_specific->probe = NULL;
1394
arch_specific->topology = NULL;
1397
dev->open_count = 0;
1399
dev->external_mode = 0;
1401
dev->boot_dirty = 0;
1403
#ifdef ENABLE_DEVICE_MAPPER
1404
dm_udev_set_sync_support(1);
1407
if (!_device_probe_type (dev))
1408
goto error_free_arch_specific;
1410
switch (dev->type) {
1411
case PED_DEVICE_IDE:
1412
if (!init_ide (dev))
1413
goto error_free_arch_specific;
1416
case PED_DEVICE_SCSI:
1417
if (!init_scsi (dev))
1418
goto error_free_arch_specific;
1421
case PED_DEVICE_DAC960:
1422
if (!init_generic (dev, _("DAC960 RAID controller")))
1423
goto error_free_arch_specific;
1426
case PED_DEVICE_SX8:
1427
if (!init_generic (dev, _("Promise SX8 SATA Device")))
1428
goto error_free_arch_specific;
1431
case PED_DEVICE_AOE:
1432
if (!init_generic (dev, _("ATA over Ethernet Device")))
1433
goto error_free_arch_specific;
1436
#if defined __s390__ || defined __s390x__
1437
case PED_DEVICE_DASD:
1438
if (!init_dasd (dev, _("IBM S390 DASD drive")))
1439
goto error_free_arch_specific;
1443
case PED_DEVICE_VIODASD:
1444
if (!init_generic (dev, _("IBM iSeries Virtual DASD")))
1445
goto error_free_arch_specific;
1448
case PED_DEVICE_CPQARRAY:
1449
if (!init_generic (dev, _("Compaq Smart Array")))
1450
goto error_free_arch_specific;
1453
case PED_DEVICE_ATARAID:
1454
if (!init_generic (dev, _("ATARAID Controller")))
1455
goto error_free_arch_specific;
1458
case PED_DEVICE_I2O:
1459
if (!init_generic (dev, _("I2O Controller")))
1460
goto error_free_arch_specific;
1463
case PED_DEVICE_UBD:
1464
if (!init_generic (dev, _("User-Mode Linux UBD")))
1465
goto error_free_arch_specific;
1468
case PED_DEVICE_FILE:
1469
if (!init_file (dev))
1470
goto error_free_arch_specific;
1473
case PED_DEVICE_LOOP:
1474
if (!init_generic (dev, _("Loopback device")))
1475
goto error_free_arch_specific;
1481
if (arch_specific->dmtype == NULL
1482
|| asprintf(&type, _("Linux device-mapper (%s)"),
1483
arch_specific->dmtype) == -1)
1484
goto error_free_arch_specific;
1485
bool ok = init_generic (dev, type);
1488
goto error_free_arch_specific;
1492
case PED_DEVICE_XVD:
1493
if (!init_generic (dev, _("Xen Virtual Block Device")))
1494
goto error_free_arch_specific;
1497
case PED_DEVICE_UNKNOWN:
1498
if (!init_generic (dev, _("Unknown")))
1499
goto error_free_arch_specific;
1502
case PED_DEVICE_SDMMC:
1503
if (!init_sdmmc (dev))
1504
goto error_free_arch_specific;
1506
case PED_DEVICE_VIRTBLK:
1507
if (!init_generic(dev, _("Virtio Block Device")))
1508
goto error_free_arch_specific;
1512
if (!init_generic(dev, _("Linux Software RAID Array")))
1513
goto error_free_arch_specific;
1517
ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
1518
PED_EXCEPTION_CANCEL,
1519
_("ped_device_new() Unsupported device type"));
1520
goto error_free_arch_specific;
1524
error_free_arch_specific:
1525
free (dev->arch_specific);
1535
linux_destroy (PedDevice* dev)
1537
LinuxSpecific *arch_specific = LINUX_SPECIFIC(dev);
1538
void *p = arch_specific->dmtype;
1541
if (arch_specific->probe)
1542
blkid_free_probe(arch_specific->probe);
1545
free (dev->arch_specific);
1552
linux_is_busy (PedDevice* dev)
1557
if (_partition_is_mounted_by_path (dev->path))
1560
for (i = 0; i < 32; i++) {
1563
part_name = _device_get_part_path (dev, i);
1566
status = _partition_is_mounted_by_path (part_name);
1576
/* we need to flush the master device, and all the partition devices,
1577
* because there is no coherency between the caches.
1578
* We should only flush unmounted partition devices, because:
1579
* - there is never a need to flush them (we're not doing IO there)
1580
* - flushing a device that is mounted causes unnecessary IO, and can
1581
* even screw journaling & friends up. Even cause oopsen!
1584
_flush_cache (PedDevice* dev)
1586
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1588
int lpn = _device_get_partition_range(dev);
1594
ioctl (arch_specific->fd, BLKFLSBUF);
1596
for (i = 1; i < lpn; i++) {
1600
name = _device_get_part_path (dev, i);
1603
if (!_partition_is_mounted_by_path (name)) {
1604
fd = open (name, WR_MODE, 0);
1606
ioctl (fd, BLKFLSBUF);
1608
if (fsync (fd) < 0 || close (fd) < 0)
1609
if (ped_exception_throw (
1610
PED_EXCEPTION_WARNING,
1611
PED_EXCEPTION_RETRY +
1612
PED_EXCEPTION_IGNORE,
1613
_("Error fsyncing/closing %s: %s"),
1614
name, strerror (errno))
1615
== PED_EXCEPTION_RETRY)
1624
linux_open (PedDevice* dev)
1626
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1629
arch_specific->fd = open (dev->path, RW_MODE);
1631
if (arch_specific->fd == -1) {
1632
char* rw_error_msg = strerror (errno);
1634
arch_specific->fd = open (dev->path, RD_MODE);
1636
if (arch_specific->fd == -1) {
1637
if (ped_exception_throw (
1638
PED_EXCEPTION_ERROR,
1639
PED_EXCEPTION_RETRY_CANCEL,
1640
_("Error opening %s: %s"),
1641
dev->path, strerror (errno))
1642
!= PED_EXCEPTION_RETRY) {
1648
ped_exception_throw (
1649
PED_EXCEPTION_WARNING,
1651
_("Unable to open %s read-write (%s). %s has "
1652
"been opened read-only."),
1653
dev->path, rw_error_msg, dev->path);
1666
linux_refresh_open (PedDevice* dev)
1672
linux_close (PedDevice* dev)
1674
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1679
if (fsync (arch_specific->fd) < 0 || close (arch_specific->fd) < 0)
1680
if (ped_exception_throw (
1681
PED_EXCEPTION_WARNING,
1682
PED_EXCEPTION_RETRY + PED_EXCEPTION_IGNORE,
1683
_("Error fsyncing/closing %s: %s"),
1684
dev->path, strerror (errno))
1685
== PED_EXCEPTION_RETRY)
1691
linux_refresh_close (PedDevice* dev)
1698
#if SIZEOF_OFF_T < 8
1700
static _syscall5(int,_llseek,
1702
unsigned long, offset_high,
1703
unsigned long, offset_low,
1705
unsigned int, origin)
1708
llseek (unsigned int fd, loff_t offset, unsigned int whence)
1713
retval = _llseek(fd,
1714
((unsigned long long)offset) >> 32,
1715
((unsigned long long)offset) & 0xffffffff,
1718
return (retval==-1 ? (loff_t) retval : result);
1721
#endif /* SIZEOF_OFF_T < 8 */
1724
_device_seek (const PedDevice* dev, PedSector sector)
1726
LinuxSpecific* arch_specific;
1728
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
1729
PED_ASSERT (dev != NULL);
1730
PED_ASSERT (!dev->external_mode);
1732
arch_specific = LINUX_SPECIFIC (dev);
1734
#if SIZEOF_OFF_T < 8
1735
if (sizeof (off_t) < 8) {
1736
loff_t pos = (loff_t)(sector * dev->sector_size);
1737
return llseek (arch_specific->fd, pos, SEEK_SET) == pos;
1741
off_t pos = sector * dev->sector_size;
1742
return lseek (arch_specific->fd, pos, SEEK_SET) == pos;
1747
_read_lastoddsector (const PedDevice* dev, void* buffer)
1749
LinuxSpecific* arch_specific;
1750
struct blkdev_ioctl_param ioctl_param;
1752
PED_ASSERT(dev != NULL);
1753
PED_ASSERT(buffer != NULL);
1755
arch_specific = LINUX_SPECIFIC (dev);
1758
ioctl_param.block = 0; /* read the last sector */
1759
ioctl_param.content_length = dev->sector_size;
1760
ioctl_param.block_contents = buffer;
1762
if (ioctl(arch_specific->fd, BLKGETLASTSECT, &ioctl_param) == -1) {
1763
PedExceptionOption opt;
1764
opt = ped_exception_throw (
1765
PED_EXCEPTION_ERROR,
1766
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1767
_("%s during read on %s"),
1768
strerror (errno), dev->path);
1770
if (opt == PED_EXCEPTION_CANCEL)
1772
if (opt == PED_EXCEPTION_RETRY)
1780
linux_read (const PedDevice* dev, void* buffer, PedSector start,
1783
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1784
PedExceptionOption ex_status;
1785
void* diobuf = NULL;
1787
PED_ASSERT (dev != NULL);
1788
PED_ASSERT (dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
1790
if (_get_linux_version() < KERNEL_VERSION (2,6,0)) {
1791
/* Kludge. This is necessary to read/write the last
1792
block of an odd-sized disk, until Linux 2.5.x kernel fixes.
1794
if (dev->type != PED_DEVICE_FILE && (dev->length & 1)
1795
&& start + count - 1 == dev->length - 1)
1796
return ped_device_read (dev, buffer, start, count - 1)
1797
&& _read_lastoddsector (
1798
dev, (char *) buffer + (count-1) * 512);
1801
if (_device_seek (dev, start))
1804
ex_status = ped_exception_throw (
1805
PED_EXCEPTION_ERROR,
1806
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1807
_("%s during seek for read on %s"),
1808
strerror (errno), dev->path);
1810
switch (ex_status) {
1811
case PED_EXCEPTION_IGNORE:
1814
case PED_EXCEPTION_RETRY:
1817
case PED_EXCEPTION_UNHANDLED:
1818
ped_exception_catch ();
1819
case PED_EXCEPTION_CANCEL:
1827
size_t read_length = count * dev->sector_size;
1828
if (posix_memalign (&diobuf, dev->sector_size, read_length) != 0)
1832
ssize_t status = read (arch_specific->fd, diobuf, read_length);
1834
memcpy(buffer, diobuf, status);
1835
if (status == (ssize_t) read_length)
1838
read_length -= status;
1839
buffer = (char *) buffer + status;
1843
ex_status = ped_exception_throw (
1844
PED_EXCEPTION_ERROR,
1845
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1847
? _("%0.0send of file while reading %s")
1848
: _("%s during read on %s")),
1852
switch (ex_status) {
1853
case PED_EXCEPTION_IGNORE:
1857
case PED_EXCEPTION_RETRY:
1860
case PED_EXCEPTION_UNHANDLED:
1861
ped_exception_catch ();
1862
case PED_EXCEPTION_CANCEL:
1877
_write_lastoddsector (PedDevice* dev, const void* buffer)
1879
LinuxSpecific* arch_specific;
1880
struct blkdev_ioctl_param ioctl_param;
1882
PED_ASSERT(dev != NULL);
1883
PED_ASSERT(buffer != NULL);
1885
arch_specific = LINUX_SPECIFIC (dev);
1888
ioctl_param.block = 0; /* write the last sector */
1889
ioctl_param.content_length = dev->sector_size;
1890
ioctl_param.block_contents = (void*) buffer;
1892
if (ioctl(arch_specific->fd, BLKSETLASTSECT, &ioctl_param) == -1) {
1893
PedExceptionOption opt;
1894
opt = ped_exception_throw (
1895
PED_EXCEPTION_ERROR,
1896
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1897
_("%s during write on %s"),
1898
strerror (errno), dev->path);
1900
if (opt == PED_EXCEPTION_CANCEL)
1902
if (opt == PED_EXCEPTION_RETRY)
1910
linux_write (PedDevice* dev, const void* buffer, PedSector start,
1913
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
1914
PedExceptionOption ex_status;
1918
PED_ASSERT(dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
1920
if (dev->read_only) {
1921
if (ped_exception_throw (
1922
PED_EXCEPTION_ERROR,
1923
PED_EXCEPTION_IGNORE_CANCEL,
1924
_("Can't write to %s, because it is opened read-only."),
1926
!= PED_EXCEPTION_IGNORE)
1932
if (_get_linux_version() < KERNEL_VERSION (2,6,0)) {
1933
/* Kludge. This is necessary to read/write the last
1934
block of an odd-sized disk, until Linux 2.5.x kernel fixes.
1936
if (dev->type != PED_DEVICE_FILE && (dev->length & 1)
1937
&& start + count - 1 == dev->length - 1)
1938
return ped_device_write (dev, buffer, start, count - 1)
1939
&& _write_lastoddsector (
1940
dev, ((char*) buffer
1941
+ (count-1) * dev->sector_size));
1944
if (_device_seek (dev, start))
1947
ex_status = ped_exception_throw (
1948
PED_EXCEPTION_ERROR, PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1949
_("%s during seek for write on %s"),
1950
strerror (errno), dev->path);
1952
switch (ex_status) {
1953
case PED_EXCEPTION_IGNORE:
1956
case PED_EXCEPTION_RETRY:
1959
case PED_EXCEPTION_UNHANDLED:
1960
ped_exception_catch ();
1961
case PED_EXCEPTION_CANCEL:
1970
printf ("ped_device_write (\"%s\", %p, %d, %d)\n",
1971
dev->path, buffer, (int) start, (int) count);
1973
size_t write_length = count * dev->sector_size;
1975
if (posix_memalign(&diobuf, dev->sector_size, write_length) != 0)
1977
memcpy(diobuf, buffer, write_length);
1978
diobuf_start = diobuf;
1980
ssize_t status = write (arch_specific->fd, diobuf, write_length);
1981
if (status == write_length) break;
1983
write_length -= status;
1984
diobuf = (char *) diobuf + status;
1988
ex_status = ped_exception_throw (
1989
PED_EXCEPTION_ERROR,
1990
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
1991
_("%s during write on %s"),
1992
strerror (errno), dev->path);
1994
switch (ex_status) {
1995
case PED_EXCEPTION_IGNORE:
1999
case PED_EXCEPTION_RETRY:
2002
case PED_EXCEPTION_UNHANDLED:
2003
ped_exception_catch ();
2004
case PED_EXCEPTION_CANCEL:
2013
#endif /* !READ_ONLY */
2017
/* returns the number of sectors that are ok.
2020
linux_check (PedDevice* dev, void* buffer, PedSector start, PedSector count)
2022
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
2027
PED_ASSERT(dev != NULL);
2029
if (!_device_seek (dev, start))
2032
if (posix_memalign(&diobuf, PED_SECTOR_SIZE_DEFAULT,
2033
count * PED_SECTOR_SIZE_DEFAULT) != 0)
2036
for (done = 0; done < count; done += status / dev->sector_size) {
2037
status = read (arch_specific->fd, diobuf,
2038
(size_t) ((count-done) * dev->sector_size));
2040
memcpy(buffer, diobuf, status);
2050
_do_fsync (PedDevice* dev)
2052
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
2054
PedExceptionOption ex_status;
2057
status = fsync (arch_specific->fd);
2058
if (status >= 0) break;
2060
ex_status = ped_exception_throw (
2061
PED_EXCEPTION_ERROR,
2062
PED_EXCEPTION_RETRY_IGNORE_CANCEL,
2063
_("%s during write on %s"),
2064
strerror (errno), dev->path);
2066
switch (ex_status) {
2067
case PED_EXCEPTION_IGNORE:
2070
case PED_EXCEPTION_RETRY:
2073
case PED_EXCEPTION_UNHANDLED:
2074
ped_exception_catch ();
2075
case PED_EXCEPTION_CANCEL:
2086
linux_sync (PedDevice* dev)
2088
PED_ASSERT (dev != NULL);
2089
PED_ASSERT (!dev->external_mode);
2093
if (!_do_fsync (dev))
2100
linux_sync_fast (PedDevice* dev)
2102
PED_ASSERT (dev != NULL);
2103
PED_ASSERT (!dev->external_mode);
2107
if (!_do_fsync (dev))
2109
/* no cache flush... */
2114
_compare_digit_state (char ch, int need_digit)
2116
return !!isdigit (ch) == need_digit;
2119
/* matches the regexp "[^0-9]+[0-9]+[^0-9]+[0-9]+$".
2120
* Motivation: accept devices looking like /dev/rd/c0d0, but
2121
* not looking like /dev/hda1 and /dev/rd/c0d0p1
2123
static int _GL_ATTRIBUTE_PURE
2124
_match_rd_device (const char* name)
2129
/* exclude directory names from test */
2130
pos = strrchr(name, '/') ?: name;
2138
for (state = 0; state < 4; state++) {
2139
int want_digits = (state % 2 == 1);
2143
if (!_compare_digit_state (*pos, want_digits))
2146
} while (_compare_digit_state (*pos, want_digits));
2153
_probe_proc_partitions ()
2155
FILE* proc_part_file;
2156
int major, minor, size;
2158
char part_name [256];
2159
char dev_name [256];
2162
proc_part_file = fopen ("/proc/partitions", "r");
2163
if (!proc_part_file)
2166
if (fgets (buf, 256, proc_part_file) == NULL)
2169
if (fgets (buf, 256, proc_part_file) == NULL)
2172
while (fgets (buf, 512, proc_part_file)
2173
&& sscanf (buf, "%d %d %d %255s", &major, &minor, &size,
2175
/* Heuristic for telling partitions and devices apart
2176
* Probably needs to be improved
2178
if (!_match_rd_device (part_name)
2179
&& isdigit (part_name [strlen (part_name) - 1]))
2182
strcpy (dev_name, "/dev/");
2183
strcat (dev_name, part_name);
2184
_ped_device_probe (dev_name);
2189
fclose (proc_part_file);
2198
static int _GL_ATTRIBUTE_PURE
2199
_skip_entry (const char *name)
2202
static struct _entry entries[] = {
2203
{ ".", sizeof (".") - 1 },
2204
{ "..", sizeof ("..") - 1 },
2205
{ "dm-", sizeof ("dm-") - 1 },
2206
{ "loop", sizeof ("loop") - 1 },
2207
{ "ram", sizeof ("ram") - 1 },
2208
{ "fd", sizeof ("fd") - 1 },
2212
for (i = entries; i->name != 0; i++) {
2213
if (strncmp (name, i->name, i->len) == 0)
2224
struct dirent *dirent;
2225
char dev_name [256];
2228
if (!(blockdir = opendir ("/sys/block")))
2230
while ((dirent = readdir (blockdir))) {
2231
if (_skip_entry (dirent->d_name))
2234
if (strlen (dirent->d_name) > sizeof (dev_name) - 6)
2235
continue; /* device name too long! */
2237
strcpy (dev_name, "/dev/");
2238
strcat (dev_name, dirent->d_name);
2239
/* in /sys/block, '/'s are replaced with '!' or '.' */
2240
for (ptr = dev_name; *ptr != '\0'; ptr++) {
2241
if (*ptr == '!' || *ptr == '.')
2244
_ped_device_probe (dev_name);
2247
closedir (blockdir);
2252
_probe_standard_devices ()
2254
_ped_device_probe ("/dev/hda");
2255
_ped_device_probe ("/dev/hdb");
2256
_ped_device_probe ("/dev/hdc");
2257
_ped_device_probe ("/dev/hdd");
2258
_ped_device_probe ("/dev/hde");
2259
_ped_device_probe ("/dev/hdf");
2260
_ped_device_probe ("/dev/hdg");
2261
_ped_device_probe ("/dev/hdh");
2263
_ped_device_probe ("/dev/sda");
2264
_ped_device_probe ("/dev/sdb");
2265
_ped_device_probe ("/dev/sdc");
2266
_ped_device_probe ("/dev/sdd");
2267
_ped_device_probe ("/dev/sde");
2268
_ped_device_probe ("/dev/sdf");
2276
/* we should probe the standard devs too, even with /proc/partitions,
2277
* because /proc/partitions might return devfs stuff, and we might not
2278
* have devfs available
2280
_probe_standard_devices ();
2282
#ifdef ENABLE_DEVICE_MAPPER
2283
/* device-mapper devices aren't listed in /proc/partitions; or, if
2284
* they are, they're listed as dm-X. So, instead of relying on that,
2285
* we do our own checks.
2287
_probe_dm_devices ();
2290
/* /sys/block is more reliable and consistent; fall back to using
2291
* /proc/partitions if the former is unavailable, however.
2293
if (!_probe_sys_block ())
2294
_probe_proc_partitions ();
2297
static char * _GL_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
2298
zasprintf (const char *format, ...)
2302
va_start (args, format);
2303
int r = vasprintf (&resultp, format, args);
2305
return r < 0 ? NULL : resultp;
2309
dm_canonical_path (PedDevice const *dev)
2311
LinuxSpecific const *arch_specific = LINUX_SPECIFIC (dev);
2313
/* Get map name from devicemapper */
2314
struct dm_task *task = dm_task_create (DM_DEVICE_INFO);
2317
if (!dm_task_set_major_minor (task, arch_specific->major,
2318
arch_specific->minor, 0))
2320
if (!dm_task_run(task))
2322
char *dev_name = zasprintf ("/dev/mapper/%s", dm_task_get_name (task));
2323
if (dev_name == NULL)
2325
dm_task_destroy (task);
2332
_device_get_part_path (PedDevice const *dev, int num)
2334
char *devpath = (dev->type == PED_DEVICE_DM
2335
? dm_canonical_path (dev) : dev->path);
2336
size_t path_len = strlen (devpath);
2338
/* Check for devfs-style /disc => /partN transformation
2339
unconditionally; the system might be using udev with devfs rules,
2340
and if not the test is harmless. */
2341
if (5 < path_len && !strcmp (devpath + path_len - 5, "/disc")) {
2342
/* replace /disc with /part%d */
2343
result = zasprintf ("%.*s/part%d",
2344
(int) (path_len - 5), devpath, num);
2346
char const *p = (dev->type == PED_DEVICE_DAC960
2347
|| dev->type == PED_DEVICE_CPQARRAY
2348
|| dev->type == PED_DEVICE_ATARAID
2349
|| isdigit (devpath[path_len - 1])
2351
result = zasprintf ("%s%s%d", devpath, p, num);
2353
if (dev->type == PED_DEVICE_DM)
2359
linux_partition_get_path (const PedPartition* part)
2361
/* loop label means use the whole disk */
2362
if (strcmp (part->disk->type->name, "loop") == 0)
2363
return xstrdup (part->disk->dev->path);
2364
return _device_get_part_path (part->disk->dev, part->num);
2368
_mount_table_search (const char* file_name, dev_t dev)
2370
struct stat part_stat;
2372
char part_name[512];
2375
file = fopen (file_name, "r");
2378
while (fgets (line, 512, file)) {
2379
if (sscanf (line, "%s", part_name) == 1
2380
&& stat (part_name, &part_stat) == 0) {
2381
if (part_stat.st_rdev == dev) {
2392
_partition_is_mounted_by_dev (dev_t dev)
2394
return _mount_table_search( "/proc/mounts", dev)
2395
|| _mount_table_search( "/proc/swaps", dev)
2396
|| _mount_table_search( "/etc/mtab", dev);
2400
_partition_is_mounted_by_path (const char *path)
2402
struct stat part_stat;
2403
if (stat (path, &part_stat) != 0)
2405
if (!S_ISBLK(part_stat.st_mode))
2407
return _partition_is_mounted_by_dev (part_stat.st_rdev);
2410
/* If partition PART is mounted, or if we encounter an out-of-memory error
2411
while trying to determine its status, return 1. Otherwise, return 0. */
2413
_partition_is_mounted (const PedPartition *part)
2415
if (!ped_partition_is_active (part))
2417
char *part_name = _device_get_part_path (part->disk->dev, part->num);
2420
int status = _partition_is_mounted_by_path (part_name);
2426
linux_partition_is_busy (const PedPartition* part)
2430
PED_ASSERT (part != NULL);
2432
if (strcmp (part->disk->type->name, "loop") == 0)
2433
return linux_is_busy (part->disk->dev);
2434
if (_partition_is_mounted (part))
2436
if (part->type == PED_PARTITION_EXTENDED) {
2437
for (walk = part->part_list; walk; walk = walk->next) {
2438
if (linux_partition_is_busy (walk))
2446
_blkpg_part_command (PedDevice* dev, struct blkpg_partition* part, int op)
2448
LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev);
2449
struct blkpg_ioctl_arg ioctl_arg;
2452
ioctl_arg.flags = 0;
2453
ioctl_arg.datalen = sizeof (struct blkpg_partition);
2454
ioctl_arg.data = (void*) part;
2456
return ioctl (arch_specific->fd, BLKPG, &ioctl_arg) == 0;
2460
_blkpg_add_partition (PedDisk* disk, const PedPartition *part)
2462
struct blkpg_partition linux_part;
2463
const char* vol_name;
2466
PED_ASSERT(disk != NULL);
2467
PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
2469
if (ped_disk_type_check_feature (disk->type,
2470
PED_DISK_TYPE_PARTITION_NAME))
2471
vol_name = ped_partition_get_name (part);
2475
dev_name = _device_get_part_path (disk->dev, part->num);
2479
memset (&linux_part, 0, sizeof (linux_part));
2480
linux_part.start = part->geom.start * disk->dev->sector_size;
2481
/* see fs/partitions/msdos.c:msdos_partition(): "leave room for LILO" */
2482
if (part->type & PED_PARTITION_EXTENDED) {
2483
linux_part.length = 1;
2484
if (disk->dev->sector_size == 512) {
2485
if (linux_part.length == 1)
2486
linux_part.length = 2;
2488
/* if the second sector is claimed by a logical partition,
2489
then there's just no room for lilo, so don't try to use it */
2490
for (walk = part->part_list; walk; walk = walk->next) {
2491
if (walk->geom.start == part->geom.start+1)
2492
linux_part.length = 1;
2495
linux_part.length *= disk->dev->sector_size;
2498
linux_part.length = part->geom.length * disk->dev->sector_size;
2500
linux_part.pno = part->num;
2501
strncpy (linux_part.devname, dev_name, BLKPG_DEVNAMELTH);
2503
strncpy (linux_part.volname, vol_name, BLKPG_VOLNAMELTH);
2507
if (!_blkpg_part_command (disk->dev, &linux_part,
2508
BLKPG_ADD_PARTITION)) {
2516
_blkpg_remove_partition (PedDisk* disk, int n)
2518
struct blkpg_partition linux_part;
2520
memset (&linux_part, 0, sizeof (linux_part));
2522
return _blkpg_part_command (disk->dev, &linux_part,
2523
BLKPG_DEL_PARTITION);
2526
#ifdef BLKPG_RESIZE_PARTITION
2527
static int _blkpg_resize_partition (PedDisk* disk, const PedPartition *part)
2529
struct blkpg_partition linux_part;
2532
PED_ASSERT(disk != NULL);
2533
PED_ASSERT(disk->dev->sector_size % PED_SECTOR_SIZE_DEFAULT == 0);
2535
dev_name = _device_get_part_path (disk->dev, part->num);
2538
memset (&linux_part, 0, sizeof (linux_part));
2539
linux_part.start = part->geom.start * disk->dev->sector_size;
2540
/* see fs/partitions/msdos.c:msdos_partition(): "leave room for LILO" */
2541
if (part->type & PED_PARTITION_EXTENDED) {
2542
if (disk->dev->sector_size == 512) {
2543
linux_part.length = 2;
2545
/* if the second sector is claimed by a logical partition,
2546
then there's just no room for lilo, so don't try to use it */
2547
for (walk = part->part_list; walk; walk = walk->next) {
2548
if (walk->geom.start == part->geom.start+1)
2549
linux_part.length = 1;
2551
} else linux_part.length = 1;
2554
linux_part.length = part->geom.length * disk->dev->sector_size;
2555
linux_part.pno = part->num;
2556
strncpy (linux_part.devname, dev_name, BLKPG_DEVNAMELTH);
2560
if (!_blkpg_part_command (disk->dev, &linux_part,
2561
BLKPG_RESIZE_PARTITION)) {
2562
return ped_exception_throw (
2563
PED_EXCEPTION_ERROR,
2564
PED_EXCEPTION_IGNORE_CANCEL,
2565
_("Error informing the kernel about modifications to "
2566
"partition %s -- %s. This means Linux won't know "
2567
"about any changes you made to %s until you reboot "
2568
"-- so you shouldn't mount it or use it in any way "
2569
"before rebooting."),
2573
== PED_EXCEPTION_IGNORE;
2580
/* Read the integer from /sys/block/DEV_BASE/ENTRY and set *VAL
2581
to that value, where DEV_BASE is the last component of DEV->path.
2582
Upon success, return true. Otherwise, return false. */
2584
_sysfs_int_entry_from_dev(PedDevice const* dev, const char *entry, int *val)
2587
int r = snprintf(path, sizeof(path), "/sys/block/%s/%s",
2588
last_component(dev->path), entry);
2589
if (r < 0 || r >= sizeof(path))
2592
FILE *fp = fopen(path, "r");
2596
bool ok = fscanf(fp, "%d", val) == 1;
2602
/* Read the unsigned long long from /sys/block/DEV_BASE/PART_BASE/ENTRY
2603
and set *VAL to that value, where DEV_BASE is the last component of path to
2604
block device corresponding to PART and PART_BASE is the sysfs name of PART.
2605
Upon success, return true. Otherwise, return false. */
2607
_sysfs_ull_entry_from_part(PedPartition const* part, const char *entry,
2608
unsigned long long *val)
2611
char *part_name = _device_get_part_path (part->disk->dev, part->num);
2615
int r = snprintf(path, sizeof(path), "/sys/block/%s/%s/%s",
2616
last_component(part->disk->dev->path),
2617
last_component(part_name), entry);
2619
if (r < 0 || r >= sizeof(path))
2622
FILE *fp = fopen(path, "r");
2626
bool ok = fscanf(fp, "%llu", val) == 1;
2633
/* Get the starting sector and length of a partition PART within a block device
2634
Use blkpg if available, then check sysfs and then use HDIO_GETGEO and
2635
BLKGETSIZE64 ioctls as fallback. Upon success, return true. Otherwise,
2638
_kernel_get_partition_start_and_length(PedPartition const *part,
2639
unsigned long long *start,
2640
unsigned long long *length)
2646
char *dev_name = _device_get_part_path (part->disk->dev, part->num);
2650
int ok = _sysfs_ull_entry_from_part (part, "start", start);
2652
struct hd_geometry geom;
2653
int dev_fd = open (dev_name, O_RDONLY);
2654
if (dev_fd != -1 && ioctl (dev_fd, HDIO_GETGEO, &geom)) {
2655
*start = geom.start;
2664
*start = (*start * 512) / part->disk->dev->sector_size;
2665
ok = _sysfs_ull_entry_from_part (part, "size", length);
2669
fd = open (dev_name, O_RDONLY);
2670
if (fd != -1 && ioctl (fd, BLKGETSIZE64, length))
2676
*length /= part->disk->dev->sector_size;
2681
ped_exception_throw (
2683
PED_EXCEPTION_CANCEL,
2684
_("Unable to determine the start and length of %s."),
2692
* The number of partitions that a device can have depends on the kernel.
2693
* If we don't find this value in /sys/block/DEV/ext_range, we will use our own
2697
_device_get_partition_range(PedDevice const* dev)
2700
if (dev->type == PED_DEVICE_DM)
2701
return MAX_NUM_PARTS;
2702
bool ok = _sysfs_int_entry_from_dev(dev, "ext_range", &range);
2705
return MAX_NUM_PARTS;
2706
/* both 0 and 1 mean no partitions */
2707
return range > 1 ? range : 0;
2710
#ifdef ENABLE_DEVICE_MAPPER
2712
_dm_remove_partition(PedDisk* disk, int partno)
2715
uint32_t cookie = 0;
2716
char *part_name = _device_get_part_path (disk->dev, partno);
2718
int fd = open (part_name, O_RDONLY | O_EXCL);
2720
if (errno == ENOENT)
2721
errno = ENXIO; /* nothing to remove, device already doesn't exist */
2725
struct dm_task *task = dm_task_create(DM_DEVICE_REMOVE);
2728
dm_task_set_name (task, part_name);
2729
if (!dm_task_set_cookie (task, &cookie, 0))
2731
rc = _dm_task_run_wait (task, cookie);
2732
dm_task_update_nodes();
2733
dm_task_destroy(task);
2740
_dm_get_partition_start_and_length(PedPartition const *part,
2741
unsigned long long *start,
2742
unsigned long long *length)
2744
struct dm_task* task = NULL;
2747
if (!(task = dm_task_create(DM_DEVICE_TABLE)))
2749
char *path = _device_get_part_path (part->disk->dev, part->num);
2751
/* libdevmapper likes to complain on stderr instead of quietly
2752
returning ENOENT or ENXIO, so try to stat first */
2754
if (stat(path, &st))
2756
dm_task_set_name(task, path);
2757
if (!dm_task_run(task))
2763
dm_get_next_target(task, NULL, (uint64_t *)start, (uint64_t *)length, &target_type, ¶ms);
2764
if (sscanf (params, "%d:%d %Ld", &major, &minor, start) != 3)
2769
dm_task_destroy(task);
2775
_dm_add_partition (PedDisk* disk, const PedPartition* part)
2777
LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev);
2778
char* params = NULL;
2779
char* vol_name = NULL;
2780
const char* dev_name = NULL;
2781
char* vol_uuid = NULL;
2782
const char* dev_uuid = NULL;
2783
uint32_t cookie = 0;
2785
/* Get map name from devicemapper */
2786
struct dm_task *task = dm_task_create (DM_DEVICE_INFO);
2790
if (!dm_task_set_major_minor (task, arch_specific->major,
2791
arch_specific->minor, 0))
2794
if (!dm_task_run(task))
2797
dev_name = dm_task_get_name (task);
2798
size_t name_len = strlen (dev_name);
2799
vol_name = zasprintf ("%s%s%d",
2801
isdigit (dev_name[name_len - 1]) ? "p" : "",
2803
if (vol_name == NULL)
2806
dev_uuid = dm_task_get_uuid (task);
2807
if (dev_uuid && (strlen(dev_uuid) > 0)
2808
&& !(vol_uuid = zasprintf ("part%d-%s", part->num, dev_uuid)))
2811
/* Caution: dm_task_destroy frees dev_name. */
2812
dm_task_destroy (task);
2814
if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major,
2815
arch_specific->minor, part->geom.start)))
2818
task = dm_task_create (DM_DEVICE_CREATE);
2822
dm_task_set_name (task, vol_name);
2824
dm_task_set_uuid (task, vol_uuid);
2825
dm_task_add_target (task, 0, part->geom.length,
2827
if (!dm_task_set_cookie (task, &cookie, 0))
2829
if (_dm_task_run_wait (task, cookie)) {
2830
dm_task_update_nodes ();
2831
dm_task_destroy (task);
2837
_dm_remove_partition (disk, part->num);
2840
dm_task_update_nodes();
2842
dm_task_destroy (task);
2850
_dm_resize_partition (PedDisk* disk, const PedPartition* part)
2852
LinuxSpecific* arch_specific = LINUX_SPECIFIC (disk->dev);
2853
char* params = NULL;
2854
char* vol_name = NULL;
2855
const char* dev_name = NULL;
2856
uint32_t cookie = 0;
2858
/* Get map name from devicemapper */
2859
struct dm_task *task = dm_task_create (DM_DEVICE_INFO);
2863
if (!dm_task_set_major_minor (task, arch_specific->major,
2864
arch_specific->minor, 0))
2867
if (!dm_task_run(task))
2870
dev_name = dm_task_get_name (task);
2871
size_t name_len = strlen (dev_name);
2872
vol_name = zasprintf ("%s%s%d",
2874
isdigit (dev_name[name_len - 1]) ? "p" : "",
2876
if (vol_name == NULL)
2879
/* Caution: dm_task_destroy frees dev_name. */
2880
dm_task_destroy (task);
2882
if ( ! (params = zasprintf ("%d:%d %lld", arch_specific->major,
2883
arch_specific->minor, part->geom.start)))
2886
task = dm_task_create (DM_DEVICE_RELOAD);
2890
dm_task_set_name (task, vol_name);
2891
dm_task_add_target (task, 0, part->geom.length,
2893
if (!dm_task_set_cookie (task, &cookie, 0))
2895
if (dm_task_run (task)) {
2896
dm_task_destroy (task);
2897
task = dm_task_create (DM_DEVICE_RESUME);
2900
dm_task_set_name (task, vol_name);
2901
if (!dm_task_set_cookie (task, &cookie, 0))
2903
if (dm_task_run (task)) {
2910
dm_task_update_nodes();
2912
dm_task_destroy (task);
2921
* Sync the partition table in two step process:
2922
* 1. Remove all of the partitions from the kernel's tables, but do not attempt
2923
* removal of any partition for which the corresponding ioctl call fails.
2924
* 2. Add all the partitions that we hold in disk, throwing a warning
2925
* if we cannot because step 1 failed to remove it and it is not being
2926
* added back with the same start and length.
2928
* To achieve this two step process we must calculate the minimum number of
2929
* maximum possible partitions between what linux supports and what the label
2930
* type supports. EX:
2932
* number=MIN(max_parts_supported_in_linux,max_parts_supported_in_msdos_tables)
2935
_disk_sync_part_table (PedDisk* disk)
2937
PED_ASSERT(disk != NULL);
2938
PED_ASSERT(disk->dev != NULL);
2940
unsigned int part_range = _device_get_partition_range(disk->dev);
2941
int (*add_partition)(PedDisk* disk, const PedPartition *part);
2942
int (*resize_partition)(PedDisk* disk, const PedPartition *part);
2943
int (*remove_partition)(PedDisk* disk, int partno);
2944
bool (*get_partition_start_and_length)(PedPartition const *part,
2945
unsigned long long *start,
2946
unsigned long long *length);
2949
if (disk->dev->type == PED_DEVICE_DM) {
2950
add_partition = _dm_add_partition;
2951
remove_partition = _dm_remove_partition;
2952
resize_partition = _dm_resize_partition;
2953
get_partition_start_and_length = _dm_get_partition_start_and_length;
2955
add_partition = _blkpg_add_partition;
2956
remove_partition = _blkpg_remove_partition;
2957
#ifdef BLKPG_RESIZE_PARTITION
2958
resize_partition = _blkpg_resize_partition;
2960
resize_partition = NULL;
2962
get_partition_start_and_length = _kernel_get_partition_start_and_length;
2965
/* lpn = largest partition number.
2966
* for remove pass, use greater of device or label limit */
2967
if (ped_disk_get_max_supported_partition_count(disk, &lpn))
2968
lpn = PED_MAX(lpn, part_range);
2971
/* for add pass, use lesser of device or label limit */
2972
if (ped_disk_get_max_supported_partition_count(disk, &lpn2))
2973
lpn2 = PED_MIN(lpn2, part_range);
2976
/* Its not possible to support largest_partnum < 0.
2977
* largest_partnum == 0 would mean does not support partitions.
2982
int *ok = calloc (lpn, sizeof *ok);
2985
int *errnums = ped_malloc(sizeof(int) * lpn);
2990
/* remove old partitions first */
2991
for (i = 1; i <= lpn; i++) {
2992
PedPartition *part = ped_disk_get_partition (disk, i);
2994
unsigned long long length;
2995
unsigned long long start;
2996
/* get start and length of existing partition */
2997
if (get_partition_start_and_length(part,
2999
&& start == part->geom.start
3000
&& (length == part->geom.length
3001
|| (resize_partition && part->num < lpn2)))
3003
/* partition is unchanged, or will be resized so nothing to do */
3008
/* Attempt to remove the partition, retrying for
3009
up to max_sleep_seconds upon any failure due to EBUSY. */
3010
unsigned int sleep_microseconds = 10000;
3011
unsigned int max_sleep_seconds = 1;
3012
unsigned int n_sleep = (max_sleep_seconds
3013
* 1000000 / sleep_microseconds);
3015
ok[i - 1] = remove_partition (disk, i);
3016
errnums[i - 1] = errno;
3017
if (ok[i - 1] || errnums[i - 1] != EBUSY)
3019
usleep (sleep_microseconds);
3020
} while (n_sleep--);
3021
if (!ok[i - 1] && errnums[i - 1] == ENXIO)
3022
ok[i - 1] = 1; /* it already doesn't exist */
3025
/* don't actually add partitions for loop */
3026
if (strcmp (disk->type->name, "loop") == 0)
3028
for (i = 1; i <= lpn; i++) {
3029
PedPartition *part = ped_disk_get_partition (disk, i);
3032
unsigned long long length;
3033
unsigned long long start;
3034
/* get start and length of existing partition */
3035
if (get_partition_start_and_length(part,
3037
&& start == part->geom.start)
3039
if (length == part->geom.length) {
3041
/* partition is unchanged, so nothing to do */
3044
if (resize_partition
3045
&& start == part->geom.start)
3048
if (resize_partition (disk, part)) {
3054
/* add the (possibly modified or new) partition */
3055
if (!add_partition (disk, part)) {
3057
errnums[i - 1] = errno;
3061
char *bad_part_list = NULL;
3062
/* now warn about any errors */
3063
for (i = 1; i <= lpn; i++) {
3064
if (ok[i - 1] || errnums[i - 1] == ENXIO)
3066
if (bad_part_list == NULL) {
3067
bad_part_list = malloc (lpn * 5);
3070
bad_part_list[0] = 0;
3072
sprintf (bad_part_list + strlen (bad_part_list), "%d, ", i);
3074
if (bad_part_list == NULL)
3077
bad_part_list[strlen (bad_part_list) - 2] = 0;
3078
if (ped_exception_throw (
3079
PED_EXCEPTION_ERROR,
3080
PED_EXCEPTION_IGNORE_CANCEL,
3081
_("Partition(s) %s on %s have been written, but we have "
3082
"been unable to inform the kernel of the change, "
3083
"probably because it/they are in use. As a result, "
3084
"the old partition(s) will remain in use. You "
3085
"should reboot now before making further changes."),
3086
bad_part_list, disk->dev->path) == PED_EXCEPTION_IGNORE)
3088
free (bad_part_list);
3099
static int have_blkpg = -1;
3102
if (have_blkpg != -1)
3105
kver = _get_linux_version();
3106
return have_blkpg = kver >= KERNEL_VERSION (2,4,0) ? 1 : 0;
3112
static int cached = -1;
3113
struct stat root, init_root;
3118
if (stat ("/", &root) || stat ("/proc/1/root", &init_root))
3119
/* We can't tell, but are unlikely to be able to tell in the
3123
else if (root.st_dev == init_root.st_dev &&
3124
root.st_ino == init_root.st_ino)
3125
/* / has the same dev/ino as /sbin/init's root, so we're not
3130
/* We must be in a chroot. */
3136
/* Return nonzero upon success, 0 if something fails. */
3138
linux_disk_commit (PedDisk* disk)
3142
/* Modern versions of udev may notice the write activity on
3143
* partition devices caused by _flush_cache, and may decide to
3144
* synthesise some change events as a result. These may in turn run
3145
* programs that open partition devices, which will race with us
3146
* trying to remove those devices. To avoid this, we need to wait
3147
* until udevd has finished processing its event queue.
3148
* TODO: for upstream submission, this should check whether udevadm
3151
if (!_chrooted () && system ("udevadm settle") != 0) {
3152
/* ignore failures */
3155
if (disk->dev->type != PED_DEVICE_FILE) {
3157
/* We now require BLKPG support. If this assertion fails,
3158
please write to the mailing list describing your system.
3159
Assuming it's never triggered, ...
3160
FIXME: remove this assertion in 2012. */
3161
assert (_have_blkpg ());
3163
if (!_disk_sync_part_table (disk))
3167
/* Now we wait for udevd to finish creating device nodes based on
3168
* the above activity, so that callers can reliably use them.
3169
* TODO: for upstream submission, this should check whether udevadm
3172
if (!_chrooted () && system ("udevadm settle") != 0) {
3173
/* ignore failures */
3180
static PedAlignment*
3181
linux_get_minimum_alignment(const PedDevice *dev)
3183
blkid_topology tp = LINUX_SPECIFIC(dev)->topology;
3187
if (blkid_topology_get_minimum_io_size(tp) == 0)
3188
return ped_alignment_new(
3189
blkid_topology_get_alignment_offset(tp) /
3191
dev->phys_sector_size / dev->sector_size);
3193
return ped_alignment_new(
3194
blkid_topology_get_alignment_offset(tp) / dev->sector_size,
3195
blkid_topology_get_minimum_io_size(tp) / dev->sector_size);
3198
static PedAlignment*
3199
linux_get_optimum_alignment(const PedDevice *dev)
3201
blkid_topology tp = LINUX_SPECIFIC(dev)->topology;
3205
/* When PED_DEFAULT_ALIGNMENT is divisible by the *_io_size or
3206
there are no *_io_size values, use the PED_DEFAULT_ALIGNMENT
3207
If one or the other will not divide evenly, fall through to
3209
unsigned long optimal_io = blkid_topology_get_optimal_io_size(tp);
3210
unsigned long minimum_io = blkid_topology_get_minimum_io_size(tp);
3212
(!optimal_io && !minimum_io)
3213
|| (optimal_io && PED_DEFAULT_ALIGNMENT % optimal_io == 0
3214
&& minimum_io && PED_DEFAULT_ALIGNMENT % minimum_io == 0)
3215
|| (!minimum_io && optimal_io
3216
&& PED_DEFAULT_ALIGNMENT % optimal_io == 0)
3217
|| (!optimal_io && minimum_io
3218
&& PED_DEFAULT_ALIGNMENT % minimum_io == 0)
3220
/* DASD needs to use minimum alignment */
3221
if (dev->type == PED_DEVICE_DASD)
3222
return linux_get_minimum_alignment(dev);
3224
return ped_alignment_new(
3225
blkid_topology_get_alignment_offset(tp) / dev->sector_size,
3226
PED_DEFAULT_ALIGNMENT / dev->sector_size);
3229
/* If optimal_io_size is 0 and we don't meet the other criteria
3230
for using the device.c default, return the minimum alignment. */
3231
if (blkid_topology_get_optimal_io_size(tp) == 0)
3232
return linux_get_minimum_alignment(dev);
3234
return ped_alignment_new(
3235
blkid_topology_get_alignment_offset(tp) / dev->sector_size,
3236
blkid_topology_get_optimal_io_size(tp) / dev->sector_size);
3240
static PedDeviceArchOps linux_dev_ops = {
3242
destroy: linux_destroy,
3243
is_busy: linux_is_busy,
3245
refresh_open: linux_refresh_open,
3247
refresh_close: linux_refresh_close,
3252
sync_fast: linux_sync_fast,
3253
probe_all: linux_probe_all,
3255
get_minimum_alignment: linux_get_minimum_alignment,
3256
get_optimum_alignment: linux_get_optimum_alignment,
3260
PedDiskArchOps linux_disk_ops = {
3261
partition_get_path: linux_partition_get_path,
3262
partition_is_busy: linux_partition_is_busy,
3263
disk_commit: linux_disk_commit
3266
PedArchitecture ped_linux_arch = {
3267
dev_ops: &linux_dev_ops,
3268
disk_ops: &linux_disk_ops