Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752091AbbEZHCa (ORCPT ); Tue, 26 May 2015 03:02:30 -0400 Received: from [133.145.228.44] ([133.145.228.44]:60467 "EHLO mail9.hitachi.co.jp" rhost-flags-FAIL-FAIL-OK-OK) by vger.kernel.org with ESMTP id S1751442AbbEZG6l (ORCPT ); Tue, 26 May 2015 02:58:41 -0400 X-AuditID: 85900ec0-9cdc8b9000001a57-a8-5564197eaa29 Subject: [PATCH trace-cmd V6 6/7] trace-cmd/virt-server: Add --dom option which makes a domain directory to virt-server From: Masami Hiramatsu To: Steven Rostedt Cc: Yoshihiro YUNOMAE , Aaron Fabbri , linux-kernel@vger.kernel.org, cti.systems-productivity-manager.ts@hitachi.com, Divya Vyas , Hidehiro Kawai , yoshihiro.yunomae@aktsk.jp Date: Tue, 26 May 2015 15:55:34 +0900 Message-ID: <20150526065534.16023.11228.stgit@localhost.localdomain> In-Reply-To: <20150526065522.16023.30813.stgit@localhost.localdomain> References: <20150526065522.16023.30813.stgit@localhost.localdomain> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Brightmail-Tracker: AAAAAA== Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 12103 Lines: 389 From: Yoshihiro YUNOMAE Add --dom option which makes a domain directory to virt-server. When a user already knows domain name of a guest before running virt-server, trace-cmd should automatically set up I/Fs of the guest. By adding --dom option, trace-cmd creates a domain directory with 0710 and qemu group. This patch adds additional options for --dom as follows: -m This option changes the permission of domain directory. If you don't use this option, the default permission is 0710. -g This option changes group of domain directory. If you don't use this option, the default group is qemu. -c This option creates trace data I/Fs(trace-path-cpu*.{in,out}) for each CPU of 'domain'. If you don't use this option, those files are not created. Here, an example you use this option is written as follows: - trace-cmd creates a guest1 directory with trace data I/Fs of 2 CPUs. # trace-cmd virt-server --dom guest1 -c 2 - trace-cmd creates guest2 and guest3 directories # trace-cmd virt-server --dom guest2 -c 3 --dom guest3 -c 1 Signed-off-by: Yoshihiro YUNOMAE Signed-off-by: Masami Hiramatsu --- Changes in V5: Update document. Changes in V4: Introduce parse_args_virt() Add usage of virt-server in trace-usage.c --- Documentation/trace-cmd-virt-server.1.txt | 58 ++++++++--- trace-listen.c | 151 ++++++++++++++++++++++++++--- trace-usage.c | 5 + 3 files changed, 179 insertions(+), 35 deletions(-) diff --git a/Documentation/trace-cmd-virt-server.1.txt b/Documentation/trace-cmd-virt-server.1.txt index b775745..19f2b23 100644 --- a/Documentation/trace-cmd-virt-server.1.txt +++ b/Documentation/trace-cmd-virt-server.1.txt @@ -34,40 +34,64 @@ OPTIONS *-l* 'filename':: This option writes the output messages to a log file instead of standard output. +*--dom* 'domain':: + This option makes a directory for the 'domain'. You can use additional options + *-m*, *-g*, *-c* after this option for the 'domain'. If you don't use these + additional options, the directory is made as 0710 and qemu group and + trace data I/Fs(trace-path-cpu*.{in,out}) are not created. + +*-m* 'permission':: + This option changes the permission of 'domain' directory. If you don't use + this option, the default permission is 0710. + +*-g* 'group':: + This option changes group of 'domain' directory. If you don't use this option, + the default group is qemu. + +*-c* 'cpu':: + This option creates trace data I/Fs(trace-path-cpu*.{in,out}) for each CPU + of 'domain'. If you don't use this option, those files are not created. + SETTING ------- Here, an example is written as follows: -1. Run virt-server on a host - # trace-cmd virt-server - -2. Make guest domain directory - # mkdir -p /tmp/trace-cmd/virt/ - # chmod 710 /tmp/trace-cmd/virt/ - # chgrp qemu /tmp/trace-cmd/virt/ - -3. Make FIFO on the host - # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} +1. Run virt-server with initializing guest interfaces on a host + # trace-cmd virt-server --dom "GUEST" -c 2 -4. Set up of virtio-serial pipe of a guest on the host +2. Set up of virtio-serial pipe of GUEST on the host Add the following tags to domain XML files. - # virsh edit + # virsh edit "GUEST" - + - ... (cpu1, cpu2, ...) + + + + -5. Boot the guest - # virsh start +3. Boot the guest + # virsh start "GUEST" -6. Run the guest's client(see trace-cmd-record(1) with the *--virt* option) +4. Run the guest1's client(see trace-cmd-record(1) with the *--virt* option) # trace-cmd record -e sched* --virt +If you want to boot another guest sends trace-data via virtio-serial, +you will manually make the guest domain directory and trace data I/Fs. + +- Make guest domain directory on the host + # mkdir -p /tmp/trace-cmd/virt/ + # chmod 710 /tmp/trace-cmd/virt/ + # chgrp qemu /tmp/trace-cmd/virt/ + +- Make FIFO on the host + # mkfifo /tmp/trace-cmd/virt//trace-path-cpu{0,1,...,X}.{in,out} + SEE ALSO -------- trace-cmd(1), trace-cmd-record(1), trace-cmd-report(1), trace-cmd-start(1), diff --git a/trace-listen.c b/trace-listen.c index 718680f..f6d53d2 100644 --- a/trace-listen.c +++ b/trace-listen.c @@ -54,11 +54,21 @@ static int backlog = 5; static int proto_ver; +struct domain_dir { + struct domain_dir *next; + char *name; + char *group; + mode_t perms; + int cpu; +}; + enum { NET = 1, VIRT = 2, }; +struct domain_dir *dom_dir_list; + #define TEMP_FILE_STR_NET "%s.%s:%s.cpu%d", output_file, host, port, cpu #define TEMP_FILE_STR_VIRT "%s.%s:%d.cpu%d", output_file, domain, virtpid, cpu static char *get_temp_file(const char *host, const char *port, @@ -382,7 +392,9 @@ static int open_udp(const char *node, const char *port, int *pid, #define TRACE_CMD_DIR "/tmp/trace-cmd/" #define VIRT_DIR TRACE_CMD_DIR "virt/" #define VIRT_TRACE_CTL_SOCK VIRT_DIR "agent-ctl-path" -#define TRACE_PATH_DOMAIN_CPU VIRT_DIR "%s/trace-path-cpu%d.out" +#define VIRT_DOMAIN_DIR VIRT_DIR "%s/" +#define TRACE_PATH_DOMAIN_CPU_O VIRT_DOMAIN_DIR "trace-path-cpu%d.out" +#define TRACE_PATH_DOMAIN_CPU_I VIRT_DOMAIN_DIR "trace-path-cpu%d.in" static int open_virtio_serial_pipe(int *pid, int cpu, int pagesize, const char *domain, int virtpid) @@ -390,7 +402,7 @@ static int open_virtio_serial_pipe(int *pid, int cpu, int pagesize, char buf[PATH_MAX]; int fd; - snprintf(buf, PATH_MAX, TRACE_PATH_DOMAIN_CPU, domain, cpu); + snprintf(buf, PATH_MAX, TRACE_PATH_DOMAIN_CPU_O, domain, cpu); fd = open(buf, O_RDONLY | O_NONBLOCK); if (fd < 0) { warning("open %s", buf); @@ -998,27 +1010,89 @@ static void do_listen_net(char *port) kill_clients(); } -static void make_virt_if_dir(void) +#define for_each_domain(i) for (i = dom_dir_list; i; i = (i)->next) + +static void make_dir_virt(const char *path, mode_t perms, const char *gr_name) { struct group *group; - if (mkdir(TRACE_CMD_DIR, 0710) < 0) { + if (mkdir(path, perms) < 0) { if (errno != EEXIST) - pdie("mkdir %s", TRACE_CMD_DIR); + pdie("mkdir %s", path); } - /* QEMU operates as qemu:qemu */ - chmod(TRACE_CMD_DIR, 0710); - group = getgrnam("qemu"); - if (chown(TRACE_CMD_DIR, -1, group->gr_gid) < 0) - pdie("chown %s", TRACE_CMD_DIR); + chmod(path, perms); - if (mkdir(VIRT_DIR, 0710) < 0) { - if (errno != EEXIST) - pdie("mkdir %s", VIRT_DIR); + group = getgrnam(gr_name); + if (!group) + pdie("getgrnam %s", gr_name); + if (chown(path, -1, group->gr_gid) < 0) + pdie("chown %s", path); +} + +static void make_traceif_in_dom_dir(const char *name, int cpu) +{ + char fifo_in[PATH_MAX]; + char fifo_out[PATH_MAX]; + int i; + + for (i = 0; i < cpu; i++) { + snprintf(fifo_in, PATH_MAX, TRACE_PATH_DOMAIN_CPU_I, name, i); + snprintf(fifo_out, PATH_MAX, TRACE_PATH_DOMAIN_CPU_O, name, i); + if (mkfifo(fifo_in, 0644) < 0) { + if (errno != EEXIST) + pdie("mkfifo %s", fifo_in); + } + if (mkfifo(fifo_out, 0644) < 0) { + if (errno != EEXIST) + pdie("mkfifo %s", fifo_out); + } } - chmod(VIRT_DIR, 0710); - if (chown(VIRT_DIR, -1, group->gr_gid) < 0) - pdie("chown %s", VIRT_DIR); + plog("CPUS: %d\n", cpu); +} + +static void make_domain_dirs(void) +{ + struct domain_dir *dom_dir; + char gr_name[5] = "qemu"; + char buf[PATH_MAX]; + mode_t perms; + + for_each_domain(dom_dir) { + snprintf(buf, PATH_MAX, VIRT_DOMAIN_DIR, dom_dir->name); + + if (dom_dir->perms) + perms = dom_dir->perms; + else + perms = 0710; + + if (dom_dir->group) + make_dir_virt(buf, perms, dom_dir->group); + else + make_dir_virt(buf, perms, gr_name); + + plog("---\n" + "Process Directory: %s\n" + "Directory permission: %o\n" + "Group: %s\n", buf, perms, dom_dir->group ? dom_dir->group : gr_name); + + if (dom_dir->cpu) + make_traceif_in_dom_dir(dom_dir->name, dom_dir->cpu); + } + + plog("---\n"); + free(dom_dir_list); +} + +static void make_virt_if_dir(void) +{ + char gr_name[5] = "qemu"; + + /* QEMU operates as qemu:qemu */ + make_dir_virt(TRACE_CMD_DIR, 0710, gr_name); + make_dir_virt(VIRT_DIR, 0710, gr_name); + + if (dom_dir_list) + make_domain_dirs(); } static void do_listen_virt(void) @@ -1060,7 +1134,14 @@ static void start_daemon(void) die("starting daemon"); } +static void add_dom_dir(struct domain_dir *dom_dir) +{ + dom_dir->next = dom_dir_list; + dom_dir_list = dom_dir; +} + enum { + OPT_dom = 254, OPT_debug = 255, }; @@ -1075,6 +1156,37 @@ static void parse_args_net(int c, char **argv, char **port) } } +static void parse_args_virt(int c, char **argv) +{ + static struct domain_dir *dom_dir; + + switch (c) { + case 'm': + if (!dom_dir) + die("-m needs --dom "); + dom_dir->perms = strtol(optarg, NULL, 8); + break; + case 'g': + if (!dom_dir) + die("-g needs --dom "); + dom_dir->group = optarg; + break; + case 'c': + if (!dom_dir) + die("-c needs --dom "); + dom_dir->cpu = atoi(optarg); + break; + case OPT_dom: + dom_dir = malloc_or_die(sizeof(*dom_dir)); + memset(dom_dir, 0, sizeof(*dom_dir)); + dom_dir->name = optarg; + add_dom_dir(dom_dir); + break; + default: + usage(argv); + } +} + void trace_listen(int argc, char **argv) { char *logfile = NULL; @@ -1097,12 +1209,13 @@ void trace_listen(int argc, char **argv) int option_index = 0; static struct option long_options[] = { {"port", required_argument, NULL, 'p'}, + {"dom", required_argument, NULL, OPT_dom}, {"help", no_argument, NULL, '?'}, {"debug", no_argument, NULL, OPT_debug}, {NULL, 0, NULL, 0} }; - c = getopt_long (argc-1, argv+1, "+hp:o:d:l:D", + c = getopt_long (argc-1, argv+1, "+hp:o:d:l:Dm:g:c:", long_options, &option_index); if (c == -1) break; @@ -1128,12 +1241,14 @@ void trace_listen(int argc, char **argv) default: if (mode == NET) parse_args_net(c, argv, &port); + else if (mode == VIRT) + parse_args_virt(c, argv); else usage(argv); } } - if (!port && mode == NET) + if (!port && (mode == NET)) usage(argv); if ((argc - optind) >= 2) diff --git a/trace-usage.c b/trace-usage.c index 23cb124..caba1f9 100644 --- a/trace-usage.c +++ b/trace-usage.c @@ -216,11 +216,16 @@ static struct usage_help usage_help[] = { "virt-server", "listen on a virtio-serial for trace clients", " %s virt-server [-o file][-d dir][-l logfile]\n" + " [--dom domain [-m permisson] [-g group] [-c cpu]]\n" " Creates a socket to listen for clients.\n" " -D create it in daemon mode.\n" " -o file name to use for clients.\n" " -d diretory to store client files.\n" " -l logfile to write messages to.\n" + " --dom create domain direcroty in /tmp/trace-cmd/virt and folling directory permissions/group names and FIFO files will be changed here\n" + " -m changes the permission of domain directory.\n" + " -g changes group of domain directory.\n" + " -c creates trace data I/F(trace-path-cpu*.{in, out} files) in domain directory.\n" }, { "list", -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/