that returns 0. Patch by Hugo Santos.
* Removed superfluous memset() of select_sync structures.
* Some cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20467 a95241bf-73f2-0310-859d-f6bbb57e9c96
would start with the first block in the unused blocks list, but then
continue with the blocks that share the same hash table slot, thus
freeing potentially used blocks. Could theoretically have caused
BFS to see and write incorrect meta/administrative data on certain
occasions.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20459 a95241bf-73f2-0310-859d-f6bbb57e9c96
defined by the UserlandFS server and is of no real use anyway.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20457 a95241bf-73f2-0310-859d-f6bbb57e9c96
yet sure what is causing this, but until I find the time to look into it (or someone else
as part of GSoC), raising the limit helps.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20427 a95241bf-73f2-0310-859d-f6bbb57e9c96
owner of that thread - this fixes the kernel part of bug #1122.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20419 a95241bf-73f2-0310-859d-f6bbb57e9c96
short, if the FD table size wasn't a multiple of 8.
* vfs_resize_fd_table() didn't seem to know at all about the
close-on-exit bitmap. The pointer in the io_context would point to
free()d memory afterwards. This explains the sporadically closed
stdin/out/err descriptors in programs started from Tracker and
Deskbar.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20413 a95241bf-73f2-0310-859d-f6bbb57e9c96
* Added a comment to vm_remove_all_page_mappings() that shows that we need to
change the mapping spinlock into a mutex.
* Pointed out some potential problems in the code.
* Added vm_page_at_index(), vm_clear_map_activation(), and vm_test_map_activation()
in preparation of the page scanner rewrite.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20407 a95241bf-73f2-0310-859d-f6bbb57e9c96
mapped fully read-only (for both kernel and userland). Previously a
kernel read access to a yet unmapped r/w accessible userland address
would cause the page from the lower cache to be mapped with write
permission for userland (on x86 also for the kernel) thus e.g.
allowing a fork()ed child process to write to the parent process'
memory.
Fixes bugs #113 and #928.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20402 a95241bf-73f2-0310-859d-f6bbb57e9c96
{set,clear}_debugger_{break,watch}point(), allowing to set/clear break
and watchpoints for the calling team. When a break/watchpoint is hit,
the team enters the debugger. Handy in situations when the program in
question can't really be started in a debugger (or it would be
complicated to do so). The functions work only as long as no debugger is
installed for the team.
We clear the arch specific team and thread debug infos now, when a new
debugger is installed, thus clearing break- and watchpoints.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20396 a95241bf-73f2-0310-859d-f6bbb57e9c96
* NewBlock()/FreeBlock() are now symmetrical in that the former no longer inserts
the block into the hash table.
* delete_transaction() also no longer removes the transaction from the hash table.
* cache_transaction_sync() now uses the new hash_remove_current() function.
* minor other cleanup (like line breaks).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20374 a95241bf-73f2-0310-859d-f6bbb57e9c96
hashtable in case of a read error (NewBlock() also adds the block,
but FreeBlock() only frees it).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20365 a95241bf-73f2-0310-859d-f6bbb57e9c96
suggested by Ingo; before it would just fill the physical pages with NULL pointers.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20364 a95241bf-73f2-0310-859d-f6bbb57e9c96
start address wasn't aligned and numBytes was a multiple of the page
size, the last page was ignored. A subsequent get_memory_map() would
return NULL as physical address for that page, if it hadn't been mapped
before (that function looks generally suspicious, IMHO). E.g. reads from a
device into an unaligned buffer that hadn't been touched before would
hit that problem. Fixes bug #1075. Might also fix other reported
problems (like #1056), since this bug could have cause all kinds of weird
behavior and crashes.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20362 a95241bf-73f2-0310-859d-f6bbb57e9c96
that points to both, the page and the area the page is in. This will allow a page
scanner to steal unused pages when necessary.
* The locking is currently done with a spinlock which we might want to have another
look at one day.
* dump_page() and dump_area_struct() now dump the page mappings as well.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20356 a95241bf-73f2-0310-859d-f6bbb57e9c96
add-ons accordingly and removed the syscall.
* Removed send_notification().
* Reimplemented notify_listener(). It used the unimplemented
send_notification(). Now it has a chance to work. Note that
notify_listener() is obsolete. I would already have removed it, if
there weren't lots of FS implementations still using it (Hint!).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20329 a95241bf-73f2-0310-859d-f6bbb57e9c96
vnode::covered_by fields. Together with sMountOpLock it allows write
access, either lock alone suffices for read access. Before
sMountOpLock had to be acquired for read (and write) access, which
meant that while mounting/unmounting a FS path resolution would have
to wait. In case of the UserlandFS this would even cause a deadlock
while mounting if the client tried to resolve the path of the device
to be mounted (e.g. by opening it).
* Added a clarifying comment about read access to the
fs_mount::covers_vnode/root_vnode field and removed locking in
resolve_volume_root_to_mount_point() which was not necessary for
explained reasons.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20308 a95241bf-73f2-0310-859d-f6bbb57e9c96
name (saves copying the name, if that has to be done anyway) and added a
wrapper version with the old interface.
* dir_vnode_to_path() was broken for file systems that didn't support
the get_vnode_name() hook. It resolved the mount point too early, so
that it was searching the mount point and not the FS root dir for the
node. It uses the get_vnode_name() function now (before resolving the
mount point).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20305 a95241bf-73f2-0310-859d-f6bbb57e9c96
to B_FULL_LOCK.
* vm_clone_area() now respects the source area's wiring and inherits it. This
should fix bug #1055.
* vm_cache::type is now duplicated in vm_area::cache_type - this allows looking
it up without having to lock a vm_cache_ref; this also solves a locking bug
in vm_unmap_pages() in this regard.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20281 a95241bf-73f2-0310-859d-f6bbb57e9c96
* Made the output look a bit more like that of the other commands.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20279 a95241bf-73f2-0310-859d-f6bbb57e9c96
Basically, there was a pretty subtle race between the cpus in main where if the main cpu released the AP cpus and then before the AP cpus had a chance to run the boot cpu started creating the main thread (which causes smp ici messages to be created) the system would livelock, where the boot cpu waited forever for the AP cpu to acknowledge the ICI (for a TLB flush when creating the kernel stack).
Added smp_cpu_rendezvous(), used to synchronize all the cpus to a particular point, and used it a few times in main().
While i was at it i fixed another race that'll probably never happen, but what the hey. Make sure the kernel args are copied into kernel space by the main cpu before letting any other ones use it.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20269 a95241bf-73f2-0310-859d-f6bbb57e9c96
* vm_area and vm_page now have a new field "mappings" where they will store lists
of vm_page_mapping structures. vm_page::ref_count is gone, as it's no longer
needed (it was never updated correctly, anyway).
* vm_caches now have a type field, ie. CACHE_TYPE_RAM for anonymous areas - this
makes the stores a bit less independent, but is quite handy in several places.
* Added new vm_map_page() and vm_unmap_pages() functions to be used whenever you
map in or unmap pages into/from an area. They don't do much more than handling
vm_page::wired_count correctly right now, though (ie. B_LAZY_LOCK is now working
as expected as well).
* Moved the device fault handler to vm_map_physical_memory(); it was not really
used as a fault handler, anyway.
* Didn't notice Ingo's changes to the I/O space region broke lock_memory(). It
now checks the type of the area that contains the memory, and doesn't lock
anymore if not needed which solves the problem in a platform independent way.
* Implemented lock_memory() and unlock_memory() for real: they now change the
vm_page::wired_count member to identify pages that shouldn't be paged out.
* vm_area_for() now uses vm_area_lookup() internally.
* Fixed various potential overflow conditions with areas that reach 0xffffffff.
* Creating anonymous areas with B_FULL_LOCK no longer causes vm_soft_fault()
to be called, instead, the pages are allocated and mapped (via vm_map_page())
directly.
* Removed the _vm_ prefix for create_area_struct() and create_reserved_area_struct().
* Fixed a bug in vm_page_write_modified() that would not have enqueued pages that
failed to be written to the modified queue again when needed.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20251 a95241bf-73f2-0310-859d-f6bbb57e9c96
opening bracket) - thanks!
* Shuffled functions a bit around to separate static and exported functions.
* Some other cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20245 a95241bf-73f2-0310-859d-f6bbb57e9c96
* Renamed them, made everything static besides vm_allocate_early() (previous
vm_alloc_from_kernel_args()) which now allows you to specify a different
virtual than physical size, and therefore makes vm_alloc_virtual_from_kernel_args()
superfluous (which isn't exported anymore, and is now called allocate_early_virtual()).
* Enabled printing a stack trace on serial output on team crash - it doesn't hurt
for now, anyway.
* Cleanup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20244 a95241bf-73f2-0310-859d-f6bbb57e9c96
The kernel arg logic was faulty, and wasn't using strlcpy properly (which returns the size of the src string, not the remaining size). Replaced it with a simpler, but less efficient series of strlcat()s.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20162 a95241bf-73f2-0310-859d-f6bbb57e9c96
The first use is to let the kernel decide what the preferred syscall mechanism is at boot time and copy the
appropriate user space code there. Can be used for routines the kernel can decide best how to use (memcpy, some
timing routines, etc).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20161 a95241bf-73f2-0310-859d-f6bbb57e9c96
the new cpuid stuff was apparently exacerbating an existing problem where various bits of low level
cpu code (specifically get_current_cpu) weren't really initialized before being used. Changed the
order to set up a fake set of threads to point each cpu at really early in boot to make sure that at
all points in code it can get the current 'thread' and thus the current cpu.
A probably better solution would be to have dr3 point to the current cpu which would then point to the
current thread, but that has a race condition that would require an int disable, etc.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20160 a95241bf-73f2-0310-859d-f6bbb57e9c96
away cpuid info into the current cpu structure. Trouble was the code was running before the current
thread pointer was set on each cpu, so it was always looking up cpu 0's structure and saving there,
leaving the other ones uninitialized. Surprisingly this works fine on my machine, but obviously fails
on others (cpuid info would have been zeroed probably). Solution is to change the order that things
are brought up on each cpu to set the current thread pointer first. I don't really like that solution
but it'll work for now. Added a comment to the effect.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20154 a95241bf-73f2-0310-859d-f6bbb57e9c96
Now two complete tss structures exist within the per-cpu structure. Instead
of having to create a seperate area per each one, initialize them in place.
Also, the old mechanism to getting all of the cpus to get initialized was
subtly broken, but still managed to work. Now, just force all the cpus to
initialize at boot, which makes the actual swapping of esp0 somewhat simpler.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20131 a95241bf-73f2-0310-859d-f6bbb57e9c96
* recursive_lock_unlock() now returns a void to mirror it's counterpart better;
use recursive_lock_get_recursion() if you're interested in the lock depth.
* switch_sem(), and release_sem() now don't do anything anymore in kernel startup
mode.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20099 a95241bf-73f2-0310-859d-f6bbb57e9c96
containing the Haiku SVN revision number which is used by uname(). The
value is 0 when built, but updated by the build system before copying
libroot to the image (new rule CopySetHaikuRevision).
* For AboutHaiku we no longer write the SVN revision number into a
resource. Instead we use the uname() info.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20082 a95241bf-73f2-0310-859d-f6bbb57e9c96
for one quantum wasn't really a good idea, as this could get quite expensive for the thread
(depending on the system load, it might have taken a long time until the thread was scheduled
again, no matter what priority it was).
Also, calling thread_yield() in a loop would have taken 100% CPU time.
Now, we sort the thread into the queue as with any other thread, but we'll ignore it once.
This now guarantees an actual context switch, as well as a much fairer rescheduling policy
for threads calling that function.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20077 a95241bf-73f2-0310-859d-f6bbb57e9c96
at boot, per cpu, detect the cpu, pull down all the relevant cpuid bits and
save them into the per-cpu structure. Changed most of the code scattered here
and there that reads the cpuid to use a new api, x86_check_feature, which looks
at the saved bits.
Also changed the system_info stuff to read from these bits.
While i was at it, refreshed all the bits to be current.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20072 a95241bf-73f2-0310-859d-f6bbb57e9c96
Replaced the _kern_null syscall with _kern_is_computer_on.
is_computer_on_fire is a bit harder, since it returns a float from kernelland, which
at the moment isn't supported in haiku.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20069 a95241bf-73f2-0310-859d-f6bbb57e9c96
I don't know why (or how) it could work before r19775, though.
This fixes the wrong return code from wait_for_thread() in most cases, and thus,
bug #1011.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20060 a95241bf-73f2-0310-859d-f6bbb57e9c96
does. Marcus, what problem did you encounter?
The BuildPXEstage1 actions use "as" ATM, which is not correct, since it
should actually use the target platform assembler (i.e.
cross-compilation won't work). It should be replaced by $(TARGET_CC),
but that results in the following errors, when compiling with gcc 2.95.3:
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:
Assembler messages:
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:39:
Error: missing ')'
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:96:
Error: `0x6(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:102:
Error: `0xa(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:127:
Error: `2(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:128:
Error: `0(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:147:
Error: `16(%ebx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:149:
Error: `20(%ebx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:173:
Error: `2(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:174:
Error: `0(%edx)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:298:
Error: `(%esi)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:299:
Error: `(%edi)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:306:
Error: `(%esi)' is not a valid 16 bit base/index expression
/home/bonefish/develop/haiku/haiku/src/system/boot/platform/pxe_ia32/pxe_stage1.S:307:
Error: `(%edi)' is not a valid 16 bit base/index expression
For the gcc 4 configuration all but the first errors disappear. It looks
like these are bugs in older assembler version. Any reasonable
work-around?
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20043 a95241bf-73f2-0310-859d-f6bbb57e9c96
* we now always flush the TLBs after having unmapped some pages.
* vm_soft_fault() could traverse to a source cache while it was being collapsed
by vm_cache_remove_consumer() - this is now no longer possible as the latter
marks the cache as busy when doing so, and the former now tests this flag and
locks the cache (via the new fault_acquire_locked_source() function).
* if fault_acquire_locked_source() fails with B_BUSY, the current cache is locked
again, and tested again for the page - as it might have been moved upwards to it
with the destruction of its former source.
* The cache delivering the page for vm_soft_fault() is now locked until the end;
it can no longer go away before having actually mapped the page into the area.
* This also fixes the issue where pages would get lost as vm_soft_fault() put the
page in the active list, no matter if its cache still existed.
* Also, we now keep a reference of to a cache in case a dummy page is inserted; this
makes again sure that it doesn't go away during the execution of vm_soft_fault()
(which could even add this page to the free list...).
* divided vm_soft_fault() into several smaller functions which should make it much
more readable.
* Added a "cache_chain" KDL command that dumps the whole chain until the bottom
when giving a pointer to a vm_cache as parameter.
* now usually call vm_cache_acquire_ref() before map_backing_store(), even though
it shouldn't be really needed (I added it for debugging purposes).
* Some minor cleanup.
* NOTE: a major problem still persists: when removing a vm_cache, it's possible
that some of its pages are still mapped, and there is currently no mechanism
to get rid of these mappings! I've added TODO comments into vm_cache.c where
appropriate.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20028 a95241bf-73f2-0310-859d-f6bbb57e9c96
Also prepare uname to return the build SVN revision number,
which will work only if I could figure out how to define it from Jamfile.
Or, better, in build/jam/BuildSetup.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20023 a95241bf-73f2-0310-859d-f6bbb57e9c96
The "lookup" option has been removed, there is now a "-p" for a physical address, and
"-v" for a virtual address.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20016 a95241bf-73f2-0310-859d-f6bbb57e9c96
process group. This fixes bug #996.
* As a result, the process group stuff and wait_for_child() got much simpler;
get_death_entry() and update_wait_for_any() could go away completely.
* If a team goes away, all of its children are now "reparented" to the kernel team,
instead of the team's parent - this follows common implementations (and POSIX if
I understand it correctly), but not BeOS anymore. The OpenGroup Base says this
about this topic: "If a parent process terminates without waiting for all of its
child processes to terminate, the remaining child processes shall be assigned a
new parent process ID corresponding to an implementation-defined system process."
* We wait too long in wait_test_4 which at least puts us on par with Linux; see
comment in _user_setpgid().
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20010 a95241bf-73f2-0310-859d-f6bbb57e9c96
ECHILD in case it doesn't. This fixes bug #995.
* Added a TODO item for solving bug #996.
* wait_for_child() did not release the team lock and restore interrupts in case
the child you wanted to wait for didn't exist...
* with child > 0, wait_for_child() will now check if its really a child of yours,
and not just in the same process group.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19993 a95241bf-73f2-0310-859d-f6bbb57e9c96
This fixes a possible crashing bug when an application with disconnected descriptors
quits.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19951 a95241bf-73f2-0310-859d-f6bbb57e9c96
We might want to remove it again once we have a replacement for it.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19929 a95241bf-73f2-0310-859d-f6bbb57e9c96
* Also, the output no longer has the leading "0x" to ease reading.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19906 a95241bf-73f2-0310-859d-f6bbb57e9c96
this fixes bug #227 again (which I recently opened again accidently).
* We actually switched the last consumer's source without having acquired its
lock! This fixes some rare random app crashes as well as potential kernel
crash ("cache to be deleted still has consumers").
* Some more comments to explain why things are done and can be done the way they
are done :-)
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19878 a95241bf-73f2-0310-859d-f6bbb57e9c96
its death entry into the parent team's queue - we need to do this atomically.
As an effect, wait_for_thread() sometimes failed with B_BAD_THREAD_ID.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19808 a95241bf-73f2-0310-859d-f6bbb57e9c96
so that this can be done safely.
It was also needed, as it would call vm_cache_release_ref() on failure which requires you
to have no vm_cache_ref locks around (as it might deadlock in this case).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19806 a95241bf-73f2-0310-859d-f6bbb57e9c96
had the cache_ref locked, it also locked two refs in the wrong order (bottom-up);
there was even a TODO item for this...
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19801 a95241bf-73f2-0310-859d-f6bbb57e9c96
* "sc"/"where"/"bt" now prints the area where the function of the stack frame
is located in case there is no other information (using the above function).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19800 a95241bf-73f2-0310-859d-f6bbb57e9c96
* even worse, in case of fork(), it was never initialized.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19799 a95241bf-73f2-0310-859d-f6bbb57e9c96
two cache_refs - it needs to count the consumers of the lower cache to find
its actual number of references; the upper cache could still be in use by
someone else.
* There were several locking bugs in the VM code; since cache_ref::cache can
change, we must not access it without having the cache_ref locked.
* As a result, map_backing_store() now requires you to have the lock of the
store's cache_ref held.
* And therefore, some functions in vm_cache.c must no longer lock the cache_ref
on their own, but require the caller to have it locked already.
* Added the -s option to the cache/cache_ref KDL commands: it will only print
the requested structure, and not its counterpart (useful if accessing one
structure results in a page fault, as was possible previously).
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19796 a95241bf-73f2-0310-859d-f6bbb57e9c96
waiting for in case it was interrupted; but that could easily lead the thread_exit()
function to access invalid memory (and thus, crash the kernel): since we could not
remove our death entry from the thread, we have to make sure the thread (which might
still run even if not in the thread hash anymore) will access our death entry as
long as it is valid. IOW we must wait for the thread to delete its exit semaphore,
even if we were interrupted before.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19790 a95241bf-73f2-0310-859d-f6bbb57e9c96