usr/src/uts/common/fs/zfs/spa_history.c
changeset 12296 7cf402a7f374
parent 11937 ee1b786b1783
child 13509 04570f5cbeca
equal deleted inserted replaced
12295:e16f396f04a1 12296:7cf402a7f374
    18  *
    18  *
    19  * CDDL HEADER END
    19  * CDDL HEADER END
    20  */
    20  */
    21 
    21 
    22 /*
    22 /*
    23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
    23  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
    24  * Use is subject to license terms.
       
    25  */
    24  */
    26 
    25 
    27 #include <sys/spa.h>
    26 #include <sys/spa.h>
    28 #include <sys/spa_impl.h>
    27 #include <sys/spa_impl.h>
    29 #include <sys/zap.h>
    28 #include <sys/zap.h>
    31 #include <sys/dmu_tx.h>
    30 #include <sys/dmu_tx.h>
    32 #include <sys/dmu_objset.h>
    31 #include <sys/dmu_objset.h>
    33 #include <sys/utsname.h>
    32 #include <sys/utsname.h>
    34 #include <sys/cmn_err.h>
    33 #include <sys/cmn_err.h>
    35 #include <sys/sunddi.h>
    34 #include <sys/sunddi.h>
       
    35 #include "zfs_comutil.h"
    36 #ifdef _KERNEL
    36 #ifdef _KERNEL
    37 #include <sys/zone.h>
    37 #include <sys/zone.h>
    38 #endif
    38 #endif
    39 
    39 
    40 /*
    40 /*
   187 /*
   187 /*
   188  * Write out a history event.
   188  * Write out a history event.
   189  */
   189  */
   190 /*ARGSUSED*/
   190 /*ARGSUSED*/
   191 static void
   191 static void
   192 spa_history_log_sync(void *arg1, void *arg2, cred_t *cr, dmu_tx_t *tx)
   192 spa_history_log_sync(void *arg1, void *arg2, dmu_tx_t *tx)
   193 {
   193 {
   194 	spa_t		*spa = arg1;
   194 	spa_t		*spa = arg1;
   195 	history_arg_t	*hap = arg2;
   195 	history_arg_t	*hap = arg2;
   196 	const char	*history_str = hap->ha_history_str;
   196 	const char	*history_str = hap->ha_history_str;
   197 	objset_t	*mos = spa->spa_meta_objset;
   197 	objset_t	*mos = spa->spa_meta_objset;
   242 #endif
   242 #endif
   243 	if (hap->ha_log_type == LOG_CMD_POOL_CREATE ||
   243 	if (hap->ha_log_type == LOG_CMD_POOL_CREATE ||
   244 	    hap->ha_log_type == LOG_CMD_NORMAL) {
   244 	    hap->ha_log_type == LOG_CMD_NORMAL) {
   245 		VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_CMD,
   245 		VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_CMD,
   246 		    history_str) == 0);
   246 		    history_str) == 0);
       
   247 
       
   248 		zfs_dbgmsg("command: %s", history_str);
   247 	} else {
   249 	} else {
   248 		VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_INT_EVENT,
   250 		VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_INT_EVENT,
   249 		    hap->ha_event) == 0);
   251 		    hap->ha_event) == 0);
   250 		VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_TXG,
   252 		VERIFY(nvlist_add_uint64(nvrecord, ZPOOL_HIST_TXG,
   251 		    tx->tx_txg) == 0);
   253 		    tx->tx_txg) == 0);
   252 		VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_INT_STR,
   254 		VERIFY(nvlist_add_string(nvrecord, ZPOOL_HIST_INT_STR,
   253 		    history_str) == 0);
   255 		    history_str) == 0);
       
   256 
       
   257 		zfs_dbgmsg("internal %s pool:%s txg:%llu %s",
       
   258 		    zfs_history_event_names[hap->ha_event], spa_name(spa),
       
   259 		    (longlong_t)tx->tx_txg, history_str);
       
   260 
   254 	}
   261 	}
   255 
   262 
   256 	VERIFY(nvlist_size(nvrecord, &reclen, NV_ENCODE_XDR) == 0);
   263 	VERIFY(nvlist_size(nvrecord, &reclen, NV_ENCODE_XDR) == 0);
   257 	record_packed = kmem_alloc(reclen, KM_SLEEP);
   264 	record_packed = kmem_alloc(reclen, KM_SLEEP);
   258 
   265 
   416 	return (err);
   423 	return (err);
   417 }
   424 }
   418 
   425 
   419 static void
   426 static void
   420 log_internal(history_internal_events_t event, spa_t *spa,
   427 log_internal(history_internal_events_t event, spa_t *spa,
   421     dmu_tx_t *tx, cred_t *cr, const char *fmt, va_list adx)
   428     dmu_tx_t *tx, const char *fmt, va_list adx)
   422 {
   429 {
   423 	history_arg_t *ha;
   430 	history_arg_t *ha;
   424 
   431 
   425 	/*
   432 	/*
   426 	 * If this is part of creating a pool, not everything is
   433 	 * If this is part of creating a pool, not everything is
   439 	ha->ha_event = event;
   446 	ha->ha_event = event;
   440 	ha->ha_zone = NULL;
   447 	ha->ha_zone = NULL;
   441 	ha->ha_uid = 0;
   448 	ha->ha_uid = 0;
   442 
   449 
   443 	if (dmu_tx_is_syncing(tx)) {
   450 	if (dmu_tx_is_syncing(tx)) {
   444 		spa_history_log_sync(spa, ha, cr, tx);
   451 		spa_history_log_sync(spa, ha, tx);
   445 	} else {
   452 	} else {
   446 		dsl_sync_task_do_nowait(spa_get_dsl(spa), NULL,
   453 		dsl_sync_task_do_nowait(spa_get_dsl(spa), NULL,
   447 		    spa_history_log_sync, spa, ha, 0, tx);
   454 		    spa_history_log_sync, spa, ha, 0, tx);
   448 	}
   455 	}
   449 	/* spa_history_log_sync() will free ha and strings */
   456 	/* spa_history_log_sync() will free ha and strings */
   450 }
   457 }
   451 
   458 
   452 void
   459 void
   453 spa_history_internal_log(history_internal_events_t event, spa_t *spa,
   460 spa_history_log_internal(history_internal_events_t event, spa_t *spa,
   454     dmu_tx_t *tx, cred_t *cr, const char *fmt, ...)
   461     dmu_tx_t *tx, const char *fmt, ...)
   455 {
   462 {
   456 	dmu_tx_t *htx = tx;
   463 	dmu_tx_t *htx = tx;
   457 	va_list adx;
   464 	va_list adx;
   458 
   465 
   459 	/* create a tx if we didn't get one */
   466 	/* create a tx if we didn't get one */
   464 			return;
   471 			return;
   465 		}
   472 		}
   466 	}
   473 	}
   467 
   474 
   468 	va_start(adx, fmt);
   475 	va_start(adx, fmt);
   469 	log_internal(event, spa, htx, cr, fmt, adx);
   476 	log_internal(event, spa, htx, fmt, adx);
   470 	va_end(adx);
   477 	va_end(adx);
   471 
   478 
   472 	/* if we didn't get a tx from the caller, commit the one we made */
   479 	/* if we didn't get a tx from the caller, commit the one we made */
   473 	if (tx == NULL)
   480 	if (tx == NULL)
   474 		dmu_tx_commit(htx);
   481 		dmu_tx_commit(htx);
   479 {
   486 {
   480 #ifdef _KERNEL
   487 #ifdef _KERNEL
   481 	uint64_t current_vers = spa_version(spa);
   488 	uint64_t current_vers = spa_version(spa);
   482 
   489 
   483 	if (current_vers >= SPA_VERSION_ZPOOL_HISTORY) {
   490 	if (current_vers >= SPA_VERSION_ZPOOL_HISTORY) {
   484 		spa_history_internal_log(event, spa, NULL, CRED(),
   491 		spa_history_log_internal(event, spa, NULL,
   485 		    "pool spa %llu; zfs spa %llu; zpl %d; uts %s %s %s %s",
   492 		    "pool spa %llu; zfs spa %llu; zpl %d; uts %s %s %s %s",
   486 		    (u_longlong_t)current_vers, SPA_VERSION, ZPL_VERSION,
   493 		    (u_longlong_t)current_vers, SPA_VERSION, ZPL_VERSION,
   487 		    utsname.nodename, utsname.release, utsname.version,
   494 		    utsname.nodename, utsname.release, utsname.version,
   488 		    utsname.machine);
   495 		    utsname.machine);
   489 	}
   496 	}