Esempio n. 1
0
static int
beagle_getxattr (const char *path,
		 const char *key,
		 char *buf,
		 size_t len)
{
	beagle_inode_t *inode;
	int ret;

	if (strlen (key) < BEAGLEFS_XATTR_PREFIX_LEN + 1)
		return -ENODATA;
	if (strncmp (key, BEAGLEFS_XATTR_PREFIX, BEAGLEFS_XATTR_PREFIX_LEN))
		return -ENODATA;
	key += BEAGLEFS_XATTR_PREFIX_LEN;

	ret = -ENOENT;
	beagle_dir_read_lock ();
	inode = beagle_dir_get_inode (path);
	if (inode) {
		if (!strcmp (key, "mime_type"))
			ret = copy_xattr (buf,
					  beagle_inode_get_mime_type (inode),
					  len);
		else if (!strcmp (key, "type"))
			ret = copy_xattr (buf,
					  beagle_inode_get_type (inode),
					  len);
		else if (!strcmp (key, "uri"))
			ret = copy_xattr (buf,
					  beagle_inode_get_uri (inode),
					  len);
		else if (!strcmp (key, "source"))
			ret = copy_xattr (buf,
					  beagle_inode_get_source (inode),
					  len);
		else if (!strcmp (key, "score"))
			ret = copy_xattr (buf,
					  beagle_inode_get_score (inode),
					  len);
		else
			ret = -ENODATA;
	}
	beagle_dir_read_unlock ();

	return ret;
}
Esempio n. 2
0
static value
copy_xattr_list (const struct guestfs_xattr_list *xattrs)
{
  CAMLparam0 ();
  CAMLlocal2 (rv, v);
  unsigned int i;

  if (xattrs->len == 0)
    CAMLreturn (Atom (0));
  else {
    rv = caml_alloc (xattrs->len, 0);
    for (i = 0; i < xattrs->len; ++i) {
      v = copy_xattr (&xattrs->val[i]);
      Store_field (rv, i, v);
    }
    CAMLreturn (rv);
  }
}
Esempio n. 3
0
static int raw_import_finish(RawImport *i) {
        int r;

        assert(i);
        assert(i->output_fd >= 0);
        assert(i->temp_path);
        assert(i->final_path);

        /* In case this was a sparse file, make sure the file system is right */
        if (i->written_uncompressed > 0) {
                if (ftruncate(i->output_fd, i->written_uncompressed) < 0)
                        return log_error_errno(errno, "Failed to truncate file: %m");
        }

        r = raw_import_maybe_convert_qcow2(i);
        if (r < 0)
                return r;

        if (S_ISREG(i->st.st_mode)) {
                (void) copy_times(i->input_fd, i->output_fd);
                (void) copy_xattr(i->input_fd, i->output_fd);
        }

        if (i->read_only) {
                r = import_make_read_only_fd(i->output_fd);
                if (r < 0)
                        return r;
        }

        if (i->force_local)
                (void) rm_rf(i->final_path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);

        r = rename_noreplace(AT_FDCWD, i->temp_path, AT_FDCWD, i->final_path);
        if (r < 0)
                return log_error_errno(r, "Failed to move image into place: %m");

        free(i->temp_path);
        i->temp_path = NULL;

        return 0;
}
Esempio n. 4
0
static int raw_pull_make_local_copy(RawPull *i) {
        _cleanup_free_ char *tp = NULL;
        _cleanup_close_ int dfd = -1;
        const char *p;
        int r;

        assert(i);
        assert(i->raw_job);

        if (!i->local)
                return 0;

        if (i->raw_job->etag_exists) {
                /* We have downloaded this one previously, reopen it */

                assert(i->raw_job->disk_fd < 0);

                i->raw_job->disk_fd = open(i->final_path, O_RDONLY|O_NOCTTY|O_CLOEXEC);
                if (i->raw_job->disk_fd < 0)
                        return log_error_errno(errno, "Failed to open vendor image: %m");
        } else {
                /* We freshly downloaded the image, use it */

                assert(i->raw_job->disk_fd >= 0);

                if (lseek(i->raw_job->disk_fd, SEEK_SET, 0) == (off_t) -1)
                        return log_error_errno(errno, "Failed to seek to beginning of vendor image: %m");
        }

        p = strjoina(i->image_root, "/", i->local, ".raw");

        if (i->force_local)
                (void) rm_rf(p, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);

        r = tempfn_random(p, NULL, &tp);
        if (r < 0)
                return log_oom();

        dfd = open(tp, O_WRONLY|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (dfd < 0)
                return log_error_errno(errno, "Failed to create writable copy of image: %m");

        /* Turn off COW writing. This should greatly improve
         * performance on COW file systems like btrfs, since it
         * reduces fragmentation caused by not allowing in-place
         * writes. */
        r = chattr_fd(dfd, FS_NOCOW_FL, FS_NOCOW_FL);
        if (r < 0)
                log_warning_errno(r, "Failed to set file attributes on %s: %m", tp);

        r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, COPY_REFLINK);
        if (r < 0) {
                unlink(tp);
                return log_error_errno(r, "Failed to make writable copy of image: %m");
        }

        (void) copy_times(i->raw_job->disk_fd, dfd);
        (void) copy_xattr(i->raw_job->disk_fd, dfd);

        dfd = safe_close(dfd);

        r = rename(tp, p);
        if (r < 0)  {
                r = log_error_errno(errno, "Failed to move writable image into place: %m");
                unlink(tp);
                return r;
        }

        log_info("Created new local image '%s'.", i->local);

        if (i->roothash) {
                r = raw_pull_copy_auxiliary_file(i, ".roothash", &i->roothash_path);
                if (r < 0)
                        return r;
        }

        if (i->settings) {
                r = raw_pull_copy_auxiliary_file(i, ".nspawn", &i->settings_path);
                if (r < 0)
                        return r;
        }

        return 0;
}
Esempio n. 5
0
static int raw_export_process(RawExport *e) {
        ssize_t l;
        int r;

        assert(e);

        if (!e->tried_reflink && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {

                /* If we shall take an uncompressed snapshot we can
                 * reflink source to destination directly. Let's see
                 * if this works. */

                r = btrfs_reflink(e->input_fd, e->output_fd);
                if (r >= 0) {
                        r = 0;
                        goto finish;
                }

                e->tried_reflink = true;
        }

        if (!e->tried_sendfile && e->compress.type == IMPORT_COMPRESS_UNCOMPRESSED) {

                l = sendfile(e->output_fd, e->input_fd, NULL, COPY_BUFFER_SIZE);
                if (l < 0) {
                        if (errno == EAGAIN)
                                return 0;

                        e->tried_sendfile = true;
                } else if (l == 0) {
                        r = 0;
                        goto finish;
                } else {
                        e->written_uncompressed += l;
                        e->written_compressed += l;

                        raw_export_report_progress(e);

                        return 0;
                }
        }

        while (e->buffer_size <= 0) {
                uint8_t input[COPY_BUFFER_SIZE];

                if (e->eof) {
                        r = 0;
                        goto finish;
                }

                l = read(e->input_fd, input, sizeof(input));
                if (l < 0) {
                        r = log_error_errno(errno, "Failed to read raw file: %m");
                        goto finish;
                }

                if (l == 0) {
                        e->eof = true;
                        r = import_compress_finish(&e->compress, &e->buffer, &e->buffer_size, &e->buffer_allocated);
                } else {
                        e->written_uncompressed += l;
                        r = import_compress(&e->compress, input, l, &e->buffer, &e->buffer_size, &e->buffer_allocated);
                }
                if (r < 0) {
                        r = log_error_errno(r, "Failed to encode: %m");
                        goto finish;
                }
        }

        l = write(e->output_fd, e->buffer, e->buffer_size);
        if (l < 0) {
                if (errno == EAGAIN)
                        return 0;

                r = log_error_errno(errno, "Failed to write output file: %m");
                goto finish;
        }

        assert((size_t) l <= e->buffer_size);
        memmove(e->buffer, (uint8_t*) e->buffer + l, e->buffer_size - l);
        e->buffer_size -= l;
        e->written_compressed += l;

        raw_export_report_progress(e);

        return 0;

finish:
        if (r >= 0) {
                (void) copy_times(e->input_fd, e->output_fd);
                (void) copy_xattr(e->input_fd, e->output_fd);
        }

        if (e->on_finished)
                e->on_finished(e, r, e->userdata);
        else
                sd_event_exit(e->event, r);

        return 0;
}