static void run_test (void) { guestfs_h *g; size_t i; printf ("Warming up the libguestfs cache ...\n"); for (i = 0; i < NR_WARMUP_PASSES; ++i) { g = create_handle (); add_drive (g); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); guestfs_close (g); } printf ("Running the tests in %d passes ...\n", NR_TEST_PASSES); for (i = 0; i < NR_TEST_PASSES; ++i) { g = create_handle (); set_up_event_handlers (g, i); start_libvirt_thread (i); add_drive (g); if (guestfs_launch (g) == -1) exit (EXIT_FAILURE); guestfs_close (g); stop_libvirt_thread (); printf (" pass %zu: %zu events collected in %" PRIi64 " ns\n", i+1, pass_data[i].nr_events, pass_data[i].elapsed_ns); } if (verbose) dump_pass_data (); printf ("Analyzing the results ...\n"); check_pass_data (); construct_timeline (); analyze_timeline (); if (verbose) dump_timeline (); printf ("\n"); g = create_handle (); test_info (g, NR_TEST_PASSES); guestfs_close (g); printf ("\n"); print_analysis (); printf ("\n"); printf ("Longest activities:\n"); printf ("\n"); print_longest_to_shortest (); free_pass_data (); free_final_timeline (); }
/* create a new dos drive */ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, const char *mount_point, enum device_type type, const GUID *guid ) { char *path, *p; HKEY hkey; NTSTATUS status = STATUS_SUCCESS; struct dos_drive *drive, *next; struct volume *volume; int notify = -1; if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY; EnterCriticalSection( &device_section ); volume = find_matching_volume( udi, device, mount_point, type ); if (letter == -1) /* auto-assign a letter */ { letter = add_drive( device, type ); if (letter == -1) { status = STATUS_OBJECT_NAME_COLLISION; goto done; } LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry ) { if (drive->volume->udi && !strcmp( udi, drive->volume->udi )) goto found; if (drive->drive == letter) delete_dos_device( drive ); } }
static int ablk_init( void ) { static pci_dev_info_t pci_config = { 0x1000, 0x0003, 0x02, 0x0, 0x0100 }; mol_device_node_t *dn = prom_find_devices("mol-blk"); bdev_desc_t *bdev = NULL; memset( &ablk, 0, sizeof(ablk) ); if( !is_oldworld_boot() && !dn ) return 0; if( !register_osi_driver( "blk", "mol-blk", is_classic_boot()? &pci_config : NULL, &ablk.irq ) ) { printm("----> Failed to register the ablk driver!\n"); return 0; } while( (bdev=bdev_get_next_volume(bdev)) ) { bdev_claim_volume( bdev ); add_drive( dn, bdev ); } pipe( ablk.ctrl_pipe ); create_thread( io_thread, NULL, "blk-io" ); register_osi_iface( osi_iface, sizeof(osi_iface) ); return 1; }
static void ensure_drive_c_is_mapped(void) { struct stat buf; const char *configdir = wine_get_config_dir(); int len; char *drive_c_dir; if (drives[2].in_use) return; len = snprintf(NULL, 0, "%s/../drive_c", configdir); drive_c_dir = HeapAlloc(GetProcessHeap(), 0, len); snprintf(drive_c_dir, len, "%s/../drive_c", configdir); HeapFree(GetProcessHeap(), 0, drive_c_dir); if (stat(drive_c_dir, &buf) == 0) { WCHAR label[64]; LoadStringW (GetModuleHandle (NULL), IDS_SYSTEM_DRIVE_LABEL, label, sizeof(label)/sizeof(label[0])); add_drive('C', "../drive_c", NULL, label, 0, DRIVE_FIXED); } else { report_error(NO_DRIVE_C); } }
static void ensure_home_is_mapped(void) { int i; BOOL mapped = FALSE; char *home = getenv("HOME"); if (!home) return; for (i = 0; i < 26; i++) if (drives[i].in_use && !strcmp(drives[i].unixpath, home)) mapped = TRUE; if (!mapped) { char letter; for (letter = 'H'; letter <= 'Z'; letter++) { if (!drives[letter - 'A'].in_use) { add_drive(letter, home, NULL, NULL, 0, DRIVE_FIXED); WINE_TRACE("allocated drive %c as the user's home directory\n", letter); break; } } if (letter == ('Z' + 1)) report_error(NO_HOME); } }
static void ensure_root_is_mapped(void) { int i; BOOL mapped = FALSE; for (i = 0; i < 26; i++) if (drives[i].in_use && !strcmp(drives[i].unixpath, "/")) mapped = TRUE; if (!mapped) { /* work backwards from Z, trying to map it */ char letter; for (letter = 'Z'; letter >= 'A'; letter--) { if (!drives[letter - 'A'].in_use) { add_drive(letter, "/", NULL, NULL, 0, DRIVE_FIXED); WINE_TRACE("allocated drive %c as the root drive\n", letter); break; } } if (letter == ('A' - 1)) report_error(NO_ROOT); } }
static void _g_udisks_device_added(GUDisksDevice* dev, GUDisksVolumeMonitor* mon, gboolean emit_signal) { /* FIXME: how should we treat sys internal devices? * make this optional */ if(!dev->is_hidden && (!dev->is_sys_internal || fm_config->show_internal_volumes) ) { if(dev->is_drive) add_drive(mon, dev, emit_signal); if(g_udisks_device_is_volume(dev)) add_volume(mon, dev, emit_signal); } }
/* Load currently defined drives into the drives array */ BOOL load_drives(void) { DWORD i, size = 1024; HANDLE mgr; WCHAR root[] = {'A',':','\\',0}; if ((mgr = open_mountmgr()) == INVALID_HANDLE_VALUE) return FALSE; while (root[0] <= 'Z') { struct mountmgr_unix_drive input; struct mountmgr_unix_drive *data; if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) break; memset( &input, 0, sizeof(input) ); input.letter = root[0]; if (DeviceIoControl( mgr, IOCTL_MOUNTMGR_QUERY_UNIX_DRIVE, &input, sizeof(input), data, size, NULL, NULL )) { char *unixpath = NULL, *device = NULL; WCHAR volname[MAX_PATH]; DWORD serial; if (data->mount_point_offset) unixpath = (char *)data + data->mount_point_offset; if (data->device_offset) device = (char *)data + data->device_offset; if (!GetVolumeInformationW( root, volname, sizeof(volname)/sizeof(WCHAR), &serial, NULL, NULL, NULL, 0 )) { volname[0] = 0; serial = 0; } add_drive( root[0], unixpath, device, volname, serial, get_drive_type(root[0]) ); root[0]++; } else { if (GetLastError() == ERROR_MORE_DATA) size = data->size; else root[0]++; /* skip this drive */ } HeapFree( GetProcessHeap(), 0, data ); } /* reset modified flags */ for (i = 0; i < 26; i++) drives[i].modified = FALSE; CloseHandle( mgr ); return TRUE; }
static void add_dos_device( const char *udi, const char *device, const char *mount_point, const char *type ) { struct dos_drive *drive; /* first check if it already exists */ LIST_FOR_EACH_ENTRY( drive, &drives_list, struct dos_drive, entry ) { if (!strcmp( udi, drive->udi )) goto found; } if (!(drive = HeapAlloc( GetProcessHeap(), 0, sizeof(*drive) ))) return; if (!(drive->udi = HeapAlloc( GetProcessHeap(), 0, strlen(udi)+1 ))) { HeapFree( GetProcessHeap(), 0, drive ); return; } strcpy( drive->udi, udi ); list_add_tail( &drives_list, &drive->entry ); found: drive->drive = add_drive( device, type ); if (drive->drive != -1) { HKEY hkey; set_mount_point( drive, mount_point ); WINE_TRACE( "added device %c: udi %s for %s on %s type %s\n", 'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device), wine_dbgstr_a(mount_point), wine_dbgstr_a(type) ); /* hack: force the drive type in the registry */ if (!RegCreateKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Drives", &hkey )) { char name[3] = "a:"; name[0] += drive->drive; if (!type || strcmp( type, "cdrom" )) type = "floppy"; /* FIXME: default to floppy */ RegSetValueExA( hkey, name, 0, REG_SZ, (const BYTE *)type, strlen(type) + 1 ); RegCloseKey( hkey ); } send_notify( drive->drive, DBT_DEVICEARRIVAL ); } }
static void g_udisks_device_changed(GUDisksDevice* dev, GUDisksVolumeMonitor* mon) { GUDisksDrive* drv = find_drive(mon, dev); GUDisksVolume* vol = find_volume(mon, dev); /* gboolean is_drive = dev->is_drive; char* usage = g_strdup(dev->usage); */ g_debug("g_udisks_device_changed"); if(drv) { g_signal_emit(mon, sig_drive_changed, 0, drv); g_udisks_drive_changed(drv); /* it's no longer a drive */ if(!dev->is_drive) remove_drive(mon, dev); } else { if(dev->is_drive) add_drive(mon, dev, TRUE); } if(vol) { update_volume_drive(vol, mon); g_signal_emit(mon, sig_volume_changed, 0, vol); g_udisks_volume_changed(vol); /* it's no longer a volume */ if(!g_udisks_device_is_volume(dev)) remove_volume(mon, dev); } else { /* we got a usable volume now */ if(g_udisks_device_is_volume(dev)) add_volume(mon, dev, TRUE); } }
static void grl_optical_media_source_browse (GrlSource *source, GrlSourceBrowseSpec *bs) { GList *drives; GList *volumes; GList *l; GrlOpticalMediaSourcePrivate *priv = GRL_OPTICAL_MEDIA_SOURCE (source)->priv; BrowseData *data; GList *media_list; GRL_DEBUG ("%s", __FUNCTION__); media_list = NULL; /* Get the drives */ drives = g_volume_monitor_get_connected_drives (priv->monitor); for (l = drives; l != NULL; l = l->next) { GDrive *drive = l->data; media_list = add_drive (media_list, drive, GRL_OPTICAL_MEDIA_SOURCE (source)); g_object_unref (drive); } g_list_free (drives); /* Look for mounted ISO images */ volumes = g_volume_monitor_get_volumes (priv->monitor); for (l = volumes; l != NULL; l = l->next) { GVolume *volume = l->data; char *path; path = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE); if (path != NULL && g_str_has_prefix (path, "/dev/loop")) media_list = add_volume (media_list, volume, NULL, GRL_OPTICAL_MEDIA_SOURCE (source)); g_free (path); g_object_unref (volume); } g_list_free (volumes); /* Got nothing? */ if (media_list == NULL) { /* Tell the caller we're done */ bs->callback (bs->source, bs->operation_id, NULL, 0, bs->user_data, NULL); return; } media_list = g_list_reverse (media_list); /* And go to resolve all those devices */ data = g_new0 (BrowseData, 1); data->source = source; data->bs = bs; data->media_list = media_list; data->cancellable = g_cancellable_new (); grl_operation_set_data (bs->operation_id, data->cancellable); data->parser = totem_pl_parser_new (); g_object_set (data->parser, "recurse", FALSE, NULL); g_signal_connect (G_OBJECT (data->parser), "entry-parsed", G_CALLBACK (entry_parsed_cb), data); resolve_disc_urls (data); }
/* * Scan SCSI busses to detect any devices * that we want to supply to the Amgia. * * Based on code from cdrecord */ static int scanscsi (SCSI *scgp) { int bus; int tgt; int lun = 0; int initiator; int have_tgt; int n; scgp->silent++; for (bus = 0; bus < 16; bus++) { scg_settarget (scgp, bus, 0, 0); if (!scg_havebus (scgp, bus)) continue; initiator = scg_initiator_id (scgp); write_log ("scsibus%d:\n", bus); for (tgt = 0; tgt < 16; tgt++) { n = bus * 100 + tgt; scg_settarget (scgp, bus, tgt, lun); have_tgt = unit_ready (scgp) || scgp->scmd->error != SCG_FATAL; if (!have_tgt && tgt > 7) { if (scgp->scmd->ux_errno == EINVAL) break; continue; } write_log (" %d,%d,%d %d ", bus, tgt, lun, n); if (tgt == initiator) { write_log ("HOST ADAPTOR\n"); continue; } if (!have_tgt) { /* Hack: fd -> -2 means no access */ write_log ( "%c\n", scgp->fd == -2 ? '?':'*'); continue; } if ((scgp->scmd->error < SCG_FATAL) || (scgp->scmd->scb.chk && scgp->scmd->sense_count > 0)) { struct scsi_inquiry *inq = scgp->inq; inquiry (scgp, inq, sizeof (*inq)); print_product (inq); /* Just CD/DVD drives for now */ if (inq->type == INQ_ROMD) add_drive (scgp); } write_log ("\n"); } } scgp->silent--; return 0; }
/* create a new dos drive */ NTSTATUS add_dos_device( int letter, const char *udi, const char *device, const char *mount_point, enum device_type type ) { struct dos_drive *drive, *next; if (letter == -1) /* auto-assign a letter */ { letter = add_drive( device, type ); if (letter == -1) return STATUS_OBJECT_NAME_COLLISION; } else /* simply reset the device symlink */ { char *path, *p; if (!(path = get_dosdevices_path( &p ))) return STATUS_NO_MEMORY; *p = 'a' + letter; unlink( path ); if (device) symlink( device, path ); } LIST_FOR_EACH_ENTRY_SAFE( drive, next, &drives_list, struct dos_drive, entry ) { if (udi && drive->udi && !strcmp( udi, drive->udi )) { if (type == drive->type) goto found; delete_disk_device( drive ); continue; } if (drive->drive == letter) delete_disk_device( drive ); } if (create_disk_device( udi, type, &drive )) return STATUS_NO_MEMORY; found: RtlFreeHeap( GetProcessHeap(), 0, drive->unix_device ); drive->unix_device = strdupA( device ); set_drive_letter( drive, letter ); set_unix_mount_point( drive, mount_point ); if (drive->drive != -1) { HKEY hkey; TRACE( "added device %c: udi %s for %s on %s type %u\n", 'a' + drive->drive, wine_dbgstr_a(udi), wine_dbgstr_a(device), wine_dbgstr_a(mount_point), type ); /* hack: force the drive type in the registry */ if (!RegCreateKeyW( HKEY_LOCAL_MACHINE, drives_keyW, &hkey )) { const WCHAR *type_name = drive_types[type]; WCHAR name[3] = {'a',':',0}; name[0] += drive->drive; if (!type_name[0] && type == DEVICE_HARDDISK) type_name = drive_types[DEVICE_FLOPPY]; if (type_name[0]) RegSetValueExW( hkey, name, 0, REG_SZ, (const BYTE *)type_name, (strlenW(type_name) + 1) * sizeof(WCHAR) ); else RegDeleteValueW( hkey, name ); RegCloseKey( hkey ); } if (udi) send_notify( drive->drive, DBT_DEVICEARRIVAL ); } return STATUS_SUCCESS; }
int autodetect_drives(void) { #ifdef HAVE_MNTENT_H struct mntent *ent; FILE *fstab; #endif /* we want to build a list of autodetected drives, then ensure each entry exists in the users setup. so, we superimpose the autodetected drives onto whatever is pre-existing. for now let's just rummage around inside the fstab. */ load_drives(); working_mask = drive_available_mask('\0'); #ifdef HAVE_MNTENT_H fstab = fopen("/etc/fstab", "r"); if (!fstab) { report_error(FSTAB_OPEN); return FALSE; } while ((ent = getmntent(fstab))) { char letter; int type; char *device = NULL; WINE_TRACE("ent->mnt_dir=%s\n", ent->mnt_dir); if (should_ignore_fstype(ent->mnt_type)) continue; if (should_ignore_mnt_dir(ent->mnt_dir)) continue; if (is_drive_defined(ent->mnt_dir)) continue; if (!strcmp(ent->mnt_type, "nfs")) type = DRIVE_REMOTE; else if (!strcmp(ent->mnt_type, "nfs4")) type = DRIVE_REMOTE; else if (!strcmp(ent->mnt_type, "smbfs")) type = DRIVE_REMOTE; else if (!strcmp(ent->mnt_type, "cifs")) type = DRIVE_REMOTE; else if (!strcmp(ent->mnt_type, "coda")) type = DRIVE_REMOTE; else if (!strcmp(ent->mnt_type, "iso9660")) type = DRIVE_CDROM; else if (!strcmp(ent->mnt_type, "ramfs")) type = DRIVE_RAMDISK; else type = try_dev_node(ent->mnt_fsname); /* allocate a drive for it */ letter = allocate_letter(type); if (letter == 'Z' + 1) { report_error(NO_MORE_LETTERS); fclose(fstab); return FALSE; } if (type == DRIVE_CDROM) device = ent->mnt_fsname; WINE_TRACE("adding drive %c for %s, device %s, type %s\n", letter, ent->mnt_dir, device, ent->mnt_type); add_drive(letter, ent->mnt_dir, device, NULL, 0, type); /* working_mask is a map of the drive letters still available. */ working_mask &= ~DRIVE_MASK_BIT(letter); } fclose(fstab); #endif ensure_root_is_mapped(); ensure_drive_c_is_mapped(); ensure_home_is_mapped(); return TRUE; }