diff options
| author | Truong Q. Nguyen <Tony.Q.Nguyen@oracle.com> | 2010-08-15 15:24:34 -0700 |
|---|---|---|
| committer | Truong Q. Nguyen <Tony.Q.Nguyen@oracle.com> | 2010-08-15 15:24:34 -0700 |
| commit | 293e3ab30a546cd932ee22f9d54b3979fcb52095 (patch) | |
| tree | a509045412a652acdf3f37c300a1fbe5bd617783 /usr/src/cmd/svc | |
| parent | d996f1b8696f9ad4e65c250b117c690729ca40bf (diff) | |
| download | illumos-joyent-293e3ab30a546cd932ee22f9d54b3979fcb52095.tar.gz | |
6974613 manifest-import can be restructured to allow importing to alternate repository
6974718 svccfg core dump after upgrading to snv_145
Diffstat (limited to 'usr/src/cmd/svc')
| -rw-r--r-- | usr/src/cmd/svc/common/manifest_find.c | 36 | ||||
| -rw-r--r-- | usr/src/cmd/svc/common/manifest_find.h | 3 | ||||
| -rw-r--r-- | usr/src/cmd/svc/mfstscan/mfstscan.c | 21 | ||||
| -rw-r--r-- | usr/src/cmd/svc/milestone/manifest-import | 82 | ||||
| -rw-r--r-- | usr/src/cmd/svc/svccfg/svccfg_engine.c | 7 | ||||
| -rw-r--r-- | usr/src/cmd/svc/svccfg/svccfg_libscf.c | 58 |
6 files changed, 127 insertions, 80 deletions
diff --git a/usr/src/cmd/svc/common/manifest_find.c b/usr/src/cmd/svc/common/manifest_find.c index 4a47176d72..8933fb5807 100644 --- a/usr/src/cmd/svc/common/manifest_find.c +++ b/usr/src/cmd/svc/common/manifest_find.c @@ -240,9 +240,17 @@ process(const char *fn, const struct stat *sp, int ftw_type, * Note, however, that *arrayp will be set to NULL if the selection is * empty, and a count of 0 will be returned. In the case of failure, -1 * will be returned and errno will be set. + * + * This function takes a repository handle argument from the caller and saves + * that handle in a thread specific data structure. The thread specific + * repository handle is used in process() to communicate with the appropriate + * repository. Thus callers should take care of thread safety with respect to + * the repository handle. Currently, the two callers of find_manifests are both + * single threaded, i.e. svccfg and mfstscan, so thread safety not an issue. */ int -find_manifests(const char *dir, manifest_info_t ***arrayp, int flags) +find_manifests(scf_handle_t *hndl, const char *dir, + manifest_info_t ***arrayp, int flags) { mftsd_t *tsdp; int status = -1; @@ -254,28 +262,8 @@ find_manifests(const char *dir, manifest_info_t ***arrayp, int flags) tsdp->tsd_flags = flags; - /* - * Create a handle for use by mhast_test_file() if - * the flag is set to request hash checking be enabled. - */ if (tsdp->tsd_flags & CHECKHASH) { - tsdp->tsd_hndl = scf_handle_create(SCF_VERSION); - if (tsdp->tsd_hndl == NULL) { - if (scf_error() == SCF_ERROR_NO_MEMORY) { - errno = ENOMEM; - } else { - errno = EINVAL; - } - goto out; - } - if (scf_handle_bind(tsdp->tsd_hndl) != SCF_SUCCESS) { - if (scf_error() == SCF_ERROR_NO_RESOURCES) { - errno = ENOMEM; - } else { - errno = EINVAL; - } - goto out; - } + tsdp->tsd_hndl = hndl; } if (nftw(dir, process, MAX_DEPTH, FTW_MOUNT) == 0) { @@ -283,10 +271,6 @@ find_manifests(const char *dir, manifest_info_t ***arrayp, int flags) } out: - if (tsdp->tsd_hndl != NULL) { - (void) scf_handle_unbind(tsdp->tsd_hndl); - (void) scf_handle_destroy(tsdp->tsd_hndl); - } if (status == 0) { *arrayp = tsdp->tsd_array; count = tsdp->tsd_count; diff --git a/usr/src/cmd/svc/common/manifest_find.h b/usr/src/cmd/svc/common/manifest_find.h index 2f2ab434a9..87b269ca80 100644 --- a/usr/src/cmd/svc/common/manifest_find.h +++ b/usr/src/cmd/svc/common/manifest_find.h @@ -31,6 +31,7 @@ extern "C" { #endif #include <sys/types.h> +#include <libscf.h> #include "manifest_hash.h" #define CHECKHASH 0x1 @@ -50,7 +51,7 @@ typedef struct manifest_info { */ -int find_manifests(const char *, manifest_info_t ***, int); +int find_manifests(scf_handle_t *, const char *, manifest_info_t ***, int); void free_manifest_array(manifest_info_t **); #ifdef __cplusplus diff --git a/usr/src/cmd/svc/mfstscan/mfstscan.c b/usr/src/cmd/svc/mfstscan/mfstscan.c index 220bfb2624..70b21903d1 100644 --- a/usr/src/cmd/svc/mfstscan/mfstscan.c +++ b/usr/src/cmd/svc/mfstscan/mfstscan.c @@ -18,17 +18,17 @@ * * CDDL HEADER END */ + /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. */ - #include <sys/types.h> #include <errno.h> #include <fcntl.h> #include <libintl.h> +#include <libscf.h> #include <libuutil.h> #include <locale.h> #include <stdio.h> @@ -63,6 +63,7 @@ main(int argc, char *argv[]) { manifest_info_t **entry; manifest_info_t **manifests; + scf_handle_t *hndl = NULL; int i; int paths_walked = 0; struct stat sb; @@ -87,6 +88,13 @@ main(int argc, char *argv[]) if (optind >= argc) usage(); + if ((hndl = scf_handle_create(SCF_VERSION)) == NULL) + uu_die(gettext("Unexpected libscf error: %s. Exiting.\n"), + scf_strerror(scf_error())); + + if (scf_handle_bind(hndl) != SCF_SUCCESS) + uu_die(gettext("Couldn't bind to svc.configd.\n")); + for (i = optind; i < argc; i++) { if (tflag) { char *pname = mhash_filename_to_propname(argv[i], @@ -106,7 +114,7 @@ main(int argc, char *argv[]) continue; } - status = find_manifests(argv[i], &manifests, + status = find_manifests(hndl, argv[i], &manifests, CHECKHASH|CHECKEXT); if (status < 0) { uu_warn(gettext("file tree walk of %s encountered " @@ -129,5 +137,10 @@ main(int argc, char *argv[]) if (!paths_walked) uu_die(gettext("no paths walked\n")); + if (hndl != NULL) { + (void) scf_handle_unbind(hndl); + (void) scf_handle_destroy(hndl); + } + return (0); } diff --git a/usr/src/cmd/svc/milestone/manifest-import b/usr/src/cmd/svc/milestone/manifest-import index 705271f2a9..a9bf71ce7e 100644 --- a/usr/src/cmd/svc/milestone/manifest-import +++ b/usr/src/cmd/svc/milestone/manifest-import @@ -34,16 +34,37 @@ EMI_SERVICE="svc:/system/early-manifest-import:default" PROFILE_DIR_SITE="/etc/svc/profile/site" X= +ALT_REPOSITORY= +ALT_MFST_DIR= early=false [ "$SMF_FMRI" == "$EMI_SERVICE" ] && early=true -while getopts "n" opt; do + +usage() +{ + echo "Usage: /lib/svc/method/manifest-import [-n]" \ + "[-f repository-file -d manifest-directory]" + echo "\nOptions:" + echo "-n dryrun" + echo "-f and -d specify alternate repository and" \ + "manifest directory for import\n" + exit 2 +} + +while getopts "nd:f:" opt; do case $opt in n) X=echo;; - ?) echo "Usage: /lib/svc/method/manifest-import [-n]\n" - exit 2;; + d) ALT_MFST_DIR=$OPTARG;; + f) ALT_REPOSITORY=$OPTARG;; + ?) usage;; esac done +# +# Both -f and -d options must be specified together or not specified at all +# +[ -n "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ] && usage +[ -n "$ALT_MFST_DIR" -a -z "$ALT_REPOSITORY" ] && usage + function svccfg_apply { $X /usr/sbin/svccfg apply $1 if [ $? -ne 0 ]; then @@ -178,16 +199,17 @@ function preserve_system_profiles { # function import_manifests { typeset basedir=$1 + typeset console_print=$2 typeset logf="/etc/svc/volatile/manifest_import.$$" rm -f $logf - nonsite_dirs=`/usr/bin/find $basedir/svc/manifest/* -name site \ + nonsite_dirs=`/usr/bin/find $basedir/* -name site \ -prune -o -type d -print -prune` if [ -n "$_MFST_DEBUG" ]; then nonsite_manifests=`/lib/svc/bin/mfstscan $nonsite_dirs` - site_manifests=`/lib/svc/bin/mfstscan $basedir/svc/manifest/site` + site_manifests=`/lib/svc/bin/mfstscan $basedir/site` manifests="$nonsite_manifests $site_manifests" @@ -196,18 +218,24 @@ function import_manifests { fi # - # Attempt of moving the repository to tmpfs. If that doesn't - # work, reset doswitch so we don't attempt switching back. + # Upon boot, attempt to move the repository to tmpfs. # - /usr/sbin/svcadm _smf_repository_switch fast - doswitch=$? + if [ -z "$ALT_REPOSITORY" -a -z "$ALT_MFST_DIR" ]; then + /usr/sbin/svcadm _smf_repository_switch fast + fi # # Import the manifests while giving a running display of imports on # console, and a final count in the logfile. # - dirs="$nonsite_dirs $basedir/svc/manifest/site" - $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1 + dirs="$nonsite_dirs" + [ -d "$basedir/site" ] && dirs="$dirs $basedir/site" + + if [ "$console_print" = "true" ]; then + $X /usr/sbin/svccfg import -p /dev/msglog $dirs > $logf 2>&1 + else + $X /usr/sbin/svccfg import $dirs > $logf 2>&1 + fi grep "Loaded .*. smf(5) service descriptions" $logf > /dev/null 2>&1 if [ $? -eq 0 ]; then @@ -222,7 +250,7 @@ function import_manifests { fi cat $logf - if [ $failures -eq 0 ]; then + if [ $failures -eq 0 -a "$console_print" = "true" ]; then msg="svccfg import warnings. See" msg="$msg /var/svc/log/system-manifest-import:default.log ." echo $msg > /dev/msglog @@ -323,10 +351,10 @@ function handle_upgrade { # under /etc/svc/profile/site directory. # function apply_site_profile { - typeset prefix="$1/svc/profile" + typeset prefix="$1" [ -f $prefix/site.xml ] && svccfg_apply $prefix/site.xml - if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc" ]; then + if [ -d $PROFILE_DIR_SITE -a "$1" = "/etc/svc/profile" ]; then svccfg_apply $PROFILE_DIR_SITE fi } @@ -401,33 +429,45 @@ if [ "$early" = "false" ]; then fi # +# If the alternate repository and directory are specified, simply set +# SVCCFG_REPOSITORY env, run svccfg import on the given directory, and +# exit. +# +if [ -n "$ALT_REPOSITORY" -a -n "$ALT_MFST_DIR" ]; then + SVCCFG_REPOSITORY=$ALT_REPOSITORY export SVCCFG_REPOSITORY + import_manifests "$ALT_MFST_DIR" false + unset SVCCFG_REPOSITORY + exit 0 +fi + +# # Call import and apply profiles here # if [ "$early" = "true" ]; then - import_manifests "/lib" + import_manifests "/lib/svc/manifest" true apply_profile - apply_site_profile "/etc" + apply_site_profile "/etc/svc/profile" else # - # Process both /lib/svc and /var/svc + # Process both /lib/svc/manifest and /var/svc/manifest # during late manifest-import # # First import the manifests # - import_manifests "/lib" - import_manifests "/var" + import_manifests "/lib/svc/manifest" true + import_manifests "/var/svc/manifest" true # # Apply profiles # apply_profile - apply_site_profile "/etc" + apply_site_profile "/etc/svc/profile" # # Run the upgrade script # handle_upgrade - apply_site_profile "/var" + apply_site_profile "/var/svc/profile" fi diff --git a/usr/src/cmd/svc/svccfg/svccfg_engine.c b/usr/src/cmd/svc/svccfg/svccfg_engine.c index c05100a502..6d8e9d1c9b 100644 --- a/usr/src/cmd/svc/svccfg/svccfg_engine.c +++ b/usr/src/cmd/svc/svccfg/svccfg_engine.c @@ -725,7 +725,8 @@ engine_import(uu_list_t *args) } /* Get list of manifests that we should import for this path. */ - if ((count = find_manifests(file, &manifests, fm_flags)) < 0) { + if ((count = find_manifests(g_hndl, file, &manifests, + fm_flags)) < 0) { if (isdir) { semerr(gettext("Could not hash directory %s\n"), file); @@ -929,7 +930,9 @@ engine_apply(const char *file, int apply_changes) } /* Get list of profiles to be applied. */ - if ((profile_count = find_manifests(file, &profiles, fm_flags)) < 0) { + if ((profile_count = find_manifests(g_hndl, file, &profiles, + fm_flags)) < 0) { + if (isdir) { semerr(gettext("Could not hash directory %s\n"), file); } else { diff --git a/usr/src/cmd/svc/svccfg/svccfg_libscf.c b/usr/src/cmd/svc/svccfg/svccfg_libscf.c index 3c276c02ab..9b04203a07 100644 --- a/usr/src/cmd/svc/svccfg/svccfg_libscf.c +++ b/usr/src/cmd/svc/svccfg/svccfg_libscf.c @@ -16207,7 +16207,7 @@ create_manifest_tree(void) * is supported by multiple manifest files. */ for (c = 0; dirs[c]; c++) { - status = find_manifests(dirs[c], &manifests, CHECKEXT); + status = find_manifests(g_hndl, dirs[c], &manifests, CHECKEXT); if (status < 0) { uu_warn(gettext("file tree walk of %s encountered " "error %s\n"), dirs[c], strerror(errno)); @@ -17054,8 +17054,8 @@ lscf_hash_cleanup() scf_property_t *prop; scf_value_t *val; scf_iter_t *iter; - char *pgname; - char *mfile; + char *pgname = NULL; + char *mfile = NULL; int r; svc = scf_service_create(g_hndl); @@ -17148,39 +17148,45 @@ lscf_hash_cleanup() if (scf_property_get_value(prop, val) != SCF_SUCCESS) { uu_warn(gettext("Unable to get value from %s\n"), pgname); - goto error_handle; + + switch (scf_error()) { + case SCF_ERROR_DELETED: + case SCF_ERROR_CONSTRAINT_VIOLATED: + case SCF_ERROR_NOT_FOUND: + case SCF_ERROR_NOT_SET: + continue; + + case SCF_ERROR_CONNECTION_BROKEN: + r = scferror2errno(scf_error()); + goto out; + + case SCF_ERROR_HANDLE_MISMATCH: + case SCF_ERROR_NOT_BOUND: + default: + bad_error("scf_property_get_value", + scf_error()); + } } - if (scf_value_get_astring(val, mfile, max_scf_value_len + 1) == - -1) { + if (scf_value_get_astring(val, mfile, max_scf_value_len + 1) + == -1) { uu_warn(gettext("Unable to get astring from %s : %s\n"), pgname, scf_strerror(scf_error())); - goto error_handle; + + switch (scf_error()) { + case SCF_ERROR_NOT_SET: + case SCF_ERROR_TYPE_MISMATCH: + continue; + + default: + bad_error("scf_value_get_astring", scf_error()); + } } if (access(mfile, F_OK) == 0) continue; (void) scf_pg_delete(pg); - -error_handle: - switch (scf_error()) { - case SCF_ERROR_DELETED: - case SCF_ERROR_CONSTRAINT_VIOLATED: - case SCF_ERROR_NOT_FOUND: - case SCF_ERROR_NOT_SET: - continue; - - case SCF_ERROR_CONNECTION_BROKEN: - r = scferror2errno(scf_error()); - goto out; - - case SCF_ERROR_HANDLE_MISMATCH: - case SCF_ERROR_NOT_BOUND: - default: - bad_error("scf_value_get_astring", - scf_error()); - } } out: |
