Exemple #1
0
int mmc_trim(int fd, off_t offset, off_t count)
{
    uint64_t range[2] = {offset, offset + count};

    if (ioctl(fd, BLKDISCARD, &range))
        fwup_warnx("BLKDISCARD (TRIM command) failed on range %"PRIu64" to %"PRIu64" (ignoring)", range[0], range[1]);

    return 0;
}
Exemple #2
0
static dev_t root_disk_device()
{
    // NOTE: We'd like to know the root device for the root directory, but stat
    //       only returns the partition device for the root directory. Since it
    //       is often the case of 16 minor devices to support each real device,
    //       assume that if we mask the root directory's device off that we'll
    //       get its parent.
    struct stat rootdev;
    if (stat("/", &rootdev) >= 0) {
        return (rootdev.st_dev & 0xfff0);
    } else {
        fwup_warnx("can't stat root directory");
        return 0;
    }
}
Exemple #3
0
int mmc_eject(const char *mmc_device)
{
    DADiskRef disk = mmc_device_to_diskref(mmc_device);
    int rc = -1;
    if (disk) {
        struct disk_op_context context;
        context.operation = "eject";
        DADiskEject(disk, kDADiskEjectOptionDefault, disk_op_done_cb,  &context);

        if (run_loop_for_time(10) < 0)
            fwup_warnx("unmount timed out");

        if (context.succeeded)
            rc = 0;

        CFRelease(disk);
    }
    return rc;
}
Exemple #4
0
int mmc_umount_all(const char *mmc_device)
{
    DADiskRef disk = mmc_device_to_diskref(mmc_device);
    int rc = -1;
    if (disk) {
        struct disk_op_context context;
        context.operation = "unmount";
        DADiskUnmount(disk, kDADiskUnmountOptionWhole, disk_op_done_cb, &context);

        // Wait for a while since unmounting sometimes takes time.
        if (run_loop_for_time(10) < 0)
            fwup_warnx("unmount timed out");

        if (context.succeeded)
            rc = 0;
        CFRelease(disk);
    }
    return rc;
}
Exemple #5
0
static void disk_op_done_cb(DADiskRef disk, DADissenterRef dissenter, void *c)
{
    (void) disk;

    struct disk_op_context *context = (struct disk_op_context *) c;
    if (dissenter) {
        CFStringRef what = DADissenterGetStatusString(dissenter);
        fwup_warnx("%s failed: 0x%x (%d) %s)",
                context->operation,
                DADissenterGetStatus(dissenter),
                DADissenterGetStatus(dissenter),
                CFStringGetCStringPtr(what, kCFStringEncodingMacRoman));
        context->succeeded = false;
    } else {
        context->succeeded = true;
    }

    CFRunLoopStop(CFRunLoopGetCurrent());
}
Exemple #6
0
int mmc_umount_all(const char *mmc_device)
{
    FILE *fp = fopen("/proc/mounts", "r");
    if (!fp)
        fwup_err(EXIT_FAILURE, "/proc/mounts");

    char *todo[64] = {0};
    int todo_ix = 0;
    int ultimate_rc = 0;

    char line[FWUP_BLOCK_SIZE] = {0};
    while (!feof(fp) &&
            fgets(line, sizeof(line), fp)) {
        char devname[64];
        char mountpoint[256];
        if (sscanf(line, "%63s %255s", devname, mountpoint) != 2)
            continue;

        if (strstr(devname, mmc_device) == devname) {
            // mmc_device is a prefix of this device, i.e. mmc_device is /dev/sdc
            // and /dev/sdc1 is mounted.

            if (todo_ix == NUM_ELEMENTS(todo))
                fwup_errx(EXIT_FAILURE, "Device mounted too many times");

            // strings from /proc/mounts are escaped, so unescape them
            todo[todo_ix++] = unescape_string(mountpoint);
        }
    }
    fclose(fp);

    int mtab_exists = (access("/etc/mtab", F_OK) != -1);
    for (int i = 0; i < todo_ix; i++) {
        if (mtab_exists) {
            // If /etc/mtab, then call umount(8) so that
            // gets updated correctly.
            int rc = fork_exec("/bin/umount", todo[i]);
            if (rc != 0) {
                fwup_warnx("Error calling umount on '%s'", todo[i]);
                ultimate_rc = -1;
            }
        } else {
            // No /etc/mtab, so call the kernel directly.
#if HAS_UMOUNT
            if (umount(todo[i]) < 0) {
                fwup_warnx("umount %s", todo[i]);
                ultimate_rc = -1;
            }
#else
            // If no umount on this platform, warn, but don't
            // return failure.
            fwup_warnx("umount %s: not supported", todo[i]);
#endif
        }
    }

    for (int i = 0; i < todo_ix; i++)
        free(todo[i]);

    return ultimate_rc;
}