diff --git a/mysql-test/r/log_state.result b/mysql-test/r/log_state.result
new file mode 100644
index 0000000000000000000000000000000000000000..df81f05fea5a85572df8429367f3aada1a4c96d1
--- /dev/null
+++ b/mysql-test/r/log_state.result
@@ -0,0 +1,155 @@
+set global general_log= OFF;
+truncate table mysql.general_log;
+truncate table mysql.slow_log;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+Variable_name	Value
+general_log	OFF
+log	OFF
+log_slow_queries	OFF
+slow_query_log	OFF
+flush logs;
+set global general_log= ON;
+create table t1(f1 int);
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
+TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
+set global general_log= OFF;
+drop table t1;
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
+TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
+TIMESTAMP	root[root] @ localhost []	#	1	Query	set global general_log= OFF
+set global general_log= ON;
+flush logs;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+Variable_name	Value
+general_log	ON
+log	ON
+log_slow_queries	OFF
+slow_query_log	OFF
+set session long_query_time=1;
+select sleep(2);
+sleep(2)
+0
+select * from mysql.slow_log;
+start_time	user_host	query_time	lock_time	rows_sent	rows_examined	db	last_insert_id	insert_id	server_id	sql_text
+set global slow_query_log= ON;
+set session long_query_time=1;
+select sleep(2);
+sleep(2)
+0
+select * from mysql.slow_log;
+start_time	user_host	query_time	lock_time	rows_sent	rows_examined	db	last_insert_id	insert_id	server_id	sql_text
+TIMESTAMP,	root[root] @ localhost []	USER_HOST,	QUERY_TIME	1	0	test	0	0	1	select sleep(2)
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+Variable_name	Value
+general_log	ON
+log	ON
+log_slow_queries	ON
+slow_query_log	ON
+set global general_log= ON;
+set global general_log= OFF;
+set global general_log= OFF;
+set global slow_query_log= ON;
+set global slow_query_log= OFF;
+set global slow_query_log= OFF;
+set global general_log= ON;
+truncate table mysql.general_log;
+create table t1(f1 int);
+drop table t1;
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+TIMESTAMP	root[root] @ localhost []	#	1	Query	create table t1(f1 int)
+TIMESTAMP	root[root] @ localhost []	#	1	Query	drop table t1
+TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
+set global general_log= OFF;
+truncate table mysql.general_log;
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+set global general_log= ON;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+Variable_name	Value
+general_log	ON
+log	ON
+log_slow_queries	OFF
+slow_query_log	OFF
+show variables like 'general_log_file';
+Variable_name	Value
+general_log_file	#
+show variables like 'slow_query_log_file';
+Variable_name	Value
+slow_query_log_file	#
+show variables like 'log_output';
+Variable_name	Value
+log_output	FILE,TABLE
+set global general_log_file='/not exiting path/log.master';
+ERROR 42000: Variable 'general_log_file' can't be set to the value of '/not exiting path/log.master'
+set global general_log_file='/tmp';
+ERROR 42000: Variable 'general_log_file' can't be set to the value of '/tmp'
+set global general_log_file='';
+ERROR 42000: Variable 'general_log_file' can't be set to the value of ''
+show variables like 'general_log_file';
+Variable_name	Value
+general_log_file	#
+set global general_log= OFF;
+set global general_log_file='/tmp/log.master';
+set global general_log= ON;
+create table t1(f1 int);
+drop table t1;
+set global general_log= OFF;
+set global general_log_file=default;
+set global general_log= ON;
+create table t1(f1 int);
+drop table t1;
+show variables like 'general_log_file';
+Variable_name	Value
+general_log_file	#
+show variables like 'slow_query_log_file';
+Variable_name	Value
+slow_query_log_file	#
+set global general_log= default;
+set global slow_query_log= default;
+set global general_log_file= default;
+set global slow_query_log_file= default;
+show variables like 'general_log';
+Variable_name	Value
+general_log	OFF
+show variables like 'slow_query_log';
+Variable_name	Value
+slow_query_log	OFF
+set global general_log=ON;
+set global log_output=default;
+show variables like 'log_output';
+Variable_name	Value
+log_output	TABLE
+set global general_log=OFF;
+set global log_output=FILE;
+truncate table mysql.general_log;
+show variables like 'log_output';
+Variable_name	Value
+log_output	FILE
+set global general_log=ON;
+create table t1(f1 int);
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+set global general_log=OFF;
+set global log_output="FILE,TABLE";
+show variables like 'log_output';
+Variable_name	Value
+log_output	FILE,TABLE
+set global general_log=ON;
+drop table t1;
+select * from mysql.general_log;
+event_time	user_host	thread_id	server_id	command_type	argument
+TIMESTAMP	root[root] @ localhost []	#	1	Query	drop table t1
+TIMESTAMP	root[root] @ localhost []	#	1	Query	select * from mysql.general_log
diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result
index 5dcb8b2afd6a1fe7533d7a29843102f8ca54864e..154bd99a7f3efefa8fa54fe8bb24bdacba2ffa29 100644
--- a/mysql-test/r/show_check.result
+++ b/mysql-test/r/show_check.result
@@ -148,14 +148,12 @@ flush tables;
 show open tables;
 Database	Table	In_use	Name_locked
 mysql	general_log	1	0
-mysql	slow_log	1	0
 create table t1(n int);
 insert into t1 values (1);
 show open tables;
 Database	Table	In_use	Name_locked
-mysql	general_log	1	0
-mysql	slow_log	1	0
 test	t1	0	0
+mysql	general_log	1	0
 drop table t1;
 create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed;
 show create table t1;
@@ -568,23 +566,21 @@ SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone
 1
 SHOW OPEN TABLES;
 Database	Table	In_use	Name_locked
-mysql	proc	0	0
+mysql	db	0	0
 test	urkunde	0	0
 mysql	time_zone	0	0
-mysql	db	0	0
+mysql	general_log	1	0
 test	txt1	0	0
-mysql	slow_log	1	0
+mysql	proc	0	0
 test	tyt2	0	0
-mysql	general_log	1	0
 mysql	user	0	0
 mysql	time_zone_name	0	0
 SHOW OPEN TABLES FROM mysql;
 Database	Table	In_use	Name_locked
-mysql	proc	0	0
-mysql	time_zone	0	0
 mysql	db	0	0
-mysql	slow_log	1	0
+mysql	time_zone	0	0
 mysql	general_log	1	0
+mysql	proc	0	0
 mysql	user	0	0
 mysql	time_zone_name	0	0
 SHOW OPEN TABLES FROM mysql LIKE 'u%';
@@ -598,16 +594,14 @@ test	tyt2	0	0
 mysql	time_zone_name	0	0
 SHOW OPEN TABLES LIKE '%o%';
 Database	Table	In_use	Name_locked
-mysql	proc	0	0
 mysql	time_zone	0	0
-mysql	slow_log	1	0
 mysql	general_log	1	0
+mysql	proc	0	0
 mysql	time_zone_name	0	0
 FLUSH TABLES;
 SHOW OPEN TABLES;
 Database	Table	In_use	Name_locked
 mysql	general_log	1	0
-mysql	slow_log	1	0
 DROP TABLE txt1;
 DROP TABLE tyt2;
 DROP TABLE urkunde;
diff --git a/mysql-test/t/log_state-master.opt b/mysql-test/t/log_state-master.opt
new file mode 100644
index 0000000000000000000000000000000000000000..445c6223d4727e70f328f871cf34de201df6f3c0
--- /dev/null
+++ b/mysql-test/t/log_state-master.opt
@@ -0,0 +1 @@
+--log-output=TABLE,FILE --log --general-log=0 --log-slow-queries --slow-query-log=0
diff --git a/mysql-test/t/log_state.test b/mysql-test/t/log_state.test
new file mode 100644
index 0000000000000000000000000000000000000000..d3dec841dc124ca3677f51c9d90554b14d8c39f1
--- /dev/null
+++ b/mysql-test/t/log_state.test
@@ -0,0 +1,122 @@
+-- source include/not_embedded.inc
+--source include/have_csv.inc
+
+--disable_ps_protocol
+set global general_log= OFF;
+truncate table mysql.general_log;
+truncate table mysql.slow_log;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+flush logs;
+set global general_log= ON;
+create table t1(f1 int);
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+set global general_log= OFF;
+drop table t1;
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+set global general_log= ON;
+flush logs;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+
+connect (con1,localhost,root,,);
+connection con1;
+set session long_query_time=1;
+select sleep(2);
+--replace_column 1 TIMESTAMP, 3 USER_HOST, 4 QUERY_TIME
+select * from mysql.slow_log;
+connection default;
+
+set global slow_query_log= ON;
+connection con1;
+set session long_query_time=1;
+select sleep(2);
+--replace_column 1 TIMESTAMP, 3 USER_HOST, 4 QUERY_TIME
+select * from mysql.slow_log;
+disconnect con1;
+connection default;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+
+set global general_log= ON;
+set global general_log= OFF;
+set global general_log= OFF;
+set global slow_query_log= ON;
+set global slow_query_log= OFF;
+set global slow_query_log= OFF;
+
+set global general_log= ON;
+truncate table mysql.general_log;
+create table t1(f1 int);
+drop table t1;
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+set global general_log= OFF;
+truncate table mysql.general_log;
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+set global general_log= ON;
+show global variables
+where Variable_name = 'log' or Variable_name = 'log_slow_queries' or
+Variable_name = 'general_log' or Variable_name = 'slow_query_log';
+
+--replace_column 2 #
+show variables like 'general_log_file';
+--replace_column 2 #
+show variables like 'slow_query_log_file';
+show variables like 'log_output';
+
+--error 1231
+set global general_log_file='/not exiting path/log.master';
+--error 1231
+set global general_log_file='/tmp';
+--error 1231
+set global general_log_file='';
+--replace_column 2 #
+show variables like 'general_log_file';
+set global general_log= OFF;
+set global general_log_file='/tmp/log.master';
+set global general_log= ON;
+create table t1(f1 int);
+drop table t1;
+set global general_log= OFF;
+set global general_log_file=default;
+set global general_log= ON;
+create table t1(f1 int);
+drop table t1;
+--replace_column 2 #
+show variables like 'general_log_file';
+--replace_column 2 #
+show variables like 'slow_query_log_file';
+
+set global general_log= default;
+set global slow_query_log= default;
+set global general_log_file= default;
+set global slow_query_log_file= default;
+show variables like 'general_log';
+show variables like 'slow_query_log';
+set global general_log=ON;
+set global log_output=default;
+show variables like 'log_output';
+set global general_log=OFF;
+set global log_output=FILE;
+truncate table mysql.general_log;
+show variables like 'log_output';
+set global general_log=ON;
+create table t1(f1 int);
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+set global general_log=OFF;
+set global log_output="FILE,TABLE";
+show variables like 'log_output';
+set global general_log=ON;
+drop table t1;
+--replace_column 1 TIMESTAMP 3 #
+select * from mysql.general_log;
+
+--enable_ps_protocol
diff --git a/sql/log.cc b/sql/log.cc
index 5a17ef817d05d711731ee5364ea912549052bf5e..c6c63ceb9292c2386813b96049235a77494268f7 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -37,9 +37,6 @@
 #define MAX_USER_HOST_SIZE 512
 #define MAX_TIME_SIZE 32
 
-/* we need this for log files intialization */
-extern char *opt_logname, *opt_slow_logname;
-
 LOGGER logger;
 
 MYSQL_LOG mysql_bin_log;
@@ -63,6 +60,13 @@ sql_print_message_func sql_print_message_handlers[3] =
 };
 
 
+char *make_default_log_name(char *buff,const char* log_ext)
+{
+  strmake(buff, glob_hostname, FN_REFLEN-5);
+  return fn_format(buff, buff, mysql_data_home, log_ext,
+                   MYF(MY_UNPACK_FILENAME|MY_APPEND_EXT));
+}
+
 /*
   This is a POD. Please keep it that way!
 
@@ -250,8 +254,10 @@ bool Log_to_csv_event_handler::reopen_log_table(uint log_type)
 
 void Log_to_csv_event_handler::cleanup()
 {
-  close_log_table(QUERY_LOG_GENERAL, FALSE);
-  close_log_table(QUERY_LOG_SLOW, FALSE);
+  if (opt_log)
+    close_log_table(QUERY_LOG_GENERAL, FALSE);
+  if (opt_slow_log)
+    close_log_table(QUERY_LOG_SLOW, FALSE);
   logger.is_log_tables_initialized= FALSE;
 }
 
@@ -505,10 +511,10 @@ bool Log_to_file_event_handler::init()
   if (!is_initialized)
   {
     if (opt_slow_log)
-      mysql_slow_log.open_slow_log(opt_slow_logname);
+      mysql_slow_log.open_slow_log(sys_var_slow_log_path.value);
 
     if (opt_log)
-      mysql_log.open_query_log(opt_logname);
+      mysql_log.open_query_log(sys_var_general_log_path.value);
 
     is_initialized= TRUE;
   }
@@ -526,8 +532,10 @@ void Log_to_file_event_handler::cleanup()
 void Log_to_file_event_handler::flush()
 {
   /* reopen log files */
-  mysql_log.new_file(1);
-  mysql_slow_log.new_file(1);
+  if (opt_log)
+    mysql_log.new_file(1);
+  if (opt_slow_log)
+    mysql_slow_log.new_file(1);
 }
 
 /*
@@ -647,10 +655,7 @@ bool LOGGER::flush_logs(THD *thd)
   close_general_log.db= (char*) "mysql";
   close_general_log.db_length= 5;
 
-  /* reopen log files */
-  file_log_handler->flush();
-
-  /* flush tables, in the case they are enabled */
+  /* lock tables, in the case they are enabled */
   if (logger.is_log_tables_initialized)
   {
     /*
@@ -663,23 +668,29 @@ bool LOGGER::flush_logs(THD *thd)
       Here we use one of the logger handler THD's. Simply because it
       seems appropriate.
     */
-    lock_and_wait_for_table_name(table_log_handler->general_log_thd,
-                                 &close_slow_log);
-    lock_and_wait_for_table_name(table_log_handler->general_log_thd,
-                                 &close_general_log);
+    if (opt_slow_log)
+      lock_and_wait_for_table_name(table_log_handler->general_log_thd,
+				   &close_slow_log);
+    if (opt_log)
+      lock_and_wait_for_table_name(table_log_handler->general_log_thd,
+				   &close_general_log);
+  }
 
-    /*
-      Deny others from logging to general and slow log,
-      while reopening tables.
-    */
-    logger.lock();
+  /*
+    Deny others from logging to general and slow log,
+    while reopening tables.
+  */
+  logger.lock();
+
+  /* reopen log files */
+  file_log_handler->flush();
 
+  /* flush tables, in the case they are enabled */
+  if (logger.is_log_tables_initialized)
     table_log_handler->flush(table_log_handler->general_log_thd,
                              &close_slow_log, &close_general_log);
-
-    /* end of log tables flush */
-    logger.unlock();
-  }
+  /* end of log flush */
+  logger.unlock();
   return FALSE;
 }
 
@@ -727,6 +738,11 @@ bool LOGGER::slow_log_print(THD *thd, const char *query, uint query_length,
       return 0;
 
     lock();
+    if (!opt_slow_log)
+    {
+      unlock();
+      return 0;
+    }
 
     /* fill in user_host value: the format is "%s[%s] @ %s [%s]" */
     user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
@@ -801,6 +817,11 @@ bool LOGGER::general_log_print(THD *thd, enum enum_server_command command,
       id=0;                                     /* Log from connect handler */
 
     lock();
+    if (!opt_log)
+    {
+      unlock();
+      return 0;
+    }
     time_t current_time= time(NULL);
 
     user_host_len= strxnmov(user_host_buff, MAX_USER_HOST_SIZE,
@@ -904,26 +925,126 @@ void LOGGER::init_general_log(uint general_log_printer)
 }
 
 
+bool LOGGER::activate_log_handler(THD* thd, uint log_type)
+{
+  bool res= 0;
+  lock();
+  switch (log_type) {
+  case QUERY_LOG_SLOW:
+    if (!opt_slow_log)
+    {
+      if ((res= reopen_log_table(log_type)))
+        goto err;
+      file_log_handler->get_mysql_slow_log()->
+        open_query_log(sys_var_slow_log_path.value);
+      init_slow_log(log_output_options);
+      opt_slow_log= TRUE;
+    }
+    break;
+  case QUERY_LOG_GENERAL:
+    if (!opt_log)
+    {
+      if ((res= reopen_log_table(log_type)))
+        goto err;
+      file_log_handler->get_mysql_log()->
+        open_query_log(sys_var_general_log_path.value);
+      init_general_log(log_output_options);
+      opt_log= TRUE;
+    }
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+err:
+  unlock();
+  return res;
+}
+
+
+void LOGGER::deactivate_log_handler(THD *thd, uint log_type)
+{
+  TABLE_LIST *table_list;
+  my_bool *tmp_opt= 0;
+  MYSQL_LOG *file_log;
+  THD *log_thd;
+
+  switch (log_type) {
+  case QUERY_LOG_SLOW:
+    table_list= &table_log_handler->slow_log;
+    tmp_opt= &opt_slow_log;
+    file_log= file_log_handler->get_mysql_slow_log();
+    log_thd= table_log_handler->slow_log_thd;
+    break;
+  case QUERY_LOG_GENERAL:
+    table_list= &table_log_handler->general_log;
+    tmp_opt= &opt_log;
+    file_log= file_log_handler->get_mysql_log();
+    log_thd= table_log_handler->general_log_thd;
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+
+  if (!(*tmp_opt))
+    return;
+
+  if (is_log_tables_initialized)
+    lock_and_wait_for_table_name(log_thd, table_list);
+  lock();
+
+  if (is_log_tables_initialized)
+  {
+    VOID(pthread_mutex_lock(&LOCK_open));
+    close_log_table(log_type, TRUE);
+    table_list->table= 0;
+    query_cache_invalidate3(log_thd, table_list, 0);
+    unlock_table_name(log_thd, table_list);
+    VOID(pthread_mutex_unlock(&LOCK_open));
+  }
+  file_log->close(0);
+  *tmp_opt= FALSE;
+  unlock();
+}
+
+
 bool Log_to_csv_event_handler::flush(THD *thd, TABLE_LIST *close_slow_log,
                                      TABLE_LIST *close_general_log)
 {
   VOID(pthread_mutex_lock(&LOCK_open));
-  close_log_table(QUERY_LOG_GENERAL, TRUE);
-  close_log_table(QUERY_LOG_SLOW, TRUE);
-  close_general_log->next_local= close_slow_log;
-  query_cache_invalidate3(thd, close_general_log, 0);
-  unlock_table_name(thd, close_slow_log);
-  unlock_table_name(thd, close_general_log);
+  if (opt_log)
+  {
+    close_log_table(QUERY_LOG_GENERAL, TRUE);
+    query_cache_invalidate3(thd, close_general_log, 0);
+    unlock_table_name(thd, close_general_log);
+  }
+  if (opt_slow_log)
+  {
+    close_log_table(QUERY_LOG_SLOW, TRUE);
+    query_cache_invalidate3(thd, close_slow_log, 0);
+    unlock_table_name(thd, close_slow_log);
+  }
   VOID(pthread_mutex_unlock(&LOCK_open));
-  return reopen_log_table(QUERY_LOG_SLOW) ||
-         reopen_log_table(QUERY_LOG_GENERAL);
+  /*
+    we use | and not || here, to ensure that both reopen_log_table
+    are called, even if the first one fails
+  */
+  if ((opt_slow_log && reopen_log_table(QUERY_LOG_SLOW)) |
+      (opt_log && reopen_log_table(QUERY_LOG_GENERAL)))
+    return 1;
+  return 0;
 }
 
 /* the parameters are unused for the log tables */
 bool Log_to_csv_event_handler::init()
 {
-  /* we always open log tables. even if the logging is disabled */
-  return (open_log_table(QUERY_LOG_GENERAL) || open_log_table(QUERY_LOG_SLOW));
+  /*
+    we use | and not || here, to ensure that both open_log_table
+    are called, even if the first one fails
+  */
+  if ((opt_log && open_log_table(QUERY_LOG_GENERAL)) |
+      (opt_slow_log && open_log_table(QUERY_LOG_SLOW)))
+    return 1;
+  return 0;
 }
 
 int LOGGER::set_handlers(uint error_log_printer,
diff --git a/sql/log.h b/sql/log.h
index 03d5466e5496af8241ca4c5a82c292c6b67eb770..49aae15feee853bf977d30f9e90a62f374864f56 100644
--- a/sql/log.h
+++ b/sql/log.h
@@ -438,6 +438,8 @@ public:
                            CHARSET_INFO *client_cs);
   void flush();
   void init_pthread_objects();
+  MYSQL_LOG *get_mysql_slow_log() { return &mysql_slow_log; }
+  MYSQL_LOG *get_mysql_log() { return &mysql_log; }
 };
 
 
@@ -510,8 +512,21 @@ public:
   void init_error_log(uint error_log_printer);
   void init_slow_log(uint slow_log_printer);
   void init_general_log(uint general_log_printer);
- };
-
+  void deactivate_log_handler(THD* thd, uint log_type);
+  bool activate_log_handler(THD* thd, uint log_type);
+  MYSQL_LOG *get_slow_log_file_handler()
+  { 
+    if (file_log_handler)
+      return file_log_handler->get_mysql_slow_log();
+    return NULL;
+  }
+  MYSQL_LOG *get_log_file_handler()
+  { 
+    if (file_log_handler)
+      return file_log_handler->get_mysql_log();
+    return NULL;
+  }
+};
 
 enum enum_binlog_format {
   BINLOG_FORMAT_STMT= 0, // statement-based
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 3d499b67519fcaf31ef42230b4efba11c9f7f424..83cbb383aef08a22b6d640fc60bdb1ac024a0b06 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1167,6 +1167,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *new_db,
 void remove_db_from_cache(const char *db);
 void flush_tables();
 bool is_equal(const LEX_STRING *a, const LEX_STRING *b);
+char *make_default_log_name(char *buff,const char* log_ext);
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
 uint fast_alter_partition_table(THD *thd, TABLE *table,
@@ -1514,7 +1515,9 @@ extern bool opt_endinfo, using_udf_functions;
 extern my_bool locked_in_memory;
 extern bool opt_using_transactions, mysqld_embedded;
 extern bool using_update_log, opt_large_files, server_id_supplied;
-extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
+extern bool opt_update_log, opt_bin_log, opt_error_log;
+extern my_bool opt_log, opt_slow_log;
+extern uint log_output_options;
 extern my_bool opt_log_queries_not_using_indexes;
 extern bool opt_disable_networking, opt_skip_show_db;
 extern my_bool opt_character_set_client_handshake;
@@ -1536,6 +1539,8 @@ extern my_bool opt_enable_shared_memory;
 extern char *default_tz_name;
 extern my_bool opt_large_pages;
 extern uint opt_large_page_size;
+extern char *opt_logname, *opt_slow_logname;
+extern const char *log_output_str;
 
 extern MYSQL_LOG mysql_bin_log;
 extern LOGGER logger;
@@ -1582,6 +1587,7 @@ extern TABLE *unused_tables;
 extern const char* any_db;
 extern struct my_option my_long_options[];
 extern const LEX_STRING view_type;
+extern TYPELIB log_output_typelib;
 
 /* optional things, have_* variables */
 
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 56c3b1857a801ef450124a5b6065c3a3d229c77b..2ec62e741b9978f1061cfa810a49c620b4d6b851 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -302,16 +302,15 @@ arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
  {&Arg_comparator::compare_row,        &Arg_comparator::compare_e_row},
  {&Arg_comparator::compare_decimal,    &Arg_comparator::compare_e_decimal}};
 
-const char *log_output_names[] =
-{ "NONE", "FILE", "TABLE", NullS};
+const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
+static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
 TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
-				 log_output_names, NULL};
+                             log_output_names, 
+                             (unsigned int *) log_output_names_len};
 
 /* static variables */
 
 /* the default log output is log tables */
-static const char *log_output_str= "TABLE";
-static ulong log_output_options= LOG_TABLE;
 static bool lower_case_table_names_used= 0;
 static bool volatile select_thread_in_use, signal_thread_in_use;
 static bool volatile ready_to_exit;
@@ -342,7 +341,9 @@ static my_bool opt_sync_bdb_logs;
 
 /* Global variables */
 
-bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+bool opt_update_log, opt_bin_log;
+my_bool opt_log, opt_slow_log;
+uint log_output_options;
 my_bool opt_log_queries_not_using_indexes= 0;
 bool opt_error_log= IF_WIN(1,0);
 bool opt_disable_networking=0, opt_skip_show_db=0;
@@ -520,6 +521,7 @@ ulong thread_id=1L,current_pid;
 ulong slow_launch_threads = 0, sync_binlog_period;
 ulong expire_logs_days = 0;
 ulong rpl_recovery_rank=0;
+const char *log_output_str= "TABLE";
 
 double log_10[32];			/* 10 potences */
 time_t start_time;
@@ -1229,6 +1231,8 @@ void clean_up(bool print_message)
     free_defaults(defaults_argv);
   my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
   my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
+  my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
+  my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
   free_tmpdir(&mysql_tmpdir_list);
 #ifdef HAVE_REPLICATION
   my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
@@ -2607,6 +2611,7 @@ static bool init_global_datetime_format(timestamp_type format_type,
 static int init_common_variables(const char *conf_file_name, int argc,
 				 char **argv, const char **groups)
 {
+  char buff[FN_REFLEN];
   umask(((~my_umask) & 0666));
   my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
   tzset();			// Set tzname
@@ -2763,6 +2768,16 @@ static int init_common_variables(const char *conf_file_name, int argc,
   else
     sys_init_slave.value=my_strdup("",MYF(0));
 
+  if (!opt_logname)
+    opt_logname= make_default_log_name(buff, ".log");
+  sys_var_general_log_path.value= my_strdup(opt_logname, MYF(0));
+  sys_var_general_log_path.value_length= strlen(opt_logname);
+
+  if (!opt_slow_logname)
+    opt_slow_logname= make_default_log_name(buff, "-slow.log");
+  sys_var_slow_log_path.value= my_strdup(opt_slow_logname, MYF(0));
+  sys_var_slow_log_path.value_length= strlen(opt_slow_logname);
+
   if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
     return 1;
   if (my_database_names_init())
@@ -4815,7 +4830,9 @@ enum options_mysqld
   OPT_TABLE_LOCK_WAIT_TIMEOUT,
   OPT_PLUGIN_DIR,
   OPT_LOG_OUTPUT,
-  OPT_PORT_OPEN_TIMEOUT
+  OPT_PORT_OPEN_TIMEOUT,
+  OPT_GENERAL_LOG,
+  OPT_SLOW_LOG
 };
 
 
@@ -5044,6 +5061,9 @@ Disable with --skip-bdb (will save memory).",
    "Set up signals usable for debugging",
    (gptr*) &opt_debugging, (gptr*) &opt_debugging,
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"general-log", OPT_GENERAL_LOG,
+   "Enable|disable general log", (gptr*) &opt_log,
+   (gptr*) &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
 #ifdef HAVE_LARGE_PAGES
   {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. \
 Disable with --skip-large-pages.",
@@ -5613,6 +5633,9 @@ replicating a LOAD DATA INFILE command.",
    "Tells the slave thread to continue replication when a query returns an error from the provided list.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 #endif
+  {"slow-query-log", OPT_SLOW_LOG,
+   "Enable|disable slow query log", (gptr*) &opt_slow_log,
+   (gptr*) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
   {"socket", OPT_SOCKET, "Socket file to use for connection.",
    (gptr*) &mysqld_unix_port, (gptr*) &mysqld_unix_port, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -6922,6 +6945,7 @@ static void mysql_init_variables(void)
   opt_skip_slave_start= opt_reckless_slave = 0;
   mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
   opt_log= opt_update_log= opt_slow_log= 0;
+  log_output_options= find_bit_type(log_output_str, &log_output_typelib);
   opt_bin_log= 0;
   opt_disable_networking= opt_skip_show_db=0;
   opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 53b4b395c37fd20ffde0fffd5352050442dd0733..79de4dd7c16736632f3267293c4a12c194dbf9c7 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -55,6 +55,7 @@
 #include <my_getopt.h>
 #include <thr_alarm.h>
 #include <myisam.h>
+#include <my_dir.h>
 
 #include "event_scheduler.h"
 
@@ -164,6 +165,11 @@ static byte *get_error_count(THD *thd);
 static byte *get_warning_count(THD *thd);
 static byte *get_prepared_stmt_count(THD *thd);
 static byte *get_tmpdir(THD *thd);
+static int  sys_check_log_path(THD *thd,  set_var *var);
+static bool sys_update_general_log_path(THD *thd, set_var * var);
+static void sys_default_general_log_path(THD *thd, enum_var_type type);
+static bool sys_update_slow_log_path(THD *thd, set_var * var);
+static void sys_default_slow_log_path(THD *thd, enum_var_type type);
 
 /*
   Variable definition list
@@ -679,6 +685,22 @@ sys_var_have_variable sys_have_row_based_replication("have_row_based_replication
 /* Global read-only variable describing server license */
 sys_var_const_str		sys_license("license", STRINGIFY_ARG(LICENSE));
 
+/* Global variables which enable|disable logging */
+sys_var_log_state sys_var_general_log("general_log", &opt_log,
+                                      QUERY_LOG_GENERAL);
+sys_var_log_state sys_var_slow_query_log("slow_query_log", &opt_slow_log,
+                                         QUERY_LOG_SLOW);
+sys_var_str sys_var_general_log_path("general_log_file", sys_check_log_path,
+				     sys_update_general_log_path,
+				     sys_default_general_log_path,
+				     opt_logname);
+sys_var_str sys_var_slow_log_path("slow_query_log_file", sys_check_log_path,
+				  sys_update_slow_log_path, 
+				  sys_default_slow_log_path,
+				  opt_slow_logname);
+sys_var_log_output sys_var_log_output_state("log_output", &log_output_options,
+					    &log_output_typelib, 0);
+
 #ifdef HAVE_REPLICATION
 static int show_slave_skip_errors(THD *thd, SHOW_VAR *var, char *buff)
 {
@@ -777,6 +799,8 @@ SHOW_VAR init_vars[]= {
   {"ft_min_word_len",         (char*) &ft_min_word_len,             SHOW_LONG},
   {"ft_query_expansion_limit",(char*) &ft_query_expansion_limit,    SHOW_LONG},
   {"ft_stopword_file",        (char*) &ft_stopword_file,            SHOW_CHAR_PTR},
+  {sys_var_general_log.name, (char*) &opt_log,                      SHOW_MY_BOOL},
+  {sys_var_general_log_path.name, (char*) &sys_var_general_log_path,  SHOW_SYS},
   {sys_group_concat_max_len.name, (char*) &sys_group_concat_max_len,  SHOW_SYS},
   {sys_have_archive_db.name,  (char*) &have_archive_db,             SHOW_HAVE},
   {sys_have_berkeley_db.name, (char*) &have_berkeley_db,            SHOW_HAVE},
@@ -854,6 +878,7 @@ SHOW_VAR init_vars[]= {
   {"log_bin",                 (char*) &opt_bin_log,                 SHOW_BOOL},
   {sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
   {"log_error",               (char*) log_error_file,               SHOW_CHAR},
+  {sys_var_log_output_state.name, (char*) &sys_var_log_output_state, SHOW_SYS},
   {sys_log_queries_not_using_indexes.name,
     (char*) &sys_log_queries_not_using_indexes, SHOW_SYS},
 #ifdef HAVE_REPLICATION
@@ -977,6 +1002,8 @@ SHOW_VAR init_vars[]= {
   {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries,   SHOW_SYS},
 #endif
   {sys_slow_launch_time.name, (char*) &sys_slow_launch_time,        SHOW_SYS},
+  {sys_var_slow_query_log.name, (char*) &opt_slow_log,              SHOW_MY_BOOL},
+  {sys_var_slow_log_path.name, (char*) &sys_var_slow_log_path,      SHOW_SYS},
 #ifdef HAVE_SYS_UN_H
   {"socket",                  (char*) &mysqld_unix_port,             SHOW_CHAR_PTR},
 #endif
@@ -2509,6 +2536,195 @@ end:
 }
 
 
+bool sys_var_log_state::update(THD *thd, set_var *var)
+{
+  bool res= 0;
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  if (!var->save_result.ulong_value)
+    logger.deactivate_log_handler(thd, log_type);
+  else
+  {
+    if ((res= logger.activate_log_handler(thd, log_type)))
+    {
+      my_error(ER_CANT_ACTIVATE_LOG, MYF(0),
+               log_type == QUERY_LOG_GENERAL ? "general" :
+               "slow query");
+      goto err;
+    }
+  }
+err:
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+  return res;
+}
+
+void sys_var_log_state::set_default(THD *thd, enum_var_type type)
+{
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  logger.deactivate_log_handler(thd, log_type);
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+}
+
+
+static int  sys_check_log_path(THD *thd,  set_var *var)
+{
+  char path[FN_REFLEN];
+  MY_STAT f_stat;
+  const char *var_path= var->value->str_value.ptr();
+  bzero(&f_stat, sizeof(MY_STAT));
+
+  (void) unpack_filename(path, var_path);
+  if (my_stat(path, &f_stat, MYF(0)))
+  {
+    /* Check if argument is a file and we have 'write' permission */
+    if (!MY_S_ISREG(f_stat.st_mode) ||
+        !(f_stat.st_mode & MY_S_IWRITE))
+      return -1;
+  }
+  else
+  {
+    /*
+      Check if directory exists and 
+      we have permission to create file & write to file
+    */
+    (void) dirname_part(path, var_path);
+    if (my_access(path, (F_OK|W_OK)))
+      return -1;
+  }
+  return 0;
+}
+
+
+bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
+			     set_var *var, const char *log_ext,
+			     bool log_state, uint log_type)
+{
+  MYSQL_LOG *file_log;
+  char buff[FN_REFLEN];
+  char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
+  bool result= 0;
+  uint str_length= (var ? var->value->str_value.length() : 0);
+
+  switch (log_type) {
+  case QUERY_LOG_SLOW:
+    file_log= logger.get_slow_log_file_handler();
+    break;
+  case QUERY_LOG_GENERAL:
+    file_log= logger.get_log_file_handler();
+    break;
+  default:
+    DBUG_ASSERT(0);
+  }
+
+  if (!old_value)
+  {
+    old_value= make_default_log_name(buff, log_ext);
+    str_length= strlen(old_value);
+  }
+  if (!(res= my_strndup((byte*)old_value, str_length, MYF(MY_FAE+MY_WME))))
+  {
+    result= 1;
+    goto err;
+  }
+
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  logger.lock();
+
+  if (file_log && log_state)
+    file_log->close(0);
+  old_value= var_str->value;
+  var_str->value= res;
+  var_str->value_length= str_length;
+  my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
+  if (file_log && log_state)
+    file_log->open_query_log(sys_var_general_log_path.value);
+
+  logger.unlock();
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+
+err:
+  return result;
+}
+
+
+static bool sys_update_general_log_path(THD *thd, set_var * var)
+{
+  return update_sys_var_str_path(thd, &sys_var_general_log_path, 
+				 var, ".log", opt_log, QUERY_LOG_GENERAL);
+}
+
+
+static void sys_default_general_log_path(THD *thd, enum_var_type type)
+{
+  (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
+				 0, ".log", opt_log, QUERY_LOG_GENERAL);
+}
+
+
+static bool sys_update_slow_log_path(THD *thd, set_var * var)
+{
+  return update_sys_var_str_path(thd, &sys_var_slow_log_path,
+				 var, "-slow.log", opt_slow_log,
+                                 QUERY_LOG_SLOW);
+}
+
+
+static void sys_default_slow_log_path(THD *thd, enum_var_type type)
+{
+  (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
+				 0, "-slow.log", opt_slow_log,
+                                 QUERY_LOG_SLOW);
+}
+
+
+bool sys_var_log_output::update(THD *thd, set_var *var)
+{
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  logger.lock();
+  logger.init_slow_log(var->save_result.ulong_value);
+  logger.init_general_log(var->save_result.ulong_value);
+  *value= var->save_result.ulong_value;
+  logger.unlock();
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+  return 0;
+}
+
+
+void sys_var_log_output::set_default(THD *thd, enum_var_type type)
+{
+  pthread_mutex_lock(&LOCK_global_system_variables);
+  logger.lock();
+  logger.init_slow_log(LOG_TABLE);
+  logger.init_general_log(LOG_TABLE);
+  *value= LOG_TABLE;
+  logger.unlock();
+  pthread_mutex_unlock(&LOCK_global_system_variables);
+}
+
+
+byte *sys_var_log_output::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
+{
+  char buff[256];
+  String tmp(buff, sizeof(buff), &my_charset_latin1);
+  ulong length;
+  ulong val= *value;
+
+  tmp.length(0);
+  for (uint i= 0; val; val>>= 1, i++)
+  {
+    if (val & 1)
+    {
+      tmp.append(log_output_typelib.type_names[i],
+                 log_output_typelib.type_lengths[i]);
+      tmp.append(',');
+    }
+  }
+
+  if ((length= tmp.length()))
+    length--;
+  return (byte*) thd->strmake(tmp.ptr(), length);
+}
+
+
 /*****************************************************************************
   Functions to handle SET NAMES and SET CHARACTER SET
 *****************************************************************************/
diff --git a/sql/set_var.h b/sql/set_var.h
index 1049b154d47034bc827af35bc4c060b484558d17..2793f60f7632a9bbfbc77cce1d584e88ff2d1045 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -262,7 +262,7 @@ public:
 
 class sys_var_enum :public sys_var
 {
-  uint	*value; 
+  uint *value;
   TYPELIB *enum_names;
 public:
   sys_var_enum(const char *name_arg, uint *value_arg,
@@ -772,6 +772,38 @@ public:
 };
 
 
+class sys_var_log_state :public sys_var_bool_ptr
+{
+  uint log_type;
+public:
+  sys_var_log_state(const char *name_arg, my_bool *value_arg, uint log_type_arg)
+    :sys_var_bool_ptr(name_arg, value_arg), log_type(log_type_arg) {}
+  bool update(THD *thd, set_var *var);
+  void set_default(THD *thd, enum_var_type type);
+};
+
+
+class sys_var_log_output :public sys_var
+{
+  uint *value;
+  TYPELIB *enum_names;
+public:
+  sys_var_log_output(const char *name_arg, uint *value_arg,
+                     TYPELIB *typelib, sys_after_update_func func)
+    :sys_var(name_arg,func), value(value_arg), enum_names(typelib)
+  {}
+  bool check(THD *thd, set_var *var)
+  {
+    return check_set(thd, var, enum_names);
+  }
+  bool update(THD *thd, set_var *var);
+  byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+  bool check_update_type(Item_result type) { return 0; }
+  void set_default(THD *thd, enum_var_type type);
+  SHOW_TYPE type() { return SHOW_CHAR; }
+};
+
+
 /* Variable that you can only read from */
 
 class sys_var_readonly: public sys_var
@@ -1068,6 +1100,8 @@ CHARSET_INFO *get_old_charset_by_name(const char *old_name);
 gptr find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
 		NAMED_LIST **found);
 
+extern sys_var_str sys_var_general_log_path, sys_var_slow_log_path;
+
 /* key_cache functions */
 KEY_CACHE *get_key_cache(LEX_STRING *cache_name);
 KEY_CACHE *get_or_create_key_cache(const char *name, uint length);
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index ae5ddd31475a5385b3f121f9e73bdb22b31475f4..317ec5fc4204c634990e79678d63b98cceb7a43f 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5832,3 +5832,5 @@ ER_EVENT_SET_VAR_ERROR
 ER_PARTITION_MERGE_ERROR
         eng "MyISAM Merge handler cannot be used in partitioned tables"
         swe "MyISAM Merge kan inte anändas i en partitionerad tabell"
+ER_CANT_ACTIVATE_LOG
+        eng "Cannot activate '%-.64s' log."
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index dd4748bc15c27a00a030567ec60bed1e10043e2d..7609c0eb4954fe627345960ced63dc93d75e3a68 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -931,7 +931,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
   /* close log tables in use */
   if (!my_strcasecmp(system_charset_info, table_list->db, "mysql"))
   {
-    if (!my_strcasecmp(system_charset_info, table_list->table_name,
+    if (opt_log &&
+        !my_strcasecmp(system_charset_info, table_list->table_name,
                        "general_log"))
     {
       lock_logger= 1;
@@ -940,7 +941,8 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
       closed_log_tables= closed_log_tables | QUERY_LOG_GENERAL;
     }
     else
-      if (!my_strcasecmp(system_charset_info, table_list->table_name,
+      if (opt_slow_log &&
+          !my_strcasecmp(system_charset_info, table_list->table_name,
                          "slow_log"))
       {
         lock_logger= 1;
@@ -981,10 +983,10 @@ end:
     unlock_table_name(thd, table_list);
     VOID(pthread_mutex_unlock(&LOCK_open));
 
-    if (closed_log_tables & QUERY_LOG_SLOW)
+    if (opt_slow_log && (closed_log_tables & QUERY_LOG_SLOW))
       logger.reopen_log_table(QUERY_LOG_SLOW);
 
-    if (closed_log_tables & QUERY_LOG_GENERAL)
+    if (opt_log && (closed_log_tables & QUERY_LOG_GENERAL))
       logger.reopen_log_table(QUERY_LOG_GENERAL);
     if (lock_logger)
       logger.unlock();