commands-linux.c 67 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244
  1. /*
  2. * QEMU Guest Agent Linux-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 "qapi/error.h"
  15. #include "qga-qapi-commands.h"
  16. #include "qapi/error.h"
  17. #include "commands-common.h"
  18. #include "cutils.h"
  19. #include <mntent.h>
  20. #include <sys/ioctl.h>
  21. #include <mntent.h>
  22. #include <linux/nvme_ioctl.h>
  23. #include "block/nvme.h"
  24. #ifdef CONFIG_LIBUDEV
  25. #include <libudev.h>
  26. #endif
  27. #ifdef HAVE_GETIFADDRS
  28. #include <net/if.h>
  29. #endif
  30. #include <sys/statvfs.h>
  31. #if defined(CONFIG_FSFREEZE) || defined(CONFIG_FSTRIM)
  32. static int dev_major_minor(const char *devpath,
  33. unsigned int *devmajor, unsigned int *devminor)
  34. {
  35. struct stat st;
  36. *devmajor = 0;
  37. *devminor = 0;
  38. if (stat(devpath, &st) < 0) {
  39. slog("failed to stat device file '%s': %s", devpath, strerror(errno));
  40. return -1;
  41. }
  42. if (S_ISDIR(st.st_mode)) {
  43. /* It is bind mount */
  44. return -2;
  45. }
  46. if (S_ISBLK(st.st_mode)) {
  47. *devmajor = major(st.st_rdev);
  48. *devminor = minor(st.st_rdev);
  49. return 0;
  50. }
  51. return -1;
  52. }
  53. /*
  54. * Check if we already have the devmajor:devminor in the mounts
  55. * If thats the case return true.
  56. */
  57. static bool dev_exists(FsMountList *mounts, unsigned int devmajor, unsigned int devminor)
  58. {
  59. FsMount *mount;
  60. QTAILQ_FOREACH(mount, mounts, next) {
  61. if (mount->devmajor == devmajor && mount->devminor == devminor) {
  62. return true;
  63. }
  64. }
  65. return false;
  66. }
  67. static bool build_fs_mount_list_from_mtab(FsMountList *mounts, Error **errp)
  68. {
  69. struct mntent *ment;
  70. FsMount *mount;
  71. char const *mtab = "/proc/self/mounts";
  72. FILE *fp;
  73. unsigned int devmajor, devminor;
  74. fp = setmntent(mtab, "r");
  75. if (!fp) {
  76. error_setg(errp, "failed to open mtab file: '%s'", mtab);
  77. return false;
  78. }
  79. while ((ment = getmntent(fp))) {
  80. /*
  81. * An entry which device name doesn't start with a '/' is
  82. * either a dummy file system or a network file system.
  83. * Add special handling for smbfs and cifs as is done by
  84. * coreutils as well.
  85. */
  86. if ((ment->mnt_fsname[0] != '/') ||
  87. (strcmp(ment->mnt_type, "smbfs") == 0) ||
  88. (strcmp(ment->mnt_type, "cifs") == 0)) {
  89. continue;
  90. }
  91. if (dev_major_minor(ment->mnt_fsname, &devmajor, &devminor) == -2) {
  92. /* Skip bind mounts */
  93. continue;
  94. }
  95. if (dev_exists(mounts, devmajor, devminor)) {
  96. /* Skip already existing devices (bind mounts) */
  97. continue;
  98. }
  99. mount = g_new0(FsMount, 1);
  100. mount->dirname = g_strdup(ment->mnt_dir);
  101. mount->devtype = g_strdup(ment->mnt_type);
  102. mount->devmajor = devmajor;
  103. mount->devminor = devminor;
  104. QTAILQ_INSERT_TAIL(mounts, mount, next);
  105. }
  106. endmntent(fp);
  107. return true;
  108. }
  109. static void decode_mntname(char *name, int len)
  110. {
  111. int i, j = 0;
  112. for (i = 0; i <= len; i++) {
  113. if (name[i] != '\\') {
  114. name[j++] = name[i];
  115. } else if (name[i + 1] == '\\') {
  116. name[j++] = '\\';
  117. i++;
  118. } else if (name[i + 1] >= '0' && name[i + 1] <= '3' &&
  119. name[i + 2] >= '0' && name[i + 2] <= '7' &&
  120. name[i + 3] >= '0' && name[i + 3] <= '7') {
  121. name[j++] = (name[i + 1] - '0') * 64 +
  122. (name[i + 2] - '0') * 8 +
  123. (name[i + 3] - '0');
  124. i += 3;
  125. } else {
  126. name[j++] = name[i];
  127. }
  128. }
  129. }
  130. /*
  131. * Walk the mount table and build a list of local file systems
  132. */
  133. bool build_fs_mount_list(FsMountList *mounts, Error **errp)
  134. {
  135. FsMount *mount;
  136. char const *mountinfo = "/proc/self/mountinfo";
  137. FILE *fp;
  138. char *line = NULL, *dash;
  139. size_t n;
  140. char check;
  141. unsigned int devmajor, devminor;
  142. int ret, dir_s, dir_e, type_s, type_e, dev_s, dev_e;
  143. fp = fopen(mountinfo, "r");
  144. if (!fp) {
  145. return build_fs_mount_list_from_mtab(mounts, errp);
  146. }
  147. while (getline(&line, &n, fp) != -1) {
  148. ret = sscanf(line, "%*u %*u %u:%u %*s %n%*s%n%c",
  149. &devmajor, &devminor, &dir_s, &dir_e, &check);
  150. if (ret < 3) {
  151. continue;
  152. }
  153. dash = strstr(line + dir_e, " - ");
  154. if (!dash) {
  155. continue;
  156. }
  157. ret = sscanf(dash, " - %n%*s%n %n%*s%n%c",
  158. &type_s, &type_e, &dev_s, &dev_e, &check);
  159. if (ret < 1) {
  160. continue;
  161. }
  162. line[dir_e] = 0;
  163. dash[type_e] = 0;
  164. dash[dev_e] = 0;
  165. decode_mntname(line + dir_s, dir_e - dir_s);
  166. decode_mntname(dash + dev_s, dev_e - dev_s);
  167. if (devmajor == 0) {
  168. /* btrfs reports major number = 0 */
  169. if (strcmp("btrfs", dash + type_s) != 0 ||
  170. dev_major_minor(dash + dev_s, &devmajor, &devminor) < 0) {
  171. continue;
  172. }
  173. }
  174. if (dev_exists(mounts, devmajor, devminor)) {
  175. /* Skip already existing devices (bind mounts) */
  176. continue;
  177. }
  178. mount = g_new0(FsMount, 1);
  179. mount->dirname = g_strdup(line + dir_s);
  180. mount->devtype = g_strdup(dash + type_s);
  181. mount->devmajor = devmajor;
  182. mount->devminor = devminor;
  183. QTAILQ_INSERT_TAIL(mounts, mount, next);
  184. }
  185. free(line);
  186. fclose(fp);
  187. return true;
  188. }
  189. #endif /* CONFIG_FSFREEZE || CONFIG_FSTRIM */
  190. #ifdef CONFIG_FSFREEZE
  191. /*
  192. * Walk list of mounted file systems in the guest, and freeze the ones which
  193. * are real local file systems.
  194. */
  195. int64_t qmp_guest_fsfreeze_do_freeze_list(bool has_mountpoints,
  196. strList *mountpoints,
  197. FsMountList mounts,
  198. Error **errp)
  199. {
  200. struct FsMount *mount;
  201. strList *list;
  202. int fd, ret, i = 0;
  203. QTAILQ_FOREACH_REVERSE(mount, &mounts, next) {
  204. /* To issue fsfreeze in the reverse order of mounts, check if the
  205. * mount is listed in the list here */
  206. if (has_mountpoints) {
  207. for (list = mountpoints; list; list = list->next) {
  208. if (strcmp(list->value, mount->dirname) == 0) {
  209. break;
  210. }
  211. }
  212. if (!list) {
  213. continue;
  214. }
  215. }
  216. fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0);
  217. if (fd == -1) {
  218. error_setg_errno(errp, errno, "failed to open %s", mount->dirname);
  219. return -1;
  220. }
  221. /* we try to cull filesystems we know won't work in advance, but other
  222. * filesystems may not implement fsfreeze for less obvious reasons.
  223. * these will report EOPNOTSUPP. we simply ignore these when tallying
  224. * the number of frozen filesystems.
  225. * if a filesystem is mounted more than once (aka bind mount) a
  226. * consecutive attempt to freeze an already frozen filesystem will
  227. * return EBUSY.
  228. *
  229. * any other error means a failure to freeze a filesystem we
  230. * expect to be freezable, so return an error in those cases
  231. * and return system to thawed state.
  232. */
  233. ret = ioctl(fd, FIFREEZE);
  234. if (ret == -1) {
  235. if (errno != EOPNOTSUPP && errno != EBUSY) {
  236. error_setg_errno(errp, errno, "failed to freeze %s",
  237. mount->dirname);
  238. close(fd);
  239. return -1;
  240. }
  241. } else {
  242. i++;
  243. }
  244. close(fd);
  245. }
  246. return i;
  247. }
  248. int qmp_guest_fsfreeze_do_thaw(Error **errp)
  249. {
  250. int ret;
  251. FsMountList mounts;
  252. FsMount *mount;
  253. int fd, i = 0, logged;
  254. Error *local_err = NULL;
  255. QTAILQ_INIT(&mounts);
  256. if (!build_fs_mount_list(&mounts, &local_err)) {
  257. error_propagate(errp, local_err);
  258. return -1;
  259. }
  260. QTAILQ_FOREACH(mount, &mounts, next) {
  261. logged = false;
  262. fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0);
  263. if (fd == -1) {
  264. continue;
  265. }
  266. /* we have no way of knowing whether a filesystem was actually unfrozen
  267. * as a result of a successful call to FITHAW, only that if an error
  268. * was returned the filesystem was *not* unfrozen by that particular
  269. * call.
  270. *
  271. * since multiple preceding FIFREEZEs require multiple calls to FITHAW
  272. * to unfreeze, continuing issuing FITHAW until an error is returned,
  273. * in which case either the filesystem is in an unfreezable state, or,
  274. * more likely, it was thawed previously (and remains so afterward).
  275. *
  276. * also, since the most recent successful call is the one that did
  277. * the actual unfreeze, we can use this to provide an accurate count
  278. * of the number of filesystems unfrozen by guest-fsfreeze-thaw, which
  279. * may * be useful for determining whether a filesystem was unfrozen
  280. * during the freeze/thaw phase by a process other than qemu-ga.
  281. */
  282. do {
  283. ret = ioctl(fd, FITHAW);
  284. if (ret == 0 && !logged) {
  285. i++;
  286. logged = true;
  287. }
  288. } while (ret == 0);
  289. close(fd);
  290. }
  291. free_fs_mount_list(&mounts);
  292. return i;
  293. }
  294. #endif /* CONFIG_FSFREEZE */
  295. #if defined(CONFIG_FSFREEZE)
  296. static char *get_pci_driver(char const *syspath, int pathlen, Error **errp)
  297. {
  298. char *path;
  299. char *dpath;
  300. char *driver = NULL;
  301. char buf[PATH_MAX];
  302. ssize_t len;
  303. path = g_strndup(syspath, pathlen);
  304. dpath = g_strdup_printf("%s/driver", path);
  305. len = readlink(dpath, buf, sizeof(buf) - 1);
  306. if (len != -1) {
  307. buf[len] = 0;
  308. driver = g_path_get_basename(buf);
  309. }
  310. g_free(dpath);
  311. g_free(path);
  312. return driver;
  313. }
  314. static int compare_uint(const void *_a, const void *_b)
  315. {
  316. unsigned int a = *(unsigned int *)_a;
  317. unsigned int b = *(unsigned int *)_b;
  318. return a < b ? -1 : a > b ? 1 : 0;
  319. }
  320. /* Walk the specified sysfs and build a sorted list of host or ata numbers */
  321. static int build_hosts(char const *syspath, char const *host, bool ata,
  322. unsigned int *hosts, int hosts_max, Error **errp)
  323. {
  324. char *path;
  325. DIR *dir;
  326. struct dirent *entry;
  327. int i = 0;
  328. path = g_strndup(syspath, host - syspath);
  329. dir = opendir(path);
  330. if (!dir) {
  331. error_setg_errno(errp, errno, "opendir(\"%s\")", path);
  332. g_free(path);
  333. return -1;
  334. }
  335. while (i < hosts_max) {
  336. entry = readdir(dir);
  337. if (!entry) {
  338. break;
  339. }
  340. if (ata && sscanf(entry->d_name, "ata%d", hosts + i) == 1) {
  341. ++i;
  342. } else if (!ata && sscanf(entry->d_name, "host%d", hosts + i) == 1) {
  343. ++i;
  344. }
  345. }
  346. qsort(hosts, i, sizeof(hosts[0]), compare_uint);
  347. g_free(path);
  348. closedir(dir);
  349. return i;
  350. }
  351. /*
  352. * Store disk device info for devices on the PCI bus.
  353. * Returns true if information has been stored, or false for failure.
  354. */
  355. static bool build_guest_fsinfo_for_pci_dev(char const *syspath,
  356. GuestDiskAddress *disk,
  357. Error **errp)
  358. {
  359. unsigned int pci[4], host, hosts[8], tgt[3];
  360. int i, nhosts = 0, pcilen;
  361. GuestPCIAddress *pciaddr = disk->pci_controller;
  362. bool has_ata = false, has_host = false, has_tgt = false;
  363. char *p, *q, *driver = NULL;
  364. bool ret = false;
  365. p = strstr(syspath, "/devices/pci");
  366. if (!p || sscanf(p + 12, "%*x:%*x/%x:%x:%x.%x%n",
  367. pci, pci + 1, pci + 2, pci + 3, &pcilen) < 4) {
  368. g_debug("only pci device is supported: sysfs path '%s'", syspath);
  369. return false;
  370. }
  371. p += 12 + pcilen;
  372. while (true) {
  373. driver = get_pci_driver(syspath, p - syspath, errp);
  374. if (driver && (g_str_equal(driver, "ata_piix") ||
  375. g_str_equal(driver, "sym53c8xx") ||
  376. g_str_equal(driver, "virtio-pci") ||
  377. g_str_equal(driver, "ahci") ||
  378. g_str_equal(driver, "nvme") ||
  379. g_str_equal(driver, "xhci_hcd") ||
  380. g_str_equal(driver, "ehci-pci"))) {
  381. break;
  382. }
  383. g_free(driver);
  384. if (sscanf(p, "/%x:%x:%x.%x%n",
  385. pci, pci + 1, pci + 2, pci + 3, &pcilen) == 4) {
  386. p += pcilen;
  387. continue;
  388. }
  389. g_debug("unsupported driver or sysfs path '%s'", syspath);
  390. return false;
  391. }
  392. p = strstr(syspath, "/target");
  393. if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u",
  394. tgt, tgt + 1, tgt + 2) == 3) {
  395. has_tgt = true;
  396. }
  397. p = strstr(syspath, "/ata");
  398. if (p) {
  399. q = p + 4;
  400. has_ata = true;
  401. } else {
  402. p = strstr(syspath, "/host");
  403. q = p + 5;
  404. }
  405. if (p && sscanf(q, "%u", &host) == 1) {
  406. has_host = true;
  407. nhosts = build_hosts(syspath, p, has_ata, hosts,
  408. ARRAY_SIZE(hosts), errp);
  409. if (nhosts < 0) {
  410. goto cleanup;
  411. }
  412. }
  413. pciaddr->domain = pci[0];
  414. pciaddr->bus = pci[1];
  415. pciaddr->slot = pci[2];
  416. pciaddr->function = pci[3];
  417. if (strcmp(driver, "ata_piix") == 0) {
  418. /* a host per ide bus, target*:0:<unit>:0 */
  419. if (!has_host || !has_tgt) {
  420. g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
  421. goto cleanup;
  422. }
  423. for (i = 0; i < nhosts; i++) {
  424. if (host == hosts[i]) {
  425. disk->bus_type = GUEST_DISK_BUS_TYPE_IDE;
  426. disk->bus = i;
  427. disk->unit = tgt[1];
  428. break;
  429. }
  430. }
  431. if (i >= nhosts) {
  432. g_debug("no host for '%s' (driver '%s')", syspath, driver);
  433. goto cleanup;
  434. }
  435. } else if (strcmp(driver, "sym53c8xx") == 0) {
  436. /* scsi(LSI Logic): target*:0:<unit>:0 */
  437. if (!has_tgt) {
  438. g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
  439. goto cleanup;
  440. }
  441. disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
  442. disk->unit = tgt[1];
  443. } else if (strcmp(driver, "virtio-pci") == 0) {
  444. if (has_tgt) {
  445. /* virtio-scsi: target*:0:0:<unit> */
  446. disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
  447. disk->unit = tgt[2];
  448. } else {
  449. /* virtio-blk: 1 disk per 1 device */
  450. disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO;
  451. }
  452. } else if (strcmp(driver, "ahci") == 0) {
  453. /* ahci: 1 host per 1 unit */
  454. if (!has_host || !has_tgt) {
  455. g_debug("invalid sysfs path '%s' (driver '%s')", syspath, driver);
  456. goto cleanup;
  457. }
  458. for (i = 0; i < nhosts; i++) {
  459. if (host == hosts[i]) {
  460. disk->unit = i;
  461. disk->bus_type = GUEST_DISK_BUS_TYPE_SATA;
  462. break;
  463. }
  464. }
  465. if (i >= nhosts) {
  466. g_debug("no host for '%s' (driver '%s')", syspath, driver);
  467. goto cleanup;
  468. }
  469. } else if (strcmp(driver, "nvme") == 0) {
  470. disk->bus_type = GUEST_DISK_BUS_TYPE_NVME;
  471. } else if (strcmp(driver, "ehci-pci") == 0 || strcmp(driver, "xhci_hcd") == 0) {
  472. disk->bus_type = GUEST_DISK_BUS_TYPE_USB;
  473. } else {
  474. g_debug("unknown driver '%s' (sysfs path '%s')", driver, syspath);
  475. goto cleanup;
  476. }
  477. ret = true;
  478. cleanup:
  479. g_free(driver);
  480. return ret;
  481. }
  482. /*
  483. * Store disk device info for non-PCI virtio devices (for example s390x
  484. * channel I/O devices). Returns true if information has been stored, or
  485. * false for failure.
  486. */
  487. static bool build_guest_fsinfo_for_nonpci_virtio(char const *syspath,
  488. GuestDiskAddress *disk,
  489. Error **errp)
  490. {
  491. unsigned int tgt[3];
  492. char *p;
  493. if (!strstr(syspath, "/virtio") || !strstr(syspath, "/block")) {
  494. g_debug("Unsupported virtio device '%s'", syspath);
  495. return false;
  496. }
  497. p = strstr(syspath, "/target");
  498. if (p && sscanf(p + 7, "%*u:%*u:%*u/%*u:%u:%u:%u",
  499. &tgt[0], &tgt[1], &tgt[2]) == 3) {
  500. /* virtio-scsi: target*:0:<target>:<unit> */
  501. disk->bus_type = GUEST_DISK_BUS_TYPE_SCSI;
  502. disk->bus = tgt[0];
  503. disk->target = tgt[1];
  504. disk->unit = tgt[2];
  505. } else {
  506. /* virtio-blk: 1 disk per 1 device */
  507. disk->bus_type = GUEST_DISK_BUS_TYPE_VIRTIO;
  508. }
  509. return true;
  510. }
  511. /*
  512. * Store disk device info for CCW devices (s390x channel I/O devices).
  513. * Returns true if information has been stored, or false for failure.
  514. */
  515. static bool build_guest_fsinfo_for_ccw_dev(char const *syspath,
  516. GuestDiskAddress *disk,
  517. Error **errp)
  518. {
  519. unsigned int cssid, ssid, subchno, devno;
  520. char *p;
  521. p = strstr(syspath, "/devices/css");
  522. if (!p || sscanf(p + 12, "%*x/%x.%x.%x/%*x.%*x.%x/",
  523. &cssid, &ssid, &subchno, &devno) < 4) {
  524. g_debug("could not parse ccw device sysfs path: %s", syspath);
  525. return false;
  526. }
  527. disk->ccw_address = g_new0(GuestCCWAddress, 1);
  528. disk->ccw_address->cssid = cssid;
  529. disk->ccw_address->ssid = ssid;
  530. disk->ccw_address->subchno = subchno;
  531. disk->ccw_address->devno = devno;
  532. if (strstr(p, "/virtio")) {
  533. build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp);
  534. }
  535. return true;
  536. }
  537. /* Store disk device info specified by @sysfs into @fs */
  538. static void build_guest_fsinfo_for_real_device(char const *syspath,
  539. GuestFilesystemInfo *fs,
  540. Error **errp)
  541. {
  542. GuestDiskAddress *disk;
  543. GuestPCIAddress *pciaddr;
  544. bool has_hwinf;
  545. #ifdef CONFIG_LIBUDEV
  546. struct udev *udev = NULL;
  547. struct udev_device *udevice = NULL;
  548. #endif
  549. pciaddr = g_new0(GuestPCIAddress, 1);
  550. pciaddr->domain = -1; /* -1 means field is invalid */
  551. pciaddr->bus = -1;
  552. pciaddr->slot = -1;
  553. pciaddr->function = -1;
  554. disk = g_new0(GuestDiskAddress, 1);
  555. disk->pci_controller = pciaddr;
  556. disk->bus_type = GUEST_DISK_BUS_TYPE_UNKNOWN;
  557. #ifdef CONFIG_LIBUDEV
  558. udev = udev_new();
  559. udevice = udev_device_new_from_syspath(udev, syspath);
  560. if (udev == NULL || udevice == NULL) {
  561. g_debug("failed to query udev");
  562. } else {
  563. const char *devnode, *serial;
  564. devnode = udev_device_get_devnode(udevice);
  565. if (devnode != NULL) {
  566. disk->dev = g_strdup(devnode);
  567. }
  568. serial = udev_device_get_property_value(udevice, "ID_SERIAL");
  569. if (serial != NULL && *serial != 0) {
  570. disk->serial = g_strdup(serial);
  571. }
  572. }
  573. udev_unref(udev);
  574. udev_device_unref(udevice);
  575. #endif
  576. if (strstr(syspath, "/devices/pci")) {
  577. has_hwinf = build_guest_fsinfo_for_pci_dev(syspath, disk, errp);
  578. } else if (strstr(syspath, "/devices/css")) {
  579. has_hwinf = build_guest_fsinfo_for_ccw_dev(syspath, disk, errp);
  580. } else if (strstr(syspath, "/virtio")) {
  581. has_hwinf = build_guest_fsinfo_for_nonpci_virtio(syspath, disk, errp);
  582. } else {
  583. g_debug("Unsupported device type for '%s'", syspath);
  584. has_hwinf = false;
  585. }
  586. if (has_hwinf || disk->dev || disk->serial) {
  587. QAPI_LIST_PREPEND(fs->disk, disk);
  588. } else {
  589. qapi_free_GuestDiskAddress(disk);
  590. }
  591. }
  592. static void build_guest_fsinfo_for_device(char const *devpath,
  593. GuestFilesystemInfo *fs,
  594. Error **errp);
  595. /* Store a list of slave devices of virtual volume specified by @syspath into
  596. * @fs */
  597. static void build_guest_fsinfo_for_virtual_device(char const *syspath,
  598. GuestFilesystemInfo *fs,
  599. Error **errp)
  600. {
  601. Error *err = NULL;
  602. DIR *dir;
  603. char *dirpath;
  604. struct dirent *entry;
  605. dirpath = g_strdup_printf("%s/slaves", syspath);
  606. dir = opendir(dirpath);
  607. if (!dir) {
  608. if (errno != ENOENT) {
  609. error_setg_errno(errp, errno, "opendir(\"%s\")", dirpath);
  610. }
  611. g_free(dirpath);
  612. return;
  613. }
  614. for (;;) {
  615. errno = 0;
  616. entry = readdir(dir);
  617. if (entry == NULL) {
  618. if (errno) {
  619. error_setg_errno(errp, errno, "readdir(\"%s\")", dirpath);
  620. }
  621. break;
  622. }
  623. if (entry->d_type == DT_LNK) {
  624. char *path;
  625. g_debug(" slave device '%s'", entry->d_name);
  626. path = g_strdup_printf("%s/slaves/%s", syspath, entry->d_name);
  627. build_guest_fsinfo_for_device(path, fs, &err);
  628. g_free(path);
  629. if (err) {
  630. error_propagate(errp, err);
  631. break;
  632. }
  633. }
  634. }
  635. g_free(dirpath);
  636. closedir(dir);
  637. }
  638. static bool is_disk_virtual(const char *devpath, Error **errp)
  639. {
  640. g_autofree char *syspath = realpath(devpath, NULL);
  641. if (!syspath) {
  642. error_setg_errno(errp, errno, "realpath(\"%s\")", devpath);
  643. return false;
  644. }
  645. return strstr(syspath, "/devices/virtual/block/") != NULL;
  646. }
  647. /* Dispatch to functions for virtual/real device */
  648. static void build_guest_fsinfo_for_device(char const *devpath,
  649. GuestFilesystemInfo *fs,
  650. Error **errp)
  651. {
  652. ERRP_GUARD();
  653. g_autofree char *syspath = NULL;
  654. bool is_virtual = false;
  655. syspath = realpath(devpath, NULL);
  656. if (!syspath) {
  657. if (errno != ENOENT) {
  658. error_setg_errno(errp, errno, "realpath(\"%s\")", devpath);
  659. return;
  660. }
  661. /* ENOENT: This devpath may not exist because of container config */
  662. if (!fs->name) {
  663. fs->name = g_path_get_basename(devpath);
  664. }
  665. return;
  666. }
  667. if (!fs->name) {
  668. fs->name = g_path_get_basename(syspath);
  669. }
  670. g_debug(" parse sysfs path '%s'", syspath);
  671. is_virtual = is_disk_virtual(syspath, errp);
  672. if (*errp != NULL) {
  673. return;
  674. }
  675. if (is_virtual) {
  676. build_guest_fsinfo_for_virtual_device(syspath, fs, errp);
  677. } else {
  678. build_guest_fsinfo_for_real_device(syspath, fs, errp);
  679. }
  680. }
  681. #ifdef CONFIG_LIBUDEV
  682. /*
  683. * Wrapper around build_guest_fsinfo_for_device() for getting just
  684. * the disk address.
  685. */
  686. static GuestDiskAddress *get_disk_address(const char *syspath, Error **errp)
  687. {
  688. g_autoptr(GuestFilesystemInfo) fs = NULL;
  689. fs = g_new0(GuestFilesystemInfo, 1);
  690. build_guest_fsinfo_for_device(syspath, fs, errp);
  691. if (fs->disk != NULL) {
  692. return g_steal_pointer(&fs->disk->value);
  693. }
  694. return NULL;
  695. }
  696. static char *get_alias_for_syspath(const char *syspath)
  697. {
  698. struct udev *udev = NULL;
  699. struct udev_device *udevice = NULL;
  700. char *ret = NULL;
  701. udev = udev_new();
  702. if (udev == NULL) {
  703. g_debug("failed to query udev");
  704. goto out;
  705. }
  706. udevice = udev_device_new_from_syspath(udev, syspath);
  707. if (udevice == NULL) {
  708. g_debug("failed to query udev for path: %s", syspath);
  709. goto out;
  710. } else {
  711. const char *alias = udev_device_get_property_value(
  712. udevice, "DM_NAME");
  713. /*
  714. * NULL means there was an error and empty string means there is no
  715. * alias. In case of no alias we return NULL instead of empty string.
  716. */
  717. if (alias == NULL) {
  718. g_debug("failed to query udev for device alias for: %s",
  719. syspath);
  720. } else if (*alias != 0) {
  721. ret = g_strdup(alias);
  722. }
  723. }
  724. out:
  725. udev_unref(udev);
  726. udev_device_unref(udevice);
  727. return ret;
  728. }
  729. static char *get_device_for_syspath(const char *syspath)
  730. {
  731. struct udev *udev = NULL;
  732. struct udev_device *udevice = NULL;
  733. char *ret = NULL;
  734. udev = udev_new();
  735. if (udev == NULL) {
  736. g_debug("failed to query udev");
  737. goto out;
  738. }
  739. udevice = udev_device_new_from_syspath(udev, syspath);
  740. if (udevice == NULL) {
  741. g_debug("failed to query udev for path: %s", syspath);
  742. goto out;
  743. } else {
  744. ret = g_strdup(udev_device_get_devnode(udevice));
  745. }
  746. out:
  747. udev_unref(udev);
  748. udev_device_unref(udevice);
  749. return ret;
  750. }
  751. static void get_disk_deps(const char *disk_dir, GuestDiskInfo *disk)
  752. {
  753. g_autofree char *deps_dir = NULL;
  754. const gchar *dep;
  755. GDir *dp_deps = NULL;
  756. /* List dependent disks */
  757. deps_dir = g_strdup_printf("%s/slaves", disk_dir);
  758. g_debug(" listing entries in: %s", deps_dir);
  759. dp_deps = g_dir_open(deps_dir, 0, NULL);
  760. if (dp_deps == NULL) {
  761. g_debug("failed to list entries in %s", deps_dir);
  762. return;
  763. }
  764. disk->has_dependencies = true;
  765. while ((dep = g_dir_read_name(dp_deps)) != NULL) {
  766. g_autofree char *dep_dir = NULL;
  767. char *dev_name;
  768. /* Add dependent disks */
  769. dep_dir = g_strdup_printf("%s/%s", deps_dir, dep);
  770. dev_name = get_device_for_syspath(dep_dir);
  771. if (dev_name != NULL) {
  772. g_debug(" adding dependent device: %s", dev_name);
  773. QAPI_LIST_PREPEND(disk->dependencies, dev_name);
  774. }
  775. }
  776. g_dir_close(dp_deps);
  777. }
  778. /*
  779. * Detect partitions subdirectory, name is "<disk_name><number>" or
  780. * "<disk_name>p<number>"
  781. *
  782. * @disk_name -- last component of /sys path (e.g. sda)
  783. * @disk_dir -- sys path of the disk (e.g. /sys/block/sda)
  784. * @disk_dev -- device node of the disk (e.g. /dev/sda)
  785. */
  786. static GuestDiskInfoList *get_disk_partitions(
  787. GuestDiskInfoList *list,
  788. const char *disk_name, const char *disk_dir,
  789. const char *disk_dev)
  790. {
  791. GuestDiskInfoList *ret = list;
  792. struct dirent *de_disk;
  793. DIR *dp_disk = NULL;
  794. size_t len = strlen(disk_name);
  795. dp_disk = opendir(disk_dir);
  796. while ((de_disk = readdir(dp_disk)) != NULL) {
  797. g_autofree char *partition_dir = NULL;
  798. char *dev_name;
  799. GuestDiskInfo *partition;
  800. if (!(de_disk->d_type & DT_DIR)) {
  801. continue;
  802. }
  803. if (!(strncmp(disk_name, de_disk->d_name, len) == 0 &&
  804. ((*(de_disk->d_name + len) == 'p' &&
  805. isdigit(*(de_disk->d_name + len + 1))) ||
  806. isdigit(*(de_disk->d_name + len))))) {
  807. continue;
  808. }
  809. partition_dir = g_strdup_printf("%s/%s",
  810. disk_dir, de_disk->d_name);
  811. dev_name = get_device_for_syspath(partition_dir);
  812. if (dev_name == NULL) {
  813. g_debug("Failed to get device name for syspath: %s",
  814. disk_dir);
  815. continue;
  816. }
  817. partition = g_new0(GuestDiskInfo, 1);
  818. partition->name = dev_name;
  819. partition->partition = true;
  820. partition->has_dependencies = true;
  821. /* Add parent disk as dependent for easier tracking of hierarchy */
  822. QAPI_LIST_PREPEND(partition->dependencies, g_strdup(disk_dev));
  823. QAPI_LIST_PREPEND(ret, partition);
  824. }
  825. closedir(dp_disk);
  826. return ret;
  827. }
  828. static void get_nvme_smart(GuestDiskInfo *disk)
  829. {
  830. int fd;
  831. GuestNVMeSmart *smart;
  832. NvmeSmartLog log = {0};
  833. struct nvme_admin_cmd cmd = {
  834. .opcode = NVME_ADM_CMD_GET_LOG_PAGE,
  835. .nsid = NVME_NSID_BROADCAST,
  836. .addr = (uintptr_t)&log,
  837. .data_len = sizeof(log),
  838. .cdw10 = NVME_LOG_SMART_INFO | (1 << 15) /* RAE bit */
  839. | (((sizeof(log) >> 2) - 1) << 16)
  840. };
  841. fd = qga_open_cloexec(disk->name, O_RDONLY, 0);
  842. if (fd == -1) {
  843. g_debug("Failed to open device: %s: %s", disk->name, g_strerror(errno));
  844. return;
  845. }
  846. if (ioctl(fd, NVME_IOCTL_ADMIN_CMD, &cmd)) {
  847. g_debug("Failed to get smart: %s: %s", disk->name, g_strerror(errno));
  848. close(fd);
  849. return;
  850. }
  851. disk->smart = g_new0(GuestDiskSmart, 1);
  852. disk->smart->type = GUEST_DISK_BUS_TYPE_NVME;
  853. smart = &disk->smart->u.nvme;
  854. smart->critical_warning = log.critical_warning;
  855. smart->temperature = lduw_le_p(&log.temperature); /* unaligned field */
  856. smart->available_spare = log.available_spare;
  857. smart->available_spare_threshold = log.available_spare_threshold;
  858. smart->percentage_used = log.percentage_used;
  859. smart->data_units_read_lo = le64_to_cpu(log.data_units_read[0]);
  860. smart->data_units_read_hi = le64_to_cpu(log.data_units_read[1]);
  861. smart->data_units_written_lo = le64_to_cpu(log.data_units_written[0]);
  862. smart->data_units_written_hi = le64_to_cpu(log.data_units_written[1]);
  863. smart->host_read_commands_lo = le64_to_cpu(log.host_read_commands[0]);
  864. smart->host_read_commands_hi = le64_to_cpu(log.host_read_commands[1]);
  865. smart->host_write_commands_lo = le64_to_cpu(log.host_write_commands[0]);
  866. smart->host_write_commands_hi = le64_to_cpu(log.host_write_commands[1]);
  867. smart->controller_busy_time_lo = le64_to_cpu(log.controller_busy_time[0]);
  868. smart->controller_busy_time_hi = le64_to_cpu(log.controller_busy_time[1]);
  869. smart->power_cycles_lo = le64_to_cpu(log.power_cycles[0]);
  870. smart->power_cycles_hi = le64_to_cpu(log.power_cycles[1]);
  871. smart->power_on_hours_lo = le64_to_cpu(log.power_on_hours[0]);
  872. smart->power_on_hours_hi = le64_to_cpu(log.power_on_hours[1]);
  873. smart->unsafe_shutdowns_lo = le64_to_cpu(log.unsafe_shutdowns[0]);
  874. smart->unsafe_shutdowns_hi = le64_to_cpu(log.unsafe_shutdowns[1]);
  875. smart->media_errors_lo = le64_to_cpu(log.media_errors[0]);
  876. smart->media_errors_hi = le64_to_cpu(log.media_errors[1]);
  877. smart->number_of_error_log_entries_lo =
  878. le64_to_cpu(log.number_of_error_log_entries[0]);
  879. smart->number_of_error_log_entries_hi =
  880. le64_to_cpu(log.number_of_error_log_entries[1]);
  881. close(fd);
  882. }
  883. static void get_disk_smart(GuestDiskInfo *disk)
  884. {
  885. if (disk->address
  886. && (disk->address->bus_type == GUEST_DISK_BUS_TYPE_NVME)) {
  887. get_nvme_smart(disk);
  888. }
  889. }
  890. GuestDiskInfoList *qmp_guest_get_disks(Error **errp)
  891. {
  892. GuestDiskInfoList *ret = NULL;
  893. GuestDiskInfo *disk;
  894. DIR *dp = NULL;
  895. struct dirent *de = NULL;
  896. g_debug("listing /sys/block directory");
  897. dp = opendir("/sys/block");
  898. if (dp == NULL) {
  899. error_setg_errno(errp, errno, "Can't open directory \"/sys/block\"");
  900. return NULL;
  901. }
  902. while ((de = readdir(dp)) != NULL) {
  903. g_autofree char *disk_dir = NULL, *line = NULL,
  904. *size_path = NULL;
  905. char *dev_name;
  906. Error *local_err = NULL;
  907. if (de->d_type != DT_LNK) {
  908. g_debug(" skipping entry: %s", de->d_name);
  909. continue;
  910. }
  911. /* Check size and skip zero-sized disks */
  912. g_debug(" checking disk size");
  913. size_path = g_strdup_printf("/sys/block/%s/size", de->d_name);
  914. if (!g_file_get_contents(size_path, &line, NULL, NULL)) {
  915. g_debug(" failed to read disk size");
  916. continue;
  917. }
  918. if (g_strcmp0(line, "0\n") == 0) {
  919. g_debug(" skipping zero-sized disk");
  920. continue;
  921. }
  922. g_debug(" adding %s", de->d_name);
  923. disk_dir = g_strdup_printf("/sys/block/%s", de->d_name);
  924. dev_name = get_device_for_syspath(disk_dir);
  925. if (dev_name == NULL) {
  926. g_debug("Failed to get device name for syspath: %s",
  927. disk_dir);
  928. continue;
  929. }
  930. disk = g_new0(GuestDiskInfo, 1);
  931. disk->name = dev_name;
  932. disk->partition = false;
  933. disk->alias = get_alias_for_syspath(disk_dir);
  934. QAPI_LIST_PREPEND(ret, disk);
  935. /* Get address for non-virtual devices */
  936. bool is_virtual = is_disk_virtual(disk_dir, &local_err);
  937. if (local_err != NULL) {
  938. g_debug(" failed to check disk path, ignoring error: %s",
  939. error_get_pretty(local_err));
  940. error_free(local_err);
  941. local_err = NULL;
  942. /* Don't try to get the address */
  943. is_virtual = true;
  944. }
  945. if (!is_virtual) {
  946. disk->address = get_disk_address(disk_dir, &local_err);
  947. if (local_err != NULL) {
  948. g_debug(" failed to get device info, ignoring error: %s",
  949. error_get_pretty(local_err));
  950. error_free(local_err);
  951. local_err = NULL;
  952. }
  953. }
  954. get_disk_deps(disk_dir, disk);
  955. get_disk_smart(disk);
  956. ret = get_disk_partitions(ret, de->d_name, disk_dir, dev_name);
  957. }
  958. closedir(dp);
  959. return ret;
  960. }
  961. #endif
  962. /* Return a list of the disk device(s)' info which @mount lies on */
  963. static GuestFilesystemInfo *build_guest_fsinfo(struct FsMount *mount,
  964. Error **errp)
  965. {
  966. GuestFilesystemInfo *fs = g_malloc0(sizeof(*fs));
  967. struct statvfs buf;
  968. unsigned long used, nonroot_total, fr_size;
  969. char *devpath = g_strdup_printf("/sys/dev/block/%u:%u",
  970. mount->devmajor, mount->devminor);
  971. fs->mountpoint = g_strdup(mount->dirname);
  972. fs->type = g_strdup(mount->devtype);
  973. build_guest_fsinfo_for_device(devpath, fs, errp);
  974. if (statvfs(fs->mountpoint, &buf) == 0) {
  975. fr_size = buf.f_frsize;
  976. used = buf.f_blocks - buf.f_bfree;
  977. nonroot_total = used + buf.f_bavail;
  978. fs->used_bytes = used * fr_size;
  979. fs->total_bytes = nonroot_total * fr_size;
  980. fs->total_bytes_privileged = buf.f_blocks * fr_size;
  981. fs->has_total_bytes = true;
  982. fs->has_total_bytes_privileged = true;
  983. fs->has_used_bytes = true;
  984. }
  985. g_free(devpath);
  986. return fs;
  987. }
  988. GuestFilesystemInfoList *qmp_guest_get_fsinfo(Error **errp)
  989. {
  990. FsMountList mounts;
  991. struct FsMount *mount;
  992. GuestFilesystemInfoList *ret = NULL;
  993. Error *local_err = NULL;
  994. QTAILQ_INIT(&mounts);
  995. if (!build_fs_mount_list(&mounts, &local_err)) {
  996. error_propagate(errp, local_err);
  997. return NULL;
  998. }
  999. QTAILQ_FOREACH(mount, &mounts, next) {
  1000. g_debug("Building guest fsinfo for '%s'", mount->dirname);
  1001. QAPI_LIST_PREPEND(ret, build_guest_fsinfo(mount, &local_err));
  1002. if (local_err) {
  1003. error_propagate(errp, local_err);
  1004. qapi_free_GuestFilesystemInfoList(ret);
  1005. ret = NULL;
  1006. break;
  1007. }
  1008. }
  1009. free_fs_mount_list(&mounts);
  1010. return ret;
  1011. }
  1012. #endif /* CONFIG_FSFREEZE */
  1013. #if defined(CONFIG_FSTRIM)
  1014. /*
  1015. * Walk list of mounted file systems in the guest, and trim them.
  1016. */
  1017. GuestFilesystemTrimResponse *
  1018. qmp_guest_fstrim(bool has_minimum, int64_t minimum, Error **errp)
  1019. {
  1020. GuestFilesystemTrimResponse *response;
  1021. GuestFilesystemTrimResult *result;
  1022. int ret = 0;
  1023. FsMountList mounts;
  1024. struct FsMount *mount;
  1025. int fd;
  1026. struct fstrim_range r;
  1027. slog("guest-fstrim called");
  1028. QTAILQ_INIT(&mounts);
  1029. if (!build_fs_mount_list(&mounts, errp)) {
  1030. return NULL;
  1031. }
  1032. response = g_malloc0(sizeof(*response));
  1033. QTAILQ_FOREACH(mount, &mounts, next) {
  1034. result = g_malloc0(sizeof(*result));
  1035. result->path = g_strdup(mount->dirname);
  1036. QAPI_LIST_PREPEND(response->paths, result);
  1037. fd = qga_open_cloexec(mount->dirname, O_RDONLY, 0);
  1038. if (fd == -1) {
  1039. result->error = g_strdup_printf("failed to open: %s",
  1040. strerror(errno));
  1041. continue;
  1042. }
  1043. /* We try to cull filesystems we know won't work in advance, but other
  1044. * filesystems may not implement fstrim for less obvious reasons.
  1045. * These will report EOPNOTSUPP; while in some other cases ENOTTY
  1046. * will be reported (e.g. CD-ROMs).
  1047. * Any other error means an unexpected error.
  1048. */
  1049. r.start = 0;
  1050. r.len = -1;
  1051. r.minlen = has_minimum ? minimum : 0;
  1052. ret = ioctl(fd, FITRIM, &r);
  1053. if (ret == -1) {
  1054. if (errno == ENOTTY || errno == EOPNOTSUPP) {
  1055. result->error = g_strdup("trim not supported");
  1056. } else {
  1057. result->error = g_strdup_printf("failed to trim: %s",
  1058. strerror(errno));
  1059. }
  1060. close(fd);
  1061. continue;
  1062. }
  1063. result->has_minimum = true;
  1064. result->minimum = r.minlen;
  1065. result->has_trimmed = true;
  1066. result->trimmed = r.len;
  1067. close(fd);
  1068. }
  1069. free_fs_mount_list(&mounts);
  1070. return response;
  1071. }
  1072. #endif /* CONFIG_FSTRIM */
  1073. #define LINUX_SYS_STATE_FILE "/sys/power/state"
  1074. #define SUSPEND_SUPPORTED 0
  1075. #define SUSPEND_NOT_SUPPORTED 1
  1076. typedef enum {
  1077. SUSPEND_MODE_DISK = 0,
  1078. SUSPEND_MODE_RAM = 1,
  1079. SUSPEND_MODE_HYBRID = 2,
  1080. } SuspendMode;
  1081. /*
  1082. * Executes a command in a child process using g_spawn_sync,
  1083. * returning an int >= 0 representing the exit status of the
  1084. * process.
  1085. *
  1086. * If the program wasn't found in path, returns -1.
  1087. *
  1088. * If a problem happened when creating the child process,
  1089. * returns -1 and errp is set.
  1090. */
  1091. static int run_process_child(const char *command[], Error **errp)
  1092. {
  1093. int exit_status, spawn_flag;
  1094. GError *g_err = NULL;
  1095. bool success;
  1096. spawn_flag = G_SPAWN_SEARCH_PATH | G_SPAWN_STDOUT_TO_DEV_NULL |
  1097. G_SPAWN_STDERR_TO_DEV_NULL;
  1098. success = g_spawn_sync(NULL, (char **)command, NULL, spawn_flag,
  1099. NULL, NULL, NULL, NULL,
  1100. &exit_status, &g_err);
  1101. if (success) {
  1102. return WEXITSTATUS(exit_status);
  1103. }
  1104. if (g_err && (g_err->code != G_SPAWN_ERROR_NOENT)) {
  1105. error_setg(errp, "failed to create child process, error '%s'",
  1106. g_err->message);
  1107. }
  1108. g_error_free(g_err);
  1109. return -1;
  1110. }
  1111. static bool systemd_supports_mode(SuspendMode mode, Error **errp)
  1112. {
  1113. const char *systemctl_args[3] = {"systemd-hibernate", "systemd-suspend",
  1114. "systemd-hybrid-sleep"};
  1115. const char *cmd[4] = {"systemctl", "status", systemctl_args[mode], NULL};
  1116. int status;
  1117. status = run_process_child(cmd, errp);
  1118. /*
  1119. * systemctl status uses LSB return codes so we can expect
  1120. * status > 0 and be ok. To assert if the guest has support
  1121. * for the selected suspend mode, status should be < 4. 4 is
  1122. * the code for unknown service status, the return value when
  1123. * the service does not exist. A common value is status = 3
  1124. * (program is not running).
  1125. */
  1126. if (status > 0 && status < 4) {
  1127. return true;
  1128. }
  1129. return false;
  1130. }
  1131. static void systemd_suspend(SuspendMode mode, Error **errp)
  1132. {
  1133. Error *local_err = NULL;
  1134. const char *systemctl_args[3] = {"hibernate", "suspend", "hybrid-sleep"};
  1135. const char *cmd[3] = {"systemctl", systemctl_args[mode], NULL};
  1136. int status;
  1137. status = run_process_child(cmd, &local_err);
  1138. if (status == 0) {
  1139. return;
  1140. }
  1141. if ((status == -1) && !local_err) {
  1142. error_setg(errp, "the helper program 'systemctl %s' was not found",
  1143. systemctl_args[mode]);
  1144. return;
  1145. }
  1146. if (local_err) {
  1147. error_propagate(errp, local_err);
  1148. } else {
  1149. error_setg(errp, "the helper program 'systemctl %s' returned an "
  1150. "unexpected exit status code (%d)",
  1151. systemctl_args[mode], status);
  1152. }
  1153. }
  1154. static bool pmutils_supports_mode(SuspendMode mode, Error **errp)
  1155. {
  1156. Error *local_err = NULL;
  1157. const char *pmutils_args[3] = {"--hibernate", "--suspend",
  1158. "--suspend-hybrid"};
  1159. const char *cmd[3] = {"pm-is-supported", pmutils_args[mode], NULL};
  1160. int status;
  1161. status = run_process_child(cmd, &local_err);
  1162. if (status == SUSPEND_SUPPORTED) {
  1163. return true;
  1164. }
  1165. if ((status == -1) && !local_err) {
  1166. return false;
  1167. }
  1168. if (local_err) {
  1169. error_propagate(errp, local_err);
  1170. } else {
  1171. error_setg(errp,
  1172. "the helper program '%s' returned an unexpected exit"
  1173. " status code (%d)", "pm-is-supported", status);
  1174. }
  1175. return false;
  1176. }
  1177. static void pmutils_suspend(SuspendMode mode, Error **errp)
  1178. {
  1179. Error *local_err = NULL;
  1180. const char *pmutils_binaries[3] = {"pm-hibernate", "pm-suspend",
  1181. "pm-suspend-hybrid"};
  1182. const char *cmd[2] = {pmutils_binaries[mode], NULL};
  1183. int status;
  1184. status = run_process_child(cmd, &local_err);
  1185. if (status == 0) {
  1186. return;
  1187. }
  1188. if ((status == -1) && !local_err) {
  1189. error_setg(errp, "the helper program '%s' was not found",
  1190. pmutils_binaries[mode]);
  1191. return;
  1192. }
  1193. if (local_err) {
  1194. error_propagate(errp, local_err);
  1195. } else {
  1196. error_setg(errp,
  1197. "the helper program '%s' returned an unexpected exit"
  1198. " status code (%d)", pmutils_binaries[mode], status);
  1199. }
  1200. }
  1201. static bool linux_sys_state_supports_mode(SuspendMode mode, Error **errp)
  1202. {
  1203. const char *sysfile_strs[3] = {"disk", "mem", NULL};
  1204. const char *sysfile_str = sysfile_strs[mode];
  1205. char buf[32]; /* hopefully big enough */
  1206. int fd;
  1207. ssize_t ret;
  1208. if (!sysfile_str) {
  1209. error_setg(errp, "unknown guest suspend mode");
  1210. return false;
  1211. }
  1212. fd = open(LINUX_SYS_STATE_FILE, O_RDONLY);
  1213. if (fd < 0) {
  1214. return false;
  1215. }
  1216. ret = read(fd, buf, sizeof(buf) - 1);
  1217. close(fd);
  1218. if (ret <= 0) {
  1219. return false;
  1220. }
  1221. buf[ret] = '\0';
  1222. if (strstr(buf, sysfile_str)) {
  1223. return true;
  1224. }
  1225. return false;
  1226. }
  1227. static void linux_sys_state_suspend(SuspendMode mode, Error **errp)
  1228. {
  1229. g_autoptr(GError) local_gerr = NULL;
  1230. const char *sysfile_strs[3] = {"disk", "mem", NULL};
  1231. const char *sysfile_str = sysfile_strs[mode];
  1232. if (!sysfile_str) {
  1233. error_setg(errp, "unknown guest suspend mode");
  1234. return;
  1235. }
  1236. if (!g_file_set_contents(LINUX_SYS_STATE_FILE, sysfile_str,
  1237. -1, &local_gerr)) {
  1238. error_setg(errp, "suspend: cannot write to '%s': %s",
  1239. LINUX_SYS_STATE_FILE, local_gerr->message);
  1240. return;
  1241. }
  1242. }
  1243. static void guest_suspend(SuspendMode mode, Error **errp)
  1244. {
  1245. Error *local_err = NULL;
  1246. bool mode_supported = false;
  1247. if (systemd_supports_mode(mode, &local_err)) {
  1248. mode_supported = true;
  1249. systemd_suspend(mode, &local_err);
  1250. if (!local_err) {
  1251. return;
  1252. }
  1253. }
  1254. error_free(local_err);
  1255. local_err = NULL;
  1256. if (pmutils_supports_mode(mode, &local_err)) {
  1257. mode_supported = true;
  1258. pmutils_suspend(mode, &local_err);
  1259. if (!local_err) {
  1260. return;
  1261. }
  1262. }
  1263. error_free(local_err);
  1264. local_err = NULL;
  1265. if (linux_sys_state_supports_mode(mode, &local_err)) {
  1266. mode_supported = true;
  1267. linux_sys_state_suspend(mode, &local_err);
  1268. }
  1269. if (!mode_supported) {
  1270. error_free(local_err);
  1271. error_setg(errp,
  1272. "the requested suspend mode is not supported by the guest");
  1273. } else {
  1274. error_propagate(errp, local_err);
  1275. }
  1276. }
  1277. void qmp_guest_suspend_disk(Error **errp)
  1278. {
  1279. guest_suspend(SUSPEND_MODE_DISK, errp);
  1280. }
  1281. void qmp_guest_suspend_ram(Error **errp)
  1282. {
  1283. guest_suspend(SUSPEND_MODE_RAM, errp);
  1284. }
  1285. void qmp_guest_suspend_hybrid(Error **errp)
  1286. {
  1287. guest_suspend(SUSPEND_MODE_HYBRID, errp);
  1288. }
  1289. /* Transfer online/offline status between @vcpu and the guest system.
  1290. *
  1291. * On input either @errp or *@errp must be NULL.
  1292. *
  1293. * In system-to-@vcpu direction, the following @vcpu fields are accessed:
  1294. * - R: vcpu->logical_id
  1295. * - W: vcpu->online
  1296. * - W: vcpu->can_offline
  1297. *
  1298. * In @vcpu-to-system direction, the following @vcpu fields are accessed:
  1299. * - R: vcpu->logical_id
  1300. * - R: vcpu->online
  1301. *
  1302. * Written members remain unmodified on error.
  1303. */
  1304. static void transfer_vcpu(GuestLogicalProcessor *vcpu, bool sys2vcpu,
  1305. char *dirpath, Error **errp)
  1306. {
  1307. int fd;
  1308. int res;
  1309. int dirfd;
  1310. static const char fn[] = "online";
  1311. dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
  1312. if (dirfd == -1) {
  1313. error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
  1314. return;
  1315. }
  1316. fd = openat(dirfd, fn, sys2vcpu ? O_RDONLY : O_RDWR);
  1317. if (fd == -1) {
  1318. if (errno != ENOENT) {
  1319. error_setg_errno(errp, errno, "open(\"%s/%s\")", dirpath, fn);
  1320. } else if (sys2vcpu) {
  1321. vcpu->online = true;
  1322. vcpu->can_offline = false;
  1323. } else if (!vcpu->online) {
  1324. error_setg(errp, "logical processor #%" PRId64 " can't be "
  1325. "offlined", vcpu->logical_id);
  1326. } /* otherwise pretend successful re-onlining */
  1327. } else {
  1328. unsigned char status;
  1329. res = pread(fd, &status, 1, 0);
  1330. if (res == -1) {
  1331. error_setg_errno(errp, errno, "pread(\"%s/%s\")", dirpath, fn);
  1332. } else if (res == 0) {
  1333. error_setg(errp, "pread(\"%s/%s\"): unexpected EOF", dirpath,
  1334. fn);
  1335. } else if (sys2vcpu) {
  1336. vcpu->online = (status != '0');
  1337. vcpu->can_offline = true;
  1338. } else if (vcpu->online != (status != '0')) {
  1339. status = '0' + vcpu->online;
  1340. if (pwrite(fd, &status, 1, 0) == -1) {
  1341. error_setg_errno(errp, errno, "pwrite(\"%s/%s\")", dirpath,
  1342. fn);
  1343. }
  1344. } /* otherwise pretend successful re-(on|off)-lining */
  1345. res = close(fd);
  1346. g_assert(res == 0);
  1347. }
  1348. res = close(dirfd);
  1349. g_assert(res == 0);
  1350. }
  1351. GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)
  1352. {
  1353. GuestLogicalProcessorList *head, **tail;
  1354. const char *cpu_dir = "/sys/devices/system/cpu";
  1355. const gchar *line;
  1356. g_autoptr(GDir) cpu_gdir = NULL;
  1357. Error *local_err = NULL;
  1358. head = NULL;
  1359. tail = &head;
  1360. cpu_gdir = g_dir_open(cpu_dir, 0, NULL);
  1361. if (cpu_gdir == NULL) {
  1362. error_setg_errno(errp, errno, "failed to list entries: %s", cpu_dir);
  1363. return NULL;
  1364. }
  1365. while (local_err == NULL && (line = g_dir_read_name(cpu_gdir)) != NULL) {
  1366. GuestLogicalProcessor *vcpu;
  1367. int64_t id;
  1368. if (sscanf(line, "cpu%" PRId64, &id)) {
  1369. g_autofree char *path = g_strdup_printf("/sys/devices/system/cpu/"
  1370. "cpu%" PRId64 "/", id);
  1371. vcpu = g_malloc0(sizeof *vcpu);
  1372. vcpu->logical_id = id;
  1373. vcpu->has_can_offline = true; /* lolspeak ftw */
  1374. transfer_vcpu(vcpu, true, path, &local_err);
  1375. QAPI_LIST_APPEND(tail, vcpu);
  1376. }
  1377. }
  1378. if (local_err == NULL) {
  1379. /* there's no guest with zero VCPUs */
  1380. g_assert(head != NULL);
  1381. return head;
  1382. }
  1383. qapi_free_GuestLogicalProcessorList(head);
  1384. error_propagate(errp, local_err);
  1385. return NULL;
  1386. }
  1387. int64_t qmp_guest_set_vcpus(GuestLogicalProcessorList *vcpus, Error **errp)
  1388. {
  1389. int64_t processed;
  1390. Error *local_err = NULL;
  1391. processed = 0;
  1392. while (vcpus != NULL) {
  1393. char *path = g_strdup_printf("/sys/devices/system/cpu/cpu%" PRId64 "/",
  1394. vcpus->value->logical_id);
  1395. transfer_vcpu(vcpus->value, false, path, &local_err);
  1396. g_free(path);
  1397. if (local_err != NULL) {
  1398. break;
  1399. }
  1400. ++processed;
  1401. vcpus = vcpus->next;
  1402. }
  1403. if (local_err != NULL) {
  1404. if (processed == 0) {
  1405. error_propagate(errp, local_err);
  1406. } else {
  1407. error_free(local_err);
  1408. }
  1409. }
  1410. return processed;
  1411. }
  1412. static void ga_read_sysfs_file(int dirfd, const char *pathname, char *buf,
  1413. int size, Error **errp)
  1414. {
  1415. int fd;
  1416. int res;
  1417. errno = 0;
  1418. fd = openat(dirfd, pathname, O_RDONLY);
  1419. if (fd == -1) {
  1420. error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
  1421. return;
  1422. }
  1423. res = pread(fd, buf, size, 0);
  1424. if (res == -1) {
  1425. error_setg_errno(errp, errno, "pread sysfs file \"%s\"", pathname);
  1426. } else if (res == 0) {
  1427. error_setg(errp, "pread sysfs file \"%s\": unexpected EOF", pathname);
  1428. }
  1429. close(fd);
  1430. }
  1431. static void ga_write_sysfs_file(int dirfd, const char *pathname,
  1432. const char *buf, int size, Error **errp)
  1433. {
  1434. int fd;
  1435. errno = 0;
  1436. fd = openat(dirfd, pathname, O_WRONLY);
  1437. if (fd == -1) {
  1438. error_setg_errno(errp, errno, "open sysfs file \"%s\"", pathname);
  1439. return;
  1440. }
  1441. if (pwrite(fd, buf, size, 0) == -1) {
  1442. error_setg_errno(errp, errno, "pwrite sysfs file \"%s\"", pathname);
  1443. }
  1444. close(fd);
  1445. }
  1446. /* Transfer online/offline status between @mem_blk and the guest system.
  1447. *
  1448. * On input either @errp or *@errp must be NULL.
  1449. *
  1450. * In system-to-@mem_blk direction, the following @mem_blk fields are accessed:
  1451. * - R: mem_blk->phys_index
  1452. * - W: mem_blk->online
  1453. * - W: mem_blk->can_offline
  1454. *
  1455. * In @mem_blk-to-system direction, the following @mem_blk fields are accessed:
  1456. * - R: mem_blk->phys_index
  1457. * - R: mem_blk->online
  1458. *- R: mem_blk->can_offline
  1459. * Written members remain unmodified on error.
  1460. */
  1461. static void transfer_memory_block(GuestMemoryBlock *mem_blk, bool sys2memblk,
  1462. GuestMemoryBlockResponse *result,
  1463. Error **errp)
  1464. {
  1465. char *dirpath;
  1466. int dirfd;
  1467. char *status;
  1468. Error *local_err = NULL;
  1469. if (!sys2memblk) {
  1470. DIR *dp;
  1471. if (!result) {
  1472. error_setg(errp, "Internal error, 'result' should not be NULL");
  1473. return;
  1474. }
  1475. errno = 0;
  1476. dp = opendir("/sys/devices/system/memory/");
  1477. /* if there is no 'memory' directory in sysfs,
  1478. * we think this VM does not support online/offline memory block,
  1479. * any other solution?
  1480. */
  1481. if (!dp) {
  1482. if (errno == ENOENT) {
  1483. result->response =
  1484. GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
  1485. }
  1486. goto out1;
  1487. }
  1488. closedir(dp);
  1489. }
  1490. dirpath = g_strdup_printf("/sys/devices/system/memory/memory%" PRId64 "/",
  1491. mem_blk->phys_index);
  1492. dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
  1493. if (dirfd == -1) {
  1494. if (sys2memblk) {
  1495. error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
  1496. } else {
  1497. if (errno == ENOENT) {
  1498. result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_NOT_FOUND;
  1499. } else {
  1500. result->response =
  1501. GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
  1502. }
  1503. }
  1504. g_free(dirpath);
  1505. goto out1;
  1506. }
  1507. g_free(dirpath);
  1508. status = g_malloc0(10);
  1509. ga_read_sysfs_file(dirfd, "state", status, 10, &local_err);
  1510. if (local_err) {
  1511. /* treat with sysfs file that not exist in old kernel */
  1512. if (errno == ENOENT) {
  1513. error_free(local_err);
  1514. if (sys2memblk) {
  1515. mem_blk->online = true;
  1516. mem_blk->can_offline = false;
  1517. } else if (!mem_blk->online) {
  1518. result->response =
  1519. GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_NOT_SUPPORTED;
  1520. }
  1521. } else {
  1522. if (sys2memblk) {
  1523. error_propagate(errp, local_err);
  1524. } else {
  1525. error_free(local_err);
  1526. result->response =
  1527. GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
  1528. }
  1529. }
  1530. goto out2;
  1531. }
  1532. if (sys2memblk) {
  1533. char removable = '0';
  1534. mem_blk->online = (strncmp(status, "online", 6) == 0);
  1535. ga_read_sysfs_file(dirfd, "removable", &removable, 1, &local_err);
  1536. if (local_err) {
  1537. /* if no 'removable' file, it doesn't support offline mem blk */
  1538. if (errno == ENOENT) {
  1539. error_free(local_err);
  1540. mem_blk->can_offline = false;
  1541. } else {
  1542. error_propagate(errp, local_err);
  1543. }
  1544. } else {
  1545. mem_blk->can_offline = (removable != '0');
  1546. }
  1547. } else {
  1548. if (mem_blk->online != (strncmp(status, "online", 6) == 0)) {
  1549. const char *new_state = mem_blk->online ? "online" : "offline";
  1550. ga_write_sysfs_file(dirfd, "state", new_state, strlen(new_state),
  1551. &local_err);
  1552. if (local_err) {
  1553. error_free(local_err);
  1554. result->response =
  1555. GUEST_MEMORY_BLOCK_RESPONSE_TYPE_OPERATION_FAILED;
  1556. goto out2;
  1557. }
  1558. result->response = GUEST_MEMORY_BLOCK_RESPONSE_TYPE_SUCCESS;
  1559. result->has_error_code = false;
  1560. } /* otherwise pretend successful re-(on|off)-lining */
  1561. }
  1562. g_free(status);
  1563. close(dirfd);
  1564. return;
  1565. out2:
  1566. g_free(status);
  1567. close(dirfd);
  1568. out1:
  1569. if (!sys2memblk) {
  1570. result->has_error_code = true;
  1571. result->error_code = errno;
  1572. }
  1573. }
  1574. GuestMemoryBlockList *qmp_guest_get_memory_blocks(Error **errp)
  1575. {
  1576. GuestMemoryBlockList *head, **tail;
  1577. Error *local_err = NULL;
  1578. struct dirent *de;
  1579. DIR *dp;
  1580. head = NULL;
  1581. tail = &head;
  1582. dp = opendir("/sys/devices/system/memory/");
  1583. if (!dp) {
  1584. /* it's ok if this happens to be a system that doesn't expose
  1585. * memory blocks via sysfs, but otherwise we should report
  1586. * an error
  1587. */
  1588. if (errno != ENOENT) {
  1589. error_setg_errno(errp, errno, "Can't open directory"
  1590. "\"/sys/devices/system/memory/\"");
  1591. }
  1592. return NULL;
  1593. }
  1594. /* Note: the phys_index of memory block may be discontinuous,
  1595. * this is because a memblk is the unit of the Sparse Memory design, which
  1596. * allows discontinuous memory ranges (ex. NUMA), so here we should
  1597. * traverse the memory block directory.
  1598. */
  1599. while ((de = readdir(dp)) != NULL) {
  1600. GuestMemoryBlock *mem_blk;
  1601. if ((strncmp(de->d_name, "memory", 6) != 0) ||
  1602. !(de->d_type & DT_DIR)) {
  1603. continue;
  1604. }
  1605. mem_blk = g_malloc0(sizeof *mem_blk);
  1606. /* The d_name is "memoryXXX", phys_index is block id, same as XXX */
  1607. mem_blk->phys_index = strtoul(&de->d_name[6], NULL, 10);
  1608. mem_blk->has_can_offline = true; /* lolspeak ftw */
  1609. transfer_memory_block(mem_blk, true, NULL, &local_err);
  1610. if (local_err) {
  1611. break;
  1612. }
  1613. QAPI_LIST_APPEND(tail, mem_blk);
  1614. }
  1615. closedir(dp);
  1616. if (local_err == NULL) {
  1617. /* there's no guest with zero memory blocks */
  1618. if (head == NULL) {
  1619. error_setg(errp, "guest reported zero memory blocks!");
  1620. }
  1621. return head;
  1622. }
  1623. qapi_free_GuestMemoryBlockList(head);
  1624. error_propagate(errp, local_err);
  1625. return NULL;
  1626. }
  1627. GuestMemoryBlockResponseList *
  1628. qmp_guest_set_memory_blocks(GuestMemoryBlockList *mem_blks, Error **errp)
  1629. {
  1630. GuestMemoryBlockResponseList *head, **tail;
  1631. Error *local_err = NULL;
  1632. head = NULL;
  1633. tail = &head;
  1634. while (mem_blks != NULL) {
  1635. GuestMemoryBlockResponse *result;
  1636. GuestMemoryBlock *current_mem_blk = mem_blks->value;
  1637. result = g_malloc0(sizeof(*result));
  1638. result->phys_index = current_mem_blk->phys_index;
  1639. transfer_memory_block(current_mem_blk, false, result, &local_err);
  1640. if (local_err) { /* should never happen */
  1641. goto err;
  1642. }
  1643. QAPI_LIST_APPEND(tail, result);
  1644. mem_blks = mem_blks->next;
  1645. }
  1646. return head;
  1647. err:
  1648. qapi_free_GuestMemoryBlockResponseList(head);
  1649. error_propagate(errp, local_err);
  1650. return NULL;
  1651. }
  1652. GuestMemoryBlockInfo *qmp_guest_get_memory_block_info(Error **errp)
  1653. {
  1654. Error *local_err = NULL;
  1655. char *dirpath;
  1656. int dirfd;
  1657. char *buf;
  1658. GuestMemoryBlockInfo *info;
  1659. dirpath = g_strdup_printf("/sys/devices/system/memory/");
  1660. dirfd = open(dirpath, O_RDONLY | O_DIRECTORY);
  1661. if (dirfd == -1) {
  1662. error_setg_errno(errp, errno, "open(\"%s\")", dirpath);
  1663. g_free(dirpath);
  1664. return NULL;
  1665. }
  1666. g_free(dirpath);
  1667. buf = g_malloc0(20);
  1668. ga_read_sysfs_file(dirfd, "block_size_bytes", buf, 20, &local_err);
  1669. close(dirfd);
  1670. if (local_err) {
  1671. g_free(buf);
  1672. error_propagate(errp, local_err);
  1673. return NULL;
  1674. }
  1675. info = g_new0(GuestMemoryBlockInfo, 1);
  1676. info->size = strtol(buf, NULL, 16); /* the unit is bytes */
  1677. g_free(buf);
  1678. return info;
  1679. }
  1680. #define MAX_NAME_LEN 128
  1681. static GuestDiskStatsInfoList *guest_get_diskstats(Error **errp)
  1682. {
  1683. GuestDiskStatsInfoList *head = NULL, **tail = &head;
  1684. const char *diskstats = "/proc/diskstats";
  1685. FILE *fp;
  1686. size_t n;
  1687. char *line = NULL;
  1688. fp = fopen(diskstats, "r");
  1689. if (fp == NULL) {
  1690. error_setg_errno(errp, errno, "open(\"%s\")", diskstats);
  1691. return NULL;
  1692. }
  1693. while (getline(&line, &n, fp) != -1) {
  1694. g_autofree GuestDiskStatsInfo *diskstatinfo = NULL;
  1695. g_autofree GuestDiskStats *diskstat = NULL;
  1696. char dev_name[MAX_NAME_LEN];
  1697. unsigned int ios_pgr, tot_ticks, rq_ticks, wr_ticks, dc_ticks, fl_ticks;
  1698. unsigned long rd_ios, rd_merges_or_rd_sec, rd_ticks_or_wr_sec, wr_ios;
  1699. unsigned long wr_merges, rd_sec_or_wr_ios, wr_sec;
  1700. unsigned long dc_ios, dc_merges, dc_sec, fl_ios;
  1701. unsigned int major, minor;
  1702. int i;
  1703. i = sscanf(line, "%u %u %s %lu %lu %lu"
  1704. "%lu %lu %lu %lu %u %u %u %u"
  1705. "%lu %lu %lu %u %lu %u",
  1706. &major, &minor, dev_name,
  1707. &rd_ios, &rd_merges_or_rd_sec, &rd_sec_or_wr_ios,
  1708. &rd_ticks_or_wr_sec, &wr_ios, &wr_merges, &wr_sec,
  1709. &wr_ticks, &ios_pgr, &tot_ticks, &rq_ticks,
  1710. &dc_ios, &dc_merges, &dc_sec, &dc_ticks,
  1711. &fl_ios, &fl_ticks);
  1712. if (i < 7) {
  1713. continue;
  1714. }
  1715. diskstatinfo = g_new0(GuestDiskStatsInfo, 1);
  1716. diskstatinfo->name = g_strdup(dev_name);
  1717. diskstatinfo->major = major;
  1718. diskstatinfo->minor = minor;
  1719. diskstat = g_new0(GuestDiskStats, 1);
  1720. if (i == 7) {
  1721. diskstat->has_read_ios = true;
  1722. diskstat->read_ios = rd_ios;
  1723. diskstat->has_read_sectors = true;
  1724. diskstat->read_sectors = rd_merges_or_rd_sec;
  1725. diskstat->has_write_ios = true;
  1726. diskstat->write_ios = rd_sec_or_wr_ios;
  1727. diskstat->has_write_sectors = true;
  1728. diskstat->write_sectors = rd_ticks_or_wr_sec;
  1729. }
  1730. if (i >= 14) {
  1731. diskstat->has_read_ios = true;
  1732. diskstat->read_ios = rd_ios;
  1733. diskstat->has_read_sectors = true;
  1734. diskstat->read_sectors = rd_sec_or_wr_ios;
  1735. diskstat->has_read_merges = true;
  1736. diskstat->read_merges = rd_merges_or_rd_sec;
  1737. diskstat->has_read_ticks = true;
  1738. diskstat->read_ticks = rd_ticks_or_wr_sec;
  1739. diskstat->has_write_ios = true;
  1740. diskstat->write_ios = wr_ios;
  1741. diskstat->has_write_sectors = true;
  1742. diskstat->write_sectors = wr_sec;
  1743. diskstat->has_write_merges = true;
  1744. diskstat->write_merges = wr_merges;
  1745. diskstat->has_write_ticks = true;
  1746. diskstat->write_ticks = wr_ticks;
  1747. diskstat->has_ios_pgr = true;
  1748. diskstat->ios_pgr = ios_pgr;
  1749. diskstat->has_total_ticks = true;
  1750. diskstat->total_ticks = tot_ticks;
  1751. diskstat->has_weight_ticks = true;
  1752. diskstat->weight_ticks = rq_ticks;
  1753. }
  1754. if (i >= 18) {
  1755. diskstat->has_discard_ios = true;
  1756. diskstat->discard_ios = dc_ios;
  1757. diskstat->has_discard_merges = true;
  1758. diskstat->discard_merges = dc_merges;
  1759. diskstat->has_discard_sectors = true;
  1760. diskstat->discard_sectors = dc_sec;
  1761. diskstat->has_discard_ticks = true;
  1762. diskstat->discard_ticks = dc_ticks;
  1763. }
  1764. if (i >= 20) {
  1765. diskstat->has_flush_ios = true;
  1766. diskstat->flush_ios = fl_ios;
  1767. diskstat->has_flush_ticks = true;
  1768. diskstat->flush_ticks = fl_ticks;
  1769. }
  1770. diskstatinfo->stats = g_steal_pointer(&diskstat);
  1771. QAPI_LIST_APPEND(tail, diskstatinfo);
  1772. diskstatinfo = NULL;
  1773. }
  1774. free(line);
  1775. fclose(fp);
  1776. return head;
  1777. }
  1778. GuestDiskStatsInfoList *qmp_guest_get_diskstats(Error **errp)
  1779. {
  1780. return guest_get_diskstats(errp);
  1781. }
  1782. GuestCpuStatsList *qmp_guest_get_cpustats(Error **errp)
  1783. {
  1784. GuestCpuStatsList *head = NULL, **tail = &head;
  1785. const char *cpustats = "/proc/stat";
  1786. int clk_tck = sysconf(_SC_CLK_TCK);
  1787. FILE *fp;
  1788. size_t n;
  1789. char *line = NULL;
  1790. fp = fopen(cpustats, "r");
  1791. if (fp == NULL) {
  1792. error_setg_errno(errp, errno, "open(\"%s\")", cpustats);
  1793. return NULL;
  1794. }
  1795. while (getline(&line, &n, fp) != -1) {
  1796. GuestCpuStats *cpustat = NULL;
  1797. GuestLinuxCpuStats *linuxcpustat;
  1798. int i;
  1799. unsigned long user, system, idle, iowait, irq, softirq, steal, guest;
  1800. unsigned long nice, guest_nice;
  1801. char name[64];
  1802. i = sscanf(line, "%s %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu",
  1803. name, &user, &nice, &system, &idle, &iowait, &irq, &softirq,
  1804. &steal, &guest, &guest_nice);
  1805. /* drop "cpu 1 2 3 ...", get "cpuX 1 2 3 ..." only */
  1806. if ((i == EOF) || strncmp(name, "cpu", 3) || (name[3] == '\0')) {
  1807. continue;
  1808. }
  1809. if (i < 5) {
  1810. slog("Parsing cpu stat from %s failed, see \"man proc\"", cpustats);
  1811. break;
  1812. }
  1813. cpustat = g_new0(GuestCpuStats, 1);
  1814. cpustat->type = GUEST_CPU_STATS_TYPE_LINUX;
  1815. linuxcpustat = &cpustat->u.q_linux;
  1816. linuxcpustat->cpu = atoi(&name[3]);
  1817. linuxcpustat->user = user * 1000 / clk_tck;
  1818. linuxcpustat->nice = nice * 1000 / clk_tck;
  1819. linuxcpustat->system = system * 1000 / clk_tck;
  1820. linuxcpustat->idle = idle * 1000 / clk_tck;
  1821. if (i > 5) {
  1822. linuxcpustat->has_iowait = true;
  1823. linuxcpustat->iowait = iowait * 1000 / clk_tck;
  1824. }
  1825. if (i > 6) {
  1826. linuxcpustat->has_irq = true;
  1827. linuxcpustat->irq = irq * 1000 / clk_tck;
  1828. linuxcpustat->has_softirq = true;
  1829. linuxcpustat->softirq = softirq * 1000 / clk_tck;
  1830. }
  1831. if (i > 8) {
  1832. linuxcpustat->has_steal = true;
  1833. linuxcpustat->steal = steal * 1000 / clk_tck;
  1834. }
  1835. if (i > 9) {
  1836. linuxcpustat->has_guest = true;
  1837. linuxcpustat->guest = guest * 1000 / clk_tck;
  1838. }
  1839. if (i > 10) {
  1840. linuxcpustat->has_guest = true;
  1841. linuxcpustat->guest = guest * 1000 / clk_tck;
  1842. linuxcpustat->has_guestnice = true;
  1843. linuxcpustat->guestnice = guest_nice * 1000 / clk_tck;
  1844. }
  1845. QAPI_LIST_APPEND(tail, cpustat);
  1846. }
  1847. free(line);
  1848. fclose(fp);
  1849. return head;
  1850. }
  1851. static char *hex_to_ip_address(const void *hex_value, int is_ipv6)
  1852. {
  1853. if (is_ipv6) {
  1854. char addr[INET6_ADDRSTRLEN];
  1855. struct in6_addr in6;
  1856. const char *hex_str = (const char *)hex_value;
  1857. int i;
  1858. for (i = 0; i < 16; i++) {
  1859. if (sscanf(&hex_str[i * 2], "%02hhx", &in6.s6_addr[i]) != 1) {
  1860. return NULL;
  1861. }
  1862. }
  1863. inet_ntop(AF_INET6, &in6, addr, INET6_ADDRSTRLEN);
  1864. return g_strdup(addr);
  1865. } else {
  1866. unsigned int hex_int = *(unsigned int *)hex_value;
  1867. unsigned int byte1 = (hex_int >> 24) & 0xFF;
  1868. unsigned int byte2 = (hex_int >> 16) & 0xFF;
  1869. unsigned int byte3 = (hex_int >> 8) & 0xFF;
  1870. unsigned int byte4 = hex_int & 0xFF;
  1871. return g_strdup_printf("%u.%u.%u.%u", byte4, byte3, byte2, byte1);
  1872. }
  1873. }
  1874. GuestNetworkRouteList *qmp_guest_network_get_route(Error **errp)
  1875. {
  1876. GuestNetworkRouteList *head = NULL, **tail = &head;
  1877. const char *route_files[] = {"/proc/net/route", "/proc/net/ipv6_route"};
  1878. FILE *fp;
  1879. size_t n = 0;
  1880. char *line = NULL;
  1881. int firstLine;
  1882. int is_ipv6;
  1883. int i;
  1884. char iface[IFNAMSIZ];
  1885. for (i = 0; i < 2; i++) {
  1886. firstLine = 1;
  1887. is_ipv6 = (i == 1);
  1888. fp = fopen(route_files[i], "r");
  1889. if (fp == NULL) {
  1890. error_setg_errno(errp, errno, "open(\"%s\")", route_files[i]);
  1891. continue;
  1892. }
  1893. while (getline(&line, &n, fp) != -1) {
  1894. if (firstLine && !is_ipv6) {
  1895. firstLine = 0;
  1896. continue;
  1897. }
  1898. g_autoptr(GuestNetworkRoute) route = g_new0(GuestNetworkRoute, 1);
  1899. if (is_ipv6) {
  1900. char destination[33], source[33], next_hop[33];
  1901. int des_prefixlen, src_prefixlen, metric, refcnt, use, flags;
  1902. if (sscanf(line, "%32s %x %32s %x %32s %x %x %x %x %s",
  1903. destination, &des_prefixlen, source,
  1904. &src_prefixlen, next_hop, &metric, &refcnt,
  1905. &use, &flags, iface) != 10) {
  1906. continue;
  1907. }
  1908. route->destination = hex_to_ip_address(destination, 1);
  1909. if (route->destination == NULL) {
  1910. continue;
  1911. }
  1912. route->iface = g_strdup(iface);
  1913. route->source = hex_to_ip_address(source, 1);
  1914. route->nexthop = hex_to_ip_address(next_hop, 1);
  1915. route->desprefixlen = g_strdup_printf("%d", des_prefixlen);
  1916. route->srcprefixlen = g_strdup_printf("%d", src_prefixlen);
  1917. route->metric = metric;
  1918. route->has_flags = true;
  1919. route->flags = flags;
  1920. route->has_refcnt = true;
  1921. route->refcnt = refcnt;
  1922. route->has_use = true;
  1923. route->use = use;
  1924. route->version = 6;
  1925. } else {
  1926. unsigned int destination, gateway, mask, flags;
  1927. int refcnt, use, metric, mtu, window, irtt;
  1928. if (sscanf(line, "%s %X %X %x %d %d %d %X %d %d %d",
  1929. iface, &destination, &gateway, &flags, &refcnt,
  1930. &use, &metric, &mask, &mtu, &window, &irtt) != 11) {
  1931. continue;
  1932. }
  1933. route->destination = hex_to_ip_address(&destination, 0);
  1934. if (route->destination == NULL) {
  1935. continue;
  1936. }
  1937. route->iface = g_strdup(iface);
  1938. route->gateway = hex_to_ip_address(&gateway, 0);
  1939. route->mask = hex_to_ip_address(&mask, 0);
  1940. route->metric = metric;
  1941. route->has_flags = true;
  1942. route->flags = flags;
  1943. route->has_refcnt = true;
  1944. route->refcnt = refcnt;
  1945. route->has_use = true;
  1946. route->use = use;
  1947. route->has_mtu = true;
  1948. route->mtu = mtu;
  1949. route->has_window = true;
  1950. route->window = window;
  1951. route->has_irtt = true;
  1952. route->irtt = irtt;
  1953. route->version = 4;
  1954. }
  1955. QAPI_LIST_APPEND(tail, route);
  1956. route = NULL;
  1957. }
  1958. fclose(fp);
  1959. }
  1960. free(line);
  1961. return head;
  1962. }