1 /* 2 libparted - a library for manipulating disk partitions 3 Copyright (C) 1999 - 2001, 2005, 2007 Free Software Foundation, Inc. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 /** \file device.c */ 20 21 /** 22 * \addtogroup PedDevice 23 * 24 * \brief Device access. 25 * 26 * When ped_device_probe_all() is called, libparted attempts to detect all 27 * devices. It constructs a list which can be accessed with 28 * ped_device_get_next(). 29 * 30 * If you want to use a device that isn't on the list, use 31 * ped_device_get(). Also, there may be OS-specific constructors, for creating 32 * devices from file descriptors, stores, etc. For example, 33 * ped_device_new_from_store(). 34 * 35 * @{ 36 */ 37 38 #include <config.h> 39 40 #include <parted/parted.h> 41 #include <parted/debug.h> 42 43 #include <limits.h> 44 #include <unistd.h> 45 #include <errno.h> 46 47 static PedDevice* devices; /* legal advice says: initialized to NULL, 48 under section 6.7.8 part 10 49 of ISO/EIC 9899:1999 */ 50 51 #ifndef HAVE_CANONICALIZE_FILE_NAME 52 char * 53 canonicalize_file_name (const char *name) 54 { 55 char * buf; 56 int size; 57 char * result; 58 59 #ifdef PATH_MAX 60 size = PATH_MAX; 61 #else 62 /* Bigger is better; realpath has no way todo bounds checking. */ 63 size = 4096; 64 #endif 65 66 /* Just in case realpath does not NULL terminate the string 67 * or it just fits in SIZE without a NULL terminator. */ 68 buf = calloc (size + 1, sizeof(char)); 69 if (! buf) { 70 errno = ENOMEM; 71 return NULL; 72 } 73 74 result = realpath (name, buf); 75 if (! result) 76 free (buf); 77 78 return result; 79 } 80 #else 81 extern char *canonicalize_file_name (const char *name); 82 #endif /* !HAVE_CANONICALIZE_FILE_NAME */ 83 84 static void 85 _device_register (PedDevice* dev) 86 { 87 PedDevice* walk; 88 for (walk = devices; walk && walk->next; walk = walk->next); 89 if (walk) 90 walk->next = dev; 91 else 92 devices = dev; 93 dev->next = NULL; 94 } 95 96 static void 97 _device_unregister (PedDevice* dev) 98 { 99 PedDevice* walk; 100 PedDevice* last = NULL; 101 102 for (walk = devices; walk != NULL; last = walk, walk = walk->next) { 103 if (walk == dev) break; 104 } 105 106 if (last) 107 last->next = dev->next; 108 else 109 devices = dev->next; 110 } 111 112 /** 113 * Returns the next device that was detected by ped_device_probe_all(), or 114 * calls to ped_device_get_next(). 115 * If dev is NULL, returns the first device. 116 * 117 * \return NULL if dev is the last device. 118 */ 119 PedDevice* 120 ped_device_get_next (const PedDevice* dev) 121 { 122 if (dev) 123 return dev->next; 124 else 125 return devices; 126 } 127 128 void 129 _ped_device_probe (const char* path) 130 { 131 PedDevice* dev; 132 133 PED_ASSERT (path != NULL, return); 134 135 ped_exception_fetch_all (); 136 dev = ped_device_get (path); 137 if (!dev) 138 ped_exception_catch (); 139 ped_exception_leave_all (); 140 } 141 142 /** 143 * Attempts to detect all devices. 144 */ 145 void 146 ped_device_probe_all () 147 { 148 ped_architecture->dev_ops->probe_all (); 149 } 150 151 /** 152 * Close/free all devices. 153 * Called by ped_done(), so you do not need to worry about it. 154 */ 155 void 156 ped_device_free_all () 157 { 158 while (devices) 159 ped_device_destroy (devices); 160 } 161 162 /** 163 * Gets the device "name", where name is usually the block device, e.g. 164 * /dev/sdb. If the device wasn't detected with ped_device_probe_all(), 165 * an attempt will be made to detect it again. If it is found, it will 166 * be added to the list. 167 */ 168 PedDevice* 169 ped_device_get (const char* path) 170 { 171 PedDevice* walk; 172 char* normal_path; 173 174 PED_ASSERT (path != NULL, return NULL); 175 normal_path = canonicalize_file_name (path); 176 if (!normal_path) 177 /* Well, maybe it is just that the file does not exist. 178 * Try it anyway. */ 179 normal_path = strdup (path); 180 if (!normal_path) 181 return NULL; 182 183 for (walk = devices; walk != NULL; walk = walk->next) { 184 if (!strcmp (walk->path, normal_path)) { 185 ped_free (normal_path); 186 return walk; 187 } 188 } 189 190 walk = ped_architecture->dev_ops->_new (normal_path); 191 ped_free (normal_path); 192 if (!walk) 193 return NULL; 194 195 _device_register (walk); 196 return walk; 197 } 198 199 /** 200 * Destroys a device and removes it from the device list, and frees 201 * all resources associated with the device (all resources allocated 202 * when the device was created). 203 */ 204 void 205 ped_device_destroy (PedDevice* dev) 206 { 207 _device_unregister (dev); 208 209 while (dev->open_count) { 210 if (!ped_device_close (dev)) 211 break; 212 } 213 214 ped_architecture->dev_ops->destroy (dev); 215 } 216 217 void 218 ped_device_cache_remove(PedDevice *dev) 219 { 220 _device_unregister (dev); 221 } 222 223 int 224 ped_device_is_busy (PedDevice* dev) 225 { 226 return ped_architecture->dev_ops->is_busy (dev); 227 } 228 229 /** 230 * Attempt to open a device to allow use of read, write and sync functions. 231 * 232 * The meaning of "open" is architecture-dependent. Apart from requesting 233 * access to the device from the operating system, it does things like flushing 234 * caches. 235 * \note May allocate resources. Any resources allocated here will 236 * be freed by a final ped_device_close(). (ped_device_open() may be 237 * called multiple times -- it's a ref-count-like mechanism) 238 * 239 * \return zero on failure 240 */ 241 int 242 ped_device_open (PedDevice* dev) 243 { 244 int status; 245 246 PED_ASSERT (dev != NULL, return 0); 247 PED_ASSERT (!dev->external_mode, return 0); 248 249 if (dev->open_count) 250 status = ped_architecture->dev_ops->refresh_open (dev); 251 else 252 status = ped_architecture->dev_ops->open (dev); 253 if (status) 254 dev->open_count++; 255 return status; 256 } 257 258 /** 259 * Close dev. 260 * If this is the final close, then resources allocated by 261 * ped_device_open() are freed. 262 * 263 * \return zero on failure 264 */ 265 int 266 ped_device_close (PedDevice* dev) 267 { 268 PED_ASSERT (dev != NULL, return 0); 269 PED_ASSERT (!dev->external_mode, return 0); 270 PED_ASSERT (dev->open_count > 0, return 0); 271 272 if (--dev->open_count) 273 return ped_architecture->dev_ops->refresh_close (dev); 274 else 275 return ped_architecture->dev_ops->close (dev); 276 } 277 278 /** 279 * Begins external access mode. External access mode allows you to 280 * safely do IO on the device. If a PedDevice is open, then you should 281 * not do any IO on that device, e.g. by calling an external program 282 * like e2fsck, unless you put it in external access mode. You should 283 * not use any libparted commands that do IO to a device, e.g. 284 * ped_file_system_{open|resize|copy}, ped_disk_{read|write}), while 285 * a device is in external access mode. 286 * Also, you should not ped_device_close() a device, while it is 287 * in external access mode. 288 * Note: ped_device_begin_external_access_mode() does things like 289 * tell the kernel to flush its caches. 290 * 291 * Close a device while pretending it is still open. 292 * This is useful for temporarily suspending libparted access to the device 293 * in order for an external program to access it. 294 * (Running external programs while the device is open can cause cache 295 * coherency problems.) 296 * 297 * In particular, this function keeps track of dev->open_count, so that 298 * reference counting isn't screwed up. 299 * 300 * \return zero on failure. 301 */ 302 int 303 ped_device_begin_external_access (PedDevice* dev) 304 { 305 PED_ASSERT (dev != NULL, return 0); 306 PED_ASSERT (!dev->external_mode, return 0); 307 308 dev->external_mode = 1; 309 if (dev->open_count) 310 return ped_architecture->dev_ops->close (dev); 311 else 312 return 1; 313 } 314 315 /** 316 * \brief Complementary function to ped_device_begin_external_access. 317 * 318 * \note does things like tell the kernel to flush the device's cache. 319 * 320 * \return zero on failure. 321 */ 322 int 323 ped_device_end_external_access (PedDevice* dev) 324 { 325 PED_ASSERT (dev != NULL, return 0); 326 PED_ASSERT (dev->external_mode, return 0); 327 328 dev->external_mode = 0; 329 if (dev->open_count) 330 return ped_architecture->dev_ops->open (dev); 331 else 332 return 1; 333 } 334 335 /** 336 * \internal Read count sectors from dev into buffer, beginning with sector 337 * start. 338 * 339 * \return zero on failure. 340 */ 341 int 342 ped_device_read (const PedDevice* dev, void* buffer, PedSector start, 343 PedSector count) 344 { 345 PED_ASSERT (dev != NULL, return 0); 346 PED_ASSERT (buffer != NULL, return 0); 347 PED_ASSERT (!dev->external_mode, return 0); 348 PED_ASSERT (dev->open_count > 0, return 0); 349 350 return (ped_architecture->dev_ops->read) (dev, buffer, start, count); 351 } 352 353 /** 354 * \internal Write count sectors from buffer to dev, starting at sector 355 * start. 356 * 357 * \return zero on failure. 358 * 359 * \sa PedDevice::sector_size 360 * \sa PedDevice::phys_sector_size 361 */ 362 int 363 ped_device_write (PedDevice* dev, const void* buffer, PedSector start, 364 PedSector count) 365 { 366 PED_ASSERT (dev != NULL, return 0); 367 PED_ASSERT (buffer != NULL, return 0); 368 PED_ASSERT (!dev->external_mode, return 0); 369 PED_ASSERT (dev->open_count > 0, return 0); 370 371 return (ped_architecture->dev_ops->write) (dev, buffer, start, count); 372 } 373 374 PedSector 375 ped_device_check (PedDevice* dev, void* buffer, PedSector start, 376 PedSector count) 377 { 378 PED_ASSERT (dev != NULL, return 0); 379 PED_ASSERT (!dev->external_mode, return 0); 380 PED_ASSERT (dev->open_count > 0, return 0); 381 382 return (ped_architecture->dev_ops->check) (dev, buffer, start, count); 383 } 384 385 /** 386 * \internal Flushes all write-behind caches that might be holding up 387 * writes. 388 * It is slow because it guarantees cache coherency among all relevant caches. 389 * 390 * \return zero on failure 391 */ 392 int 393 ped_device_sync (PedDevice* dev) 394 { 395 PED_ASSERT (dev != NULL, return 0); 396 PED_ASSERT (!dev->external_mode, return 0); 397 PED_ASSERT (dev->open_count > 0, return 0); 398 399 return ped_architecture->dev_ops->sync (dev); 400 } 401 402 /** 403 * \internal Flushes all write-behind caches that might be holding writes. 404 * \warning Does NOT ensure cache coherency with other caches. 405 * If you need cache coherency, use ped_device_sync() instead. 406 * 407 * \return zero on failure 408 */ 409 int 410 ped_device_sync_fast (PedDevice* dev) 411 { 412 PED_ASSERT (dev != NULL, return 0); 413 PED_ASSERT (!dev->external_mode, return 0); 414 PED_ASSERT (dev->open_count > 0, return 0); 415 416 return ped_architecture->dev_ops->sync_fast (dev); 417 } 418 419 /** 420 * Get a constraint that represents hardware requirements on alignment and 421 * geometry. 422 * This is, for example, important for media that have a physical sector 423 * size that is a multiple of the logical sector size. 424 * 425 * \warning This function is experimental for physical sector sizes not equal to 426 * 2^9. 427 */ 428 PedConstraint* 429 ped_device_get_constraint (PedDevice* dev) 430 { 431 int multiplier = dev->phys_sector_size / dev->sector_size; 432 433 PedAlignment* start_align = ped_alignment_new (multiplier, multiplier); 434 435 PedConstraint* c = ped_constraint_new ( 436 start_align, ped_alignment_any, 437 ped_geometry_new (dev, 0, dev->length), 438 ped_geometry_new (dev, 0, dev->length), 439 1, dev->length); 440 441 return c; 442 } 443 444 /** @} */ 445