| Server IP : 152.69.216.235 / Your IP : 80.80.80.28 Web Server : Apache/2.4.37 (Oracle Linux Server) System : Linux ust-wp4-prod 5.15.0-310.184.5.2.el8uek.x86_64 #2 SMP Wed Jul 9 16:08:33 PDT 2025 x86_64 User : apache ( 48) PHP Version : 8.4.10 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/bin/ |
Upload File : |
#! /usr/bin/python3.6
# -*- coding: utf-8 -*-
# Copyright © 2015, 2019 Oracle and/or its affiliates. All rights reserved.
from __future__ import print_function
import argparse
import os
import sys
from ksplicelib.cron import cron_backoff
from ksplicelib.pager import output_to_pager
from ksplicelib.logger import KspliceClientError, Logger, NoUspliceTargetsKspliceClientError
from ksplicelib.config import KspliceConfig
from ksplicelib.pidlock import PIDLock, PIDLockFailed
from ksplicelib.utils import (
CoreDebugLog,
has_errors,
print_blacklisted,
print_errors,
)
from ksplicelib.version import KSPLICE_VERSION
KSPLICE_LOCK_FILE = '/var/lib/ksplice/lock'
from ksplicelib.user import ( # noqa
do_apply_user,
do_list_user,
do_remove_user,
do_show_user,
do_undo_user,
do_upgrade_user,
do_init_user,
manager_factory,
)
from ksplicelib.kernel import ( # noqa
do_apply_kernel,
do_list_kernel,
do_remove_kernel,
do_show_kernel,
do_uname_kernel,
do_undo_kernel,
do_upgrade_kernel,
do_init_kernel,
)
from ksplicelib.xen import ( # noqa
do_apply_xen,
do_list_xen,
do_show_xen,
do_undo_xen,
do_upgrade_xen,
do_remove_xen,
do_init_xen,
)
ERROR_UNKNOWN = 1
ERROR_INTERRUPT = 2
# This is inconsistent but the previous two errors aren't likely to ever occur
# together and it saves some bits for future use
ERROR_NO_BINARIES = 3
ERROR_KERNEL_FAIL = 4
ERROR_USERSPACE_FAIL = 8
ERROR_XEN_FAIL = 16
def do_init_all(args, config):
do_init_xen(args, config)
return 0
def do_list_all(args, config):
do_list_user(args, config)
do_list_kernel(args, config)
do_list_xen(args, config)
return 0
def do_show_all(args, config):
failed = False
print('Ksplice user-space updates:')
if do_show_user(args, config) != 0:
failed = True
print('\nKsplice kernel updates:')
if do_show_kernel(args, config) != 0:
failed = True
if do_show_xen(args, config) != 0:
failed = True
return -1 if failed else 0
def do_upgrade_all(args, config):
exit_code = 0
upgrade_result = do_upgrade_user(args, config)
if do_upgrade_kernel(args, config) != 0:
exit_code = exit_code | ERROR_KERNEL_FAIL
if config.xen_enabled and do_upgrade_xen(args, config) != 0:
exit_code = exit_code | ERROR_XEN_FAIL
if upgrade_result != 0:
exit_code = exit_code | ERROR_USERSPACE_FAIL
return exit_code
def do_remove_all(args, config):
failed = False
remove_result = do_remove_user(args, config)
if do_remove_kernel(args, config) != 0:
failed = True
if config.xen_enabled and do_remove_xen(args, config) != 0:
failed = True
if remove_result != 0:
failed = True
return -1 if failed else 0
def dispatch(args, config):
handler = globals().get('do_%s_%s' % (args.command, args.subsys))
if handler is None:
print('error: "{command}" not applicable to subsystem "{subsys}"'.format(command=args.command,
subsys=args.subsys))
else:
Logger().log.debug("Running %s %s." % (args.subsys, args.command))
pager_commands = ['list', 'show']
if args.command in pager_commands:
output_to_pager()
try:
with PIDLock(KSPLICE_LOCK_FILE):
return handler(args, config)
except PIDLockFailed:
Logger().log.error('Failed to lock {lockfile}, another instance of ksplice may be running'.format(lockfile=KSPLICE_LOCK_FILE))
return 1
return 0
def configure_logger(args):
try:
logger = Logger()
logger.configure(args)
except Exception:
print('Error: failed to configure the logger', file=sys.stderr)
sys.exit(1)
def main():
default_path = "/usr/sbin:/usr/bin:/sbin:/bin"
if 'PATH' not in os.environ or not os.environ['PATH']:
os.environ['PATH'] = default_path
else:
os.environ['PATH'] += ":" + default_path
parser = argparse.ArgumentParser(prog='ksplice')
parser.add_argument('subsys',
choices=['kernel', 'user', 'xen', 'all'],
help='Select what to patch, either the kernel, user-space, Xen hypervisor or all.',
default='all')
subparsers = parser.add_subparsers(title='subcommands',
description='valid subcommands',
metavar='{list-targets,uname,upgrade,remove,show}')
subparsers.required = True
parser.add_argument('--debug', help='Write a debug log file', type=str)
parser.add_argument('--yes', '-y', help='answer "yes" to all user prompts',
action='store_true', dest='yes', default=False)
parser.add_argument('--retries', type=int, default=0, metavar='max_retries',
help='Retry patching until all running processes are patched or exceeded maximum number of retries')
parser.add_argument('--no', '-n', help='answer "no" to all user prompts',
action='store_true', dest='no', default=False)
parser.add_argument('--verbose', '-v', help='provide more detail about what this program is doing',
action='count', default=0)
parser.add_argument('--quiet', '-q', help="don't print status messages",
action='store_true', default=False)
parser.add_argument('--version', action='version', version='Ksplice %s' % (KSPLICE_VERSION,))
parser.add_argument('--cron', help=argparse.SUPPRESS, action='store_true', default=False)
# Parser for list-targets
list_targets_parser = subparsers.add_parser('list-targets',
description='List Ksplice targets',
help='List all Ksplice capable targets in running processes')
list_targets_parser.add_argument('--pid', type=int,
help='PID to list targets for, omitting this option scans all processes')
list_targets_parser.add_argument('--target', type=str,
help='Target name to limit results to, omitting this option lists all targets')
list_targets_parser.set_defaults(func=dispatch, command='list')
# Parser for uname
uname_parser = subparsers.add_parser('uname',
description='Show the effective uname output for a patched kernel',
help='Show the effective uname output for the kernel after Ksplice updates have been applied.')
uname_parser.add_argument('-a', '--all', action='store_const', const='-a',
help='print all information, in the following order, except omit -p and -i if unknown')
uname_parser.add_argument('-s', '--kernel-name', action='store_const', const='-s',
help='print the kernel name')
uname_parser.add_argument('-n', '--nodename', action='store_const', const='-n',
help='print the network node hostname')
uname_parser.add_argument('-r', '--kernel-release', action='store_const', const='-r',
help='print the kernel release')
uname_parser.add_argument('-v', '--kernel-version', action='store_const', const='-v',
help='print the kernel version')
uname_parser.add_argument('-m', '--machine', action='store_const', const='-m',
help='print the machine hardware name')
uname_parser.add_argument('-p', '--processor', action='store_const', const='-p',
help='print the processor type or "unknown"')
uname_parser.add_argument('-i', '--hardware-platform', action='store_const', const='-i',
help='print the hardware platform or "unknown"')
uname_parser.add_argument('-o', '--operating-system', action='store_const', const='-o',
help='print the operating system')
uname_parser.set_defaults(func=dispatch, command='uname')
# Parser for upgrade
upgrade_parser = subparsers.add_parser('upgrade',
description='Upgrade the system with all available updates',
help='Fetch all available updates and apply them to the system')
upgrade_parser.add_argument('--pid', type=int,
help='PID to undo the update from, omitting this option undoes the update from all processes')
upgrade_parser.add_argument('--no-yum', action='store_true', default=False,
help=argparse.SUPPRESS)
# symbols that can be ignored if not
# on the call stack during stack check:
# format: <kid>:<target>:<symbol> where <target> could be empty
upgrade_parser.add_argument('--reliable-match', default=list(), action='append',
help=argparse.SUPPRESS)
upgrade_parser.set_defaults(func=dispatch, command='upgrade')
# Parser for remove
remove_parser = subparsers.add_parser('remove',
description='Remove selected updates from a running system',
help='Remove selected updates from a running system')
remove_parser.add_argument('--all', action='store_true', default=False,
help='take action for all updates')
remove_parser.add_argument('--pid', type=int,
help='PID to remove the updates from, omitting this option removes the updates from all processes')
remove_parser.add_argument('kids', nargs='*',
help='The Ksplice IDs of the updates to remove from the system')
# symbols that can be ignored if not
# on the call stack during stack check:
# format: <kid>:<target>:<symbol> where <target> could be empty
remove_parser.add_argument('--reliable-match', default=list(), action='append',
help=argparse.SUPPRESS)
remove_parser.set_defaults(func=dispatch, command='remove')
# Parser for apply
apply_parser = subparsers.add_parser('apply',
description='Apply a Ksplice update',
)
apply_parser.add_argument('--pid', type=int,
help='PID to apply the update on, omitting this option applies the update to all processes')
apply_parser.add_argument('--partial', action='store_true',
help='For kernel updates only, applies the update only to those modules which are loaded.')
# symbols that can be ignored if not on the call stack during stack check:
# format: <symbol>
apply_parser.add_argument('--reliable-match', default=list(), action='append',
help=argparse.SUPPRESS)
apply_parser.add_argument('update', nargs=1, help='The update tarball to apply')
apply_parser.set_defaults(func=dispatch, command='apply')
# Parser for undo
undo_parser = subparsers.add_parser('undo',
description='Undo a Ksplice update')
undo_parser.add_argument('--pid', type=int,
help='PID to undo the update from, omitting this option undoes the update from all processes')
undo_parser.add_argument('kid', nargs=1, help='The update KID to undo')
# symbols that can be ignored if not on the call stack during stack check:
# format: <symbol>
undo_parser.add_argument('--reliable-match', default=list(), action='append',
help=argparse.SUPPRESS)
undo_parser.set_defaults(func=dispatch, command='undo')
# Parser for show
show_parser = subparsers.add_parser('show',
description='Show installed Ksplice updates',
help='Show Ksplice updates that are installed for processes running on the system')
show_parser.add_argument('--pid', type=int,
help='PID to list updates for, omitting this option will show updates for all processes')
show_parser.add_argument('--available', action='store_const', const='--available',
help='Show the updates that are available to be installed')
show_parser.add_argument('--count', action='store_const', const='--count',
help=argparse.SUPPRESS)
show_parser.add_argument('--all', action='store_const', const='--all',
help=argparse.SUPPRESS)
show_parser.set_defaults(func=dispatch, command='show')
init_parser = subparsers.add_parser('init',
description='Init ksplice updates',
)
init_parser.add_argument('--check', action='store_true', dest='check_init', default=False,
help=argparse.SUPPRESS)
init_parser.set_defaults(func=dispatch, command='init')
args = parser.parse_args(sys.argv[1:])
if args.debug:
try:
os.unlink(args.debug)
except OSError:
pass
if args.cron:
args.quiet = True
configure_logger(args)
if args.cron and not cron_backoff.may_run():
Logger().log.debug("Server backoff time not met, will not run")
return 0
# Note that reliable-match option is not supported with subsys == "all"
if 'reliable_match' in args and args.reliable_match and args.subsys != 'user':
print(
'error: --reliable-match only compatible with ',
'user-space updates.',
file=sys.stderr
)
try:
config = KspliceConfig()
if args.cron:
if not config.autoinstall:
return 0
if args.subsys == 'xen' and not config.xen_enabled:
return 0
args.yes = config.autoinstall
args.no = not config.autoinstall
rc = args.func(args, config)
except NoUspliceTargetsKspliceClientError as e:
Logger().log.error('No active user-space Ksplice targets')
Logger().log.error('Have you installed Ksplice-aware libraries and rebooted?')
rc = ERROR_NO_BINARIES
except KspliceClientError as e:
# Pretty handle the exception
Logger().log.error(e)
Logger().log.debug("KspliceClientError: ", exc_info=1)
rc = ERROR_UNKNOWN
except KeyboardInterrupt:
# User-initiated
Logger().log.error("Interrupted!")
Logger().log.debug("", exc_info=1)
rc = ERROR_INTERRUPT
except SystemExit as e:
raise
except:
# Report and log all other exceptions
print("An unexpected error occured.", file=sys.stderr)
Logger().log.debug("Unexpected exception recieved.", exc_info=1)
rc = ERROR_UNKNOWN
if args.debug:
with open(args.debug, 'a') as debug:
debug.write(CoreDebugLog().all_debug())
return rc
if __name__ == '__main__':
sys.exit(main())