summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzheng <Zheng.chai@citrix.com>2015-07-16 15:44:59 +0800
committerzheng <Zheng.chai@citrix.com>2015-07-16 15:44:59 +0800
commit586e9090c1706b9180a7afd4a8d7b80a1c2a51a5 (patch)
tree8f773d544f9399f0badac2d012ca0d3427d76975
parentfe78cd379770d32eabb6dc80beaf50a439562ae3 (diff)
parent9a1317d7733cb07274b5d82873bc3051764586c5 (diff)
downloadvyos-xe-guest-utilities-586e9090c1706b9180a7afd4a8d7b80a1c2a51a5.tar.gz
vyos-xe-guest-utilities-586e9090c1706b9180a7afd4a8d7b80a1c2a51a5.zip
Merge pull request #9 from xs-nanjing/master
CA-172369: Golang Guest Agent doesn't use print the logs into guest machine syslog
-rw-r--r--xe-daemon/syslog.go60
-rw-r--r--xe-daemon/xe-daemon.go64
2 files changed, 103 insertions, 21 deletions
diff --git a/xe-daemon/syslog.go b/xe-daemon/syslog.go
new file mode 100644
index 0000000..a074407
--- /dev/null
+++ b/xe-daemon/syslog.go
@@ -0,0 +1,60 @@
+// To run 32bit xe-daemon under 64bit system,
+// Here we re-implement a syslog writer base on logger CLI.
+
+package main
+
+import (
+ "io"
+ "os"
+ "os/exec"
+ "time"
+)
+
+const (
+ waitLoggerQuitSeconds = 5
+)
+
+type SysLoggerWriter struct {
+ cmd *exec.Cmd
+ stdin io.WriteCloser
+}
+
+func NewSyslogWriter(topic string) (io.Writer, error) {
+ cmd := exec.Command("logger", "-t", topic)
+
+ stdin, err := cmd.StdinPipe()
+ if err != nil {
+ return nil, err
+ }
+
+ err = cmd.Start()
+ if err != nil {
+ return nil, err
+ }
+
+ return &SysLoggerWriter{cmd, stdin}, nil
+}
+
+func (s *SysLoggerWriter) Write(data []byte) (int, error) {
+ return s.stdin.Write(data)
+}
+
+func (s *SysLoggerWriter) Close() error {
+
+ s.stdin.Close()
+ s.cmd.Process.Signal(os.Interrupt)
+
+ done := make(chan error, 1)
+ go func(c chan<- error) {
+ c <- s.cmd.Wait()
+ }(done)
+
+ select {
+ case <-done:
+ return nil
+ case <-time.After(waitLoggerQuitSeconds * time.Second):
+ return s.cmd.Process.Kill()
+ }
+
+ return nil
+}
diff --git a/xe-daemon/xe-daemon.go b/xe-daemon/xe-daemon.go
index 1e5fdb1..3ad8c27 100644
--- a/xe-daemon/xe-daemon.go
+++ b/xe-daemon/xe-daemon.go
@@ -5,23 +5,19 @@ import (
xenstoreclient "../xenstoreclient"
"flag"
"fmt"
+ "io"
+ "io/ioutil"
"log"
"os"
"os/signal"
+ "strconv"
"syscall"
"time"
)
-func write_pid_file(pid_file string) error {
- f, err := os.Create(pid_file)
- if err != nil {
- return err
- }
- defer f.Close()
-
- fmt.Fprintf(f, "%d\n", os.Getpid())
- return nil
-}
+const (
+ LoggerName string = "xe-daemon"
+)
func main() {
var err error
@@ -34,17 +30,32 @@ func main() {
flag.Parse()
if *pid != "" {
- write_pid_file(*pid)
+ if err = ioutil.WriteFile(*pid, []byte(strconv.Itoa(os.Getpid())), 0644); err != nil {
+ fmt.Fprintf(os.Stderr, "Write pid to %s error: %s\n", *pid, err)
+ return
+ }
+ }
+
+ var loggerWriter io.Writer = os.Stderr
+ var topic string = LoggerName
+ if w, err := NewSyslogWriter(topic); err == nil {
+ loggerWriter = w
+ topic = ""
+ } else {
+ fmt.Fprintf(os.Stderr, "NewSyslogWriter(%s) error: %s, use stderr logging\n", topic, err)
+ topic = LoggerName + ": "
}
- logger := log.New(os.Stderr, "xe-daemon", 0)
+ logger := log.New(loggerWriter, topic, 0)
exitChannel := make(chan os.Signal, 1)
signal.Notify(exitChannel, syscall.SIGTERM, syscall.SIGINT)
xs, err := xenstoreclient.NewCachedXenstore(0)
if err != nil {
- logger.Printf("NewCachedXenstore error: %v", err)
+ message := fmt.Sprintf("NewCachedXenstore error: %v\n", err)
+ logger.Print(message)
+ fmt.Fprint(os.Stderr, message)
return
}
@@ -68,13 +79,13 @@ func main() {
lastUniqueID, err := xs.Read("unique-domain-id")
if err != nil {
- logger.Printf("xenstore.Read unique-domain-id error: %v", err)
+ logger.Printf("xenstore.Read unique-domain-id error: %v\n", err)
}
for count := 0; ; count += 1 {
uniqueID, err := xs.Read("unique-domain-id")
if err != nil {
- logger.Printf("xenstore.Read unique-domain-id error: %v", err)
+ logger.Printf("xenstore.Read unique-domain-id error: %v\n", err)
return
}
if uniqueID != lastUniqueID {
@@ -86,30 +97,41 @@ func main() {
}
// invoke collectors
+ updated := false
for _, collector := range collectors {
if count%collector.divisor == 0 {
- logger.Printf("Running %s ...", collector.name)
+ logger.Printf("Running %s ...\n", collector.name)
result, err := collector.Collect()
if err != nil {
- logger.Printf("%s error: %#v", collector.name, err)
+ logger.Printf("%s error: %#v\n", collector.name, err)
} else {
for name, value := range result {
err := xs.Write(name, value)
if err != nil {
- logger.Printf("xenstore.Write error: %v", err)
+ logger.Printf("xenstore.Write error: %v\n", err)
} else {
- logger.Printf("xenstore.Write OK: %#v: %#v", name, value)
+ if *debugFlag {
+ logger.Printf("xenstore.Write OK: %#v: %#v\n", name, value)
+ }
+ updated = true
}
}
}
}
}
- xs.Write("data/updated", time.Now().Format("Mon Jan _2 15:04:05 2006"))
+ if updated {
+ xs.Write("data/updated", time.Now().Format("Mon Jan _2 15:04:05 2006"))
+ }
select {
case <-exitChannel:
- logger.Printf("Received an interrupt, stopping services...")
+ logger.Printf("Received an interrupt, stopping services...\n")
+ if c, ok := loggerWriter.(io.Closer); ok {
+ if err := c.Close(); err != nil {
+ fmt.Fprintf(os.Stderr, "logger close error: %s\n", err)
+ }
+ }
return
case <-time.After(time.Duration(*sleepInterval) * time.Second):