Dear Dave, could you please update vz.c extension on your site. New version supports RHEL7-based Vz7 kernels. Thank you, Vasily Averin On 30.04.2015 18:57, Dave Anderson wrote: > > > ----- Original Message ----- >> On 30.04.2015 18:02, Dave Anderson wrote: >>>> I've prepared vz crash extension with commands >>>> useful for troubleshooting of OpenVZ kernel crashes. >>>> >>>> Could you please review the patch and advise how it's better >>>> to distribute this extension. >>> >>> I no longer accept extension modules as part of the base >>> crash utility package. However, I do offer to host them >>> on the crash extension modules page that is available from >>> the main web site. Would you like me to post the module there? >> >> Yes, let's post current version on your crash extension modules page. >> >> However I could you please clarify, what should I do in case of code >> modification? >> >> As far as I understand listed extensions are not included in your repository >> and you are not maintain them. > > Correct. > >> Should I publish my extension module in some external repository, maintain it, >> and notify you about important changes via crash-utility mailing list? > > Whether you publish it somewhere externally is up to you. But for maintenance > purposes, simply post a patch, or send an updated copy of vz.c, to this list > and I'll plug it in. > > Here you go, either to the top of the extensions page, or directly to your module: > > http://people.redhat.com/anderson/extensions.html > http://people.redhat.com/anderson/extensions.html#VZ > > Thanks, > Dave > > >
/* vz.c - crash extension for OpenVZ containers * * Copyright (C) 2015 Vasily Averin * Copyright (C) 2015 Parallels IP Holdings GmbH. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. See the * GNU General Public License for more details. */ #include "defs.h" #define VZ_MEMBER_OFFSET_INIT(X,Y,Z) (vz_offset_table.X=MEMBER_OFFSET(Y,Z)) #define VZ_OFFSET(X) (OFFSET_verify(vz_offset_table.X, (char *)__FUNCTION__, __FILE__, __LINE__, #X)) #define VZ_INVALID_MEMBER(X) (vz_offset_table.X == INVALID_OFFSET) #define VZ_VALID_MEMBER(X) (vz_offset_table.X >= 0) #define VZ_INIT 0x1 struct vz_offset_table { long task_veinfo; long veinfo_ve; long task_ve; long ve_velist; long ve_veid; long ve_nsproxy; long nsproxy_pidns; long pidns_init; }; static struct vz_offset_table vz_offset_table = { 0 }; static int init_flags = 0; static int id_size; void vz_init(void); void vz_fini(void); static ulong ve_to_task(ulong ve) { ulong ns, pidns, task; readmem(ve + VZ_OFFSET(ve_nsproxy), KVADDR, &ns, sizeof(ulong), "ve_struct.ve_ns", FAULT_ON_ERROR); readmem(ns + VZ_OFFSET(nsproxy_pidns), KVADDR, &pidns, sizeof(ulong), "nsproxy.ve_pidns", FAULT_ON_ERROR); readmem(pidns + VZ_OFFSET(pidns_init), KVADDR, &task, sizeof(ulong), "pid_namespace.child_reaper", FAULT_ON_ERROR); return task; } #define VZLIST_HEADER \ " CTID VE_STRUCT TASK PID COMM\n" static void show_container(ulong ve, ulong ctid, ulong flag) { ulong task; struct task_context *tc; task = ve_to_task(ve); tc = task_to_context(task); if (!(flag & PS_NO_HEADER)) fprintf(fp, VZLIST_HEADER); fprintf(fp, "%9ld %16lx %16lx %6ld %s\n", ctid, ve, tc->task, tc->pid, tc->comm); return; } static void show_containers(ulong ctid) { struct list_data list_data, *ld; ulong ve, id, flag = 0; int i, cnt; ld = &list_data; BZERO(ld, sizeof(struct list_data)); ld->flags |= LIST_ALLOCATE; ld->start = ld->end = symbol_value("ve_list_head"); ld->list_head_offset = 0; cnt = do_list(ld); for (i = 1; i < cnt; i++) { id = 0; ve = ld->list_ptr[i] - VZ_OFFSET(ve_velist); readmem(ve + VZ_OFFSET(ve_veid), KVADDR, &id, id_size, "ve_struct.veid", FAULT_ON_ERROR); if ((ctid == -1) || ctid == id) { show_container(ve, id, flag); flag = PS_NO_HEADER; } } return; } void cmd_vzlist(void) { int c; ulong ctid = -1; while ((c = getopt(argcnt, args, "E:")) != EOF) { switch(c) { case 'E': ctid = stol(optarg, FAULT_ON_ERROR, NULL); break; default: argerrs++; break; } } if (argerrs) { cmd_usage(pc->curcmd, SYNOPSIS); return; } show_containers(ctid); return; } char *help_vzlist[] = { "vzlist", "shows list of runnig OpenVZ containers", "[-E CTID]", "If no argument is entered, command shows IDs of all running containers\n", " -E Container ID", "\nEXAMPLES", "%s> vzlist", " CTID VE_STRUCT TASK PID COMM", " 121 ffff8801491e7000 ffff8801493d0ff0 95990 init", " 123 ffff880135a37000 ffff8803fb0a3470 95924 init", " 321 ffff88045a778000 ffff880400616300 95923 init", " 700 ffff88019ddae000 ffff88019ddd4fb0 95882 init", " 503 ffff88045a84e800 ffff8803c3c782c0 95902 init", " 122 ffff8804004ea000 ffff88045612afb0 95886 init", " 600 ffff88016e467000 ffff880459d653f0 95885 init", " 0 ffffffff81aaa220 ffff88045e530b30 1 init", NULL }; static ulong task_to_ctid(ulong task) { ulong veinfo, ve, ctid = 0; if (VZ_VALID_MEMBER(task_veinfo)) { veinfo = task + VZ_OFFSET(task_veinfo); readmem(veinfo + VZ_OFFSET(veinfo_ve), KVADDR, &ve, sizeof(ulong), "ve_task_info.exec_env", FAULT_ON_ERROR); } else if (VZ_VALID_MEMBER(task_ve)) { readmem(task + VZ_OFFSET(task_ve), KVADDR, &ve, sizeof(ulong), "task_struct.task_ve", FAULT_ON_ERROR); } else return 0; readmem(ve + VZ_OFFSET(ve_veid), KVADDR, &ctid, id_size, "ve_struct.veid", FAULT_ON_ERROR); return ctid; } static void show_ctid(struct task_context *tc, ulong flag) { ulong ctid; ctid = task_to_ctid(tc->task); if (!(flag & PS_NO_HEADER)) fprintf(fp, " CTID PID TASK COMM\n"); fprintf(fp, "%9ld %6ld %16lx %s\n", ctid, tc->pid, tc->task, tc->comm); return; } void cmd_ctid(void) { ulong value, flag = 0; struct task_context *tc; int c; while ((c = getopt(argcnt, args, "")) != EOF) { switch(c) { default: cmd_usage(pc->curcmd, SYNOPSIS); return; } } if (!args[optind]) { tc = task_to_context(CURRENT_TASK()); show_ctid(tc, flag); } while (args[optind]) { switch (str_to_context(args[optind], &value, &tc)) { case STR_PID: case STR_TASK: break; case STR_INVALID: error(INFO, "invalid task or pid value: %s\n", args[optind]); default: argerrs++; break; } if (argerrs) break; show_ctid(tc, flag); flag = PS_NO_HEADER; optind++; } if (argerrs) cmd_usage(pc->curcmd, SYNOPSIS); return; } char *help_ctid[] = { "ctid", "shows Container ID of given tasks", "[task|pid]", " If no argument is entered, command shows CTID of current task", "\nEXAMPLES", "%s> ctid 99583", " CTID PID TASK COMM", " 121 99583 ffff880203e56f30 httpd", NULL }; static void show_vzps(ulong ctid) { struct task_context *tc; ulong flag; int i; tc = FIRST_CONTEXT(); for (i = 0; i < RUNNING_TASKS(); i++, tc++) { ulong id = task_to_ctid(tc->task); if ((ctid == -1) || (ctid == id)) { show_ctid(tc, flag); flag = PS_NO_HEADER; } } return; } void cmd_vzps(void) { ulong ctid = -1; int c; while ((c = getopt(argcnt, args, "E:")) != EOF) { switch(c) { case 'E': ctid = stol(optarg, FAULT_ON_ERROR, NULL); break; default: argerrs++; break; } } if (argerrs) cmd_usage(pc->curcmd, SYNOPSIS); show_vzps(ctid); return; } char *help_vzps[] = { "vzps", "shows list of tasks related to specified CTID", " [ -E CTID]", " If no argument is entered, command shows CTID for all processes\n", "\nEXAMPLES", "%s> vzps -E 121", " CTID PID TASK COMM", " 121 95990 ffff8801493d0ff0 init", " 121 95996 ffff8803c3e3b0f0 kthreadd/121", " 121 95997 ffff8803cd3aacb0 khelper/121", " 121 97267 ffff880405e4b2f0 udevd", " 121 99341 ffff8803c3fd2440 syslogd", " 121 99404 ffff880405e0c2c0 klogd", " 121 99424 ffff8803fb0f68c0 sshd", " 121 99445 ffff8801493d0500 xinetd", " 121 99557 ffff8804599f9230 sendmail", " 121 99568 ffff8804591b00c0 sendmail", " 121 99583 ffff880203e56f30 httpd", " 121 99594 ffff88016e4e01c0 crond", " 121 99614 ffff8803fb26cf70 xfs", " 121 99624 ffff88045a6ce2c0 saslauthd", " 121 99625 ffff8801ce134ff0 saslauthd", " 121 248691 ffff88040e2ee9c0 httpd", NULL }; static struct command_table_entry command_table[] = { { "vzlist", cmd_vzlist, help_vzlist, 0}, { "ctid", cmd_ctid, help_ctid, 0}, { "vzps", cmd_vzps, help_vzps, 0}, { NULL }, }; void __attribute__((constructor)) vz_init(void) { if (init_flags & VZ_INIT) return; if (!symbol_exists("ve_list_head")) { fprintf(fp, "vz commands only work on OpenVZ kernels\n"); return; } init_flags |= VZ_INIT; BNEG(&vz_offset_table, sizeof(vz_offset_table)); if (STRUCT_EXISTS("ve_task_info")) { /* RHEL6-based OpenVZ */ VZ_MEMBER_OFFSET_INIT(task_veinfo, "task_struct", "ve_task_info"); VZ_MEMBER_OFFSET_INIT(veinfo_ve, "ve_task_info", "exec_env"); } else { /* RHEL7-based OpenVZ */ VZ_MEMBER_OFFSET_INIT(task_ve, "task_struct", "task_ve"); } if (STRUCT_EXISTS("ve_struct")) { VZ_MEMBER_OFFSET_INIT(ve_velist, "ve_struct", "ve_list"); VZ_MEMBER_OFFSET_INIT(ve_veid, "ve_struct", "veid"); VZ_MEMBER_OFFSET_INIT(ve_nsproxy, "ve_struct", "ve_ns"); id_size = MEMBER_SIZE("ve_struct", "veid"); } if (STRUCT_EXISTS("nsproxy")) { VZ_MEMBER_OFFSET_INIT(nsproxy_pidns, "nsproxy", "pid_ns"); } if (STRUCT_EXISTS("pid_namespace")) VZ_MEMBER_OFFSET_INIT(pidns_init, "pid_namespace", "child_reaper"); register_extension(command_table); } void __attribute__((destructor)) vz_fini(void) { }
-- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility