commands-posix.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370
  1. /*
  2. * QEMU Guest Agent POSIX-specific command implementations
  3. *
  4. * Copyright IBM Corp. 2011
  5. *
  6. * Authors:
  7. * Michael Roth <mdroth@linux.vnet.ibm.com>
  8. * Michal Privoznik <mprivozn@redhat.com>
  9. *
  10. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  11. * See the COPYING file in the top-level directory.
  12. */
  13. #include "qemu/osdep.h"
  14. #include <sys/ioctl.h>
  15. #include <sys/utsname.h>
  16. #include <sys/wait.h>
  17. #include <dirent.h>
  18. #include "qga-qapi-commands.h"
  19. #include "qapi/error.h"
  20. #include "qemu/host-utils.h"
  21. #include "qemu/sockets.h"
  22. #include "qemu/base64.h"
  23. #include "qemu/cutils.h"
  24. #include "commands-common.h"
  25. #include "cutils.h"
  26. #ifdef HAVE_UTMPX
  27. #include <utmpx.h>
  28. #endif
  29. #ifdef HAVE_GETIFADDRS
  30. #include <arpa/inet.h>
  31. #include <sys/socket.h>
  32. #include <net/if.h>
  33. #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(CONFIG_SOLARIS)
  34. #include <net/if_arp.h>
  35. #include <netinet/if_ether.h>
  36. #if !defined(ETHER_ADDR_LEN) && defined(ETHERADDRL)
  37. #define ETHER_ADDR_LEN ETHERADDRL
  38. #endif
  39. #else
  40. #include <net/ethernet.h>
  41. #endif
  42. #ifdef CONFIG_SOLARIS
  43. #include <sys/sockio.h>
  44. #endif
  45. #endif
  46. static bool ga_wait_child(pid_t pid, int *status, Error **errp)
  47. {
  48. pid_t rpid;
  49. *status = 0;
  50. rpid = RETRY_ON_EINTR(waitpid(pid, status, 0));
  51. if (rpid == -1) {
  52. error_setg_errno(errp, errno, "failed to wait for child (pid: %d)",
  53. pid);
  54. return false;
  55. }
  56. g_assert(rpid == pid);
  57. return true;
  58. }
  59. static ssize_t ga_pipe_read_str(int fd[2], char **str)
  60. {
  61. ssize_t n, len = 0;
  62. char buf[1024];
  63. close(fd[1]);
  64. fd[1] = -1;
  65. while ((n = read(fd[0], buf, sizeof(buf))) != 0) {
  66. if (n < 0) {
  67. if (errno == EINTR) {
  68. continue;
  69. } else {
  70. len = -errno;
  71. break;
  72. }
  73. }
  74. *str = g_realloc(*str, len + n + 1);
  75. memcpy(*str + len, buf, n);
  76. len += n;
  77. *str[len] = '\0';
  78. }
  79. close(fd[0]);
  80. fd[0] = -1;
  81. return len;
  82. }
  83. /*
  84. * Helper to run command with input/output redirection,
  85. * sending string to stdin and taking error message from
  86. * stdout/err.
  87. */
  88. static int ga_run_command(const char *argv[], const char *in_str,
  89. const char *action, Error **errp)
  90. {
  91. pid_t pid;
  92. int status;
  93. int retcode = -1;
  94. int infd[2] = { -1, -1 };
  95. int outfd[2] = { -1, -1 };
  96. char *str = NULL;
  97. ssize_t len = 0;
  98. if ((in_str && !g_unix_open_pipe(infd, FD_CLOEXEC, NULL)) ||
  99. !g_unix_open_pipe(outfd, FD_CLOEXEC, NULL)) {
  100. error_setg(errp, "cannot create pipe FDs");
  101. goto out;
  102. }
  103. pid = fork();
  104. if (pid == 0) {
  105. char *cherr = NULL;
  106. setsid();
  107. if (in_str) {
  108. /* Redirect stdin to infd. */
  109. close(infd[1]);
  110. dup2(infd[0], 0);
  111. close(infd[0]);
  112. } else {
  113. reopen_fd_to_null(0);
  114. }
  115. /* Redirect stdout/stderr to outfd. */
  116. close(outfd[0]);
  117. dup2(outfd[1], 1);
  118. dup2(outfd[1], 2);
  119. close(outfd[1]);
  120. execvp(argv[0], (char *const *)argv);
  121. /* Write the cause of failed exec to pipe for the parent to read it. */
  122. cherr = g_strdup_printf("failed to exec '%s'", argv[0]);
  123. perror(cherr);
  124. g_free(cherr);
  125. _exit(EXIT_FAILURE);
  126. } else if (pid < 0) {
  127. error_setg_errno(errp, errno, "failed to create child process");
  128. goto out;
  129. }
  130. if (in_str) {
  131. close(infd[0]);
  132. infd[0] = -1;
  133. if (qemu_write_full(infd[1], in_str, strlen(in_str)) !=
  134. strlen(in_str)) {
  135. error_setg_errno(errp, errno, "%s: cannot write to stdin pipe",
  136. action);
  137. goto out;
  138. }
  139. close(infd[1]);
  140. infd[1] = -1;
  141. }
  142. len = ga_pipe_read_str(outfd, &str);
  143. if (len < 0) {
  144. error_setg_errno(errp, -len, "%s: cannot read from stdout/stderr pipe",
  145. action);
  146. goto out;
  147. }
  148. if (!ga_wait_child(pid, &status, errp)) {
  149. goto out;
  150. }
  151. if (!WIFEXITED(status)) {
  152. if (len) {
  153. error_setg(errp, "child process has terminated abnormally: %s",
  154. str);
  155. } else {
  156. error_setg(errp, "child process has terminated abnormally");
  157. }
  158. goto out;
  159. }
  160. retcode = WEXITSTATUS(status);
  161. if (WEXITSTATUS(status)) {
  162. if (len) {
  163. error_setg(errp, "child process has failed to %s: %s",
  164. action, str);
  165. } else {
  166. error_setg(errp, "child process has failed to %s: exit status %d",
  167. action, WEXITSTATUS(status));
  168. }
  169. goto out;
  170. }
  171. out:
  172. g_free(str);
  173. if (infd[0] != -1) {
  174. close(infd[0]);
  175. }
  176. if (infd[1] != -1) {
  177. close(infd[1]);
  178. }
  179. if (outfd[0] != -1) {
  180. close(outfd[0]);
  181. }
  182. if (outfd[1] != -1) {
  183. close(outfd[1]);
  184. }
  185. return retcode;
  186. }
  187. void qmp_guest_shutdown(const char *mode, Error **errp)
  188. {
  189. const char *shutdown_flag;
  190. Error *local_err = NULL;
  191. #ifdef CONFIG_SOLARIS
  192. const char *powerdown_flag = "-i5";
  193. const char *halt_flag = "-i0";
  194. const char *reboot_flag = "-i6";
  195. #elif defined(CONFIG_BSD)
  196. const char *powerdown_flag = "-p";
  197. const char *halt_flag = "-h";
  198. const char *reboot_flag = "-r";
  199. #else
  200. const char *powerdown_flag = "-P";
  201. const char *halt_flag = "-H";
  202. const char *reboot_flag = "-r";
  203. #endif
  204. slog("guest-shutdown called, mode: %s", mode);
  205. if (!mode || strcmp(mode, "powerdown") == 0) {
  206. shutdown_flag = powerdown_flag;
  207. } else if (strcmp(mode, "halt") == 0) {
  208. shutdown_flag = halt_flag;
  209. } else if (strcmp(mode, "reboot") == 0) {
  210. shutdown_flag = reboot_flag;
  211. } else {
  212. error_setg(errp,
  213. "mode is invalid (valid values are: halt|powerdown|reboot");
  214. return;
  215. }
  216. const char *argv[] = {"/sbin/shutdown",
  217. #ifdef CONFIG_SOLARIS
  218. shutdown_flag, "-g0", "-y",
  219. #elif defined(CONFIG_BSD)
  220. shutdown_flag, "+0",
  221. #else
  222. "-h", shutdown_flag, "+0",
  223. #endif
  224. "hypervisor initiated shutdown", (char *) NULL};
  225. ga_run_command(argv, NULL, "shutdown", &local_err);
  226. if (local_err) {
  227. error_propagate(errp, local_err);
  228. return;
  229. }
  230. /* succeeded */
  231. }
  232. void qmp_guest_set_time(bool has_time, int64_t time_ns, Error **errp)
  233. {
  234. int ret;
  235. Error *local_err = NULL;
  236. struct timeval tv;
  237. const char *argv[] = {"/sbin/hwclock", has_time ? "-w" : "-s", NULL};
  238. /* If user has passed a time, validate and set it. */
  239. if (has_time) {
  240. GDate date = { 0, };
  241. /* year-2038 will overflow in case time_t is 32bit */
  242. if (time_ns / 1000000000 != (time_t)(time_ns / 1000000000)) {
  243. error_setg(errp, "Time %" PRId64 " is too large", time_ns);
  244. return;
  245. }
  246. tv.tv_sec = time_ns / 1000000000;
  247. tv.tv_usec = (time_ns % 1000000000) / 1000;
  248. g_date_set_time_t(&date, tv.tv_sec);
  249. if (date.year < 1970 || date.year >= 2070) {
  250. error_setg_errno(errp, errno, "Invalid time");
  251. return;
  252. }
  253. ret = settimeofday(&tv, NULL);
  254. if (ret < 0) {
  255. error_setg_errno(errp, errno, "Failed to set time to guest");
  256. return;
  257. }
  258. }
  259. /* Now, if user has passed a time to set and the system time is set, we
  260. * just need to synchronize the hardware clock. However, if no time was
  261. * passed, user is requesting the opposite: set the system time from the
  262. * hardware clock (RTC). */
  263. ga_run_command(argv, NULL, "set hardware clock to system time",
  264. &local_err);
  265. if (local_err) {
  266. error_propagate(errp, local_err);
  267. return;
  268. }
  269. }
  270. typedef enum {
  271. RW_STATE_NEW,
  272. RW_STATE_READING,
  273. RW_STATE_WRITING,
  274. } RwState;
  275. struct GuestFileHandle {
  276. uint64_t id;
  277. FILE *fh;
  278. RwState state;
  279. QTAILQ_ENTRY(GuestFileHandle) next;
  280. };
  281. static struct {
  282. QTAILQ_HEAD(, GuestFileHandle) filehandles;
  283. } guest_file_state = {
  284. .filehandles = QTAILQ_HEAD_INITIALIZER(guest_file_state.filehandles),
  285. };
  286. static int64_t guest_file_handle_add(FILE *fh, Error **errp)
  287. {
  288. GuestFileHandle *gfh;
  289. int64_t handle;
  290. handle = ga_get_fd_handle(ga_state, errp);
  291. if (handle < 0) {
  292. return -1;
  293. }
  294. gfh = g_new0(GuestFileHandle, 1);
  295. gfh->id = handle;
  296. gfh->fh = fh;
  297. QTAILQ_INSERT_TAIL(&guest_file_state.filehandles, gfh, next);
  298. return handle;
  299. }
  300. GuestFileHandle *guest_file_handle_find(int64_t id, Error **errp)
  301. {
  302. GuestFileHandle *gfh;
  303. QTAILQ_FOREACH(gfh, &guest_file_state.filehandles, next)
  304. {
  305. if (gfh->id == id) {
  306. return gfh;
  307. }
  308. }
  309. error_setg(errp, "handle '%" PRId64 "' has not been found", id);
  310. return NULL;
  311. }
  312. typedef const char * const ccpc;
  313. #ifndef O_BINARY
  314. #define O_BINARY 0
  315. #endif
  316. /* http://pubs.opengroup.org/onlinepubs/9699919799/functions/fopen.html */
  317. static const struct {
  318. ccpc *forms;
  319. int oflag_base;
  320. } guest_file_open_modes[] = {
  321. { (ccpc[]){ "r", NULL }, O_RDONLY },
  322. { (ccpc[]){ "rb", NULL }, O_RDONLY | O_BINARY },
  323. { (ccpc[]){ "w", NULL }, O_WRONLY | O_CREAT | O_TRUNC },
  324. { (ccpc[]){ "wb", NULL }, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY },
  325. { (ccpc[]){ "a", NULL }, O_WRONLY | O_CREAT | O_APPEND },
  326. { (ccpc[]){ "ab", NULL }, O_WRONLY | O_CREAT | O_APPEND | O_BINARY },
  327. { (ccpc[]){ "r+", NULL }, O_RDWR },
  328. { (ccpc[]){ "rb+", "r+b", NULL }, O_RDWR | O_BINARY },
  329. { (ccpc[]){ "w+", NULL }, O_RDWR | O_CREAT | O_TRUNC },
  330. { (ccpc[]){ "wb+", "w+b", NULL }, O_RDWR | O_CREAT | O_TRUNC | O_BINARY },
  331. { (ccpc[]){ "a+", NULL }, O_RDWR | O_CREAT | O_APPEND },
  332. { (ccpc[]){ "ab+", "a+b", NULL }, O_RDWR | O_CREAT | O_APPEND | O_BINARY }
  333. };
  334. static int
  335. find_open_flag(const char *mode_str, Error **errp)
  336. {
  337. unsigned mode;
  338. for (mode = 0; mode < ARRAY_SIZE(guest_file_open_modes); ++mode) {
  339. ccpc *form;
  340. form = guest_file_open_modes[mode].forms;
  341. while (*form != NULL && strcmp(*form, mode_str) != 0) {
  342. ++form;
  343. }
  344. if (*form != NULL) {
  345. break;
  346. }
  347. }
  348. if (mode == ARRAY_SIZE(guest_file_open_modes)) {
  349. error_setg(errp, "invalid file open mode '%s'", mode_str);
  350. return -1;
  351. }
  352. return guest_file_open_modes[mode].oflag_base | O_NOCTTY | O_NONBLOCK;
  353. }
  354. #define DEFAULT_NEW_FILE_MODE (S_IRUSR | S_IWUSR | \
  355. S_IRGRP | S_IWGRP | \
  356. S_IROTH | S_IWOTH)
  357. static FILE *
  358. safe_open_or_create(const char *path, const char *mode, Error **errp)
  359. {
  360. int oflag;
  361. int fd = -1;
  362. FILE *f = NULL;
  363. oflag = find_open_flag(mode, errp);
  364. if (oflag < 0) {
  365. goto end;
  366. }
  367. /* If the caller wants / allows creation of a new file, we implement it
  368. * with a two step process: open() + (open() / fchmod()).
  369. *
  370. * First we insist on creating the file exclusively as a new file. If
  371. * that succeeds, we're free to set any file-mode bits on it. (The
  372. * motivation is that we want to set those file-mode bits independently
  373. * of the current umask.)
  374. *
  375. * If the exclusive creation fails because the file already exists
  376. * (EEXIST is not possible for any other reason), we just attempt to
  377. * open the file, but in this case we won't be allowed to change the
  378. * file-mode bits on the preexistent file.
  379. *
  380. * The pathname should never disappear between the two open()s in
  381. * practice. If it happens, then someone very likely tried to race us.
  382. * In this case just go ahead and report the ENOENT from the second
  383. * open() to the caller.
  384. *
  385. * If the caller wants to open a preexistent file, then the first
  386. * open() is decisive and its third argument is ignored, and the second
  387. * open() and the fchmod() are never called.
  388. */
  389. fd = qga_open_cloexec(path, oflag | ((oflag & O_CREAT) ? O_EXCL : 0), 0);
  390. if (fd == -1 && errno == EEXIST) {
  391. oflag &= ~(unsigned)O_CREAT;
  392. fd = qga_open_cloexec(path, oflag, 0);
  393. }
  394. if (fd == -1) {
  395. error_setg_errno(errp, errno,
  396. "failed to open file '%s' (mode: '%s')",
  397. path, mode);
  398. goto end;
  399. }
  400. if ((oflag & O_CREAT) && fchmod(fd, DEFAULT_NEW_FILE_MODE) == -1) {
  401. error_setg_errno(errp, errno, "failed to set permission "
  402. "0%03o on new file '%s' (mode: '%s')",
  403. (unsigned)DEFAULT_NEW_FILE_MODE, path, mode);
  404. goto end;
  405. }
  406. f = fdopen(fd, mode);
  407. if (f == NULL) {
  408. error_setg_errno(errp, errno, "failed to associate stdio stream with "
  409. "file descriptor %d, file '%s' (mode: '%s')",
  410. fd, path, mode);
  411. }
  412. end:
  413. if (f == NULL && fd != -1) {
  414. close(fd);
  415. if (oflag & O_CREAT) {
  416. unlink(path);
  417. }
  418. }
  419. return f;
  420. }
  421. int64_t qmp_guest_file_open(const char *path, const char *mode,
  422. Error **errp)
  423. {
  424. FILE *fh;
  425. Error *local_err = NULL;
  426. int64_t handle;
  427. if (!mode) {
  428. mode = "r";
  429. }
  430. slog("guest-file-open called, filepath: %s, mode: %s", path, mode);
  431. fh = safe_open_or_create(path, mode, &local_err);
  432. if (local_err != NULL) {
  433. error_propagate(errp, local_err);
  434. return -1;
  435. }
  436. /* set fd non-blocking to avoid common use cases (like reading from a
  437. * named pipe) from hanging the agent
  438. */
  439. if (!g_unix_set_fd_nonblocking(fileno(fh), true, NULL)) {
  440. fclose(fh);
  441. error_setg_errno(errp, errno, "Failed to set FD nonblocking");
  442. return -1;
  443. }
  444. handle = guest_file_handle_add(fh, errp);
  445. if (handle < 0) {
  446. fclose(fh);
  447. return -1;
  448. }
  449. slog("guest-file-open, handle: %" PRId64, handle);
  450. return handle;
  451. }
  452. void qmp_guest_file_close(int64_t handle, Error **errp)
  453. {
  454. GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
  455. int ret;
  456. slog("guest-file-close called, handle: %" PRId64, handle);
  457. if (!gfh) {
  458. return;
  459. }
  460. ret = fclose(gfh->fh);
  461. if (ret == EOF) {
  462. error_setg_errno(errp, errno, "failed to close handle");
  463. return;
  464. }
  465. QTAILQ_REMOVE(&guest_file_state.filehandles, gfh, next);
  466. g_free(gfh);
  467. }
  468. GuestFileRead *guest_file_read_unsafe(GuestFileHandle *gfh,
  469. int64_t count, Error **errp)
  470. {
  471. GuestFileRead *read_data = NULL;
  472. guchar *buf;
  473. FILE *fh = gfh->fh;
  474. size_t read_count;
  475. /* explicitly flush when switching from writing to reading */
  476. if (gfh->state == RW_STATE_WRITING) {
  477. int ret = fflush(fh);
  478. if (ret == EOF) {
  479. error_setg_errno(errp, errno, "failed to flush file");
  480. return NULL;
  481. }
  482. gfh->state = RW_STATE_NEW;
  483. }
  484. buf = g_malloc0(count + 1);
  485. read_count = fread(buf, 1, count, fh);
  486. if (ferror(fh)) {
  487. error_setg_errno(errp, errno, "failed to read file");
  488. } else {
  489. buf[read_count] = 0;
  490. read_data = g_new0(GuestFileRead, 1);
  491. read_data->count = read_count;
  492. read_data->eof = feof(fh);
  493. if (read_count) {
  494. read_data->buf_b64 = g_base64_encode(buf, read_count);
  495. }
  496. gfh->state = RW_STATE_READING;
  497. }
  498. g_free(buf);
  499. clearerr(fh);
  500. return read_data;
  501. }
  502. GuestFileWrite *qmp_guest_file_write(int64_t handle, const char *buf_b64,
  503. bool has_count, int64_t count,
  504. Error **errp)
  505. {
  506. GuestFileWrite *write_data = NULL;
  507. guchar *buf;
  508. gsize buf_len;
  509. int write_count;
  510. GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
  511. FILE *fh;
  512. if (!gfh) {
  513. return NULL;
  514. }
  515. fh = gfh->fh;
  516. if (gfh->state == RW_STATE_READING) {
  517. int ret = fseek(fh, 0, SEEK_CUR);
  518. if (ret == -1) {
  519. error_setg_errno(errp, errno, "failed to seek file");
  520. return NULL;
  521. }
  522. gfh->state = RW_STATE_NEW;
  523. }
  524. buf = qbase64_decode(buf_b64, -1, &buf_len, errp);
  525. if (!buf) {
  526. return NULL;
  527. }
  528. if (!has_count) {
  529. count = buf_len;
  530. } else if (count < 0 || count > buf_len) {
  531. error_setg(errp, "value '%" PRId64 "' is invalid for argument count",
  532. count);
  533. g_free(buf);
  534. return NULL;
  535. }
  536. write_count = fwrite(buf, 1, count, fh);
  537. if (ferror(fh)) {
  538. error_setg_errno(errp, errno, "failed to write to file");
  539. slog("guest-file-write failed, handle: %" PRId64, handle);
  540. } else {
  541. write_data = g_new0(GuestFileWrite, 1);
  542. write_data->count = write_count;
  543. write_data->eof = feof(fh);
  544. gfh->state = RW_STATE_WRITING;
  545. }
  546. g_free(buf);
  547. clearerr(fh);
  548. return write_data;
  549. }
  550. struct GuestFileSeek *qmp_guest_file_seek(int64_t handle, int64_t offset,
  551. GuestFileWhence *whence_code,
  552. Error **errp)
  553. {
  554. GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
  555. GuestFileSeek *seek_data = NULL;
  556. FILE *fh;
  557. int ret;
  558. int whence;
  559. Error *err = NULL;
  560. if (!gfh) {
  561. return NULL;
  562. }
  563. /* We stupidly exposed 'whence':'int' in our qapi */
  564. whence = ga_parse_whence(whence_code, &err);
  565. if (err) {
  566. error_propagate(errp, err);
  567. return NULL;
  568. }
  569. fh = gfh->fh;
  570. ret = fseek(fh, offset, whence);
  571. if (ret == -1) {
  572. error_setg_errno(errp, errno, "failed to seek file");
  573. if (errno == ESPIPE) {
  574. /* file is non-seekable, stdio shouldn't be buffering anyways */
  575. gfh->state = RW_STATE_NEW;
  576. }
  577. } else {
  578. seek_data = g_new0(GuestFileSeek, 1);
  579. seek_data->position = ftell(fh);
  580. seek_data->eof = feof(fh);
  581. gfh->state = RW_STATE_NEW;
  582. }
  583. clearerr(fh);
  584. return seek_data;
  585. }
  586. void qmp_guest_file_flush(int64_t handle, Error **errp)
  587. {
  588. GuestFileHandle *gfh = guest_file_handle_find(handle, errp);
  589. FILE *fh;
  590. int ret;
  591. if (!gfh) {
  592. return;
  593. }
  594. fh = gfh->fh;
  595. ret = fflush(fh);
  596. if (ret == EOF) {
  597. error_setg_errno(errp, errno, "failed to flush file");
  598. } else {
  599. gfh->state = RW_STATE_NEW;
  600. }
  601. }
  602. #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
  603. void free_fs_mount_list(FsMountList *mounts)
  604. {
  605. FsMount *mount, *temp;
  606. if (!mounts) {
  607. return;
  608. }
  609. QTAILQ_FOREACH_SAFE(mount, mounts, next, temp) {
  610. QTAILQ_REMOVE(mounts, mount, next);
  611. g_free(mount->dirname);
  612. g_free(mount->devtype);
  613. g_free(mount);
  614. }
  615. }
  616. #endif
  617. #if defined(CONFIG_FSFREEZE)
  618. typedef enum {
  619. FSFREEZE_HOOK_THAW = 0,
  620. FSFREEZE_HOOK_FREEZE,
  621. } FsfreezeHookArg;
  622. static const char *fsfreeze_hook_arg_string[] = {
  623. "thaw",
  624. "freeze",
  625. };
  626. static void execute_fsfreeze_hook(FsfreezeHookArg arg, Error **errp)
  627. {
  628. const char *hook;
  629. const char *arg_str = fsfreeze_hook_arg_string[arg];
  630. Error *local_err = NULL;
  631. hook = ga_fsfreeze_hook(ga_state);
  632. if (!hook) {
  633. return;
  634. }
  635. const char *argv[] = {hook, arg_str, NULL};
  636. slog("executing fsfreeze hook with arg '%s'", arg_str);
  637. ga_run_command(argv, NULL, "execute fsfreeze hook", &local_err);
  638. if (local_err) {
  639. error_propagate(errp, local_err);
  640. return;
  641. }
  642. }
  643. /*
  644. * Return status of freeze/thaw
  645. */
  646. GuestFsfreezeStatus qmp_guest_fsfreeze_status(Error **errp)
  647. {
  648. if (ga_is_frozen(ga_state)) {
  649. return GUEST_FSFREEZE_STATUS_FROZEN;
  650. }
  651. return GUEST_FSFREEZE_STATUS_THAWED;
  652. }
  653. int64_t qmp_guest_fsfreeze_freeze(Error **errp)
  654. {
  655. return qmp_guest_fsfreeze_freeze_list(false, NULL, errp);
  656. }
  657. int64_t qmp_guest_fsfreeze_freeze_list(bool has_mountpoints,
  658. strList *mountpoints,
  659. Error **errp)
  660. {
  661. int ret;
  662. FsMountList mounts;
  663. Error *local_err = NULL;
  664. slog("guest-fsfreeze called");
  665. execute_fsfreeze_hook(FSFREEZE_HOOK_FREEZE, &local_err);
  666. if (local_err) {
  667. error_propagate(errp, local_err);
  668. return -1;
  669. }
  670. QTAILQ_INIT(&mounts);
  671. if (!build_fs_mount_list(&mounts, &local_err)) {
  672. error_propagate(errp, local_err);
  673. return -1;
  674. }
  675. /* cannot risk guest agent blocking itself on a write in this state */
  676. ga_set_frozen(ga_state);
  677. ret = qmp_guest_fsfreeze_do_freeze_list(has_mountpoints, mountpoints,
  678. mounts, errp);
  679. free_fs_mount_list(&mounts);
  680. /* We may not issue any FIFREEZE here.
  681. * Just unset ga_state here and ready for the next call.
  682. */
  683. if (ret == 0) {
  684. ga_unset_frozen(ga_state);
  685. } else if (ret < 0) {
  686. qmp_guest_fsfreeze_thaw(NULL);
  687. }
  688. return ret;
  689. }
  690. int64_t qmp_guest_fsfreeze_thaw(Error **errp)
  691. {
  692. int ret;
  693. ret = qmp_guest_fsfreeze_do_thaw(errp);
  694. if (ret >= 0) {
  695. ga_unset_frozen(ga_state);
  696. execute_fsfreeze_hook(FSFREEZE_HOOK_THAW, errp);
  697. } else {
  698. ret = 0;
  699. }
  700. return ret;
  701. }
  702. static void guest_fsfreeze_cleanup(void)
  703. {
  704. Error *err = NULL;
  705. if (ga_is_frozen(ga_state) == GUEST_FSFREEZE_STATUS_FROZEN) {
  706. qmp_guest_fsfreeze_thaw(&err);
  707. if (err) {
  708. slog("failed to clean up frozen filesystems: %s",
  709. error_get_pretty(err));
  710. error_free(err);
  711. }
  712. }
  713. }
  714. #endif
  715. #if defined(__linux__) || defined(__FreeBSD__)
  716. void qmp_guest_set_user_password(const char *username,
  717. const char *password,
  718. bool crypted,
  719. Error **errp)
  720. {
  721. Error *local_err = NULL;
  722. g_autofree char *rawpasswddata = NULL;
  723. size_t rawpasswdlen;
  724. rawpasswddata = (char *)qbase64_decode(password, -1, &rawpasswdlen, errp);
  725. if (!rawpasswddata) {
  726. return;
  727. }
  728. rawpasswddata = g_renew(char, rawpasswddata, rawpasswdlen + 1);
  729. rawpasswddata[rawpasswdlen] = '\0';
  730. if (strchr(rawpasswddata, '\n')) {
  731. error_setg(errp, "forbidden characters in raw password");
  732. return;
  733. }
  734. if (strchr(username, '\n') ||
  735. strchr(username, ':')) {
  736. error_setg(errp, "forbidden characters in username");
  737. return;
  738. }
  739. #ifdef __FreeBSD__
  740. g_autofree char *chpasswddata = g_strdup(rawpasswddata);
  741. const char *crypt_flag = crypted ? "-H" : "-h";
  742. const char *argv[] = {"pw", "usermod", "-n", username,
  743. crypt_flag, "0", NULL};
  744. #else
  745. g_autofree char *chpasswddata = g_strdup_printf("%s:%s\n", username,
  746. rawpasswddata);
  747. const char *crypt_flag = crypted ? "-e" : NULL;
  748. const char *argv[] = {"chpasswd", crypt_flag, NULL};
  749. #endif
  750. ga_run_command(argv, chpasswddata, "set user password", &local_err);
  751. if (local_err) {
  752. error_propagate(errp, local_err);
  753. return;
  754. }
  755. }
  756. #endif /* __linux__ || __FreeBSD__ */
  757. #ifdef HAVE_GETIFADDRS
  758. static GuestNetworkInterface *
  759. guest_find_interface(GuestNetworkInterfaceList *head,
  760. const char *name)
  761. {
  762. for (; head; head = head->next) {
  763. if (strcmp(head->value->name, name) == 0) {
  764. return head->value;
  765. }
  766. }
  767. return NULL;
  768. }
  769. static int guest_get_network_stats(const char *name,
  770. GuestNetworkInterfaceStat *stats)
  771. {
  772. #ifdef CONFIG_LINUX
  773. int name_len;
  774. char const *devinfo = "/proc/net/dev";
  775. FILE *fp;
  776. char *line = NULL, *colon;
  777. size_t n = 0;
  778. fp = fopen(devinfo, "r");
  779. if (!fp) {
  780. g_debug("failed to open network stats %s: %s", devinfo,
  781. g_strerror(errno));
  782. return -1;
  783. }
  784. name_len = strlen(name);
  785. while (getline(&line, &n, fp) != -1) {
  786. long long dummy;
  787. long long rx_bytes;
  788. long long rx_packets;
  789. long long rx_errs;
  790. long long rx_dropped;
  791. long long tx_bytes;
  792. long long tx_packets;
  793. long long tx_errs;
  794. long long tx_dropped;
  795. char *trim_line;
  796. trim_line = g_strchug(line);
  797. if (trim_line[0] == '\0') {
  798. continue;
  799. }
  800. colon = strchr(trim_line, ':');
  801. if (!colon) {
  802. continue;
  803. }
  804. if (colon - name_len == trim_line &&
  805. strncmp(trim_line, name, name_len) == 0) {
  806. if (sscanf(colon + 1,
  807. "%lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld %lld",
  808. &rx_bytes, &rx_packets, &rx_errs, &rx_dropped,
  809. &dummy, &dummy, &dummy, &dummy,
  810. &tx_bytes, &tx_packets, &tx_errs, &tx_dropped,
  811. &dummy, &dummy, &dummy, &dummy) != 16) {
  812. continue;
  813. }
  814. stats->rx_bytes = rx_bytes;
  815. stats->rx_packets = rx_packets;
  816. stats->rx_errs = rx_errs;
  817. stats->rx_dropped = rx_dropped;
  818. stats->tx_bytes = tx_bytes;
  819. stats->tx_packets = tx_packets;
  820. stats->tx_errs = tx_errs;
  821. stats->tx_dropped = tx_dropped;
  822. fclose(fp);
  823. g_free(line);
  824. return 0;
  825. }
  826. }
  827. fclose(fp);
  828. g_free(line);
  829. g_debug("/proc/net/dev: Interface '%s' not found", name);
  830. #else /* !CONFIG_LINUX */
  831. g_debug("Network stats reporting available only for Linux");
  832. #endif /* !CONFIG_LINUX */
  833. return -1;
  834. }
  835. #ifndef CONFIG_BSD
  836. /*
  837. * Fill "buf" with MAC address by ifaddrs. Pointer buf must point to a
  838. * buffer with ETHER_ADDR_LEN length at least.
  839. *
  840. * Returns false in case of an error, otherwise true. "obtained" argument
  841. * is true if a MAC address was obtained successful, otherwise false.
  842. */
  843. bool guest_get_hw_addr(struct ifaddrs *ifa, unsigned char *buf,
  844. bool *obtained, Error **errp)
  845. {
  846. struct ifreq ifr;
  847. int sock;
  848. *obtained = false;
  849. /* we haven't obtained HW address yet */
  850. sock = socket(PF_INET, SOCK_STREAM, 0);
  851. if (sock == -1) {
  852. error_setg_errno(errp, errno, "failed to create socket");
  853. return false;
  854. }
  855. memset(&ifr, 0, sizeof(ifr));
  856. pstrcpy(ifr.ifr_name, IF_NAMESIZE, ifa->ifa_name);
  857. if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
  858. /*
  859. * We can't get the hw addr of this interface, but that's not a
  860. * fatal error.
  861. */
  862. if (errno == EADDRNOTAVAIL) {
  863. /* The interface doesn't have a hw addr (e.g. loopback). */
  864. g_debug("failed to get MAC address of %s: %s",
  865. ifa->ifa_name, strerror(errno));
  866. } else{
  867. g_warning("failed to get MAC address of %s: %s",
  868. ifa->ifa_name, strerror(errno));
  869. }
  870. } else {
  871. #ifdef CONFIG_SOLARIS
  872. memcpy(buf, &ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
  873. #else
  874. memcpy(buf, &ifr.ifr_hwaddr.sa_data, ETHER_ADDR_LEN);
  875. #endif
  876. *obtained = true;
  877. }
  878. close(sock);
  879. return true;
  880. }
  881. #endif /* CONFIG_BSD */
  882. /*
  883. * Build information about guest interfaces
  884. */
  885. GuestNetworkInterfaceList *qmp_guest_network_get_interfaces(Error **errp)
  886. {
  887. GuestNetworkInterfaceList *head = NULL, **tail = &head;
  888. struct ifaddrs *ifap, *ifa;
  889. if (getifaddrs(&ifap) < 0) {
  890. error_setg_errno(errp, errno, "getifaddrs failed");
  891. goto error;
  892. }
  893. for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
  894. GuestNetworkInterface *info;
  895. GuestIpAddressList **address_tail;
  896. GuestIpAddress *address_item = NULL;
  897. GuestNetworkInterfaceStat *interface_stat = NULL;
  898. char addr4[INET_ADDRSTRLEN];
  899. char addr6[INET6_ADDRSTRLEN];
  900. unsigned char mac_addr[ETHER_ADDR_LEN];
  901. bool obtained;
  902. void *p;
  903. g_debug("Processing %s interface", ifa->ifa_name);
  904. info = guest_find_interface(head, ifa->ifa_name);
  905. if (!info) {
  906. info = g_malloc0(sizeof(*info));
  907. info->name = g_strdup(ifa->ifa_name);
  908. QAPI_LIST_APPEND(tail, info);
  909. }
  910. if (!info->hardware_address) {
  911. if (!guest_get_hw_addr(ifa, mac_addr, &obtained, errp)) {
  912. goto error;
  913. }
  914. if (obtained) {
  915. info->hardware_address =
  916. g_strdup_printf("%02x:%02x:%02x:%02x:%02x:%02x",
  917. (int) mac_addr[0], (int) mac_addr[1],
  918. (int) mac_addr[2], (int) mac_addr[3],
  919. (int) mac_addr[4], (int) mac_addr[5]);
  920. }
  921. }
  922. if (ifa->ifa_addr &&
  923. ifa->ifa_addr->sa_family == AF_INET) {
  924. /* interface with IPv4 address */
  925. p = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
  926. if (!inet_ntop(AF_INET, p, addr4, sizeof(addr4))) {
  927. error_setg_errno(errp, errno, "inet_ntop failed");
  928. goto error;
  929. }
  930. address_item = g_malloc0(sizeof(*address_item));
  931. address_item->ip_address = g_strdup(addr4);
  932. address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV4;
  933. if (ifa->ifa_netmask) {
  934. /* Count the number of set bits in netmask.
  935. * This is safe as '1' and '0' cannot be shuffled in netmask. */
  936. p = &((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;
  937. address_item->prefix = ctpop32(((uint32_t *) p)[0]);
  938. }
  939. } else if (ifa->ifa_addr &&
  940. ifa->ifa_addr->sa_family == AF_INET6) {
  941. /* interface with IPv6 address */
  942. p = &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
  943. if (!inet_ntop(AF_INET6, p, addr6, sizeof(addr6))) {
  944. error_setg_errno(errp, errno, "inet_ntop failed");
  945. goto error;
  946. }
  947. address_item = g_malloc0(sizeof(*address_item));
  948. address_item->ip_address = g_strdup(addr6);
  949. address_item->ip_address_type = GUEST_IP_ADDRESS_TYPE_IPV6;
  950. if (ifa->ifa_netmask) {
  951. /* Count the number of set bits in netmask.
  952. * This is safe as '1' and '0' cannot be shuffled in netmask. */
  953. p = &((struct sockaddr_in6 *)ifa->ifa_netmask)->sin6_addr;
  954. address_item->prefix =
  955. ctpop32(((uint32_t *) p)[0]) +
  956. ctpop32(((uint32_t *) p)[1]) +
  957. ctpop32(((uint32_t *) p)[2]) +
  958. ctpop32(((uint32_t *) p)[3]);
  959. }
  960. }
  961. if (!address_item) {
  962. continue;
  963. }
  964. address_tail = &info->ip_addresses;
  965. while (*address_tail) {
  966. address_tail = &(*address_tail)->next;
  967. }
  968. QAPI_LIST_APPEND(address_tail, address_item);
  969. info->has_ip_addresses = true;
  970. if (!info->statistics) {
  971. interface_stat = g_malloc0(sizeof(*interface_stat));
  972. if (guest_get_network_stats(info->name, interface_stat) == -1) {
  973. g_free(interface_stat);
  974. } else {
  975. info->statistics = interface_stat;
  976. }
  977. }
  978. }
  979. freeifaddrs(ifap);
  980. return head;
  981. error:
  982. freeifaddrs(ifap);
  983. qapi_free_GuestNetworkInterfaceList(head);
  984. return NULL;
  985. }
  986. #endif /* HAVE_GETIFADDRS */
  987. /* register init/cleanup routines for stateful command groups */
  988. void ga_command_state_init(GAState *s, GACommandState *cs)
  989. {
  990. #if defined(CONFIG_FSFREEZE)
  991. ga_command_state_add(cs, NULL, guest_fsfreeze_cleanup);
  992. #endif
  993. }
  994. #ifdef HAVE_UTMPX
  995. #define QGA_MICRO_SECOND_TO_SECOND 1000000
  996. static double ga_get_login_time(struct utmpx *user_info)
  997. {
  998. double seconds = (double)user_info->ut_tv.tv_sec;
  999. double useconds = (double)user_info->ut_tv.tv_usec;
  1000. useconds /= QGA_MICRO_SECOND_TO_SECOND;
  1001. return seconds + useconds;
  1002. }
  1003. GuestUserList *qmp_guest_get_users(Error **errp)
  1004. {
  1005. GHashTable *cache = NULL;
  1006. GuestUserList *head = NULL, **tail = &head;
  1007. struct utmpx *user_info = NULL;
  1008. gpointer value = NULL;
  1009. GuestUser *user = NULL;
  1010. double login_time = 0;
  1011. cache = g_hash_table_new(g_str_hash, g_str_equal);
  1012. setutxent();
  1013. for (;;) {
  1014. user_info = getutxent();
  1015. if (user_info == NULL) {
  1016. break;
  1017. } else if (user_info->ut_type != USER_PROCESS) {
  1018. continue;
  1019. } else if (g_hash_table_contains(cache, user_info->ut_user)) {
  1020. value = g_hash_table_lookup(cache, user_info->ut_user);
  1021. user = (GuestUser *)value;
  1022. login_time = ga_get_login_time(user_info);
  1023. /* We're ensuring the earliest login time to be sent */
  1024. if (login_time < user->login_time) {
  1025. user->login_time = login_time;
  1026. }
  1027. continue;
  1028. }
  1029. user = g_new0(GuestUser, 1);
  1030. user->user = g_strdup(user_info->ut_user);
  1031. user->login_time = ga_get_login_time(user_info);
  1032. g_hash_table_insert(cache, user->user, user);
  1033. QAPI_LIST_APPEND(tail, user);
  1034. }
  1035. endutxent();
  1036. g_hash_table_destroy(cache);
  1037. return head;
  1038. }
  1039. #endif /* HAVE_UTMPX */
  1040. /* Replace escaped special characters with their real values. The replacement
  1041. * is done in place -- returned value is in the original string.
  1042. */
  1043. static void ga_osrelease_replace_special(gchar *value)
  1044. {
  1045. gchar *p, *p2, quote;
  1046. /* Trim the string at first space or semicolon if it is not enclosed in
  1047. * single or double quotes. */
  1048. if ((value[0] != '"') || (value[0] == '\'')) {
  1049. p = strchr(value, ' ');
  1050. if (p != NULL) {
  1051. *p = 0;
  1052. }
  1053. p = strchr(value, ';');
  1054. if (p != NULL) {
  1055. *p = 0;
  1056. }
  1057. return;
  1058. }
  1059. quote = value[0];
  1060. p2 = value;
  1061. p = value + 1;
  1062. while (*p != 0) {
  1063. if (*p == '\\') {
  1064. p++;
  1065. switch (*p) {
  1066. case '$':
  1067. case '\'':
  1068. case '"':
  1069. case '\\':
  1070. case '`':
  1071. break;
  1072. default:
  1073. /* Keep literal backslash followed by whatever is there */
  1074. p--;
  1075. break;
  1076. }
  1077. } else if (*p == quote) {
  1078. *p2 = 0;
  1079. break;
  1080. }
  1081. *(p2++) = *(p++);
  1082. }
  1083. }
  1084. static GKeyFile *ga_parse_osrelease(const char *fname)
  1085. {
  1086. gchar *content = NULL;
  1087. gchar *content2 = NULL;
  1088. GError *err = NULL;
  1089. GKeyFile *keys = g_key_file_new();
  1090. const char *group = "[os-release]\n";
  1091. if (!g_file_get_contents(fname, &content, NULL, &err)) {
  1092. slog("failed to read '%s', error: %s", fname, err->message);
  1093. goto fail;
  1094. }
  1095. if (!g_utf8_validate(content, -1, NULL)) {
  1096. slog("file is not utf-8 encoded: %s", fname);
  1097. goto fail;
  1098. }
  1099. content2 = g_strdup_printf("%s%s", group, content);
  1100. if (!g_key_file_load_from_data(keys, content2, -1, G_KEY_FILE_NONE,
  1101. &err)) {
  1102. slog("failed to parse file '%s', error: %s", fname, err->message);
  1103. goto fail;
  1104. }
  1105. g_free(content);
  1106. g_free(content2);
  1107. return keys;
  1108. fail:
  1109. g_error_free(err);
  1110. g_free(content);
  1111. g_free(content2);
  1112. g_key_file_free(keys);
  1113. return NULL;
  1114. }
  1115. GuestOSInfo *qmp_guest_get_osinfo(Error **errp)
  1116. {
  1117. GuestOSInfo *info = NULL;
  1118. struct utsname kinfo;
  1119. GKeyFile *osrelease = NULL;
  1120. const char *qga_os_release = g_getenv("QGA_OS_RELEASE");
  1121. info = g_new0(GuestOSInfo, 1);
  1122. if (uname(&kinfo) != 0) {
  1123. error_setg_errno(errp, errno, "uname failed");
  1124. } else {
  1125. info->kernel_version = g_strdup(kinfo.version);
  1126. info->kernel_release = g_strdup(kinfo.release);
  1127. info->machine = g_strdup(kinfo.machine);
  1128. }
  1129. if (qga_os_release != NULL) {
  1130. osrelease = ga_parse_osrelease(qga_os_release);
  1131. } else {
  1132. osrelease = ga_parse_osrelease("/etc/os-release");
  1133. if (osrelease == NULL) {
  1134. osrelease = ga_parse_osrelease("/usr/lib/os-release");
  1135. }
  1136. }
  1137. if (osrelease != NULL) {
  1138. char *value;
  1139. #define GET_FIELD(field, osfield) do { \
  1140. value = g_key_file_get_value(osrelease, "os-release", osfield, NULL); \
  1141. if (value != NULL) { \
  1142. ga_osrelease_replace_special(value); \
  1143. info->field = value; \
  1144. } \
  1145. } while (0)
  1146. GET_FIELD(id, "ID");
  1147. GET_FIELD(name, "NAME");
  1148. GET_FIELD(pretty_name, "PRETTY_NAME");
  1149. GET_FIELD(version, "VERSION");
  1150. GET_FIELD(version_id, "VERSION_ID");
  1151. GET_FIELD(variant, "VARIANT");
  1152. GET_FIELD(variant_id, "VARIANT_ID");
  1153. #undef GET_FIELD
  1154. g_key_file_free(osrelease);
  1155. }
  1156. return info;
  1157. }
  1158. #ifndef HOST_NAME_MAX
  1159. # ifdef _POSIX_HOST_NAME_MAX
  1160. # define HOST_NAME_MAX _POSIX_HOST_NAME_MAX
  1161. # else
  1162. # define HOST_NAME_MAX 255
  1163. # endif
  1164. #endif
  1165. char *qga_get_host_name(Error **errp)
  1166. {
  1167. long len = -1;
  1168. g_autofree char *hostname = NULL;
  1169. #ifdef _SC_HOST_NAME_MAX
  1170. len = sysconf(_SC_HOST_NAME_MAX);
  1171. #endif /* _SC_HOST_NAME_MAX */
  1172. if (len < 0) {
  1173. len = HOST_NAME_MAX;
  1174. }
  1175. /* Unfortunately, gethostname() below does not guarantee a
  1176. * NULL terminated string. Therefore, allocate one byte more
  1177. * to be sure. */
  1178. hostname = g_new0(char, len + 1);
  1179. if (gethostname(hostname, len) < 0) {
  1180. error_setg_errno(errp, errno,
  1181. "cannot get hostname");
  1182. return NULL;
  1183. }
  1184. return g_steal_pointer(&hostname);
  1185. }