cregit-Linux how code gets into the kernel

Release 4.18 tools/hv/hv_fcopy_daemon.c

Directory: tools/hv
/*
 * An implementation of host to guest copy functionality for Linux.
 *
 * Copyright (C) 2014, Microsoft, Inc.
 *
 * Author : K. Y. Srinivasan <kys@microsoft.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
 * NON INFRINGEMENT.  See the GNU General Public License for more
 * details.
 */


#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <linux/hyperv.h>
#include <linux/limits.h>
#include <syslog.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <getopt.h>


static int target_fd;

static char target_fname[PATH_MAX];

static unsigned long long filesize;


static int hv_start_fcopy(struct hv_start_fcopy *smsg) { int error = HV_E_FAIL; char *q, *p; filesize = 0; p = (char *)smsg->path_name; snprintf(target_fname, sizeof(target_fname), "%s/%s", (char *)smsg->path_name, (char *)smsg->file_name); syslog(LOG_INFO, "Target file name: %s", target_fname); /* * Check to see if the path is already in place; if not, * create if required. */ while ((q = strchr(p, '/')) != NULL) { if (q == p) { p++; continue; } *q = '\0'; if (access((char *)smsg->path_name, F_OK)) { if (smsg->copy_flags & CREATE_PATH) { if (mkdir((char *)smsg->path_name, 0755)) { syslog(LOG_ERR, "Failed to create %s", (char *)smsg->path_name); goto done; } } else { syslog(LOG_ERR, "Invalid path: %s", (char *)smsg->path_name); goto done; } } p = q + 1; *q = '/'; } if (!access(target_fname, F_OK)) { syslog(LOG_INFO, "File: %s exists", target_fname); if (!(smsg->copy_flags & OVER_WRITE)) { error = HV_ERROR_ALREADY_EXISTS; goto done; } } target_fd = open(target_fname, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0744); if (target_fd == -1) { syslog(LOG_INFO, "Open Failed: %s", strerror(errno)); goto done; } error = 0; done: return error; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan28496.60%240.00%
Vitaly Kuznetsov41.36%120.00%
Olaf Hering41.36%120.00%
Yue Zhang20.68%120.00%
Total294100.00%5100.00%


static int hv_copy_data(struct hv_do_fcopy *cpmsg) { ssize_t bytes_written; int ret = 0; bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size, cpmsg->offset); filesize += cpmsg->size; if (bytes_written != cpmsg->size) { switch (errno) { case ENOSPC: ret = HV_ERROR_DISK_FULL; break; default: ret = HV_E_FAIL; break; } syslog(LOG_ERR, "pwrite failed to write %llu bytes: %ld (%s)", filesize, (long)bytes_written, strerror(errno)); } return ret; }

Contributors

PersonTokensPropCommitsCommitProp
Olaf Hering5254.17%150.00%
K. Y. Srinivasan4445.83%150.00%
Total96100.00%2100.00%


static int hv_copy_finished(void) { close(target_fd); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan16100.00%1100.00%
Total16100.00%1100.00%


static int hv_copy_cancel(void) { close(target_fd); unlink(target_fname); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan21100.00%1100.00%
Total21100.00%1100.00%


void print_usage(char *argv[]) { fprintf(stderr, "Usage: %s [options]\n" "Options are:\n" " -n, --no-daemon stay in foreground, don't daemonize\n" " -h, --help print this help\n", argv[0]); }

Contributors

PersonTokensPropCommitsCommitProp
Vitaly Kuznetsov25100.00%1100.00%
Total25100.00%1100.00%


int main(int argc, char *argv[]) { int fcopy_fd; int error; int daemonize = 1, long_index = 0, opt; int version = FCOPY_CURRENT_VERSION; union { struct hv_fcopy_hdr hdr; struct hv_start_fcopy start; struct hv_do_fcopy copy; __u32 kernel_modver; } buffer = { }; int in_handshake = 1; static struct option long_options[] = { {"help", no_argument, 0, 'h' }, {"no-daemon", no_argument, 0, 'n' }, {0, 0, 0, 0 } }; while ((opt = getopt_long(argc, argv, "hn", long_options, &long_index)) != -1) { switch (opt) { case 'n': daemonize = 0; break; case 'h': default: print_usage(argv); exit(EXIT_FAILURE); } } if (daemonize && daemon(1, 0)) { syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno)); exit(EXIT_FAILURE); } openlog("HV_FCOPY", 0, LOG_USER); syslog(LOG_INFO, "starting; pid is:%d", getpid()); fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR); if (fcopy_fd < 0) { syslog(LOG_ERR, "open /dev/vmbus/hv_fcopy failed; error: %d %s", errno, strerror(errno)); exit(EXIT_FAILURE); } /* * Register with the kernel. */ if ((write(fcopy_fd, &version, sizeof(int))) != sizeof(int)) { syslog(LOG_ERR, "Registration failed: %s", strerror(errno)); exit(EXIT_FAILURE); } while (1) { /* * In this loop we process fcopy messages after the * handshake is complete. */ ssize_t len; len = pread(fcopy_fd, &buffer, sizeof(buffer), 0); if (len < 0) { syslog(LOG_ERR, "pread failed: %s", strerror(errno)); exit(EXIT_FAILURE); } if (in_handshake) { if (len != sizeof(buffer.kernel_modver)) { syslog(LOG_ERR, "invalid version negotiation"); exit(EXIT_FAILURE); } in_handshake = 0; syslog(LOG_INFO, "kernel module version: %u", buffer.kernel_modver); continue; } switch (buffer.hdr.operation) { case START_FILE_COPY: error = hv_start_fcopy(&buffer.start); break; case WRITE_TO_FILE: error = hv_copy_data(&buffer.copy); break; case COMPLETE_FCOPY: error = hv_copy_finished(); break; case CANCEL_FCOPY: error = hv_copy_cancel(); break; default: syslog(LOG_ERR, "Unknown operation: %d", buffer.hdr.operation); } if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) { syslog(LOG_ERR, "pwrite failed: %s", strerror(errno)); exit(EXIT_FAILURE); } } }

Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan28357.76%120.00%
Vitaly Kuznetsov15832.24%240.00%
Olaf Hering4910.00%240.00%
Total490100.00%5100.00%


Overall Contributors

PersonTokensPropCommitsCommitProp
K. Y. Srinivasan68869.08%218.18%
Vitaly Kuznetsov18818.88%327.27%
Olaf Hering11411.45%436.36%
Dexuan Cui40.40%19.09%
Yue Zhang20.20%19.09%
Total996100.00%11100.00%
Directory: tools/hv
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
Created with cregit.