You can subscribe to this list here.
| 2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(32) |
Jun
(66) |
Jul
(102) |
Aug
(78) |
Sep
(106) |
Oct
(137) |
Nov
(147) |
Dec
(147) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2010 |
Jan
(71) |
Feb
(139) |
Mar
(86) |
Apr
(76) |
May
(57) |
Jun
(10) |
Jul
(12) |
Aug
(6) |
Sep
(8) |
Oct
(12) |
Nov
(12) |
Dec
(18) |
| 2011 |
Jan
(16) |
Feb
(19) |
Mar
(3) |
Apr
(1) |
May
(16) |
Jun
(17) |
Jul
(74) |
Aug
(22) |
Sep
(18) |
Oct
(24) |
Nov
(21) |
Dec
(30) |
| 2012 |
Jan
(31) |
Feb
(16) |
Mar
(22) |
Apr
(25) |
May
(18) |
Jun
(13) |
Jul
(83) |
Aug
(49) |
Sep
(20) |
Oct
(60) |
Nov
(35) |
Dec
(28) |
| 2013 |
Jan
(39) |
Feb
(61) |
Mar
(35) |
Apr
(21) |
May
(45) |
Jun
(56) |
Jul
(20) |
Aug
(9) |
Sep
(10) |
Oct
(31) |
Nov
(8) |
Dec
(4) |
| 2014 |
Jan
(6) |
Feb
(7) |
Mar
(7) |
Apr
(6) |
May
(4) |
Jun
(8) |
Jul
(5) |
Aug
(2) |
Sep
(4) |
Oct
(4) |
Nov
(11) |
Dec
(5) |
| 2015 |
Jan
(4) |
Feb
(4) |
Mar
(3) |
Apr
(4) |
May
(9) |
Jun
(4) |
Jul
(15) |
Aug
(8) |
Sep
(16) |
Oct
(18) |
Nov
(15) |
Dec
(7) |
| 2016 |
Jan
(20) |
Feb
(9) |
Mar
(15) |
Apr
(24) |
May
(16) |
Jun
(28) |
Jul
(22) |
Aug
(23) |
Sep
(18) |
Oct
(30) |
Nov
(40) |
Dec
(9) |
| 2017 |
Jan
(1) |
Feb
(8) |
Mar
(37) |
Apr
(26) |
May
(25) |
Jun
(46) |
Jul
(24) |
Aug
(9) |
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Seiji A. <sei...@hd...> - 2013-05-11 00:10:49
|
Any comments? > -----Original Message----- > From: Seiji Aguchi > Sent: Thursday, May 02, 2013 1:26 PM > To: lib...@re... > Cc: dle...@li...; Tomoki Sekiyama (tom...@hd...) > Subject: [PATCH] Introduce startupPolicy for chardev to make guest OS bootable when hardware failure happens in log disk > > [Problem] > Currently, guest OS's messages can be logged to a local disk of host OS > by creating chadevs with options below. > -chardev file,id=charserial0,path=<log file's path> -device isa-serial,chardev=chardevserial0,id=serial0 > > When a hardware failure happens in the disk, qemu-kvm can't create the chardevs. > In this case, guest OS doesn't boot up. > > Actually, there are users who don't desire that guest OS goes down due to a hardware failure > of a log disk only.Therefore, qemu should offer some way to boot guest OS up even if the log > disk is broken. > > [Solution] > This patch supports startupPolicy for chardev. > > The starupPolicy is introduced just in case where chardev is "file" > because this patch aims for making guest OS boot up when a hardware failure happens. > > In other cases ,pty, dev, pipe and unix, it is not introduced > because they don't access to hardware. > > The policy works as follows. > - If the value is "optional", guestOS boots up by dropping the chardev. > - If other values are specified, guestOS fails to boot up. (the default) > > Description about original startupPolicy attribute: > http://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=e5a84d74a2789a917bf394f15de9989ec48fded0 > > Signed-off-by: Seiji Aguchi <sei...@hd...> > --- > docs/formatdomain.html.in | 9 ++++++++- > docs/schemas/domaincommon.rng | 3 +++ > src/conf/domain_conf.c | 8 ++++++++ > src/conf/domain_conf.h | 1 + > src/qemu/qemu_process.c | 25 ++++++++++++++++++++++++- > tests/virt-aa-helper-test | 3 +++ > 6 files changed, 47 insertions(+), 2 deletions(-) > > diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in > index f325c3c..1e1bf27 100644 > --- a/docs/formatdomain.html.in > +++ b/docs/formatdomain.html.in > @@ -4044,13 +4044,20 @@ qemu-kvm -net nic,model=? /dev/null > <p> > A file is opened and all data sent to the character > device is written to the file. > + It is possible to define policy whether guestOS boots up > + if the file is not accessible. This is done by a startupPolicy > + attribute: > + <ul> > + <li>If the vaule is "optional", guestOS boots up by dropping the file.</li> > + <li>If other values are specified, guestOS fails to boot up. (the default)</li> > + </ul> > </p> > > <pre> > ... > <devices> > <serial type="file"> > - <source path="/var/log/vm/vm-serial.log"/> > + <source path="/var/log/vm/vm-serial.log" startupPolicy="optional"/> > <target port="1"/> > </serial> > </devices> > diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng > index 10596dc..6fc0a3c 100644 > --- a/docs/schemas/domaincommon.rng > +++ b/docs/schemas/domaincommon.rng > @@ -2706,6 +2706,9 @@ > </optional> > <optional> > <attribute name="path"/> > + <optional> > + <ref name='startupPolicy'/> > + </optional> > </optional> > <optional> > <attribute name="host"/> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c > index a8b5dfd..6680f15 100644 > --- a/src/conf/domain_conf.c > +++ b/src/conf/domain_conf.c > @@ -6467,6 +6467,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, > char *path = NULL; > char *mode = NULL; > char *protocol = NULL; > + char *startupPolicy = NULL; > int remaining = 0; > > while (cur != NULL) { > @@ -6487,6 +6488,9 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, > !(flags & VIR_DOMAIN_XML_INACTIVE))) > path = virXMLPropString(cur, "path"); > > + if (startupPolicy == NULL && > + def->type == VIR_DOMAIN_CHR_TYPE_FILE) > + startupPolicy = virXMLPropString(cur, "startupPolicy"); > break; > > case VIR_DOMAIN_CHR_TYPE_UDP: > @@ -6559,6 +6563,10 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, > > def->data.file.path = path; > path = NULL; > + > + def->data.file.startupPolicy = > + virDomainStartupPolicyTypeFromString(startupPolicy); > + startupPolicy = NULL; > break; > > case VIR_DOMAIN_CHR_TYPE_STDIO: > diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h > index 3a0f23a..e709951 100644 > --- a/src/conf/domain_conf.h > +++ b/src/conf/domain_conf.h > @@ -1052,6 +1052,7 @@ struct _virDomainChrSourceDef { > /* no <source> for null, vc, stdio */ > struct { > char *path; > + int startupPolicy; /* enum virDomainStartupPolicy */ > } file; /* pty, file, pipe, or device */ > struct { > char *host; > diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c > index e75c8c9..6e2f78e 100644 > --- a/src/qemu/qemu_process.c > +++ b/src/qemu/qemu_process.c > @@ -2442,7 +2442,30 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, > virReportSystemError(errno, > _("Unable to pre-create chardev file '%s'"), > dev->source.data.file.path); > - return -1; > + if (dev->source.data.file.startupPolicy != > + VIR_DOMAIN_STARTUP_POLICY_OPTIONAL) { > + return -1; > + } > + VIR_FREE(dev->source.data.file.path); > + /* > + * Change a destination to /dev/null to boot guest OS up > + * even if a log disk is broken. > + */ > + VIR_WARN("Switch the destination to /dev/null"); > + dev->source.data.file.path = strdup("/dev/null"); > + > + if (!(dev->source.data.file.path)) { > + virReportOOMError(); > + return -1; > + } > + > + if ((fd = open(dev->source.data.file.path, > + O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) { > + virReportSystemError(errno, > + _("Unable to pre-create chardev file '%s'"), > + dev->source.data.file.path); > + return -1; > + } > } > > VIR_FORCE_CLOSE(fd); > diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test > index af91c61..7172fd6 100755 > --- a/tests/virt-aa-helper-test > +++ b/tests/virt-aa-helper-test > @@ -255,6 +255,9 @@ testme "0" "disk (empty cdrom)" "-r -u $valid_uuid" "$test_xml" > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='file'><source > path='$tmpdir/serial.log'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > > +sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='file'><source path='$tmpdir/serial.log' > startupPolicy='optional'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > +testme "0" "serial" "-r -u $valid_uuid" "$test_xml" > + > sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='pty'><target > port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" > testme "0" "serial (pty)" "-r -u $valid_uuid" "$test_xml" > > -- > 1.7.1 |
|
From: Seiji A. <sei...@hd...> - 2013-05-10 20:45:53
|
The loop in efivar_update_sysfs_entries() reuses the same allocation for
entries each time it calls efivar_create_sysfs_entry(entry). This is
wrong because efivar_create_sysfs_entry() expects to keep the memory it
was passed, so the caller may not free it (and may not pass the same
memory in multiple times). This leads to the oops below. Fix by
getting a new allocation each time we go around the loop.
---[ end trace ba4907d5c519d111 ]---
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
PGD 0
Oops: 0000 [#2] SMP
Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F) video(F) dm_mirror(F) dm
_region_hash(F) dm_log(F) dm_mod(F)
CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
Workqueue: events efivar_update_sysfs_entries
task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
Call Trace:
[<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
[<ffffffff8125b6d2>] ? put_dec+0x72/0x90
[<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
[<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
[<ffffffff8103dd29>] ? efi_call2+0x9/0x70
[<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
[<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
[<ffffffff81430033>] efivar_init+0x2c3/0x380
[<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
[<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
[<ffffffff810605f3>] process_one_work+0x183/0x490
[<ffffffff81061780>] worker_thread+0x120/0x3a0
[<ffffffff81061660>] ? manage_workers+0x160/0x160
[<ffffffff8106752e>] kthread+0xce/0xe0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP <ffff88019413fa48>
CR2: 0000000000000000
---[ end trace ba4907d5c519d112 ]---
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
drivers/firmware/efi/efivars.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index b623c59..8bd1bb6 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
struct efivar_entry *entry;
int err;
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return;
-
/* Add new sysfs entries */
while (1) {
- memset(entry, 0, sizeof(*entry));
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
err = efivar_init(efivar_update_sysfs_entry, entry,
true, false, &efivar_sysfs_list);
-- 1.7.1
|
|
From: Seiji A. <sei...@hd...> - 2013-05-10 20:35:09
|
> the problem isn't anything to > do with memset, it's because we're not getting a new allocation each > time we call efivar_create_sysfs_entries(). I see. I agree with you. I will update my patch with your explanation below. Seiji > > --- > Subject: [PATCH] efivar: fix oops in efivar_update_sysfs_entries() caused by memory reuse > > The loop in efivar_update_sysfs_entries() reuses the same allocation for > entries each time it calls efivar_create_sysfs_entry(entry). This is > wrong because efivar_create_sysfs_entry() expects to keep the memory it > was passed, so the caller may not free it (and may not pass the same > memory in multiple times). This leads to the oops below. Fix by > getting a new allocation each time we go around the loop. > > [insert oops report here] > --- > > James > |
|
From: James B. <Jam...@Ha...> - 2013-05-10 20:25:01
|
I really think the description is wrong. the problem isn't anything to do with memset, it's because we're not getting a new allocation each time we call efivar_create_sysfs_entries(). How about this? --- Subject: [PATCH] efivar: fix oops in efivar_update_sysfs_entries() caused by memory reuse The loop in efivar_update_sysfs_entries() reuses the same allocation for entries each time it calls efivar_create_sysfs_entry(entry). This is wrong because efivar_create_sysfs_entry() expects to keep the memory it was passed, so the caller may not free it (and may not pass the same memory in multiple times). This leads to the oops below. Fix by getting a new allocation each time we go around the loop. [insert oops report here] --- James |
|
From: Seiji A. <sei...@hd...> - 2013-05-10 20:21:11
|
Changelog
v2 -> v3
- Change a patch title from "Move kzalloc() just before memset() to avoid initializing new sysfs entries"
to "Move kzalloc() inside while(1) to avoid initializing new sysfs entries"
v1 -> v2
- Remove unnecessary memset()
- Add a description the reason why we don't need to worry about a memory leak.
Problem
=======
When sysfs entries are updated by updated_sysfs_entries(),
they are mistakenly initialized by memset().
Then, it causes following oops.
---[ end trace ba4907d5c519d111 ]---
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
PGD 0
Oops: 0000 [#2] SMP
Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F) video(F) dm_mirror(F) dm
_region_hash(F) dm_log(F) dm_mod(F)
CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
Workqueue: events efivar_update_sysfs_entries
task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
Call Trace:
[<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
[<ffffffff8125b6d2>] ? put_dec+0x72/0x90
[<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
[<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
[<ffffffff8103dd29>] ? efi_call2+0x9/0x70
[<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
[<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
[<ffffffff81430033>] efivar_init+0x2c3/0x380
[<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
[<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
[<ffffffff810605f3>] process_one_work+0x183/0x490
[<ffffffff81061780>] worker_thread+0x120/0x3a0
[<ffffffff81061660>] ? manage_workers+0x160/0x160
[<ffffffff8106752e>] kthread+0xce/0xe0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP <ffff88019413fa48>
CR2: 0000000000000000
---[ end trace ba4907d5c519d112 ]---
Patch description
=============
This patch moves kzalloc() inside while(1) to avoid initializing new sysfs entries wrongly.
Also, it removes memset() because it is already initialized in kzalloc().
With this patch, kzalloc() is called in an infinite loop, but a memory leak never happens
for these reasons.
- in case where a new sysfs entry is created, it is consumed in create_sysfs_entry().
- in case where a new sysfs entry is not created, it is freed by kfree() outside the infinite loop.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
drivers/firmware/efi/efivars.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index b623c59..8bd1bb6 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
struct efivar_entry *entry;
int err;
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return;
-
/* Add new sysfs entries */
while (1) {
- memset(entry, 0, sizeof(*entry));
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
err = efivar_init(efivar_update_sysfs_entry, entry,
true, false, &efivar_sysfs_list);
-- 1.7.1
|
|
From: Seiji A. <sei...@hd...> - 2013-05-10 20:11:36
|
The patch title is wrong because memset() is not called with this patch.
I will resend by changing the title shortly.
> -----Original Message-----
> From: lin...@vg... [mailto:lin...@vg...] On Behalf Of Seiji Aguchi
> Sent: Friday, May 10, 2013 4:10 PM
> To: lin...@vg...; mat...@in...; Jam...@Ha...
> Cc: dle...@li...; Tomoki Sekiyama
> Subject: [PATCH v2]Move kzalloc() just before memset() to avoid initializing new sysfs entries
>
> Changelog
> v1 -> v2
> - Remove unnecessary memset()
> - Add a description the reason why we don't need to worry about a memory leak.
>
> Problem
> =======
>
> When sysfs entries are updated by updated_sysfs_entries(),
> they are mistakenly initialized by memset().
> Then, it causes following oops.
>
> ---[ end trace ba4907d5c519d111 ]---
> BUG: unable to handle kernel NULL pointer dereference at (null)
> IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
> PGD 0
> Oops: 0000 [#2] SMP
> Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc
> cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6
> nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt
> iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel
> ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich
> mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq
> snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F)
> crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F)
> video(F) dm_mirror(F) dm
>
> _region_hash(F) dm_log(F) dm_mod(F)
> CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
> Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
> Workqueue: events efivar_update_sysfs_entries
> task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
> RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
> RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
> RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
> RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
> RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
> R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
> R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
> FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Stack:
> ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
> ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
> 00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
> Call Trace:
> [<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
> [<ffffffff8125b6d2>] ? put_dec+0x72/0x90
> [<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
> [<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
> [<ffffffff8103dd29>] ? efi_call2+0x9/0x70
> [<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
> [<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
> [<ffffffff81430033>] efivar_init+0x2c3/0x380
> [<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
> [<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
> [<ffffffff810605f3>] process_one_work+0x183/0x490
> [<ffffffff81061780>] worker_thread+0x120/0x3a0
> [<ffffffff81061660>] ? manage_workers+0x160/0x160
> [<ffffffff8106752e>] kthread+0xce/0xe0
> [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
> [<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
> [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
> Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b
> 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
> RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
> RSP <ffff88019413fa48>
> CR2: 0000000000000000
> ---[ end trace ba4907d5c519d112 ]---
>
> Patch description
> =============
>
> This patch moves kzalloc() inside while(1) to avoid initializing new sysfs entries wrongly.
> Also, it removes memset() because it is already initialized in kzalloc().
>
> With this patch, kzalloc() is called in an infinite loop, but a memory leak never happens
> for these reasons.
> - in case where a new sysfs entry is created, it is consumed in create_sysfs_entry().
> - in case where a new sysfs entry is not created, it is freed by kfree() outside the infinite loop.
>
> Signed-off-by: Seiji Aguchi <sei...@hd...>
> ---
> drivers/firmware/efi/efivars.c | 8 +++-----
> 1 files changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
> index b623c59..8bd1bb6 100644
> --- a/drivers/firmware/efi/efivars.c
> +++ b/drivers/firmware/efi/efivars.c
> @@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
> struct efivar_entry *entry;
> int err;
>
> - entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> - if (!entry)
> - return;
> -
> /* Add new sysfs entries */
> while (1) {
> - memset(entry, 0, sizeof(*entry));
> + entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> + if (!entry)
> + return;
>
> err = efivar_init(efivar_update_sysfs_entry, entry,
> true, false, &efivar_sysfs_list);
> -- 1.7.1
> --
> To unsubscribe from this list: send the line "unsubscribe linux-efi" in
> the body of a message to maj...@vg...
> More majordomo info at http://vger.kernel.org/majordomo-info.html
|
|
From: Seiji A. <sei...@hd...> - 2013-05-10 20:09:49
|
Changelog
v1 -> v2
- Remove unnecessary memset()
- Add a description the reason why we don't need to worry about a memory leak.
Problem
=======
When sysfs entries are updated by updated_sysfs_entries(),
they are mistakenly initialized by memset().
Then, it causes following oops.
---[ end trace ba4907d5c519d111 ]---
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
PGD 0
Oops: 0000 [#2] SMP
Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F) video(F) dm_mirror(F) dm
_region_hash(F) dm_log(F) dm_mod(F)
CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
Workqueue: events efivar_update_sysfs_entries
task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
Call Trace:
[<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
[<ffffffff8125b6d2>] ? put_dec+0x72/0x90
[<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
[<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
[<ffffffff8103dd29>] ? efi_call2+0x9/0x70
[<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
[<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
[<ffffffff81430033>] efivar_init+0x2c3/0x380
[<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
[<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
[<ffffffff810605f3>] process_one_work+0x183/0x490
[<ffffffff81061780>] worker_thread+0x120/0x3a0
[<ffffffff81061660>] ? manage_workers+0x160/0x160
[<ffffffff8106752e>] kthread+0xce/0xe0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP <ffff88019413fa48>
CR2: 0000000000000000
---[ end trace ba4907d5c519d112 ]---
Patch description
=============
This patch moves kzalloc() inside while(1) to avoid initializing new sysfs entries wrongly.
Also, it removes memset() because it is already initialized in kzalloc().
With this patch, kzalloc() is called in an infinite loop, but a memory leak never happens
for these reasons.
- in case where a new sysfs entry is created, it is consumed in create_sysfs_entry().
- in case where a new sysfs entry is not created, it is freed by kfree() outside the infinite loop.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
drivers/firmware/efi/efivars.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index b623c59..8bd1bb6 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -523,13 +523,11 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
struct efivar_entry *entry;
int err;
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return;
-
/* Add new sysfs entries */
while (1) {
- memset(entry, 0, sizeof(*entry));
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
err = efivar_init(efivar_update_sysfs_entry, entry,
true, false, &efivar_sysfs_list);
-- 1.7.1
|
|
From: Seiji A. <sei...@hd...> - 2013-05-10 19:35:38
|
> -----Original Message----- > From: James Bottomley [mailto:Jam...@Ha...] > Sent: Friday, May 10, 2013 3:32 PM > To: Seiji Aguchi > Cc: lin...@vg...; mat...@in...; dle...@li...; Tomoki Sekiyama > Subject: Re: [PATCH]Move kzalloc() just before memset() to avoid initializing new sysfs entries wrongly > > On Fri, 2013-05-10 at 19:10 +0000, Seiji Aguchi wrote: > > > This is manifestly wrong: it would leak memory as it circulates around > > > the loop. > > > > I don't think the memory leak happens. > > As you can see below, if a new entry is not created, kfree() is called outside while(1). > > Ah, I see, entry is consumed by efivar_create_sysfs_entry(entry)? Yes. > In that case, saying so in the change log would be helpful plus remove the > memset, which is what implied in the old code that the loop didn't > consume entry and which is rendered superfluous by the kzalloc. OK. I will update my patch. Thank you for reviewing! Seiji |
|
From: James B. <Jam...@Ha...> - 2013-05-10 19:32:03
|
On Fri, 2013-05-10 at 19:10 +0000, Seiji Aguchi wrote: > > This is manifestly wrong: it would leak memory as it circulates around > > the loop. > > I don't think the memory leak happens. > As you can see below, if a new entry is not created, kfree() is called outside while(1). Ah, I see, entry is consumed by efivar_create_sysfs_entry(entry)? In that case, saying so in the change log would be helpful plus remove the memset, which is what implied in the old code that the loop didn't consume entry and which is rendered superfluous by the kzalloc. James |
|
From: Seiji A. <sei...@hd...> - 2013-05-10 19:10:55
|
> This is manifestly wrong: it would leak memory as it circulates around
> the loop.
I don't think the memory leak happens.
As you can see below, if a new entry is not created, kfree() is called outside while(1).
static void efivar_update_sysfs_entries(struct work_struct *work)
{
struct efivar_entry *entry;
int err;
/* Add new sysfs entries */
while (1) {
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry)
return;
memset(entry, 0, sizeof(*entry));
err = efivar_init(efivar_update_sysfs_entry, entry,
true, false, &efivar_sysfs_list);
if (!err)
break;
efivar_create_sysfs_entry(entry);
}
kfree(entry);
}
|
|
From: James B. <Jam...@Ha...> - 2013-05-10 19:04:49
|
On Fri, 2013-05-10 at 18:46 +0000, Seiji Aguchi wrote:
> When sysfs entries are updated by updated_sysfs_entries(),
> they are mistakenly initialized by memset().
> Then, it causes following oops.
>
> ---[ end trace ba4907d5c519d111 ]---
> BUG: unable to handle kernel NULL pointer dereference at (null)
> IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
> PGD 0
> Oops: 0000 [#2] SMP
> Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F) video(F) dm_mirror(F) d
> m
> _region_hash(F) dm_log(F) dm_mod(F)
> CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
> Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
> Workqueue: events efivar_update_sysfs_entries
> task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
> RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
This shows the oops was in efivar_entry_find ... that's nothing to do
with the entries variable, it means something went wrong with the
arguments to that function in efivar_update_sysfs_entry(). Entries is
only touched if that function returns zero. Could you dig a little
deeper and find out what the arguments are that cause the oops?
> RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
> RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
> RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
> RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
> R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
> R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
> FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
> DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> Stack:
> ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
> ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
> 00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
> Call Trace:
> [<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
> [<ffffffff8125b6d2>] ? put_dec+0x72/0x90
> [<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
> [<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
> [<ffffffff8103dd29>] ? efi_call2+0x9/0x70
> [<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
> [<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
> [<ffffffff81430033>] efivar_init+0x2c3/0x380
> [<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
> [<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
> [<ffffffff810605f3>] process_one_work+0x183/0x490
> [<ffffffff81061780>] worker_thread+0x120/0x3a0
> [<ffffffff81061660>] ? manage_workers+0x160/0x160
> [<ffffffff8106752e>] kthread+0xce/0xe0
> [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
> [<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
> [<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
> Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
> RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
> RSP <ffff88019413fa48>
> CR2: 0000000000000000
> ---[ end trace ba4907d5c519d112 ]---
>
> This patch moves kzalloc() just before memset() to avoid initializing new sysfs entries wrongly.
>
> Signed-off-by: Seiji Aguchi <sei...@hd...>
> ---
> drivers/firmware/efi/efivars.c | 8 ++++----
> 1 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
> index b623c59..cf91ca1 100644
> --- a/drivers/firmware/efi/efivars.c
> +++ b/drivers/firmware/efi/efivars.c
> @@ -523,12 +523,12 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
> struct efivar_entry *entry;
> int err;
>
> - entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> - if (!entry)
> - return;
> -
> /* Add new sysfs entries */
> while (1) {
> + entry = kzalloc(sizeof(*entry), GFP_KERNEL);
> + if (!entry)
> + return;
> +
This is manifestly wrong: it would leak memory as it circulates around
the loop.
James
|
|
From: Seiji A. <sei...@hd...> - 2013-05-10 18:47:03
|
When sysfs entries are updated by updated_sysfs_entries(),
they are mistakenly initialized by memset().
Then, it causes following oops.
---[ end trace ba4907d5c519d111 ]---
BUG: unable to handle kernel NULL pointer dereference at (null)
IP: [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
PGD 0
Oops: 0000 [#2] SMP
Modules linked in: oops(OF+) ebtable_nat ebtables xt_CHECKSUM iptable_mangle bridge autofs4 sunrpc 8021q garp stp llc cpufreq_ondemand ipt_REJECT nf_conntrack_ipv4 nf_defrag_ipv4 iptable_filter ip_tables ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 xt_state nf_conntrack ip6table_filter ip6_tables ipv6 vfat fat vhost_net macvtap macvlan tun uinput iTCO_wdt iTCO_vendor_support acpi_cpufreq freq_table mperf coretemp kvm_intel kvm crc32c_intel arc4 ghash_clmulni_intel aesni_intel ablk_helper iwldvm cryptd lrw gf128mul glue_helper aes_x86_64 microcode mac80211 sg thinkpad_acpi pcspkr i2c_i801 lpc_ich mfd_core iwlwifi cfg80211 rfkill snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm snd_timer snd soundcore snd_page_alloc e1000e ptp pps_core wmi ext4(F) jbd2(F) mbcache(F) sd_mod(F) crc_t10dif(F) ahci(F) libahci(F) sdhci_pci(F) sdhci(F) mmc_core(F) i915(F) drm_kms_helper(F) drm(F) i2c_algo_bit(F) i2c_core(F) video(F) dm_mirror(F) dm
_region_hash(F) dm_log(F) dm_mod(F)
CPU: 0 PID: 301 Comm: kworker/0:2 Tainted: GF D O 3.9.0+ #1
Hardware name: LENOVO 4291EV7/4291EV7, BIOS 8DET52WW (1.22 ) 09/15/2011
Workqueue: events efivar_update_sysfs_entries
task: ffff8801955920c0 ti: ffff88019413e000 task.ti: ffff88019413e000
RIP: 0010:[<ffffffff8142f81f>] [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP: 0018:ffff88019413fa48 EFLAGS: 00010006
RAX: 0000000000000000 RBX: ffff880195d87c00 RCX: ffffffff81ab6f60
RDX: ffff88019413fb88 RSI: 0000000000000400 RDI: ffff880196254000
RBP: ffff88019413fbd8 R08: 0000000000000000 R09: ffff8800dad99037
R10: ffff880195d87c00 R11: 0000000000000430 R12: ffffffff81ab6f60
R13: fffffffffffff7d8 R14: ffff880196254000 R15: 0000000000000000
FS: 0000000000000000(0000) GS:ffff88019e200000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000001a0b000 CR4: 00000000000407f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Stack:
ffff88019413fb78 ffff88019413fb88 ffffffff81e85d60 03000000972b5c00
ffff88019413fa29 ffffffff81e85d60 ffff88019413fbfb 0000000197087280
00000000000000fe 0000000000000001 ffffffff81e85dd9 ffff880197087280
Call Trace:
[<ffffffff81254371>] ? idr_get_empty_slot+0x131/0x240
[<ffffffff8125b6d2>] ? put_dec+0x72/0x90
[<ffffffff81158e40>] ? cache_alloc_refill+0x170/0x2f0
[<ffffffff81430420>] efivar_update_sysfs_entry+0x150/0x220
[<ffffffff8103dd29>] ? efi_call2+0x9/0x70
[<ffffffff8103d787>] ? virt_efi_get_next_variable+0x47/0x1b0
[<ffffffff8115a8df>] ? kmem_cache_alloc_trace+0x1af/0x1c0
[<ffffffff81430033>] efivar_init+0x2c3/0x380
[<ffffffff814302d0>] ? efivar_delete+0xd0/0xd0
[<ffffffff8143111f>] efivar_update_sysfs_entries+0x6f/0x90
[<ffffffff810605f3>] process_one_work+0x183/0x490
[<ffffffff81061780>] worker_thread+0x120/0x3a0
[<ffffffff81061660>] ? manage_workers+0x160/0x160
[<ffffffff8106752e>] kthread+0xce/0xe0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
[<ffffffff81543c5c>] ret_from_fork+0x7c/0xb0
[<ffffffff81067460>] ? kthread_freezable_should_stop+0x70/0x70
Code: 8d 55 b0 48 8d 45 a0 49 81 ed 28 08 00 00 48 89 95 78 fe ff ff 48 89 85 70 fe ff ff eb 27 66 0f 1f 44 00 00 4d 8d bd 28 08 00 00 <49> 8b 85 28 08 00 00 4d 39 e7 0f 84 21 01 00 00 4d 89 ee 4c 8d
RIP [<ffffffff8142f81f>] efivar_entry_find+0x14f/0x2d0
RSP <ffff88019413fa48>
CR2: 0000000000000000
---[ end trace ba4907d5c519d112 ]---
This patch moves kzalloc() just before memset() to avoid initializing new sysfs entries wrongly.
Signed-off-by: Seiji Aguchi <sei...@hd...>
---
drivers/firmware/efi/efivars.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c
index b623c59..cf91ca1 100644
--- a/drivers/firmware/efi/efivars.c
+++ b/drivers/firmware/efi/efivars.c
@@ -523,12 +523,12 @@ static void efivar_update_sysfs_entries(struct work_struct *work)
struct efivar_entry *entry;
int err;
- entry = kzalloc(sizeof(*entry), GFP_KERNEL);
- if (!entry)
- return;
-
/* Add new sysfs entries */
while (1) {
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (!entry)
+ return;
+
memset(entry, 0, sizeof(*entry));
err = efivar_init(efivar_update_sysfs_entry, entry,
-- 1.7.1
|
|
From: <new...@mi...> - 2013-05-09 14:41:31
|
Untitled Document
A:LINK { color: #0066CC; text-decoration: none}
A:VISITED { color: #0066CC; text-decoration: none}
A:HOVER { color: #5090FC; text-decoration: none}
A:ACTIVE { color: #5090FC; text-decoration: none}
BODY {
COLOR: #303a47;
BACKGROUND: #FFFFFF;
scrollbar-base-color: #F0F0F0;
scrollbar-track-color: #F0F0F0;
scrollbar-face-color: #CDCDCD;
scrollbar-highlight-color: #FFFFFF;
scrollbar-3dlight-color: #CDCDCD;
scrollbar-darkshadow-color: #CDCDCD;
scrollbar-shadow-color: #FFFFFF;
scrollbar-arrow-color: #2C5A88;
font-family:Arial, Helvetica, sans-serif;
}
Dear Customer
We now organize a $400 worth giveaway and provide 10 licenses for Audio Dedupe PRO. Entering this giveaway takes only few seconds and does not require filling endless surveys or purchasing any products. You can enter this giveaway here:
Audio Dedupe Music Manager $400 Giveaway – Organize Music Libraries, Remove Duplicate Songs and Find Similar Audio Files
Audio Dedupe is an innovative tool that "Listens" to your audio files in order to find similar or duplicate items.
Do not forget to visit www.mindgems.com and check our award-winning and FREE tools.
Please press the SHARE buttons below (or the ones at the top-left corner of our web site) to share MindGems on your favorite social network. This will help us to provide more free products and frequent updates. Thank you! Stay tuned for giveaways and discounts. We will notify you by e-mail for upcoming events or you can subscribe to our RSS Feed.
Best regards Allan Cass MindGems Inc. Webmaster www.mindgems.com
CONFIDENTIALITY NOTICE: E-mail documents sent by Mindgems Inc. are intended for, and should only be read by, those persons to whom they are addressed. Their contents are confidential and if you have received such message in error, please delete it and notify us immediately. Any form of reproduction, dissemination, copying, disclosure, modification, distribution and / or publication of e-mails sent by Mindgems Inc. without our prior written consent is strictly prohibited.
This is not SPAM!. This is a promotional e-mail that complies with the guidelines of CAN-SPAM Act, 2003. You may be receiving this e-mail because you have opted-in to our mailing list or you have purchased products from www.mindgems.com. We do not recommend you to unsubscribe from this mailing list as you will miss the new version notifications, discount offers and giveaways. If you do not want to receive e-mails from us again please click here and enter your e-mail address. All subscribe/unsubscribe requests must be confirmed via email. Your email address will not be revealed to third parties!
|
|
From: Steven R. <ro...@go...> - 2013-05-09 14:33:21
|
On Thu, 2013-05-09 at 14:25 +0000, Seiji Aguchi wrote: > Steven, Peter > > When can I get feedback? > Good timing, this actually came up just today. Yeah, we need to get this out for 3.11. I'm currently busy on some other things that need fixing in 3.10, but I'll work on this next. Thanks, -- Steve |
|
From: Seiji A. <sei...@hd...> - 2013-05-09 14:26:56
|
Steven, Peter
When can I get feedback?
Seiji
> -----Original Message-----
> From: Seiji Aguchi
> Sent: Friday, April 05, 2013 3:16 PM
> To: lin...@vg...; x8...@ke...; ro...@go...; hp...@zy...
> Cc: Thomas Gleixner (tg...@li...); 'mi...@el...' (mi...@el...); Borislav Petkov (bp...@al...); linux-
> ed...@vg...; Luck, Tony (ton...@in...); dle...@li...; Tomoki Sekiyama
> Subject: [PATCH v12 0/3] trace,x86: irq vector tracepoint support
>
> Change log
> v11 -> v12
> - Rebase to 3.9-rc5
>
> v10 -> v11
> - Rebase to 3.9-rc2
> - Add a modification for hyperv_callback vector. (patch 2/3)
> - Change a way to switch idt to check the table in use instead of saving/restoring it,
> because saving/restoring functions will break if we have to add another one. (patch 2/3)
>
> v9 -> v10
> - Add an explanation the reason why tracepoints has to place inside irq enter/exit handling. (patch 3/3)
>
> v8 -> v9
> - Rebase to 3.8-rc6
> - Add Steven's email address at the top of the message and
> move my signed-off-by below Steven's one because it is
> originally created by Steven. (patch 1/3)
> - Introduce a irq_vector_mutex to avoid a race at registering/unregistering
> time. (patch 2/3)
> - Use a per_cpu data to orig_idt_descr because IDT descritor is needed to each cpu
> and the appropriate data type is per_cpu data. It is suggested by Steven.
> (patch 2/3)
>
> v7 -> v8
> - Rebase to 3.8-rc4
> - Add a patch 1 introducing DEFINE_EVENT_FN() macro.
> - Rename original patches 1 and 2 to 2 and 3.
> - Change a definition of tracepoint to use DEFINE_EVENT_FN(). (patch 2)
> - Change alloc_intr_gate() to use do{}while(0) to avoid a warning
> of checkpatch.pl. (patch 2)
> - Move entering_irq()/exiting_irq() to arch/x86/include/asm/apic.h (patch 3)
>
> v6 -> v7
> - Divide into two patches to make a code review easier.
> Summery of each patch is as follows.
> - Patch 1/2
> - Add an irq_vector tracing infrastructure.
> - Create idt_table for tracing. It is refactored to avoid duplicating
> existing logic.
> - Duplicate new irq handlers inserted tracepoints.
>
> - Patch 2/2
> - Share a common logic among irq handlers to make them
> manageable and readable.
>
> v5 -> v6
> - Rebased to 3.7
>
> v4 -> v5
> - Rebased to 3.6.0
>
> - Introduce a logic switching IDT at enabling/disabling TP time
> so that a time penalty makes a zero when tracepoints are disabled.
> This IDT is created only when CONFIG_TRACEPOINTS is enabled.
>
> - Remove arch_irq_vector_entry/exit and add followings again
> so that we can add each tracepoint in a generic way.
> - error_apic_vector
> - thermal_apic_vector
> - threshold_apic_vector
> - spurious_apic_vector
> - x86_platform_ipi_vector
>
> - Drop nmi tracepoints to begin with apic interrupts and discuss a logic switching
> IDT first.
>
> - Move irq_vectors.h in the directory of arch/x86/include/asm/trace because
> I'm not sure if a logic switching IDT is sharable with other architectures.
>
> v3 -> v4
> - Add a latency measurement of each tracepoint
> - Rebased to 3.6-rc6
>
> v2 -> v3
> - Remove an invalidate_tlb_vector event because it was replaced by a call function vector
> in a following commit.
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=52aec3308db85f4e9f5c8b9f5dc4fbd0138c6fa4
>
> v1 -> v2
> - Modify variable name from irq to vector.
> - Merge arch-specific tracepoints below to an arch_irq_vector_entry/exit.
> - error_apic_vector
> - thermal_apic_vector
> - threshold_apic_vector
> - spurious_apic_vector
> - x86_platform_ipi_vector
>
> [Purpose of this patch]
>
> As Vaibhav explained in the thread below, tracepoints for irq vectors are useful.
>
> http://www.spinics.net/lists/mm-commits/msg85707.html
>
> <snip>
> The current interrupt traces from irq_handler_entry and irq_handler_exit provide when an interrupt is handled.
> They provide good data about when the system has switched to kernel space and how it affects the currently running processes.
>
> There are some IRQ vectors which trigger the system into kernel space, which are not handled in generic IRQ handlers.
> Tracing such events gives us the information about IRQ interaction with other system events.
>
> The trace also tells where the system is spending its time. We want to know which cores are handling interrupts and
> how they are affecting other processes in the system. Also, the trace provides information about when the cores are
> idle and which interrupts are changing that state.
> <snip>
>
> On the other hand, my usecase is tracing just local timer event and getting a value of instruction pointer.
>
> I suggested to add an argument local timer event to get instruction pointer before.
> But there is another way to get it with external module like systemtap.
> So, I don't need to add any argument to irq vector tracepoints now.
>
> [Patch Description]
>
> Vaibhav's patch shared a trace point ,irq_vector_entry/irq_vector_exit, in all events.
> But there is an above use case to trace specific irq_vector rather than tracing all events.
> In this case, we are concerned about overhead due to unwanted events.
>
> This patch adds following tracepoints instead of introducing irq_vector_entry/exit.
> so that we can enable them independently.
> - local_timer_vector
> - reschedule_vector
> - call_function_vector
> - call_function_single_vector
> - irq_work_entry_vector
> - error_apic_vector
> - thermal_apic_vector
> - threshold_apic_vector
> - spurious_apic_vector
> - x86_platform_ipi_vector
>
> Please see descriptions in each patch.
>
> Seiji Aguchi (2):
> trace,x86: add x86 irq vector tracepoints
> trace,x86: code-sharing between non-trace and trace irq handlers
>
> Steven Rostedt (1):
> tracing: Add DEFINE_EVENT_FN() macro
>
> arch/x86/include/asm/apic.h | 27 +++++
> arch/x86/include/asm/desc.h | 36 +++++++-
> arch/x86/include/asm/entry_arch.h | 5 +-
> arch/x86/include/asm/hw_irq.h | 16 +++
> arch/x86/include/asm/mshyperv.h | 1 +
> arch/x86/include/asm/trace/irq_vectors.h | 159 ++++++++++++++++++++++++++++++
> arch/x86/kernel/Makefile | 1 +
> arch/x86/kernel/apic/apic.c | 71 +++++++++++---
> arch/x86/kernel/cpu/common.c | 12 ++-
> arch/x86/kernel/cpu/mcheck/therm_throt.c | 24 ++++-
> arch/x86/kernel/cpu/mcheck/threshold.c | 24 ++++-
> arch/x86/kernel/entry_32.S | 12 ++-
> arch/x86/kernel/entry_64.S | 29 +++++-
> arch/x86/kernel/head_64.S | 6 +
> arch/x86/kernel/irq.c | 31 ++++--
> arch/x86/kernel/irq_work.c | 24 ++++-
> arch/x86/kernel/smp.c | 65 +++++++++++--
> arch/x86/kernel/tracepoint.c | 71 +++++++++++++
> include/linux/tracepoint.h | 2 +
> include/trace/define_trace.h | 5 +
> include/trace/ftrace.h | 4 +
> include/xen/events.h | 3 +
> 22 files changed, 570 insertions(+), 58 deletions(-)
> create mode 100644 arch/x86/include/asm/trace/irq_vectors.h
> create mode 100644 arch/x86/kernel/tracepoint.c
|
|
From: Eric W. B. <ebi...@xm...> - 2013-05-09 00:24:42
|
Nak. Do this in the crash dump cature kernel. If you are worried about your modules failing to initialize load them after. There is already a perfectly capable policy hook here that will allow any policy you desire. We don't need to add crap onto that kexec on panic code path to implement your chosen policy. Also note that "Always being able to explain a kernel crash" is impossible and you seem to be actively working against the reliability you claim you desire by attempting to make the code less comprehensible and more brittle. Eric Seiji Aguchi <sei...@hd...> wrote: >Problem >======= > >From our support service experience, we always need to detect root >cause of OS panic. >And customers in enterprise area never forgive us if we can't detect >the root cause >of panic due to lack of materials for investigation. > >Kdump is a powerful troubleshooting feature, but it may accesses to >multiple hardware, >like HBA, FC-cable, to get to dump disk. > >This means kdump is not robust against hardware failure. > >Solution >======== > >Logging kernel message to persistent device is an effective way to get >materials >for investigation in case of kdump failure. > >So, this patch adds kmsg_dump() to a kexec path. >Also, it adds KMSG_DUMP_KEXEC to pstore_cannot_block_path() >so that it can avoid deadlocking in kexec path. > >Please see the detail of pstore_cannot_block_path(). >https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/fs/pstore/platform.c?id=9f244e9cfd70c7c0f82d3c92ce772ab2a92d9f64 > > >Actually, there are some objections about kmsg_dump(KMSG_DUMP_KEXEC) >and EFI below. >But I still think adding kmsg_dump() to a kexec path is useful. > >- http://marc.info/?l=linux-kernel&m=130698519720887&w=2 > >(1) kdump already saves kernel messages inside /proc/vmcore > >- >https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/kernel/kexec.c?id=a3dd3323058d281abd584b15ad4c5b65064d7a61 > >It is correct, but the content of /proc/vmcore is stored a dump disk as >well. >So, if kdump fails due to hardware failures, the kernel messages will >be lost. > >(2) EFI firmware is buggy > >- http://marc.info/?l=linux-kernel&m=130698519720887&w=2 > >I haven't seen actual firmware bugs which may cause kdump failure. >So I don't think we need to care about it too much. >However, just to be safe, I introduced pstore_cannot_block_path() avoid >deadlocking to pstore. > >Also, this patch doesn't affect almost all users because kmsg_dump() is >kicked only when >specifying both pstore.backend and printk.always_kmsg_dump parameters. >Even if a buggy firmware causes a kdump failure and someone blames >kdump, >we can ask them to reproduce the kdump failure by removing the >parameters. > >In addition, I checked current coding of platform drivers. >There is no obvious problem as follows. > >- mtdoops/ramoops > They are designed to be kicked in panic and oops cases only. > So, they never run in a kexec path. > >- erst/efi/early_printk_mrst/nvram driver for powerpc > I don't see any bugs which may causes kdump failure because >deadlocking/dynamic memory allocation don't happen in their write >callbacks. > >Signed-off-by: Seiji Aguchi <sei...@hd...> >--- > fs/pstore/platform.c | 4 ++++ > include/linux/kmsg_dump.h | 1 + > kernel/kexec.c | 2 ++ > 3 files changed, 7 insertions(+), 0 deletions(-) > >diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c >index 86d1038..e6f651f 100644 >--- a/fs/pstore/platform.c >+++ b/fs/pstore/platform.c >@@ -91,6 +91,8 @@ static const char *get_reason_str(enum >kmsg_dump_reason reason) > return "Halt"; > case KMSG_DUMP_POWEROFF: > return "Poweroff"; >+ case KMSG_DUMP_KEXEC: >+ return "Kexec"; > default: > return "Unknown"; > } >@@ -110,6 +112,8 @@ bool pstore_cannot_block_path(enum kmsg_dump_reason >reason) > case KMSG_DUMP_PANIC: > /* Emergency restart shouldn't be blocked by spin lock. */ > case KMSG_DUMP_EMERG: >+ /* In kexec path, pstore shouldn't be blocked to avoid kexec failure. >*/ >+ case KMSG_DUMP_KEXEC: > return true; > default: > return false; >diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h >index 2e7a1e0..c943ecb 100644 >--- a/include/linux/kmsg_dump.h >+++ b/include/linux/kmsg_dump.h >@@ -28,6 +28,7 @@ enum kmsg_dump_reason { > KMSG_DUMP_RESTART, > KMSG_DUMP_HALT, > KMSG_DUMP_POWEROFF, >+ KMSG_DUMP_KEXEC, > }; > > /** >diff --git a/kernel/kexec.c b/kernel/kexec.c >index 59f7b55..f084132 100644 >--- a/kernel/kexec.c >+++ b/kernel/kexec.c >@@ -32,6 +32,7 @@ > #include <linux/vmalloc.h> > #include <linux/swap.h> > #include <linux/syscore_ops.h> >+#include <linux/kmsg_dump.h> > > #include <asm/page.h> > #include <asm/uaccess.h> >@@ -1089,6 +1090,7 @@ void crash_kexec(struct pt_regs *regs) > > crash_setup_regs(&fixed_regs, regs); > crash_save_vmcoreinfo(); >+ kmsg_dump(KMSG_DUMP_KEXEC); > machine_crash_shutdown(&fixed_regs); > machine_kexec(kexec_crash_image); > } >-- 1.7.1 |
|
From: Seiji A. <sei...@hd...> - 2013-05-08 23:19:41
|
Problem ======= >From our support service experience, we always need to detect root cause of OS panic. And customers in enterprise area never forgive us if we can't detect the root cause of panic due to lack of materials for investigation. Kdump is a powerful troubleshooting feature, but it may accesses to multiple hardware, like HBA, FC-cable, to get to dump disk. This means kdump is not robust against hardware failure. Solution ======== Logging kernel message to persistent device is an effective way to get materials for investigation in case of kdump failure. So, this patch adds kmsg_dump() to a kexec path. Also, it adds KMSG_DUMP_KEXEC to pstore_cannot_block_path() so that it can avoid deadlocking in kexec path. Please see the detail of pstore_cannot_block_path(). https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/fs/pstore/platform.c?id=9f244e9cfd70c7c0f82d3c92ce772ab2a92d9f64 Actually, there are some objections about kmsg_dump(KMSG_DUMP_KEXEC) and EFI below. But I still think adding kmsg_dump() to a kexec path is useful. - http://marc.info/?l=linux-kernel&m=130698519720887&w=2 (1) kdump already saves kernel messages inside /proc/vmcore - https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/kernel/kexec.c?id=a3dd3323058d281abd584b15ad4c5b65064d7a61 It is correct, but the content of /proc/vmcore is stored a dump disk as well. So, if kdump fails due to hardware failures, the kernel messages will be lost. (2) EFI firmware is buggy - http://marc.info/?l=linux-kernel&m=130698519720887&w=2 I haven't seen actual firmware bugs which may cause kdump failure. So I don't think we need to care about it too much. However, just to be safe, I introduced pstore_cannot_block_path() avoid deadlocking to pstore. Also, this patch doesn't affect almost all users because kmsg_dump() is kicked only when specifying both pstore.backend and printk.always_kmsg_dump parameters. Even if a buggy firmware causes a kdump failure and someone blames kdump, we can ask them to reproduce the kdump failure by removing the parameters. In addition, I checked current coding of platform drivers. There is no obvious problem as follows. - mtdoops/ramoops They are designed to be kicked in panic and oops cases only. So, they never run in a kexec path. - erst/efi/early_printk_mrst/nvram driver for powerpc I don't see any bugs which may causes kdump failure because deadlocking/dynamic memory allocation don't happen in their write callbacks. Signed-off-by: Seiji Aguchi <sei...@hd...> --- fs/pstore/platform.c | 4 ++++ include/linux/kmsg_dump.h | 1 + kernel/kexec.c | 2 ++ 3 files changed, 7 insertions(+), 0 deletions(-) diff --git a/fs/pstore/platform.c b/fs/pstore/platform.c index 86d1038..e6f651f 100644 --- a/fs/pstore/platform.c +++ b/fs/pstore/platform.c @@ -91,6 +91,8 @@ static const char *get_reason_str(enum kmsg_dump_reason reason) return "Halt"; case KMSG_DUMP_POWEROFF: return "Poweroff"; + case KMSG_DUMP_KEXEC: + return "Kexec"; default: return "Unknown"; } @@ -110,6 +112,8 @@ bool pstore_cannot_block_path(enum kmsg_dump_reason reason) case KMSG_DUMP_PANIC: /* Emergency restart shouldn't be blocked by spin lock. */ case KMSG_DUMP_EMERG: + /* In kexec path, pstore shouldn't be blocked to avoid kexec failure. */ + case KMSG_DUMP_KEXEC: return true; default: return false; diff --git a/include/linux/kmsg_dump.h b/include/linux/kmsg_dump.h index 2e7a1e0..c943ecb 100644 --- a/include/linux/kmsg_dump.h +++ b/include/linux/kmsg_dump.h @@ -28,6 +28,7 @@ enum kmsg_dump_reason { KMSG_DUMP_RESTART, KMSG_DUMP_HALT, KMSG_DUMP_POWEROFF, + KMSG_DUMP_KEXEC, }; /** diff --git a/kernel/kexec.c b/kernel/kexec.c index 59f7b55..f084132 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -32,6 +32,7 @@ #include <linux/vmalloc.h> #include <linux/swap.h> #include <linux/syscore_ops.h> +#include <linux/kmsg_dump.h> #include <asm/page.h> #include <asm/uaccess.h> @@ -1089,6 +1090,7 @@ void crash_kexec(struct pt_regs *regs) crash_setup_regs(&fixed_regs, regs); crash_save_vmcoreinfo(); + kmsg_dump(KMSG_DUMP_KEXEC); machine_crash_shutdown(&fixed_regs); machine_kexec(kexec_crash_image); } -- 1.7.1 |
|
From: Seiji A. <sei...@hd...> - 2013-05-02 20:43:47
|
Thank you for giving the comments. I will separate this functionality from the qemu error file. > I also don't buy that we can't use strftime. There are very few places > where we use fork() in QEMU (it doesn't exist on Windows so it can't be > used without protection). None of those places use the error reporting > infrastructure. > > This code is also extremely naive. It doesn't take into account leap > seconds and makes bad assumptions about leap years. OK. I will use strftime(). Seiji > -----Original Message----- > From: qem...@no... [mailto:qem...@no...] > On Behalf Of Anthony Liguori > Sent: Wednesday, May 01, 2013 10:27 AM > To: Daniel P. Berrange; Eric Blake > Cc: kw...@re...; dle...@li...; Seiji Aguchi; ste...@re...; ms...@re...; Stefan Hajnoczi; > mto...@re...; qem...@no...; ar...@re...; av...@co...; Tomoki Sekiyama; pbo...@re...; > lca...@re...; Seiji Aguchi > Subject: Re: [Qemu-devel] [RFC][PATCH v2]Add timestamp to error message > > "Daniel P. Berrange" <ber...@re...> writes: > > > On Wed, May 01, 2013 at 06:16:33AM -0600, Eric Blake wrote: > >> On 05/01/2013 06:05 AM, Stefan Hajnoczi wrote: > >> > >> >> + error_printf( > >> >> + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", > >> >> + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, > >> >> + fields.tm_hour, fields.tm_min, fields.tm_sec, > >> >> + now % 1000); > >> > > >> > Can strftime(3) be used instead of copying code from glibc? > >> > >> No, because glibc's strftime() is not async-signal safe, and therefore > >> is not safe to call between fork() and exec() (libvirt hit actual > >> deadlocks[1] where a child was blocked on a mutex associated with > >> time-related functions that happened to be held by another parent > >> thread, but where the fork nuked that other thread so the mutex would > >> never clear). This code is copied from libvirt, which copied the > >> no-lock-needed safe portions of glibc for a reason. > >> > >> [1] https://www.redhat.com/archives/libvir-list/2011-November/msg01609.html > > > > NB the original libvirt code had this & other related functions in > > a standalone file, along with a significant test suite. I think it > > is better from a maintenence POV to keep this functionality in a > > file that's separate from the qemu error file, so it can be reused > > elsewhere in QEMU if needed. It should also copy the test suite, > > since it is bad practice to throw away tests which already exist. > > I also don't buy that we can't use strftime. There are very few places > where we use fork() in QEMU (it doesn't exist on Windows so it can't be > used without protection). None of those places use the error reporting > infrastructure. > > This code is also extremely naive. It doesn't take into account leap > seconds and makes bad assumptions about leap years. > > Regards, > > Anthony Liguori > > > > > Daniel > > -- > > |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| > > |: http://libvirt.org -o- http://virt-manager.org :| > > |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| > > |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| > |
|
From: Seiji A. <sei...@hd...> - 2013-05-02 17:26:40
|
[Problem] Currently, guest OS's messages can be logged to a local disk of host OS by creating chadevs with options below. -chardev file,id=charserial0,path=<log file's path> -device isa-serial,chardev=chardevserial0,id=serial0 When a hardware failure happens in the disk, qemu-kvm can't create the chardevs. In this case, guest OS doesn't boot up. Actually, there are users who don't desire that guest OS goes down due to a hardware failure of a log disk only.Therefore, qemu should offer some way to boot guest OS up even if the log disk is broken. [Solution] This patch supports startupPolicy for chardev. The starupPolicy is introduced just in case where chardev is "file" because this patch aims for making guest OS boot up when a hardware failure happens. In other cases ,pty, dev, pipe and unix, it is not introduced because they don't access to hardware. The policy works as follows. - If the value is "optional", guestOS boots up by dropping the chardev. - If other values are specified, guestOS fails to boot up. (the default) Description about original startupPolicy attribute: http://libvirt.org/git/?p=libvirt.git;a=commitdiff;h=e5a84d74a2789a917bf394f15de9989ec48fded0 Signed-off-by: Seiji Aguchi <sei...@hd...> --- docs/formatdomain.html.in | 9 ++++++++- docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_conf.c | 8 ++++++++ src/conf/domain_conf.h | 1 + src/qemu/qemu_process.c | 25 ++++++++++++++++++++++++- tests/virt-aa-helper-test | 3 +++ 6 files changed, 47 insertions(+), 2 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index f325c3c..1e1bf27 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -4044,13 +4044,20 @@ qemu-kvm -net nic,model=? /dev/null <p> A file is opened and all data sent to the character device is written to the file. + It is possible to define policy whether guestOS boots up + if the file is not accessible. This is done by a startupPolicy + attribute: + <ul> + <li>If the vaule is "optional", guestOS boots up by dropping the file.</li> + <li>If other values are specified, guestOS fails to boot up. (the default)</li> + </ul> </p> <pre> ... <devices> <serial type="file"> - <source path="/var/log/vm/vm-serial.log"/> + <source path="/var/log/vm/vm-serial.log" startupPolicy="optional"/> <target port="1"/> </serial> </devices> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 10596dc..6fc0a3c 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2706,6 +2706,9 @@ </optional> <optional> <attribute name="path"/> + <optional> + <ref name='startupPolicy'/> + </optional> </optional> <optional> <attribute name="host"/> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a8b5dfd..6680f15 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6467,6 +6467,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, char *path = NULL; char *mode = NULL; char *protocol = NULL; + char *startupPolicy = NULL; int remaining = 0; while (cur != NULL) { @@ -6487,6 +6488,9 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, !(flags & VIR_DOMAIN_XML_INACTIVE))) path = virXMLPropString(cur, "path"); + if (startupPolicy == NULL && + def->type == VIR_DOMAIN_CHR_TYPE_FILE) + startupPolicy = virXMLPropString(cur, "startupPolicy"); break; case VIR_DOMAIN_CHR_TYPE_UDP: @@ -6559,6 +6563,10 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def, def->data.file.path = path; path = NULL; + + def->data.file.startupPolicy = + virDomainStartupPolicyTypeFromString(startupPolicy); + startupPolicy = NULL; break; case VIR_DOMAIN_CHR_TYPE_STDIO: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3a0f23a..e709951 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1052,6 +1052,7 @@ struct _virDomainChrSourceDef { /* no <source> for null, vc, stdio */ struct { char *path; + int startupPolicy; /* enum virDomainStartupPolicy */ } file; /* pty, file, pipe, or device */ struct { char *host; diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index e75c8c9..6e2f78e 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2442,7 +2442,30 @@ qemuProcessPrepareChardevDevice(virDomainDefPtr def ATTRIBUTE_UNUSED, virReportSystemError(errno, _("Unable to pre-create chardev file '%s'"), dev->source.data.file.path); - return -1; + if (dev->source.data.file.startupPolicy != + VIR_DOMAIN_STARTUP_POLICY_OPTIONAL) { + return -1; + } + VIR_FREE(dev->source.data.file.path); + /* + * Change a destination to /dev/null to boot guest OS up + * even if a log disk is broken. + */ + VIR_WARN("Switch the destination to /dev/null"); + dev->source.data.file.path = strdup("/dev/null"); + + if (!(dev->source.data.file.path)) { + virReportOOMError(); + return -1; + } + + if ((fd = open(dev->source.data.file.path, + O_CREAT | O_APPEND, S_IRUSR|S_IWUSR)) < 0) { + virReportSystemError(errno, + _("Unable to pre-create chardev file '%s'"), + dev->source.data.file.path); + return -1; + } } VIR_FORCE_CLOSE(fd); diff --git a/tests/virt-aa-helper-test b/tests/virt-aa-helper-test index af91c61..7172fd6 100755 --- a/tests/virt-aa-helper-test +++ b/tests/virt-aa-helper-test @@ -255,6 +255,9 @@ testme "0" "disk (empty cdrom)" "-r -u $valid_uuid" "$test_xml" sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='file'><source path='$tmpdir/serial.log'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" testme "0" "serial" "-r -u $valid_uuid" "$test_xml" +sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='file'><source path='$tmpdir/serial.log' startupPolicy='optional'/><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" +testme "0" "serial" "-r -u $valid_uuid" "$test_xml" + sed -e "s,###UUID###,$uuid,g" -e "s,###DISK###,$disk1,g" -e "s,</devices>,<serial type='pty'><target port='0'/></serial></devices>,g" "$template_xml" > "$test_xml" testme "0" "serial (pty)" "-r -u $valid_uuid" "$test_xml" -- 1.7.1 |
|
From: Anthony L. <ali...@us...> - 2013-05-01 14:57:22
|
"Daniel P. Berrange" <ber...@re...> writes: > On Wed, May 01, 2013 at 06:16:33AM -0600, Eric Blake wrote: >> On 05/01/2013 06:05 AM, Stefan Hajnoczi wrote: >> >> >> + error_printf( >> >> + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", >> >> + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, >> >> + fields.tm_hour, fields.tm_min, fields.tm_sec, >> >> + now % 1000); >> > >> > Can strftime(3) be used instead of copying code from glibc? >> >> No, because glibc's strftime() is not async-signal safe, and therefore >> is not safe to call between fork() and exec() (libvirt hit actual >> deadlocks[1] where a child was blocked on a mutex associated with >> time-related functions that happened to be held by another parent >> thread, but where the fork nuked that other thread so the mutex would >> never clear). This code is copied from libvirt, which copied the >> no-lock-needed safe portions of glibc for a reason. >> >> [1] https://www.redhat.com/archives/libvir-list/2011-November/msg01609.html > > NB the original libvirt code had this & other related functions in > a standalone file, along with a significant test suite. I think it > is better from a maintenence POV to keep this functionality in a > file that's separate from the qemu error file, so it can be reused > elsewhere in QEMU if needed. It should also copy the test suite, > since it is bad practice to throw away tests which already exist. I also don't buy that we can't use strftime. There are very few places where we use fork() in QEMU (it doesn't exist on Windows so it can't be used without protection). None of those places use the error reporting infrastructure. This code is also extremely naive. It doesn't take into account leap seconds and makes bad assumptions about leap years. Regards, Anthony Liguori > > Daniel > -- > |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| > |: http://libvirt.org -o- http://virt-manager.org :| > |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| > |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| |
|
From: Daniel P. B. <ber...@re...> - 2013-05-01 12:25:23
|
On Wed, May 01, 2013 at 06:16:33AM -0600, Eric Blake wrote: > On 05/01/2013 06:05 AM, Stefan Hajnoczi wrote: > > >> + error_printf( > >> + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", > >> + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, > >> + fields.tm_hour, fields.tm_min, fields.tm_sec, > >> + now % 1000); > > > > Can strftime(3) be used instead of copying code from glibc? > > No, because glibc's strftime() is not async-signal safe, and therefore > is not safe to call between fork() and exec() (libvirt hit actual > deadlocks[1] where a child was blocked on a mutex associated with > time-related functions that happened to be held by another parent > thread, but where the fork nuked that other thread so the mutex would > never clear). This code is copied from libvirt, which copied the > no-lock-needed safe portions of glibc for a reason. > > [1] https://www.redhat.com/archives/libvir-list/2011-November/msg01609.html NB the original libvirt code had this & other related functions in a standalone file, along with a significant test suite. I think it is better from a maintenence POV to keep this functionality in a file that's separate from the qemu error file, so it can be reused elsewhere in QEMU if needed. It should also copy the test suite, since it is bad practice to throw away tests which already exist. Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :| |
|
From: Eric B. <eb...@re...> - 2013-05-01 12:16:52
|
On 05/01/2013 06:05 AM, Stefan Hajnoczi wrote: >> + error_printf( >> + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", >> + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, >> + fields.tm_hour, fields.tm_min, fields.tm_sec, >> + now % 1000); > > Can strftime(3) be used instead of copying code from glibc? No, because glibc's strftime() is not async-signal safe, and therefore is not safe to call between fork() and exec() (libvirt hit actual deadlocks[1] where a child was blocked on a mutex associated with time-related functions that happened to be held by another parent thread, but where the fork nuked that other thread so the mutex would never clear). This code is copied from libvirt, which copied the no-lock-needed safe portions of glibc for a reason. [1] https://www.redhat.com/archives/libvir-list/2011-November/msg01609.html -- Eric Blake eblake redhat com +1-919-301-3266 Libvirt virtualization library http://libvirt.org |
|
From: Stefan H. <ste...@gm...> - 2013-05-01 12:06:01
|
On Mon, Apr 29, 2013 at 03:57:25PM -0400, Seiji Aguchi wrote:
> diff --git a/util/qemu-error.c b/util/qemu-error.c
> index 08a36f4..35ef9ab 100644
> --- a/util/qemu-error.c
> +++ b/util/qemu-error.c
> @@ -196,6 +196,96 @@ void error_print_loc(void)
> }
> }
>
> +
> +#define SECS_PER_HOUR (60 * 60)
> +#define SECS_PER_DAY (SECS_PER_HOUR * 24)
> +#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
> +#define LEAPS_THRU_END_OF(y) (DIV(y, 4) - DIV(y, 100) + DIV(y, 400))
> +
> +const unsigned short int __mon_yday[2][13] = {
> + /* Normal years. */
> + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
> + /* Leap years. */
> + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
> +};
> +
> +#define is_leap_year(y) \
> + ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))
> +
> +static void error_print_timestamp(void)
> +{
> + struct timespec ts;
> + unsigned long long now;
> +
> + struct tm fields;
> + long int days, rem, y;
> + const unsigned short int *ip;
> + unsigned long long whenSecs;
> + unsigned int offset = 0; /* We hardcoded GMT */
> +
> + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
> + return;
> + }
> +
> + now = (ts.tv_sec * 1000ull) + (ts.tv_nsec / (1000ull * 1000ull));
> + /* This code is taken from GLibC under terms of LGPLv2+ */
> +
> + whenSecs = now / 1000ull;
> +
> + days = whenSecs / SECS_PER_DAY;
> + rem = whenSecs % SECS_PER_DAY;
> + rem += offset;
> + while (rem < 0) {
> + rem += SECS_PER_DAY;
> + --days;
> + }
> + while (rem >= SECS_PER_DAY) {
> + rem -= SECS_PER_DAY;
> + ++days;
> + }
> + fields.tm_hour = rem / SECS_PER_HOUR;
> + rem %= SECS_PER_HOUR;
> + fields.tm_min = rem / 60;
> + fields.tm_sec = rem % 60;
> + /* January 1, 1970 was a Thursday. */
> + fields.tm_wday = (4 + days) % 7;
> + if (fields.tm_wday < 0) {
> + fields.tm_wday += 7;
> + }
> + y = 1970;
> +
> + while (days < 0 || days >= (is_leap_year(y) ? 366 : 365)) {
> + /* Guess a corrected year, assuming 365 days per year. */
> + long int yg = y + days / 365 - (days % 365 < 0);
> +
> + /* Adjust DAYS and Y to match the guessed year. */
> + days -= ((yg - y) * 365
> + + LEAPS_THRU_END_OF(yg - 1)
> + - LEAPS_THRU_END_OF(y - 1));
> + y = yg;
> + }
> + fields.tm_year = y - 1900;
> +
> + fields.tm_yday = days;
> + ip = __mon_yday[is_leap_year(y)];
> + for (y = 11; days < (long int) ip[y]; --y) {
> + continue;
> + }
> +
> + days -= ip[y];
> + fields.tm_mon = y;
> + fields.tm_mday = days + 1;
> +
> + error_printf(
> + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ",
> + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday,
> + fields.tm_hour, fields.tm_min, fields.tm_sec,
> + now % 1000);
Can strftime(3) be used instead of copying code from glibc?
|
|
From: Seiji A. <sa...@re...> - 2013-04-29 19:58:18
|
From: Seiji Aguchi <sei...@hd...> [Issue] When we offer a customer support service and a problem happens in a customer's system, we try to understand the problem by comparing what the customer reports with message logs of the customer's system. In this case, we often need to know when the problem happens. But, currently, there is no timestamp in qemu's error messages. Therefore, we may not be able to understand the problem based on error messages. [Solution] This patch adds a timestamp to qemu's error message logged by error_report(). A logic calculating a time is copied from libvirt, src/util/virtime.c. * http://libvirt.org/git/?p=libvirt.git;a=commit;h=3ec128989606278635a7c5dfbeee959692d12e15 [TODO] Add timestamp Messages with monitor_printf() and fprintf(). Signed-off-by: Seiji Aguchi <sei...@hd...> --- Changelog v1 -> v2 - add an option, -msg timestamp={on|off}, to enable output message with timestamp --- include/monitor/monitor.h | 2 + qemu-options.hx | 12 ++++++ util/qemu-error.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ vl.c | 26 ++++++++++++ 4 files changed, 133 insertions(+), 0 deletions(-) diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h index b868760..6cbb0ff 100644 --- a/include/monitor/monitor.h +++ b/include/monitor/monitor.h @@ -99,4 +99,6 @@ int monitor_fdset_dup_fd_add(int64_t fdset_id, int dup_fd); int monitor_fdset_dup_fd_remove(int dup_fd); int monitor_fdset_dup_fd_find(int dup_fd); +extern bool enable_timestamp_msg; + #endif /* !MONITOR_H */ diff --git a/qemu-options.hx b/qemu-options.hx index e86cc24..a421261 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -3097,3 +3097,15 @@ HXCOMM This is the last statement. Insert new options before this line! STEXI @end table ETEXI + +DEF("msg", HAS_ARG, QEMU_OPTION_msg, + "-msg [timestamp=on|off]\n" + " output message with timestamp (default: off)\n", + QEMU_ARCH_ALL) +STEXI +@item -msg timestamp=on|off +@findex - msg +Output message with timestamp. +Adding timestamp to messages with @option{timestamp=on} +(disabled by default). +ETEXI diff --git a/util/qemu-error.c b/util/qemu-error.c index 08a36f4..35ef9ab 100644 --- a/util/qemu-error.c +++ b/util/qemu-error.c @@ -196,6 +196,96 @@ void error_print_loc(void) } } + +#define SECS_PER_HOUR (60 * 60) +#define SECS_PER_DAY (SECS_PER_HOUR * 24) +#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) +#define LEAPS_THRU_END_OF(y) (DIV(y, 4) - DIV(y, 100) + DIV(y, 400)) + +const unsigned short int __mon_yday[2][13] = { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } +}; + +#define is_leap_year(y) \ + ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0)) + +static void error_print_timestamp(void) +{ + struct timespec ts; + unsigned long long now; + + struct tm fields; + long int days, rem, y; + const unsigned short int *ip; + unsigned long long whenSecs; + unsigned int offset = 0; /* We hardcoded GMT */ + + if (clock_gettime(CLOCK_REALTIME, &ts) < 0) { + return; + } + + now = (ts.tv_sec * 1000ull) + (ts.tv_nsec / (1000ull * 1000ull)); + /* This code is taken from GLibC under terms of LGPLv2+ */ + + whenSecs = now / 1000ull; + + days = whenSecs / SECS_PER_DAY; + rem = whenSecs % SECS_PER_DAY; + rem += offset; + while (rem < 0) { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) { + rem -= SECS_PER_DAY; + ++days; + } + fields.tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + fields.tm_min = rem / 60; + fields.tm_sec = rem % 60; + /* January 1, 1970 was a Thursday. */ + fields.tm_wday = (4 + days) % 7; + if (fields.tm_wday < 0) { + fields.tm_wday += 7; + } + y = 1970; + + while (days < 0 || days >= (is_leap_year(y) ? 366 : 365)) { + /* Guess a corrected year, assuming 365 days per year. */ + long int yg = y + days / 365 - (days % 365 < 0); + + /* Adjust DAYS and Y to match the guessed year. */ + days -= ((yg - y) * 365 + + LEAPS_THRU_END_OF(yg - 1) + - LEAPS_THRU_END_OF(y - 1)); + y = yg; + } + fields.tm_year = y - 1900; + + fields.tm_yday = days; + ip = __mon_yday[is_leap_year(y)]; + for (y = 11; days < (long int) ip[y]; --y) { + continue; + } + + days -= ip[y]; + fields.tm_mon = y; + fields.tm_mday = days + 1; + + error_printf( + "%4d-%02d-%02d %02d:%02d:%02d.%03lld+0000 ", + fields.tm_year + 1900, fields.tm_mon + 1, fields.tm_mday, + fields.tm_hour, fields.tm_min, fields.tm_sec, + now % 1000); + + return; +} + +bool enable_timestamp_msg; /* * Print an error message to current monitor if we have one, else to stderr. * Format arguments like sprintf(). The result should not contain @@ -207,6 +297,9 @@ void error_report(const char *fmt, ...) { va_list ap; + if (enable_timestamp_msg) { + error_print_timestamp(); + } error_print_loc(); va_start(ap, fmt); error_vprintf(fmt, ap); diff --git a/vl.c b/vl.c index 6caa5f4..f1286a3 100644 --- a/vl.c +++ b/vl.c @@ -533,6 +533,18 @@ static QemuOptsList qemu_realtime_opts = { }, }; +static QemuOptsList qemu_msg_opts = { + .name = "msg", + .head = QTAILQ_HEAD_INITIALIZER(qemu_msg_opts.head), + .desc = { + { + .name = "timestamp", + .type = QEMU_OPT_BOOL, + }, + { /* end of list */ } + }, +}; + const char *qemu_get_vm_name(void) { return qemu_name; @@ -1446,6 +1458,12 @@ static void configure_realtime(QemuOpts *opts) } } + +static void configure_msg(QemuOpts *opts) +{ + enable_timestamp_msg = qemu_opt_get_bool(opts, "timestamp", true); +} + /***********************************************************/ /* USB devices */ @@ -2889,6 +2907,7 @@ int main(int argc, char **argv, char **envp) qemu_add_opts(&qemu_object_opts); qemu_add_opts(&qemu_tpmdev_opts); qemu_add_opts(&qemu_realtime_opts); + qemu_add_opts(&qemu_msg_opts); runstate_init(); @@ -3869,6 +3888,13 @@ int main(int argc, char **argv, char **envp) } configure_realtime(opts); break; + case QEMU_OPTION_msg: + opts = qemu_opts_parse(qemu_find_opts("msg"), optarg, 0); + if (!opts) { + exit(1); + } + configure_msg(opts); + break; default: os_parse_cmd_args(popt->index, optarg); } -- 1.7.1 |
|
From: Anthony L. <ali...@us...> - 2013-04-22 18:38:39
|
Applied. Thanks. Regards, Anthony Liguori |